diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-01-08 17:03:55 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-01-08 17:03:55 -0500 |
commit | 82062e7b50280bcf0feca70ac35a44f375602976 (patch) | |
tree | 0321bff42945768990a92c3770d4270497c0e8ee | |
parent | dbd6a7cfead4fa2d7ad3fefe47168fcb146ac5ba (diff) | |
parent | 31370f62baa1460b785cee9944bdcaf63d19e567 (diff) |
Merge branch 'reiserfs/kill-bkl' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic/random-tracing
* 'reiserfs/kill-bkl' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic/random-tracing:
reiserfs: Relax reiserfs_xattr_set_handle() while acquiring xattr locks
reiserfs: Fix unreachable statement
reiserfs: Don't call reiserfs_get_acl() with the reiserfs lock
reiserfs: Relax lock on xattr removing
reiserfs: Relax the lock before truncating pages
reiserfs: Fix recursive lock on lchown
reiserfs: Fix mistake in down_write() conversion
-rw-r--r-- | fs/reiserfs/inode.c | 19 | ||||
-rw-r--r-- | fs/reiserfs/ioctl.c | 3 | ||||
-rw-r--r-- | fs/reiserfs/xattr.c | 18 | ||||
-rw-r--r-- | fs/reiserfs/xattr_acl.c | 2 |
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, | |||
3062 | int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) | 3062 | int 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)) |