Blame view

fs/fat/fat.h 11.7 KB
9e975dae2   OGAWA Hirofumi   fat: split includ...
1
2
3
4
5
6
7
8
  #ifndef _FAT_H
  #define _FAT_H
  
  #include <linux/buffer_head.h>
  #include <linux/string.h>
  #include <linux/nls.h>
  #include <linux/fs.h>
  #include <linux/mutex.h>
aaa04b487   OGAWA Hirofumi   fatfs: ratelimit ...
9
  #include <linux/ratelimit.h>
9e975dae2   OGAWA Hirofumi   fat: split includ...
10
11
12
13
14
15
16
17
18
19
  #include <linux/msdos_fs.h>
  
  /*
   * vfat shortname flags
   */
  #define VFAT_SFN_DISPLAY_LOWER	0x0001 /* convert to lowercase for display */
  #define VFAT_SFN_DISPLAY_WIN95	0x0002 /* emulate win95 rule for display */
  #define VFAT_SFN_DISPLAY_WINNT	0x0004 /* emulate winnt rule for display */
  #define VFAT_SFN_CREATE_WIN95	0x0100 /* emulate win95 rule for create */
  #define VFAT_SFN_CREATE_WINNT	0x0200 /* emulate winnt rule for create */
85c785919   Denis Karpov   FAT: add 'errors'...
20
21
22
  #define FAT_ERRORS_CONT		1      /* ignore error and continue */
  #define FAT_ERRORS_PANIC	2      /* panic on error */
  #define FAT_ERRORS_RO		3      /* remount r/o on error */
9e975dae2   OGAWA Hirofumi   fat: split includ...
23
24
25
26
27
28
29
30
31
  struct fat_mount_options {
  	uid_t fs_uid;
  	gid_t fs_gid;
  	unsigned short fs_fmask;
  	unsigned short fs_dmask;
  	unsigned short codepage;  /* Codepage for shortname conversions */
  	char *iocharset;          /* Charset used for filename input/display */
  	unsigned short shortname; /* flags for shortname display/create rule */
  	unsigned char name_check; /* r = relaxed, n = normal, s = strict */
85c785919   Denis Karpov   FAT: add 'errors'...
32
  	unsigned char errors;	  /* On error: continue, panic, remount-ro */
9e975dae2   OGAWA Hirofumi   fat: split includ...
33
34
35
36
37
38
39
40
41
42
43
44
  	unsigned short allow_utime;/* permission for setting the [am]time */
  	unsigned quiet:1,         /* set = fake successful chmods and chowns */
  		 showexec:1,      /* set = only set x bit for com/exe/bat */
  		 sys_immutable:1, /* set = system files are immutable */
  		 dotsOK:1,        /* set = hidden and system files are named '.filename' */
  		 isvfat:1,        /* 0=no vfat long filename support, 1=vfat support */
  		 utf8:1,	  /* Use of UTF-8 character set (Default) */
  		 unicode_xlate:1, /* create escape sequences for unhandled Unicode */
  		 numtail:1,       /* Does first alias have a numeric '~1' type tail? */
  		 flush:1,	  /* write things quickly */
  		 nocase:1,	  /* Does this need case conversion? 0=need case conversion*/
  		 usefree:1,	  /* Use free_clusters for FAT32 */
dfc209c00   OGAWA Hirofumi   fat: Fix ATTR_RO ...
45
  		 tz_utc:1,	  /* Filesystem timestamps are in UTC */
681142f92   Christoph Hellwig   fat: make discard...
46
47
  		 rodir:1,	  /* allow ATTR_RO for directory */
  		 discard:1;	  /* Issue discard requests on deletions */
9e975dae2   OGAWA Hirofumi   fat: split includ...
48
49
50
51
  };
  
  #define FAT_HASH_BITS	8
  #define FAT_HASH_SIZE	(1UL << FAT_HASH_BITS)
