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>
This commit is contained in:
Damien Le Moal 2023-01-04 17:20:55 +09:00
Родитель d207794aba
Коммит 43592c4637
2 изменённых файлов: 49 добавлений и 0 удалений

Просмотреть файл

@ -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);

Просмотреть файл

@ -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;
};