1 /* 2 * fs/f2fs/inline.c 3 * Copyright (c) 2013, Intel Corporation 4 * Authors: Huajun Li <huajun.li@intel.com> 5 * Haicheng Li <haicheng.li@intel.com> 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 */ 10 11 #include <linux/fs.h> 12 #include <linux/f2fs_fs.h> 13 14 #include "f2fs.h" 15 16 bool f2fs_may_inline(struct inode *inode) 17 { 18 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 19 block_t nr_blocks; 20 loff_t i_size; 21 22 if (!test_opt(sbi, INLINE_DATA)) 23 return false; 24 25 nr_blocks = F2FS_I(inode)->i_xattr_nid ? 3 : 2; 26 if (inode->i_blocks > nr_blocks) 27 return false; 28 29 i_size = i_size_read(inode); 30 if (i_size > MAX_INLINE_DATA) 31 return false; 32 33 return true; 34 } 35 36 int f2fs_read_inline_data(struct inode *inode, struct page *page) 37 { 38 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 39 struct page *ipage; 40 void *src_addr, *dst_addr; 41 42 if (page->index) { 43 zero_user_segment(page, 0, PAGE_CACHE_SIZE); 44 goto out; 45 } 46 47 ipage = get_node_page(sbi, inode->i_ino); 48 if (IS_ERR(ipage)) 49 return PTR_ERR(ipage); 50 51 zero_user_segment(page, MAX_INLINE_DATA, PAGE_CACHE_SIZE); 52 53 /* Copy the whole inline data block */ 54 src_addr = inline_data_addr(ipage); 55 dst_addr = kmap(page); 56 memcpy(dst_addr, src_addr, MAX_INLINE_DATA); 57 kunmap(page); 58 f2fs_put_page(ipage, 1); 59 60 out: 61 SetPageUptodate(page); 62 unlock_page(page); 63 64 return 0; 65 } 66 67 static int __f2fs_convert_inline_data(struct inode *inode, struct page *page) 68 { 69 int err; 70 struct page *ipage; 71 struct dnode_of_data dn; 72 void *src_addr, *dst_addr; 73 block_t new_blk_addr; 74 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 75 struct f2fs_io_info fio = { 76 .type = DATA, 77 .rw = WRITE_SYNC | REQ_PRIO, 78 }; 79 80 f2fs_lock_op(sbi); 81 ipage = get_node_page(sbi, inode->i_ino); 82 if (IS_ERR(ipage)) 83 return PTR_ERR(ipage); 84 85 /* 86 * i_addr[0] is not used for inline data, 87 * so reserving new block will not destroy inline data 88 */ 89 set_new_dnode(&dn, inode, ipage, NULL, 0); 90 err = f2fs_reserve_block(&dn, 0); 91 if (err) { 92 f2fs_unlock_op(sbi); 93 return err; 94 } 95 96 zero_user_segment(page, MAX_INLINE_DATA, PAGE_CACHE_SIZE); 97 98 /* Copy the whole inline data block */ 99 src_addr = inline_data_addr(ipage); 100 dst_addr = kmap(page); 101 memcpy(dst_addr, src_addr, MAX_INLINE_DATA); 102 kunmap(page); 103 SetPageUptodate(page); 104 105 /* write data page to try to make data consistent */ 106 set_page_writeback(page); 107 write_data_page(page, &dn, &new_blk_addr, &fio); 108 update_extent_cache(new_blk_addr, &dn); 109 f2fs_wait_on_page_writeback(page, DATA); 110 111 /* clear inline data and flag after data writeback */ 112 zero_user_segment(ipage, INLINE_DATA_OFFSET, 113 INLINE_DATA_OFFSET + MAX_INLINE_DATA); 114 clear_inode_flag(F2FS_I(inode), FI_INLINE_DATA); 115 stat_dec_inline_inode(inode); 116 117 sync_inode_page(&dn); 118 f2fs_put_dnode(&dn); 119 f2fs_unlock_op(sbi); 120 return err; 121 } 122 123 int f2fs_convert_inline_data(struct inode *inode, pgoff_t to_size) 124 { 125 struct page *page; 126 int err; 127 128 if (!f2fs_has_inline_data(inode)) 129 return 0; 130 else if (to_size <= MAX_INLINE_DATA) 131 return 0; 132 133 page = grab_cache_page_write_begin(inode->i_mapping, 0, AOP_FLAG_NOFS); 134 if (!page) 135 return -ENOMEM; 136 137 err = __f2fs_convert_inline_data(inode, page); 138 f2fs_put_page(page, 1); 139 return err; 140 } 141 142 int f2fs_write_inline_data(struct inode *inode, 143 struct page *page, unsigned size) 144 { 145 void *src_addr, *dst_addr; 146 struct page *ipage; 147 struct dnode_of_data dn; 148 int err; 149 150 set_new_dnode(&dn, inode, NULL, NULL, 0); 151 err = get_dnode_of_data(&dn, 0, LOOKUP_NODE); 152 if (err) 153 return err; 154 ipage = dn.inode_page; 155 156 zero_user_segment(ipage, INLINE_DATA_OFFSET, 157 INLINE_DATA_OFFSET + MAX_INLINE_DATA); 158 src_addr = kmap(page); 159 dst_addr = inline_data_addr(ipage); 160 memcpy(dst_addr, src_addr, size); 161 kunmap(page); 162 163 /* Release the first data block if it is allocated */ 164 if (!f2fs_has_inline_data(inode)) { 165 truncate_data_blocks_range(&dn, 1); 166 set_inode_flag(F2FS_I(inode), FI_INLINE_DATA); 167 stat_inc_inline_inode(inode); 168 } 169 170 sync_inode_page(&dn); 171 f2fs_put_dnode(&dn); 172 173 return 0; 174 } 175 176 int recover_inline_data(struct inode *inode, struct page *npage) 177 { 178 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 179 struct f2fs_inode *ri = NULL; 180 void *src_addr, *dst_addr; 181 struct page *ipage; 182 183 /* 184 * The inline_data recovery policy is as follows. 185 * [prev.] [next] of inline_data flag 186 * o o -> recover inline_data 187 * o x -> remove inline_data, and then recover data blocks 188 * x o -> remove inline_data, and then recover inline_data 189 * x x -> recover data blocks 190 */ 191 if (IS_INODE(npage)) 192 ri = F2FS_INODE(npage); 193 194 if (f2fs_has_inline_data(inode) && 195 ri && ri->i_inline & F2FS_INLINE_DATA) { 196 process_inline: 197 ipage = get_node_page(sbi, inode->i_ino); 198 f2fs_bug_on(IS_ERR(ipage)); 199 200 src_addr = inline_data_addr(npage); 201 dst_addr = inline_data_addr(ipage); 202 memcpy(dst_addr, src_addr, MAX_INLINE_DATA); 203 update_inode(inode, ipage); 204 f2fs_put_page(ipage, 1); 205 return -1; 206 } 207 208 if (f2fs_has_inline_data(inode)) { 209 ipage = get_node_page(sbi, inode->i_ino); 210 f2fs_bug_on(IS_ERR(ipage)); 211 zero_user_segment(ipage, INLINE_DATA_OFFSET, 212 INLINE_DATA_OFFSET + MAX_INLINE_DATA); 213 clear_inode_flag(F2FS_I(inode), FI_INLINE_DATA); 214 update_inode(inode, ipage); 215 f2fs_put_page(ipage, 1); 216 } else if (ri && ri->i_inline & F2FS_INLINE_DATA) { 217 truncate_blocks(inode, 0); 218 set_inode_flag(F2FS_I(inode), FI_INLINE_DATA); 219 goto process_inline; 220 } 221 return 0; 222 } 223