Re: [PATCH v3] f2fs: add an ioctl to disable GC for specific file
On 01/03, Chao Yu wrote: > On 2018/1/3 11:21, Jaegeuk Kim wrote: > > This patch gives a flag to disable GC on given file, which would be useful, > > when > > user wants to keep its block map. It also conducts in-place-update for > > dontmove > > file. > > > > Signed-off-by: Jaegeuk Kim > > --- > > > > Change log from v2: > > - modify ioctl to allow users unpin the file > > > > fs/f2fs/data.c | 2 ++ > > fs/f2fs/f2fs.h | 28 +- > > fs/f2fs/file.c | 64 > > + > > fs/f2fs/gc.c| 11 + > > fs/f2fs/gc.h| 2 ++ > > fs/f2fs/sysfs.c | 2 ++ > > include/linux/f2fs_fs.h | 9 ++- > > 7 files changed, 116 insertions(+), 2 deletions(-) > > > > diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c > > index 449b0aaa3905..45f65a5b9871 100644 > > --- a/fs/f2fs/data.c > > +++ b/fs/f2fs/data.c > > @@ -1395,6 +1395,8 @@ static inline bool need_inplace_update(struct > > f2fs_io_info *fio) > > { > > struct inode *inode = fio->page->mapping->host; > > > > + if (f2fs_is_pinned_file(inode)) > > + return true; > > if (S_ISDIR(inode->i_mode) || f2fs_is_atomic_file(inode)) > > return false; > > if (is_cold_data(fio->page)) > > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h > > index a0e8eec23125..f4b7d73695a7 100644 > > --- a/fs/f2fs/f2fs.h > > +++ b/fs/f2fs/f2fs.h > > @@ -350,6 +350,7 @@ 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_SET_ENCRYPTION_POLICY FS_IOC_SET_ENCRYPTION_POLICY > > #define F2FS_IOC_GET_ENCRYPTION_POLICY FS_IOC_GET_ENCRYPTION_POLICY > > @@ -587,7 +588,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 */ > > > > @@ -1133,6 +1137,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; > > > > @@ -2124,6 +2131,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, > > @@ -2137,6 +2145,7 @@ static inline void __mark_inode_dirty_flag(struct > > inode *inode, > > return; > > case FI_DATA_EXIST: > > case FI_INLINE_DOTS: > > + case FI_PIN_FILE: > > f2fs_mark_inode_dirty_sync(inode, true); > > } > > } > > @@ -2217,6 +2226,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; > > @@ -2245,6 +2261,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) > > @@ -2263,6 +2281,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
Re: [PATCH v3] f2fs: add an ioctl to disable GC for specific file
On 2018/1/3 11:21, Jaegeuk Kim wrote: > This patch gives a flag to disable GC on given file, which would be useful, > when > user wants to keep its block map. It also conducts in-place-update for > dontmove > file. > > Signed-off-by: Jaegeuk Kim > --- > > Change log from v2: > - modify ioctl to allow users unpin the file > > fs/f2fs/data.c | 2 ++ > fs/f2fs/f2fs.h | 28 +- > fs/f2fs/file.c | 64 > + > fs/f2fs/gc.c| 11 + > fs/f2fs/gc.h| 2 ++ > fs/f2fs/sysfs.c | 2 ++ > include/linux/f2fs_fs.h | 9 ++- > 7 files changed, 116 insertions(+), 2 deletions(-) > > diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c > index 449b0aaa3905..45f65a5b9871 100644 > --- a/fs/f2fs/data.c > +++ b/fs/f2fs/data.c > @@ -1395,6 +1395,8 @@ static inline bool need_inplace_update(struct > f2fs_io_info *fio) > { > struct inode *inode = fio->page->mapping->host; > > + if (f2fs_is_pinned_file(inode)) > + return true; > if (S_ISDIR(inode->i_mode) || f2fs_is_atomic_file(inode)) > return false; > if (is_cold_data(fio->page)) > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h > index a0e8eec23125..f4b7d73695a7 100644 > --- a/fs/f2fs/f2fs.h > +++ b/fs/f2fs/f2fs.h > @@ -350,6 +350,7 @@ 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_SET_ENCRYPTION_POLICY FS_IOC_SET_ENCRYPTION_POLICY > #define F2FS_IOC_GET_ENCRYPTION_POLICY FS_IOC_GET_ENCRYPTION_POLICY > @@ -587,7 +588,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 */ > > @@ -1133,6 +1137,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; > > @@ -2124,6 +2131,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, > @@ -2137,6 +2145,7 @@ static inline void __mark_inode_dirty_flag(struct inode > *inode, > return; > case FI_DATA_EXIST: > case FI_INLINE_DOTS: > + case FI_PIN_FILE: > f2fs_mark_inode_dirty_sync(inode, true); > } > } > @@ -2217,6 +2226,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; > @@ -2245,6 +2261,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) > @@ -2263,6 +2281,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 *ino
Re: [PATCH v3] f2fs: add an ioctl to disable GC for specific file
This patch gives a flag to disable GC on given file, which would be useful, when user wants to keep its block map. It also conducts in-place-update for dontmove file. Signed-off-by: Jaegeuk Kim --- Change log from v2: - modify ioctl to allow users unpin the file fs/f2fs/data.c | 2 ++ fs/f2fs/f2fs.h | 28 +- fs/f2fs/file.c | 64 + fs/f2fs/gc.c| 11 + fs/f2fs/gc.h| 2 ++ fs/f2fs/sysfs.c | 2 ++ include/linux/f2fs_fs.h | 9 ++- 7 files changed, 116 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 449b0aaa3905..45f65a5b9871 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1395,6 +1395,8 @@ static inline bool need_inplace_update(struct f2fs_io_info *fio) { struct inode *inode = fio->page->mapping->host; + if (f2fs_is_pinned_file(inode)) + return true; if (S_ISDIR(inode->i_mode) || f2fs_is_atomic_file(inode)) return false; if (is_cold_data(fio->page)) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index a0e8eec23125..f4b7d73695a7 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -350,6 +350,7 @@ 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_SET_ENCRYPTION_POLICY FS_IOC_SET_ENCRYPTION_POLICY #define F2FS_IOC_GET_ENCRYPTION_POLICY FS_IOC_GET_ENCRYPTION_POLICY @@ -587,7 +588,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 */ @@ -1133,6 +1137,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; @@ -2124,6 +2131,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, @@ -2137,6 +2145,7 @@ static inline void __mark_inode_dirty_flag(struct inode *inode, return; case FI_DATA_EXIST: case FI_INLINE_DOTS: + case FI_PIN_FILE: f2fs_mark_inode_dirty_sync(inode, true); } } @@ -2217,6 +2226,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; @@ -2245,6 +2261,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) @@ -2263,6 +2281,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) @@ -2308,6 +2328,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 i