aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk.kim@samsung.com>2013-08-12 08:08:03 -0400
committerJaegeuk Kim <jaegeuk.kim@samsung.com>2013-08-26 07:15:01 -0400
commitde93653fe31fc9439971296842dcd0280f8ab5f4 (patch)
treed4db3c55eead49b0a4f3c9e56eca372f9142d6cd
parent444c580f7e9ad29927a5d5269d576bd7cdccebb8 (diff)
f2fs: reserve the xattr space dynamically
This patch enables the number of direct pointers inside on-disk inode block to be changed dynamically according to the size of inline xattr space. The number of direct pointers, ADDRS_PER_INODE, can be changed only if the file has inline xattr flag. The number of direct pointers that will be used by inline xattrs is defined as F2FS_INLINE_XATTR_ADDRS. Current patch assigns F2FS_INLINE_XATTR_ADDRS to 0 temporarily. Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
-rw-r--r--fs/f2fs/data.c5
-rw-r--r--fs/f2fs/f2fs.h18
-rw-r--r--fs/f2fs/file.c2
-rw-r--r--fs/f2fs/gc.c9
-rw-r--r--fs/f2fs/node.c9
-rw-r--r--fs/f2fs/recovery.c13
-rw-r--r--fs/f2fs/super.c2
-rw-r--r--include/linux/f2fs_fs.h16
8 files changed, 45 insertions, 29 deletions
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 6b328de41728..941f9b9ca3a5 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -117,7 +117,8 @@ void update_extent_cache(block_t blk_addr, struct dnode_of_data *dn)
117 block_t start_blkaddr, end_blkaddr; 117 block_t start_blkaddr, end_blkaddr;
118 118
119 BUG_ON(blk_addr == NEW_ADDR); 119 BUG_ON(blk_addr == NEW_ADDR);
120 fofs = start_bidx_of_node(ofs_of_node(dn->node_page)) + dn->ofs_in_node; 120 fofs = start_bidx_of_node(ofs_of_node(dn->node_page), fi) +
121 dn->ofs_in_node;
121 122
122 /* Update the page address in the parent node */ 123 /* Update the page address in the parent node */
123 __set_data_blkaddr(dn, blk_addr); 124 __set_data_blkaddr(dn, blk_addr);
@@ -448,7 +449,7 @@ static int get_data_block_ro(struct inode *inode, sector_t iblock,
448 unsigned int end_offset; 449 unsigned int end_offset;
449 450
450 end_offset = IS_INODE(dn.node_page) ? 451 end_offset = IS_INODE(dn.node_page) ?
451 ADDRS_PER_INODE : 452 ADDRS_PER_INODE(F2FS_I(inode)) :
452 ADDRS_PER_BLOCK; 453 ADDRS_PER_BLOCK;
453 454
454 clear_buffer_new(bh_result); 455 clear_buffer_new(bh_result);
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index b82f14199921..0343759ceb4c 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -301,15 +301,6 @@ struct f2fs_sm_info {
301}; 301};
302 302
303/* 303/*
304 * For directory operation
305 */
306#define NODE_DIR1_BLOCK (ADDRS_PER_INODE + 1)
307#define NODE_DIR2_BLOCK (ADDRS_PER_INODE + 2)
308#define NODE_IND1_BLOCK (ADDRS_PER_INODE + 3)
309#define NODE_IND2_BLOCK (ADDRS_PER_INODE + 4)
310#define NODE_DIND_BLOCK (ADDRS_PER_INODE + 5)
311
312/*
313 * For superblock 304 * For superblock
314 */ 305 */
315/* 306/*
@@ -942,6 +933,13 @@ static inline void set_raw_inline(struct f2fs_inode_info *fi,
942 ri->i_inline |= F2FS_INLINE_XATTR; 933 ri->i_inline |= F2FS_INLINE_XATTR;
943} 934}
944 935
936static inline unsigned int addrs_per_inode(struct f2fs_inode_info *fi)
937{
938 if (is_inode_flag_set(fi, FI_INLINE_XATTR))
939 return DEF_ADDRS_PER_INODE - F2FS_INLINE_XATTR_ADDRS;
940 return DEF_ADDRS_PER_INODE;
941}
942
945static inline int f2fs_readonly(struct super_block *sb) 943static inline int f2fs_readonly(struct super_block *sb)
946{ 944{
947 return sb->s_flags & MS_RDONLY; 945 return sb->s_flags & MS_RDONLY;
@@ -1108,7 +1106,7 @@ int do_write_data_page(struct page *);
1108 */ 1106 */
1109int start_gc_thread(struct f2fs_sb_info *); 1107int start_gc_thread(struct f2fs_sb_info *);
1110void stop_gc_thread(struct f2fs_sb_info *); 1108void stop_gc_thread(struct f2fs_sb_info *);
1111block_t start_bidx_of_node(unsigned int); 1109block_t start_bidx_of_node(unsigned int, struct f2fs_inode_info *);
1112int f2fs_gc(struct f2fs_sb_info *); 1110int f2fs_gc(struct f2fs_sb_info *);
1113void build_gc_manager(struct f2fs_sb_info *); 1111void build_gc_manager(struct f2fs_sb_info *);
1114int __init create_gc_caches(void); 1112int __init create_gc_caches(void);
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index bd4184e35525..02c906971cc6 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -290,7 +290,7 @@ static int truncate_blocks(struct inode *inode, u64 from)
290 } 290 }
291 291
292 if (IS_INODE(dn.node_page)) 292 if (IS_INODE(dn.node_page))
293 count = ADDRS_PER_INODE; 293 count = ADDRS_PER_INODE(F2FS_I(inode));
294 else 294 else
295 count = ADDRS_PER_BLOCK; 295 count = ADDRS_PER_BLOCK;
296 296
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index e6b3ffd5ff6a..eb89037e3312 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -461,7 +461,7 @@ next_step:
461 * as indirect or double indirect node blocks, are given, it must be a caller's 461 * as indirect or double indirect node blocks, are given, it must be a caller's
462 * bug. 462 * bug.
463 */ 463 */
464block_t start_bidx_of_node(unsigned int node_ofs) 464block_t start_bidx_of_node(unsigned int node_ofs, struct f2fs_inode_info *fi)
465{ 465{
466 unsigned int indirect_blks = 2 * NIDS_PER_BLOCK + 4; 466 unsigned int indirect_blks = 2 * NIDS_PER_BLOCK + 4;
467 unsigned int bidx; 467 unsigned int bidx;
@@ -478,7 +478,7 @@ block_t start_bidx_of_node(unsigned int node_ofs)
478 int dec = (node_ofs - indirect_blks - 3) / (NIDS_PER_BLOCK + 1); 478 int dec = (node_ofs - indirect_blks - 3) / (NIDS_PER_BLOCK + 1);
479 bidx = node_ofs - 5 - dec; 479 bidx = node_ofs - 5 - dec;
480 } 480 }
481 return bidx * ADDRS_PER_BLOCK + ADDRS_PER_INODE; 481 return bidx * ADDRS_PER_BLOCK + ADDRS_PER_INODE(fi);
482} 482}
483 483
484static int check_dnode(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, 484static int check_dnode(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
@@ -586,7 +586,6 @@ next_step:
586 continue; 586 continue;
587 } 587 }
588 588
589 start_bidx = start_bidx_of_node(nofs);
590 ofs_in_node = le16_to_cpu(entry->ofs_in_node); 589 ofs_in_node = le16_to_cpu(entry->ofs_in_node);
591 590
592 if (phase == 2) { 591 if (phase == 2) {
@@ -594,6 +593,8 @@ next_step:
594 if (IS_ERR(inode)) 593 if (IS_ERR(inode))
595 continue; 594 continue;
596 595
596 start_bidx = start_bidx_of_node(nofs, F2FS_I(inode));
597
597 data_page = find_data_page(inode, 598 data_page = find_data_page(inode,
598 start_bidx + ofs_in_node, false); 599 start_bidx + ofs_in_node, false);
599 if (IS_ERR(data_page)) 600 if (IS_ERR(data_page))
@@ -604,6 +605,8 @@ next_step:
604 } else { 605 } else {
605 inode = find_gc_inode(dni.ino, ilist); 606 inode = find_gc_inode(dni.ino, ilist);
606 if (inode) { 607 if (inode) {
608 start_bidx = start_bidx_of_node(nofs,
609 F2FS_I(inode));
607 data_page = get_lock_data_page(inode, 610 data_page = get_lock_data_page(inode,
608 start_bidx + ofs_in_node); 611 start_bidx + ofs_in_node);
609 if (IS_ERR(data_page)) 612 if (IS_ERR(data_page))
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 818ff368de81..f0e733b21b2a 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -315,9 +315,10 @@ cache:
315 * The maximum depth is four. 315 * The maximum depth is four.
316 * Offset[0] will have raw inode offset. 316 * Offset[0] will have raw inode offset.
317 */ 317 */
318static int get_node_path(long block, int offset[4], unsigned int noffset[4]) 318static int get_node_path(struct f2fs_inode_info *fi, long block,
319 int offset[4], unsigned int noffset[4])
319{ 320{
320 const long direct_index = ADDRS_PER_INODE; 321 const long direct_index = ADDRS_PER_INODE(fi);
321 const long direct_blks = ADDRS_PER_BLOCK; 322 const long direct_blks = ADDRS_PER_BLOCK;
322 const long dptrs_per_blk = NIDS_PER_BLOCK; 323 const long dptrs_per_blk = NIDS_PER_BLOCK;
323 const long indirect_blks = ADDRS_PER_BLOCK * NIDS_PER_BLOCK; 324 const long indirect_blks = ADDRS_PER_BLOCK * NIDS_PER_BLOCK;
@@ -405,7 +406,7 @@ int get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode)
405 int level, i; 406 int level, i;
406 int err = 0; 407 int err = 0;
407 408
408 level = get_node_path(index, offset, noffset); 409 level = get_node_path(F2FS_I(dn->inode), index, offset, noffset);
409 410
410 nids[0] = dn->inode->i_ino; 411 nids[0] = dn->inode->i_ino;
411 npage[0] = dn->inode_page; 412 npage[0] = dn->inode_page;
@@ -687,7 +688,7 @@ int truncate_inode_blocks(struct inode *inode, pgoff_t from)
687 688
688 trace_f2fs_truncate_inode_blocks_enter(inode, from); 689 trace_f2fs_truncate_inode_blocks_enter(inode, from);
689 690
690 level = get_node_path(from, offset, noffset); 691 level = get_node_path(F2FS_I(inode), from, offset, noffset);
691restart: 692restart:
692 page = get_node_page(sbi, inode->i_ino); 693 page = get_node_page(sbi, inode->i_ino);
693 if (IS_ERR(page)) { 694 if (IS_ERR(page)) {
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index fa493bb64167..51ef5eec33d7 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -213,6 +213,7 @@ static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
213 void *kaddr; 213 void *kaddr;
214 struct inode *inode; 214 struct inode *inode;
215 struct page *node_page; 215 struct page *node_page;
216 unsigned int offset;
216 block_t bidx; 217 block_t bidx;
217 int i; 218 int i;
218 219
@@ -257,8 +258,8 @@ static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
257 node_page = get_node_page(sbi, nid); 258 node_page = get_node_page(sbi, nid);
258 if (IS_ERR(node_page)) 259 if (IS_ERR(node_page))
259 return PTR_ERR(node_page); 260 return PTR_ERR(node_page);
260 bidx = start_bidx_of_node(ofs_of_node(node_page)) + 261
261 le16_to_cpu(sum.ofs_in_node); 262 offset = ofs_of_node(node_page);
262 ino = ino_of_node(node_page); 263 ino = ino_of_node(node_page);
263 f2fs_put_page(node_page, 1); 264 f2fs_put_page(node_page, 1);
264 265
@@ -267,6 +268,9 @@ static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
267 if (IS_ERR(inode)) 268 if (IS_ERR(inode))
268 return PTR_ERR(inode); 269 return PTR_ERR(inode);
269 270
271 bidx = start_bidx_of_node(offset, F2FS_I(inode)) +
272 le16_to_cpu(sum.ofs_in_node);
273
270 truncate_hole(inode, bidx, bidx + 1); 274 truncate_hole(inode, bidx, bidx + 1);
271 iput(inode); 275 iput(inode);
272 return 0; 276 return 0;
@@ -275,6 +279,7 @@ static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
275static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode, 279static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
276 struct page *page, block_t blkaddr) 280 struct page *page, block_t blkaddr)
277{ 281{
282 struct f2fs_inode_info *fi = F2FS_I(inode);
278 unsigned int start, end; 283 unsigned int start, end;
279 struct dnode_of_data dn; 284 struct dnode_of_data dn;
280 struct f2fs_summary sum; 285 struct f2fs_summary sum;
@@ -282,9 +287,9 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
282 int err = 0, recovered = 0; 287 int err = 0, recovered = 0;
283 int ilock; 288 int ilock;
284 289
285 start = start_bidx_of_node(ofs_of_node(page)); 290 start = start_bidx_of_node(ofs_of_node(page), fi);
286 if (IS_INODE(page)) 291 if (IS_INODE(page))
287 end = start + ADDRS_PER_INODE; 292 end = start + ADDRS_PER_INODE(fi);
288 else 293 else
289 end = start + ADDRS_PER_BLOCK; 294 end = start + ADDRS_PER_BLOCK;
290 295
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 70ecf484e7e5..13d0a0fe49dd 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -618,7 +618,7 @@ static const struct export_operations f2fs_export_ops = {
618 618
619static loff_t max_file_size(unsigned bits) 619static loff_t max_file_size(unsigned bits)
620{ 620{
621 loff_t result = ADDRS_PER_INODE; 621 loff_t result = (DEF_ADDRS_PER_INODE - F2FS_INLINE_XATTR_ADDRS);
622 loff_t leaf_count = ADDRS_PER_BLOCK; 622 loff_t leaf_count = ADDRS_PER_BLOCK;
623 623
624 /* two direct node blocks */ 624 /* two direct node blocks */
diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
index 10ab11f8f99d..93e7020fb7a8 100644
--- a/include/linux/f2fs_fs.h
+++ b/include/linux/f2fs_fs.h
@@ -140,9 +140,17 @@ struct f2fs_extent {
140} __packed; 140} __packed;
141 141
142#define F2FS_NAME_LEN 255 142#define F2FS_NAME_LEN 255
143#define ADDRS_PER_INODE 923 /* Address Pointers in an Inode */ 143#define F2FS_INLINE_XATTR_ADDRS 0 /* 0 bytes for inline xattrs */
144#define ADDRS_PER_BLOCK 1018 /* Address Pointers in a Direct Block */ 144#define DEF_ADDRS_PER_INODE 923 /* Address Pointers in an Inode */
145#define NIDS_PER_BLOCK 1018 /* Node IDs in an Indirect Block */ 145#define ADDRS_PER_INODE(fi) addrs_per_inode(fi)
146#define ADDRS_PER_BLOCK 1018 /* Address Pointers in a Direct Block */
147#define NIDS_PER_BLOCK 1018 /* Node IDs in an Indirect Block */
148
149#define NODE_DIR1_BLOCK (DEF_ADDRS_PER_INODE + 1)
150#define NODE_DIR2_BLOCK (DEF_ADDRS_PER_INODE + 2)
151#define NODE_IND1_BLOCK (DEF_ADDRS_PER_INODE + 3)
152#define NODE_IND2_BLOCK (DEF_ADDRS_PER_INODE + 4)
153#define NODE_DIND_BLOCK (DEF_ADDRS_PER_INODE + 5)
146 154
147#define F2FS_INLINE_XATTR 0x01 /* file inline xattr flag */ 155#define F2FS_INLINE_XATTR 0x01 /* file inline xattr flag */
148 156
@@ -172,7 +180,7 @@ struct f2fs_inode {
172 180
173 struct f2fs_extent i_ext; /* caching a largest extent */ 181 struct f2fs_extent i_ext; /* caching a largest extent */
174 182
175 __le32 i_addr[ADDRS_PER_INODE]; /* Pointers to data blocks */ 183 __le32 i_addr[DEF_ADDRS_PER_INODE]; /* Pointers to data blocks */
176 184
177 __le32 i_nid[5]; /* direct(2), indirect(2), 185 __le32 i_nid[5]; /* direct(2), indirect(2),
178 double_indirect(1) node id */ 186 double_indirect(1) node id */