diff options
Diffstat (limited to 'fs/reiserfs/inode.c')
-rw-r--r-- | fs/reiserfs/inode.c | 19 |
1 files changed, 15 insertions, 4 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 | ||