Skip to content

Commit 211ed54

Browse files
committed
Merge tag 'zonefs-5.18-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/zonefs
Pull zonefs fixes from Damien Le Moal: "Two fixes for rc5: - Fix inode initialization to make sure that the inode flags are all cleared. - Use zone reset operation instead of close to make sure that the zone of an empty sequential file in never in an active state after closing the file" * tag 'zonefs-5.18-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/zonefs: zonefs: Fix management of open zones zonefs: Clear inode information flags on inode creation
2 parents 03498b7 + 1da18a2 commit 211ed54

File tree

1 file changed

+41
-5
lines changed

1 file changed

+41
-5
lines changed

fs/zonefs/super.c

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,17 @@ static inline int zonefs_zone_mgmt(struct inode *inode,
3535

3636
lockdep_assert_held(&zi->i_truncate_mutex);
3737

38+
/*
39+
* With ZNS drives, closing an explicitly open zone that has not been
40+
* written will change the zone state to "closed", that is, the zone
41+
* will remain active. Since this can then cause failure of explicit
42+
* open operation on other zones if the drive active zone resources
43+
* are exceeded, make sure that the zone does not remain active by
44+
* resetting it.
45+
*/
46+
if (op == REQ_OP_ZONE_CLOSE && !zi->i_wpoffset)
47+
op = REQ_OP_ZONE_RESET;
48+
3849
trace_zonefs_zone_mgmt(inode, op);
3950
ret = blkdev_zone_mgmt(inode->i_sb->s_bdev, op, zi->i_zsector,
4051
zi->i_zone_size >> SECTOR_SHIFT, GFP_NOFS);
@@ -1142,6 +1153,7 @@ static struct inode *zonefs_alloc_inode(struct super_block *sb)
11421153
inode_init_once(&zi->i_vnode);
11431154
mutex_init(&zi->i_truncate_mutex);
11441155
zi->i_wr_refcnt = 0;
1156+
zi->i_flags = 0;
11451157

11461158
return &zi->i_vnode;
11471159
}
@@ -1293,12 +1305,13 @@ static void zonefs_init_dir_inode(struct inode *parent, struct inode *inode,
12931305
inc_nlink(parent);
12941306
}
12951307

1296-
static void zonefs_init_file_inode(struct inode *inode, struct blk_zone *zone,
1297-
enum zonefs_ztype type)
1308+
static int zonefs_init_file_inode(struct inode *inode, struct blk_zone *zone,
1309+
enum zonefs_ztype type)
12981310
{
12991311
struct super_block *sb = inode->i_sb;
13001312
struct zonefs_sb_info *sbi = ZONEFS_SB(sb);
13011313
struct zonefs_inode_info *zi = ZONEFS_I(inode);
1314+
int ret = 0;
13021315

13031316
inode->i_ino = zone->start >> sbi->s_zone_sectors_shift;
13041317
inode->i_mode = S_IFREG | sbi->s_perm;
@@ -1323,6 +1336,22 @@ static void zonefs_init_file_inode(struct inode *inode, struct blk_zone *zone,
13231336
sb->s_maxbytes = max(zi->i_max_size, sb->s_maxbytes);
13241337
sbi->s_blocks += zi->i_max_size >> sb->s_blocksize_bits;
13251338
sbi->s_used_blocks += zi->i_wpoffset >> sb->s_blocksize_bits;
1339+
1340+
/*
1341+
* For sequential zones, make sure that any open zone is closed first
1342+
* to ensure that the initial number of open zones is 0, in sync with
1343+
* the open zone accounting done when the mount option
1344+
* ZONEFS_MNTOPT_EXPLICIT_OPEN is used.
1345+
*/
1346+
if (type == ZONEFS_ZTYPE_SEQ &&
1347+
(zone->cond == BLK_ZONE_COND_IMP_OPEN ||
1348+
zone->cond == BLK_ZONE_COND_EXP_OPEN)) {
1349+
mutex_lock(&zi->i_truncate_mutex);
1350+
ret = zonefs_zone_mgmt(inode, REQ_OP_ZONE_CLOSE);
1351+
mutex_unlock(&zi->i_truncate_mutex);
1352+
}
1353+
1354+
return ret;
13261355
}
13271356

13281357
static struct dentry *zonefs_create_inode(struct dentry *parent,
@@ -1332,6 +1361,7 @@ static struct dentry *zonefs_create_inode(struct dentry *parent,
13321361
struct inode *dir = d_inode(parent);
13331362
struct dentry *dentry;
13341363
struct inode *inode;
1364+
int ret;
13351365

13361366
dentry = d_alloc_name(parent, name);
13371367
if (!dentry)
@@ -1342,10 +1372,16 @@ static struct dentry *zonefs_create_inode(struct dentry *parent,
13421372
goto dput;
13431373

13441374
inode->i_ctime = inode->i_mtime = inode->i_atime = dir->i_ctime;
1345-
if (zone)
1346-
zonefs_init_file_inode(inode, zone, type);
1347-
else
1375+
if (zone) {
1376+
ret = zonefs_init_file_inode(inode, zone, type);
1377+
if (ret) {
1378+
iput(inode);
1379+
goto dput;
1380+
}
1381+
} else {
13481382
zonefs_init_dir_inode(dir, inode, type);
1383+
}
1384+
13491385
d_add(dentry, inode);
13501386
dir->i_size++;
13511387

0 commit comments

Comments
 (0)