Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit db719222 authored by Jan Blunck's avatar Jan Blunck Committed by Arnd Bergmann
Browse files

BKL: Explicitly add BKL around get_sb/fill_super



This patch is a preparation necessary to remove the BKL from do_new_mount().
It explicitly adds calls to lock_kernel()/unlock_kernel() around
get_sb/fill_super operations for filesystems that still uses the BKL.

I've read through all the code formerly covered by the BKL inside
do_kern_mount() and have satisfied myself that it doesn't need the BKL
any more.

do_kern_mount() is already called without the BKL when mounting the rootfs
and in nfsctl. do_kern_mount() calls vfs_kern_mount(), which is called
from various places without BKL: simple_pin_fs(), nfs_do_clone_mount()
through nfs_follow_mountpoint(), afs_mntpt_do_automount() through
afs_mntpt_follow_link(). Both later functions are actually the filesystems
follow_link inode operation. vfs_kern_mount() is calling the specified
get_sb function and lets the filesystem do its job by calling the given
fill_super function.

Therefore I think it is safe to push down the BKL from the VFS to the
low-level filesystems get_sb/fill_super operation.

[arnd: do not add the BKL to those file systems that already
       don't use it elsewhere]

Signed-off-by: default avatarJan Blunck <jblunck@infradead.org>
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
Cc: Matthew Wilcox <matthew@wil.cx>
Cc: Christoph Hellwig <hch@infradead.org>
parent 899611ee
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -352,11 +352,15 @@ static int adfs_fill_super(struct super_block *sb, void *data, int silent)
	struct adfs_sb_info *asb;
	struct inode *root;

	lock_kernel();

	sb->s_flags |= MS_NODIRATIME;

	asb = kzalloc(sizeof(*asb), GFP_KERNEL);
	if (!asb)
	if (!asb) {
		unlock_kernel();
		return -ENOMEM;
	}
	sb->s_fs_info = asb;

	/* set default options */
@@ -474,6 +478,7 @@ static int adfs_fill_super(struct super_block *sb, void *data, int silent)
		goto error;
	} else
		sb->s_root->d_op = &adfs_dentry_operations;
	unlock_kernel();
	return 0;

error_free_bh:
@@ -481,6 +486,7 @@ static int adfs_fill_super(struct super_block *sb, void *data, int silent)
error:
	sb->s_fs_info = NULL;
	kfree(asb);
	unlock_kernel();
	return -EINVAL;
}

+8 −1
Original line number Diff line number Diff line
@@ -291,6 +291,8 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent)
	u8			 sig[4];
	int			 ret = -EINVAL;

	lock_kernel();

	save_mount_options(sb, data);

	pr_debug("AFFS: read_super(%s)\n",data ? (const char *)data : "no options");
@@ -300,8 +302,10 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent)
	sb->s_flags |= MS_NODIRATIME;

	sbi = kzalloc(sizeof(struct affs_sb_info), GFP_KERNEL);
	if (!sbi)
	if (!sbi) {
		unlock_kernel();
		return -ENOMEM;
	}
	sb->s_fs_info = sbi;
	mutex_init(&sbi->s_bmlock);
	spin_lock_init(&sbi->symlink_lock);
@@ -312,6 +316,7 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent)
		printk(KERN_ERR "AFFS: Error parsing options\n");
		kfree(sbi->s_prefix);
		kfree(sbi);
		unlock_kernel();
		return -EINVAL;
	}
	/* N.B. after this point s_prefix must be released */
@@ -482,6 +487,7 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent)
	sb->s_root->d_op = &affs_dentry_operations;

	pr_debug("AFFS: s_flags=%lX\n",sb->s_flags);
	unlock_kernel();
	return 0;

	/*
@@ -496,6 +502,7 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent)
	kfree(sbi->s_prefix);
	kfree(sbi);
	sb->s_fs_info = NULL;
	unlock_kernel();
	return ret;
}

+5 −0
Original line number Diff line number Diff line
@@ -302,12 +302,15 @@ static int afs_fill_super(struct super_block *sb, void *data)
	struct inode *inode = NULL;
	int ret;

	lock_kernel();

	_enter("");

	/* allocate a superblock info record */
	as = kzalloc(sizeof(struct afs_super_info), GFP_KERNEL);
	if (!as) {
		_leave(" = -ENOMEM");
		unlock_kernel();
		return -ENOMEM;
	}

@@ -341,6 +344,7 @@ static int afs_fill_super(struct super_block *sb, void *data)
	sb->s_root = root;

	_leave(" = 0");
	unlock_kernel();
	return 0;

error_inode:
@@ -354,6 +358,7 @@ static int afs_fill_super(struct super_block *sb, void *data)
	sb->s_fs_info = NULL;

	_leave(" = %d", ret);
	unlock_kernel();
	return ret;
}

+7 −1
Original line number Diff line number Diff line
@@ -322,9 +322,13 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
	int ret = -EINVAL;
	unsigned long i_sblock, i_eblock, i_eoff, s_size;

	lock_kernel();

	info = kzalloc(sizeof(*info), GFP_KERNEL);
	if (!info)
	if (!info) {
		unlock_kernel();
		return -ENOMEM;
	}
	mutex_init(&info->bfs_lock);
	s->s_fs_info = info;

@@ -439,6 +443,7 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
	brelse(bh);
	brelse(sbh);
	dump_imap("read_super", s);
	unlock_kernel();
	return 0;

out3:
@@ -452,6 +457,7 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
	mutex_destroy(&info->bfs_lock);
	kfree(info);
	s->s_fs_info = NULL;
	unlock_kernel();
	return ret;
}

+10 −2
Original line number Diff line number Diff line
@@ -514,22 +514,30 @@ cifs_get_sb(struct file_system_type *fs_type,
	    int flags, const char *dev_name, void *data, struct vfsmount *mnt)
{
	int rc;
	struct super_block *sb = sget(fs_type, NULL, set_anon_super, NULL);
	struct super_block *sb;

	lock_kernel();

	sb = sget(fs_type, NULL, set_anon_super, NULL);

	cFYI(1, "Devname: %s flags: %d ", dev_name, flags);

	if (IS_ERR(sb))
	if (IS_ERR(sb)) {
		unlock_kernel();
		return PTR_ERR(sb);
	}

	sb->s_flags = flags;

	rc = cifs_read_super(sb, data, dev_name, flags & MS_SILENT ? 1 : 0);
	if (rc) {
		deactivate_locked_super(sb);
		unlock_kernel();
		return rc;
	}
	sb->s_flags |= MS_ACTIVE;
	simple_set_mnt(mnt, sb);
	unlock_kernel();
	return 0;
}

Loading