From: Damien Le Moal <damien.lemoal@opensource.wdc.com>
To: linux-fsdevel@vger.kernel.org
Cc: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Subject: [PATCH 6/8] zonefs: Add active seq file accounting
Date: Mon, 18 Apr 2022 10:12:05 +0900 [thread overview]
Message-ID: <20220418011207.2385416-7-damien.lemoal@opensource.wdc.com> (raw)
In-Reply-To: <20220418011207.2385416-1-damien.lemoal@opensource.wdc.com>
Modify struct zonefs_sb_info to add the s_active_seq_files atomic to
count the number of seq files representing a zone that is partially
written or explicitly open, that is, to count sequential files with
a zone that is in an active state on the device.
The helper function zonefs_account_active() is introduced to update
this counter whenever a file is written or truncated. This helper is
also used in the zonefs_seq_file_write_open() and
zonefs_seq_file_write_close() functions when the explicit_open mount
option is used.
The s_active_seq_files counter is exported through sysfs using the
read-only attribute nr_active_seq_files. The device maximum number of
active zones is also exported through sysfs with the read-only attribute
max_active_seq_files.
Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
---
fs/zonefs/super.c | 62 +++++++++++++++++++++++++++++++++++++++++++---
fs/zonefs/sysfs.c | 14 +++++++++++
fs/zonefs/zonefs.h | 4 +++
3 files changed, 76 insertions(+), 4 deletions(-)
diff --git a/fs/zonefs/super.c b/fs/zonefs/super.c
index aa359f27102e..3934a68520fe 100644
--- a/fs/zonefs/super.c
+++ b/fs/zonefs/super.c
@@ -27,6 +27,37 @@
#define CREATE_TRACE_POINTS
#include "trace.h"
+/*
+ * Manage the active zone count. Called with zi->i_truncate_mutex held.
+ */
+static void zonefs_account_active(struct inode *inode)
+{
+ struct zonefs_sb_info *sbi = ZONEFS_SB(inode->i_sb);
+ struct zonefs_inode_info *zi = ZONEFS_I(inode);
+
+ if (zi->i_ztype != ZONEFS_ZTYPE_SEQ)
+ return;
+
+ /*
+ * If the zone is active, that is, if it is explicitly open or
+ * partially written, check if it was already accounted as active.
+ */
+ if ((zi->i_flags & ZONEFS_ZONE_OPEN) ||
+ (zi->i_wpoffset > 0 && zi->i_wpoffset < zi->i_max_size)) {
+ if (!(zi->i_flags & ZONEFS_ZONE_ACTIVE)) {
+ zi->i_flags |= ZONEFS_ZONE_ACTIVE;
+ atomic_inc(&sbi->s_active_seq_files);
+ }
+ return;
+ }
+
+ /* The zone is not active. If it was, update the active count */
+ if (zi->i_flags & ZONEFS_ZONE_ACTIVE) {
+ zi->i_flags &= ~ZONEFS_ZONE_ACTIVE;
+ atomic_dec(&sbi->s_active_seq_files);
+ }
+}
+
static inline int zonefs_zone_mgmt(struct inode *inode,
enum req_opf op)
{
@@ -68,8 +99,13 @@ static inline void zonefs_i_size_write(struct inode *inode, loff_t isize)
* A full zone is no longer open/active and does not need
* explicit closing.
*/
- if (isize >= zi->i_max_size)
- zi->i_flags &= ~ZONEFS_ZONE_OPEN;
+ if (isize >= zi->i_max_size) {
+ struct zonefs_sb_info *sbi = ZONEFS_SB(inode->i_sb);
+
+ if (zi->i_flags & ZONEFS_ZONE_ACTIVE)
+ atomic_dec(&sbi->s_active_seq_files);
+ zi->i_flags &= ~(ZONEFS_ZONE_OPEN | ZONEFS_ZONE_ACTIVE);
+ }
}
static int zonefs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
@@ -397,6 +433,7 @@ static int zonefs_io_error_cb(struct blk_zone *zone, unsigned int idx,
zonefs_update_stats(inode, data_size);
zonefs_i_size_write(inode, data_size);
zi->i_wpoffset = data_size;
+ zonefs_account_active(inode);
return 0;
}
@@ -508,6 +545,7 @@ static int zonefs_file_truncate(struct inode *inode, loff_t isize)
zonefs_update_stats(inode, isize);
truncate_setsize(inode, isize);
zi->i_wpoffset = isize;
+ zonefs_account_active(inode);
unlock:
mutex_unlock(&zi->i_truncate_mutex);
@@ -866,8 +904,15 @@ static ssize_t zonefs_file_dio_write(struct kiocb *iocb, struct iov_iter *from)
(ret > 0 || ret == -EIOCBQUEUED)) {
if (ret > 0)
count = ret;
+
+ /*
+ * Update the zone write pointer offset assuming the write
+ * operation succeeded. If it did not, the error recovery path
+ * will correct it. Also do active seq file accounting.
+ */
mutex_lock(&zi->i_truncate_mutex);
zi->i_wpoffset += count;
+ zonefs_account_active(inode);
mutex_unlock(&zi->i_truncate_mutex);
}
@@ -1052,6 +1097,7 @@ static int zonefs_seq_file_write_open(struct inode *inode)
goto unlock;
}
zi->i_flags |= ZONEFS_ZONE_OPEN;
+ zonefs_account_active(inode);
}
}
}
@@ -1119,6 +1165,7 @@ static void zonefs_seq_file_write_close(struct inode *inode)
}
zi->i_flags &= ~ZONEFS_ZONE_OPEN;
+ zonefs_account_active(inode);
}
atomic_dec(&sbi->s_wro_seq_files);
@@ -1325,7 +1372,7 @@ static int zonefs_init_file_inode(struct inode *inode, struct blk_zone *zone,
struct super_block *sb = inode->i_sb;
struct zonefs_sb_info *sbi = ZONEFS_SB(sb);
struct zonefs_inode_info *zi = ZONEFS_I(inode);
- int ret = 0;
+ int ret;
inode->i_ino = zone->start >> sbi->s_zone_sectors_shift;
inode->i_mode = S_IFREG | sbi->s_perm;
@@ -1363,9 +1410,13 @@ static int zonefs_init_file_inode(struct inode *inode, struct blk_zone *zone,
mutex_lock(&zi->i_truncate_mutex);
ret = zonefs_zone_mgmt(inode, REQ_OP_ZONE_CLOSE);
mutex_unlock(&zi->i_truncate_mutex);
+ if (ret)
+ return ret;
}
- return ret;
+ zonefs_account_active(inode);
+
+ return 0;
}
static struct dentry *zonefs_create_inode(struct dentry *parent,
@@ -1711,6 +1762,9 @@ static int zonefs_fill_super(struct super_block *sb, void *data, int silent)
sbi->s_mount_opts &= ~ZONEFS_MNTOPT_EXPLICIT_OPEN;
}
+ atomic_set(&sbi->s_active_seq_files, 0);
+ sbi->s_max_active_seq_files = bdev_max_active_zones(sb->s_bdev);
+
ret = zonefs_read_super(sb);
if (ret)
return ret;
diff --git a/fs/zonefs/sysfs.c b/fs/zonefs/sysfs.c
index eaeaf983ed87..9cb6755ce39a 100644
--- a/fs/zonefs/sysfs.c
+++ b/fs/zonefs/sysfs.c
@@ -51,9 +51,23 @@ static ssize_t nr_wro_seq_files_show(struct zonefs_sb_info *sbi, char *buf)
}
ZONEFS_SYSFS_ATTR_RO(nr_wro_seq_files);
+static ssize_t max_active_seq_files_show(struct zonefs_sb_info *sbi, char *buf)
+{
+ return sysfs_emit(buf, "%u\n", sbi->s_max_active_seq_files);
+}
+ZONEFS_SYSFS_ATTR_RO(max_active_seq_files);
+
+static ssize_t nr_active_seq_files_show(struct zonefs_sb_info *sbi, char *buf)
+{
+ return sysfs_emit(buf, "%d\n", atomic_read(&sbi->s_active_seq_files));
+}
+ZONEFS_SYSFS_ATTR_RO(nr_active_seq_files);
+
static struct attribute *zonefs_sysfs_attrs[] = {
ATTR_LIST(max_wro_seq_files),
ATTR_LIST(nr_wro_seq_files),
+ ATTR_LIST(max_active_seq_files),
+ ATTR_LIST(nr_active_seq_files),
NULL,
};
ATTRIBUTE_GROUPS(zonefs_sysfs);
diff --git a/fs/zonefs/zonefs.h b/fs/zonefs/zonefs.h
index 77d2d153c59d..4b3de66c3233 100644
--- a/fs/zonefs/zonefs.h
+++ b/fs/zonefs/zonefs.h
@@ -40,6 +40,7 @@ static inline enum zonefs_ztype zonefs_zone_type(struct blk_zone *zone)
}
#define ZONEFS_ZONE_OPEN (1 << 0)
+#define ZONEFS_ZONE_ACTIVE (1 << 1)
/*
* In-memory inode data.
@@ -186,6 +187,9 @@ struct zonefs_sb_info {
unsigned int s_max_wro_seq_files;
atomic_t s_wro_seq_files;
+ unsigned int s_max_active_seq_files;
+ atomic_t s_active_seq_files;
+
bool s_sysfs_registered;
struct kobject s_kobj;
struct completion s_kobj_unregister;
--
2.35.1
next prev parent reply other threads:[~2022-04-18 1:12 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-04-18 1:11 [PATCH 0/8] zonefs improvements Damien Le Moal
2022-04-18 1:12 ` [PATCH 1/8] zonefs: Clear inode information flags on inode creation Damien Le Moal
2022-04-19 9:27 ` Johannes Thumshirn
2022-04-18 1:12 ` [PATCH 2/8] zonefs: Fix management of open zones Damien Le Moal
2022-04-19 9:38 ` Johannes Thumshirn
2022-04-18 1:12 ` [PATCH 3/8] zonefs: Rename super block information fields Damien Le Moal
2022-04-19 9:29 ` Johannes Thumshirn
2022-04-18 1:12 ` [PATCH 4/8] zonefs: Always do seq file write open accounting Damien Le Moal
2022-04-19 9:55 ` Johannes Thumshirn
2022-04-18 1:12 ` [PATCH 5/8] zonefs: Export open zone resource information through sysfs Damien Le Moal
2022-04-19 10:06 ` Johannes Thumshirn
2022-04-18 1:12 ` Damien Le Moal [this message]
2022-04-19 10:59 ` [PATCH 6/8] zonefs: Add active seq file accounting Johannes Thumshirn
2022-04-19 11:02 ` Damien Le Moal
2022-04-19 11:06 ` Johannes Thumshirn
2022-04-19 11:26 ` Damien Le Moal
2022-04-18 1:12 ` [PATCH 7/8] documentation: zonefs: Cleanup the mount options section Damien Le Moal
2022-04-19 10:14 ` Johannes Thumshirn
2022-04-18 1:12 ` [PATCH 8/8] documentation: zonefs: Document sysfs attributes Damien Le Moal
2022-04-19 10:14 ` Johannes Thumshirn
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220418011207.2385416-7-damien.lemoal@opensource.wdc.com \
--to=damien.lemoal@opensource.wdc.com \
--cc=johannes.thumshirn@wdc.com \
--cc=linux-fsdevel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.