Commit f2470371 authored by Chao Yu's avatar Chao Yu Committed by Jaegeuk Kim

f2fs: make max inline size changeable

This patch tries to make below macros calculating max inline size,
inline dentry field size considerring reserving size-changeable
space:
- MAX_INLINE_DATA
- NR_INLINE_DENTRY
- INLINE_DENTRY_BITMAP_SIZE
- INLINE_RESERVED_SIZE

Then, when inline_{data,dentry} options is enabled, it allows us to
reserve inline space with different size flexibly for adding newly
introduced inode attribute.
Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent e65ef207
......@@ -813,7 +813,7 @@ int f2fs_preallocate_blocks(struct kiocb *iocb, struct iov_iter *from)
F2FS_GET_BLOCK_PRE_AIO :
F2FS_GET_BLOCK_PRE_DIO);
}
if (iocb->ki_pos + iov_iter_count(from) > MAX_INLINE_DATA) {
if (iocb->ki_pos + iov_iter_count(from) > MAX_INLINE_DATA(inode)) {
err = f2fs_convert_inline_inode(inode);
if (err)
return err;
......@@ -1857,7 +1857,7 @@ static int prepare_write_begin(struct f2fs_sb_info *sbi,
set_new_dnode(&dn, inode, ipage, ipage, 0);
if (f2fs_has_inline_data(inode)) {
if (pos + len <= MAX_INLINE_DATA) {
if (pos + len <= MAX_INLINE_DATA(inode)) {
read_inline_data(page, ipage);
set_inode_flag(inode, FI_DATA_EXIST);
if (inode->i_nlink)
......
......@@ -357,6 +357,25 @@ struct f2fs_flush_device {
u32 segments; /* # of segments to flush */
};
/* for inline stuff */
#define DEF_INLINE_RESERVED_SIZE 1
static inline int get_inline_reserved_size(struct inode *inode);
#define MAX_INLINE_DATA(inode) (sizeof(__le32) * (DEF_ADDRS_PER_INODE -\
get_inline_reserved_size(inode) -\
F2FS_INLINE_XATTR_ADDRS))
/* for inline dir */
#define NR_INLINE_DENTRY(inode) (MAX_INLINE_DATA(inode) * BITS_PER_BYTE / \
((SIZE_OF_DIR_ENTRY + F2FS_SLOT_LEN) * \
BITS_PER_BYTE + 1))
#define INLINE_DENTRY_BITMAP_SIZE(inode) ((NR_INLINE_DENTRY(inode) + \
BITS_PER_BYTE - 1) / BITS_PER_BYTE)
#define INLINE_RESERVED_SIZE(inode) (MAX_INLINE_DATA(inode) - \
((SIZE_OF_DIR_ENTRY + F2FS_SLOT_LEN) * \
NR_INLINE_DENTRY(inode) + \
INLINE_DENTRY_BITMAP_SIZE(inode)))
/*
* For INODE and NODE manager
*/
......@@ -382,14 +401,19 @@ static inline void make_dentry_ptr_block(struct inode *inode,
}
static inline void make_dentry_ptr_inline(struct inode *inode,
struct f2fs_dentry_ptr *d, struct f2fs_inline_dentry *t)
struct f2fs_dentry_ptr *d, void *t)
{
int entry_cnt = NR_INLINE_DENTRY(inode);
int bitmap_size = INLINE_DENTRY_BITMAP_SIZE(inode);
int reserved_size = INLINE_RESERVED_SIZE(inode);
d->inode = inode;
d->max = NR_INLINE_DENTRY;
d->nr_bitmap = INLINE_DENTRY_BITMAP_SIZE;
d->bitmap = &t->dentry_bitmap;
d->dentry = t->dentry;
d->filename = t->filename;
d->max = entry_cnt;
d->nr_bitmap = bitmap_size;
d->bitmap = t;
d->dentry = t + bitmap_size + reserved_size;
d->filename = t + bitmap_size + reserved_size +
SIZE_OF_DIR_ENTRY * entry_cnt;
}
/*
......@@ -543,6 +567,8 @@ struct f2fs_inode_info {
struct extent_tree *extent_tree; /* cached extent_tree entry */
struct rw_semaphore dio_rwsem[2];/* avoid racing between dio and gc */
struct rw_semaphore i_mmap_sem;
int i_inline_reserved; /* reserved size in inline data */
};
static inline void get_extent_info(struct extent_info *ext,
......@@ -2075,11 +2101,12 @@ static inline bool f2fs_is_drop_cache(struct inode *inode)
return is_inode_flag_set(inode, FI_DROP_CACHE);
}
static inline void *inline_data_addr(struct page *page)
static inline void *inline_data_addr(struct inode *inode, struct page *page)
{
struct f2fs_inode *ri = F2FS_INODE(page);
int reserved_size = get_inline_reserved_size(inode);
return (void *)&(ri->i_addr[1]);
return (void *)&(ri->i_addr[reserved_size]);
}
static inline int f2fs_has_inline_dentry(struct inode *inode)
......@@ -2170,6 +2197,11 @@ static inline void *f2fs_kmalloc(struct f2fs_sb_info *sbi,
return kmalloc(size, flags);
}
static inline int get_inline_reserved_size(struct inode *inode)
{
return F2FS_I(inode)->i_inline_reserved;
}
#define get_inode_mode(i) \
((is_inode_flag_set(i, FI_ACL_MODE)) ? \
(F2FS_I(i)->i_acl_mode) : ((i)->i_mode))
......
This diff is collapsed.
......@@ -87,9 +87,9 @@ static void __set_inode_rdev(struct inode *inode, struct f2fs_inode *ri)
static void __recover_inline_status(struct inode *inode, struct page *ipage)
{
void *inline_data = inline_data_addr(ipage);
void *inline_data = inline_data_addr(inode, ipage);
__le32 *start = inline_data;
__le32 *end = start + MAX_INLINE_DATA / sizeof(__le32);
__le32 *end = start + MAX_INLINE_DATA(inode) / sizeof(__le32);
while (start < end) {
if (*start++) {
......
......@@ -446,6 +446,9 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb)
#endif
/* Will be used by directory only */
fi->i_dir_level = F2FS_SB(sb)->dir_level;
fi->i_inline_reserved = DEF_INLINE_RESERVED_SIZE;
return &fi->vfs_inode;
}
......
......@@ -206,9 +206,6 @@ struct f2fs_extent {
#define F2FS_DATA_EXIST 0x08 /* file inline data exist flag */
#define F2FS_INLINE_DOTS 0x10 /* file having implicit dot dentries */
#define MAX_INLINE_DATA (sizeof(__le32) * (DEF_ADDRS_PER_INODE - \
F2FS_INLINE_XATTR_ADDRS - 1))
struct f2fs_inode {
__le16 i_mode; /* file mode */
__u8 i_advise; /* file hints */
......@@ -465,7 +462,7 @@ typedef __le32 f2fs_hash_t;
#define MAX_DIR_BUCKETS (1 << ((MAX_DIR_HASH_DEPTH / 2) - 1))
/*
* space utilization of regular dentry and inline dentry
* space utilization of regular dentry and inline dentry (w/o extra reservation)
* regular dentry inline dentry
* bitmap 1 * 27 = 27 1 * 23 = 23
* reserved 1 * 3 = 3 1 * 7 = 7
......@@ -501,24 +498,6 @@ struct f2fs_dentry_block {
__u8 filename[NR_DENTRY_IN_BLOCK][F2FS_SLOT_LEN];
} __packed;
/* for inline dir */
#define NR_INLINE_DENTRY (MAX_INLINE_DATA * BITS_PER_BYTE / \
((SIZE_OF_DIR_ENTRY + F2FS_SLOT_LEN) * \
BITS_PER_BYTE + 1))
#define INLINE_DENTRY_BITMAP_SIZE ((NR_INLINE_DENTRY + \
BITS_PER_BYTE - 1) / BITS_PER_BYTE)
#define INLINE_RESERVED_SIZE (MAX_INLINE_DATA - \
((SIZE_OF_DIR_ENTRY + F2FS_SLOT_LEN) * \
NR_INLINE_DENTRY + INLINE_DENTRY_BITMAP_SIZE))
/* inline directory entry structure */
struct f2fs_inline_dentry {
__u8 dentry_bitmap[INLINE_DENTRY_BITMAP_SIZE];
__u8 reserved[INLINE_RESERVED_SIZE];
struct f2fs_dir_entry dentry[NR_INLINE_DENTRY];
__u8 filename[NR_INLINE_DENTRY][F2FS_SLOT_LEN];
} __packed;
/* file types used in inode_info->flags */
enum {
F2FS_FT_UNKNOWN,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment