diff options
author | Tao Ma <boyu.mt@taobao.com> | 2012-12-10 14:06:00 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2012-12-10 14:06:00 -0500 |
commit | 9f40fe54635b7533f51993d0f5e7f014fc14d33a (patch) | |
tree | 4fba9eb2fbf97ee21cfecba4746c439e51794030 /fs/ext4 | |
parent | 05019a9e7f025133f20c67677c9c8551eca3c6dc (diff) |
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>
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/inline.c | 55 | ||||
-rw-r--r-- | fs/ext4/namei.c | 8 | ||||
-rw-r--r-- | fs/ext4/xattr.h | 13 |
3 files changed, 76 insertions, 0 deletions
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index 0a8f5a865496..f5e9c0e6d737 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c | |||
@@ -1510,6 +1510,61 @@ out_find: | |||
1510 | return iloc.bh; | 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 | int ext4_destroy_inline_data(handle_t *handle, struct inode *inode) | 1568 | int ext4_destroy_inline_data(handle_t *handle, struct inode *inode) |
1514 | { | 1569 | { |
1515 | int ret; | 1570 | int ret; |
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index c10fc2631ff5..a32228a73df0 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -2158,6 +2158,14 @@ static int ext4_delete_entry(handle_t *handle, | |||
2158 | { | 2158 | { |
2159 | int err, csum_size = 0; | 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 | if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb, | 2169 | if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb, |
2162 | EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) | 2170 | EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) |
2163 | csum_size = sizeof(struct ext4_dir_entry_tail); | 2171 | csum_size = sizeof(struct ext4_dir_entry_tail); |
diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h index c6f3dea88d6f..f86e424d75e4 100644 --- a/fs/ext4/xattr.h +++ b/fs/ext4/xattr.h | |||
@@ -175,6 +175,11 @@ extern struct buffer_head *ext4_find_inline_entry(struct inode *dir, | |||
175 | const struct qstr *d_name, | 175 | const struct qstr *d_name, |
176 | struct ext4_dir_entry_2 **res_dir, | 176 | struct ext4_dir_entry_2 **res_dir, |
177 | int *has_inline_data); | 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 | # else /* CONFIG_EXT4_FS_XATTR */ | 183 | # else /* CONFIG_EXT4_FS_XATTR */ |
179 | 184 | ||
180 | static inline int | 185 | static inline int |
@@ -368,6 +373,14 @@ ext4_find_inline_entry(struct inode *dir, | |||
368 | { | 373 | { |
369 | return NULL; | 374 | return NULL; |
370 | } | 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; | ||
383 | } | ||
371 | # endif /* CONFIG_EXT4_FS_XATTR */ | 384 | # endif /* CONFIG_EXT4_FS_XATTR */ |
372 | 385 | ||
373 | #ifdef CONFIG_EXT4_FS_SECURITY | 386 | #ifdef CONFIG_EXT4_FS_SECURITY |