Commit b2461ad6 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] (1/5) more BKL shifting

BKL shifted into ->mkdir()
parent 8af480ec
......@@ -57,7 +57,7 @@ lookup: no yes
create: no yes
link: yes yes
mknod: no yes
mkdir: yes yes
mkdir: no yes
unlink: no yes (both)
rmdir: yes yes (both) (see below)
rename: yes yes (all) (see below)
......
......@@ -80,8 +80,8 @@ can relax your locking.
---
[mandatory]
->lookup(), ->truncate(), ->create(), ->unlink() 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
->lookup(), ->truncate(), ->create(), ->unlink(), ->mknod() and ->mkdir()
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.
......@@ -794,6 +794,7 @@ static int comx_mkdir(struct inode *dir, struct dentry *dentry, int mode)
}
memset(dev, 0, sizeof(struct net_device));
lock_kernel();
if ((new_dir = create_proc_entry(dentry->d_name.name, mode | S_IFDIR,
comx_root_dir)) == NULL) {
goto cleanup_dev;
......@@ -853,6 +854,7 @@ static int comx_mkdir(struct inode *dir, struct dentry *dentry, int mode)
ch->lineup_delay = DEFAULT_LINEUP_DELAY;
MOD_INC_USE_COUNT;
unlock_kernel();
return 0;
cleanup_if_ptr:
kfree(ch->if_ptr);
......@@ -872,6 +874,7 @@ static int comx_mkdir(struct inode *dir, struct dentry *dentry, int mode)
remove_proc_entry(dentry->d_name.name, comx_root_dir);
cleanup_dev:
kfree(dev);
unlock_kernel();
return ret;
}
......
......@@ -310,9 +310,12 @@ affs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
pr_debug("AFFS: mkdir(%lu,\"%.*s\",0%o)\n",dir->i_ino,
(int)dentry->d_name.len,dentry->d_name.name,mode);
lock_kernel();
inode = affs_new_inode(dir);
if (!inode)
if (!inode) {
unlock_kernel();
return -ENOSPC;
}
inode->i_mode = S_IFDIR | mode;
mode_to_prot(inode);
......@@ -325,8 +328,10 @@ affs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
inode->i_nlink = 0;
mark_inode_dirty(inode);
iput(inode);
unlock_kernel();
return error;
}
unlock_kernel();
return 0;
}
......
......@@ -399,26 +399,35 @@ static int autofs_root_mkdir(struct inode *dir, struct dentry *dentry, int mode)
struct autofs_dir_ent *ent;
ino_t ino;
if ( !autofs_oz_mode(sbi) )
lock_kernel();
if ( !autofs_oz_mode(sbi) ) {
unlock_kernel();
return -EACCES;
}
ent = autofs_hash_lookup(dh, &dentry->d_name);
if ( ent )
if ( ent ) {
unlock_kernel();
return -EEXIST;
}
if ( sbi->next_dir_ino < AUTOFS_FIRST_DIR_INO ) {
printk("autofs: Out of inode numbers -- what the heck did you do??\n");
unlock_kernel();
return -ENOSPC;
}
ino = sbi->next_dir_ino++;
ent = kmalloc(sizeof(struct autofs_dir_ent), GFP_KERNEL);
if ( !ent )
if ( !ent ) {
unlock_kernel();
return -ENOSPC;
}
ent->name = kmalloc(dentry->d_name.len+1, GFP_KERNEL);
if ( !ent->name ) {
kfree(ent);
unlock_kernel();
return -ENOSPC;
}
......@@ -430,6 +439,7 @@ static int autofs_root_mkdir(struct inode *dir, struct dentry *dentry, int mode)
dir->i_nlink++;
d_instantiate(dentry, iget(dir->i_sb,ino));
unlock_kernel();
return 0;
}
......
......@@ -431,15 +431,20 @@ static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, int mode)
struct autofs_info *ino = autofs4_dentry_ino(dentry);
struct inode *inode;
if ( !autofs4_oz_mode(sbi) )
lock_kernel();
if ( !autofs4_oz_mode(sbi) ) {
unlock_kernel();
return -EACCES;
}
DPRINTK(("autofs_dir_mkdir: dentry %p, creating %.*s\n",
dentry, dentry->d_name.len, dentry->d_name.name));
ino = autofs4_init_ino(ino, sbi, S_IFDIR | 0555);
if (ino == NULL)
if (ino == NULL) {
unlock_kernel();
return -ENOSPC;
}
inode = autofs4_get_inode(dir->i_sb, ino);
d_instantiate(dentry, inode);
......@@ -455,6 +460,7 @@ static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, int mode)
dir->i_nlink++;
dir->i_mtime = CURRENT_TIME;
unlock_kernel();
return 0;
}
......
......@@ -313,10 +313,13 @@ static int coda_mkdir(struct inode *dir, struct dentry *de, int mode)
int error;
struct ViceFid newfid;
lock_kernel();
coda_vfs_stat.mkdir++;
if (coda_isroot(dir) && coda_iscontrol(name, len))
if (coda_isroot(dir) && coda_iscontrol(name, len)) {
unlock_kernel();
return -EPERM;
}
CDEBUG(D_INODE, "mkdir %s (len %d) in %s, mode %o.\n",
name, len, coda_i2s(dir), mode);
......@@ -329,6 +332,7 @@ static int coda_mkdir(struct inode *dir, struct dentry *de, int mode)
CDEBUG(D_INODE, "mkdir error: %s result %d\n",
coda_f2s(&newfid), error);
d_drop(de);
unlock_kernel();
return error;
}
......@@ -338,11 +342,13 @@ static int coda_mkdir(struct inode *dir, struct dentry *de, int mode)
error = coda_cnode_make(&inode, &newfid, dir->i_sb);
if ( error ) {
d_drop(de);
unlock_kernel();
return error;
}
/* invalidate the directory cnode's attributes */
coda_dir_changed(dir, 1);
unlock_kernel();
d_instantiate(de, inode);
return 0;
}
......
......@@ -3098,26 +3098,38 @@ static int devfs_mkdir (struct inode *dir, struct dentry *dentry, int mode)
struct inode *inode;
mode = (mode & ~S_IFMT) | S_IFDIR; /* VFS doesn't pass S_IFMT part */
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 ( ( 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_DISABLED, "(%s): new VFS inode(%u): %p dentry: %p\n",
dentry->d_name.name, 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_mkdir */
......
......@@ -118,8 +118,12 @@ static int driverfs_mknod(struct inode *dir, struct dentry *dentry, int mode, in
static int driverfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
{
int res;
lock_kernel();
dentry->d_op = &driverfs_dentry_dir_ops;
return driverfs_mknod(dir, dentry, mode | S_IFDIR, 0);
res = driverfs_mknod(dir, dentry, mode | S_IFDIR, 0);
unlock_kernel();
return res;
}
static int driverfs_create(struct inode *dir, struct dentry *dentry, int mode)
......
......@@ -520,9 +520,12 @@ static int ext3_mkdir(struct inode * dir, struct dentry * dentry, int mode)
if (dir->i_nlink >= EXT3_LINK_MAX)
return -EMLINK;
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;
......@@ -575,6 +578,7 @@ static int ext3_mkdir(struct inode * dir, struct dentry * dentry, int mode)
d_instantiate(dentry, inode);
out_stop:
ext3_journal_stop(handle, dir);
unlock_kernel();
return err;
out_no_entry:
......
......@@ -217,26 +217,33 @@ int hfs_create(struct inode * dir, struct dentry *dentry, int mode)
*/
int hfs_mkdir(struct inode * parent, struct dentry *dentry, int mode)
{
struct hfs_cat_entry *entry = HFS_I(parent)->entry;
struct hfs_cat_entry *entry;
struct hfs_cat_entry *new;
struct hfs_cat_key key;
struct inode *inode;
int error;
lock_kernel();
entry = HFS_I(parent)->entry;
/* build the key, checking against reserved names */
if (build_key(&key, parent, dentry->d_name.name,
dentry->d_name.len))
dentry->d_name.len)) {
unlock_kernel();
return -EEXIST;
}
/* try to create the directory */
if ((error = hfs_cat_mkdir(entry, &key, &new)))
if ((error = hfs_cat_mkdir(entry, &key, &new))) {
unlock_kernel();
return error;
}
/* back out if we run into trouble */
new->count++; /* hfs_iget eats one */
if (!(inode = hfs_iget(new, HFS_I(parent)->file_type, dentry))) {
hfs_cat_delete(entry, new, 1);
hfs_cat_put(new);
unlock_kernel();
return -EIO;
}
......@@ -244,6 +251,7 @@ int hfs_mkdir(struct inode * parent, struct dentry *dentry, int mode)
update_dirs_plus(entry, 1);
mark_inode_dirty(inode);
d_instantiate(dentry, inode);
unlock_kernel();
return 0;
}
......
......@@ -295,11 +295,13 @@ static int dbl_mkdir(struct inode * parent, struct dentry *dentry,
{
int error;
lock_kernel();
if (is_hdr(parent, dentry->d_name.name, dentry->d_name.len)) {
error = -EEXIST;
} else {
error = hfs_mkdir(parent, dentry, mode);
}
unlock_kernel();
return error;
}
......
......@@ -25,6 +25,7 @@ int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
struct hpfs_dirent dee;
int err;
if ((err = hpfs_chk_name((char *)name, &len))) return err==-ENOENT ? -EINVAL : err;
lock_kernel();
if (!(fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh))) goto bail;
if (!(dnode = hpfs_alloc_dnode(dir->i_sb, fno, &dno, &qbh0, 1))) goto bail1;
memset(&dee, 0, sizeof dee);
......@@ -43,6 +44,7 @@ int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
hpfs_free_sectors(dir->i_sb, fno, 1);
hpfs_free_dnode(dir->i_sb, dno);
hpfs_unlock_inode(dir);
unlock_kernel();
return -EEXIST;
}
fnode->len = len;
......@@ -85,15 +87,17 @@ int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
}
hpfs_unlock_iget(dir->i_sb);
hpfs_unlock_inode(dir);
unlock_kernel();
return 0;
bail2:
bail2:
hpfs_brelse4(&qbh0);
hpfs_free_dnode(dir->i_sb, dno);
hpfs_unlock_inode(dir);
bail1:
bail1:
brelse(bh);
hpfs_free_sectors(dir->i_sb, fno, 1);
bail:
bail:
unlock_kernel();
return -ENOSPC;
}
......
......@@ -807,11 +807,13 @@ jffs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
kfree(_name);
});
lock_kernel();
dir_f = (struct jffs_file *)dir->u.generic_ip;
ASSERT(if (!dir_f) {
printk(KERN_ERR "jffs_mkdir(): No reference to a "
"jffs_file struct in inode.\n");
unlock_kernel();
return -EIO;
});
......@@ -885,6 +887,7 @@ jffs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
jffs_mkdir_end:
D3(printk (KERN_NOTICE "mkdir(): up biglock\n"));
up(&c->fmc->biglock);
unlock_kernel();
return result;
} /* jffs_mkdir() */
......
......@@ -665,9 +665,12 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
mode |= S_IFDIR;
lock_kernel();
ri = jffs2_alloc_raw_inode();
if (!ri)
if (!ri) {
unlock_kernel();
return -ENOMEM;
}
c = JFFS2_SB_INFO(dir_i->i_sb);
......@@ -679,6 +682,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
if (ret) {
jffs2_free_raw_inode(ri);
unlock_kernel();
return ret;
}
......@@ -687,6 +691,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
if (IS_ERR(inode)) {
jffs2_free_raw_inode(ri);
jffs2_complete_reservation(c);
unlock_kernel();
return PTR_ERR(inode);
}
......@@ -707,6 +712,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
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
......@@ -727,6 +733,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
if (ret) {
/* Eep. */
jffs2_clear_inode(inode);
unlock_kernel();
return ret;
}
}
......@@ -736,6 +743,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
/* Argh. Now we treat it like a normal delete */
jffs2_complete_reservation(c);
jffs2_clear_inode(inode);
unlock_kernel();
return -ENOMEM;
}
......@@ -766,6 +774,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
as if it were the final unlink() */
up(&dir_f->sem);
jffs2_clear_inode(inode);
unlock_kernel();
return PTR_ERR(fd);
}
......@@ -775,6 +784,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
up(&dir_f->sem);
d_instantiate(dentry, inode);
unlock_kernel();
return 0;
}
......
......@@ -361,10 +361,13 @@ int msdos_mkdir(struct inode *dir,struct dentry *dentry,int mode)
char msdos_name[MSDOS_NAME];
int ino;
lock_kernel();
res = msdos_format_name(dentry->d_name.name,dentry->d_name.len,
msdos_name, &MSDOS_SB(sb)->options);
if (res < 0)
if (res < 0) {
unlock_kernel();
return res;
}
is_hid = (dentry->d_name.name[0]=='.') && (msdos_name[0]!='.');
/* foo vs .foo situation */
if (fat_scan(dir,msdos_name,&bh,&de,&ino) >= 0)
......@@ -392,6 +395,7 @@ int msdos_mkdir(struct inode *dir,struct dentry *dentry,int mode)
res = 0;
out_unlock:
unlock_kernel();
return res;
mkdir_error:
......
......@@ -1325,9 +1325,7 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
DQUOT_INIT(dir);
mode &= (S_IRWXUGO|S_ISVTX);
lock_kernel();
error = dir->i_op->mkdir(dir, dentry, mode);
unlock_kernel();
if (!error)
inode_dir_notify(dir, DN_CREATE);
return error;
......
......@@ -883,6 +883,7 @@ static int ncp_mkdir(struct inode *dir, struct dentry *dentry, int mode)
DPRINTK("ncp_mkdir: making %s/%s\n",
dentry->d_parent->d_name.name, dentry->d_name.name);
error = -EIO;
lock_kernel();
if (!ncp_conn_valid(server))
goto out;
......@@ -900,6 +901,7 @@ static int ncp_mkdir(struct inode *dir, struct dentry *dentry, int mode)
error = ncp_instantiate(dir, dentry, &finfo);
}
out:
unlock_kernel();
return error;
}
......
......@@ -698,6 +698,7 @@ static int nfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
attr.ia_valid = ATTR_MODE;
attr.ia_mode = mode | S_IFDIR;
lock_kernel();
#if 0
/*
* Always drop the dentry, we can't always depend on
......@@ -714,6 +715,7 @@ static int nfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
error = nfs_instantiate(dentry, &fhandle, &fattr);
if (error || fhandle.size == 0)
d_drop(dentry);
unlock_kernel();
return error;
}
......
......@@ -642,6 +642,7 @@ static int _linux_ntfs_mkdir(struct inode *dir, struct dentry* d, int mode)
ntfs_inode *ino;
ntfs_attribute *si;
lock_kernel();
ntfs_debug (DEBUG_DIR1, "mkdir %s in %x\n", d->d_name.name, dir->i_ino);
error = -ENAMETOOLONG;
if (d->d_name.len > /* FIXME: */ 255)
......@@ -682,6 +683,7 @@ static int _linux_ntfs_mkdir(struct inode *dir, struct dentry* d, int mode)
error = 0;
out:
ntfs_debug (DEBUG_DIR1, "mkdir returns %d\n", error);
unlock_kernel();
return error;
}
#endif
......
......@@ -647,6 +647,7 @@ static int reiserfs_mkdir (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_mkdir") ;
......@@ -663,6 +664,7 @@ static int reiserfs_mkdir (struct inode * dir, struct dentry *dentry, int mode)
pop_journal_writer(windex) ;
dir->i_nlink-- ;
journal_end(&th, dir->i_sb, jbegin_count) ;
unlock_kernel();
return retval;
}
reiserfs_update_inode_transaction(inode) ;
......@@ -681,6 +683,7 @@ static int reiserfs_mkdir (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;
}
......@@ -690,6 +693,7 @@ static int reiserfs_mkdir (struct inode * dir, struct dentry *dentry, int mode)
d_instantiate(dentry, inode);
pop_journal_writer(windex) ;
journal_end(&th, dir->i_sb, jbegin_count) ;
unlock_kernel();
return 0;
}
......
......@@ -504,11 +504,13 @@ smb_mkdir(struct inode *dir, struct dentry *dentry, int mode)
{
int error;
lock_kernel();
smb_invalid_dir_cache(dir);
error = smb_proc_mkdir(dentry);
if (!error) {
error = smb_instantiate(dentry, 0, 0);
}
unlock_kernel();
return error;
}
......
......@@ -723,6 +723,7 @@ static int udf_mkdir(struct inode * dir, struct dentry * dentry, int mode)
int err;
struct FileIdentDesc cfi, *fi;
lock_kernel();
err = -EMLINK;
if (dir->i_nlink >= (256<<sizeof(dir->i_nlink))-1)
goto out;
......@@ -775,6 +776,7 @@ static int udf_mkdir(struct inode * dir, struct dentry * dentry, int mode)
udf_release_data(fibh.sbh);
err = 0;
out:
unlock_kernel();
return err;
}
......
......@@ -188,6 +188,7 @@ static int ufs_mkdir(struct inode * dir, struct dentry * dentry, int mode)
if (dir->i_nlink >= UFS_LINK_MAX)
goto out;
lock_kernel();
ufs_inc_count(dir);
inode = ufs_new_inode(dir, S_IFDIR|mode);
......@@ -207,6 +208,7 @@ static int ufs_mkdir(struct inode * dir, struct dentry * dentry, int mode)
err = ufs_add_link(dentry, inode);
if (err)
goto out_fail;
unlock_kernel();
d_instantiate(dentry, inode);
out:
......@@ -218,6 +220,7 @@ static int ufs_mkdir(struct inode * dir, struct dentry * dentry, int mode)
iput (inode);
out_dir:
ufs_dec_count(dir);
unlock_kernel();
goto out;
}
......
......@@ -1140,9 +1140,12 @@ int vfat_mkdir(struct inode *dir,struct dentry* dentry,int mode)
struct msdos_dir_entry *de;
int res;
lock_kernel();
res = vfat_add_entry(dir, &dentry->d_name, 1, &sinfo, &bh, &de);
if (res < 0)
if (res < 0) {
unlock_kernel();
return res;
}
inode = fat_build_inode(sb, de, sinfo.ino, &res);
if (!inode)
goto out;
......@@ -1159,6 +1162,7 @@ int vfat_mkdir(struct inode *dir,struct dentry* dentry,int mode)
d_instantiate(dentry,inode);
out:
fat_brelse(sb, bh);
unlock_kernel();
return res;
mkdir_failed:
......@@ -1171,6 +1175,7 @@ int vfat_mkdir(struct inode *dir,struct dentry* dentry,int mode)
vfat_remove_entry(dir,&sinfo,bh,de);
iput(inode);
dir->i_nlink--;
unlock_kernel();
return res;
}
......
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