aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/reiserfs/inode.c19
-rw-r--r--fs/reiserfs/ioctl.c3
-rw-r--r--fs/reiserfs/xattr.c18
-rw-r--r--fs/reiserfs/xattr_acl.c2
4 files changed, 33 insertions, 9 deletions
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 1150ebb2536f..9087b10209e6 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -3062,13 +3062,14 @@ static ssize_t reiserfs_direct_IO(int rw, struct kiocb *iocb,
3062int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) 3062int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
3063{ 3063{
3064 struct inode *inode = dentry->d_inode; 3064 struct inode *inode = dentry->d_inode;
3065 int error;
3066 unsigned int ia_valid; 3065 unsigned int ia_valid;
3066 int depth;
3067 int error;
3067 3068
3068 /* must be turned off for recursive notify_change calls */ 3069 /* must be turned off for recursive notify_change calls */
3069 ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID); 3070 ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID);
3070 3071
3071 reiserfs_write_lock(inode->i_sb); 3072 depth = reiserfs_write_lock_once(inode->i_sb);
3072 if (attr->ia_valid & ATTR_SIZE) { 3073 if (attr->ia_valid & ATTR_SIZE) {
3073 /* version 2 items will be caught by the s_maxbytes check 3074 /* version 2 items will be caught by the s_maxbytes check
3074 ** done for us in vmtruncate 3075 ** done for us in vmtruncate
@@ -3149,8 +3150,17 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
3149 journal_end(&th, inode->i_sb, jbegin_count); 3150 journal_end(&th, inode->i_sb, jbegin_count);
3150 } 3151 }
3151 } 3152 }
3152 if (!error) 3153 if (!error) {
3154 /*
3155 * Relax the lock here, as it might truncate the
3156 * inode pages and wait for inode pages locks.
3157 * To release such page lock, the owner needs the
3158 * reiserfs lock
3159 */
3160 reiserfs_write_unlock_once(inode->i_sb, depth);
3153 error = inode_setattr(inode, attr); 3161 error = inode_setattr(inode, attr);
3162 depth = reiserfs_write_lock_once(inode->i_sb);
3163 }
3154 } 3164 }
3155 3165
3156 if (!error && reiserfs_posixacl(inode->i_sb)) { 3166 if (!error && reiserfs_posixacl(inode->i_sb)) {
@@ -3159,7 +3169,8 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
3159 } 3169 }
3160 3170
3161 out: 3171 out:
3162 reiserfs_write_unlock(inode->i_sb); 3172 reiserfs_write_unlock_once(inode->i_sb, depth);
3173
3163 return error; 3174 return error;
3164} 3175}
3165 3176
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c
index ace77451ceb1..f53505de0712 100644
--- a/fs/reiserfs/ioctl.c
+++ b/fs/reiserfs/ioctl.c
@@ -104,9 +104,10 @@ setflags_out:
104 err = put_user(inode->i_generation, (int __user *)arg); 104 err = put_user(inode->i_generation, (int __user *)arg);
105 break; 105 break;
106 case REISERFS_IOC_SETVERSION: 106 case REISERFS_IOC_SETVERSION:
107 if (!is_owner_or_cap(inode)) 107 if (!is_owner_or_cap(inode)) {
108 err = -EPERM; 108 err = -EPERM;
109 break; 109 break;
110 }
110 err = mnt_want_write(filp->f_path.mnt); 111 err = mnt_want_write(filp->f_path.mnt);
111 if (err) 112 if (err)
112 break; 113 break;
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index c3b004ee627b..81f09fab8ae4 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -452,7 +452,9 @@ static int lookup_and_delete_xattr(struct inode *inode, const char *name)
452 } 452 }
453 453
454 if (dentry->d_inode) { 454 if (dentry->d_inode) {
455 reiserfs_write_lock(inode->i_sb);
455 err = xattr_unlink(xadir->d_inode, dentry); 456 err = xattr_unlink(xadir->d_inode, dentry);
457 reiserfs_write_unlock(inode->i_sb);
456 update_ctime(inode); 458 update_ctime(inode);
457 } 459 }
458 460
@@ -486,17 +488,21 @@ reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th,
486 if (get_inode_sd_version(inode) == STAT_DATA_V1) 488 if (get_inode_sd_version(inode) == STAT_DATA_V1)
487 return -EOPNOTSUPP; 489 return -EOPNOTSUPP;
488 490
489 if (!buffer)
490 return lookup_and_delete_xattr(inode, name);
491
492 reiserfs_write_unlock(inode->i_sb); 491 reiserfs_write_unlock(inode->i_sb);
492
493 if (!buffer) {
494 err = lookup_and_delete_xattr(inode, name);
495 reiserfs_write_lock(inode->i_sb);
496 return err;
497 }
498
493 dentry = xattr_lookup(inode, name, flags); 499 dentry = xattr_lookup(inode, name, flags);
494 if (IS_ERR(dentry)) { 500 if (IS_ERR(dentry)) {
495 reiserfs_write_lock(inode->i_sb); 501 reiserfs_write_lock(inode->i_sb);
496 return PTR_ERR(dentry); 502 return PTR_ERR(dentry);
497 } 503 }
498 504
499 down_read(&REISERFS_I(inode)->i_xattr_sem); 505 down_write(&REISERFS_I(inode)->i_xattr_sem);
500 506
501 reiserfs_write_lock(inode->i_sb); 507 reiserfs_write_lock(inode->i_sb);
502 508
@@ -554,8 +560,12 @@ reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th,
554 .ia_size = buffer_size, 560 .ia_size = buffer_size,
555 .ia_valid = ATTR_SIZE | ATTR_CTIME, 561 .ia_valid = ATTR_SIZE | ATTR_CTIME,
556 }; 562 };
563
564 reiserfs_write_unlock(inode->i_sb);
557 mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_XATTR); 565 mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_XATTR);
558 down_write(&dentry->d_inode->i_alloc_sem); 566 down_write(&dentry->d_inode->i_alloc_sem);
567 reiserfs_write_lock(inode->i_sb);
568
559 err = reiserfs_setattr(dentry, &newattrs); 569 err = reiserfs_setattr(dentry, &newattrs);
560 up_write(&dentry->d_inode->i_alloc_sem); 570 up_write(&dentry->d_inode->i_alloc_sem);
561 mutex_unlock(&dentry->d_inode->i_mutex); 571 mutex_unlock(&dentry->d_inode->i_mutex);
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c
index cc32e6ada67b..dd20a7883f0f 100644
--- a/fs/reiserfs/xattr_acl.c
+++ b/fs/reiserfs/xattr_acl.c
@@ -455,7 +455,9 @@ int reiserfs_acl_chmod(struct inode *inode)
455 return 0; 455 return 0;
456 } 456 }
457 457
458 reiserfs_write_unlock(inode->i_sb);
458 acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS); 459 acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS);
460 reiserfs_write_lock(inode->i_sb);
459 if (!acl) 461 if (!acl)
460 return 0; 462 return 0;
461 if (IS_ERR(acl)) 463 if (IS_ERR(acl))