1 ext4: factor out loop for freeing inode xattr space
3 From: Jan Kara <jack@suse.cz>
5 Move loop to make enough space in the inode from
6 ext4_expand_extra_isize_ea() into a separate function to make that
7 function smaller and better readable and also to avoid delaration of
8 variables inside a loop block.
10 Signed-off-by: Jan Kara <jack@suse.cz>
11 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
13 fs/ext4/xattr.c | 121 ++++++++++++++++++++++++++++++++------------------------
14 1 file changed, 69 insertions(+), 52 deletions(-)
16 diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
17 index 2ef687620205..c15d63389957 100644
20 @@ -1417,6 +1417,63 @@ out:
24 +static int ext4_xattr_make_inode_space(handle_t *handle, struct inode *inode,
25 + struct ext4_inode *raw_inode,
26 + int isize_diff, size_t ifree,
27 + size_t bfree, int *total_ino)
29 + struct ext4_xattr_ibody_header *header = IHDR(inode, raw_inode);
30 + struct ext4_xattr_entry *small_entry;
31 + struct ext4_xattr_entry *entry;
32 + struct ext4_xattr_entry *last;
33 + unsigned int entry_size; /* EA entry size */
34 + unsigned int total_size; /* EA entry size + value size */
35 + unsigned int min_total_size;
38 + while (isize_diff > ifree) {
41 + min_total_size = ~0U;
42 + last = IFIRST(header);
43 + /* Find the entry best suited to be pushed into EA block */
44 + for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) {
46 + EXT4_XATTR_SIZE(le32_to_cpu(last->e_value_size)) +
47 + EXT4_XATTR_LEN(last->e_name_len);
48 + if (total_size <= bfree &&
49 + total_size < min_total_size) {
50 + if (total_size + ifree < isize_diff) {
54 + min_total_size = total_size;
59 + if (entry == NULL) {
60 + if (small_entry == NULL)
62 + entry = small_entry;
65 + entry_size = EXT4_XATTR_LEN(entry->e_name_len);
66 + total_size = entry_size +
67 + EXT4_XATTR_SIZE(le32_to_cpu(entry->e_value_size));
68 + error = ext4_xattr_move_to_block(handle, inode, raw_inode,
73 + *total_ino -= entry_size;
74 + ifree += total_size;
75 + bfree -= total_size;
82 * Expand an inode by new_extra_isize bytes when EAs are present.
83 * Returns 0 on success or negative error number on failure.
84 @@ -1491,66 +1548,26 @@ retry:
93 bfree = inode->i_sb->s_blocksize;
96 - while (isize_diff > ifree) {
97 - struct ext4_xattr_entry *small_entry = NULL, *entry = NULL;
98 - struct ext4_xattr_entry *last;
99 - unsigned int entry_size; /* EA entry size */
100 - unsigned int total_size; /* EA entry size + value size */
101 - unsigned int min_total_size = ~0U;
103 - last = IFIRST(header);
104 - /* Find the entry best suited to be pushed into EA block */
105 - for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) {
107 - EXT4_XATTR_SIZE(le32_to_cpu(last->e_value_size)) +
108 - EXT4_XATTR_LEN(last->e_name_len);
109 - if (total_size <= bfree &&
110 - total_size < min_total_size) {
111 - if (total_size + ifree < isize_diff) {
112 - small_entry = last;
115 - min_total_size = total_size;
120 - if (entry == NULL) {
122 - entry = small_entry;
124 - if (!tried_min_extra_isize &&
125 - s_min_extra_isize) {
126 - tried_min_extra_isize++;
127 - new_extra_isize = s_min_extra_isize;
134 + error = ext4_xattr_make_inode_space(handle, inode, raw_inode,
135 + isize_diff, ifree, bfree,
138 + if (error == -ENOSPC && !tried_min_extra_isize &&
139 + s_min_extra_isize) {
140 + tried_min_extra_isize++;
141 + new_extra_isize = s_min_extra_isize;
146 - entry_size = EXT4_XATTR_LEN(entry->e_name_len);
147 - total_size = entry_size +
148 - EXT4_XATTR_SIZE(le32_to_cpu(entry->e_value_size));
149 - error = ext4_xattr_move_to_block(handle, inode, raw_inode,
154 - total_ino -= entry_size;
155 - ifree += total_size;
156 - bfree -= total_size;
161 /* Adjust the offsets and shift the remaining entries ahead */
162 ext4_xattr_shift_entries(IFIRST(header), EXT4_I(inode)->i_extra_isize