|
@@ -19,6 +19,7 @@
|
|
|
#include <linux/magic.h>
|
|
|
#include <linux/kobject.h>
|
|
|
#include <linux/sched.h>
|
|
|
+#include <linux/cred.h>
|
|
|
#include <linux/vmalloc.h>
|
|
|
#include <linux/bio.h>
|
|
|
#include <linux/blkdev.h>
|
|
@@ -43,6 +44,7 @@
|
|
|
#ifdef CONFIG_F2FS_FAULT_INJECTION
|
|
|
enum {
|
|
|
FAULT_KMALLOC,
|
|
|
+ FAULT_KVMALLOC,
|
|
|
FAULT_PAGE_ALLOC,
|
|
|
FAULT_PAGE_GET,
|
|
|
FAULT_ALLOC_BIO,
|
|
@@ -94,6 +96,7 @@ extern char *fault_name[FAULT_MAX];
|
|
|
#define F2FS_MOUNT_PRJQUOTA 0x00200000
|
|
|
#define F2FS_MOUNT_QUOTA 0x00400000
|
|
|
#define F2FS_MOUNT_INLINE_XATTR_SIZE 0x00800000
|
|
|
+#define F2FS_MOUNT_RESERVE_ROOT 0x01000000
|
|
|
|
|
|
#define clear_opt(sbi, option) ((sbi)->mount_opt.opt &= ~F2FS_MOUNT_##option)
|
|
|
#define set_opt(sbi, option) ((sbi)->mount_opt.opt |= F2FS_MOUNT_##option)
|
|
@@ -121,6 +124,7 @@ struct f2fs_mount_info {
|
|
|
#define F2FS_FEATURE_INODE_CHKSUM 0x0020
|
|
|
#define F2FS_FEATURE_FLEXIBLE_INLINE_XATTR 0x0040
|
|
|
#define F2FS_FEATURE_QUOTA_INO 0x0080
|
|
|
+#define F2FS_FEATURE_INODE_CRTIME 0x0100
|
|
|
|
|
|
#define F2FS_HAS_FEATURE(sb, mask) \
|
|
|
((F2FS_SB(sb)->raw_super->feature & cpu_to_le32(mask)) != 0)
|
|
@@ -129,6 +133,12 @@ struct f2fs_mount_info {
|
|
|
#define F2FS_CLEAR_FEATURE(sb, mask) \
|
|
|
(F2FS_SB(sb)->raw_super->feature &= ~cpu_to_le32(mask))
|
|
|
|
|
|
+/*
|
|
|
+ * Default values for user and/or group using reserved blocks
|
|
|
+ */
|
|
|
+#define F2FS_DEF_RESUID 0
|
|
|
+#define F2FS_DEF_RESGID 0
|
|
|
+
|
|
|
/*
|
|
|
* For checkpoint manager
|
|
|
*/
|
|
@@ -179,6 +189,7 @@ enum {
|
|
|
ORPHAN_INO, /* for orphan ino list */
|
|
|
APPEND_INO, /* for append ino list */
|
|
|
UPDATE_INO, /* for update ino list */
|
|
|
+ TRANS_DIR_INO, /* for trasactions dir ino list */
|
|
|
FLUSH_INO, /* for multiple device flushing */
|
|
|
MAX_INO_ENTRY, /* max. list */
|
|
|
};
|
|
@@ -264,7 +275,6 @@ struct discard_cmd_control {
|
|
|
struct task_struct *f2fs_issue_discard; /* discard thread */
|
|
|
struct list_head entry_list; /* 4KB discard entry list */
|
|
|
struct list_head pend_list[MAX_PLIST_NUM];/* store pending entries */
|
|
|
- unsigned char pend_list_tag[MAX_PLIST_NUM];/* tag for pending entries */
|
|
|
struct list_head wait_list; /* store on-flushing entries */
|
|
|
struct list_head fstrim_list; /* in-flight discard from fstrim */
|
|
|
wait_queue_head_t discard_wait_queue; /* waiting queue for wake-up */
|
|
@@ -347,6 +357,9 @@ static inline bool __has_cursum_space(struct f2fs_journal *journal,
|
|
|
#define F2FS_IOC_GARBAGE_COLLECT_RANGE _IOW(F2FS_IOCTL_MAGIC, 11, \
|
|
|
struct f2fs_gc_range)
|
|
|
#define F2FS_IOC_GET_FEATURES _IOR(F2FS_IOCTL_MAGIC, 12, __u32)
|
|
|
+#define F2FS_IOC_SET_PIN_FILE _IOW(F2FS_IOCTL_MAGIC, 13, __u32)
|
|
|
+#define F2FS_IOC_GET_PIN_FILE _IOR(F2FS_IOCTL_MAGIC, 14, __u32)
|
|
|
+#define F2FS_IOC_PRECACHE_EXTENTS _IO(F2FS_IOCTL_MAGIC, 15)
|
|
|
|
|
|
#define F2FS_IOC_SET_ENCRYPTION_POLICY FS_IOC_SET_ENCRYPTION_POLICY
|
|
|
#define F2FS_IOC_GET_ENCRYPTION_POLICY FS_IOC_GET_ENCRYPTION_POLICY
|
|
@@ -402,10 +415,9 @@ struct f2fs_flush_device {
|
|
|
#define DEF_MIN_INLINE_SIZE 1
|
|
|
static inline int get_extra_isize(struct inode *inode);
|
|
|
static inline int get_inline_xattr_addrs(struct inode *inode);
|
|
|
-#define F2FS_INLINE_XATTR_ADDRS(inode) get_inline_xattr_addrs(inode)
|
|
|
#define MAX_INLINE_DATA(inode) (sizeof(__le32) * \
|
|
|
(CUR_ADDRS_PER_INODE(inode) - \
|
|
|
- F2FS_INLINE_XATTR_ADDRS(inode) - \
|
|
|
+ get_inline_xattr_addrs(inode) - \
|
|
|
DEF_INLINE_RESERVED_SIZE))
|
|
|
|
|
|
/* for inline dir */
|
|
@@ -542,6 +554,8 @@ struct f2fs_map_blocks {
|
|
|
unsigned int m_len;
|
|
|
unsigned int m_flags;
|
|
|
pgoff_t *m_next_pgofs; /* point next possible non-hole pgofs */
|
|
|
+ pgoff_t *m_next_extent; /* point to next possible extent */
|
|
|
+ int m_seg_type;
|
|
|
};
|
|
|
|
|
|
/* for flag in get_data_block */
|
|
@@ -551,6 +565,7 @@ enum {
|
|
|
F2FS_GET_BLOCK_BMAP,
|
|
|
F2FS_GET_BLOCK_PRE_DIO,
|
|
|
F2FS_GET_BLOCK_PRE_AIO,
|
|
|
+ F2FS_GET_BLOCK_PRECACHE,
|
|
|
};
|
|
|
|
|
|
/*
|
|
@@ -583,7 +598,10 @@ struct f2fs_inode_info {
|
|
|
unsigned long i_flags; /* keep an inode flags for ioctl */
|
|
|
unsigned char i_advise; /* use to give file attribute hints */
|
|
|
unsigned char i_dir_level; /* use for dentry level for large dir */
|
|
|
- unsigned int i_current_depth; /* use only in directory structure */
|
|
|
+ union {
|
|
|
+ unsigned int i_current_depth; /* only for directory depth */
|
|
|
+ unsigned short i_gc_failures; /* only for regular file */
|
|
|
+ };
|
|
|
unsigned int i_pino; /* parent inode number */
|
|
|
umode_t i_acl_mode; /* keep file acl mode temporarily */
|
|
|
|
|
@@ -618,6 +636,7 @@ struct f2fs_inode_info {
|
|
|
int i_extra_isize; /* size of extra space located in i_addr */
|
|
|
kprojid_t i_projid; /* id for project quota */
|
|
|
int i_inline_xattr_size; /* inline xattr size */
|
|
|
+ struct timespec i_crtime; /* inode creation time */
|
|
|
};
|
|
|
|
|
|
static inline void get_extent_info(struct extent_info *ext,
|
|
@@ -922,6 +941,7 @@ enum cp_reason_type {
|
|
|
CP_NODE_NEED_CP,
|
|
|
CP_FASTBOOT_MODE,
|
|
|
CP_SPEC_LOG_NUM,
|
|
|
+ CP_RECOVER_DIR,
|
|
|
};
|
|
|
|
|
|
enum iostat_type {
|
|
@@ -957,6 +977,7 @@ struct f2fs_io_info {
|
|
|
int need_lock; /* indicate we need to lock cp_rwsem */
|
|
|
bool in_list; /* indicate fio is in io_list */
|
|
|
enum iostat_type io_type; /* io type */
|
|
|
+ struct writeback_control *io_wbc; /* writeback control */
|
|
|
};
|
|
|
|
|
|
#define is_read_io(rw) ((rw) == READ)
|
|
@@ -1093,6 +1114,7 @@ struct f2fs_sb_info {
|
|
|
int dir_level; /* directory level */
|
|
|
int inline_xattr_size; /* inline xattr size */
|
|
|
unsigned int trigger_ssr_threshold; /* threshold to trigger ssr */
|
|
|
+ int readdir_ra; /* readahead inode in readdir */
|
|
|
|
|
|
block_t user_block_count; /* # of user blocks */
|
|
|
block_t total_valid_block_count; /* # of valid blocks */
|
|
@@ -1100,6 +1122,11 @@ struct f2fs_sb_info {
|
|
|
block_t last_valid_block_count; /* for recovery */
|
|
|
block_t reserved_blocks; /* configurable reserved blocks */
|
|
|
block_t current_reserved_blocks; /* current reserved blocks */
|
|
|
+ block_t root_reserved_blocks; /* root reserved blocks */
|
|
|
+ kuid_t s_resuid; /* reserved blocks for uid */
|
|
|
+ kgid_t s_resgid; /* reserved blocks for gid */
|
|
|
+
|
|
|
+ unsigned int nquota_files; /* # of quota sysfile */
|
|
|
|
|
|
u32 s_next_generation; /* for NFS support */
|
|
|
|
|
@@ -1124,6 +1151,9 @@ struct f2fs_sb_info {
|
|
|
/* threshold for converting bg victims for fg */
|
|
|
u64 fggc_threshold;
|
|
|
|
|
|
+ /* threshold for gc trials on pinned files */
|
|
|
+ u64 gc_pin_file_threshold;
|
|
|
+
|
|
|
/* maximum # of trials to find a victim segment for SSR and GC */
|
|
|
unsigned int max_victim_search;
|
|
|
|
|
@@ -1250,33 +1280,7 @@ static inline bool is_idle(struct f2fs_sb_info *sbi)
|
|
|
/*
|
|
|
* Inline functions
|
|
|
*/
|
|
|
-static inline u32 f2fs_crc32(struct f2fs_sb_info *sbi, const void *address,
|
|
|
- unsigned int length)
|
|
|
-{
|
|
|
- SHASH_DESC_ON_STACK(shash, sbi->s_chksum_driver);
|
|
|
- u32 *ctx = (u32 *)shash_desc_ctx(shash);
|
|
|
- u32 retval;
|
|
|
- int err;
|
|
|
-
|
|
|
- shash->tfm = sbi->s_chksum_driver;
|
|
|
- shash->flags = 0;
|
|
|
- *ctx = F2FS_SUPER_MAGIC;
|
|
|
-
|
|
|
- err = crypto_shash_update(shash, address, length);
|
|
|
- BUG_ON(err);
|
|
|
-
|
|
|
- retval = *ctx;
|
|
|
- barrier_data(ctx);
|
|
|
- return retval;
|
|
|
-}
|
|
|
-
|
|
|
-static inline bool f2fs_crc_valid(struct f2fs_sb_info *sbi, __u32 blk_crc,
|
|
|
- void *buf, size_t buf_size)
|
|
|
-{
|
|
|
- return f2fs_crc32(sbi, buf, buf_size) == blk_crc;
|
|
|
-}
|
|
|
-
|
|
|
-static inline u32 f2fs_chksum(struct f2fs_sb_info *sbi, u32 crc,
|
|
|
+static inline u32 __f2fs_crc32(struct f2fs_sb_info *sbi, u32 crc,
|
|
|
const void *address, unsigned int length)
|
|
|
{
|
|
|
struct {
|
|
@@ -1297,6 +1301,24 @@ static inline u32 f2fs_chksum(struct f2fs_sb_info *sbi, u32 crc,
|
|
|
return *(u32 *)desc.ctx;
|
|
|
}
|
|
|
|
|
|
+static inline u32 f2fs_crc32(struct f2fs_sb_info *sbi, const void *address,
|
|
|
+ unsigned int length)
|
|
|
+{
|
|
|
+ return __f2fs_crc32(sbi, F2FS_SUPER_MAGIC, address, length);
|
|
|
+}
|
|
|
+
|
|
|
+static inline bool f2fs_crc_valid(struct f2fs_sb_info *sbi, __u32 blk_crc,
|
|
|
+ void *buf, size_t buf_size)
|
|
|
+{
|
|
|
+ return f2fs_crc32(sbi, buf, buf_size) == blk_crc;
|
|
|
+}
|
|
|
+
|
|
|
+static inline u32 f2fs_chksum(struct f2fs_sb_info *sbi, u32 crc,
|
|
|
+ const void *address, unsigned int length)
|
|
|
+{
|
|
|
+ return __f2fs_crc32(sbi, crc, address, length);
|
|
|
+}
|
|
|
+
|
|
|
static inline struct f2fs_inode_info *F2FS_I(struct inode *inode)
|
|
|
{
|
|
|
return container_of(inode, struct f2fs_inode_info, vfs_inode);
|
|
@@ -1555,6 +1577,25 @@ static inline bool f2fs_has_xattr_block(unsigned int ofs)
|
|
|
return ofs == XATTR_NODE_OFFSET;
|
|
|
}
|
|
|
|
|
|
+static inline bool __allow_reserved_blocks(struct f2fs_sb_info *sbi,
|
|
|
+ struct inode *inode)
|
|
|
+{
|
|
|
+ if (!inode)
|
|
|
+ return true;
|
|
|
+ if (!test_opt(sbi, RESERVE_ROOT))
|
|
|
+ return false;
|
|
|
+ if (IS_NOQUOTA(inode))
|
|
|
+ return true;
|
|
|
+ if (capable(CAP_SYS_RESOURCE))
|
|
|
+ return true;
|
|
|
+ if (uid_eq(sbi->s_resuid, current_fsuid()))
|
|
|
+ return true;
|
|
|
+ if (!gid_eq(sbi->s_resgid, GLOBAL_ROOT_GID) &&
|
|
|
+ in_group_p(sbi->s_resgid))
|
|
|
+ return true;
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
static inline void f2fs_i_blocks_write(struct inode *, block_t, bool, bool);
|
|
|
static inline int inc_valid_block_count(struct f2fs_sb_info *sbi,
|
|
|
struct inode *inode, blkcnt_t *count)
|
|
@@ -1584,11 +1625,17 @@ static inline int inc_valid_block_count(struct f2fs_sb_info *sbi,
|
|
|
sbi->total_valid_block_count += (block_t)(*count);
|
|
|
avail_user_block_count = sbi->user_block_count -
|
|
|
sbi->current_reserved_blocks;
|
|
|
+
|
|
|
+ if (!__allow_reserved_blocks(sbi, inode))
|
|
|
+ avail_user_block_count -= sbi->root_reserved_blocks;
|
|
|
+
|
|
|
if (unlikely(sbi->total_valid_block_count > avail_user_block_count)) {
|
|
|
diff = sbi->total_valid_block_count - avail_user_block_count;
|
|
|
+ if (diff > *count)
|
|
|
+ diff = *count;
|
|
|
*count -= diff;
|
|
|
release = diff;
|
|
|
- sbi->total_valid_block_count = avail_user_block_count;
|
|
|
+ sbi->total_valid_block_count -= diff;
|
|
|
if (!*count) {
|
|
|
spin_unlock(&sbi->stat_lock);
|
|
|
percpu_counter_sub(&sbi->alloc_valid_block_count, diff);
|
|
@@ -1597,7 +1644,7 @@ static inline int inc_valid_block_count(struct f2fs_sb_info *sbi,
|
|
|
}
|
|
|
spin_unlock(&sbi->stat_lock);
|
|
|
|
|
|
- if (release)
|
|
|
+ if (unlikely(release))
|
|
|
dquot_release_reservation_block(inode, release);
|
|
|
f2fs_i_blocks_write(inode, *count, true, true);
|
|
|
return 0;
|
|
@@ -1777,9 +1824,13 @@ static inline int inc_valid_node_count(struct f2fs_sb_info *sbi,
|
|
|
|
|
|
spin_lock(&sbi->stat_lock);
|
|
|
|
|
|
- valid_block_count = sbi->total_valid_block_count + 1;
|
|
|
- if (unlikely(valid_block_count + sbi->current_reserved_blocks >
|
|
|
- sbi->user_block_count)) {
|
|
|
+ valid_block_count = sbi->total_valid_block_count +
|
|
|
+ sbi->current_reserved_blocks + 1;
|
|
|
+
|
|
|
+ if (!__allow_reserved_blocks(sbi, inode))
|
|
|
+ valid_block_count += sbi->root_reserved_blocks;
|
|
|
+
|
|
|
+ if (unlikely(valid_block_count > sbi->user_block_count)) {
|
|
|
spin_unlock(&sbi->stat_lock);
|
|
|
goto enospc;
|
|
|
}
|
|
@@ -1992,11 +2043,11 @@ static inline block_t datablock_addr(struct inode *inode,
|
|
|
raw_node = F2FS_NODE(node_page);
|
|
|
|
|
|
/* from GC path only */
|
|
|
- if (!inode) {
|
|
|
- if (is_inode)
|
|
|
+ if (is_inode) {
|
|
|
+ if (!inode)
|
|
|
base = offset_in_addr(&raw_node->i);
|
|
|
- } else if (f2fs_has_extra_attr(inode) && is_inode) {
|
|
|
- base = get_extra_isize(inode);
|
|
|
+ else if (f2fs_has_extra_attr(inode))
|
|
|
+ base = get_extra_isize(inode);
|
|
|
}
|
|
|
|
|
|
addr_array = blkaddr_in_node(raw_node);
|
|
@@ -2107,6 +2158,7 @@ enum {
|
|
|
FI_HOT_DATA, /* indicate file is hot */
|
|
|
FI_EXTRA_ATTR, /* indicate file has extra attribute */
|
|
|
FI_PROJ_INHERIT, /* indicate file inherits projectid */
|
|
|
+ FI_PIN_FILE, /* indicate file should not be gced */
|
|
|
};
|
|
|
|
|
|
static inline void __mark_inode_dirty_flag(struct inode *inode,
|
|
@@ -2116,10 +2168,12 @@ static inline void __mark_inode_dirty_flag(struct inode *inode,
|
|
|
case FI_INLINE_XATTR:
|
|
|
case FI_INLINE_DATA:
|
|
|
case FI_INLINE_DENTRY:
|
|
|
+ case FI_NEW_INODE:
|
|
|
if (set)
|
|
|
return;
|
|
|
case FI_DATA_EXIST:
|
|
|
case FI_INLINE_DOTS:
|
|
|
+ case FI_PIN_FILE:
|
|
|
f2fs_mark_inode_dirty_sync(inode, true);
|
|
|
}
|
|
|
}
|
|
@@ -2200,6 +2254,13 @@ static inline void f2fs_i_depth_write(struct inode *inode, unsigned int depth)
|
|
|
f2fs_mark_inode_dirty_sync(inode, true);
|
|
|
}
|
|
|
|
|
|
+static inline void f2fs_i_gc_failures_write(struct inode *inode,
|
|
|
+ unsigned int count)
|
|
|
+{
|
|
|
+ F2FS_I(inode)->i_gc_failures = count;
|
|
|
+ f2fs_mark_inode_dirty_sync(inode, true);
|
|
|
+}
|
|
|
+
|
|
|
static inline void f2fs_i_xnid_write(struct inode *inode, nid_t xnid)
|
|
|
{
|
|
|
F2FS_I(inode)->i_xattr_nid = xnid;
|
|
@@ -2228,6 +2289,8 @@ static inline void get_inline_info(struct inode *inode, struct f2fs_inode *ri)
|
|
|
set_bit(FI_INLINE_DOTS, &fi->flags);
|
|
|
if (ri->i_inline & F2FS_EXTRA_ATTR)
|
|
|
set_bit(FI_EXTRA_ATTR, &fi->flags);
|
|
|
+ if (ri->i_inline & F2FS_PIN_FILE)
|
|
|
+ set_bit(FI_PIN_FILE, &fi->flags);
|
|
|
}
|
|
|
|
|
|
static inline void set_raw_inline(struct inode *inode, struct f2fs_inode *ri)
|
|
@@ -2246,6 +2309,8 @@ static inline void set_raw_inline(struct inode *inode, struct f2fs_inode *ri)
|
|
|
ri->i_inline |= F2FS_INLINE_DOTS;
|
|
|
if (is_inode_flag_set(inode, FI_EXTRA_ATTR))
|
|
|
ri->i_inline |= F2FS_EXTRA_ATTR;
|
|
|
+ if (is_inode_flag_set(inode, FI_PIN_FILE))
|
|
|
+ ri->i_inline |= F2FS_PIN_FILE;
|
|
|
}
|
|
|
|
|
|
static inline int f2fs_has_extra_attr(struct inode *inode)
|
|
@@ -2260,7 +2325,7 @@ static inline int f2fs_has_inline_xattr(struct inode *inode)
|
|
|
|
|
|
static inline unsigned int addrs_per_inode(struct inode *inode)
|
|
|
{
|
|
|
- return CUR_ADDRS_PER_INODE(inode) - F2FS_INLINE_XATTR_ADDRS(inode);
|
|
|
+ return CUR_ADDRS_PER_INODE(inode) - get_inline_xattr_addrs(inode);
|
|
|
}
|
|
|
|
|
|
static inline void *inline_xattr_addr(struct inode *inode, struct page *page)
|
|
@@ -2268,7 +2333,7 @@ static inline void *inline_xattr_addr(struct inode *inode, struct page *page)
|
|
|
struct f2fs_inode *ri = F2FS_INODE(page);
|
|
|
|
|
|
return (void *)&(ri->i_addr[DEF_ADDRS_PER_INODE -
|
|
|
- F2FS_INLINE_XATTR_ADDRS(inode)]);
|
|
|
+ get_inline_xattr_addrs(inode)]);
|
|
|
}
|
|
|
|
|
|
static inline int inline_xattr_size(struct inode *inode)
|
|
@@ -2291,6 +2356,11 @@ static inline int f2fs_has_inline_dots(struct inode *inode)
|
|
|
return is_inode_flag_set(inode, FI_INLINE_DOTS);
|
|
|
}
|
|
|
|
|
|
+static inline bool f2fs_is_pinned_file(struct inode *inode)
|
|
|
+{
|
|
|
+ return is_inode_flag_set(inode, FI_PIN_FILE);
|
|
|
+}
|
|
|
+
|
|
|
static inline bool f2fs_is_atomic_file(struct inode *inode)
|
|
|
{
|
|
|
return is_inode_flag_set(inode, FI_ATOMIC_FILE);
|
|
@@ -2418,12 +2488,35 @@ static inline void *f2fs_kmalloc(struct f2fs_sb_info *sbi,
|
|
|
return kmalloc(size, flags);
|
|
|
}
|
|
|
|
|
|
+static inline void *f2fs_kzalloc(struct f2fs_sb_info *sbi,
|
|
|
+ size_t size, gfp_t flags)
|
|
|
+{
|
|
|
+ return f2fs_kmalloc(sbi, size, flags | __GFP_ZERO);
|
|
|
+}
|
|
|
+
|
|
|
+static inline void *f2fs_kvmalloc(struct f2fs_sb_info *sbi,
|
|
|
+ size_t size, gfp_t flags)
|
|
|
+{
|
|
|
+#ifdef CONFIG_F2FS_FAULT_INJECTION
|
|
|
+ if (time_to_inject(sbi, FAULT_KVMALLOC)) {
|
|
|
+ f2fs_show_injection_info(FAULT_KVMALLOC);
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ return kvmalloc(size, flags);
|
|
|
+}
|
|
|
+
|
|
|
+static inline void *f2fs_kvzalloc(struct f2fs_sb_info *sbi,
|
|
|
+ size_t size, gfp_t flags)
|
|
|
+{
|
|
|
+ return f2fs_kvmalloc(sbi, size, flags | __GFP_ZERO);
|
|
|
+}
|
|
|
+
|
|
|
static inline int get_extra_isize(struct inode *inode)
|
|
|
{
|
|
|
return F2FS_I(inode)->i_extra_isize / sizeof(__le32);
|
|
|
}
|
|
|
|
|
|
-static inline int f2fs_sb_has_flexible_inline_xattr(struct super_block *sb);
|
|
|
static inline int get_inline_xattr_addrs(struct inode *inode)
|
|
|
{
|
|
|
return F2FS_I(inode)->i_inline_xattr_size;
|
|
@@ -2479,9 +2572,11 @@ int f2fs_getattr(const struct path *path, struct kstat *stat,
|
|
|
u32 request_mask, unsigned int flags);
|
|
|
int f2fs_setattr(struct dentry *dentry, struct iattr *attr);
|
|
|
int truncate_hole(struct inode *inode, pgoff_t pg_start, pgoff_t pg_end);
|
|
|
-int truncate_data_blocks_range(struct dnode_of_data *dn, int count);
|
|
|
+void truncate_data_blocks_range(struct dnode_of_data *dn, int count);
|
|
|
+int f2fs_precache_extents(struct inode *inode);
|
|
|
long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
|
|
|
long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
|
|
|
+int f2fs_pin_file_control(struct inode *inode, bool inc);
|
|
|
|
|
|
/*
|
|
|
* inode.c
|
|
@@ -2492,8 +2587,8 @@ void f2fs_inode_chksum_set(struct f2fs_sb_info *sbi, struct page *page);
|
|
|
struct inode *f2fs_iget(struct super_block *sb, unsigned long ino);
|
|
|
struct inode *f2fs_iget_retry(struct super_block *sb, unsigned long ino);
|
|
|
int try_to_free_nats(struct f2fs_sb_info *sbi, int nr_shrink);
|
|
|
-int update_inode(struct inode *inode, struct page *node_page);
|
|
|
-int update_inode_page(struct inode *inode);
|
|
|
+void update_inode(struct inode *inode, struct page *node_page);
|
|
|
+void update_inode_page(struct inode *inode);
|
|
|
int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc);
|
|
|
void f2fs_evict_inode(struct inode *inode);
|
|
|
void handle_failed_inode(struct inode *inode);
|
|
@@ -2604,10 +2699,9 @@ void alloc_nid_done(struct f2fs_sb_info *sbi, nid_t nid);
|
|
|
void alloc_nid_failed(struct f2fs_sb_info *sbi, nid_t nid);
|
|
|
int try_to_free_nids(struct f2fs_sb_info *sbi, int nr_shrink);
|
|
|
void recover_inline_xattr(struct inode *inode, struct page *page);
|
|
|
-int recover_xattr_data(struct inode *inode, struct page *page,
|
|
|
- block_t blkaddr);
|
|
|
+int recover_xattr_data(struct inode *inode, struct page *page);
|
|
|
int recover_inode_page(struct f2fs_sb_info *sbi, struct page *page);
|
|
|
-int restore_node_summary(struct f2fs_sb_info *sbi,
|
|
|
+void restore_node_summary(struct f2fs_sb_info *sbi,
|
|
|
unsigned int segno, struct f2fs_summary_block *sum);
|
|
|
void flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc);
|
|
|
int build_node_manager(struct f2fs_sb_info *sbi);
|
|
@@ -2634,6 +2728,7 @@ void invalidate_blocks(struct f2fs_sb_info *sbi, block_t addr);
|
|
|
bool is_checkpointed_data(struct f2fs_sb_info *sbi, block_t blkaddr);
|
|
|
void init_discard_policy(struct discard_policy *dpolicy, int discard_type,
|
|
|
unsigned int granularity);
|
|
|
+void drop_discard_cmd(struct f2fs_sb_info *sbi);
|
|
|
void stop_discard_thread(struct f2fs_sb_info *sbi);
|
|
|
bool f2fs_wait_discard_bios(struct f2fs_sb_info *sbi);
|
|
|
void clear_prefree_segments(struct f2fs_sb_info *sbi, struct cp_control *cpc);
|
|
@@ -2672,6 +2767,7 @@ int build_segment_manager(struct f2fs_sb_info *sbi);
|
|
|
void destroy_segment_manager(struct f2fs_sb_info *sbi);
|
|
|
int __init create_segment_manager_caches(void);
|
|
|
void destroy_segment_manager_caches(void);
|
|
|
+int rw_hint_to_seg_type(enum rw_hint hint);
|
|
|
|
|
|
/*
|
|
|
* checkpoint.c
|
|
@@ -2741,6 +2837,8 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
|
|
|
int create, int flag);
|
|
|
int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
|
|
|
u64 start, u64 len);
|
|
|
+bool should_update_inplace(struct inode *inode, struct f2fs_io_info *fio);
|
|
|
+bool should_update_outplace(struct inode *inode, struct f2fs_io_info *fio);
|
|
|
void f2fs_set_page_dirty_nobuffers(struct page *page);
|
|
|
int __f2fs_write_data_pages(struct address_space *mapping,
|
|
|
struct writeback_control *wbc,
|
|
@@ -3109,6 +3207,11 @@ static inline int f2fs_sb_has_quota_ino(struct super_block *sb)
|
|
|
return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_QUOTA_INO);
|
|
|
}
|
|
|
|
|
|
+static inline int f2fs_sb_has_inode_crtime(struct super_block *sb)
|
|
|
+{
|
|
|
+ return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_INODE_CRTIME);
|
|
|
+}
|
|
|
+
|
|
|
#ifdef CONFIG_BLK_DEV_ZONED
|
|
|
static inline int get_blkz_type(struct f2fs_sb_info *sbi,
|
|
|
struct block_device *bdev, block_t blkaddr)
|