Commit db3c9117 authored by Dave Hansen's avatar Dave Hansen Committed by Linus Torvalds

[PATCH] shift BKL out of notify_change

Moved i_sem down into notify_change() and out of the UMSDOS
function. Moved BKL down from notify_change into filesystems.
parent 6f4b1d4b
...@@ -302,6 +302,8 @@ adfs_notify_change(struct dentry *dentry, struct iattr *attr) ...@@ -302,6 +302,8 @@ adfs_notify_change(struct dentry *dentry, struct iattr *attr)
struct super_block *sb = inode->i_sb; struct super_block *sb = inode->i_sb;
unsigned int ia_valid = attr->ia_valid; unsigned int ia_valid = attr->ia_valid;
int error; int error;
lock_kernel();
error = inode_change_ok(inode, attr); error = inode_change_ok(inode, attr);
...@@ -346,6 +348,7 @@ adfs_notify_change(struct dentry *dentry, struct iattr *attr) ...@@ -346,6 +348,7 @@ adfs_notify_change(struct dentry *dentry, struct iattr *attr)
if (ia_valid & (ATTR_SIZE | ATTR_MTIME | ATTR_MODE)) if (ia_valid & (ATTR_SIZE | ATTR_MTIME | ATTR_MODE))
mark_inode_dirty(inode); mark_inode_dirty(inode);
out: out:
unlock_kernel();
return error; return error;
} }
......
...@@ -235,6 +235,8 @@ affs_notify_change(struct dentry *dentry, struct iattr *attr) ...@@ -235,6 +235,8 @@ affs_notify_change(struct dentry *dentry, struct iattr *attr)
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
int error; int error;
lock_kernel();
pr_debug("AFFS: notify_change(%lu,0x%x)\n",inode->i_ino,attr->ia_valid); pr_debug("AFFS: notify_change(%lu,0x%x)\n",inode->i_ino,attr->ia_valid);
error = inode_change_ok(inode,attr); error = inode_change_ok(inode,attr);
...@@ -254,6 +256,7 @@ affs_notify_change(struct dentry *dentry, struct iattr *attr) ...@@ -254,6 +256,7 @@ affs_notify_change(struct dentry *dentry, struct iattr *attr)
if (!error && (attr->ia_valid & ATTR_MODE)) if (!error && (attr->ia_valid & ATTR_MODE))
mode_to_prot(inode); mode_to_prot(inode);
out: out:
unlock_kernel();
return error; return error;
} }
......
...@@ -21,6 +21,8 @@ int inode_change_ok(struct inode *inode, struct iattr *attr) ...@@ -21,6 +21,8 @@ int inode_change_ok(struct inode *inode, struct iattr *attr)
int retval = -EPERM; int retval = -EPERM;
unsigned int ia_valid = attr->ia_valid; unsigned int ia_valid = attr->ia_valid;
lock_kernel();
/* If force is set do it anyway. */ /* If force is set do it anyway. */
if (ia_valid & ATTR_FORCE) if (ia_valid & ATTR_FORCE)
goto fine; goto fine;
...@@ -55,6 +57,7 @@ int inode_change_ok(struct inode *inode, struct iattr *attr) ...@@ -55,6 +57,7 @@ int inode_change_ok(struct inode *inode, struct iattr *attr)
fine: fine:
retval = 0; retval = 0;
error: error:
unlock_kernel();
return retval; return retval;
} }
...@@ -62,7 +65,8 @@ int inode_setattr(struct inode * inode, struct iattr * attr) ...@@ -62,7 +65,8 @@ int inode_setattr(struct inode * inode, struct iattr * attr)
{ {
unsigned int ia_valid = attr->ia_valid; unsigned int ia_valid = attr->ia_valid;
int error = 0; int error = 0;
lock_kernel();
if (ia_valid & ATTR_SIZE) { if (ia_valid & ATTR_SIZE) {
error = vmtruncate(inode, attr->ia_size); error = vmtruncate(inode, attr->ia_size);
if (error) if (error)
...@@ -86,6 +90,7 @@ int inode_setattr(struct inode * inode, struct iattr * attr) ...@@ -86,6 +90,7 @@ int inode_setattr(struct inode * inode, struct iattr * attr)
} }
mark_inode_dirty(inode); mark_inode_dirty(inode);
out: out:
unlock_kernel();
return error; return error;
} }
...@@ -127,7 +132,7 @@ int notify_change(struct dentry * dentry, struct iattr * attr) ...@@ -127,7 +132,7 @@ int notify_change(struct dentry * dentry, struct iattr * attr)
if (!(ia_valid & ATTR_MTIME_SET)) if (!(ia_valid & ATTR_MTIME_SET))
attr->ia_mtime = now; attr->ia_mtime = now;
lock_kernel(); down(&inode->i_sem);
if (inode->i_op && inode->i_op->setattr) if (inode->i_op && inode->i_op->setattr)
error = inode->i_op->setattr(dentry, attr); error = inode->i_op->setattr(dentry, attr);
else { else {
...@@ -140,7 +145,7 @@ int notify_change(struct dentry * dentry, struct iattr * attr) ...@@ -140,7 +145,7 @@ int notify_change(struct dentry * dentry, struct iattr * attr)
error = inode_setattr(inode, attr); error = inode_setattr(inode, attr);
} }
} }
unlock_kernel(); up(&inode->i_sem);
if (!error) { if (!error) {
unsigned long dn_mask = setattr_mask(ia_valid); unsigned long dn_mask = setattr_mask(ia_valid);
if (dn_mask) if (dn_mask)
......
...@@ -258,6 +258,8 @@ int coda_notify_change(struct dentry *de, struct iattr *iattr) ...@@ -258,6 +258,8 @@ int coda_notify_change(struct dentry *de, struct iattr *iattr)
struct coda_vattr vattr; struct coda_vattr vattr;
int error; int error;
lock_kernel();
memset(&vattr, 0, sizeof(vattr)); memset(&vattr, 0, sizeof(vattr));
inode->i_ctime = CURRENT_TIME; inode->i_ctime = CURRENT_TIME;
...@@ -272,6 +274,8 @@ int coda_notify_change(struct dentry *de, struct iattr *iattr) ...@@ -272,6 +274,8 @@ int coda_notify_change(struct dentry *de, struct iattr *iattr)
coda_cache_clear_inode(inode); coda_cache_clear_inode(inode);
} }
unlock_kernel();
return error; return error;
} }
......
...@@ -1054,17 +1054,24 @@ int fat_notify_change(struct dentry * dentry, struct iattr * attr) ...@@ -1054,17 +1054,24 @@ int fat_notify_change(struct dentry * dentry, struct iattr * attr)
{ {
struct super_block *sb = dentry->d_sb; struct super_block *sb = dentry->d_sb;
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
int error; int error = 0;
lock_kernel();
/* FAT cannot truncate to a longer file */ /* FAT cannot truncate to a longer file */
if (attr->ia_valid & ATTR_SIZE) { if (attr->ia_valid & ATTR_SIZE) {
if (attr->ia_size > inode->i_size) if (attr->ia_size > inode->i_size) {
return -EPERM; error = -EPERM;
goto out;
}
} }
error = inode_change_ok(inode, attr); error = inode_change_ok(inode, attr);
if (error) if (error) {
return MSDOS_SB(sb)->options.quiet ? 0 : error; if( MSDOS_SB(sb)->options.quiet )
error = 0;
goto out;
}
if (((attr->ia_valid & ATTR_UID) && if (((attr->ia_valid & ATTR_UID) &&
(attr->ia_uid != MSDOS_SB(sb)->options.fs_uid)) || (attr->ia_uid != MSDOS_SB(sb)->options.fs_uid)) ||
...@@ -1074,12 +1081,13 @@ int fat_notify_change(struct dentry * dentry, struct iattr * attr) ...@@ -1074,12 +1081,13 @@ int fat_notify_change(struct dentry * dentry, struct iattr * attr)
(attr->ia_mode & ~MSDOS_VALID_MODE))) (attr->ia_mode & ~MSDOS_VALID_MODE)))
error = -EPERM; error = -EPERM;
if (error) if (error) {
return MSDOS_SB(sb)->options.quiet ? 0 : error; if( MSDOS_SB(sb)->options.quiet )
error = 0;
error = inode_setattr(inode, attr); goto out;
if (error) }
return error; if( error = inode_setattr(inode, attr) )
goto out;
if (S_ISDIR(inode->i_mode)) if (S_ISDIR(inode->i_mode))
inode->i_mode |= S_IXUGO; inode->i_mode |= S_IXUGO;
...@@ -1087,6 +1095,8 @@ int fat_notify_change(struct dentry * dentry, struct iattr * attr) ...@@ -1087,6 +1095,8 @@ int fat_notify_change(struct dentry * dentry, struct iattr * attr)
inode->i_mode = ((inode->i_mode & S_IFMT) | ((((inode->i_mode & S_IRWXU inode->i_mode = ((inode->i_mode & S_IFMT) | ((((inode->i_mode & S_IRWXU
& ~MSDOS_SB(sb)->options.fs_umask) | S_IRUSR) >> 6)*S_IXUGO)) & & ~MSDOS_SB(sb)->options.fs_umask) | S_IRUSR) >> 6)*S_IXUGO)) &
~MSDOS_SB(sb)->options.fs_umask; ~MSDOS_SB(sb)->options.fs_umask;
return 0; out:
unlock_kernel();
return error;
} }
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -117,17 +117,18 @@ static int __hfs_notify_change(struct dentry *dentry, struct iattr * attr, int k ...@@ -117,17 +117,18 @@ static int __hfs_notify_change(struct dentry *dentry, struct iattr * attr, int k
struct hfs_cat_entry *entry = HFS_I(inode)->entry; struct hfs_cat_entry *entry = HFS_I(inode)->entry;
struct dentry **de = entry->sys_entry; struct dentry **de = entry->sys_entry;
struct hfs_sb_info *hsb = HFS_SB(inode->i_sb); struct hfs_sb_info *hsb = HFS_SB(inode->i_sb);
int error, i; int error=0, i;
lock_kernel();
error = inode_change_ok(inode, attr); /* basic permission checks */ error = inode_change_ok(inode, attr); /* basic permission checks */
if (error) { if (error) {
/* Let netatalk's afpd think chmod() always succeeds */ /* Let netatalk's afpd think chmod() always succeeds */
if (hsb->s_afpd && if (hsb->s_afpd &&
(attr->ia_valid == (ATTR_MODE | ATTR_CTIME))) { (attr->ia_valid == (ATTR_MODE | ATTR_CTIME))) {
return 0; error = 0;
} else {
return error;
} }
goto out;
} }
/* no uig/gid changes and limit which mode bits can be set */ /* no uig/gid changes and limit which mode bits can be set */
...@@ -139,7 +140,10 @@ static int __hfs_notify_change(struct dentry *dentry, struct iattr * attr, int k ...@@ -139,7 +140,10 @@ static int __hfs_notify_change(struct dentry *dentry, struct iattr * attr, int k
(((entry->type == HFS_CDR_DIR) && (((entry->type == HFS_CDR_DIR) &&
(attr->ia_mode != inode->i_mode))|| (attr->ia_mode != inode->i_mode))||
(attr->ia_mode & ~HFS_VALID_MODE_BITS)))) { (attr->ia_mode & ~HFS_VALID_MODE_BITS)))) {
return hsb->s_quiet ? 0 : error; if( hsb->s_quiet ) {
error = 0;
goto out;
}
} }
if (entry->type == HFS_CDR_DIR) { if (entry->type == HFS_CDR_DIR) {
...@@ -170,9 +174,9 @@ static int __hfs_notify_change(struct dentry *dentry, struct iattr * attr, int k ...@@ -170,9 +174,9 @@ static int __hfs_notify_change(struct dentry *dentry, struct iattr * attr, int k
} }
} }
error = inode_setattr(inode, attr); error = inode_setattr(inode, attr);
if (error) if (error)
return error; goto out;
/* We wouldn't want to mess with the sizes of the other fork */ /* We wouldn't want to mess with the sizes of the other fork */
attr->ia_valid &= ~ATTR_SIZE; attr->ia_valid &= ~ATTR_SIZE;
...@@ -204,7 +208,9 @@ static int __hfs_notify_change(struct dentry *dentry, struct iattr * attr, int k ...@@ -204,7 +208,9 @@ static int __hfs_notify_change(struct dentry *dentry, struct iattr * attr, int k
} }
/* size changes handled in hfs_extent_adj() */ /* size changes handled in hfs_extent_adj() */
return 0; out:
unlock_kernel();
return error;
} }
int hfs_notify_change(struct dentry *dentry, struct iattr * attr) int hfs_notify_change(struct dentry *dentry, struct iattr * attr)
......
...@@ -303,15 +303,18 @@ void hpfs_write_inode_nolock(struct inode *i) ...@@ -303,15 +303,18 @@ void hpfs_write_inode_nolock(struct inode *i)
int hpfs_notify_change(struct dentry *dentry, struct iattr *attr) int hpfs_notify_change(struct dentry *dentry, struct iattr *attr)
{ {
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
int error; int error=0;
if ((attr->ia_valid & ATTR_SIZE) && attr->ia_size > inode->i_size) lock_kernel();
return -EINVAL; if ( ((attr->ia_valid & ATTR_SIZE) && attr->ia_size > inode->i_size) ||
if (inode->i_sb->s_hpfs_root == inode->i_ino) return -EINVAL; (inode->i_sb->s_hpfs_root == inode->i_ino) ) {
if ((error = inode_change_ok(inode, attr))) return error; error = -EINVAL;
error = inode_setattr(inode, attr); } else if ((error = inode_change_ok(inode, attr))) {
if (error) return error; } else if ((error = inode_setattr(inode, attr))) {
hpfs_write_inode(inode); } else {
return 0; hpfs_write_inode(inode);
}
unlock_kernel();
return error;
} }
void hpfs_write_if_changed(struct inode *inode) void hpfs_write_if_changed(struct inode *inode)
......
...@@ -143,6 +143,7 @@ void inode_init_once(struct inode *inode) ...@@ -143,6 +143,7 @@ void inode_init_once(struct inode *inode)
INIT_LIST_HEAD(&inode->i_dirty_data_buffers); INIT_LIST_HEAD(&inode->i_dirty_data_buffers);
INIT_LIST_HEAD(&inode->i_devices); INIT_LIST_HEAD(&inode->i_devices);
sema_init(&inode->i_sem, 1); sema_init(&inode->i_sem, 1);
sema_init(&inode->i_attr_lock, 1);
spin_lock_init(&inode->i_data.i_shared_lock); spin_lock_init(&inode->i_data.i_shared_lock);
INIT_LIST_HEAD(&inode->i_data.i_mmap); INIT_LIST_HEAD(&inode->i_data.i_mmap);
INIT_LIST_HEAD(&inode->i_data.i_mmap_shared); INIT_LIST_HEAD(&inode->i_data.i_mmap_shared);
......
...@@ -282,11 +282,13 @@ int presto_setattr(struct dentry *de, struct iattr *iattr) ...@@ -282,11 +282,13 @@ int presto_setattr(struct dentry *de, struct iattr *iattr)
struct presto_file_set *fset; struct presto_file_set *fset;
struct lento_vfs_context info = { 0, 0, 0 }; struct lento_vfs_context info = { 0, 0, 0 };
lock_kernel();
ENTRY; ENTRY;
error = presto_prep(de, &cache, &fset); error = presto_prep(de, &cache, &fset);
if ( error ) { if ( error ) {
EXIT; EXIT;
return error; goto out;
} }
if (!iattr->ia_valid) if (!iattr->ia_valid)
...@@ -300,7 +302,8 @@ int presto_setattr(struct dentry *de, struct iattr *iattr) ...@@ -300,7 +302,8 @@ int presto_setattr(struct dentry *de, struct iattr *iattr)
if ( presto_get_permit(de->d_inode) < 0 ) { if ( presto_get_permit(de->d_inode) < 0 ) {
EXIT; EXIT;
return -EROFS; error = -EROFS;
goto out;
} }
if (!ISLENTO(presto_c2m(cache))) if (!ISLENTO(presto_c2m(cache)))
...@@ -308,6 +311,8 @@ int presto_setattr(struct dentry *de, struct iattr *iattr) ...@@ -308,6 +311,8 @@ int presto_setattr(struct dentry *de, struct iattr *iattr)
info.flags |= LENTO_FL_IGNORE_TIME; info.flags |= LENTO_FL_IGNORE_TIME;
error = presto_do_setattr(fset, de, iattr, &info); error = presto_do_setattr(fset, de, iattr, &info);
presto_put_permit(de->d_inode); presto_put_permit(de->d_inode);
out:
unlock_kernel();
return error; return error;
} }
......
...@@ -196,11 +196,13 @@ jffs_setattr(struct dentry *dentry, struct iattr *iattr) ...@@ -196,11 +196,13 @@ jffs_setattr(struct dentry *dentry, struct iattr *iattr)
struct jffs_file *f; struct jffs_file *f;
struct jffs_node *new_node; struct jffs_node *new_node;
int update_all; int update_all;
int res; int res = 0;
int recoverable = 0; int recoverable = 0;
if ((res = inode_change_ok(inode, iattr))) lock_kernel();
return res;
if ((res = inode_change_ok(inode, iattr)))
goto out;
c = (struct jffs_control *)inode->i_sb->u.generic_sbp; c = (struct jffs_control *)inode->i_sb->u.generic_sbp;
fmc = c->fmc; fmc = c->fmc;
...@@ -215,7 +217,8 @@ jffs_setattr(struct dentry *dentry, struct iattr *iattr) ...@@ -215,7 +217,8 @@ jffs_setattr(struct dentry *dentry, struct iattr *iattr)
inode->i_ino); inode->i_ino);
D3(printk (KERN_NOTICE "notify_change(): up biglock\n")); D3(printk (KERN_NOTICE "notify_change(): up biglock\n"));
up(&fmc->biglock); up(&fmc->biglock);
return -EINVAL; res = -EINVAL;
goto out;
}); });
D1(printk("***jffs_setattr(): file: \"%s\", ino: %u\n", D1(printk("***jffs_setattr(): file: \"%s\", ino: %u\n",
...@@ -235,7 +238,8 @@ jffs_setattr(struct dentry *dentry, struct iattr *iattr) ...@@ -235,7 +238,8 @@ jffs_setattr(struct dentry *dentry, struct iattr *iattr)
D(printk("jffs_setattr(): Allocation failed!\n")); D(printk("jffs_setattr(): Allocation failed!\n"));
D3(printk (KERN_NOTICE "notify_change(): up biglock\n")); D3(printk (KERN_NOTICE "notify_change(): up biglock\n"));
up(&fmc->biglock); up(&fmc->biglock);
return -ENOMEM; res = -ENOMEM;
goto out;
} }
new_node->data_offset = 0; new_node->data_offset = 0;
...@@ -321,7 +325,7 @@ jffs_setattr(struct dentry *dentry, struct iattr *iattr) ...@@ -321,7 +325,7 @@ jffs_setattr(struct dentry *dentry, struct iattr *iattr)
jffs_free_node(new_node); jffs_free_node(new_node);
D3(printk (KERN_NOTICE "n_c(): up biglock\n")); D3(printk (KERN_NOTICE "n_c(): up biglock\n"));
up(&c->fmc->biglock); up(&c->fmc->biglock);
return res; goto out;
} }
jffs_insert_node(c, f, &raw_inode, 0, new_node); jffs_insert_node(c, f, &raw_inode, 0, new_node);
...@@ -329,7 +333,9 @@ jffs_setattr(struct dentry *dentry, struct iattr *iattr) ...@@ -329,7 +333,9 @@ jffs_setattr(struct dentry *dentry, struct iattr *iattr)
mark_inode_dirty(inode); mark_inode_dirty(inode);
D3(printk (KERN_NOTICE "n_c(): up biglock\n")); D3(printk (KERN_NOTICE "n_c(): up biglock\n"));
up(&c->fmc->biglock); up(&c->fmc->biglock);
return 0; out:
unlock_kernel();
return res;
} /* jffs_notify_change() */ } /* jffs_notify_change() */
......
...@@ -109,11 +109,12 @@ int jffs2_setattr (struct dentry *dentry, struct iattr *iattr) ...@@ -109,11 +109,12 @@ int jffs2_setattr (struct dentry *dentry, struct iattr *iattr)
int mdatalen = 0; int mdatalen = 0;
unsigned int ivalid; unsigned int ivalid;
uint32_t phys_ofs, alloclen; uint32_t phys_ofs, alloclen;
int ret; int ret = 0;
lock_kernel();
D1(printk(KERN_DEBUG "jffs2_setattr(): ino #%lu\n", inode->i_ino)); D1(printk(KERN_DEBUG "jffs2_setattr(): ino #%lu\n", inode->i_ino));
ret = inode_change_ok(inode, iattr); ret = inode_change_ok(inode, iattr);
if (ret) if (ret)
return ret; goto out;
/* Special cases - we don't want more than one data node /* Special cases - we don't want more than one data node
for these types on the medium at any time. So setattr for these types on the medium at any time. So setattr
...@@ -130,12 +131,14 @@ int jffs2_setattr (struct dentry *dentry, struct iattr *iattr) ...@@ -130,12 +131,14 @@ int jffs2_setattr (struct dentry *dentry, struct iattr *iattr)
} else if (S_ISLNK(inode->i_mode)) { } else if (S_ISLNK(inode->i_mode)) {
mdatalen = f->metadata->size; mdatalen = f->metadata->size;
mdata = kmalloc(f->metadata->size, GFP_USER); mdata = kmalloc(f->metadata->size, GFP_USER);
if (!mdata) if (!mdata) {
return -ENOMEM; ret = -ENOMEM;
goto out;
}
ret = jffs2_read_dnode(c, f->metadata, mdata, 0, mdatalen); ret = jffs2_read_dnode(c, f->metadata, mdata, 0, mdatalen);
if (ret) { if (ret) {
kfree(mdata); kfree(mdata);
return ret; goto out;
} }
D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of symlink target\n", mdatalen)); D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of symlink target\n", mdatalen));
} }
...@@ -144,7 +147,8 @@ int jffs2_setattr (struct dentry *dentry, struct iattr *iattr) ...@@ -144,7 +147,8 @@ int jffs2_setattr (struct dentry *dentry, struct iattr *iattr)
if (!ri) { if (!ri) {
if (S_ISLNK(inode->i_mode)) if (S_ISLNK(inode->i_mode))
kfree(mdata); kfree(mdata);
return -ENOMEM; ret = -ENOMEM;
goto out;
} }
ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &phys_ofs, &alloclen, ALLOC_NORMAL); ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &phys_ofs, &alloclen, ALLOC_NORMAL);
...@@ -152,7 +156,7 @@ int jffs2_setattr (struct dentry *dentry, struct iattr *iattr) ...@@ -152,7 +156,7 @@ int jffs2_setattr (struct dentry *dentry, struct iattr *iattr)
jffs2_free_raw_inode(ri); jffs2_free_raw_inode(ri);
if (S_ISLNK(inode->i_mode & S_IFMT)) if (S_ISLNK(inode->i_mode & S_IFMT))
kfree(mdata); kfree(mdata);
return ret; goto out;
} }
down(&f->sem); down(&f->sem);
ivalid = iattr->ia_valid; ivalid = iattr->ia_valid;
...@@ -201,7 +205,8 @@ int jffs2_setattr (struct dentry *dentry, struct iattr *iattr) ...@@ -201,7 +205,8 @@ int jffs2_setattr (struct dentry *dentry, struct iattr *iattr)
jffs2_complete_reservation(c); jffs2_complete_reservation(c);
jffs2_free_raw_inode(ri); jffs2_free_raw_inode(ri);
up(&f->sem); up(&f->sem);
return PTR_ERR(new_metadata); ret = PTR_ERR(new_metadata);
goto out;
} }
/* It worked. Update the inode */ /* It worked. Update the inode */
inode->i_atime = ri->atime; inode->i_atime = ri->atime;
...@@ -235,7 +240,9 @@ int jffs2_setattr (struct dentry *dentry, struct iattr *iattr) ...@@ -235,7 +240,9 @@ int jffs2_setattr (struct dentry *dentry, struct iattr *iattr)
up(&f->sem); up(&f->sem);
jffs2_complete_reservation(c); jffs2_complete_reservation(c);
return 0; out:
unlock_kernel();
return ret;
} }
int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg) int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg)
......
...@@ -592,6 +592,8 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr) ...@@ -592,6 +592,8 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
result = -EIO; result = -EIO;
lock_kernel();
server = NCP_SERVER(inode); server = NCP_SERVER(inode);
if ((!server) || !ncp_conn_valid(server)) if ((!server) || !ncp_conn_valid(server))
goto out; goto out;
...@@ -636,7 +638,8 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr) ...@@ -636,7 +638,8 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
info.attributes |= (aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT); info.attributes |= (aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
} else if (!S_ISREG(inode->i_mode)) } else if (!S_ISREG(inode->i_mode))
{ {
return -EPERM; result = -EPERM;
goto out;
} }
else else
{ {
...@@ -722,7 +725,8 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr) ...@@ -722,7 +725,8 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
attr->ia_size); attr->ia_size);
if ((result = ncp_make_open(inode, O_WRONLY)) < 0) { if ((result = ncp_make_open(inode, O_WRONLY)) < 0) {
return -EACCES; result = -EACCES;
goto out;
} }
ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle, ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
attr->ia_size, 0, "", &written); attr->ia_size, 0, "", &written);
...@@ -735,6 +739,7 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr) ...@@ -735,6 +739,7 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
result = vmtruncate(inode, attr->ia_size); result = vmtruncate(inode, attr->ia_size);
} }
out: out:
unlock_kernel();
return result; return result;
} }
......
...@@ -733,6 +733,8 @@ nfs_notify_change(struct dentry *dentry, struct iattr *attr) ...@@ -733,6 +733,8 @@ nfs_notify_change(struct dentry *dentry, struct iattr *attr)
struct nfs_fattr fattr; struct nfs_fattr fattr;
int error; int error;
lock_kernel();
/* /*
* Make sure the inode is up-to-date. * Make sure the inode is up-to-date.
*/ */
...@@ -781,6 +783,7 @@ printk("nfs_notify_change: revalidate failed, error=%d\n", error); ...@@ -781,6 +783,7 @@ printk("nfs_notify_change: revalidate failed, error=%d\n", error);
NFS_CACHEINV(inode); NFS_CACHEINV(inode);
error = nfs_refresh_inode(inode, &fattr); error = nfs_refresh_inode(inode, &fattr);
out: out:
unlock_kernel();
return error; return error;
} }
......
...@@ -81,11 +81,9 @@ int do_truncate(struct dentry *dentry, loff_t length) ...@@ -81,11 +81,9 @@ int do_truncate(struct dentry *dentry, loff_t length)
if (length < 0) if (length < 0)
return -EINVAL; return -EINVAL;
down(&inode->i_sem);
newattrs.ia_size = length; newattrs.ia_size = length;
newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
error = notify_change(dentry, &newattrs); error = notify_change(dentry, &newattrs);
up(&inode->i_sem);
return error; return error;
} }
......
...@@ -95,14 +95,16 @@ static int reiserfs_sync_file( ...@@ -95,14 +95,16 @@ static int reiserfs_sync_file(
static int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) { static int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) {
struct inode *inode = dentry->d_inode ; struct inode *inode = dentry->d_inode ;
int error ; int error ;
lock_kernel();
if (attr->ia_valid & ATTR_SIZE) { if (attr->ia_valid & ATTR_SIZE) {
/* version 2 items will be caught by the s_maxbytes check /* version 2 items will be caught by the s_maxbytes check
** done for us in vmtruncate ** done for us in vmtruncate
*/ */
if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5 && if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5 &&
attr->ia_size > MAX_NON_LFS) attr->ia_size > MAX_NON_LFS) {
return -EFBIG ; error = -EFBIG ;
goto out;
}
/* fill in hole pointers in the expanding truncate case. */ /* fill in hole pointers in the expanding truncate case. */
if (attr->ia_size > inode->i_size) { if (attr->ia_size > inode->i_size) {
error = generic_cont_expand(inode, attr->ia_size) ; error = generic_cont_expand(inode, attr->ia_size) ;
...@@ -114,20 +116,24 @@ static int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) { ...@@ -114,20 +116,24 @@ static int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) {
journal_end(&th, inode->i_sb, 4) ; journal_end(&th, inode->i_sb, 4) ;
} }
if (error) if (error)
return error ; goto out;
} }
} }
if ((((attr->ia_valid & ATTR_UID) && (attr->ia_uid & ~0xffff)) || if ((((attr->ia_valid & ATTR_UID) && (attr->ia_uid & ~0xffff)) ||
((attr->ia_valid & ATTR_GID) && (attr->ia_gid & ~0xffff))) && ((attr->ia_valid & ATTR_GID) && (attr->ia_gid & ~0xffff))) &&
(get_inode_sd_version (inode) == STAT_DATA_V1)) (get_inode_sd_version (inode) == STAT_DATA_V1)) {
/* stat data of format v3.5 has 16 bit uid and gid */ /* stat data of format v3.5 has 16 bit uid and gid */
return -EINVAL; error = -EINVAL;
goto out;
}
error = inode_change_ok(inode, attr) ; error = inode_change_ok(inode, attr) ;
if (!error) if (!error)
inode_setattr(inode, attr) ; inode_setattr(inode, attr) ;
out:
unlock_kernel();
return error ; return error ;
} }
......
...@@ -621,6 +621,8 @@ smb_notify_change(struct dentry *dentry, struct iattr *attr) ...@@ -621,6 +621,8 @@ smb_notify_change(struct dentry *dentry, struct iattr *attr)
int error, changed, refresh = 0; int error, changed, refresh = 0;
struct smb_fattr fattr; struct smb_fattr fattr;
lock_kernel();
error = smb_revalidate_inode(dentry); error = smb_revalidate_inode(dentry);
if (error) if (error)
goto out; goto out;
...@@ -714,6 +716,7 @@ smb_notify_change(struct dentry *dentry, struct iattr *attr) ...@@ -714,6 +716,7 @@ smb_notify_change(struct dentry *dentry, struct iattr *attr)
out: out:
if (refresh) if (refresh)
smb_refresh_inode(dentry); smb_refresh_inode(dentry);
unlock_kernel();
return error; return error;
} }
......
...@@ -165,6 +165,8 @@ int UMSDOS_notify_change (struct dentry *dentry, struct iattr *attr) ...@@ -165,6 +165,8 @@ int UMSDOS_notify_change (struct dentry *dentry, struct iattr *attr)
struct dentry *temp, *old_dentry = NULL; struct dentry *temp, *old_dentry = NULL;
int ret; int ret;
lock_kernel();
ret = umsdos_parse (dentry->d_name.name, dentry->d_name.len, ret = umsdos_parse (dentry->d_name.name, dentry->d_name.len,
&info); &info);
if (ret) if (ret)
...@@ -208,14 +210,13 @@ dentry->d_parent->d_name.name, dentry->d_name.name, info.fake.fname)); ...@@ -208,14 +210,13 @@ dentry->d_parent->d_name.name, dentry->d_name.name, info.fake.fname));
if (ret) if (ret)
goto out; goto out;
down(&dir->i_sem);
ret = umsdos_notify_change_locked(dentry, attr); ret = umsdos_notify_change_locked(dentry, attr);
up(&dir->i_sem);
if (ret == 0) if (ret == 0)
ret = inode_setattr (inode, attr); ret = inode_setattr (inode, attr);
out: out:
if (old_dentry) if (old_dentry)
dput (dentry); /* if we had to use fake dentry for hardlinks, dput() it now */ dput (dentry); /* if we had to use fake dentry for hardlinks, dput() it now */
unlock_kernel();
return ret; return ret;
} }
......
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