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