aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fat/fat.h
diff options
context:
space:
mode:
authorSteven J. Magnani <steve@digidescorp.com>2012-10-04 20:14:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-05 14:05:09 -0400
commit7669e8fb09da47dd45c07a51394f01031ea81da8 (patch)
tree1112667a0606e27999a18b8dae574ae8ad01a151 /fs/fat/fat.h
parent21b6633d516c4f5d03ec02ede6374e320191003f (diff)
fat (exportfs): fix dentry reconnection
Maintain an index of directory inodes by starting cluster, so that fat_get_parent() can return the proper cached inode rather than inventing one that cannot be traced back to the filesystem root. Add a new msdos/vfat binary mount option "nfs" so that FAT filesystems that are _not_ exported via NFS are not saddled with maintenance of an index they will never use. Finally, simplify NFS file handle generation and lookups. An ext2-congruent implementation is adequate for FAT needs. Signed-off-by: Steven J. Magnani <steve@digidescorp.com> Acked-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/fat/fat.h')
-rw-r--r--fs/fat/fat.h27
1 files changed, 12 insertions, 15 deletions
diff --git a/fs/fat/fat.h b/fs/fat/fat.h
index fb95939ff870..ec54c3a7f2f7 100644
--- a/fs/fat/fat.h
+++ b/fs/fat/fat.h
@@ -5,6 +5,7 @@
5#include <linux/string.h> 5#include <linux/string.h>
6#include <linux/nls.h> 6#include <linux/nls.h>
7#include <linux/fs.h> 7#include <linux/fs.h>
8#include <linux/hash.h>
8#include <linux/mutex.h> 9#include <linux/mutex.h>
9#include <linux/ratelimit.h> 10#include <linux/ratelimit.h>
10#include <linux/msdos_fs.h> 11#include <linux/msdos_fs.h>
@@ -46,7 +47,8 @@ struct fat_mount_options {
46 usefree:1, /* Use free_clusters for FAT32 */ 47 usefree:1, /* Use free_clusters for FAT32 */
47 tz_utc:1, /* Filesystem timestamps are in UTC */ 48 tz_utc:1, /* Filesystem timestamps are in UTC */
48 rodir:1, /* allow ATTR_RO for directory */ 49 rodir:1, /* allow ATTR_RO for directory */
49 discard:1; /* Issue discard requests on deletions */ 50 discard:1, /* Issue discard requests on deletions */
51 nfs:1; /* Do extra work needed for NFS export */
50}; 52};
51 53
52#define FAT_HASH_BITS 8 54#define FAT_HASH_BITS 8
@@ -88,6 +90,9 @@ struct msdos_sb_info {
88 90
89 spinlock_t inode_hash_lock; 91 spinlock_t inode_hash_lock;
90 struct hlist_head inode_hashtable[FAT_HASH_SIZE]; 92 struct hlist_head inode_hashtable[FAT_HASH_SIZE];
93
94 spinlock_t dir_hash_lock;
95 struct hlist_head dir_hashtable[FAT_HASH_SIZE];
91}; 96};
92 97
93#define FAT_CACHE_VALID 0 /* special case for valid cache */ 98#define FAT_CACHE_VALID 0 /* special case for valid cache */
@@ -110,6 +115,7 @@ struct msdos_inode_info {
110 int i_attrs; /* unused attribute bits */ 115 int i_attrs; /* unused attribute bits */
111 loff_t i_pos; /* on-disk position of directory entry or 0 */ 116 loff_t i_pos; /* on-disk position of directory entry or 0 */
112 struct hlist_node i_fat_hash; /* hash by i_location */ 117 struct hlist_node i_fat_hash; /* hash by i_location */
118 struct hlist_node i_dir_hash; /* hash by i_logstart */
113 struct rw_semaphore truncate_lock; /* protect bmap against truncate */ 119 struct rw_semaphore truncate_lock; /* protect bmap against truncate */
114 struct inode vfs_inode; 120 struct inode vfs_inode;
115}; 121};
@@ -262,7 +268,7 @@ extern int fat_subdirs(struct inode *dir);
262extern int fat_scan(struct inode *dir, const unsigned char *name, 268extern int fat_scan(struct inode *dir, const unsigned char *name,
263 struct fat_slot_info *sinfo); 269 struct fat_slot_info *sinfo);
264extern int fat_get_dotdot_entry(struct inode *dir, struct buffer_head **bh, 270extern int fat_get_dotdot_entry(struct inode *dir, struct buffer_head **bh,
265 struct msdos_dir_entry **de, loff_t *i_pos); 271 struct msdos_dir_entry **de);
266extern int fat_alloc_new_dir(struct inode *dir, struct timespec *ts); 272extern int fat_alloc_new_dir(struct inode *dir, struct timespec *ts);
267extern int fat_add_entries(struct inode *dir, void *slots, int nr_slots, 273extern int fat_add_entries(struct inode *dir, void *slots, int nr_slots,
268 struct fat_slot_info *sinfo); 274 struct fat_slot_info *sinfo);
@@ -341,18 +347,9 @@ extern int fat_fill_super(struct super_block *sb, void *data, int silent,
341 347
342extern int fat_flush_inodes(struct super_block *sb, struct inode *i1, 348extern int fat_flush_inodes(struct super_block *sb, struct inode *i1,
343 struct inode *i2); 349 struct inode *i2);
344static inline loff_t fat_i_pos_read(struct msdos_sb_info *sbi, 350static inline unsigned long fat_dir_hash(int logstart)
345 struct inode *inode)
346{ 351{
347 loff_t i_pos; 352 return hash_32(logstart, FAT_HASH_BITS);
348#if BITS_PER_LONG == 32
349 spin_lock(&sbi->inode_hash_lock);
350#endif
351 i_pos = MSDOS_I(inode)->i_pos;
352#if BITS_PER_LONG == 32
353 spin_unlock(&sbi->inode_hash_lock);
354#endif
355 return i_pos;
356} 353}
357 354
358/* fat/misc.c */ 355/* fat/misc.c */
@@ -382,10 +379,10 @@ void fat_cache_destroy(void);
382 379
383/* fat/nfs.c */ 380/* fat/nfs.c */
384struct fid; 381struct fid;
385extern int fat_encode_fh(struct inode *inode, __u32 *fh, int *lenp,
386 struct inode *parent);
387extern struct dentry *fat_fh_to_dentry(struct super_block *sb, struct fid *fid, 382extern struct dentry *fat_fh_to_dentry(struct super_block *sb, struct fid *fid,
388 int fh_len, int fh_type); 383 int fh_len, int fh_type);
384extern struct dentry *fat_fh_to_parent(struct super_block *sb, struct fid *fid,
385 int fh_len, int fh_type);
389extern struct dentry *fat_get_parent(struct dentry *child_dir); 386extern struct dentry *fat_get_parent(struct dentry *child_dir);
390 387
391/* helper for printk */ 388/* helper for printk */