diff options
author | Damien Le Moal <damien.lemoal@opensource.wdc.com> | 2023-01-04 09:20:55 +0100 |
---|---|---|
committer | Damien Le Moal <damien.lemoal@opensource.wdc.com> | 2023-01-23 01:25:51 +0100 |
commit | 43592c46375a056b411b065acf2d37fc1e3ab251 (patch) | |
tree | f331151261d2f067a6fb51e980bead844a8b545e /fs/zonefs | |
parent | zonefs: Dynamically create file inodes when needed (diff) | |
download | linux-43592c46375a056b411b065acf2d37fc1e3ab251.tar.xz linux-43592c46375a056b411b065acf2d37fc1e3ab251.zip |
zonefs: Cache zone group directory inodes
Since looking up any zone file inode requires looking up first the inode
for the directory representing the zone group of the file, ensuring that
the zone group inodes are always cached is desired. To do so, take an
extra reference on the zone groups directory inodes on mount, thus
avoiding the eviction of these inodes from the inode cache until the
volume is unmounted.
Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Diffstat (limited to 'fs/zonefs')
-rw-r--r-- | fs/zonefs/super.c | 48 | ||||
-rw-r--r-- | fs/zonefs/zonefs.h | 1 |
2 files changed, 49 insertions, 0 deletions
diff --git a/fs/zonefs/super.c b/fs/zonefs/super.c index 7d70c327883e..010b53545e5b 100644 --- a/fs/zonefs/super.c +++ b/fs/zonefs/super.c @@ -1199,6 +1199,42 @@ static const struct super_operations zonefs_sops = { .show_options = zonefs_show_options, }; +static int zonefs_get_zgroup_inodes(struct super_block *sb) +{ + struct zonefs_sb_info *sbi = ZONEFS_SB(sb); + struct inode *dir_inode; + enum zonefs_ztype ztype; + + for (ztype = 0; ztype < ZONEFS_ZTYPE_MAX; ztype++) { + if (!sbi->s_zgroup[ztype].g_nr_zones) + continue; + + dir_inode = zonefs_get_zgroup_inode(sb, ztype); + if (IS_ERR(dir_inode)) + return PTR_ERR(dir_inode); + + sbi->s_zgroup[ztype].g_inode = dir_inode; + } + + return 0; +} + +static void zonefs_release_zgroup_inodes(struct super_block *sb) +{ + struct zonefs_sb_info *sbi = ZONEFS_SB(sb); + enum zonefs_ztype ztype; + + if (!sbi) + return; + + for (ztype = 0; ztype < ZONEFS_ZTYPE_MAX; ztype++) { + if (sbi->s_zgroup[ztype].g_inode) { + iput(sbi->s_zgroup[ztype].g_inode); + sbi->s_zgroup[ztype].g_inode = NULL; + } + } +} + /* * Check that the device is zoned. If it is, get the list of zones and create * sub-directories and files according to the device zone configuration and @@ -1297,6 +1333,14 @@ static int zonefs_fill_super(struct super_block *sb, void *data, int silent) if (!sb->s_root) goto cleanup; + /* + * Take a reference on the zone groups directory inodes + * to keep them in the inode cache. + */ + ret = zonefs_get_zgroup_inodes(sb); + if (ret) + goto cleanup; + ret = zonefs_sysfs_register(sb); if (ret) goto cleanup; @@ -1304,6 +1348,7 @@ static int zonefs_fill_super(struct super_block *sb, void *data, int silent) return 0; cleanup: + zonefs_release_zgroup_inodes(sb); zonefs_free_zgroups(sb); return ret; @@ -1319,6 +1364,9 @@ static void zonefs_kill_super(struct super_block *sb) { struct zonefs_sb_info *sbi = ZONEFS_SB(sb); + /* Release the reference on the zone group directory inodes */ + zonefs_release_zgroup_inodes(sb); + kill_block_super(sb); zonefs_sysfs_unregister(sb); diff --git a/fs/zonefs/zonefs.h b/fs/zonefs/zonefs.h index f88466a4158b..8175652241b5 100644 --- a/fs/zonefs/zonefs.h +++ b/fs/zonefs/zonefs.h @@ -76,6 +76,7 @@ struct zonefs_zone { * as files, one file per zone. */ struct zonefs_zone_group { + struct inode *g_inode; unsigned int g_nr_zones; struct zonefs_zone *g_zones; }; |