2013-11-10 23:13:19 +08:00
/*
* fs / f2fs / inline . c
* Copyright ( c ) 2013 , Intel Corporation
* Authors : Huajun Li < huajun . li @ intel . com >
* Haicheng Li < haicheng . li @ intel . com >
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*/
# include <linux/fs.h>
# include <linux/f2fs_fs.h>
# include "f2fs.h"
bool f2fs_may_inline ( struct inode * inode )
{
2014-09-02 15:31:18 -07:00
if ( ! test_opt ( F2FS_I_SB ( inode ) , INLINE_DATA ) )
2013-11-10 23:13:19 +08:00
return false ;
2014-10-06 17:39:50 -07:00
if ( f2fs_is_atomic_file ( inode ) )
return false ;
2014-10-23 19:48:09 -07:00
if ( ! S_ISREG ( inode - > i_mode ) )
2013-11-10 23:13:19 +08:00
return false ;
2014-11-11 14:10:01 -08:00
if ( i_size_read ( inode ) > MAX_INLINE_DATA )
return false ;
2013-11-10 23:13:19 +08:00
return true ;
}
2014-10-23 19:48:09 -07:00
void read_inline_data ( struct page * page , struct page * ipage )
2013-11-10 23:13:19 +08:00
{
void * src_addr , * dst_addr ;
2014-10-23 19:48:09 -07:00
if ( PageUptodate ( page ) )
return ;
2013-12-30 18:36:23 +08:00
2014-10-23 19:48:09 -07:00
f2fs_bug_on ( F2FS_P_SB ( page ) , page - > index ) ;
2013-11-10 23:13:19 +08:00
2013-12-30 09:29:06 +08:00
zero_user_segment ( page , MAX_INLINE_DATA , PAGE_CACHE_SIZE ) ;
2013-11-10 23:13:19 +08:00
/* Copy the whole inline data block */
src_addr = inline_data_addr ( ipage ) ;
2014-10-18 23:41:38 -07:00
dst_addr = kmap_atomic ( page ) ;
2013-11-10 23:13:19 +08:00
memcpy ( dst_addr , src_addr , MAX_INLINE_DATA ) ;
2014-10-26 22:59:27 -07:00
flush_dcache_page ( page ) ;
2014-10-18 23:41:38 -07:00
kunmap_atomic ( dst_addr ) ;
2013-11-10 23:13:19 +08:00
SetPageUptodate ( page ) ;
2014-10-23 19:48:09 -07:00
}
int f2fs_read_inline_data ( struct inode * inode , struct page * page )
{
struct page * ipage ;
ipage = get_node_page ( F2FS_I_SB ( inode ) , inode - > i_ino ) ;
if ( IS_ERR ( ipage ) ) {
unlock_page ( page ) ;
return PTR_ERR ( ipage ) ;
}
2013-11-10 23:13:19 +08:00
2014-10-23 19:48:09 -07:00
if ( ! f2fs_has_inline_data ( inode ) ) {
f2fs_put_page ( ipage , 1 ) ;
return - EAGAIN ;
}
if ( page - > index )
zero_user_segment ( page , 0 , PAGE_CACHE_SIZE ) ;
else
read_inline_data ( page , ipage ) ;
SetPageUptodate ( page ) ;
f2fs_put_page ( ipage , 1 ) ;
unlock_page ( page ) ;
2013-11-10 23:13:19 +08:00
return 0 ;
}
2014-10-23 19:48:09 -07:00
int f2fs_convert_inline_page ( struct dnode_of_data * dn , struct page * page )
2013-11-10 23:13:19 +08:00
{
void * src_addr , * dst_addr ;
block_t new_blk_addr ;
struct f2fs_io_info fio = {
. type = DATA ,
. rw = WRITE_SYNC | REQ_PRIO ,
} ;
2014-11-25 11:34:02 -08:00
int dirty , err ;
2013-11-10 23:13:19 +08:00
2014-10-23 19:48:09 -07:00
f2fs_bug_on ( F2FS_I_SB ( dn - > inode ) , page - > index ) ;
2013-11-10 23:13:19 +08:00
2014-10-23 19:48:09 -07:00
if ( ! f2fs_exist_data ( dn - > inode ) )
goto clear_out ;
2014-08-18 14:41:11 -07:00
2014-10-23 19:48:09 -07:00
err = f2fs_reserve_block ( dn , 0 ) ;
2014-04-16 14:22:50 +09:00
if ( err )
2014-10-23 19:48:09 -07:00
return err ;
2013-11-10 23:13:19 +08:00
2014-04-29 17:35:10 +09:00
f2fs_wait_on_page_writeback ( page , DATA ) ;
2014-10-23 19:48:09 -07:00
if ( PageUptodate ( page ) )
goto no_update ;
2013-12-30 09:29:06 +08:00
zero_user_segment ( page , MAX_INLINE_DATA , PAGE_CACHE_SIZE ) ;
2013-11-10 23:13:19 +08:00
/* Copy the whole inline data block */
2014-10-23 19:48:09 -07:00
src_addr = inline_data_addr ( dn - > inode_page ) ;
2014-10-18 23:41:38 -07:00
dst_addr = kmap_atomic ( page ) ;
2013-11-10 23:13:19 +08:00
memcpy ( dst_addr , src_addr , MAX_INLINE_DATA ) ;
2014-11-18 10:50:21 -08:00
flush_dcache_page ( page ) ;
2014-10-18 23:41:38 -07:00
kunmap_atomic ( dst_addr ) ;
2013-12-27 12:28:59 +09:00
SetPageUptodate ( page ) ;
2014-10-23 19:48:09 -07:00
no_update :
2014-11-25 11:34:02 -08:00
/* clear dirty state */
dirty = clear_page_dirty_for_io ( page ) ;
2013-11-10 23:13:19 +08:00
/* write data page to try to make data consistent */
set_page_writeback ( page ) ;
2014-10-23 19:48:09 -07:00
write_data_page ( page , dn , & new_blk_addr , & fio ) ;
update_extent_cache ( new_blk_addr , dn ) ;
2014-01-10 07:26:14 +00:00
f2fs_wait_on_page_writeback ( page , DATA ) ;
2014-11-25 11:34:02 -08:00
if ( dirty )
inode_dec_dirty_pages ( dn - > inode ) ;
2013-11-10 23:13:19 +08:00
2014-11-25 17:27:38 -08:00
/* this converted inline_data should be recovered. */
set_inode_flag ( F2FS_I ( dn - > inode ) , FI_APPEND_WRITE ) ;
2013-11-10 23:13:19 +08:00
/* clear inline data and flag after data writeback */
2014-10-23 19:48:09 -07:00
truncate_inline_data ( dn - > inode_page , 0 ) ;
clear_out :
stat_dec_inline_inode ( dn - > inode ) ;
2014-11-10 16:29:14 -08:00
f2fs_clear_inline_inode ( dn - > inode ) ;
2014-10-23 19:48:09 -07:00
sync_inode_page ( dn ) ;
f2fs_put_dnode ( dn ) ;
return 0 ;
2013-11-10 23:13:19 +08:00
}
2014-10-23 19:48:09 -07:00
int f2fs_convert_inline_inode ( struct inode * inode )
2013-11-10 23:13:19 +08:00
{
2014-10-23 19:48:09 -07:00
struct f2fs_sb_info * sbi = F2FS_I_SB ( inode ) ;
struct dnode_of_data dn ;
struct page * ipage , * page ;
int err = 0 ;
2013-11-10 23:13:19 +08:00
2014-10-23 19:48:09 -07:00
page = grab_cache_page ( inode - > i_mapping , 0 ) ;
if ( ! page )
return - ENOMEM ;
2013-11-10 23:13:19 +08:00
2014-10-23 19:48:09 -07:00
f2fs_lock_op ( sbi ) ;
ipage = get_node_page ( sbi , inode - > i_ino ) ;
if ( IS_ERR ( ipage ) ) {
2014-11-17 16:06:55 -08:00
err = PTR_ERR ( ipage ) ;
goto out ;
2014-08-07 16:32:25 -07:00
}
2013-11-10 23:13:19 +08:00
2014-10-23 19:48:09 -07:00
set_new_dnode ( & dn , inode , ipage , ipage , 0 ) ;
if ( f2fs_has_inline_data ( inode ) )
err = f2fs_convert_inline_page ( & dn , page ) ;
f2fs_put_dnode ( & dn ) ;
2014-11-17 16:06:55 -08:00
out :
2014-10-23 19:48:09 -07:00
f2fs_unlock_op ( sbi ) ;
f2fs_put_page ( page , 1 ) ;
2013-11-10 23:13:19 +08:00
return err ;
}
2014-10-23 19:48:09 -07:00
int f2fs_write_inline_data ( struct inode * inode , struct page * page )
2013-11-10 23:13:19 +08:00
{
void * src_addr , * dst_addr ;
struct dnode_of_data dn ;
int err ;
set_new_dnode ( & dn , inode , NULL , NULL , 0 ) ;
err = get_dnode_of_data ( & dn , 0 , LOOKUP_NODE ) ;
if ( err )
return err ;
2014-10-15 10:16:54 -07:00
if ( ! f2fs_has_inline_data ( inode ) ) {
2014-10-23 19:48:09 -07:00
f2fs_put_dnode ( & dn ) ;
return - EAGAIN ;
2014-10-15 10:16:54 -07:00
}
2014-10-23 19:48:09 -07:00
f2fs_bug_on ( F2FS_I_SB ( inode ) , page - > index ) ;
f2fs_wait_on_page_writeback ( dn . inode_page , NODE ) ;
2014-10-18 23:41:38 -07:00
src_addr = kmap_atomic ( page ) ;
2014-10-23 19:48:09 -07:00
dst_addr = inline_data_addr ( dn . inode_page ) ;
memcpy ( dst_addr , src_addr , MAX_INLINE_DATA ) ;
2014-10-18 23:41:38 -07:00
kunmap_atomic ( src_addr ) ;
2013-11-10 23:13:19 +08:00
2014-07-25 07:40:59 -07:00
set_inode_flag ( F2FS_I ( inode ) , FI_APPEND_WRITE ) ;
2014-10-23 19:48:09 -07:00
set_inode_flag ( F2FS_I ( inode ) , FI_DATA_EXIST ) ;
2013-11-10 23:13:19 +08:00
sync_inode_page ( & dn ) ;
f2fs_put_dnode ( & dn ) ;
return 0 ;
}
2013-12-26 12:49:48 +09:00
2014-10-23 19:48:09 -07:00
void truncate_inline_data ( struct page * ipage , u64 from )
2014-04-29 09:03:03 +08:00
{
2014-10-23 19:48:09 -07:00
void * addr ;
2014-04-29 09:03:03 +08:00
if ( from > = MAX_INLINE_DATA )
return ;
2014-04-29 17:28:32 +09:00
f2fs_wait_on_page_writeback ( ipage , NODE ) ;
2014-10-23 19:48:09 -07:00
addr = inline_data_addr ( ipage ) ;
memset ( addr + from , 0 , MAX_INLINE_DATA - from ) ;
2014-04-29 09:03:03 +08:00
}
2014-08-07 16:57:17 -07:00
bool recover_inline_data ( struct inode * inode , struct page * npage )
2013-12-26 12:49:48 +09:00
{
2014-09-02 15:31:18 -07:00
struct f2fs_sb_info * sbi = F2FS_I_SB ( inode ) ;
2013-12-26 12:49:48 +09:00
struct f2fs_inode * ri = NULL ;
void * src_addr , * dst_addr ;
struct page * ipage ;
/*
* The inline_data recovery policy is as follows .
* [ prev . ] [ next ] of inline_data flag
* o o - > recover inline_data
* o x - > remove inline_data , and then recover data blocks
* x o - > remove inline_data , and then recover inline_data
* x x - > recover data blocks
*/
if ( IS_INODE ( npage ) )
ri = F2FS_INODE ( npage ) ;
if ( f2fs_has_inline_data ( inode ) & &
2014-08-07 16:57:17 -07:00
ri & & ( ri - > i_inline & F2FS_INLINE_DATA ) ) {
2013-12-26 12:49:48 +09:00
process_inline :
ipage = get_node_page ( sbi , inode - > i_ino ) ;
2014-09-02 15:52:58 -07:00
f2fs_bug_on ( sbi , IS_ERR ( ipage ) ) ;
2013-12-26 12:49:48 +09:00
2014-04-29 17:28:32 +09:00
f2fs_wait_on_page_writeback ( ipage , NODE ) ;
2013-12-26 12:49:48 +09:00
src_addr = inline_data_addr ( npage ) ;
dst_addr = inline_data_addr ( ipage ) ;
memcpy ( dst_addr , src_addr , MAX_INLINE_DATA ) ;
2014-10-23 19:48:09 -07:00
set_inode_flag ( F2FS_I ( inode ) , FI_INLINE_DATA ) ;
set_inode_flag ( F2FS_I ( inode ) , FI_DATA_EXIST ) ;
2013-12-26 12:49:48 +09:00
update_inode ( inode , ipage ) ;
f2fs_put_page ( ipage , 1 ) ;
2014-08-07 16:57:17 -07:00
return true ;
2013-12-26 12:49:48 +09:00
}
if ( f2fs_has_inline_data ( inode ) ) {
ipage = get_node_page ( sbi , inode - > i_ino ) ;
2014-09-02 15:52:58 -07:00
f2fs_bug_on ( sbi , IS_ERR ( ipage ) ) ;
2014-10-23 19:48:09 -07:00
truncate_inline_data ( ipage , 0 ) ;
f2fs_clear_inline_inode ( inode ) ;
2013-12-26 12:49:48 +09:00
update_inode ( inode , ipage ) ;
f2fs_put_page ( ipage , 1 ) ;
2014-08-07 16:57:17 -07:00
} else if ( ri & & ( ri - > i_inline & F2FS_INLINE_DATA ) ) {
2014-08-14 16:32:54 -07:00
truncate_blocks ( inode , 0 , false ) ;
2013-12-26 12:49:48 +09:00
goto process_inline ;
}
2014-08-07 16:57:17 -07:00
return false ;
2013-12-26 12:49:48 +09:00
}
2014-09-24 18:17:53 +08:00
struct f2fs_dir_entry * find_in_inline_dir ( struct inode * dir ,
struct qstr * name , struct page * * res_page )
{
struct f2fs_sb_info * sbi = F2FS_SB ( dir - > i_sb ) ;
2014-10-13 17:26:14 -07:00
struct f2fs_inline_dentry * inline_dentry ;
2014-09-24 18:17:53 +08:00
struct f2fs_dir_entry * de ;
2014-10-18 22:52:52 -07:00
struct f2fs_dentry_ptr d ;
2014-10-13 17:26:14 -07:00
struct page * ipage ;
2014-09-24 18:17:53 +08:00
ipage = get_node_page ( sbi , dir - > i_ino ) ;
if ( IS_ERR ( ipage ) )
return NULL ;
2014-10-13 17:26:14 -07:00
inline_dentry = inline_data_addr ( ipage ) ;
2014-09-24 18:17:53 +08:00
2014-10-18 22:52:52 -07:00
make_dentry_ptr ( & d , ( void * ) inline_dentry , 2 ) ;
de = find_target_dentry ( name , NULL , & d ) ;
2014-09-24 18:17:53 +08:00
unlock_page ( ipage ) ;
2014-10-13 17:26:14 -07:00
if ( de )
* res_page = ipage ;
else
f2fs_put_page ( ipage , 0 ) ;
/*
* For the most part , it should be a bug when name_len is zero .
* We stop here for figuring out where the bugs has occurred .
*/
2014-10-18 22:52:52 -07:00
f2fs_bug_on ( sbi , d . max < 0 ) ;
2014-09-24 18:17:53 +08:00
return de ;
}
struct f2fs_dir_entry * f2fs_parent_inline_dir ( struct inode * dir ,
struct page * * p )
{
struct f2fs_sb_info * sbi = F2FS_I_SB ( dir ) ;
struct page * ipage ;
struct f2fs_dir_entry * de ;
struct f2fs_inline_dentry * dentry_blk ;
ipage = get_node_page ( sbi , dir - > i_ino ) ;
if ( IS_ERR ( ipage ) )
return NULL ;
dentry_blk = inline_data_addr ( ipage ) ;
de = & dentry_blk - > dentry [ 1 ] ;
* p = ipage ;
unlock_page ( ipage ) ;
return de ;
}
int make_empty_inline_dir ( struct inode * inode , struct inode * parent ,
struct page * ipage )
{
struct f2fs_inline_dentry * dentry_blk ;
2014-10-18 23:06:41 -07:00
struct f2fs_dentry_ptr d ;
2014-09-24 18:17:53 +08:00
dentry_blk = inline_data_addr ( ipage ) ;
2014-10-18 23:06:41 -07:00
make_dentry_ptr ( & d , ( void * ) dentry_blk , 2 ) ;
do_make_empty_dir ( inode , parent , & d ) ;
2014-09-24 18:17:53 +08:00
set_page_dirty ( ipage ) ;
/* update i_size to MAX_INLINE_DATA */
if ( i_size_read ( inode ) < MAX_INLINE_DATA ) {
i_size_write ( inode , MAX_INLINE_DATA ) ;
set_inode_flag ( F2FS_I ( inode ) , FI_UPDATE_DIR ) ;
}
return 0 ;
}
2014-10-20 20:28:49 -07:00
static int f2fs_convert_inline_dir ( struct inode * dir , struct page * ipage ,
2014-09-24 18:17:53 +08:00
struct f2fs_inline_dentry * inline_dentry )
{
struct page * page ;
struct dnode_of_data dn ;
struct f2fs_dentry_block * dentry_blk ;
int err ;
page = grab_cache_page ( dir - > i_mapping , 0 ) ;
if ( ! page )
return - ENOMEM ;
set_new_dnode ( & dn , dir , ipage , NULL , 0 ) ;
err = f2fs_reserve_block ( & dn , 0 ) ;
if ( err )
goto out ;
f2fs_wait_on_page_writeback ( page , DATA ) ;
zero_user_segment ( page , 0 , PAGE_CACHE_SIZE ) ;
2014-10-18 23:41:38 -07:00
dentry_blk = kmap_atomic ( page ) ;
2014-09-24 18:17:53 +08:00
/* copy data from inline dentry block to new dentry block */
memcpy ( dentry_blk - > dentry_bitmap , inline_dentry - > dentry_bitmap ,
INLINE_DENTRY_BITMAP_SIZE ) ;
memcpy ( dentry_blk - > dentry , inline_dentry - > dentry ,
sizeof ( struct f2fs_dir_entry ) * NR_INLINE_DENTRY ) ;
memcpy ( dentry_blk - > filename , inline_dentry - > filename ,
NR_INLINE_DENTRY * F2FS_SLOT_LEN ) ;
2014-10-18 23:41:38 -07:00
kunmap_atomic ( dentry_blk ) ;
2014-09-24 18:17:53 +08:00
SetPageUptodate ( page ) ;
set_page_dirty ( page ) ;
/* clear inline dir and flag after data writeback */
2014-10-23 19:48:09 -07:00
truncate_inline_data ( ipage , 0 ) ;
2014-10-13 20:00:16 -07:00
stat_dec_inline_dir ( dir ) ;
2014-09-24 18:19:10 +08:00
clear_inode_flag ( F2FS_I ( dir ) , FI_INLINE_DENTRY ) ;
2014-09-24 18:17:53 +08:00
if ( i_size_read ( dir ) < PAGE_CACHE_SIZE ) {
i_size_write ( dir , PAGE_CACHE_SIZE ) ;
set_inode_flag ( F2FS_I ( dir ) , FI_UPDATE_DIR ) ;
}
sync_inode_page ( & dn ) ;
out :
f2fs_put_page ( page , 1 ) ;
return err ;
}
int f2fs_add_inline_entry ( struct inode * dir , const struct qstr * name ,
struct inode * inode )
{
struct f2fs_sb_info * sbi = F2FS_I_SB ( dir ) ;
struct page * ipage ;
unsigned int bit_pos ;
f2fs_hash_t name_hash ;
struct f2fs_dir_entry * de ;
size_t namelen = name - > len ;
struct f2fs_inline_dentry * dentry_blk = NULL ;
int slots = GET_DENTRY_SLOTS ( namelen ) ;
struct page * page ;
int err = 0 ;
int i ;
name_hash = f2fs_dentry_hash ( name ) ;
ipage = get_node_page ( sbi , dir - > i_ino ) ;
if ( IS_ERR ( ipage ) )
return PTR_ERR ( ipage ) ;
dentry_blk = inline_data_addr ( ipage ) ;
2014-10-13 16:28:13 -07:00
bit_pos = room_for_filename ( & dentry_blk - > dentry_bitmap ,
slots , NR_INLINE_DENTRY ) ;
2014-09-24 18:17:53 +08:00
if ( bit_pos > = NR_INLINE_DENTRY ) {
err = f2fs_convert_inline_dir ( dir , ipage , dentry_blk ) ;
if ( ! err )
err = - EAGAIN ;
goto out ;
}
down_write ( & F2FS_I ( inode ) - > i_sem ) ;
2014-10-13 19:42:53 -07:00
page = init_inode_metadata ( inode , dir , name , ipage ) ;
2014-09-24 18:17:53 +08:00
if ( IS_ERR ( page ) ) {
err = PTR_ERR ( page ) ;
goto fail ;
}
2014-10-13 19:42:53 -07:00
f2fs_wait_on_page_writeback ( ipage , NODE ) ;
2014-09-24 18:17:53 +08:00
de = & dentry_blk - > dentry [ bit_pos ] ;
de - > hash_code = name_hash ;
de - > name_len = cpu_to_le16 ( namelen ) ;
memcpy ( dentry_blk - > filename [ bit_pos ] , name - > name , name - > len ) ;
de - > ino = cpu_to_le32 ( inode - > i_ino ) ;
set_de_type ( de , inode ) ;
for ( i = 0 ; i < slots ; i + + )
test_and_set_bit_le ( bit_pos + i , & dentry_blk - > dentry_bitmap ) ;
set_page_dirty ( ipage ) ;
/* we don't need to mark_inode_dirty now */
F2FS_I ( inode ) - > i_pino = dir - > i_ino ;
update_inode ( inode , page ) ;
f2fs_put_page ( page , 1 ) ;
update_parent_metadata ( dir , inode , 0 ) ;
fail :
up_write ( & F2FS_I ( inode ) - > i_sem ) ;
if ( is_inode_flag_set ( F2FS_I ( dir ) , FI_UPDATE_DIR ) ) {
update_inode ( dir , ipage ) ;
clear_inode_flag ( F2FS_I ( dir ) , FI_UPDATE_DIR ) ;
}
out :
f2fs_put_page ( ipage , 1 ) ;
return err ;
}
void f2fs_delete_inline_entry ( struct f2fs_dir_entry * dentry , struct page * page ,
struct inode * dir , struct inode * inode )
{
struct f2fs_inline_dentry * inline_dentry ;
int slots = GET_DENTRY_SLOTS ( le16_to_cpu ( dentry - > name_len ) ) ;
unsigned int bit_pos ;
int i ;
lock_page ( page ) ;
2014-10-13 19:34:26 -07:00
f2fs_wait_on_page_writeback ( page , NODE ) ;
2014-09-24 18:17:53 +08:00
inline_dentry = inline_data_addr ( page ) ;
bit_pos = dentry - inline_dentry - > dentry ;
for ( i = 0 ; i < slots ; i + + )
test_and_clear_bit_le ( bit_pos + i ,
& inline_dentry - > dentry_bitmap ) ;
set_page_dirty ( page ) ;
dir - > i_ctime = dir - > i_mtime = CURRENT_TIME ;
if ( inode )
f2fs_drop_nlink ( dir , inode , page ) ;
f2fs_put_page ( page , 1 ) ;
}
bool f2fs_empty_inline_dir ( struct inode * dir )
{
struct f2fs_sb_info * sbi = F2FS_I_SB ( dir ) ;
struct page * ipage ;
unsigned int bit_pos = 2 ;
struct f2fs_inline_dentry * dentry_blk ;
ipage = get_node_page ( sbi , dir - > i_ino ) ;
if ( IS_ERR ( ipage ) )
return false ;
dentry_blk = inline_data_addr ( ipage ) ;
bit_pos = find_next_bit_le ( & dentry_blk - > dentry_bitmap ,
NR_INLINE_DENTRY ,
bit_pos ) ;
f2fs_put_page ( ipage , 1 ) ;
if ( bit_pos < NR_INLINE_DENTRY )
return false ;
return true ;
}
int f2fs_read_inline_dir ( struct file * file , struct dir_context * ctx )
{
struct inode * inode = file_inode ( file ) ;
struct f2fs_inline_dentry * inline_dentry = NULL ;
struct page * ipage = NULL ;
2014-10-18 22:52:52 -07:00
struct f2fs_dentry_ptr d ;
2014-09-24 18:17:53 +08:00
if ( ctx - > pos = = NR_INLINE_DENTRY )
return 0 ;
2014-10-15 21:29:51 -07:00
ipage = get_node_page ( F2FS_I_SB ( inode ) , inode - > i_ino ) ;
2014-09-24 18:17:53 +08:00
if ( IS_ERR ( ipage ) )
return PTR_ERR ( ipage ) ;
inline_dentry = inline_data_addr ( ipage ) ;
2014-10-18 22:52:52 -07:00
make_dentry_ptr ( & d , ( void * ) inline_dentry , 2 ) ;
if ( ! f2fs_fill_dentries ( ctx , & d , 0 ) )
2014-10-15 21:29:51 -07:00
ctx - > pos = NR_INLINE_DENTRY ;
2014-09-24 18:17:53 +08:00
2014-10-15 21:29:51 -07:00
f2fs_put_page ( ipage , 1 ) ;
2014-09-24 18:17:53 +08:00
return 0 ;
}