| .. | .. |
|---|
| 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 | } |
|---|