diff options
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/xattr.c | 35 |
1 files changed, 18 insertions, 17 deletions
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 9932254c3de9..ab94d6ee496b 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -909,11 +909,6 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i, int in_inode = i->in_inode; int rc; - if (ext4_has_feature_ea_inode(inode->i_sb) && - (EXT4_XATTR_SIZE(i->value_len) > - EXT4_XATTR_MIN_LARGE_EA_SIZE(inode->i_sb->s_blocksize))) - in_inode = 1; - /* Compute min_offs and last. */ last = s->first; for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) { @@ -1095,7 +1090,8 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode, { struct super_block *sb = inode->i_sb; struct buffer_head *new_bh = NULL; - struct ext4_xattr_search *s = &bs->s; + struct ext4_xattr_search s_copy = bs->s; + struct ext4_xattr_search *s = &s_copy; struct mb_cache_entry *ce = NULL; int error = 0; struct mb_cache *ext4_mb_cache = EXT4_GET_MB_CACHE(inode); @@ -1517,6 +1513,11 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index, if (!bs.s.not_found && ext4_xattr_value_same(&bs.s, &i)) goto cleanup; + if (ext4_has_feature_ea_inode(inode->i_sb) && + (EXT4_XATTR_SIZE(i.value_len) > + EXT4_XATTR_MIN_LARGE_EA_SIZE(inode->i_sb->s_blocksize))) + i.in_inode = 1; +retry_inode: error = ext4_xattr_ibody_set(handle, inode, &i, &is); if (!error && !bs.s.not_found) { i.value = NULL; @@ -1528,20 +1529,20 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index, goto cleanup; } error = ext4_xattr_block_set(handle, inode, &i, &bs); - if (ext4_has_feature_ea_inode(inode->i_sb) && - error == -ENOSPC) { - /* xattr not fit to block, store at external - * inode */ - i.in_inode = 1; - error = ext4_xattr_ibody_set(handle, inode, - &i, &is); - } - if (error) - goto cleanup; - if (!is.s.not_found) { + if (!error && !is.s.not_found) { i.value = NULL; error = ext4_xattr_ibody_set(handle, inode, &i, &is); + } else if (error == -ENOSPC) { + /* + * Xattr does not fit in the block, store at + * external inode if possible. + */ + if (ext4_has_feature_ea_inode(inode->i_sb) && + !i.in_inode) { + i.in_inode = 1; + goto retry_inode; + } } } } |