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 (at) huawei.com> 9 * Liu Shuoran <liushuoran (at) huawei.com> 10 * Jaegeuk Kim <jaegeuk (at) 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 24 static inline int IS_INODE(struct f2fs_node *node) 25 { 26 return ((node)->footer.nid == (node)->footer.ino); 27 } 28 29 static inline __le32 *blkaddr_in_inode(struct f2fs_node *node) 30 { 31 return node->i.i_addr + get_extra_isize(node); 32 } 33 34 static inline __le32 *blkaddr_in_node(struct f2fs_node *node) 35 { 36 return IS_INODE(node) ? blkaddr_in_inode(node) : node->dn.addr; 37 } 38 39 static inline block_t datablock_addr(struct f2fs_node *node_page, 40 unsigned int offset) 41 { 42 __le32 *addr_array; 43 44 ASSERT(node_page); 45 addr_array = blkaddr_in_node(node_page); 46 return le32_to_cpu(addr_array[offset]); 47 } 48 49 static inline void set_nid(struct f2fs_node * rn, int off, nid_t nid, int i) 50 { 51 if (i) 52 rn->i.i_nid[off - NODE_DIR1_BLOCK] = cpu_to_le32(nid); 53 else 54 rn->in.nid[off] = cpu_to_le32(nid); 55 } 56 57 static inline nid_t get_nid(struct f2fs_node * rn, int off, int i) 58 { 59 if (i) 60 return le32_to_cpu(rn->i.i_nid[off - NODE_DIR1_BLOCK]); 61 else 62 return le32_to_cpu(rn->in.nid[off]); 63 } 64 65 enum { 66 ALLOC_NODE, /* allocate a new node page if needed */ 67 LOOKUP_NODE, /* lookup up a node without readahead */ 68 LOOKUP_NODE_RA, 69 }; 70 71 static inline void set_new_dnode(struct dnode_of_data *dn, 72 struct f2fs_node *iblk, struct f2fs_node *nblk, nid_t nid) 73 { 74 memset(dn, 0, sizeof(*dn)); 75 dn->inode_blk = iblk; 76 dn->node_blk = nblk; 77 dn->nid = nid; 78 dn->idirty = 0; 79 dn->ndirty = 0; 80 } 81 82 static inline void inc_inode_blocks(struct dnode_of_data *dn) 83 { 84 u64 blocks = le64_to_cpu(dn->inode_blk->i.i_blocks); 85 86 dn->inode_blk->i.i_blocks = cpu_to_le64(blocks + 1); 87 dn->idirty = 1; 88 } 89 90 static inline int IS_DNODE(struct f2fs_node *node_page) 91 { 92 unsigned int ofs = ofs_of_node(node_page); 93 94 if (ofs == 3 || ofs == 4 + NIDS_PER_BLOCK || 95 ofs == 5 + 2 * NIDS_PER_BLOCK) 96 return 0; 97 98 if (ofs >= 6 + 2 * NIDS_PER_BLOCK) { 99 ofs -= 6 + 2 * NIDS_PER_BLOCK; 100 if (!((long int)ofs % (NIDS_PER_BLOCK + 1))) 101 return 0; 102 } 103 return 1; 104 } 105 106 #endif 107