summaryrefslogtreecommitdiffstats
path: root/fs/fat/fat.h
diff options
context:
space:
mode:
authorSteven J. Magnani <steve@digidescorp.com>2012-10-04 17:14:45 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-06 03:05:09 +0900
commit7669e8fb09da47dd45c07a51394f01031ea81da8 (patch)
tree1112667a0606e27999a18b8dae574ae8ad01a151 /fs/fat/fat.h
parent21b6633d516c4f5d03ec02ede6374e320191003f (diff)
downloadop-kernel-dev-7669e8fb09da47dd45c07a51394f01031ea81da8.zip
op-kernel-dev-7669e8fb09da47dd45c07a51394f01031ea81da8.tar.gz
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 fb95939..ec54c3a 100644
--- a/fs/fat/fat.h
+++ b/fs/fat/fat.h
@@ -5,6 +5,7 @@
#include <linux/string.h>
#include <linux/nls.h>
#include <linux/fs.h>
+#include <linux/hash.h>
#include <linux/mutex.h>
#include <linux/ratelimit.h>
#include <linux/msdos_fs.h>
@@ -46,7 +47,8 @@ struct fat_mount_options {
usefree:1, /* Use free_clusters for FAT32 */
tz_utc:1, /* Filesystem timestamps are in UTC */
rodir:1, /* allow ATTR_RO for directory */
- discard:1; /* Issue discard requests on deletions */
+ discard:1, /* Issue discard requests on deletions */
+ nfs:1; /* Do extra work needed for NFS export */
};
#define FAT_HASH_BITS 8
@@ -88,6 +90,9 @@ struct msdos_sb_info {
spinlock_t inode_hash_lock;
struct hlist_head inode_hashtable[FAT_HASH_SIZE];
+
+ spinlock_t dir_hash_lock;
+ struct hlist_head dir_hashtable[FAT_HASH_SIZE];
};
#define FAT_CACHE_VALID 0 /* special case for valid cache */
@@ -110,6 +115,7 @@ struct msdos_inode_info {
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 */
+ struct hlist_node i_dir_hash; /* hash by i_logstart */
struct rw_semaphore truncate_lock; /* protect bmap against truncate */
struct inode vfs_inode;
};
@@ -262,7 +268,7 @@ 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);
+ struct msdos_dir_entry **de);
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);
@@ -341,18 +347,9 @@ extern int fat_fill_super(struct super_block *sb, void *data, int silent,
extern int fat_flush_inodes(struct super_block *sb, struct inode *i1,
struct inode *i2);
-static inline loff_t fat_i_pos_read(struct msdos_sb_info *sbi,
- struct inode *inode)
+static inline unsigned long fat_dir_hash(int logstart)
{
- loff_t i_pos;
-#if BITS_PER_LONG == 32
- spin_lock(&sbi->inode_hash_lock);
-#endif
- i_pos = MSDOS_I(inode)->i_pos;
-#if BITS_PER_LONG == 32
- spin_unlock(&sbi->inode_hash_lock);
-#endif
- return i_pos;
+ return hash_32(logstart, FAT_HASH_BITS);
}
/* fat/misc.c */
@@ -382,10 +379,10 @@ void fat_cache_destroy(void);
/* fat/nfs.c */
struct fid;
-extern int fat_encode_fh(struct inode *inode, __u32 *fh, int *lenp,
- struct inode *parent);
extern struct dentry *fat_fh_to_dentry(struct super_block *sb, struct fid *fid,
int fh_len, int fh_type);
+extern struct dentry *fat_fh_to_parent(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type);
extern struct dentry *fat_get_parent(struct dentry *child_dir);
/* helper for printk */
OpenPOWER on IntegriCloud