|
@@ -443,12 +443,25 @@ static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static inline void fat_lock_build_inode(struct msdos_sb_info *sbi)
|
|
|
|
+{
|
|
|
|
+ if (sbi->options.nfs == FAT_NFS_NOSTALE_RO)
|
|
|
|
+ mutex_lock(&sbi->nfs_build_inode_lock);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline void fat_unlock_build_inode(struct msdos_sb_info *sbi)
|
|
|
|
+{
|
|
|
|
+ if (sbi->options.nfs == FAT_NFS_NOSTALE_RO)
|
|
|
|
+ mutex_unlock(&sbi->nfs_build_inode_lock);
|
|
|
|
+}
|
|
|
|
+
|
|
struct inode *fat_build_inode(struct super_block *sb,
|
|
struct inode *fat_build_inode(struct super_block *sb,
|
|
struct msdos_dir_entry *de, loff_t i_pos)
|
|
struct msdos_dir_entry *de, loff_t i_pos)
|
|
{
|
|
{
|
|
struct inode *inode;
|
|
struct inode *inode;
|
|
int err;
|
|
int err;
|
|
|
|
|
|
|
|
+ fat_lock_build_inode(MSDOS_SB(sb));
|
|
inode = fat_iget(sb, i_pos);
|
|
inode = fat_iget(sb, i_pos);
|
|
if (inode)
|
|
if (inode)
|
|
goto out;
|
|
goto out;
|
|
@@ -468,6 +481,7 @@ struct inode *fat_build_inode(struct super_block *sb,
|
|
fat_attach(inode, i_pos);
|
|
fat_attach(inode, i_pos);
|
|
insert_inode_hash(inode);
|
|
insert_inode_hash(inode);
|
|
out:
|
|
out:
|
|
|
|
+ fat_unlock_build_inode(MSDOS_SB(sb));
|
|
return inode;
|
|
return inode;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1247,6 +1261,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
|
|
sb->s_magic = MSDOS_SUPER_MAGIC;
|
|
sb->s_magic = MSDOS_SUPER_MAGIC;
|
|
sb->s_op = &fat_sops;
|
|
sb->s_op = &fat_sops;
|
|
sb->s_export_op = &fat_export_ops;
|
|
sb->s_export_op = &fat_export_ops;
|
|
|
|
+ mutex_init(&sbi->nfs_build_inode_lock);
|
|
ratelimit_state_init(&sbi->ratelimit, DEFAULT_RATELIMIT_INTERVAL,
|
|
ratelimit_state_init(&sbi->ratelimit, DEFAULT_RATELIMIT_INTERVAL,
|
|
DEFAULT_RATELIMIT_BURST);
|
|
DEFAULT_RATELIMIT_BURST);
|
|
|
|
|