9e975dae2   OGAWA Hirofumi   fat: split includ...
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
  
  /*
   * MS-DOS file system in-core superblock data
   */
  struct msdos_sb_info {
  	unsigned short sec_per_clus; /* sectors/cluster */
  	unsigned short cluster_bits; /* log2(cluster_size) */
  	unsigned int cluster_size;   /* cluster size */
  	unsigned char fats,fat_bits; /* number of FATs, FAT bits (12 or 16) */
  	unsigned short fat_start;
  	unsigned long fat_length;    /* FAT start & length (sec.) */
  	unsigned long dir_start;
  	unsigned short dir_entries;  /* root dir start & entries */
  	unsigned long data_start;    /* first data sector */
  	unsigned long max_cluster;   /* maximum cluster number */
  	unsigned long root_cluster;  /* first cluster of the root directory */
  	unsigned long fsinfo_sector; /* sector number of FAT32 fsinfo */
  	struct mutex fat_lock;
  	unsigned int prev_free;      /* previously allocated cluster number */
  	unsigned int free_clusters;  /* -1 if undefined */
  	unsigned int free_clus_valid; /* is free_clusters valid? */
  	struct fat_mount_options options;
  	struct nls_table *nls_disk;  /* Codepage used on disk */
  	struct nls_table *nls_io;    /* Charset used for input and display */
  	const void *dir_ops;		     /* Opaque; default directory operations */
  	int dir_per_block;	     /* dir entries per block */
  	int dir_per_block_bits;	     /* log2(dir_per_block) */
  
  	int fatent_shift;
  	struct fatent_operations *fatent_ops;
b522412ae   Al Viro   Sanitize ->fsync(...
82
  	struct inode *fat_inode;
9e975dae2   OGAWA Hirofumi   fat: split includ...
83

aaa04b487   OGAWA Hirofumi   fatfs: ratelimit ...
84
  	struct ratelimit_state ratelimit;
9e975dae2   OGAWA Hirofumi   fat: split includ...
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
  	spinlock_t inode_hash_lock;
  	struct hlist_head inode_hashtable[FAT_HASH_SIZE];
  };
  
  #define FAT_CACHE_VALID	0	/* special case for valid cache */
  
  /*
   * MS-DOS file system inode data in memory
   */
  struct msdos_inode_info {
  	spinlock_t cache_lru_lock;
  	struct list_head cache_lru;
  	int nr_caches;
  	/* for avoiding the race between fat_free() and fat_get_cluster() */
  	unsigned int cache_valid_id;
2bdf67eb1   OGAWA Hirofumi   fat: mmu_private ...
100
101
  	/* NOTE: mmu_private is 64bits, so must hold ->i_mutex to access */
  	loff_t mmu_private;	/* physically allocated size */
9e975dae2   OGAWA Hirofumi   fat: split includ...
102
103
104
105
106
  	int i_start;		/* first cluster or 0 */
  	int i_logstart;		/* logical first cluster */
  	int i_attrs;		/* unused attribute bits */
  	loff_t i_pos;		/* on-disk position of directory entry or 0 */
  	struct hlist_node i_fat_hash;	/* hash by i_location */
582686915   Christoph Hellwig   fat: remove i_all...
107
  	struct rw_semaphore truncate_lock; /* protect bmap against truncate */
9e975dae2   OGAWA Hirofumi   fat: split includ...
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
  	struct inode vfs_inode;
  };
  
  struct fat_slot_info {
  	loff_t i_pos;		/* on-disk position of directory entry */
  	loff_t slot_off;	/* offset for slot or de start */
  	int nr_slots;		/* number of slots + 1(de) in filename */
  	struct msdos_dir_entry *de;
  	struct buffer_head *bh;
  };
  
  static inline struct msdos_sb_info *MSDOS_SB(struct super_block *sb)
  {
  	return sb->s_fs_info;
  }
  
  static inline struct msdos_inode_info *MSDOS_I(struct inode *inode)
  {
  	return container_of(inode, struct msdos_inode_info, vfs_inode);
  }
9183482f5   OGAWA Hirofumi   fat: Fix ATTR_RO ...
128
129
130
  /*
   * If ->i_mode can't hold S_IWUGO (i.e. ATTR_RO), we use ->i_attrs to
   * save ATTR_RO instead of ->i_mode.
dfc209c00   OGAWA Hirofumi   fat: Fix ATTR_RO ...
131
132
133
   *
   * If it's directory and !sbi->options.rodir, ATTR_RO isn't read-only
   * bit, it's just used as flag for app.
9183482f5   OGAWA Hirofumi   fat: Fix ATTR_RO ...
134
135
136
137
   */
  static inline int fat_mode_can_hold_ro(struct inode *inode)
  {
  	struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
dacd0e7b3   Al Viro   fat: propagate um...
138
  	umode_t mask;
9183482f5   OGAWA Hirofumi   fat: Fix ATTR_RO ...
139

dfc209c00   OGAWA Hirofumi   fat: Fix ATTR_RO ...
140
141
142
  	if (S_ISDIR(inode->i_mode)) {
  		if (!sbi->options.rodir)
  			return 0;
9183482f5   OGAWA Hirofumi   fat: Fix ATTR_RO ...
143
  		mask = ~sbi->options.fs_dmask;
dfc209c00   OGAWA Hirofumi   fat: Fix ATTR_RO ...
144
  	} else
9183482f5   OGAWA Hirofumi   fat: Fix ATTR_RO ...
145
146
147
148
149
150
  		mask = ~sbi->options.fs_fmask;
  
  	if (!(mask & S_IWUGO))
  		return 0;
  	return 1;
  }
9c0aa1b87   OGAWA Hirofumi   fat: Cleanup FAT ...
151
  /* Convert attribute bits and a mask to the UNIX mode. */
dacd0e7b3   Al Viro   fat: propagate um...
152
153
  static inline umode_t fat_make_mode(struct msdos_sb_info *sbi,
  				   u8 attrs, umode_t mode)
9c0aa1b87   OGAWA Hirofumi   fat: Cleanup FAT ...
154
  {
dfc209c00   OGAWA Hirofumi   fat: Fix ATTR_RO ...
155
  	if (attrs & ATTR_RO && !((attrs & ATTR_DIR) && !sbi->options.rodir))
9c0aa1b87   OGAWA Hirofumi   fat: Cleanup FAT ...
156
157
158
159
160
161
162
  		mode &= ~S_IWUGO;
  
  	if (attrs & ATTR_DIR)
  		return (mode & ~sbi->options.fs_dmask) | S_IFDIR;
  	else
  		return (mode & ~sbi->options.fs_fmask) | S_IFREG;
  }
9e975dae2   OGAWA Hirofumi   fat: split includ...
163
  /* Return the FAT attribute byte for this inode */
9c0aa1b87   OGAWA Hirofumi   fat: Cleanup FAT ...
164
  static inline u8 fat_make_attrs(struct inode *inode)
9e975dae2   OGAWA Hirofumi   fat: split includ...
165
  {
9183482f5   OGAWA Hirofumi   fat: Fix ATTR_RO ...
166
167
168
169
170
171
  	u8 attrs = MSDOS_I(inode)->i_attrs;
  	if (S_ISDIR(inode->i_mode))
  		attrs |= ATTR_DIR;
  	if (fat_mode_can_hold_ro(inode) && !(inode->i_mode & S_IWUGO))
  		attrs |= ATTR_RO;
  	return attrs;
9e975dae2   OGAWA Hirofumi   fat: split includ...
172
  }
9c0aa1b87   OGAWA Hirofumi   fat: Cleanup FAT ...
173
174
  static inline void fat_save_attrs(struct inode *inode, u8 attrs)
  {
9183482f5   OGAWA Hirofumi   fat: Fix ATTR_RO ...
175
176
177
178
  	if (fat_mode_can_hold_ro(inode))
  		MSDOS_I(inode)->i_attrs = attrs & ATTR_UNUSED;
  	else
  		MSDOS_I(inode)->i_attrs = attrs & (ATTR_UNUSED | ATTR_RO);
9c0aa1b87   OGAWA Hirofumi   fat: Cleanup FAT ...
179
  }
9e975dae2   OGAWA Hirofumi   fat: split includ...
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
  static inline unsigned char fat_checksum(const __u8 *name)
  {
  	unsigned char s = name[0];
  	s = (s<<7) + (s>>1) + name[1];	s = (s<<7) + (s>>1) + name[2];
  	s = (s<<7) + (s>>1) + name[3];	s = (s<<7) + (s>>1) + name[4];
  	s = (s<<7) + (s>>1) + name[5];	s = (s<<7) + (s>>1) + name[6];
  	s = (s<<7) + (s>>1) + name[7];	s = (s<<7) + (s>>1) + name[8];
  	s = (s<<7) + (s>>1) + name[9];	s = (s<<7) + (s>>1) + name[10];
  	return s;
  }
  
  static inline sector_t fat_clus_to_blknr(struct msdos_sb_info *sbi, int clus)
  {
  	return ((sector_t)clus - FAT_START_ENT) * sbi->sec_per_clus
  		+ sbi->data_start;
  }
  
  static inline void fat16_towchar(wchar_t *dst, const __u8 *src, size_t len)
  {
  #ifdef __BIG_ENDIAN
  	while (len--) {
  		*dst++ = src[0] | (src[1] << 8);
  		src += 2;
  	}
  #else
  	memcpy(dst, src, len * 2);
  #endif
  }
  
  static inline void fatwchar_to16(__u8 *dst, const wchar_t *src, size_t len)
  {
  #ifdef __BIG_ENDIAN
  	while (len--) {
  		dst[0] = *src & 0x00FF;
  		dst[1] = (*src & 0xFF00) >> 8;
  		dst += 2;
  		src++;
  	}
  #else
  	memcpy(dst, src, len * 2);
  #endif
  }
  
  /* fat/cache.c */
  extern void fat_cache_inval_inode(struct inode *inode);
  extern int fat_get_cluster(struct inode *inode, int cluster,
  			   int *fclus, int *dclus);
  extern int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys,
2bdf67eb1   OGAWA Hirofumi   fat: mmu_private ...
228
  		    unsigned long *mapped_blocks, int create);
