diff options
Diffstat (limited to 'fs/reiserfs')
-rw-r--r-- | fs/reiserfs/inode.c | 97 |
1 files changed, 52 insertions, 45 deletions
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 045729f5674a..2b8dc5c22867 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -3134,55 +3134,62 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
3134 | } | 3134 | } |
3135 | 3135 | ||
3136 | error = inode_change_ok(inode, attr); | 3136 | error = inode_change_ok(inode, attr); |
3137 | if (!error) { | 3137 | if (error) |
3138 | if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || | 3138 | goto out; |
3139 | (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) { | ||
3140 | error = reiserfs_chown_xattrs(inode, attr); | ||
3141 | 3139 | ||
3142 | if (!error) { | 3140 | if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || |
3143 | struct reiserfs_transaction_handle th; | 3141 | (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) { |
3144 | int jbegin_count = | 3142 | struct reiserfs_transaction_handle th; |
3145 | 2 * | 3143 | int jbegin_count = |
3146 | (REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb) + | 3144 | 2 * |
3147 | REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb)) + | 3145 | (REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb) + |
3148 | 2; | 3146 | REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb)) + |
3149 | 3147 | 2; | |
3150 | /* (user+group)*(old+new) structure - we count quota info and , inode write (sb, inode) */ | 3148 | |
3151 | error = | 3149 | error = reiserfs_chown_xattrs(inode, attr); |
3152 | journal_begin(&th, inode->i_sb, | 3150 | |
3153 | jbegin_count); | 3151 | if (error) |
3154 | if (error) | 3152 | return error; |
3155 | goto out; | 3153 | |
3156 | error = dquot_transfer(inode, attr); | 3154 | /* (user+group)*(old+new) structure - we count quota info and , inode write (sb, inode) */ |
3157 | if (error) { | 3155 | error = journal_begin(&th, inode->i_sb, jbegin_count); |
3158 | journal_end(&th, inode->i_sb, | 3156 | if (error) |
3159 | jbegin_count); | 3157 | goto out; |
3160 | goto out; | 3158 | error = dquot_transfer(inode, attr); |
3161 | } | 3159 | if (error) { |
3162 | /* Update corresponding info in inode so that everything is in | 3160 | journal_end(&th, inode->i_sb, jbegin_count); |
3163 | * one transaction */ | 3161 | goto out; |
3164 | if (attr->ia_valid & ATTR_UID) | ||
3165 | inode->i_uid = attr->ia_uid; | ||
3166 | if (attr->ia_valid & ATTR_GID) | ||
3167 | inode->i_gid = attr->ia_gid; | ||
3168 | mark_inode_dirty(inode); | ||
3169 | error = | ||
3170 | journal_end(&th, inode->i_sb, jbegin_count); | ||
3171 | } | ||
3172 | } | ||
3173 | if (!error) { | ||
3174 | /* | ||
3175 | * Relax the lock here, as it might truncate the | ||
3176 | * inode pages and wait for inode pages locks. | ||
3177 | * To release such page lock, the owner needs the | ||
3178 | * reiserfs lock | ||
3179 | */ | ||
3180 | reiserfs_write_unlock_once(inode->i_sb, depth); | ||
3181 | error = inode_setattr(inode, attr); | ||
3182 | depth = reiserfs_write_lock_once(inode->i_sb); | ||
3183 | } | 3162 | } |
3163 | |||
3164 | /* Update corresponding info in inode so that everything is in | ||
3165 | * one transaction */ | ||
3166 | if (attr->ia_valid & ATTR_UID) | ||
3167 | inode->i_uid = attr->ia_uid; | ||
3168 | if (attr->ia_valid & ATTR_GID) | ||
3169 | inode->i_gid = attr->ia_gid; | ||
3170 | mark_inode_dirty(inode); | ||
3171 | error = journal_end(&th, inode->i_sb, jbegin_count); | ||
3172 | if (error) | ||
3173 | goto out; | ||
3184 | } | 3174 | } |
3185 | 3175 | ||
3176 | /* | ||
3177 | * Relax the lock here, as it might truncate the | ||
3178 | * inode pages and wait for inode pages locks. | ||
3179 | * To release such page lock, the owner needs the | ||
3180 | * reiserfs lock | ||
3181 | */ | ||
3182 | reiserfs_write_unlock_once(inode->i_sb, depth); | ||
3183 | if ((attr->ia_valid & ATTR_SIZE) && | ||
3184 | attr->ia_size != i_size_read(inode)) | ||
3185 | error = vmtruncate(inode, attr->ia_size); | ||
3186 | |||
3187 | if (!error) { | ||
3188 | setattr_copy(inode, attr); | ||
3189 | mark_inode_dirty(inode); | ||
3190 | } | ||
3191 | depth = reiserfs_write_lock_once(inode->i_sb); | ||
3192 | |||
3186 | if (!error && reiserfs_posixacl(inode->i_sb)) { | 3193 | if (!error && reiserfs_posixacl(inode->i_sb)) { |
3187 | if (attr->ia_valid & ATTR_MODE) | 3194 | if (attr->ia_valid & ATTR_MODE) |
3188 | error = reiserfs_acl_chmod(inode); | 3195 | error = reiserfs_acl_chmod(inode); |