diff options
Diffstat (limited to 'fs/ext4/inline.c')
-rw-r--r-- | fs/ext4/inline.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index bec68b364832..e4a41d5d06db 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c | |||
@@ -454,6 +454,67 @@ out: | |||
454 | return error; | 454 | return error; |
455 | } | 455 | } |
456 | 456 | ||
457 | static int ext4_read_inline_page(struct inode *inode, struct page *page) | ||
458 | { | ||
459 | void *kaddr; | ||
460 | int ret = 0; | ||
461 | size_t len; | ||
462 | struct ext4_iloc iloc; | ||
463 | |||
464 | BUG_ON(!PageLocked(page)); | ||
465 | BUG_ON(!ext4_has_inline_data(inode)); | ||
466 | BUG_ON(page->index); | ||
467 | |||
468 | if (!EXT4_I(inode)->i_inline_off) { | ||
469 | ext4_warning(inode->i_sb, "inode %lu doesn't have inline data.", | ||
470 | inode->i_ino); | ||
471 | goto out; | ||
472 | } | ||
473 | |||
474 | ret = ext4_get_inode_loc(inode, &iloc); | ||
475 | if (ret) | ||
476 | goto out; | ||
477 | |||
478 | len = min_t(size_t, ext4_get_inline_size(inode), i_size_read(inode)); | ||
479 | kaddr = kmap_atomic(page); | ||
480 | ret = ext4_read_inline_data(inode, kaddr, len, &iloc); | ||
481 | flush_dcache_page(page); | ||
482 | kunmap_atomic(kaddr); | ||
483 | zero_user_segment(page, len, PAGE_CACHE_SIZE); | ||
484 | SetPageUptodate(page); | ||
485 | brelse(iloc.bh); | ||
486 | |||
487 | out: | ||
488 | return ret; | ||
489 | } | ||
490 | |||
491 | int ext4_readpage_inline(struct inode *inode, struct page *page) | ||
492 | { | ||
493 | int ret = 0; | ||
494 | |||
495 | down_read(&EXT4_I(inode)->xattr_sem); | ||
496 | if (!ext4_has_inline_data(inode)) { | ||
497 | up_read(&EXT4_I(inode)->xattr_sem); | ||
498 | return -EAGAIN; | ||
499 | } | ||
500 | |||
501 | /* | ||
502 | * Current inline data can only exist in the 1st page, | ||
503 | * So for all the other pages, just set them uptodate. | ||
504 | */ | ||
505 | if (!page->index) | ||
506 | ret = ext4_read_inline_page(inode, page); | ||
507 | else if (!PageUptodate(page)) { | ||
508 | zero_user_segment(page, 0, PAGE_CACHE_SIZE); | ||
509 | SetPageUptodate(page); | ||
510 | } | ||
511 | |||
512 | up_read(&EXT4_I(inode)->xattr_sem); | ||
513 | |||
514 | unlock_page(page); | ||
515 | return ret >= 0 ? 0 : ret; | ||
516 | } | ||
517 | |||
457 | int ext4_destroy_inline_data(handle_t *handle, struct inode *inode) | 518 | int ext4_destroy_inline_data(handle_t *handle, struct inode *inode) |
458 | { | 519 | { |
459 | int ret; | 520 | int ret; |