9e975dae2   OGAWA Hirofumi   fat: split includ...
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
  
  /* fat/dir.c */
  extern const struct file_operations fat_dir_operations;
  extern int fat_search_long(struct inode *inode, const unsigned char *name,
  			   int name_len, struct fat_slot_info *sinfo);
  extern int fat_dir_empty(struct inode *dir);
  extern int fat_subdirs(struct inode *dir);
  extern int fat_scan(struct inode *dir, const unsigned char *name,
  		    struct fat_slot_info *sinfo);
  extern int fat_get_dotdot_entry(struct inode *dir, struct buffer_head **bh,
  				struct msdos_dir_entry **de, loff_t *i_pos);
  extern int fat_alloc_new_dir(struct inode *dir, struct timespec *ts);
  extern int fat_add_entries(struct inode *dir, void *slots, int nr_slots,
  			   struct fat_slot_info *sinfo);
  extern int fat_remove_entries(struct inode *dir, struct fat_slot_info *sinfo);
  
  /* fat/fatent.c */
  struct fat_entry {
  	int entry;
  	union {
  		u8 *ent12_p[2];
  		__le16 *ent16_p;
  		__le32 *ent32_p;
  	} u;
  	int nr_bhs;
  	struct buffer_head *bhs[2];
b522412ae   Al Viro   Sanitize ->fsync(...
255
  	struct inode *fat_inode;
9e975dae2   OGAWA Hirofumi   fat: split includ...
256
257
258
259
260
261
262
263
  };
  
  static inline void fatent_init(struct fat_entry *fatent)
  {
  	fatent->nr_bhs = 0;
  	fatent->entry = 0;
  	fatent->u.ent32_p = NULL;
  	fatent->bhs[0] = fatent->bhs[1] = NULL;
b522412ae   Al Viro   Sanitize ->fsync(...
264
  	fatent->fat_inode = NULL;
9e975dae2   OGAWA Hirofumi   fat: split includ...
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
  }
  
  static inline void fatent_set_entry(struct fat_entry *fatent, int entry)
  {
  	fatent->entry = entry;
  	fatent->u.ent32_p = NULL;
  }
  
  static inline void fatent_brelse(struct fat_entry *fatent)
  {
  	int i;
  	fatent->u.ent32_p = NULL;
  	for (i = 0; i < fatent->nr_bhs; i++)
  		brelse(fatent->bhs[i]);
  	fatent->nr_bhs = 0;
  	fatent->bhs[0] = fatent->bhs[1] = NULL;
b522412ae   Al Viro   Sanitize ->fsync(...
281
  	fatent->fat_inode = NULL;
9e975dae2   OGAWA Hirofumi   fat: split includ...
282
283
284
285
286
287
288
289
290
291
292
293
294
  }
  
  extern void fat_ent_access_init(struct super_block *sb);
  extern int fat_ent_read(struct inode *inode, struct fat_entry *fatent,
  			int entry);
  extern int fat_ent_write(struct inode *inode, struct fat_entry *fatent,
  			 int new, int wait);
  extern int fat_alloc_clusters(struct inode *inode, int *cluster,
  			      int nr_cluster);
  extern int fat_free_clusters(struct inode *inode, int cluster);
  extern int fat_count_free_clusters(struct super_block *sb);
  
  /* fat/file.c */
7845bc3e1   Arnd Bergmann   fat: convert to u...
295
296
  extern long fat_generic_ioctl(struct file *filp, unsigned int cmd,
  			      unsigned long arg);
9e975dae2   OGAWA Hirofumi   fat: split includ...
297
298
299
  extern const struct file_operations fat_file_operations;
  extern const struct inode_operations fat_file_inode_operations;
  extern int fat_setattr(struct dentry * dentry, struct iattr * attr);
459f6ed3b   npiggin@suse.de   fat: convert to u...
300
  extern void fat_truncate_blocks(struct inode *inode, loff_t offset);
9e975dae2   OGAWA Hirofumi   fat: split includ...
301
302
  extern int fat_getattr(struct vfsmount *mnt, struct dentry *dentry,
  		       struct kstat *stat);
02c24a821   Josef Bacik   fs: push i_mutex ...
303
304
  extern int fat_file_fsync(struct file *file, loff_t start, loff_t end,
  			  int datasync);
9e975dae2   OGAWA Hirofumi   fat: split includ...
305
306
307
308
309
310
311
312
313
  
  /* fat/inode.c */
  extern void fat_attach(struct inode *inode, loff_t i_pos);
  extern void fat_detach(struct inode *inode);
  extern struct inode *fat_iget(struct super_block *sb, loff_t i_pos);
  extern struct inode *fat_build_inode(struct super_block *sb,
  			struct msdos_dir_entry *de, loff_t i_pos);
  extern int fat_sync_inode(struct inode *inode);
  extern int fat_fill_super(struct super_block *sb, void *data, int silent,
384f5c96e   OGAWA Hirofumi   fat: use new setu...
314
  			  int isvfat, void (*setup)(struct super_block *));
9e975dae2   OGAWA Hirofumi   fat: split includ...
315
316
317
318
  
  extern int fat_flush_inodes(struct super_block *sb, struct inode *i1,
  		            struct inode *i2);
  /* fat/misc.c */
b9075fa96   Joe Perches   treewide: use __p...
319
320
  extern __printf(3, 4) __cold
  void __fat_fs_error(struct super_block *sb, int report, const char *fmt, ...);
2c8a5ffb9   Alexey Fisher   fat: Convert fat_...
321
322
323
324
  #define fat_fs_error(sb, fmt, args...)		\
  	__fat_fs_error(sb, 1, fmt , ## args)
  #define fat_fs_error_ratelimit(sb, fmt, args...) \
  	__fat_fs_error(sb, __ratelimit(&MSDOS_SB(sb)->ratelimit), fmt , ## args)
b9075fa96   Joe Perches   treewide: use __p...
325
326
  __printf(3, 4) __cold
  void fat_msg(struct super_block *sb, const char *level, const char *fmt, ...);
ed248b290   OGAWA Hirofumi   fat: Check s_dirt...
327
  extern int fat_clusters_flush(struct super_block *sb);
9e975dae2   OGAWA Hirofumi   fat: split includ...
328
  extern int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster);
7decd1cb0   OGAWA Hirofumi   fat: Fix and clea...
329
330
331
332
  extern void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec *ts,
  			      __le16 __time, __le16 __date, u8 time_cs);
  extern void fat_time_unix2fat(struct msdos_sb_info *sbi, struct timespec *ts,
  			      __le16 *time, __le16 *date, u8 *time_cs);
9e975dae2   OGAWA Hirofumi   fat: split includ...
333
334
335
336
  extern int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs);
  
  int fat_cache_init(void);
  void fat_cache_destroy(void);
c3302931d   OGAWA Hirofumi   fat: i_blocks war...
337
338
  /* helper for printk */
  typedef unsigned long long	llu;
9e975dae2   OGAWA Hirofumi   fat: split includ...
339
  #endif /* !_FAT_H */