/*
* fs/f2fs/f2fs.h
*
* Copyright (c) 2012 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef _LINUX_F2FS_H
#define _LINUX_F2FS_H
#include <linux/types.h>
#include <linux/page-flags.h>
#include <linux/buffer_head.h>
#include <linux/slab.h>
#include <linux/crc32.h>
#include <linux/magic.h>
/*
* For mount options
*/
#define F2FS_MOUNT_BG_GC 0x00000001
#define F2FS_MOUNT_DISABLE_ROLL_FORWARD 0x00000002
#define F2FS_MOUNT_DISCARD 0x00000004
#define F2FS_MOUNT_NOHEAP 0x00000008
#define F2FS_MOUNT_XATTR_USER 0x00000010
#define F2FS_MOUNT_POSIX_ACL 0x00000020
#define F2FS_MOUNT_DISABLE_EXT_IDENTIFY 0x00000040
#define clear_opt(sbi, option) (sbi->mount_opt.opt &= ~F2FS_MOUNT_##option)
#define set_opt(sbi, option) (sbi->mount_opt.opt |= F2FS_MOUNT_##option)
#define test_opt(sbi, option) (sbi->mount_opt.opt & F2FS_MOUNT_##option)
#define ver_after(a, b) (typecheck(unsigned long long, a) && \
typecheck(unsigned long long, b) && \
((long long)((a) - (b)) > 0))
typedef u64 block_t;
typedef u32 nid_t;
struct f2fs_mount_info {
unsigned int opt;
};
static inline __u32 f2fs_crc32(void *buff, size_t len)
{
return crc32_le(F2FS_SUPER_MAGIC, buff, len);
}
static inline bool f2fs_crc_valid(__u32 blk_crc, void *buff, size_t buff_size)
{
return f2fs_crc32(buff, buff_size) == blk_crc;
}
/*
* For checkpoint manager
*/
enum {
NAT_BITMAP,
SIT_BITMAP
};
/* for the list of orphan inodes */
struct orphan_inode_entry {
struct list_head list; /* list head */
nid_t ino; /* inode number */
};
/* for the list of directory inodes */
struct dir_inode_entry {
struct list_head list; /* list head */
struct inode *inode; /* vfs inode pointer */
};
/* for the list of fsync inodes, used only during recovery */
struct fsync_inode_entry {
struct list_head list; /* list head */
struct inode *inode; /* vfs inode pointer */
block_t blkaddr; /* block address locating the last inode */
};
#define nats_in_cursum(sum) (le16_to_cpu(sum->n_nats))
#define sits_in_cursum(sum) (le16_to_cpu(sum->n_sits))
#define nat_in_journal(sum, i) (sum->nat_j.entries[i].ne)
#define nid_in_journal(sum, i) (sum->nat_j.entries[i].nid)
#define sit_in_journal(sum, i) (sum->sit_j.entries[i].se)
#define segno_in_journal(sum, i) (sum->sit_j.entries[i].segno)
static inline int update_nats_in_cursum(struct f2fs_summary_block *rs, int i)
{
int before = nats_in_cursum(rs);
rs->n_nats = cpu_to_le16(before + i);
return before;
}
static inline int update_sits_in_cursum(struct f2fs_summary_block *rs, int i)
{
int before = sits_in_cursum(rs);
rs->n_sits = cpu_to_le16(before + i);
return before;
}
/*
* For INODE and NODE manager
*/
#define XATTR_NODE_OFFSET (-1) /*
* store xattrs to one node block per
* file keeping -1 as its node offset to
* distinguish from index node blocks.
*/
#define RDONLY_NODE 1 /*
* specify a read-only mode when getting
* a node block. 0 is read-write mode.
* used by get_dnode_of_data().
*/
#define F2FS_LINK_MAX 32000 /* maximum link count per file */
/* for in-memory extent cache entry */
struct extent_info {
rwlock_t ext_lock; /* rwlock for consistency */
unsigned int fofs; /* start offset in a file */
u32 blk_addr; /* start block address of the extent */
unsigned int len; /* lenth of the extent */
};
/*
* i_advise uses FADVISE_XXX_BIT. We can add additional hints later.
*/
#define FADVISE_COLD_BIT 0x01
struct f2fs_inode_info {
struct inode vfs_inode; /* serve a vfs inode */
unsigned long i_flags; /* keep an inode flags for ioctl */
unsigned char i_advise; /* use to give file attribute hints */
unsigned int i_current_depth; /* use only in directory structure */
unsigned int i_pino; /* parent inode number */
umode_t i_acl_mode; /* keep file acl mode temporarily */
/* Use below internally in f2fs*/
unsigned long flags; /* use to pass per-file flags */
unsigned long long data_version;/* latest version of data for fsync */
atomic_t dirty_dents; /* # of dirty dentry pages */
f2fs_hash_t chash; /* hash value of given file name */
unsigned int clevel; /* maximum level of given file name */
nid_t i_xattr_nid; /* node id that contains xattrs */
struct extent_info ext; /* in-memory extent cache entry */
};
static inline void get_extent_info(struct extent_info *ext,
struct f2fs_extent i_ext)
{
write_lock(&ext->ext_lock);
ext->fofs = le32_to_cpu(i_ext.fofs);
ext->blk_addr = le32_to_cpu(i_ext.blk_addr);
ext->len = le32_to_cpu(i_ext.len);
write_unlock(&ext->ext_lock);
}
static inline void set_raw_extent(struct extent_info *ext,
struct f2fs_extent *i_ext)
{
read_lock(&ext->ext_lock);
i_ext->fofs =