提交 3d23985d 编写于 作者: A Al Viro

switch fat to ->s_d_op, close exportfs races there

don't bother with lock_super() in fat_fill_super() callers, while
we are at it - there won't be any concurrency anyway.
Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
上级 6cc9c1d2
...@@ -319,7 +319,8 @@ extern struct inode *fat_build_inode(struct super_block *sb, ...@@ -319,7 +319,8 @@ extern 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);
extern int fat_sync_inode(struct inode *inode); extern int fat_sync_inode(struct inode *inode);
extern int fat_fill_super(struct super_block *sb, void *data, int silent, extern int fat_fill_super(struct super_block *sb, void *data, int silent,
const struct inode_operations *fs_dir_inode_ops, int isvfat); const struct inode_operations *fs_dir_inode_ops,
int isvfat, void (*setup)(struct super_block *));
extern int fat_flush_inodes(struct super_block *sb, struct inode *i1, extern int fat_flush_inodes(struct super_block *sb, struct inode *i1,
struct inode *i2); struct inode *i2);
......
...@@ -703,7 +703,6 @@ static struct dentry *fat_fh_to_dentry(struct super_block *sb, ...@@ -703,7 +703,6 @@ static struct dentry *fat_fh_to_dentry(struct super_block *sb,
struct fid *fid, int fh_len, int fh_type) struct fid *fid, int fh_len, int fh_type)
{ {
struct inode *inode = NULL; struct inode *inode = NULL;
struct dentry *result;
u32 *fh = fid->raw; u32 *fh = fid->raw;
if (fh_len < 5 || fh_type != 3) if (fh_len < 5 || fh_type != 3)
...@@ -748,10 +747,7 @@ static struct dentry *fat_fh_to_dentry(struct super_block *sb, ...@@ -748,10 +747,7 @@ static struct dentry *fat_fh_to_dentry(struct super_block *sb,
* the fat_iget lookup again. If that fails, then we are totally out * the fat_iget lookup again. If that fails, then we are totally out
* of luck. But all that is for another day * of luck. But all that is for another day
*/ */
result = d_obtain_alias(inode); return d_obtain_alias(inode);
if (!IS_ERR(result))
d_set_d_op(result, sb->s_root->d_op);
return result;
} }
static int static int
...@@ -799,8 +795,6 @@ static struct dentry *fat_get_parent(struct dentry *child) ...@@ -799,8 +795,6 @@ static struct dentry *fat_get_parent(struct dentry *child)
brelse(bh); brelse(bh);
parent = d_obtain_alias(inode); parent = d_obtain_alias(inode);
if (!IS_ERR(parent))
d_set_d_op(parent, sb->s_root->d_op);
out: out:
unlock_super(sb); unlock_super(sb);
...@@ -1244,7 +1238,8 @@ static int fat_read_root(struct inode *inode) ...@@ -1244,7 +1238,8 @@ static int fat_read_root(struct inode *inode)
* Read the super block of an MS-DOS FS. * Read the super block of an MS-DOS FS.
*/ */
int fat_fill_super(struct super_block *sb, void *data, int silent, int fat_fill_super(struct super_block *sb, void *data, int silent,
const struct inode_operations *fs_dir_inode_ops, int isvfat) const struct inode_operations *fs_dir_inode_ops, int isvfat,
void (*setup)(struct super_block *))
{ {
struct inode *root_inode = NULL, *fat_inode = NULL; struct inode *root_inode = NULL, *fat_inode = NULL;
struct buffer_head *bh; struct buffer_head *bh;
...@@ -1280,6 +1275,8 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, ...@@ -1280,6 +1275,8 @@ int fat_fill_super(struct super_block *sb, void *data, int silent,
if (error) if (error)
goto out_fail; goto out_fail;
setup(sb); /* flavour-specific stuff that needs options */
error = -EIO; error = -EIO;
sb_min_blocksize(sb, 512); sb_min_blocksize(sb, 512);
bh = sb_bread(sb, 0); bh = sb_bread(sb, 0);
......
...@@ -227,11 +227,7 @@ static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry, ...@@ -227,11 +227,7 @@ static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry,
} }
out: out:
unlock_super(sb); unlock_super(sb);
d_set_d_op(dentry, &msdos_dentry_operations); return d_splice_alias(inode, dentry);
dentry = d_splice_alias(inode, dentry);
if (dentry)
d_set_d_op(dentry, &msdos_dentry_operations);
return dentry;
error: error:
unlock_super(sb); unlock_super(sb);
...@@ -661,21 +657,16 @@ static const struct inode_operations msdos_dir_inode_operations = { ...@@ -661,21 +657,16 @@ static const struct inode_operations msdos_dir_inode_operations = {
.getattr = fat_getattr, .getattr = fat_getattr,
}; };
static int msdos_fill_super(struct super_block *sb, void *data, int silent) static void setup(struct super_block *sb)
{ {
int res; sb->s_d_op = &msdos_dentry_operations;
lock_super(sb);
res = fat_fill_super(sb, data, silent, &msdos_dir_inode_operations, 0);
if (res) {
unlock_super(sb);
return res;
}
sb->s_flags |= MS_NOATIME; sb->s_flags |= MS_NOATIME;
d_set_d_op(sb->s_root, &msdos_dentry_operations); }
unlock_super(sb);
return 0; static int msdos_fill_super(struct super_block *sb, void *data, int silent)
{
return fat_fill_super(sb, data, silent, &msdos_dir_inode_operations,
0, setup);
} }
static struct dentry *msdos_mount(struct file_system_type *fs_type, static struct dentry *msdos_mount(struct file_system_type *fs_type,
......
...@@ -772,13 +772,10 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry, ...@@ -772,13 +772,10 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
out: out:
unlock_super(sb); unlock_super(sb);
d_set_d_op(dentry, sb->s_root->d_op);
dentry->d_time = dentry->d_parent->d_inode->i_version; dentry->d_time = dentry->d_parent->d_inode->i_version;
dentry = d_splice_alias(inode, dentry); dentry = d_splice_alias(inode, dentry);
if (dentry) { if (dentry)
d_set_d_op(dentry, sb->s_root->d_op);
dentry->d_time = dentry->d_parent->d_inode->i_version; dentry->d_time = dentry->d_parent->d_inode->i_version;
}
return dentry; return dentry;
error: error:
...@@ -1066,24 +1063,18 @@ static const struct inode_operations vfat_dir_inode_operations = { ...@@ -1066,24 +1063,18 @@ static const struct inode_operations vfat_dir_inode_operations = {
.getattr = fat_getattr, .getattr = fat_getattr,
}; };
static int vfat_fill_super(struct super_block *sb, void *data, int silent) static void setup(struct super_block *sb)
{ {
int res;
lock_super(sb);
res = fat_fill_super(sb, data, silent, &vfat_dir_inode_operations, 1);
if (res) {
unlock_super(sb);
return res;
}
if (MSDOS_SB(sb)->options.name_check != 's') if (MSDOS_SB(sb)->options.name_check != 's')
d_set_d_op(sb->s_root, &vfat_ci_dentry_ops); sb->s_d_op = &vfat_ci_dentry_ops;
else else
d_set_d_op(sb->s_root, &vfat_dentry_ops); sb->s_d_op = &vfat_dentry_ops;
}
unlock_super(sb); static int vfat_fill_super(struct super_block *sb, void *data, int silent)
return 0; {
return fat_fill_super(sb, data, silent, &vfat_dir_inode_operations,
1, setup);
} }
static struct dentry *vfat_mount(struct file_system_type *fs_type, static struct dentry *vfat_mount(struct file_system_type *fs_type,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册