1e18c65b2SHuajun Li /* 2e18c65b2SHuajun Li * fs/f2fs/inline.c 3e18c65b2SHuajun Li * Copyright (c) 2013, Intel Corporation 4e18c65b2SHuajun Li * Authors: Huajun Li <huajun.li@intel.com> 5e18c65b2SHuajun Li * Haicheng Li <haicheng.li@intel.com> 6e18c65b2SHuajun Li * This program is free software; you can redistribute it and/or modify 7e18c65b2SHuajun Li * it under the terms of the GNU General Public License version 2 as 8e18c65b2SHuajun Li * published by the Free Software Foundation. 9e18c65b2SHuajun Li */ 10e18c65b2SHuajun Li 11e18c65b2SHuajun Li #include <linux/fs.h> 12e18c65b2SHuajun Li #include <linux/f2fs_fs.h> 13e18c65b2SHuajun Li 14e18c65b2SHuajun Li #include "f2fs.h" 15e18c65b2SHuajun Li 16e18c65b2SHuajun Li bool f2fs_may_inline(struct inode *inode) 17e18c65b2SHuajun Li { 18e18c65b2SHuajun Li block_t nr_blocks; 19e18c65b2SHuajun Li loff_t i_size; 20e18c65b2SHuajun Li 214081363fSJaegeuk Kim if (!test_opt(F2FS_I_SB(inode), INLINE_DATA)) 22e18c65b2SHuajun Li return false; 23e18c65b2SHuajun Li 2488b88a66SJaegeuk Kim if (f2fs_is_atomic_file(inode)) 2588b88a66SJaegeuk Kim return false; 2688b88a66SJaegeuk Kim 27e18c65b2SHuajun Li nr_blocks = F2FS_I(inode)->i_xattr_nid ? 3 : 2; 28e18c65b2SHuajun Li if (inode->i_blocks > nr_blocks) 29e18c65b2SHuajun Li return false; 30e18c65b2SHuajun Li 31e18c65b2SHuajun Li i_size = i_size_read(inode); 32e18c65b2SHuajun Li if (i_size > MAX_INLINE_DATA) 33e18c65b2SHuajun Li return false; 34e18c65b2SHuajun Li 35e18c65b2SHuajun Li return true; 36e18c65b2SHuajun Li } 37e18c65b2SHuajun Li 38e18c65b2SHuajun Li int f2fs_read_inline_data(struct inode *inode, struct page *page) 39e18c65b2SHuajun Li { 40e18c65b2SHuajun Li struct page *ipage; 41e18c65b2SHuajun Li void *src_addr, *dst_addr; 42e18c65b2SHuajun Li 4304a17fb1SChao Yu if (page->index) { 4404a17fb1SChao Yu zero_user_segment(page, 0, PAGE_CACHE_SIZE); 4504a17fb1SChao Yu goto out; 4604a17fb1SChao Yu } 4704a17fb1SChao Yu 484081363fSJaegeuk Kim ipage = get_node_page(F2FS_I_SB(inode), inode->i_ino); 49d54c795bSChao Yu if (IS_ERR(ipage)) { 50d54c795bSChao Yu unlock_page(page); 51e18c65b2SHuajun Li return PTR_ERR(ipage); 52d54c795bSChao Yu } 53e18c65b2SHuajun Li 5418309aaaSChao Yu zero_user_segment(page, MAX_INLINE_DATA, PAGE_CACHE_SIZE); 55e18c65b2SHuajun Li 56e18c65b2SHuajun Li /* Copy the whole inline data block */ 57e18c65b2SHuajun Li src_addr = inline_data_addr(ipage); 58e18c65b2SHuajun Li dst_addr = kmap(page); 59e18c65b2SHuajun Li memcpy(dst_addr, src_addr, MAX_INLINE_DATA); 60e18c65b2SHuajun Li kunmap(page); 61e18c65b2SHuajun Li f2fs_put_page(ipage, 1); 62e18c65b2SHuajun Li 6304a17fb1SChao Yu out: 64e18c65b2SHuajun Li SetPageUptodate(page); 65e18c65b2SHuajun Li unlock_page(page); 66e18c65b2SHuajun Li 67e18c65b2SHuajun Li return 0; 68e18c65b2SHuajun Li } 69e18c65b2SHuajun Li 70e18c65b2SHuajun Li static int __f2fs_convert_inline_data(struct inode *inode, struct page *page) 71e18c65b2SHuajun Li { 72ec4e7af4SJaegeuk Kim int err = 0; 73e18c65b2SHuajun Li struct page *ipage; 74e18c65b2SHuajun Li struct dnode_of_data dn; 75e18c65b2SHuajun Li void *src_addr, *dst_addr; 76e18c65b2SHuajun Li block_t new_blk_addr; 774081363fSJaegeuk Kim struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 78e18c65b2SHuajun Li struct f2fs_io_info fio = { 79e18c65b2SHuajun Li .type = DATA, 80e18c65b2SHuajun Li .rw = WRITE_SYNC | REQ_PRIO, 81e18c65b2SHuajun Li }; 82e18c65b2SHuajun Li 83e18c65b2SHuajun Li f2fs_lock_op(sbi); 84e18c65b2SHuajun Li ipage = get_node_page(sbi, inode->i_ino); 8515c6e3aaSJaegeuk Kim if (IS_ERR(ipage)) { 8615c6e3aaSJaegeuk Kim err = PTR_ERR(ipage); 8715c6e3aaSJaegeuk Kim goto out; 8815c6e3aaSJaegeuk Kim } 89e18c65b2SHuajun Li 90ec4e7af4SJaegeuk Kim /* someone else converted inline_data already */ 91ec4e7af4SJaegeuk Kim if (!f2fs_has_inline_data(inode)) 92ec4e7af4SJaegeuk Kim goto out; 93ec4e7af4SJaegeuk Kim 94e18c65b2SHuajun Li /* 95e18c65b2SHuajun Li * i_addr[0] is not used for inline data, 96e18c65b2SHuajun Li * so reserving new block will not destroy inline data 97e18c65b2SHuajun Li */ 98a8865372SJaegeuk Kim set_new_dnode(&dn, inode, ipage, NULL, 0); 99e18c65b2SHuajun Li err = f2fs_reserve_block(&dn, 0); 10015c6e3aaSJaegeuk Kim if (err) 10115c6e3aaSJaegeuk Kim goto out; 102e18c65b2SHuajun Li 1039ac1349aSJaegeuk Kim f2fs_wait_on_page_writeback(page, DATA); 10418309aaaSChao Yu zero_user_segment(page, MAX_INLINE_DATA, PAGE_CACHE_SIZE); 105e18c65b2SHuajun Li 106e18c65b2SHuajun Li /* Copy the whole inline data block */ 107e18c65b2SHuajun Li src_addr = inline_data_addr(ipage); 108e18c65b2SHuajun Li dst_addr = kmap(page); 109e18c65b2SHuajun Li memcpy(dst_addr, src_addr, MAX_INLINE_DATA); 110e18c65b2SHuajun Li kunmap(page); 1119e09fc85SJaegeuk Kim SetPageUptodate(page); 112e18c65b2SHuajun Li 113e18c65b2SHuajun Li /* write data page to try to make data consistent */ 114e18c65b2SHuajun Li set_page_writeback(page); 115e18c65b2SHuajun Li write_data_page(page, &dn, &new_blk_addr, &fio); 116e18c65b2SHuajun Li update_extent_cache(new_blk_addr, &dn); 1175514f0aaSYuan Zhong f2fs_wait_on_page_writeback(page, DATA); 118e18c65b2SHuajun Li 119e18c65b2SHuajun Li /* clear inline data and flag after data writeback */ 120e18c65b2SHuajun Li zero_user_segment(ipage, INLINE_DATA_OFFSET, 121e18c65b2SHuajun Li INLINE_DATA_OFFSET + MAX_INLINE_DATA); 122e18c65b2SHuajun Li clear_inode_flag(F2FS_I(inode), FI_INLINE_DATA); 1230dbdc2aeSJaegeuk Kim stat_dec_inline_inode(inode); 124e18c65b2SHuajun Li 125e18c65b2SHuajun Li sync_inode_page(&dn); 126a8865372SJaegeuk Kim f2fs_put_dnode(&dn); 12715c6e3aaSJaegeuk Kim out: 128e18c65b2SHuajun Li f2fs_unlock_op(sbi); 129e18c65b2SHuajun Li return err; 130e18c65b2SHuajun Li } 131e18c65b2SHuajun Li 132b067ba1fSJaegeuk Kim int f2fs_convert_inline_data(struct inode *inode, pgoff_t to_size, 133b067ba1fSJaegeuk Kim struct page *page) 134e18c65b2SHuajun Li { 135b067ba1fSJaegeuk Kim struct page *new_page = page; 1369e09fc85SJaegeuk Kim int err; 137e18c65b2SHuajun Li 1389e09fc85SJaegeuk Kim if (!f2fs_has_inline_data(inode)) 1399e09fc85SJaegeuk Kim return 0; 1409e09fc85SJaegeuk Kim else if (to_size <= MAX_INLINE_DATA) 1419e09fc85SJaegeuk Kim return 0; 1429e09fc85SJaegeuk Kim 143b067ba1fSJaegeuk Kim if (!page || page->index != 0) { 144b067ba1fSJaegeuk Kim new_page = grab_cache_page(inode->i_mapping, 0); 145b067ba1fSJaegeuk Kim if (!new_page) 1469e09fc85SJaegeuk Kim return -ENOMEM; 147b067ba1fSJaegeuk Kim } 148e18c65b2SHuajun Li 149b067ba1fSJaegeuk Kim err = __f2fs_convert_inline_data(inode, new_page); 150b067ba1fSJaegeuk Kim if (!page || page->index != 0) 151b067ba1fSJaegeuk Kim f2fs_put_page(new_page, 1); 152e18c65b2SHuajun Li return err; 153e18c65b2SHuajun Li } 154e18c65b2SHuajun Li 155e18c65b2SHuajun Li int f2fs_write_inline_data(struct inode *inode, 156e18c65b2SHuajun Li struct page *page, unsigned size) 157e18c65b2SHuajun Li { 158e18c65b2SHuajun Li void *src_addr, *dst_addr; 159e18c65b2SHuajun Li struct page *ipage; 160e18c65b2SHuajun Li struct dnode_of_data dn; 161e18c65b2SHuajun Li int err; 162e18c65b2SHuajun Li 163e18c65b2SHuajun Li set_new_dnode(&dn, inode, NULL, NULL, 0); 164e18c65b2SHuajun Li err = get_dnode_of_data(&dn, 0, LOOKUP_NODE); 165e18c65b2SHuajun Li if (err) 166e18c65b2SHuajun Li return err; 167e18c65b2SHuajun Li ipage = dn.inode_page; 168e18c65b2SHuajun Li 169c08a690bSJaegeuk Kim /* Release any data block if it is allocated */ 170c08a690bSJaegeuk Kim if (!f2fs_has_inline_data(inode)) { 171c08a690bSJaegeuk Kim int count = ADDRS_PER_PAGE(dn.node_page, F2FS_I(inode)); 172c08a690bSJaegeuk Kim truncate_data_blocks_range(&dn, count); 173c08a690bSJaegeuk Kim set_inode_flag(F2FS_I(inode), FI_INLINE_DATA); 174c08a690bSJaegeuk Kim stat_inc_inline_inode(inode); 175c08a690bSJaegeuk Kim } 176c08a690bSJaegeuk Kim 17754b591dfSJaegeuk Kim f2fs_wait_on_page_writeback(ipage, NODE); 178e18c65b2SHuajun Li zero_user_segment(ipage, INLINE_DATA_OFFSET, 179e18c65b2SHuajun Li INLINE_DATA_OFFSET + MAX_INLINE_DATA); 180e18c65b2SHuajun Li src_addr = kmap(page); 181e18c65b2SHuajun Li dst_addr = inline_data_addr(ipage); 182e18c65b2SHuajun Li memcpy(dst_addr, src_addr, size); 183e18c65b2SHuajun Li kunmap(page); 184e18c65b2SHuajun Li 185fff04f90SJaegeuk Kim set_inode_flag(F2FS_I(inode), FI_APPEND_WRITE); 186e18c65b2SHuajun Li sync_inode_page(&dn); 187e18c65b2SHuajun Li f2fs_put_dnode(&dn); 188e18c65b2SHuajun Li 189e18c65b2SHuajun Li return 0; 190e18c65b2SHuajun Li } 1911e1bb4baSJaegeuk Kim 1928aa6f1c5SChao Yu void truncate_inline_data(struct inode *inode, u64 from) 1938aa6f1c5SChao Yu { 1948aa6f1c5SChao Yu struct page *ipage; 1958aa6f1c5SChao Yu 1968aa6f1c5SChao Yu if (from >= MAX_INLINE_DATA) 1978aa6f1c5SChao Yu return; 1988aa6f1c5SChao Yu 1994081363fSJaegeuk Kim ipage = get_node_page(F2FS_I_SB(inode), inode->i_ino); 2008aa6f1c5SChao Yu if (IS_ERR(ipage)) 2018aa6f1c5SChao Yu return; 2028aa6f1c5SChao Yu 20354b591dfSJaegeuk Kim f2fs_wait_on_page_writeback(ipage, NODE); 20454b591dfSJaegeuk Kim 2058aa6f1c5SChao Yu zero_user_segment(ipage, INLINE_DATA_OFFSET + from, 2068aa6f1c5SChao Yu INLINE_DATA_OFFSET + MAX_INLINE_DATA); 2078aa6f1c5SChao Yu set_page_dirty(ipage); 2088aa6f1c5SChao Yu f2fs_put_page(ipage, 1); 2098aa6f1c5SChao Yu } 2108aa6f1c5SChao Yu 2110342fd30SJaegeuk Kim bool recover_inline_data(struct inode *inode, struct page *npage) 2121e1bb4baSJaegeuk Kim { 2134081363fSJaegeuk Kim struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 2141e1bb4baSJaegeuk Kim struct f2fs_inode *ri = NULL; 2151e1bb4baSJaegeuk Kim void *src_addr, *dst_addr; 2161e1bb4baSJaegeuk Kim struct page *ipage; 2171e1bb4baSJaegeuk Kim 2181e1bb4baSJaegeuk Kim /* 2191e1bb4baSJaegeuk Kim * The inline_data recovery policy is as follows. 2201e1bb4baSJaegeuk Kim * [prev.] [next] of inline_data flag 2211e1bb4baSJaegeuk Kim * o o -> recover inline_data 2221e1bb4baSJaegeuk Kim * o x -> remove inline_data, and then recover data blocks 2231e1bb4baSJaegeuk Kim * x o -> remove inline_data, and then recover inline_data 2241e1bb4baSJaegeuk Kim * x x -> recover data blocks 2251e1bb4baSJaegeuk Kim */ 2261e1bb4baSJaegeuk Kim if (IS_INODE(npage)) 2271e1bb4baSJaegeuk Kim ri = F2FS_INODE(npage); 2281e1bb4baSJaegeuk Kim 2291e1bb4baSJaegeuk Kim if (f2fs_has_inline_data(inode) && 2300342fd30SJaegeuk Kim ri && (ri->i_inline & F2FS_INLINE_DATA)) { 2311e1bb4baSJaegeuk Kim process_inline: 2321e1bb4baSJaegeuk Kim ipage = get_node_page(sbi, inode->i_ino); 2339850cf4aSJaegeuk Kim f2fs_bug_on(sbi, IS_ERR(ipage)); 2341e1bb4baSJaegeuk Kim 23554b591dfSJaegeuk Kim f2fs_wait_on_page_writeback(ipage, NODE); 23654b591dfSJaegeuk Kim 2371e1bb4baSJaegeuk Kim src_addr = inline_data_addr(npage); 2381e1bb4baSJaegeuk Kim dst_addr = inline_data_addr(ipage); 2391e1bb4baSJaegeuk Kim memcpy(dst_addr, src_addr, MAX_INLINE_DATA); 2401e1bb4baSJaegeuk Kim update_inode(inode, ipage); 2411e1bb4baSJaegeuk Kim f2fs_put_page(ipage, 1); 2420342fd30SJaegeuk Kim return true; 2431e1bb4baSJaegeuk Kim } 2441e1bb4baSJaegeuk Kim 2451e1bb4baSJaegeuk Kim if (f2fs_has_inline_data(inode)) { 2461e1bb4baSJaegeuk Kim ipage = get_node_page(sbi, inode->i_ino); 2479850cf4aSJaegeuk Kim f2fs_bug_on(sbi, IS_ERR(ipage)); 24854b591dfSJaegeuk Kim f2fs_wait_on_page_writeback(ipage, NODE); 2491e1bb4baSJaegeuk Kim zero_user_segment(ipage, INLINE_DATA_OFFSET, 2501e1bb4baSJaegeuk Kim INLINE_DATA_OFFSET + MAX_INLINE_DATA); 2511e1bb4baSJaegeuk Kim clear_inode_flag(F2FS_I(inode), FI_INLINE_DATA); 2521e1bb4baSJaegeuk Kim update_inode(inode, ipage); 2531e1bb4baSJaegeuk Kim f2fs_put_page(ipage, 1); 2540342fd30SJaegeuk Kim } else if (ri && (ri->i_inline & F2FS_INLINE_DATA)) { 255764aa3e9SJaegeuk Kim truncate_blocks(inode, 0, false); 2561e1bb4baSJaegeuk Kim set_inode_flag(F2FS_I(inode), FI_INLINE_DATA); 2571e1bb4baSJaegeuk Kim goto process_inline; 2581e1bb4baSJaegeuk Kim } 2590342fd30SJaegeuk Kim return false; 2601e1bb4baSJaegeuk Kim } 261*201a05beSChao Yu 262*201a05beSChao Yu struct f2fs_dir_entry *find_in_inline_dir(struct inode *dir, 263*201a05beSChao Yu struct qstr *name, struct page **res_page) 264*201a05beSChao Yu { 265*201a05beSChao Yu struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb); 266*201a05beSChao Yu struct page *ipage; 267*201a05beSChao Yu struct f2fs_dir_entry *de; 268*201a05beSChao Yu f2fs_hash_t namehash; 269*201a05beSChao Yu unsigned long bit_pos = 0; 270*201a05beSChao Yu struct f2fs_inline_dentry *dentry_blk; 271*201a05beSChao Yu const void *dentry_bits; 272*201a05beSChao Yu 273*201a05beSChao Yu ipage = get_node_page(sbi, dir->i_ino); 274*201a05beSChao Yu if (IS_ERR(ipage)) 275*201a05beSChao Yu return NULL; 276*201a05beSChao Yu 277*201a05beSChao Yu namehash = f2fs_dentry_hash(name); 278*201a05beSChao Yu 279*201a05beSChao Yu dentry_blk = inline_data_addr(ipage); 280*201a05beSChao Yu dentry_bits = &dentry_blk->dentry_bitmap; 281*201a05beSChao Yu 282*201a05beSChao Yu while (bit_pos < NR_INLINE_DENTRY) { 283*201a05beSChao Yu if (!test_bit_le(bit_pos, dentry_bits)) { 284*201a05beSChao Yu bit_pos++; 285*201a05beSChao Yu continue; 286*201a05beSChao Yu } 287*201a05beSChao Yu de = &dentry_blk->dentry[bit_pos]; 288*201a05beSChao Yu if (early_match_name(name->len, namehash, de)) { 289*201a05beSChao Yu if (!memcmp(dentry_blk->filename[bit_pos], 290*201a05beSChao Yu name->name, 291*201a05beSChao Yu name->len)) { 292*201a05beSChao Yu *res_page = ipage; 293*201a05beSChao Yu goto found; 294*201a05beSChao Yu } 295*201a05beSChao Yu } 296*201a05beSChao Yu 297*201a05beSChao Yu /* 298*201a05beSChao Yu * For the most part, it should be a bug when name_len is zero. 299*201a05beSChao Yu * We stop here for figuring out where the bugs are occurred. 300*201a05beSChao Yu */ 301*201a05beSChao Yu f2fs_bug_on(F2FS_P_SB(ipage), !de->name_len); 302*201a05beSChao Yu 303*201a05beSChao Yu bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len)); 304*201a05beSChao Yu } 305*201a05beSChao Yu 306*201a05beSChao Yu de = NULL; 307*201a05beSChao Yu found: 308*201a05beSChao Yu unlock_page(ipage); 309*201a05beSChao Yu return de; 310*201a05beSChao Yu } 311*201a05beSChao Yu 312*201a05beSChao Yu struct f2fs_dir_entry *f2fs_parent_inline_dir(struct inode *dir, 313*201a05beSChao Yu struct page **p) 314*201a05beSChao Yu { 315*201a05beSChao Yu struct f2fs_sb_info *sbi = F2FS_I_SB(dir); 316*201a05beSChao Yu struct page *ipage; 317*201a05beSChao Yu struct f2fs_dir_entry *de; 318*201a05beSChao Yu struct f2fs_inline_dentry *dentry_blk; 319*201a05beSChao Yu 320*201a05beSChao Yu ipage = get_node_page(sbi, dir->i_ino); 321*201a05beSChao Yu if (IS_ERR(ipage)) 322*201a05beSChao Yu return NULL; 323*201a05beSChao Yu 324*201a05beSChao Yu dentry_blk = inline_data_addr(ipage); 325*201a05beSChao Yu de = &dentry_blk->dentry[1]; 326*201a05beSChao Yu *p = ipage; 327*201a05beSChao Yu unlock_page(ipage); 328*201a05beSChao Yu return de; 329*201a05beSChao Yu } 330*201a05beSChao Yu 331*201a05beSChao Yu int make_empty_inline_dir(struct inode *inode, struct inode *parent, 332*201a05beSChao Yu struct page *ipage) 333*201a05beSChao Yu { 334*201a05beSChao Yu struct f2fs_inline_dentry *dentry_blk; 335*201a05beSChao Yu struct f2fs_dir_entry *de; 336*201a05beSChao Yu 337*201a05beSChao Yu dentry_blk = inline_data_addr(ipage); 338*201a05beSChao Yu 339*201a05beSChao Yu de = &dentry_blk->dentry[0]; 340*201a05beSChao Yu de->name_len = cpu_to_le16(1); 341*201a05beSChao Yu de->hash_code = 0; 342*201a05beSChao Yu de->ino = cpu_to_le32(inode->i_ino); 343*201a05beSChao Yu memcpy(dentry_blk->filename[0], ".", 1); 344*201a05beSChao Yu set_de_type(de, inode); 345*201a05beSChao Yu 346*201a05beSChao Yu de = &dentry_blk->dentry[1]; 347*201a05beSChao Yu de->hash_code = 0; 348*201a05beSChao Yu de->name_len = cpu_to_le16(2); 349*201a05beSChao Yu de->ino = cpu_to_le32(parent->i_ino); 350*201a05beSChao Yu memcpy(dentry_blk->filename[1], "..", 2); 351*201a05beSChao Yu set_de_type(de, inode); 352*201a05beSChao Yu 353*201a05beSChao Yu test_and_set_bit_le(0, &dentry_blk->dentry_bitmap); 354*201a05beSChao Yu test_and_set_bit_le(1, &dentry_blk->dentry_bitmap); 355*201a05beSChao Yu 356*201a05beSChao Yu set_page_dirty(ipage); 357*201a05beSChao Yu 358*201a05beSChao Yu /* update i_size to MAX_INLINE_DATA */ 359*201a05beSChao Yu if (i_size_read(inode) < MAX_INLINE_DATA) { 360*201a05beSChao Yu i_size_write(inode, MAX_INLINE_DATA); 361*201a05beSChao Yu set_inode_flag(F2FS_I(inode), FI_UPDATE_DIR); 362*201a05beSChao Yu } 363*201a05beSChao Yu return 0; 364*201a05beSChao Yu } 365*201a05beSChao Yu 366*201a05beSChao Yu int room_in_inline_dir(struct f2fs_inline_dentry *dentry_blk, int slots) 367*201a05beSChao Yu { 368*201a05beSChao Yu int bit_start = 0; 369*201a05beSChao Yu int zero_start, zero_end; 370*201a05beSChao Yu next: 371*201a05beSChao Yu zero_start = find_next_zero_bit_le(&dentry_blk->dentry_bitmap, 372*201a05beSChao Yu NR_INLINE_DENTRY, 373*201a05beSChao Yu bit_start); 374*201a05beSChao Yu if (zero_start >= NR_INLINE_DENTRY) 375*201a05beSChao Yu return NR_INLINE_DENTRY; 376*201a05beSChao Yu 377*201a05beSChao Yu zero_end = find_next_bit_le(&dentry_blk->dentry_bitmap, 378*201a05beSChao Yu NR_INLINE_DENTRY, 379*201a05beSChao Yu zero_start); 380*201a05beSChao Yu if (zero_end - zero_start >= slots) 381*201a05beSChao Yu return zero_start; 382*201a05beSChao Yu 383*201a05beSChao Yu bit_start = zero_end + 1; 384*201a05beSChao Yu 385*201a05beSChao Yu if (zero_end + 1 >= NR_INLINE_DENTRY) 386*201a05beSChao Yu return NR_INLINE_DENTRY; 387*201a05beSChao Yu goto next; 388*201a05beSChao Yu } 389*201a05beSChao Yu 390*201a05beSChao Yu int f2fs_convert_inline_dir(struct inode *dir, struct page *ipage, 391*201a05beSChao Yu struct f2fs_inline_dentry *inline_dentry) 392*201a05beSChao Yu { 393*201a05beSChao Yu struct page *page; 394*201a05beSChao Yu struct dnode_of_data dn; 395*201a05beSChao Yu struct f2fs_dentry_block *dentry_blk; 396*201a05beSChao Yu int err; 397*201a05beSChao Yu 398*201a05beSChao Yu page = grab_cache_page(dir->i_mapping, 0); 399*201a05beSChao Yu if (!page) 400*201a05beSChao Yu return -ENOMEM; 401*201a05beSChao Yu 402*201a05beSChao Yu set_new_dnode(&dn, dir, ipage, NULL, 0); 403*201a05beSChao Yu err = f2fs_reserve_block(&dn, 0); 404*201a05beSChao Yu if (err) 405*201a05beSChao Yu goto out; 406*201a05beSChao Yu 407*201a05beSChao Yu f2fs_wait_on_page_writeback(page, DATA); 408*201a05beSChao Yu zero_user_segment(page, 0, PAGE_CACHE_SIZE); 409*201a05beSChao Yu 410*201a05beSChao Yu dentry_blk = kmap(page); 411*201a05beSChao Yu 412*201a05beSChao Yu /* copy data from inline dentry block to new dentry block */ 413*201a05beSChao Yu memcpy(dentry_blk->dentry_bitmap, inline_dentry->dentry_bitmap, 414*201a05beSChao Yu INLINE_DENTRY_BITMAP_SIZE); 415*201a05beSChao Yu memcpy(dentry_blk->dentry, inline_dentry->dentry, 416*201a05beSChao Yu sizeof(struct f2fs_dir_entry) * NR_INLINE_DENTRY); 417*201a05beSChao Yu memcpy(dentry_blk->filename, inline_dentry->filename, 418*201a05beSChao Yu NR_INLINE_DENTRY * F2FS_SLOT_LEN); 419*201a05beSChao Yu 420*201a05beSChao Yu kunmap(page); 421*201a05beSChao Yu SetPageUptodate(page); 422*201a05beSChao Yu set_page_dirty(page); 423*201a05beSChao Yu 424*201a05beSChao Yu /* clear inline dir and flag after data writeback */ 425*201a05beSChao Yu zero_user_segment(ipage, INLINE_DATA_OFFSET, 426*201a05beSChao Yu INLINE_DATA_OFFSET + MAX_INLINE_DATA); 427*201a05beSChao Yu 428*201a05beSChao Yu stat_dec_inline_inode(dir); 429*201a05beSChao Yu 430*201a05beSChao Yu if (i_size_read(dir) < PAGE_CACHE_SIZE) { 431*201a05beSChao Yu i_size_write(dir, PAGE_CACHE_SIZE); 432*201a05beSChao Yu set_inode_flag(F2FS_I(dir), FI_UPDATE_DIR); 433*201a05beSChao Yu } 434*201a05beSChao Yu 435*201a05beSChao Yu sync_inode_page(&dn); 436*201a05beSChao Yu out: 437*201a05beSChao Yu f2fs_put_page(page, 1); 438*201a05beSChao Yu return err; 439*201a05beSChao Yu } 440*201a05beSChao Yu 441*201a05beSChao Yu int f2fs_add_inline_entry(struct inode *dir, const struct qstr *name, 442*201a05beSChao Yu struct inode *inode) 443*201a05beSChao Yu { 444*201a05beSChao Yu struct f2fs_sb_info *sbi = F2FS_I_SB(dir); 445*201a05beSChao Yu struct page *ipage; 446*201a05beSChao Yu unsigned int bit_pos; 447*201a05beSChao Yu f2fs_hash_t name_hash; 448*201a05beSChao Yu struct f2fs_dir_entry *de; 449*201a05beSChao Yu size_t namelen = name->len; 450*201a05beSChao Yu struct f2fs_inline_dentry *dentry_blk = NULL; 451*201a05beSChao Yu int slots = GET_DENTRY_SLOTS(namelen); 452*201a05beSChao Yu struct page *page; 453*201a05beSChao Yu int err = 0; 454*201a05beSChao Yu int i; 455*201a05beSChao Yu 456*201a05beSChao Yu name_hash = f2fs_dentry_hash(name); 457*201a05beSChao Yu 458*201a05beSChao Yu ipage = get_node_page(sbi, dir->i_ino); 459*201a05beSChao Yu if (IS_ERR(ipage)) 460*201a05beSChao Yu return PTR_ERR(ipage); 461*201a05beSChao Yu 462*201a05beSChao Yu dentry_blk = inline_data_addr(ipage); 463*201a05beSChao Yu bit_pos = room_in_inline_dir(dentry_blk, slots); 464*201a05beSChao Yu if (bit_pos >= NR_INLINE_DENTRY) { 465*201a05beSChao Yu err = f2fs_convert_inline_dir(dir, ipage, dentry_blk); 466*201a05beSChao Yu if (!err) 467*201a05beSChao Yu err = -EAGAIN; 468*201a05beSChao Yu goto out; 469*201a05beSChao Yu } 470*201a05beSChao Yu 471*201a05beSChao Yu f2fs_wait_on_page_writeback(ipage, DATA); 472*201a05beSChao Yu 473*201a05beSChao Yu down_write(&F2FS_I(inode)->i_sem); 474*201a05beSChao Yu page = init_inode_metadata(inode, dir, name); 475*201a05beSChao Yu if (IS_ERR(page)) { 476*201a05beSChao Yu err = PTR_ERR(page); 477*201a05beSChao Yu goto fail; 478*201a05beSChao Yu } 479*201a05beSChao Yu de = &dentry_blk->dentry[bit_pos]; 480*201a05beSChao Yu de->hash_code = name_hash; 481*201a05beSChao Yu de->name_len = cpu_to_le16(namelen); 482*201a05beSChao Yu memcpy(dentry_blk->filename[bit_pos], name->name, name->len); 483*201a05beSChao Yu de->ino = cpu_to_le32(inode->i_ino); 484*201a05beSChao Yu set_de_type(de, inode); 485*201a05beSChao Yu for (i = 0; i < slots; i++) 486*201a05beSChao Yu test_and_set_bit_le(bit_pos + i, &dentry_blk->dentry_bitmap); 487*201a05beSChao Yu set_page_dirty(ipage); 488*201a05beSChao Yu 489*201a05beSChao Yu /* we don't need to mark_inode_dirty now */ 490*201a05beSChao Yu F2FS_I(inode)->i_pino = dir->i_ino; 491*201a05beSChao Yu update_inode(inode, page); 492*201a05beSChao Yu f2fs_put_page(page, 1); 493*201a05beSChao Yu 494*201a05beSChao Yu update_parent_metadata(dir, inode, 0); 495*201a05beSChao Yu fail: 496*201a05beSChao Yu up_write(&F2FS_I(inode)->i_sem); 497*201a05beSChao Yu 498*201a05beSChao Yu if (is_inode_flag_set(F2FS_I(dir), FI_UPDATE_DIR)) { 499*201a05beSChao Yu update_inode(dir, ipage); 500*201a05beSChao Yu clear_inode_flag(F2FS_I(dir), FI_UPDATE_DIR); 501*201a05beSChao Yu } 502*201a05beSChao Yu out: 503*201a05beSChao Yu f2fs_put_page(ipage, 1); 504*201a05beSChao Yu return err; 505*201a05beSChao Yu } 506*201a05beSChao Yu 507*201a05beSChao Yu void f2fs_delete_inline_entry(struct f2fs_dir_entry *dentry, struct page *page, 508*201a05beSChao Yu struct inode *dir, struct inode *inode) 509*201a05beSChao Yu { 510*201a05beSChao Yu struct f2fs_inline_dentry *inline_dentry; 511*201a05beSChao Yu int slots = GET_DENTRY_SLOTS(le16_to_cpu(dentry->name_len)); 512*201a05beSChao Yu unsigned int bit_pos; 513*201a05beSChao Yu int i; 514*201a05beSChao Yu 515*201a05beSChao Yu lock_page(page); 516*201a05beSChao Yu f2fs_wait_on_page_writeback(page, DATA); 517*201a05beSChao Yu 518*201a05beSChao Yu inline_dentry = inline_data_addr(page); 519*201a05beSChao Yu bit_pos = dentry - inline_dentry->dentry; 520*201a05beSChao Yu for (i = 0; i < slots; i++) 521*201a05beSChao Yu test_and_clear_bit_le(bit_pos + i, 522*201a05beSChao Yu &inline_dentry->dentry_bitmap); 523*201a05beSChao Yu 524*201a05beSChao Yu set_page_dirty(page); 525*201a05beSChao Yu 526*201a05beSChao Yu dir->i_ctime = dir->i_mtime = CURRENT_TIME; 527*201a05beSChao Yu 528*201a05beSChao Yu if (inode) 529*201a05beSChao Yu f2fs_drop_nlink(dir, inode, page); 530*201a05beSChao Yu 531*201a05beSChao Yu f2fs_put_page(page, 1); 532*201a05beSChao Yu } 533*201a05beSChao Yu 534*201a05beSChao Yu bool f2fs_empty_inline_dir(struct inode *dir) 535*201a05beSChao Yu { 536*201a05beSChao Yu struct f2fs_sb_info *sbi = F2FS_I_SB(dir); 537*201a05beSChao Yu struct page *ipage; 538*201a05beSChao Yu unsigned int bit_pos = 2; 539*201a05beSChao Yu struct f2fs_inline_dentry *dentry_blk; 540*201a05beSChao Yu 541*201a05beSChao Yu ipage = get_node_page(sbi, dir->i_ino); 542*201a05beSChao Yu if (IS_ERR(ipage)) 543*201a05beSChao Yu return false; 544*201a05beSChao Yu 545*201a05beSChao Yu dentry_blk = inline_data_addr(ipage); 546*201a05beSChao Yu bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, 547*201a05beSChao Yu NR_INLINE_DENTRY, 548*201a05beSChao Yu bit_pos); 549*201a05beSChao Yu 550*201a05beSChao Yu f2fs_put_page(ipage, 1); 551*201a05beSChao Yu 552*201a05beSChao Yu if (bit_pos < NR_INLINE_DENTRY) 553*201a05beSChao Yu return false; 554*201a05beSChao Yu 555*201a05beSChao Yu return true; 556*201a05beSChao Yu } 557*201a05beSChao Yu 558*201a05beSChao Yu int f2fs_read_inline_dir(struct file *file, struct dir_context *ctx) 559*201a05beSChao Yu { 560*201a05beSChao Yu struct inode *inode = file_inode(file); 561*201a05beSChao Yu struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 562*201a05beSChao Yu unsigned int bit_pos = 0; 563*201a05beSChao Yu struct f2fs_inline_dentry *inline_dentry = NULL; 564*201a05beSChao Yu struct f2fs_dir_entry *de = NULL; 565*201a05beSChao Yu struct page *ipage = NULL; 566*201a05beSChao Yu unsigned char d_type = DT_UNKNOWN; 567*201a05beSChao Yu 568*201a05beSChao Yu if (ctx->pos == NR_INLINE_DENTRY) 569*201a05beSChao Yu return 0; 570*201a05beSChao Yu 571*201a05beSChao Yu ipage = get_node_page(sbi, inode->i_ino); 572*201a05beSChao Yu if (IS_ERR(ipage)) 573*201a05beSChao Yu return PTR_ERR(ipage); 574*201a05beSChao Yu 575*201a05beSChao Yu bit_pos = ((unsigned long)ctx->pos % NR_INLINE_DENTRY); 576*201a05beSChao Yu 577*201a05beSChao Yu inline_dentry = inline_data_addr(ipage); 578*201a05beSChao Yu while (bit_pos < NR_INLINE_DENTRY) { 579*201a05beSChao Yu bit_pos = find_next_bit_le(&inline_dentry->dentry_bitmap, 580*201a05beSChao Yu NR_INLINE_DENTRY, 581*201a05beSChao Yu bit_pos); 582*201a05beSChao Yu if (bit_pos >= NR_INLINE_DENTRY) 583*201a05beSChao Yu break; 584*201a05beSChao Yu 585*201a05beSChao Yu de = &inline_dentry->dentry[bit_pos]; 586*201a05beSChao Yu if (de->file_type < F2FS_FT_MAX) 587*201a05beSChao Yu d_type = f2fs_filetype_table[de->file_type]; 588*201a05beSChao Yu else 589*201a05beSChao Yu d_type = DT_UNKNOWN; 590*201a05beSChao Yu 591*201a05beSChao Yu if (!dir_emit(ctx, 592*201a05beSChao Yu inline_dentry->filename[bit_pos], 593*201a05beSChao Yu le16_to_cpu(de->name_len), 594*201a05beSChao Yu le32_to_cpu(de->ino), d_type)) 595*201a05beSChao Yu goto out; 596*201a05beSChao Yu 597*201a05beSChao Yu bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len)); 598*201a05beSChao Yu ctx->pos = bit_pos; 599*201a05beSChao Yu } 600*201a05beSChao Yu 601*201a05beSChao Yu ctx->pos = NR_INLINE_DENTRY; 602*201a05beSChao Yu out: 603*201a05beSChao Yu f2fs_put_page(ipage, 1); 604*201a05beSChao Yu 605*201a05beSChao Yu return 0; 606*201a05beSChao Yu } 607