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 | e8e948e7802a2ab05c146d3e72a39b93b5718236 (patch) | |
tree | 3e6914f6b16c457e0d14cee75bf0149f730bbd99 | |
parent | 7335cd3b41b1e704608ca46159641ca9cb598121 (diff) |
ext4: let ext4_find_entry handle inline data
Create a new function ext4_find_inline_entry() to handle the case of
inline data.
Signed-off-by: Tao Ma <boyu.mt@taobao.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-rw-r--r-- | fs/ext4/inline.c | 48 | ||||
-rw-r--r-- | fs/ext4/namei.c | 10 | ||||
-rw-r--r-- | fs/ext4/xattr.h | 13 |
3 files changed, 70 insertions, 1 deletions
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index 471504133c76..0a8f5a865496 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c | |||
@@ -1462,6 +1462,54 @@ out: | |||
1462 | return ret; | 1462 | return ret; |
1463 | } | 1463 | } |
1464 | 1464 | ||
1465 | struct buffer_head *ext4_find_inline_entry(struct inode *dir, | ||
1466 | const struct qstr *d_name, | ||
1467 | struct ext4_dir_entry_2 **res_dir, | ||
1468 | int *has_inline_data) | ||
1469 | { | ||
1470 | int ret; | ||
1471 | struct ext4_iloc iloc; | ||
1472 | void *inline_start; | ||
1473 | int inline_size; | ||
1474 | |||
1475 | if (ext4_get_inode_loc(dir, &iloc)) | ||
1476 | return NULL; | ||
1477 | |||
1478 | down_read(&EXT4_I(dir)->xattr_sem); | ||
1479 | if (!ext4_has_inline_data(dir)) { | ||
1480 | *has_inline_data = 0; | ||
1481 | goto out; | ||
1482 | } | ||
1483 | |||
1484 | inline_start = (void *)ext4_raw_inode(&iloc)->i_block + | ||
1485 | EXT4_INLINE_DOTDOT_SIZE; | ||
1486 | inline_size = EXT4_MIN_INLINE_DATA_SIZE - EXT4_INLINE_DOTDOT_SIZE; | ||
1487 | ret = search_dir(iloc.bh, inline_start, inline_size, | ||
1488 | dir, d_name, 0, res_dir); | ||
1489 | if (ret == 1) | ||
1490 | goto out_find; | ||
1491 | if (ret < 0) | ||
1492 | goto out; | ||
1493 | |||
1494 | if (ext4_get_inline_size(dir) == EXT4_MIN_INLINE_DATA_SIZE) | ||
1495 | goto out; | ||
1496 | |||
1497 | inline_start = ext4_get_inline_xattr_pos(dir, &iloc); | ||
1498 | inline_size = ext4_get_inline_size(dir) - EXT4_MIN_INLINE_DATA_SIZE; | ||
1499 | |||
1500 | ret = search_dir(iloc.bh, inline_start, inline_size, | ||
1501 | dir, d_name, 0, res_dir); | ||
1502 | if (ret == 1) | ||
1503 | goto out_find; | ||
1504 | |||
1505 | out: | ||
1506 | brelse(iloc.bh); | ||
1507 | iloc.bh = NULL; | ||
1508 | out_find: | ||
1509 | up_read(&EXT4_I(dir)->xattr_sem); | ||
1510 | return iloc.bh; | ||
1511 | } | ||
1512 | |||
1465 | int ext4_destroy_inline_data(handle_t *handle, struct inode *inode) | 1513 | int ext4_destroy_inline_data(handle_t *handle, struct inode *inode) |
1466 | { | 1514 | { |
1467 | int ret; | 1515 | int ret; |
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index d50684b91496..b498cafed12b 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -1015,7 +1015,6 @@ static inline int search_dirblock(struct buffer_head *bh, | |||
1015 | d_name, offset, res_dir); | 1015 | d_name, offset, res_dir); |
1016 | } | 1016 | } |
1017 | 1017 | ||
1018 | |||
1019 | /* | 1018 | /* |
1020 | * Directory block splitting, compacting | 1019 | * Directory block splitting, compacting |
1021 | */ | 1020 | */ |
@@ -1198,6 +1197,15 @@ static struct buffer_head * ext4_find_entry (struct inode *dir, | |||
1198 | namelen = d_name->len; | 1197 | namelen = d_name->len; |
1199 | if (namelen > EXT4_NAME_LEN) | 1198 | if (namelen > EXT4_NAME_LEN) |
1200 | return NULL; | 1199 | return NULL; |
1200 | |||
1201 | if (ext4_has_inline_data(dir)) { | ||
1202 | int has_inline_data = 1; | ||
1203 | ret = ext4_find_inline_entry(dir, d_name, res_dir, | ||
1204 | &has_inline_data); | ||
1205 | if (has_inline_data) | ||
1206 | return ret; | ||
1207 | } | ||
1208 | |||
1201 | if ((namelen <= 2) && (name[0] == '.') && | 1209 | if ((namelen <= 2) && (name[0] == '.') && |
1202 | (name[1] == '.' || name[1] == '\0')) { | 1210 | (name[1] == '.' || name[1] == '\0')) { |
1203 | /* | 1211 | /* |
diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h index 539e6a08c95f..c6f3dea88d6f 100644 --- a/fs/ext4/xattr.h +++ b/fs/ext4/xattr.h | |||
@@ -171,6 +171,10 @@ extern int ext4_try_create_inline_dir(handle_t *handle, | |||
171 | extern int ext4_read_inline_dir(struct file *filp, | 171 | extern int ext4_read_inline_dir(struct file *filp, |
172 | void *dirent, filldir_t filldir, | 172 | void *dirent, filldir_t filldir, |
173 | int *has_inline_data); | 173 | int *has_inline_data); |
174 | extern struct buffer_head *ext4_find_inline_entry(struct inode *dir, | ||
175 | const struct qstr *d_name, | ||
176 | struct ext4_dir_entry_2 **res_dir, | ||
177 | int *has_inline_data); | ||
174 | # else /* CONFIG_EXT4_FS_XATTR */ | 178 | # else /* CONFIG_EXT4_FS_XATTR */ |
175 | 179 | ||
176 | static inline int | 180 | static inline int |
@@ -355,6 +359,15 @@ static inline int ext4_read_inline_dir(struct file *filp, | |||
355 | { | 359 | { |
356 | return 0; | 360 | return 0; |
357 | } | 361 | } |
362 | |||
363 | static inline struct buffer_head * | ||
364 | ext4_find_inline_entry(struct inode *dir, | ||
365 | const struct qstr *d_name, | ||
366 | struct ext4_dir_entry_2 **res_dir, | ||
367 | int *has_inline_data) | ||
368 | { | ||
369 | return NULL; | ||
370 | } | ||
358 | # endif /* CONFIG_EXT4_FS_XATTR */ | 371 | # endif /* CONFIG_EXT4_FS_XATTR */ |
359 | 372 | ||
360 | #ifdef CONFIG_EXT4_FS_SECURITY | 373 | #ifdef CONFIG_EXT4_FS_SECURITY |