summaryrefslogtreecommitdiffstats
path: root/fs/fat/fat.h
diff options
context:
space:
mode:
authorSteven J. Magnani <steve@digidescorp.com>2012-10-04 20:14:44 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-05 14:05:09 -0400
commit21b6633d516c4f5d03ec02ede6374e320191003f (patch)
tree1117879875a138230c3fb2dea435026012270141 /fs/fat/fat.h
parent4b63709861e431e73f0be6b83f420fdd8fc518f5 (diff)
fat (exportfs): move NFS support code
Under memory pressure, the system may evict dentries from cache. When the FAT driver receives a NFS request involving an evicted dentry, it is unable to reconnect it to the filesystem root. This causes the request to fail, often with ENOENT. This is partially due to ineffectiveness of the current FAT NFS implementation, and partially due to an unimplemented fh_to_parent method. The latter can cause file accesses to fail on shares exported with subtree_check. This patch set provides the FAT driver with the ability to reconnect dentries. NFS file handle generation and lookups are simplified and made congruent with ext2. Testing has involved a memory-starved virtual machine running 3.5-rc5 that exports a ~2 GB vfat filesystem containing a kernel tree (~770 MB, ~40000 files, 9 levels). Both 'cp -r' and 'ls -lR' operations were performed from a client, some overlapping, some consecutive. Exports with 'subtree_check' and 'no_subtree_check' have been tested. Note that while this patch set improves FAT's NFS support, it does not eliminate ESTALE errors completely. The following should be considered for NFS clients who are sensitive to ESTALE: * Mounting with lookupcache=none Unfortunately this can degrade performance severely, particularly for deep filesystems. * Incorporating VFS patches to retry ESTALE failures on the client-side, such as https://lkml.org/lkml/2012/6/29/381 * Handling ESTALE errors in client application code This patch: Move NFS-related code into its own C file. No functional changes. 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.h22
1 files changed, 22 insertions, 0 deletions
diff --git a/fs/fat/fat.h b/fs/fat/fat.h
index 7d8e0dcac5d5..fb95939ff870 100644
--- a/fs/fat/fat.h
+++ b/fs/fat/fat.h
@@ -341,6 +341,20 @@ extern int fat_fill_super(struct super_block *sb, void *data, int silent,
341 341
342extern int fat_flush_inodes(struct super_block *sb, struct inode *i1, 342extern int fat_flush_inodes(struct super_block *sb, struct inode *i1,
343 struct inode *i2); 343 struct inode *i2);
344static inline loff_t fat_i_pos_read(struct msdos_sb_info *sbi,
345 struct inode *inode)
346{
347 loff_t i_pos;
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}
357
344/* fat/misc.c */ 358/* fat/misc.c */
345extern __printf(3, 4) __cold 359extern __printf(3, 4) __cold
346void __fat_fs_error(struct super_block *sb, int report, const char *fmt, ...); 360void __fat_fs_error(struct super_block *sb, int report, const char *fmt, ...);
@@ -366,6 +380,14 @@ extern int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs);
366int fat_cache_init(void); 380int fat_cache_init(void);
367void fat_cache_destroy(void); 381void fat_cache_destroy(void);
368 382
383/* fat/nfs.c */
384struct 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,
388 int fh_len, int fh_type);
389extern struct dentry *fat_get_parent(struct dentry *child_dir);
390
369/* helper for printk */ 391/* helper for printk */
370typedef unsigned long long llu; 392typedef unsigned long long llu;
371 393