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: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Родитель
6cc9c1d2c1
Коммит
3d23985d6c
|
@ -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,
|
||||||
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,
|
||||||
* 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)
|
||||||
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)
|
||||||
* 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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
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 = {
|
||||||
.getattr = fat_getattr,
|
.getattr = fat_getattr,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void setup(struct super_block *sb)
|
||||||
|
{
|
||||||
|
sb->s_d_op = &msdos_dentry_operations;
|
||||||
|
sb->s_flags |= MS_NOATIME;
|
||||||
|
}
|
||||||
|
|
||||||
static int msdos_fill_super(struct super_block *sb, void *data, int silent)
|
static int msdos_fill_super(struct super_block *sb, void *data, int silent)
|
||||||
{
|
{
|
||||||
int res;
|
return fat_fill_super(sb, data, silent, &msdos_dir_inode_operations,
|
||||||
|
0, setup);
|
||||||
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;
|
|
||||||
d_set_d_op(sb->s_root, &msdos_dentry_operations);
|
|
||||||
unlock_super(sb);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
|
|
||||||
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 = {
|
||||||
.getattr = fat_getattr,
|
.getattr = fat_getattr,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void setup(struct super_block *sb)
|
||||||
|
{
|
||||||
|
if (MSDOS_SB(sb)->options.name_check != 's')
|
||||||
|
sb->s_d_op = &vfat_ci_dentry_ops;
|
||||||
|
else
|
||||||
|
sb->s_d_op = &vfat_dentry_ops;
|
||||||
|
}
|
||||||
|
|
||||||
static int vfat_fill_super(struct super_block *sb, void *data, int silent)
|
static int vfat_fill_super(struct super_block *sb, void *data, int silent)
|
||||||
{
|
{
|
||||||
int res;
|
return fat_fill_super(sb, data, silent, &vfat_dir_inode_operations,
|
||||||
|
1, setup);
|
||||||
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')
|
|
||||||
d_set_d_op(sb->s_root, &vfat_ci_dentry_ops);
|
|
||||||
else
|
|
||||||
d_set_d_op(sb->s_root, &vfat_dentry_ops);
|
|
||||||
|
|
||||||
unlock_super(sb);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct dentry *vfat_mount(struct file_system_type *fs_type,
|
static struct dentry *vfat_mount(struct file_system_type *fs_type,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче