Home | History | Annotate | Download | only in fsck
      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