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_node(struct f2fs_node *node)
     30 {
     31 	return IS_INODE(node) ? node->i.i_addr : node->dn.addr;
     32 }
     33 
     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 
     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 
     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 
     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 
     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 
     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