1 /**
2 * node.h
3 *
4 * Many parts of codes are copied from Linux kernel/fs/f2fs.
5 *
6 * Copyright (C) 2015 Huawei Ltd.
7 * Witten by:
8 * Hou Pengyang <houpengyang@huawei.com>
9 * Liu Shuoran <liushuoran@huawei.com>
10 * Jaegeuk Kim <jaegeuk@kernel.org>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16 #ifndef _NODE_H_
17 #define _NODE_H_
18
19 #include "fsck.h"
20
21 #define ADDRS_PER_PAGE(page) \
22 (IS_INODE(page) ? ADDRS_PER_INODE(&page->i) : ADDRS_PER_BLOCK)
23
IS_INODE(struct f2fs_node * node)24 static inline int IS_INODE(struct f2fs_node *node)
25 {
26 return ((node)->footer.nid == (node)->footer.ino);
27 }
28
blkaddr_in_node(struct f2fs_node * node)29 static inline __le32 *blkaddr_in_node(struct f2fs_node *node)
30 {
31 return IS_INODE(node) ? node->i.i_addr : node->dn.addr;
32 }
33
datablock_addr(struct f2fs_node * node_page,unsigned int offset)34 static inline block_t datablock_addr(struct f2fs_node *node_page,
35 unsigned int offset)
36 {
37 __le32 *addr_array;
38
39 ASSERT(node_page);
40 addr_array = blkaddr_in_node(node_page);
41 return le32_to_cpu(addr_array[offset]);
42 }
43
set_nid(struct f2fs_node * rn,int off,nid_t nid,int i)44 static inline void set_nid(struct f2fs_node * rn, int off, nid_t nid, int i)
45 {
46 if (i)
47 rn->i.i_nid[off - NODE_DIR1_BLOCK] = cpu_to_le32(nid);
48 else
49 rn->in.nid[off] = cpu_to_le32(nid);
50 }
51
get_nid(struct f2fs_node * rn,int off,int i)52 static inline nid_t get_nid(struct f2fs_node * rn, int off, int i)
53 {
54 if (i)
55 return le32_to_cpu(rn->i.i_nid[off - NODE_DIR1_BLOCK]);
56 else
57 return le32_to_cpu(rn->in.nid[off]);
58 }
59
60 enum {
61 ALLOC_NODE, /* allocate a new node page if needed */
62 LOOKUP_NODE, /* lookup up a node without readahead */
63 LOOKUP_NODE_RA,
64 };
65
set_new_dnode(struct dnode_of_data * dn,struct f2fs_node * iblk,struct f2fs_node * nblk,nid_t nid)66 static inline void set_new_dnode(struct dnode_of_data *dn,
67 struct f2fs_node *iblk, struct f2fs_node *nblk, nid_t nid)
68 {
69 memset(dn, 0, sizeof(*dn));
70 dn->inode_blk = iblk;
71 dn->node_blk = nblk;
72 dn->nid = nid;
73 dn->idirty = 0;
74 dn->ndirty = 0;
75 }
76
inc_inode_blocks(struct dnode_of_data * dn)77 static inline void inc_inode_blocks(struct dnode_of_data *dn)
78 {
79 u64 blocks = le64_to_cpu(dn->inode_blk->i.i_blocks);
80
81 dn->inode_blk->i.i_blocks = cpu_to_le64(blocks + 1);
82 dn->idirty = 1;
83 }
84
IS_DNODE(struct f2fs_node * node_page)85 static inline int IS_DNODE(struct f2fs_node *node_page)
86 {
87 unsigned int ofs = ofs_of_node(node_page);
88
89 if (ofs == 3 || ofs == 4 + NIDS_PER_BLOCK ||
90 ofs == 5 + 2 * NIDS_PER_BLOCK)
91 return 0;
92
93 if (ofs >= 6 + 2 * NIDS_PER_BLOCK) {
94 ofs -= 6 + 2 * NIDS_PER_BLOCK;
95 if (!((long int)ofs % (NIDS_PER_BLOCK + 1)))
96 return 0;
97 }
98 return 1;
99 }
100
101 #endif
102