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

[PATCH] BKL shifted into ->create()

	BKL shifted into ->create().  lock_kernel()/unlock_kernel() added
in dquot_{alloc,free}_inode() - that makes {ext2,minix,sysv,ufs}_read_inode()
SMP-safe.
parent 467ae2e9
...@@ -50,7 +50,7 @@ locking rules: ...@@ -50,7 +50,7 @@ locking rules:
all may block all may block
BKL i_sem(inode) BKL i_sem(inode)
lookup: no yes lookup: no yes
create: yes yes create: no yes
link: yes yes link: yes yes
mknod: yes yes mknod: yes yes
mkdir: yes yes mkdir: yes yes
...@@ -59,7 +59,7 @@ rmdir: yes yes (both) (see below) ...@@ -59,7 +59,7 @@ rmdir: yes yes (both) (see below)
rename: yes yes (all) (see below) rename: yes yes (all) (see below)
readlink: no no readlink: no no
follow_link: no no follow_link: no no
truncate: yes yes (see below) truncate: no yes (see below)
setattr: yes if ATTR_SIZE setattr: yes if ATTR_SIZE
permssion: yes no permssion: yes no
getattr: (see below) getattr: (see below)
......
...@@ -89,3 +89,8 @@ unlock_kernel() so that they would protect exactly what needs to be protected. ...@@ -89,3 +89,8 @@ unlock_kernel() so that they would protect exactly what needs to be protected.
[mandatory] [mandatory]
->truncate() is called without BKL now (same as above). ->truncate() is called without BKL now (same as above).
---
[mandatory]
->create() is called without BKL now (same as above).
...@@ -130,6 +130,7 @@ static struct inode *pcihpfs_get_inode (struct super_block *sb, int mode, int de ...@@ -130,6 +130,7 @@ static struct inode *pcihpfs_get_inode (struct super_block *sb, int mode, int de
return inode; return inode;
} }
/* SMP-safe */
static int pcihpfs_mknod (struct inode *dir, struct dentry *dentry, int mode, int dev) static int pcihpfs_mknod (struct inode *dir, struct dentry *dentry, int mode, int dev)
{ {
struct inode *inode = pcihpfs_get_inode(dir->i_sb, mode, dev); struct inode *inode = pcihpfs_get_inode(dir->i_sb, mode, dev);
......
...@@ -186,6 +186,7 @@ static struct inode *usbfs_get_inode (struct super_block *sb, int mode, int dev) ...@@ -186,6 +186,7 @@ static struct inode *usbfs_get_inode (struct super_block *sb, int mode, int dev)
return inode; return inode;
} }
/* SMP-safe */
static int usbfs_mknod (struct inode *dir, struct dentry *dentry, int mode, static int usbfs_mknod (struct inode *dir, struct dentry *dentry, int mode,
int dev) int dev)
{ {
......
...@@ -272,9 +272,12 @@ affs_create(struct inode *dir, struct dentry *dentry, int mode) ...@@ -272,9 +272,12 @@ affs_create(struct inode *dir, struct dentry *dentry, int mode)
pr_debug("AFFS: create(%lu,\"%.*s\",0%o)\n",dir->i_ino,(int)dentry->d_name.len, pr_debug("AFFS: create(%lu,\"%.*s\",0%o)\n",dir->i_ino,(int)dentry->d_name.len,
dentry->d_name.name,mode); dentry->d_name.name,mode);
lock_kernel();
inode = affs_new_inode(dir); inode = affs_new_inode(dir);
if (!inode) if (!inode) {
unlock_kernel();
return -ENOSPC; return -ENOSPC;
}
inode->i_mode = mode; inode->i_mode = mode;
mode_to_prot(inode); mode_to_prot(inode);
...@@ -287,8 +290,10 @@ affs_create(struct inode *dir, struct dentry *dentry, int mode) ...@@ -287,8 +290,10 @@ affs_create(struct inode *dir, struct dentry *dentry, int mode)
if (error) { if (error) {
inode->i_nlink = 0; inode->i_nlink = 0;
iput(inode); iput(inode);
unlock_kernel();
return error; return error;
} }
unlock_kernel();
return 0; return 0;
} }
......
...@@ -83,8 +83,10 @@ static int bfs_create(struct inode * dir, struct dentry * dentry, int mode) ...@@ -83,8 +83,10 @@ static int bfs_create(struct inode * dir, struct dentry * dentry, int mode)
inode = new_inode(s); inode = new_inode(s);
if (!inode) if (!inode)
return -ENOSPC; return -ENOSPC;
lock_kernel();
ino = find_first_zero_bit(s->su_imap, s->su_lasti); ino = find_first_zero_bit(s->su_imap, s->su_lasti);
if (ino > s->su_lasti) { if (ino > s->su_lasti) {
unlock_kernel();
iput(inode); iput(inode);
return -ENOSPC; return -ENOSPC;
} }
...@@ -111,8 +113,10 @@ static int bfs_create(struct inode * dir, struct dentry * dentry, int mode) ...@@ -111,8 +113,10 @@ static int bfs_create(struct inode * dir, struct dentry * dentry, int mode)
inode->i_nlink--; inode->i_nlink--;
mark_inode_dirty(inode); mark_inode_dirty(inode);
iput(inode); iput(inode);
unlock_kernel();
return err; return err;
} }
unlock_kernel();
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
return 0; return 0;
} }
......
...@@ -219,12 +219,15 @@ static int coda_create(struct inode *dir, struct dentry *de, int mode) ...@@ -219,12 +219,15 @@ static int coda_create(struct inode *dir, struct dentry *de, int mode)
struct ViceFid newfid; struct ViceFid newfid;
struct coda_vattr attrs; struct coda_vattr attrs;
lock_kernel();
coda_vfs_stat.create++; coda_vfs_stat.create++;
CDEBUG(D_INODE, "name: %s, length %d, mode %o\n", name, length, mode); CDEBUG(D_INODE, "name: %s, length %d, mode %o\n", name, length, mode);
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, 0, &newfid, &attrs); 0, mode, 0, &newfid, &attrs);
...@@ -232,12 +235,14 @@ static int coda_create(struct inode *dir, struct dentry *de, int mode) ...@@ -232,12 +235,14 @@ static int coda_create(struct inode *dir, struct dentry *de, int mode)
if ( error ) { if ( error ) {
CDEBUG(D_INODE, "create: %s, result %d\n", CDEBUG(D_INODE, "create: %s, result %d\n",
coda_f2s(&newfid), error); coda_f2s(&newfid), error);
unlock_kernel();
d_drop(de); d_drop(de);
return error; return error;
} }
error = coda_cnode_make(&result, &newfid, dir->i_sb); error = coda_cnode_make(&result, &newfid, dir->i_sb);
if ( error ) { if ( error ) {
unlock_kernel();
d_drop(de); d_drop(de);
result = NULL; result = NULL;
return error; return error;
...@@ -245,6 +250,7 @@ static int coda_create(struct inode *dir, struct dentry *de, int mode) ...@@ -245,6 +250,7 @@ static int coda_create(struct inode *dir, struct dentry *de, int mode)
/* 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;
} }
......
...@@ -1083,6 +1083,7 @@ int dquot_alloc_inode(const struct inode *inode, unsigned long number) ...@@ -1083,6 +1083,7 @@ int dquot_alloc_inode(const struct inode *inode, unsigned long number)
warntype[cnt] = NOWARN; warntype[cnt] = NOWARN;
} }
/* NOBLOCK Start */ /* NOBLOCK Start */
lock_kernel();
for (cnt = 0; cnt < MAXQUOTAS; cnt++) { for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
dquot[cnt] = dqduplicate(inode -> i_dquot[cnt]); dquot[cnt] = dqduplicate(inode -> i_dquot[cnt]);
if (dquot[cnt] == NODQUOT) if (dquot[cnt] == NODQUOT)
...@@ -1103,6 +1104,7 @@ int dquot_alloc_inode(const struct inode *inode, unsigned long number) ...@@ -1103,6 +1104,7 @@ int dquot_alloc_inode(const struct inode *inode, unsigned long number)
for (cnt = 0; cnt < MAXQUOTAS; cnt++) for (cnt = 0; cnt < MAXQUOTAS; cnt++)
if (dquot[cnt] != NODQUOT) if (dquot[cnt] != NODQUOT)
dqput(dquot[cnt]); dqput(dquot[cnt]);
unlock_kernel();
return ret; return ret;
} }
...@@ -1137,6 +1139,7 @@ void dquot_free_inode(const struct inode *inode, unsigned long number) ...@@ -1137,6 +1139,7 @@ void dquot_free_inode(const struct inode *inode, unsigned long number)
struct dquot *dquot; struct dquot *dquot;
/* NOBLOCK Start */ /* NOBLOCK Start */
lock_kernel();
for (cnt = 0; cnt < MAXQUOTAS; cnt++) { for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
dquot = dqduplicate(inode->i_dquot[cnt]); dquot = dqduplicate(inode->i_dquot[cnt]);
if (dquot == NODQUOT) if (dquot == NODQUOT)
...@@ -1144,6 +1147,7 @@ void dquot_free_inode(const struct inode *inode, unsigned long number) ...@@ -1144,6 +1147,7 @@ void dquot_free_inode(const struct inode *inode, unsigned long number)
dquot_decr_inodes(dquot, number); dquot_decr_inodes(dquot, number);
dqput(dquot); dqput(dquot);
} }
unlock_kernel();
/* NOBLOCK End */ /* NOBLOCK End */
} }
......
...@@ -127,8 +127,12 @@ static int driverfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) ...@@ -127,8 +127,12 @@ static int driverfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
static int driverfs_create(struct inode *dir, struct dentry *dentry, int mode) static int driverfs_create(struct inode *dir, struct dentry *dentry, int mode)
{ {
int res;
lock_kernel();
dentry->d_op = &driverfs_dentry_file_ops; dentry->d_op = &driverfs_dentry_file_ops;
return driverfs_mknod(dir, dentry, mode | S_IFREG, 0); res = driverfs_mknod(dir, dentry, mode | S_IFREG, 0);
unlock_kernel();
return res;
} }
static int static int
......
...@@ -105,7 +105,9 @@ static int ext2_create (struct inode * dir, struct dentry * dentry, int mode) ...@@ -105,7 +105,9 @@ static int ext2_create (struct inode * dir, struct dentry * dentry, int mode)
inode->i_fop = &ext2_file_operations; inode->i_fop = &ext2_file_operations;
inode->i_mapping->a_ops = &ext2_aops; inode->i_mapping->a_ops = &ext2_aops;
mark_inode_dirty(inode); mark_inode_dirty(inode);
lock_kernel();
err = ext2_add_nondir(dentry, inode); err = ext2_add_nondir(dentry, inode);
unlock_kernel();
} }
return err; return err;
} }
......
...@@ -456,9 +456,12 @@ static int ext3_create (struct inode * dir, struct dentry * dentry, int mode) ...@@ -456,9 +456,12 @@ static int ext3_create (struct inode * dir, struct dentry * dentry, int mode)
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;
...@@ -473,6 +476,7 @@ static int ext3_create (struct inode * dir, struct dentry * dentry, int mode) ...@@ -473,6 +476,7 @@ static int ext3_create (struct inode * dir, struct dentry * dentry, int mode)
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;
} }
...@@ -1118,8 +1122,8 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry, ...@@ -1118,8 +1122,8 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry,
* directories can handle most operations... * directories can handle most operations...
*/ */
struct inode_operations ext3_dir_inode_operations = { struct inode_operations ext3_dir_inode_operations = {
create: ext3_create, /* BKL held */ create: ext3_create,
lookup: ext3_lookup, /* BKL held */ lookup: ext3_lookup,
link: ext3_link, /* BKL held */ link: ext3_link, /* BKL held */
unlink: ext3_unlink, /* BKL held */ unlink: ext3_unlink, /* BKL held */
symlink: ext3_symlink, /* BKL held */ symlink: ext3_symlink, /* BKL held */
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/hfs_fs_sb.h> #include <linux/hfs_fs_sb.h>
#include <linux/hfs_fs_i.h> #include <linux/hfs_fs_i.h>
#include <linux/hfs_fs.h> #include <linux/hfs_fs.h>
#include <linux/smp_lock.h>
/*================ File-local functions ================*/ /*================ File-local functions ================*/
...@@ -170,15 +171,20 @@ int hfs_create(struct inode * dir, struct dentry *dentry, int mode) ...@@ -170,15 +171,20 @@ int hfs_create(struct inode * dir, struct dentry *dentry, int mode)
struct inode *inode; struct inode *inode;
int error; int error;
lock_kernel();
/* build the key, checking against reserved names */ /* build the key, checking against reserved names */
if (build_key(&key, dir, dentry->d_name.name, dentry->d_name.len)) if (build_key(&key, dir, dentry->d_name.name, dentry->d_name.len)) {
unlock_kernel();
return -EEXIST; return -EEXIST;
}
if ((error = hfs_cat_create(entry, &key, if ((error = hfs_cat_create(entry, &key,
(mode & S_IWUSR) ? 0 : HFS_FIL_LOCK, (mode & S_IWUSR) ? 0 : HFS_FIL_LOCK,
HFS_SB(dir->i_sb)->s_type, HFS_SB(dir->i_sb)->s_type,
HFS_SB(dir->i_sb)->s_creator, &new))) HFS_SB(dir->i_sb)->s_creator, &new))) {
unlock_kernel();
return error; return error;
}
/* create an inode for the new file. back out if we run /* create an inode for the new file. back out if we run
* into trouble. */ * into trouble. */
...@@ -186,6 +192,7 @@ int hfs_create(struct inode * dir, struct dentry *dentry, int mode) ...@@ -186,6 +192,7 @@ int hfs_create(struct inode * dir, struct dentry *dentry, int mode)
if (!(inode = hfs_iget(new, HFS_I(dir)->file_type, dentry))) { if (!(inode = hfs_iget(new, HFS_I(dir)->file_type, dentry))) {
hfs_cat_delete(entry, new, 1); hfs_cat_delete(entry, new, 1);
hfs_cat_put(new); hfs_cat_put(new);
unlock_kernel();
return -EIO; return -EIO;
} }
...@@ -195,6 +202,7 @@ int hfs_create(struct inode * dir, struct dentry *dentry, int mode) ...@@ -195,6 +202,7 @@ int hfs_create(struct inode * dir, struct dentry *dentry, int mode)
if (HFS_I(dir)->d_drop_op) if (HFS_I(dir)->d_drop_op)
HFS_I(dir)->d_drop_op(dentry, HFS_I(dir)->file_type); HFS_I(dir)->d_drop_op(dentry, HFS_I(dir)->file_type);
mark_inode_dirty(inode); mark_inode_dirty(inode);
unlock_kernel();
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
return 0; return 0;
} }
......
...@@ -272,11 +272,13 @@ static int dbl_create(struct inode * dir, struct dentry *dentry, ...@@ -272,11 +272,13 @@ static int dbl_create(struct inode * dir, struct dentry *dentry,
{ {
int error; int error;
lock_kernel();
if (is_hdr(dir, dentry->d_name.name, dentry->d_name.len)) { if (is_hdr(dir, dentry->d_name.name, dentry->d_name.len)) {
error = -EEXIST; error = -EEXIST;
} else { } else {
error = hfs_create(dir, dentry, mode); error = hfs_create(dir, dentry, mode);
} }
unlock_kernel();
return error; return error;
} }
......
...@@ -108,7 +108,9 @@ int hpfs_create(struct inode *dir, struct dentry *dentry, int mode) ...@@ -108,7 +108,9 @@ int hpfs_create(struct inode *dir, struct dentry *dentry, int mode)
int r; int r;
struct hpfs_dirent dee; struct hpfs_dirent dee;
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;
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;
...@@ -123,6 +125,7 @@ int hpfs_create(struct inode *dir, struct dentry *dentry, int mode) ...@@ -123,6 +125,7 @@ int hpfs_create(struct inode *dir, struct dentry *dentry, int mode)
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;
...@@ -155,12 +158,14 @@ int hpfs_create(struct inode *dir, struct dentry *dentry, int mode) ...@@ -155,12 +158,14 @@ int hpfs_create(struct inode *dir, struct dentry *dentry, int mode)
} }
hpfs_unlock_iget(dir->i_sb); hpfs_unlock_iget(dir->i_sb);
hpfs_unlock_inode(dir); hpfs_unlock_inode(dir);
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;
} }
......
...@@ -1243,6 +1243,7 @@ jffs_create(struct inode *dir, struct dentry *dentry, int mode) ...@@ -1243,6 +1243,7 @@ jffs_create(struct inode *dir, struct dentry *dentry, int mode)
struct inode *inode; struct inode *inode;
int err; int err;
lock_kernel();
D1({ D1({
int len = dentry->d_name.len; int len = dentry->d_name.len;
char *s = (char *)kmalloc(len + 1, GFP_KERNEL); char *s = (char *)kmalloc(len + 1, GFP_KERNEL);
...@@ -1256,6 +1257,7 @@ jffs_create(struct inode *dir, struct dentry *dentry, int mode) ...@@ -1256,6 +1257,7 @@ jffs_create(struct inode *dir, struct dentry *dentry, int mode)
ASSERT(if (!dir_f) { ASSERT(if (!dir_f) {
printk(KERN_ERR "jffs_create(): No reference to a " printk(KERN_ERR "jffs_create(): No reference to a "
"jffs_file struct in inode.\n"); "jffs_file struct in inode.\n");
unlock_kernel();
return -EIO; return -EIO;
}); });
...@@ -1264,6 +1266,7 @@ jffs_create(struct inode *dir, struct dentry *dentry, int mode) ...@@ -1264,6 +1266,7 @@ jffs_create(struct inode *dir, struct dentry *dentry, int mode)
/* Create a node and initialize as much as needed. */ /* Create a node and initialize as much as needed. */
if (!(node = jffs_alloc_node())) { if (!(node = jffs_alloc_node())) {
D(printk("jffs_create(): Allocation failed: node == 0\n")); D(printk("jffs_create(): Allocation failed: node == 0\n"));
unlock_kernel();
return -ENOMEM; return -ENOMEM;
} }
D3(printk (KERN_NOTICE "create(): down biglock\n")); D3(printk (KERN_NOTICE "create(): down biglock\n"));
...@@ -1321,6 +1324,7 @@ jffs_create(struct inode *dir, struct dentry *dentry, int mode) ...@@ -1321,6 +1324,7 @@ jffs_create(struct inode *dir, struct dentry *dentry, int mode)
jffs_create_end: jffs_create_end:
D3(printk (KERN_NOTICE "create(): up biglock\n")); D3(printk (KERN_NOTICE "create(): up biglock\n"));
up(&c->fmc->biglock); up(&c->fmc->biglock);
unlock_kernel();
return err; return err;
} /* jffs_create() */ } /* jffs_create() */
......
...@@ -206,9 +206,12 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode) ...@@ -206,9 +206,12 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode)
__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);
...@@ -222,6 +225,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode) ...@@ -222,6 +225,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode)
D1(printk(KERN_DEBUG "jffs2_create(): reserved 0x%x bytes\n", alloclen)); D1(printk(KERN_DEBUG "jffs2_create(): reserved 0x%x bytes\n", alloclen));
if (ret) { if (ret) {
jffs2_free_raw_inode(ri); jffs2_free_raw_inode(ri);
unlock_kernel();
return ret; return ret;
} }
...@@ -231,6 +235,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode) ...@@ -231,6 +235,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode)
D1(printk(KERN_DEBUG "jffs2_new_inode() failed\n")); D1(printk(KERN_DEBUG "jffs2_new_inode() failed\n"));
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);
} }
...@@ -254,6 +259,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode) ...@@ -254,6 +259,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode)
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
...@@ -276,6 +282,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode) ...@@ -276,6 +282,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode)
/* Eep. */ /* Eep. */
D1(printk(KERN_DEBUG "jffs2_reserve_space() for dirent failed\n")); D1(printk(KERN_DEBUG "jffs2_reserve_space() for dirent failed\n"));
jffs2_clear_inode(inode); jffs2_clear_inode(inode);
unlock_kernel();
return ret; return ret;
} }
} }
...@@ -285,6 +292,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode) ...@@ -285,6 +292,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode)
/* 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;
} }
...@@ -315,6 +323,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode) ...@@ -315,6 +323,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode)
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);
} }
...@@ -327,6 +336,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode) ...@@ -327,6 +336,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode)
D1(printk(KERN_DEBUG "jffs2_create: Created ino #%lu with mode %o, nlink %d(%d). nrpages %ld\n", D1(printk(KERN_DEBUG "jffs2_create: Created ino #%lu with mode %o, nlink %d(%d). nrpages %ld\n",
inode->i_ino, inode->i_mode, inode->i_nlink, f->inocache->nlink, inode->i_mapping->nrpages)); inode->i_ino, inode->i_mode, inode->i_nlink, f->inocache->nlink, inode->i_mapping->nrpages));
unlock_kernel();
return 0; return 0;
} }
......
...@@ -91,7 +91,9 @@ static int minix_mknod(struct inode * dir, struct dentry *dentry, int mode, int ...@@ -91,7 +91,9 @@ static int minix_mknod(struct inode * dir, struct dentry *dentry, int mode, int
inode->i_mode = mode; inode->i_mode = mode;
minix_set_inode(inode, rdev); minix_set_inode(inode, rdev);
mark_inode_dirty(inode); mark_inode_dirty(inode);
lock_kernel();
error = add_nondir(dentry, inode); error = add_nondir(dentry, inode);
unlock_kernel();
} }
return error; return error;
} }
......
...@@ -280,27 +280,36 @@ int msdos_create(struct inode *dir,struct dentry *dentry,int mode) ...@@ -280,27 +280,36 @@ int msdos_create(struct inode *dir,struct dentry *dentry,int mode)
int ino,res,is_hid; int ino,res,is_hid;
char msdos_name[MSDOS_NAME]; char msdos_name[MSDOS_NAME];
lock_kernel();
res = msdos_format_name(dentry->d_name.name,dentry->d_name.len, res = msdos_format_name(dentry->d_name.name,dentry->d_name.len,
msdos_name, &MSDOS_SB(sb)->options); msdos_name, &MSDOS_SB(sb)->options);
if (res < 0) if (res < 0) {
unlock_kernel();
return res; return res;
}
is_hid = (dentry->d_name.name[0]=='.') && (msdos_name[0]!='.'); is_hid = (dentry->d_name.name[0]=='.') && (msdos_name[0]!='.');
/* Have to do it due to foo vs. .foo conflicts */ /* Have to do it due to foo vs. .foo conflicts */
if (fat_scan(dir,msdos_name,&bh,&de,&ino) >= 0) { if (fat_scan(dir,msdos_name,&bh,&de,&ino) >= 0) {
fat_brelse(sb, bh); fat_brelse(sb, bh);
unlock_kernel();
return -EINVAL; return -EINVAL;
} }
inode = NULL; inode = NULL;
res = msdos_add_entry(dir, msdos_name, &bh, &de, &ino, 0, is_hid); res = msdos_add_entry(dir, msdos_name, &bh, &de, &ino, 0, is_hid);
if (res) if (res) {
unlock_kernel();
return res; return res;
}
inode = fat_build_inode(dir->i_sb, de, ino, &res); inode = fat_build_inode(dir->i_sb, de, ino, &res);
fat_brelse(sb, bh); fat_brelse(sb, bh);
if (!inode) if (!inode) {
unlock_kernel();
return res; return res;
}
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
mark_inode_dirty(inode); mark_inode_dirty(inode);
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
unlock_kernel();
return 0; return 0;
} }
......
...@@ -990,9 +990,7 @@ int vfs_create(struct inode *dir, struct dentry *dentry, int mode) ...@@ -990,9 +990,7 @@ int vfs_create(struct inode *dir, struct dentry *dentry, int mode)
mode &= S_IALLUGO; mode &= S_IALLUGO;
mode |= S_IFREG; mode |= S_IFREG;
lock_kernel();
error = dir->i_op->create(dir, dentry, mode); error = dir->i_op->create(dir, dentry, mode);
unlock_kernel();
if (!error) if (!error)
inode_dir_notify(dir, DN_CREATE); inode_dir_notify(dir, DN_CREATE);
return error; return error;
......
...@@ -827,6 +827,7 @@ int ncp_create_new(struct inode *dir, struct dentry *dentry, int mode, ...@@ -827,6 +827,7 @@ int ncp_create_new(struct inode *dir, struct dentry *dentry, int mode,
PPRINTK("ncp_create_new: creating %s/%s, mode=%x\n", PPRINTK("ncp_create_new: creating %s/%s, mode=%x\n",
dentry->d_parent->d_name.name, dentry->d_name.name, mode); dentry->d_parent->d_name.name, dentry->d_name.name, mode);
error = -EIO; error = -EIO;
lock_kernel();
if (!ncp_conn_valid(server)) if (!ncp_conn_valid(server))
goto out; goto out;
...@@ -863,6 +864,7 @@ int ncp_create_new(struct inode *dir, struct dentry *dentry, int mode, ...@@ -863,6 +864,7 @@ int ncp_create_new(struct inode *dir, struct dentry *dentry, int mode,
finfo.access = opmode; finfo.access = opmode;
error = ncp_instantiate(dir, dentry, &finfo); error = ncp_instantiate(dir, dentry, &finfo);
out: out:
unlock_kernel();
return error; return error;
} }
......
...@@ -642,6 +642,7 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode) ...@@ -642,6 +642,7 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode)
* select the appropriate create strategy. Currently open_namei * select the appropriate create strategy. Currently open_namei
* does not pass the create flags. * does not pass the create flags.
*/ */
lock_kernel();
nfs_zap_caches(dir); nfs_zap_caches(dir);
error = NFS_PROTO(dir)->create(dir, &dentry->d_name, error = NFS_PROTO(dir)->create(dir, &dentry->d_name,
&attr, 0, &fhandle, &fattr); &attr, 0, &fhandle, &fattr);
...@@ -649,6 +650,7 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode) ...@@ -649,6 +650,7 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode)
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;
} }
......
...@@ -578,6 +578,7 @@ static int ntfs_create(struct inode* dir, struct dentry *d, int mode) ...@@ -578,6 +578,7 @@ static int ntfs_create(struct inode* dir, struct dentry *d, int mode)
int error = 0; int error = 0;
ntfs_attribute *si; ntfs_attribute *si;
lock_kernel();
r = new_inode(dir->i_sb); r = new_inode(dir->i_sb);
if (!r) { if (!r) {
error = -ENOMEM; error = -ENOMEM;
...@@ -622,10 +623,12 @@ static int ntfs_create(struct inode* dir, struct dentry *d, int mode) ...@@ -622,10 +623,12 @@ static int ntfs_create(struct inode* dir, struct dentry *d, int mode)
r->i_mode |= S_IWUGO; r->i_mode |= S_IWUGO;
#endif #endif
r->i_mode &= ~vol->umask; r->i_mode &= ~vol->umask;
unlock_kernel();
insert_inode_hash(r); insert_inode_hash(r);
d_instantiate(d, r); d_instantiate(d, r);
return 0; return 0;
fail: fail:
unlock_kernel();
if (r) if (r)
iput(r); iput(r);
return error; return error;
......
...@@ -833,24 +833,31 @@ static int openpromfs_create (struct inode *dir, struct dentry *dentry, int mode ...@@ -833,24 +833,31 @@ static int openpromfs_create (struct inode *dir, struct dentry *dentry, int mode
return -ENOENT; return -ENOENT;
if (dentry->d_name.len > 256) if (dentry->d_name.len > 256)
return -EINVAL; return -EINVAL;
if (aliases_nodes == ALIASES_NNODES)
return -EIO;
p = kmalloc (dentry->d_name.len + 1, GFP_KERNEL); p = kmalloc (dentry->d_name.len + 1, GFP_KERNEL);
if (!p) if (!p)
return -ENOMEM; return -ENOMEM;
strncpy (p, dentry->d_name.name, dentry->d_name.len); strncpy (p, dentry->d_name.name, dentry->d_name.len);
p [dentry->d_name.len] = 0; p [dentry->d_name.len] = 0;
lock_kernel();
if (aliases_nodes == ALIASES_NNODES) {
kfree(p);
unlock_kernel();
return -EIO;
}
alias_names [aliases_nodes++] = p; alias_names [aliases_nodes++] = p;
inode = iget (dir->i_sb, inode = iget (dir->i_sb,
NODEP2INO(NODE(dir->i_ino).first_prop) + aliases_nodes); NODEP2INO(NODE(dir->i_ino).first_prop) + aliases_nodes);
if (!inode) if (!inode) {
unlock_kernel();
return -EINVAL; return -EINVAL;
}
inode->i_mode = S_IFREG | S_IRUGO | S_IWUSR; inode->i_mode = S_IFREG | S_IRUGO | S_IWUSR;
inode->i_fop = &openpromfs_prop_ops; inode->i_fop = &openpromfs_prop_ops;
inode->i_nlink = 1; inode->i_nlink = 1;
if (inode->i_size < 0) inode->i_size = 0; if (inode->i_size < 0) inode->i_size = 0;
inode->u.generic_ip = (void *)(long)(((u16)aliases) | inode->u.generic_ip = (void *)(long)(((u16)aliases) |
(((u16)(aliases_nodes - 1)) << 16)); (((u16)(aliases_nodes - 1)) << 16));
unlock_kernel();
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
return 0; return 0;
} }
......
...@@ -134,6 +134,7 @@ struct inode *ramfs_get_inode(struct super_block *sb, int mode, int dev) ...@@ -134,6 +134,7 @@ struct inode *ramfs_get_inode(struct super_block *sb, int mode, int dev)
/* /*
* File creation. Allocate an inode, and we're done.. * File creation. Allocate an inode, and we're done..
*/ */
/* SMP-safe */
static int ramfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev) static int ramfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev)
{ {
struct inode * inode = ramfs_get_inode(dir->i_sb, mode, dev); struct inode * inode = ramfs_get_inode(dir->i_sb, mode, dev);
......
...@@ -525,11 +525,11 @@ static int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode) ...@@ -525,11 +525,11 @@ static int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode)
int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 ; int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 ;
struct reiserfs_transaction_handle th ; struct reiserfs_transaction_handle th ;
inode = new_inode(dir->i_sb) ; inode = new_inode(dir->i_sb) ;
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) ;
th.t_caller = "create" ; th.t_caller = "create" ;
windex = push_journal_writer("reiserfs_create") ; windex = push_journal_writer("reiserfs_create") ;
...@@ -537,6 +537,7 @@ static int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode) ...@@ -537,6 +537,7 @@ static int reiserfs_create (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;
} }
...@@ -554,6 +555,7 @@ static int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode) ...@@ -554,6 +555,7 @@ static int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode)
// in the same transactioin // in the same transactioin
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;
} }
reiserfs_update_inode_transaction(inode) ; reiserfs_update_inode_transaction(inode) ;
...@@ -562,6 +564,7 @@ static int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode) ...@@ -562,6 +564,7 @@ static int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode)
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;
} }
......
...@@ -485,6 +485,7 @@ smb_create(struct inode *dir, struct dentry *dentry, int mode) ...@@ -485,6 +485,7 @@ smb_create(struct inode *dir, struct dentry *dentry, int mode)
VERBOSE("creating %s/%s, mode=%d\n", DENTRY_PATH(dentry), mode); VERBOSE("creating %s/%s, mode=%d\n", DENTRY_PATH(dentry), mode);
lock_kernel();
smb_invalid_dir_cache(dir); smb_invalid_dir_cache(dir);
error = smb_proc_create(dentry, 0, CURRENT_TIME, &fileid); error = smb_proc_create(dentry, 0, CURRENT_TIME, &fileid);
if (!error) { if (!error) {
...@@ -493,6 +494,7 @@ smb_create(struct inode *dir, struct dentry *dentry, int mode) ...@@ -493,6 +494,7 @@ smb_create(struct inode *dir, struct dentry *dentry, int mode)
PARANOIA("%s/%s failed, error=%d\n", PARANOIA("%s/%s failed, error=%d\n",
DENTRY_PATH(dentry), error); DENTRY_PATH(dentry), error);
} }
unlock_kernel();
return error; return error;
} }
......
...@@ -96,7 +96,9 @@ static int sysv_mknod(struct inode * dir, struct dentry * dentry, int mode, int ...@@ -96,7 +96,9 @@ static int sysv_mknod(struct inode * dir, struct dentry * dentry, int mode, int
if (!IS_ERR(inode)) { if (!IS_ERR(inode)) {
sysv_set_inode(inode, rdev); sysv_set_inode(inode, rdev);
mark_inode_dirty(inode); mark_inode_dirty(inode);
lock_kernel();
err = add_nondir(dentry, inode); err = add_nondir(dentry, inode);
unlock_kernel();
} }
return err; return err;
} }
......
...@@ -631,9 +631,12 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode) ...@@ -631,9 +631,12 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode)
struct FileIdentDesc cfi, *fi; struct FileIdentDesc cfi, *fi;
int err; int err;
lock_kernel();
inode = udf_new_inode(dir, mode, &err); inode = udf_new_inode(dir, mode, &err);
if (!inode) if (!inode) {
unlock_kernel();
return err; return err;
}
if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB) if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
inode->i_data.a_ops = &udf_adinicb_aops; inode->i_data.a_ops = &udf_adinicb_aops;
...@@ -649,6 +652,7 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode) ...@@ -649,6 +652,7 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode)
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);
...@@ -663,6 +667,7 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode) ...@@ -663,6 +667,7 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode)
if (fibh.sbh != fibh.ebh) if (fibh.sbh != fibh.ebh)
udf_release_data(fibh.ebh); udf_release_data(fibh.ebh);
udf_release_data(fibh.sbh); udf_release_data(fibh.sbh);
unlock_kernel();
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
return 0; return 0;
} }
......
...@@ -100,7 +100,9 @@ static int ufs_create (struct inode * dir, struct dentry * dentry, int mode) ...@@ -100,7 +100,9 @@ static int ufs_create (struct inode * dir, struct dentry * dentry, int mode)
inode->i_fop = &ufs_file_operations; inode->i_fop = &ufs_file_operations;
inode->i_mapping->a_ops = &ufs_aops; inode->i_mapping->a_ops = &ufs_aops;
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;
} }
......
...@@ -1031,19 +1031,25 @@ int vfat_create(struct inode *dir,struct dentry* dentry,int mode) ...@@ -1031,19 +1031,25 @@ int vfat_create(struct inode *dir,struct dentry* dentry,int mode)
struct vfat_slot_info sinfo; struct vfat_slot_info sinfo;
int res; int res;
lock_kernel();
res = vfat_add_entry(dir, &dentry->d_name, 0, &sinfo, &bh, &de); res = vfat_add_entry(dir, &dentry->d_name, 0, &sinfo, &bh, &de);
if (res < 0) if (res < 0) {
unlock_kernel();
return res; return res;
}
inode = fat_build_inode(sb, de, sinfo.ino, &res); inode = fat_build_inode(sb, de, sinfo.ino, &res);
fat_brelse(sb, bh); fat_brelse(sb, bh);
if (!inode) if (!inode) {
unlock_kernel();
return res; return res;
}
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
mark_inode_dirty(inode); mark_inode_dirty(inode);
inode->i_version++; inode->i_version++;
dir->i_version++; dir->i_version++;
dentry->d_time = dentry->d_parent->d_inode->i_version; dentry->d_time = dentry->d_parent->d_inode->i_version;
d_instantiate(dentry,inode); d_instantiate(dentry,inode);
unlock_kernel();
return 0; return 0;
} }
......
...@@ -984,6 +984,7 @@ static struct dentry * shmem_lookup(struct inode *dir, struct dentry *dentry) ...@@ -984,6 +984,7 @@ static struct dentry * shmem_lookup(struct inode *dir, struct dentry *dentry)
/* /*
* File creation. Allocate an inode, and we're done.. * File creation. Allocate an inode, and we're done..
*/ */
/* SMP-safe */
static int shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev) static int shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev)
{ {
struct inode * inode = shmem_get_inode(dir->i_sb, mode, dev); struct inode * inode = shmem_get_inode(dir->i_sb, mode, dev);
......
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