Commit 6441b29e authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] BKL shifted into ->mknod()

parent 0443970a
......@@ -52,7 +52,7 @@ locking rules:
lookup: no yes
create: no yes
link: yes yes
mknod: yes yes
mknod: no yes
mkdir: yes yes
unlink: yes yes (both)
rmdir: yes yes (both) (see below)
......
......@@ -80,17 +80,8 @@ can relax your locking.
---
[mandatory]
->lookup() is called without BKL now. Grab it on the entry, drop upon return
- that will guarantee the same locking you used to have. If your ->lookup()
or its parts do not need BKL - better yet, now you can shift lock_kernel()/
unlock_kernel() so that they would protect exactly what needs to be protected.
---
[mandatory]
->truncate() is called without BKL now (same as above).
---
[mandatory]
->create() is called without BKL now (same as above).
->lookup(), ->truncate(), ->create() and ->mknod() are called without BKL now.
Grab it on the entry, drop upon return - that will guarantee the same
locking you used to have. If your ->method or its parts do not need
BKL - better yet, now you can shift lock_kernel()/ unlock_kernel()
so that they would protect exactly what needs to be protected.
......@@ -267,13 +267,16 @@ static int coda_mknod(struct inode *dir, struct dentry *de, int mode, int rdev)
if ( coda_hasmknod == 0 )
return -EIO;
lock_kernel();
coda_vfs_stat.create++;
CDEBUG(D_INODE, "name: %s, length %d, mode %o, rdev %x\n",
name, length, mode, rdev);
if (coda_isroot(dir) && coda_iscontrol(name, length))
if (coda_isroot(dir) && coda_iscontrol(name, length)) {
unlock_kernel();
return -EPERM;
}
error = venus_create(dir->i_sb, coda_i2f(dir), name, length,
0, mode, rdev, &newfid, &attrs);
......@@ -282,6 +285,7 @@ static int coda_mknod(struct inode *dir, struct dentry *de, int mode, int rdev)
CDEBUG(D_INODE, "mknod: %s, result %d\n",
coda_f2s(&newfid), error);
d_drop(de);
unlock_kernel();
return error;
}
......@@ -289,11 +293,13 @@ static int coda_mknod(struct inode *dir, struct dentry *de, int mode, int rdev)
if ( error ) {
d_drop(de);
result = NULL;
unlock_kernel();
return error;
}
/* invalidate the directory cnode's attributes */
coda_dir_changed(dir, 0);
unlock_kernel();
d_instantiate(de, result);
return 0;
}
......
......@@ -3151,31 +3151,43 @@ static int devfs_mknod (struct inode *dir, struct dentry *dentry, int mode,
DPRINTK (DEBUG_I_MKNOD, "(%s): mode: 0%o dev: %d\n",
dentry->d_name.name, mode, rdev);
lock_kernel();
parent = get_devfs_entry_from_vfs_inode (dir);
if (parent == NULL) return -ENOENT;
if (parent == NULL) {
unlock_kernel();
return -ENOENT;
}
de = _devfs_alloc_entry (dentry->d_name.name, dentry->d_name.len, mode);
if (!de) return -ENOMEM;
if (!de) {
unlock_kernel();
return -ENOMEM;
}
de->vfs_deletable = TRUE;
if ( S_ISBLK (mode) || S_ISCHR (mode) )
{
de->u.fcb.u.device.major = MAJOR (rdev);
de->u.fcb.u.device.minor = MINOR (rdev);
}
if ( ( err = _devfs_append_entry (parent, de, FALSE, NULL) ) != 0 )
if ( ( err = _devfs_append_entry (parent, de, FALSE, NULL) ) != 0 ) {
unlock_kernel();
return err;
}
de->inode.uid = current->euid;
de->inode.gid = current->egid;
de->inode.atime = CURRENT_TIME;
de->inode.mtime = CURRENT_TIME;
de->inode.ctime = CURRENT_TIME;
if ( ( inode = _devfs_get_vfs_inode (dir->i_sb, de, dentry) ) == NULL )
if ( ( inode = _devfs_get_vfs_inode (dir->i_sb, de, dentry) ) == NULL ) {
unlock_kernel();
return -ENOMEM;
}
DPRINTK (DEBUG_I_MKNOD, ": new VFS inode(%u): %p dentry: %p\n",
de->inode.ino, inode, dentry);
d_instantiate (dentry, inode);
if ( !is_devfsd_or_child (fs_info) )
devfsd_notify_de (de, DEVFSD_NOTIFY_CREATE, inode->i_mode,
inode->i_uid, inode->i_gid, fs_info, 0);
unlock_kernel();
return 0;
} /* End Function devfs_mknod */
......
......@@ -487,9 +487,12 @@ static int ext3_mknod (struct inode * dir, struct dentry *dentry,
struct inode *inode;
int err;
lock_kernel();
handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3);
if (IS_ERR(handle))
if (IS_ERR(handle)) {
unlock_kernel();
return PTR_ERR(handle);
}
if (IS_SYNC(dir))
handle->h_sync = 1;
......@@ -502,6 +505,7 @@ static int ext3_mknod (struct inode * dir, struct dentry *dentry,
err = ext3_add_nondir(handle, dentry, inode);
}
ext3_journal_stop(handle, dir);
unlock_kernel();
return err;
}
......@@ -1129,6 +1133,6 @@ struct inode_operations ext3_dir_inode_operations = {
symlink: ext3_symlink, /* BKL held */
mkdir: ext3_mkdir, /* BKL held */
rmdir: ext3_rmdir, /* BKL held */
mknod: ext3_mknod, /* BKL held */
mknod: ext3_mknod,
rename: ext3_rename, /* BKL held */
};
......@@ -182,6 +182,7 @@ int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev)
int err;
if ((err = hpfs_chk_name((char *)name, &len))) return err==-ENOENT ? -EINVAL : err;
if (dir->i_sb->s_hpfs_eas < 2) return -EPERM;
lock_kernel();
if (!(fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh))) goto bail;
memset(&dee, 0, sizeof dee);
if (!(mode & 0222)) dee.read_only = 1;
......@@ -196,6 +197,7 @@ int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev)
brelse(bh);
hpfs_free_sectors(dir->i_sb, fno, 1);
hpfs_unlock_inode(dir);
unlock_kernel();
return -EEXIST;
}
fnode->len = len;
......@@ -221,12 +223,14 @@ int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev)
hpfs_unlock_iget(dir->i_sb);
hpfs_unlock_inode(dir);
brelse(bh);
unlock_kernel();
return 0;
bail1:
bail1:
brelse(bh);
hpfs_free_sectors(dir->i_sb, fno, 1);
hpfs_unlock_inode(dir);
bail:
bail:
unlock_kernel();
return -ENOSPC;
}
......
......@@ -1052,6 +1052,7 @@ jffs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev)
D1(printk("***jffs_mknod()\n"));
lock_kernel();
dir_f = (struct jffs_file *)dir->u.generic_ip;
c = dir_f->c;
......@@ -1123,6 +1124,7 @@ jffs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev)
jffs_mknod_end:
D3(printk (KERN_NOTICE "mknod(): up biglock\n"));
up(&c->fmc->biglock);
unlock_kernel();
return result;
} /* jffs_mknod() */
......
......@@ -802,9 +802,12 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, in
__u32 writtenlen;
int ret;
lock_kernel();
ri = jffs2_alloc_raw_inode();
if (!ri)
if (!ri) {
unlock_kernel();
return -ENOMEM;
}
c = JFFS2_SB_INFO(dir_i->i_sb);
......@@ -822,6 +825,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, in
if (ret) {
jffs2_free_raw_inode(ri);
unlock_kernel();
return ret;
}
......@@ -830,6 +834,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, in
if (IS_ERR(inode)) {
jffs2_free_raw_inode(ri);
jffs2_complete_reservation(c);
unlock_kernel();
return PTR_ERR(inode);
}
inode->i_op = &jffs2_file_inode_operations;
......@@ -854,6 +859,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, in
up(&f->sem);
jffs2_complete_reservation(c);
jffs2_clear_inode(inode);
unlock_kernel();
return PTR_ERR(fn);
}
/* No data here. Only a metadata node, which will be
......@@ -874,6 +880,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, in
if (ret) {
/* Eep. */
jffs2_clear_inode(inode);
unlock_kernel();
return ret;
}
}
......@@ -883,6 +890,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, in
/* Argh. Now we treat it like a normal delete */
jffs2_complete_reservation(c);
jffs2_clear_inode(inode);
unlock_kernel();
return -ENOMEM;
}
......@@ -916,6 +924,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, in
as if it were the final unlink() */
up(&dir_f->sem);
jffs2_clear_inode(inode);
unlock_kernel();
return PTR_ERR(fd);
}
......@@ -923,6 +932,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, in
one if necessary. */
jffs2_add_fd_to_list(c, fd, &dir_f->dents);
up(&dir_f->sem);
unlock_kernel();
d_instantiate(dentry, inode);
return 0;
......
......@@ -1262,9 +1262,7 @@ int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
return -EPERM;
DQUOT_INIT(dir);
lock_kernel();
error = dir->i_op->mknod(dir, dentry, mode, dev);
unlock_kernel();
if (!error)
inode_dir_notify(dir, DN_CREATE);
return error;
......
......@@ -670,6 +670,7 @@ static int nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rde
attr.ia_mode = mode;
attr.ia_valid = ATTR_MODE;
lock_kernel();
nfs_zap_caches(dir);
error = NFS_PROTO(dir)->mknod(dir, &dentry->d_name, &attr, rdev,
&fhandle, &fattr);
......@@ -677,6 +678,7 @@ static int nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rde
error = nfs_instantiate(dentry, &fhandle, &fattr);
if (error || fhandle.size == 0)
d_drop(dentry);
unlock_kernel();
return error;
}
......
......@@ -588,6 +588,7 @@ static int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode,
if (!inode) {
return -ENOMEM ;
}
lock_kernel();
journal_begin(&th, dir->i_sb, jbegin_count) ;
windex = push_journal_writer("reiserfs_mknod") ;
......@@ -595,6 +596,7 @@ static int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode,
if (!inode) {
pop_journal_writer(windex) ;
journal_end(&th, dir->i_sb, jbegin_count) ;
unlock_kernel();
return retval;
}
......@@ -614,12 +616,14 @@ static int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode,
pop_journal_writer(windex) ;
journal_end(&th, dir->i_sb, jbegin_count) ;
iput (inode);
unlock_kernel();
return retval;
}
d_instantiate(dentry, inode);
pop_journal_writer(windex) ;
journal_end(&th, dir->i_sb, jbegin_count) ;
unlock_kernel();
return 0;
}
......
......@@ -679,6 +679,7 @@ static int udf_mknod(struct inode * dir, struct dentry * dentry, int mode, int r
int err;
struct FileIdentDesc cfi, *fi;
lock_kernel();
err = -EIO;
inode = udf_new_inode(dir, mode, &err);
if (!inode)
......@@ -691,6 +692,7 @@ static int udf_mknod(struct inode * dir, struct dentry * dentry, int mode, int r
inode->i_nlink --;
mark_inode_dirty(inode);
iput(inode);
unlock_kernel();
return err;
}
cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
......@@ -710,6 +712,7 @@ static int udf_mknod(struct inode * dir, struct dentry * dentry, int mode, int r
d_instantiate(dentry, inode);
err = 0;
out:
unlock_kernel();
return err;
}
......
......@@ -114,7 +114,9 @@ static int ufs_mknod (struct inode * dir, struct dentry *dentry, int mode, int r
if (!IS_ERR(inode)) {
init_special_inode(inode, mode, rdev);
mark_inode_dirty(inode);
lock_kernel();
err = ufs_add_nondir(dentry, inode);
unlock_kernel();
}
return err;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment