Commit 9f40fe54635b7533f51993d0f5e7f014fc14d33a
Committed by
Theodore Ts'o
1 parent
05019a9e7f
Exists in
master
and in
20 other branches
ext4: let ext4_delete_entry() handle inline data
Signed-off-by: Tao Ma <boyu.mt@taobao.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Showing 3 changed files with 76 additions and 0 deletions Side-by-side Diff
fs/ext4/inline.c
... | ... | @@ -1510,6 +1510,61 @@ |
1510 | 1510 | return iloc.bh; |
1511 | 1511 | } |
1512 | 1512 | |
1513 | +int ext4_delete_inline_entry(handle_t *handle, | |
1514 | + struct inode *dir, | |
1515 | + struct ext4_dir_entry_2 *de_del, | |
1516 | + struct buffer_head *bh, | |
1517 | + int *has_inline_data) | |
1518 | +{ | |
1519 | + int err, inline_size; | |
1520 | + struct ext4_iloc iloc; | |
1521 | + void *inline_start; | |
1522 | + | |
1523 | + err = ext4_get_inode_loc(dir, &iloc); | |
1524 | + if (err) | |
1525 | + return err; | |
1526 | + | |
1527 | + down_write(&EXT4_I(dir)->xattr_sem); | |
1528 | + if (!ext4_has_inline_data(dir)) { | |
1529 | + *has_inline_data = 0; | |
1530 | + goto out; | |
1531 | + } | |
1532 | + | |
1533 | + if ((void *)de_del - ((void *)ext4_raw_inode(&iloc)->i_block) < | |
1534 | + EXT4_MIN_INLINE_DATA_SIZE) { | |
1535 | + inline_start = (void *)ext4_raw_inode(&iloc)->i_block + | |
1536 | + EXT4_INLINE_DOTDOT_SIZE; | |
1537 | + inline_size = EXT4_MIN_INLINE_DATA_SIZE - | |
1538 | + EXT4_INLINE_DOTDOT_SIZE; | |
1539 | + } else { | |
1540 | + inline_start = ext4_get_inline_xattr_pos(dir, &iloc); | |
1541 | + inline_size = ext4_get_inline_size(dir) - | |
1542 | + EXT4_MIN_INLINE_DATA_SIZE; | |
1543 | + } | |
1544 | + | |
1545 | + err = ext4_journal_get_write_access(handle, bh); | |
1546 | + if (err) | |
1547 | + goto out; | |
1548 | + | |
1549 | + err = ext4_generic_delete_entry(handle, dir, de_del, bh, | |
1550 | + inline_start, inline_size, 0); | |
1551 | + if (err) | |
1552 | + goto out; | |
1553 | + | |
1554 | + BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata"); | |
1555 | + err = ext4_mark_inode_dirty(handle, dir); | |
1556 | + if (unlikely(err)) | |
1557 | + goto out; | |
1558 | + | |
1559 | + ext4_show_inline_dir(dir, iloc.bh, inline_start, inline_size); | |
1560 | +out: | |
1561 | + up_write(&EXT4_I(dir)->xattr_sem); | |
1562 | + brelse(iloc.bh); | |
1563 | + if (err != -ENOENT) | |
1564 | + ext4_std_error(dir->i_sb, err); | |
1565 | + return err; | |
1566 | +} | |
1567 | + | |
1513 | 1568 | int ext4_destroy_inline_data(handle_t *handle, struct inode *inode) |
1514 | 1569 | { |
1515 | 1570 | int ret; |
fs/ext4/namei.c
... | ... | @@ -2158,6 +2158,14 @@ |
2158 | 2158 | { |
2159 | 2159 | int err, csum_size = 0; |
2160 | 2160 | |
2161 | + if (ext4_has_inline_data(dir)) { | |
2162 | + int has_inline_data = 1; | |
2163 | + err = ext4_delete_inline_entry(handle, dir, de_del, bh, | |
2164 | + &has_inline_data); | |
2165 | + if (has_inline_data) | |
2166 | + return err; | |
2167 | + } | |
2168 | + | |
2161 | 2169 | if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb, |
2162 | 2170 | EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) |
2163 | 2171 | csum_size = sizeof(struct ext4_dir_entry_tail); |
fs/ext4/xattr.h
... | ... | @@ -175,6 +175,11 @@ |
175 | 175 | const struct qstr *d_name, |
176 | 176 | struct ext4_dir_entry_2 **res_dir, |
177 | 177 | int *has_inline_data); |
178 | +extern int ext4_delete_inline_entry(handle_t *handle, | |
179 | + struct inode *dir, | |
180 | + struct ext4_dir_entry_2 *de_del, | |
181 | + struct buffer_head *bh, | |
182 | + int *has_inline_data); | |
178 | 183 | # else /* CONFIG_EXT4_FS_XATTR */ |
179 | 184 | |
180 | 185 | static inline int |
... | ... | @@ -367,6 +372,14 @@ |
367 | 372 | int *has_inline_data) |
368 | 373 | { |
369 | 374 | return NULL; |
375 | +} | |
376 | +static inline int ext4_delete_inline_entry(handle_t *handle, | |
377 | + struct inode *dir, | |
378 | + struct ext4_dir_entry_2 *de_del, | |
379 | + struct buffer_head *bh, | |
380 | + int *has_inline_data) | |
381 | +{ | |
382 | + return 0; | |
370 | 383 | } |
371 | 384 | # endif /* CONFIG_EXT4_FS_XATTR */ |
372 | 385 |