.. | .. |
---|
33 | 33 | struct ext4_xattr_ibody_header *header; |
---|
34 | 34 | struct ext4_xattr_entry *entry; |
---|
35 | 35 | struct ext4_inode *raw_inode; |
---|
| 36 | + void *end; |
---|
36 | 37 | int free, min_offs; |
---|
37 | 38 | |
---|
38 | 39 | if (!EXT4_INODE_HAS_XATTR_SPACE(inode)) |
---|
.. | .. |
---|
56 | 57 | raw_inode = ext4_raw_inode(iloc); |
---|
57 | 58 | header = IHDR(inode, raw_inode); |
---|
58 | 59 | entry = IFIRST(header); |
---|
| 60 | + end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size; |
---|
59 | 61 | |
---|
60 | 62 | /* Compute min_offs. */ |
---|
61 | | - for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) { |
---|
| 63 | + while (!IS_LAST_ENTRY(entry)) { |
---|
| 64 | + void *next = EXT4_XATTR_NEXT(entry); |
---|
| 65 | + |
---|
| 66 | + if (next >= end) { |
---|
| 67 | + EXT4_ERROR_INODE(inode, |
---|
| 68 | + "corrupt xattr in inline inode"); |
---|
| 69 | + return 0; |
---|
| 70 | + } |
---|
62 | 71 | if (!entry->e_value_inum && entry->e_value_size) { |
---|
63 | 72 | size_t offs = le16_to_cpu(entry->e_value_offs); |
---|
64 | 73 | if (offs < min_offs) |
---|
65 | 74 | min_offs = offs; |
---|
66 | 75 | } |
---|
| 76 | + entry = next; |
---|
67 | 77 | } |
---|
68 | 78 | free = min_offs - |
---|
69 | 79 | ((void *)entry - (void *)IFIRST(header)) - sizeof(__u32); |
---|
.. | .. |
---|
158 | 168 | (void *)ext4_raw_inode(&is.iloc)); |
---|
159 | 169 | EXT4_I(inode)->i_inline_size = EXT4_MIN_INLINE_DATA_SIZE + |
---|
160 | 170 | le32_to_cpu(is.s.here->e_value_size); |
---|
161 | | - ext4_set_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA); |
---|
162 | 171 | } |
---|
163 | 172 | out: |
---|
164 | 173 | brelse(is.iloc.bh); |
---|
.. | .. |
---|
208 | 217 | /* |
---|
209 | 218 | * write the buffer to the inline inode. |
---|
210 | 219 | * If 'create' is set, we don't need to do the extra copy in the xattr |
---|
211 | | - * value since it is already handled by ext4_xattr_ibody_inline_set. |
---|
| 220 | + * value since it is already handled by ext4_xattr_ibody_set. |
---|
212 | 221 | * That saves us one memcpy. |
---|
213 | 222 | */ |
---|
214 | 223 | static void ext4_write_inline_data(struct inode *inode, struct ext4_iloc *iloc, |
---|
.. | .. |
---|
290 | 299 | |
---|
291 | 300 | BUG_ON(!is.s.not_found); |
---|
292 | 301 | |
---|
293 | | - error = ext4_xattr_ibody_inline_set(handle, inode, &i, &is); |
---|
| 302 | + error = ext4_xattr_ibody_set(handle, inode, &i, &is); |
---|
294 | 303 | if (error) { |
---|
295 | 304 | if (error == -ENOSPC) |
---|
296 | 305 | ext4_clear_inode_state(inode, |
---|
.. | .. |
---|
350 | 359 | |
---|
351 | 360 | error = ext4_xattr_ibody_get(inode, i.name_index, i.name, |
---|
352 | 361 | value, len); |
---|
353 | | - if (error == -ENODATA) |
---|
| 362 | + if (error < 0) |
---|
354 | 363 | goto out; |
---|
355 | 364 | |
---|
356 | 365 | BUFFER_TRACE(is.iloc.bh, "get_write_access"); |
---|
.. | .. |
---|
362 | 371 | i.value = value; |
---|
363 | 372 | i.value_len = len; |
---|
364 | 373 | |
---|
365 | | - error = ext4_xattr_ibody_inline_set(handle, inode, &i, &is); |
---|
| 374 | + error = ext4_xattr_ibody_set(handle, inode, &i, &is); |
---|
366 | 375 | if (error) |
---|
367 | 376 | goto out; |
---|
368 | 377 | |
---|
.. | .. |
---|
435 | 444 | if (error) |
---|
436 | 445 | goto out; |
---|
437 | 446 | |
---|
438 | | - error = ext4_xattr_ibody_inline_set(handle, inode, &i, &is); |
---|
| 447 | + error = ext4_xattr_ibody_set(handle, inode, &i, &is); |
---|
439 | 448 | if (error) |
---|
440 | 449 | goto out; |
---|
441 | 450 | |
---|
.. | .. |
---|
813 | 822 | * clear the inode state safely. |
---|
814 | 823 | * 2. The inode has inline data, then we need to read the data, make it |
---|
815 | 824 | * update and dirty so that ext4_da_writepages can handle it. We don't |
---|
816 | | - * need to start the journal since the file's metatdata isn't changed now. |
---|
| 825 | + * need to start the journal since the file's metadata isn't changed now. |
---|
817 | 826 | */ |
---|
818 | 827 | static int ext4_da_convert_inline_data_to_extent(struct address_space *mapping, |
---|
819 | 828 | struct inode *inode, |
---|
.. | .. |
---|
1187 | 1196 | ext4_initialize_dirent_tail(dir_block, |
---|
1188 | 1197 | inode->i_sb->s_blocksize); |
---|
1189 | 1198 | set_buffer_uptodate(dir_block); |
---|
| 1199 | + unlock_buffer(dir_block); |
---|
1190 | 1200 | err = ext4_handle_dirty_dirblock(handle, inode, dir_block); |
---|
1191 | 1201 | if (err) |
---|
1192 | 1202 | return err; |
---|
.. | .. |
---|
1260 | 1270 | if (!S_ISDIR(inode->i_mode)) { |
---|
1261 | 1271 | memcpy(data_bh->b_data, buf, inline_size); |
---|
1262 | 1272 | set_buffer_uptodate(data_bh); |
---|
| 1273 | + unlock_buffer(data_bh); |
---|
1263 | 1274 | error = ext4_handle_dirty_metadata(handle, |
---|
1264 | 1275 | inode, data_bh); |
---|
1265 | 1276 | } else { |
---|
.. | .. |
---|
1267 | 1278 | buf, inline_size); |
---|
1268 | 1279 | } |
---|
1269 | 1280 | |
---|
1270 | | - unlock_buffer(data_bh); |
---|
1271 | 1281 | out_restore: |
---|
1272 | 1282 | if (error) |
---|
1273 | 1283 | ext4_restore_inline_data(handle, inode, iloc, buf, inline_size); |
---|
.. | .. |
---|
1950 | 1960 | i.value = value; |
---|
1951 | 1961 | i.value_len = i_size > EXT4_MIN_INLINE_DATA_SIZE ? |
---|
1952 | 1962 | i_size - EXT4_MIN_INLINE_DATA_SIZE : 0; |
---|
1953 | | - err = ext4_xattr_ibody_inline_set(handle, inode, |
---|
1954 | | - &i, &is); |
---|
| 1963 | + err = ext4_xattr_ibody_set(handle, inode, &i, &is); |
---|
1955 | 1964 | if (err) |
---|
1956 | 1965 | goto out_error; |
---|
1957 | 1966 | } |
---|