1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * linux/fs/hpfs/hpfs_fn.h
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * function headers
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun //#define DBG
11*4882a593Smuzhiyun //#define DEBUG_LOCKS
12*4882a593Smuzhiyun #ifdef pr_fmt
13*4882a593Smuzhiyun #undef pr_fmt
14*4882a593Smuzhiyun #endif
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun #include <linux/mutex.h>
19*4882a593Smuzhiyun #include <linux/pagemap.h>
20*4882a593Smuzhiyun #include <linux/buffer_head.h>
21*4882a593Smuzhiyun #include <linux/slab.h>
22*4882a593Smuzhiyun #include <linux/sched/signal.h>
23*4882a593Smuzhiyun #include <linux/blkdev.h>
24*4882a593Smuzhiyun #include <asm/unaligned.h>
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun #include "hpfs.h"
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun #define EIOERROR EIO
29*4882a593Smuzhiyun #define EFSERROR EUCLEAN
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun #define ANODE_ALLOC_FWD 512
32*4882a593Smuzhiyun #define FNODE_ALLOC_FWD 0
33*4882a593Smuzhiyun #define ALLOC_FWD_MIN 16
34*4882a593Smuzhiyun #define ALLOC_FWD_MAX 128
35*4882a593Smuzhiyun #define ALLOC_M 1
36*4882a593Smuzhiyun #define FNODE_RD_AHEAD 16
37*4882a593Smuzhiyun #define ANODE_RD_AHEAD 0
38*4882a593Smuzhiyun #define DNODE_RD_AHEAD 72
39*4882a593Smuzhiyun #define COUNT_RD_AHEAD 62
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun #define FREE_DNODES_ADD 58
42*4882a593Smuzhiyun #define FREE_DNODES_DEL 29
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun #define CHKCOND(x,y) if (!(x)) printk y
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun struct hpfs_inode_info {
47*4882a593Smuzhiyun loff_t mmu_private;
48*4882a593Smuzhiyun ino_t i_parent_dir; /* (directories) gives fnode of parent dir */
49*4882a593Smuzhiyun unsigned i_dno; /* (directories) root dnode */
50*4882a593Smuzhiyun unsigned i_dpos; /* (directories) temp for readdir */
51*4882a593Smuzhiyun unsigned i_dsubdno; /* (directories) temp for readdir */
52*4882a593Smuzhiyun unsigned i_file_sec; /* (files) minimalist cache of alloc info */
53*4882a593Smuzhiyun unsigned i_disk_sec; /* (files) minimalist cache of alloc info */
54*4882a593Smuzhiyun unsigned i_n_secs; /* (files) minimalist cache of alloc info */
55*4882a593Smuzhiyun unsigned i_ea_size; /* size of extended attributes */
56*4882a593Smuzhiyun unsigned i_ea_mode : 1; /* file's permission is stored in ea */
57*4882a593Smuzhiyun unsigned i_ea_uid : 1; /* file's uid is stored in ea */
58*4882a593Smuzhiyun unsigned i_ea_gid : 1; /* file's gid is stored in ea */
59*4882a593Smuzhiyun unsigned i_dirty : 1;
60*4882a593Smuzhiyun loff_t **i_rddir_off;
61*4882a593Smuzhiyun struct inode vfs_inode;
62*4882a593Smuzhiyun };
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun struct hpfs_sb_info {
65*4882a593Smuzhiyun struct mutex hpfs_mutex; /* global hpfs lock */
66*4882a593Smuzhiyun ino_t sb_root; /* inode number of root dir */
67*4882a593Smuzhiyun unsigned sb_fs_size; /* file system size, sectors */
68*4882a593Smuzhiyun unsigned sb_bitmaps; /* sector number of bitmap list */
69*4882a593Smuzhiyun unsigned sb_dirband_start; /* directory band start sector */
70*4882a593Smuzhiyun unsigned sb_dirband_size; /* directory band size, dnodes */
71*4882a593Smuzhiyun unsigned sb_dmap; /* sector number of dnode bit map */
72*4882a593Smuzhiyun unsigned sb_n_free; /* free blocks for statfs, or -1 */
73*4882a593Smuzhiyun unsigned sb_n_free_dnodes; /* free dnodes for statfs, or -1 */
74*4882a593Smuzhiyun kuid_t sb_uid; /* uid from mount options */
75*4882a593Smuzhiyun kgid_t sb_gid; /* gid from mount options */
76*4882a593Smuzhiyun umode_t sb_mode; /* mode from mount options */
77*4882a593Smuzhiyun unsigned sb_eas : 2; /* eas: 0-ignore, 1-ro, 2-rw */
78*4882a593Smuzhiyun unsigned sb_err : 2; /* on errs: 0-cont, 1-ro, 2-panic */
79*4882a593Smuzhiyun unsigned sb_chk : 2; /* checks: 0-no, 1-normal, 2-strict */
80*4882a593Smuzhiyun unsigned sb_lowercase : 1; /* downcase filenames hackery */
81*4882a593Smuzhiyun unsigned sb_was_error : 1; /* there was an error, set dirty flag */
82*4882a593Smuzhiyun unsigned sb_chkdsk : 2; /* chkdsk: 0-no, 1-on errs, 2-allways */
83*4882a593Smuzhiyun unsigned char *sb_cp_table; /* code page tables: */
84*4882a593Smuzhiyun /* 128 bytes uppercasing table & */
85*4882a593Smuzhiyun /* 128 bytes lowercasing table */
86*4882a593Smuzhiyun __le32 *sb_bmp_dir; /* main bitmap directory */
87*4882a593Smuzhiyun unsigned sb_c_bitmap; /* current bitmap */
88*4882a593Smuzhiyun unsigned sb_max_fwd_alloc; /* max forwad allocation */
89*4882a593Smuzhiyun int sb_timeshift;
90*4882a593Smuzhiyun struct rcu_head rcu;
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun unsigned n_hotfixes;
93*4882a593Smuzhiyun secno hotfix_from[256];
94*4882a593Smuzhiyun secno hotfix_to[256];
95*4882a593Smuzhiyun };
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun /* Four 512-byte buffers and the 2k block obtained by concatenating them */
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun struct quad_buffer_head {
100*4882a593Smuzhiyun struct buffer_head *bh[4];
101*4882a593Smuzhiyun void *data;
102*4882a593Smuzhiyun };
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun /* The b-tree down pointer from a dir entry */
105*4882a593Smuzhiyun
de_down_pointer(struct hpfs_dirent * de)106*4882a593Smuzhiyun static inline dnode_secno de_down_pointer (struct hpfs_dirent *de)
107*4882a593Smuzhiyun {
108*4882a593Smuzhiyun CHKCOND(de->down,("HPFS: de_down_pointer: !de->down\n"));
109*4882a593Smuzhiyun return le32_to_cpu(*(__le32 *) ((void *) de + le16_to_cpu(de->length) - 4));
110*4882a593Smuzhiyun }
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun /* The first dir entry in a dnode */
113*4882a593Smuzhiyun
dnode_first_de(struct dnode * dnode)114*4882a593Smuzhiyun static inline struct hpfs_dirent *dnode_first_de (struct dnode *dnode)
115*4882a593Smuzhiyun {
116*4882a593Smuzhiyun return (void *) dnode->dirent;
117*4882a593Smuzhiyun }
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun /* The end+1 of the dir entries */
120*4882a593Smuzhiyun
dnode_end_de(struct dnode * dnode)121*4882a593Smuzhiyun static inline struct hpfs_dirent *dnode_end_de (struct dnode *dnode)
122*4882a593Smuzhiyun {
123*4882a593Smuzhiyun CHKCOND(le32_to_cpu(dnode->first_free)>=0x14 && le32_to_cpu(dnode->first_free)<=0xa00,("HPFS: dnode_end_de: dnode->first_free = %x\n",(unsigned)le32_to_cpu(dnode->first_free)));
124*4882a593Smuzhiyun return (void *) dnode + le32_to_cpu(dnode->first_free);
125*4882a593Smuzhiyun }
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun /* The dir entry after dir entry de */
128*4882a593Smuzhiyun
de_next_de(struct hpfs_dirent * de)129*4882a593Smuzhiyun static inline struct hpfs_dirent *de_next_de (struct hpfs_dirent *de)
130*4882a593Smuzhiyun {
131*4882a593Smuzhiyun CHKCOND(le16_to_cpu(de->length)>=0x20 && le16_to_cpu(de->length)<0x800,("HPFS: de_next_de: de->length = %x\n",(unsigned)le16_to_cpu(de->length)));
132*4882a593Smuzhiyun return (void *) de + le16_to_cpu(de->length);
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun
fnode_ea(struct fnode * fnode)135*4882a593Smuzhiyun static inline struct extended_attribute *fnode_ea(struct fnode *fnode)
136*4882a593Smuzhiyun {
137*4882a593Smuzhiyun return (struct extended_attribute *)((char *)fnode + le16_to_cpu(fnode->ea_offs) + le16_to_cpu(fnode->acl_size_s));
138*4882a593Smuzhiyun }
139*4882a593Smuzhiyun
fnode_end_ea(struct fnode * fnode)140*4882a593Smuzhiyun static inline struct extended_attribute *fnode_end_ea(struct fnode *fnode)
141*4882a593Smuzhiyun {
142*4882a593Smuzhiyun return (struct extended_attribute *)((char *)fnode + le16_to_cpu(fnode->ea_offs) + le16_to_cpu(fnode->acl_size_s) + le16_to_cpu(fnode->ea_size_s));
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun
ea_valuelen(struct extended_attribute * ea)145*4882a593Smuzhiyun static unsigned ea_valuelen(struct extended_attribute *ea)
146*4882a593Smuzhiyun {
147*4882a593Smuzhiyun return ea->valuelen_lo + 256 * ea->valuelen_hi;
148*4882a593Smuzhiyun }
149*4882a593Smuzhiyun
next_ea(struct extended_attribute * ea)150*4882a593Smuzhiyun static inline struct extended_attribute *next_ea(struct extended_attribute *ea)
151*4882a593Smuzhiyun {
152*4882a593Smuzhiyun return (struct extended_attribute *)((char *)ea + 5 + ea->namelen + ea_valuelen(ea));
153*4882a593Smuzhiyun }
154*4882a593Smuzhiyun
ea_sec(struct extended_attribute * ea)155*4882a593Smuzhiyun static inline secno ea_sec(struct extended_attribute *ea)
156*4882a593Smuzhiyun {
157*4882a593Smuzhiyun return le32_to_cpu(get_unaligned((__le32 *)((char *)ea + 9 + ea->namelen)));
158*4882a593Smuzhiyun }
159*4882a593Smuzhiyun
ea_len(struct extended_attribute * ea)160*4882a593Smuzhiyun static inline secno ea_len(struct extended_attribute *ea)
161*4882a593Smuzhiyun {
162*4882a593Smuzhiyun return le32_to_cpu(get_unaligned((__le32 *)((char *)ea + 5 + ea->namelen)));
163*4882a593Smuzhiyun }
164*4882a593Smuzhiyun
ea_data(struct extended_attribute * ea)165*4882a593Smuzhiyun static inline char *ea_data(struct extended_attribute *ea)
166*4882a593Smuzhiyun {
167*4882a593Smuzhiyun return (char *)((char *)ea + 5 + ea->namelen);
168*4882a593Smuzhiyun }
169*4882a593Smuzhiyun
de_size(int namelen,secno down_ptr)170*4882a593Smuzhiyun static inline unsigned de_size(int namelen, secno down_ptr)
171*4882a593Smuzhiyun {
172*4882a593Smuzhiyun return ((0x1f + namelen + 3) & ~3) + (down_ptr ? 4 : 0);
173*4882a593Smuzhiyun }
174*4882a593Smuzhiyun
copy_de(struct hpfs_dirent * dst,struct hpfs_dirent * src)175*4882a593Smuzhiyun static inline void copy_de(struct hpfs_dirent *dst, struct hpfs_dirent *src)
176*4882a593Smuzhiyun {
177*4882a593Smuzhiyun int a;
178*4882a593Smuzhiyun int n;
179*4882a593Smuzhiyun if (!dst || !src) return;
180*4882a593Smuzhiyun a = dst->down;
181*4882a593Smuzhiyun n = dst->not_8x3;
182*4882a593Smuzhiyun memcpy((char *)dst + 2, (char *)src + 2, 28);
183*4882a593Smuzhiyun dst->down = a;
184*4882a593Smuzhiyun dst->not_8x3 = n;
185*4882a593Smuzhiyun }
186*4882a593Smuzhiyun
tstbits(__le32 * bmp,unsigned b,unsigned n)187*4882a593Smuzhiyun static inline unsigned tstbits(__le32 *bmp, unsigned b, unsigned n)
188*4882a593Smuzhiyun {
189*4882a593Smuzhiyun int i;
190*4882a593Smuzhiyun if ((b >= 0x4000) || (b + n - 1 >= 0x4000)) return n;
191*4882a593Smuzhiyun if (!((le32_to_cpu(bmp[(b & 0x3fff) >> 5]) >> (b & 0x1f)) & 1)) return 1;
192*4882a593Smuzhiyun for (i = 1; i < n; i++)
193*4882a593Smuzhiyun if (!((le32_to_cpu(bmp[((b+i) & 0x3fff) >> 5]) >> ((b+i) & 0x1f)) & 1))
194*4882a593Smuzhiyun return i + 1;
195*4882a593Smuzhiyun return 0;
196*4882a593Smuzhiyun }
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun /* alloc.c */
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun int hpfs_chk_sectors(struct super_block *, secno, int, char *);
201*4882a593Smuzhiyun secno hpfs_alloc_sector(struct super_block *, secno, unsigned, int);
202*4882a593Smuzhiyun int hpfs_alloc_if_possible(struct super_block *, secno);
203*4882a593Smuzhiyun void hpfs_free_sectors(struct super_block *, secno, unsigned);
204*4882a593Smuzhiyun int hpfs_check_free_dnodes(struct super_block *, int);
205*4882a593Smuzhiyun void hpfs_free_dnode(struct super_block *, secno);
206*4882a593Smuzhiyun struct dnode *hpfs_alloc_dnode(struct super_block *, secno, dnode_secno *, struct quad_buffer_head *);
207*4882a593Smuzhiyun struct fnode *hpfs_alloc_fnode(struct super_block *, secno, fnode_secno *, struct buffer_head **);
208*4882a593Smuzhiyun struct anode *hpfs_alloc_anode(struct super_block *, secno, anode_secno *, struct buffer_head **);
209*4882a593Smuzhiyun int hpfs_trim_fs(struct super_block *, u64, u64, u64, unsigned *);
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun /* anode.c */
212*4882a593Smuzhiyun
213*4882a593Smuzhiyun secno hpfs_bplus_lookup(struct super_block *, struct inode *, struct bplus_header *, unsigned, struct buffer_head *);
214*4882a593Smuzhiyun secno hpfs_add_sector_to_btree(struct super_block *, secno, int, unsigned);
215*4882a593Smuzhiyun void hpfs_remove_btree(struct super_block *, struct bplus_header *);
216*4882a593Smuzhiyun int hpfs_ea_read(struct super_block *, secno, int, unsigned, unsigned, char *);
217*4882a593Smuzhiyun int hpfs_ea_write(struct super_block *, secno, int, unsigned, unsigned, const char *);
218*4882a593Smuzhiyun void hpfs_ea_remove(struct super_block *, secno, int, unsigned);
219*4882a593Smuzhiyun void hpfs_truncate_btree(struct super_block *, secno, int, unsigned);
220*4882a593Smuzhiyun void hpfs_remove_fnode(struct super_block *, fnode_secno fno);
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun /* buffer.c */
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun secno hpfs_search_hotfix_map(struct super_block *s, secno sec);
225*4882a593Smuzhiyun unsigned hpfs_search_hotfix_map_for_range(struct super_block *s, secno sec, unsigned n);
226*4882a593Smuzhiyun void hpfs_prefetch_sectors(struct super_block *, unsigned, int);
227*4882a593Smuzhiyun void *hpfs_map_sector(struct super_block *, unsigned, struct buffer_head **, int);
228*4882a593Smuzhiyun void *hpfs_get_sector(struct super_block *, unsigned, struct buffer_head **);
229*4882a593Smuzhiyun void *hpfs_map_4sectors(struct super_block *, unsigned, struct quad_buffer_head *, int);
230*4882a593Smuzhiyun void *hpfs_get_4sectors(struct super_block *, unsigned, struct quad_buffer_head *);
231*4882a593Smuzhiyun void hpfs_brelse4(struct quad_buffer_head *);
232*4882a593Smuzhiyun void hpfs_mark_4buffers_dirty(struct quad_buffer_head *);
233*4882a593Smuzhiyun
234*4882a593Smuzhiyun /* dentry.c */
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun extern const struct dentry_operations hpfs_dentry_operations;
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun /* dir.c */
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun struct dentry *hpfs_lookup(struct inode *, struct dentry *, unsigned int);
241*4882a593Smuzhiyun extern const struct file_operations hpfs_dir_ops;
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun /* dnode.c */
244*4882a593Smuzhiyun
245*4882a593Smuzhiyun int hpfs_add_pos(struct inode *, loff_t *);
246*4882a593Smuzhiyun void hpfs_del_pos(struct inode *, loff_t *);
247*4882a593Smuzhiyun struct hpfs_dirent *hpfs_add_de(struct super_block *, struct dnode *,
248*4882a593Smuzhiyun const unsigned char *, unsigned, secno);
249*4882a593Smuzhiyun int hpfs_add_dirent(struct inode *, const unsigned char *, unsigned,
250*4882a593Smuzhiyun struct hpfs_dirent *);
251*4882a593Smuzhiyun int hpfs_remove_dirent(struct inode *, dnode_secno, struct hpfs_dirent *, struct quad_buffer_head *, int);
252*4882a593Smuzhiyun void hpfs_count_dnodes(struct super_block *, dnode_secno, int *, int *, int *);
253*4882a593Smuzhiyun dnode_secno hpfs_de_as_down_as_possible(struct super_block *, dnode_secno dno);
254*4882a593Smuzhiyun struct hpfs_dirent *map_pos_dirent(struct inode *, loff_t *, struct quad_buffer_head *);
255*4882a593Smuzhiyun struct hpfs_dirent *map_dirent(struct inode *, dnode_secno,
256*4882a593Smuzhiyun const unsigned char *, unsigned, dnode_secno *,
257*4882a593Smuzhiyun struct quad_buffer_head *);
258*4882a593Smuzhiyun void hpfs_remove_dtree(struct super_block *, dnode_secno);
259*4882a593Smuzhiyun struct hpfs_dirent *map_fnode_dirent(struct super_block *, fnode_secno, struct fnode *, struct quad_buffer_head *);
260*4882a593Smuzhiyun
261*4882a593Smuzhiyun /* ea.c */
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun void hpfs_ea_ext_remove(struct super_block *, secno, int, unsigned);
264*4882a593Smuzhiyun int hpfs_read_ea(struct super_block *, struct fnode *, char *, char *, int);
265*4882a593Smuzhiyun char *hpfs_get_ea(struct super_block *, struct fnode *, char *, int *);
266*4882a593Smuzhiyun void hpfs_set_ea(struct inode *, struct fnode *, const char *,
267*4882a593Smuzhiyun const char *, int);
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun /* file.c */
270*4882a593Smuzhiyun
271*4882a593Smuzhiyun int hpfs_file_fsync(struct file *, loff_t, loff_t, int);
272*4882a593Smuzhiyun void hpfs_truncate(struct inode *);
273*4882a593Smuzhiyun extern const struct file_operations hpfs_file_ops;
274*4882a593Smuzhiyun extern const struct inode_operations hpfs_file_iops;
275*4882a593Smuzhiyun extern const struct address_space_operations hpfs_aops;
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun /* inode.c */
278*4882a593Smuzhiyun
279*4882a593Smuzhiyun void hpfs_init_inode(struct inode *);
280*4882a593Smuzhiyun void hpfs_read_inode(struct inode *);
281*4882a593Smuzhiyun void hpfs_write_inode(struct inode *);
282*4882a593Smuzhiyun void hpfs_write_inode_nolock(struct inode *);
283*4882a593Smuzhiyun int hpfs_setattr(struct dentry *, struct iattr *);
284*4882a593Smuzhiyun void hpfs_write_if_changed(struct inode *);
285*4882a593Smuzhiyun void hpfs_evict_inode(struct inode *);
286*4882a593Smuzhiyun
287*4882a593Smuzhiyun /* map.c */
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun __le32 *hpfs_map_dnode_bitmap(struct super_block *, struct quad_buffer_head *);
290*4882a593Smuzhiyun __le32 *hpfs_map_bitmap(struct super_block *, unsigned, struct quad_buffer_head *, char *);
291*4882a593Smuzhiyun void hpfs_prefetch_bitmap(struct super_block *, unsigned);
292*4882a593Smuzhiyun unsigned char *hpfs_load_code_page(struct super_block *, secno);
293*4882a593Smuzhiyun __le32 *hpfs_load_bitmap_directory(struct super_block *, secno bmp);
294*4882a593Smuzhiyun void hpfs_load_hotfix_map(struct super_block *s, struct hpfs_spare_block *spareblock);
295*4882a593Smuzhiyun struct fnode *hpfs_map_fnode(struct super_block *s, ino_t, struct buffer_head **);
296*4882a593Smuzhiyun struct anode *hpfs_map_anode(struct super_block *s, anode_secno, struct buffer_head **);
297*4882a593Smuzhiyun struct dnode *hpfs_map_dnode(struct super_block *s, dnode_secno, struct quad_buffer_head *);
298*4882a593Smuzhiyun dnode_secno hpfs_fnode_dno(struct super_block *s, ino_t ino);
299*4882a593Smuzhiyun
300*4882a593Smuzhiyun /* name.c */
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun unsigned char hpfs_upcase(unsigned char *, unsigned char);
303*4882a593Smuzhiyun int hpfs_chk_name(const unsigned char *, unsigned *);
304*4882a593Smuzhiyun unsigned char *hpfs_translate_name(struct super_block *, unsigned char *, unsigned, int, int);
305*4882a593Smuzhiyun int hpfs_compare_names(struct super_block *, const unsigned char *, unsigned,
306*4882a593Smuzhiyun const unsigned char *, unsigned, int);
307*4882a593Smuzhiyun int hpfs_is_name_long(const unsigned char *, unsigned);
308*4882a593Smuzhiyun void hpfs_adjust_length(const unsigned char *, unsigned *);
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun /* namei.c */
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun extern const struct inode_operations hpfs_dir_iops;
313*4882a593Smuzhiyun extern const struct address_space_operations hpfs_symlink_aops;
314*4882a593Smuzhiyun
hpfs_i(struct inode * inode)315*4882a593Smuzhiyun static inline struct hpfs_inode_info *hpfs_i(struct inode *inode)
316*4882a593Smuzhiyun {
317*4882a593Smuzhiyun return container_of(inode, struct hpfs_inode_info, vfs_inode);
318*4882a593Smuzhiyun }
319*4882a593Smuzhiyun
hpfs_sb(struct super_block * sb)320*4882a593Smuzhiyun static inline struct hpfs_sb_info *hpfs_sb(struct super_block *sb)
321*4882a593Smuzhiyun {
322*4882a593Smuzhiyun return sb->s_fs_info;
323*4882a593Smuzhiyun }
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun /* super.c */
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun __printf(2, 3)
328*4882a593Smuzhiyun void hpfs_error(struct super_block *, const char *, ...);
329*4882a593Smuzhiyun int hpfs_stop_cycles(struct super_block *, int, int *, int *, char *);
330*4882a593Smuzhiyun unsigned hpfs_get_free_dnodes(struct super_block *);
331*4882a593Smuzhiyun long hpfs_ioctl(struct file *file, unsigned cmd, unsigned long arg);
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun /*
334*4882a593Smuzhiyun * local time (HPFS) to GMT (Unix)
335*4882a593Smuzhiyun */
336*4882a593Smuzhiyun
local_to_gmt(struct super_block * s,time64_t t)337*4882a593Smuzhiyun static inline time64_t local_to_gmt(struct super_block *s, time64_t t)
338*4882a593Smuzhiyun {
339*4882a593Smuzhiyun extern struct timezone sys_tz;
340*4882a593Smuzhiyun return t + sys_tz.tz_minuteswest * 60 + hpfs_sb(s)->sb_timeshift;
341*4882a593Smuzhiyun }
342*4882a593Smuzhiyun
gmt_to_local(struct super_block * s,time64_t t)343*4882a593Smuzhiyun static inline time32_t gmt_to_local(struct super_block *s, time64_t t)
344*4882a593Smuzhiyun {
345*4882a593Smuzhiyun extern struct timezone sys_tz;
346*4882a593Smuzhiyun return t - sys_tz.tz_minuteswest * 60 - hpfs_sb(s)->sb_timeshift;
347*4882a593Smuzhiyun }
348*4882a593Smuzhiyun
local_get_seconds(struct super_block * s)349*4882a593Smuzhiyun static inline time32_t local_get_seconds(struct super_block *s)
350*4882a593Smuzhiyun {
351*4882a593Smuzhiyun return gmt_to_local(s, ktime_get_real_seconds());
352*4882a593Smuzhiyun }
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun /*
355*4882a593Smuzhiyun * Locking:
356*4882a593Smuzhiyun *
357*4882a593Smuzhiyun * hpfs_lock() locks the whole filesystem. It must be taken
358*4882a593Smuzhiyun * on any method called by the VFS.
359*4882a593Smuzhiyun *
360*4882a593Smuzhiyun * We don't do any per-file locking anymore, it is hard to
361*4882a593Smuzhiyun * review and HPFS is not performance-sensitive anyway.
362*4882a593Smuzhiyun */
hpfs_lock(struct super_block * s)363*4882a593Smuzhiyun static inline void hpfs_lock(struct super_block *s)
364*4882a593Smuzhiyun {
365*4882a593Smuzhiyun struct hpfs_sb_info *sbi = hpfs_sb(s);
366*4882a593Smuzhiyun mutex_lock(&sbi->hpfs_mutex);
367*4882a593Smuzhiyun }
368*4882a593Smuzhiyun
hpfs_unlock(struct super_block * s)369*4882a593Smuzhiyun static inline void hpfs_unlock(struct super_block *s)
370*4882a593Smuzhiyun {
371*4882a593Smuzhiyun struct hpfs_sb_info *sbi = hpfs_sb(s);
372*4882a593Smuzhiyun mutex_unlock(&sbi->hpfs_mutex);
373*4882a593Smuzhiyun }
374*4882a593Smuzhiyun
hpfs_lock_assert(struct super_block * s)375*4882a593Smuzhiyun static inline void hpfs_lock_assert(struct super_block *s)
376*4882a593Smuzhiyun {
377*4882a593Smuzhiyun struct hpfs_sb_info *sbi = hpfs_sb(s);
378*4882a593Smuzhiyun WARN_ON(!mutex_is_locked(&sbi->hpfs_mutex));
379*4882a593Smuzhiyun }
380