mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 18:21:24 +02:00
nilfs2: use setup_bdev_super to de-duplicate the mount code
Use the generic setup_bdev_super helper to open the main block device and do various bits of superblock setup instead of duplicating the logic. This includes moving to the new scheme implemented in common code that only opens the block device after the superblock has allocated. It does not yet convert nilfs2 to the new mount API, but doing so will become a bit simpler after this first step. Signed-off-by: Christoph Hellwig <hch@lst.de> Acked-by: Ryusuke Konishi <konishi.ryusuke@gmail.com> Message-Id: <20230802154131.2221419-3-hch@lst.de> Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
parent
cf6da236c2
commit
c1e012ea9e
|
|
@ -35,6 +35,7 @@
|
||||||
#include <linux/writeback.h>
|
#include <linux/writeback.h>
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
#include <linux/mount.h>
|
#include <linux/mount.h>
|
||||||
|
#include <linux/fs_context.h>
|
||||||
#include "nilfs.h"
|
#include "nilfs.h"
|
||||||
#include "export.h"
|
#include "export.h"
|
||||||
#include "mdt.h"
|
#include "mdt.h"
|
||||||
|
|
@ -1216,7 +1217,6 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct nilfs_super_data {
|
struct nilfs_super_data {
|
||||||
struct block_device *bdev;
|
|
||||||
__u64 cno;
|
__u64 cno;
|
||||||
int flags;
|
int flags;
|
||||||
};
|
};
|
||||||
|
|
@ -1283,64 +1283,49 @@ static int nilfs_identify(char *data, struct nilfs_super_data *sd)
|
||||||
|
|
||||||
static int nilfs_set_bdev_super(struct super_block *s, void *data)
|
static int nilfs_set_bdev_super(struct super_block *s, void *data)
|
||||||
{
|
{
|
||||||
s->s_bdev = data;
|
s->s_dev = *(dev_t *)data;
|
||||||
s->s_dev = s->s_bdev->bd_dev;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nilfs_test_bdev_super(struct super_block *s, void *data)
|
static int nilfs_test_bdev_super(struct super_block *s, void *data)
|
||||||
{
|
{
|
||||||
return (void *)s->s_bdev == data;
|
return !(s->s_iflags & SB_I_RETIRED) && s->s_dev == *(dev_t *)data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct dentry *
|
static struct dentry *
|
||||||
nilfs_mount(struct file_system_type *fs_type, int flags,
|
nilfs_mount(struct file_system_type *fs_type, int flags,
|
||||||
const char *dev_name, void *data)
|
const char *dev_name, void *data)
|
||||||
{
|
{
|
||||||
struct nilfs_super_data sd;
|
struct nilfs_super_data sd = { .flags = flags };
|
||||||
struct super_block *s;
|
struct super_block *s;
|
||||||
struct dentry *root_dentry;
|
dev_t dev;
|
||||||
int err, s_new = false;
|
int err;
|
||||||
|
|
||||||
sd.bdev = blkdev_get_by_path(dev_name, sb_open_mode(flags), fs_type,
|
if (nilfs_identify(data, &sd))
|
||||||
NULL);
|
return ERR_PTR(-EINVAL);
|
||||||
if (IS_ERR(sd.bdev))
|
|
||||||
return ERR_CAST(sd.bdev);
|
|
||||||
|
|
||||||
sd.cno = 0;
|
err = lookup_bdev(dev_name, &dev);
|
||||||
sd.flags = flags;
|
if (err)
|
||||||
if (nilfs_identify((char *)data, &sd)) {
|
return ERR_PTR(err);
|
||||||
err = -EINVAL;
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* once the super is inserted into the list by sget, s_umount
|
|
||||||
* will protect the lockfs code from trying to start a snapshot
|
|
||||||
* while we are mounting
|
|
||||||
*/
|
|
||||||
mutex_lock(&sd.bdev->bd_fsfreeze_mutex);
|
|
||||||
if (sd.bdev->bd_fsfreeze_count > 0) {
|
|
||||||
mutex_unlock(&sd.bdev->bd_fsfreeze_mutex);
|
|
||||||
err = -EBUSY;
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
s = sget(fs_type, nilfs_test_bdev_super, nilfs_set_bdev_super, flags,
|
s = sget(fs_type, nilfs_test_bdev_super, nilfs_set_bdev_super, flags,
|
||||||
sd.bdev);
|
&dev);
|
||||||
mutex_unlock(&sd.bdev->bd_fsfreeze_mutex);
|
if (IS_ERR(s))
|
||||||
if (IS_ERR(s)) {
|
return ERR_CAST(s);
|
||||||
err = PTR_ERR(s);
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!s->s_root) {
|
if (!s->s_root) {
|
||||||
s_new = true;
|
/*
|
||||||
|
* We drop s_umount here because we need to open the bdev and
|
||||||
/* New superblock instance created */
|
* bdev->open_mutex ranks above s_umount (blkdev_put() ->
|
||||||
snprintf(s->s_id, sizeof(s->s_id), "%pg", sd.bdev);
|
* __invalidate_device()). It is safe because we have active sb
|
||||||
sb_set_blocksize(s, block_size(sd.bdev));
|
* reference and SB_BORN is not set yet.
|
||||||
|
*/
|
||||||
err = nilfs_fill_super(s, data, flags & SB_SILENT ? 1 : 0);
|
up_write(&s->s_umount);
|
||||||
|
err = setup_bdev_super(s, flags, NULL);
|
||||||
|
down_write(&s->s_umount);
|
||||||
|
if (!err)
|
||||||
|
err = nilfs_fill_super(s, data,
|
||||||
|
flags & SB_SILENT ? 1 : 0);
|
||||||
if (err)
|
if (err)
|
||||||
goto failed_super;
|
goto failed_super;
|
||||||
|
|
||||||
|
|
@ -1366,24 +1351,18 @@ nilfs_mount(struct file_system_type *fs_type, int flags,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sd.cno) {
|
if (sd.cno) {
|
||||||
|
struct dentry *root_dentry;
|
||||||
|
|
||||||
err = nilfs_attach_snapshot(s, sd.cno, &root_dentry);
|
err = nilfs_attach_snapshot(s, sd.cno, &root_dentry);
|
||||||
if (err)
|
if (err)
|
||||||
goto failed_super;
|
goto failed_super;
|
||||||
} else {
|
return root_dentry;
|
||||||
root_dentry = dget(s->s_root);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!s_new)
|
return dget(s->s_root);
|
||||||
blkdev_put(sd.bdev, fs_type);
|
|
||||||
|
|
||||||
return root_dentry;
|
|
||||||
|
|
||||||
failed_super:
|
failed_super:
|
||||||
deactivate_locked_super(s);
|
deactivate_locked_super(s);
|
||||||
|
|
||||||
failed:
|
|
||||||
if (!s_new)
|
|
||||||
blkdev_put(sd.bdev, fs_type);
|
|
||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user