f2fs: add an sysfs entry to control the directory level
authorJaegeuk Kim <jaegeuk.kim@samsung.com>
Thu, 27 Feb 2014 11:09:05 +0000 (20:09 +0900)
committerJaegeuk Kim <jaegeuk.kim@samsung.com>
Thu, 27 Feb 2014 11:31:15 +0000 (20:31 +0900)
This patch adds an sysfs entry to control dir_level used by the large directory.

The description of this entry is:

 dir_level                    This parameter controls the directory level to
      support large directory. If a directory has a
      number of files, it can reduce the file lookup
      latency by increasing this dir_level value.
      Otherwise, it needs to decrease this value to
      reduce the space overhead. The default value is 0.

Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
Documentation/filesystems/f2fs.txt
fs/f2fs/f2fs.h
fs/f2fs/super.c

index 8eb06b0..803784e 100644 (file)
@@ -195,6 +195,13 @@ Files in /sys/fs/f2fs/<devname>
                              cleaning operations. The default value is 4096
                              which covers 8GB block address range.
 
+ dir_level                    This parameter controls the directory level to
+                             support large directory. If a directory has a
+                             number of files, it can reduce the file lookup
+                             latency by increasing this dir_level value.
+                             Otherwise, it needs to decrease this value to
+                             reduce the space overhead. The default value is 0.
+
 ================================================================================
 USAGE
 ================================================================================
index a826916..6f88191 100644 (file)
@@ -196,6 +196,8 @@ struct extent_info {
 #define FADVISE_COLD_BIT       0x01
 #define FADVISE_LOST_PINO_BIT  0x02
 
+#define DEF_DIR_LEVEL          0
+
 struct f2fs_inode_info {
        struct inode vfs_inode;         /* serve a vfs inode */
        unsigned long i_flags;          /* keep an inode flags for ioctl */
@@ -447,6 +449,7 @@ struct f2fs_sb_info {
        unsigned int total_valid_node_count;    /* valid node block count */
        unsigned int total_valid_inode_count;   /* valid inode count */
        int active_logs;                        /* # of active logs */
+       int dir_level;                          /* directory level */
 
        block_t user_block_count;               /* # of user blocks */
        block_t total_valid_block_count;        /* # of valid blocks */
index 475560e..1bd9153 100644 (file)
@@ -184,6 +184,7 @@ F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, max_small_discards, max_discards);
 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, ipu_policy, ipu_policy);
 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ipu_util, min_ipu_util);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search);
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level);
 
 #define ATTR_LIST(name) (&f2fs_attr_##name.attr)
 static struct attribute *f2fs_attrs[] = {
@@ -196,6 +197,7 @@ static struct attribute *f2fs_attrs[] = {
        ATTR_LIST(ipu_policy),
        ATTR_LIST(min_ipu_util),
        ATTR_LIST(max_victim_search),
+       ATTR_LIST(dir_level),
        NULL,
 };
 
@@ -359,6 +361,9 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb)
        if (test_opt(F2FS_SB(sb), INLINE_XATTR))
                set_inode_flag(fi, FI_INLINE_XATTR);
 
+       /* Will be used by directory only */
+       fi->i_dir_level = F2FS_SB(sb)->dir_level;
+
        return &fi->vfs_inode;
 }
 
@@ -785,6 +790,8 @@ static void init_sb_info(struct f2fs_sb_info *sbi)
 
        for (i = 0; i < NR_COUNT_TYPE; i++)
                atomic_set(&sbi->nr_pages[i], 0);
+
+       sbi->dir_level = DEF_DIR_LEVEL;
 }
 
 /*