From: Andreas Rohner <andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
To: linux-nilfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: Andreas Rohner <andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
Subject: [PATCH 4/6] nilfs-utils: implement the tracking of live blocks for set_suinfo
Date: Tue, 24 Feb 2015 20:04:17 +0100 [thread overview]
Message-ID: <1424804659-10986-4-git-send-email-andreas.rohner@gmx.net> (raw)
In-Reply-To: <1424804659-10986-1-git-send-email-andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
If the tracking of live blocks is enabled, the information passed to
the kernel with the set_suinfo ioctl must also be modified. To this
end the nilfs_count_nlive_blks() fucntion is introduced. It simply
loops through the vdescv and bdescv vectors and counts the live
blocks belonging to a certain segment. Here the new vdesc flags
introduced earlier come in handy. If NILFS_VDESC_SNAPSHOT flag is set,
the block is always counted as alive. However if it is not set and
NILFS_VDESC_PROTECTION_PERIOD is set instead it is counted as
reclaimable.
Additionally the nilfs_xreclaim_segment() function is refactored, so
that the set_suinfo part is extracted into its own function
nilfs_try_set_suinfo(). This is useful, because the code gets more
complicated with the new additions.
If the kernel either doesn't support the set_suinfo ioctl or doesn't
support the set_nlive_blks flag, it returns ENOTTY or EINVAL
respectively and the corresponding options are disabled and not used
again.
Signed-off-by: Andreas Rohner <andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
---
include/nilfs.h | 6 ++
lib/gc.c | 168 +++++++++++++++++++++++++++++++++++++++++++-------------
2 files changed, 136 insertions(+), 38 deletions(-)
diff --git a/include/nilfs.h b/include/nilfs.h
index 22a9190..8511163 100644
--- a/include/nilfs.h
+++ b/include/nilfs.h
@@ -343,6 +343,12 @@ static inline __u32 nilfs_get_blocks_per_segment(const struct nilfs *nilfs)
return le32_to_cpu(nilfs->n_sb->s_blocks_per_segment);
}
+static inline __u64
+nilfs_get_segnum_of_block(const struct nilfs *nilfs, sector_t blocknr)
+{
+ return blocknr / nilfs_get_blocks_per_segment(nilfs);
+}
+
static inline int nilfs_feature_track_live_blks(const struct nilfs *nilfs)
{
__u64 fc = le64_to_cpu(nilfs->n_sb->s_feature_compat);
diff --git a/lib/gc.c b/lib/gc.c
index b56744c..a2461b9 100644
--- a/lib/gc.c
+++ b/lib/gc.c
@@ -620,6 +620,121 @@ static int nilfs_toss_bdescs(struct nilfs_vector *bdescv)
}
/**
+ * nilfs_count_nlive_blks - returns the number of live blocks in segnum
+ * @nilfs: nilfs object
+ * @segnum: segment number
+ * @bdescv: vector object storing (descriptors of) disk block numbers
+ * @vdescv: vector object storing (descriptors of) virtual block numbers
+ */
+static size_t nilfs_count_nlive_blks(const struct nilfs *nilfs,
+ __u64 segnum,
+ struct nilfs_vector *vdescv,
+ struct nilfs_vector *bdescv)
+{
+ struct nilfs_vdesc *vdesc;
+ struct nilfs_bdesc *bdesc;
+ int i;
+ size_t res = 0;
+
+ for (i = 0; i < nilfs_vector_get_size(bdescv); i++) {
+ bdesc = nilfs_vector_get_element(bdescv, i);
+ assert(bdesc != NULL);
+
+ if (nilfs_get_segnum_of_block(nilfs, bdesc->bd_blocknr) ==
+ segnum && nilfs_bdesc_is_live(bdesc))
+ ++res;
+ }
+
+ for (i = 0; i < nilfs_vector_get_size(vdescv); i++) {
+ vdesc = nilfs_vector_get_element(vdescv, i);
+ assert(vdesc != NULL);
+
+ if (nilfs_get_segnum_of_block(nilfs, vdesc->vd_blocknr) ==
+ segnum && (nilfs_vdesc_snapshot(vdesc) ||
+ !nilfs_vdesc_protection_period(vdesc)))
+ ++res;
+ }
+
+ return res;
+}
+
+/**
+ * nilfs_try_set_suinfo - wrapper for nilfs_set_suinfo
+ * @nilfs: nilfs object
+ * @segnums: array of segment numbers storing selected segments
+ * @nsegs: size of the @segnums array
+ * @vdescv: vector object storing (descriptors of) virtual block numbers
+ * @bdescv: vector object storing (descriptors of) disk block numbers
+ *
+ * Description: nilfs_try_set_suinfo() prepares the input data structure
+ * for nilfs_set_suinfo(). If the kernel doesn't support the
+ * NILFS_IOCTL_SET_SUINFO ioctl, errno is set to ENOTTY and the set_suinfo
+ * option is cleared to prevent future calls to nilfs_try_set_suinfo().
+ * Similarly if the SUFILE extension is not supported by the kernel,
+ * errno is set to EINVAL and the track_live_blks option is disabled.
+ *
+ * Return Value: On success, zero is returned. On error, a negative value
+ * is returned. If errno is set to ENOTTY or EINVAL, the kernel doesn't support
+ * the current configuration for nilfs_set_suinfo().
+ */
+static int nilfs_try_set_suinfo(struct nilfs *nilfs, __u64 *segnums,
+ size_t nsegs, struct nilfs_vector *vdescv,
+ struct nilfs_vector *bdescv)
+{
+ struct nilfs_vector *supv;
+ struct nilfs_suinfo_update *sup;
+ struct timeval tv;
+ int ret = -1;
+ size_t i, nblocks;
+
+ supv = nilfs_vector_create(sizeof(struct nilfs_suinfo_update));
+ if (!supv)
+ goto out;
+
+ ret = gettimeofday(&tv, NULL);
+ if (ret < 0)
+ goto out;
+
+ for (i = 0; i < nsegs; ++i) {
+ sup = nilfs_vector_get_new_element(supv);
+ if (!sup) {
+ ret = -1;
+ goto out;
+ }
+
+ sup->sup_segnum = segnums[i];
+ sup->sup_flags = 0;
+ nilfs_suinfo_update_set_lastmod(sup);
+ sup->sup_sui.sui_lastmod = tv.tv_sec;
+
+ if (nilfs_opt_test_track_live_blks(nilfs)) {
+ nilfs_suinfo_update_set_nlive_blks(sup);
+
+ nblocks = nilfs_count_nlive_blks(nilfs,
+ segnums[i], vdescv, bdescv);
+ sup->sup_sui.sui_nlive_blks = nblocks;
+ }
+ }
+
+ ret = nilfs_set_suinfo(nilfs, nilfs_vector_get_data(supv), nsegs);
+ if (ret < 0) {
+ if (errno == ENOTTY) {
+ nilfs_gc_logger(LOG_WARNING,
+ "set_suinfo ioctl is not supported");
+ nilfs_opt_clear_set_suinfo(nilfs);
+ } else if (errno == EINVAL) {
+ nilfs_gc_logger(LOG_WARNING,
+ "sufile extension is not supported");
+ nilfs_opt_clear_track_live_blks(nilfs);
+ }
+ }
+
+out:
+ nilfs_vector_destroy(supv);
+ return ret;
+}
+
+/**
* nilfs_xreclaim_segment - reclaim segments (enhanced API)
* @nilfs: nilfs object
* @segnums: array of segment numbers storing selected segments
@@ -633,14 +748,12 @@ int nilfs_xreclaim_segment(struct nilfs *nilfs,
const struct nilfs_reclaim_params *params,
struct nilfs_reclaim_stat *stat)
{
- struct nilfs_vector *vdescv, *bdescv, *periodv, *vblocknrv, *supv;
+ struct nilfs_vector *vdescv, *bdescv, *periodv, *vblocknrv;
sigset_t sigset, oldset, waitset;
nilfs_cno_t protcno;
- ssize_t n, i, ret = -1;
+ ssize_t n, ret = -1;
size_t nblocks;
__u32 reclaimable_blocks;
- struct nilfs_suinfo_update *sup;
- struct timeval tv;
if (!(params->flags & NILFS_RECLAIM_PARAM_PROTSEQ) ||
(params->flags & (~0UL << __NR_NILFS_RECLAIM_PARAMS))) {
@@ -659,8 +772,7 @@ int nilfs_xreclaim_segment(struct nilfs *nilfs,
bdescv = nilfs_vector_create(sizeof(struct nilfs_bdesc));
periodv = nilfs_vector_create(sizeof(struct nilfs_period));
vblocknrv = nilfs_vector_create(sizeof(__u64));
- supv = nilfs_vector_create(sizeof(struct nilfs_suinfo_update));
- if (!vdescv || !bdescv || !periodv || !vblocknrv || !supv)
+ if (!vdescv || !bdescv || !periodv || !vblocknrv)
goto out_vec;
sigemptyset(&sigset);
@@ -758,46 +870,27 @@ int nilfs_xreclaim_segment(struct nilfs *nilfs,
if ((params->flags & NILFS_RECLAIM_PARAM_MIN_RECLAIMABLE_BLKS) &&
nilfs_opt_test_set_suinfo(nilfs) &&
reclaimable_blocks < params->min_reclaimable_blks * n) {
- if (stat) {
- stat->deferred_segs = n;
- stat->cleaned_segs = 0;
- }
- ret = gettimeofday(&tv, NULL);
- if (ret < 0)
+ ret = nilfs_try_set_suinfo(nilfs, segnums, n, vdescv, bdescv);
+ if (ret == 0) {
+ if (stat) {
+ stat->deferred_segs = n;
+ stat->cleaned_segs = 0;
+ }
goto out_lock;
-
- for (i = 0; i < n; ++i) {
- sup = nilfs_vector_get_new_element(supv);
- if (!sup)
- goto out_lock;
-
- sup->sup_segnum = segnums[i];
- sup->sup_flags = 0;
- nilfs_suinfo_update_set_lastmod(sup);
- sup->sup_sui.sui_lastmod = tv.tv_sec;
}
- ret = nilfs_set_suinfo(nilfs, nilfs_vector_get_data(supv), n);
-
- if (ret == 0)
- goto out_lock;
-
- if (ret < 0 && errno != ENOTTY) {
+ if (ret < 0 && errno != ENOTTY && errno != EINVAL) {
nilfs_gc_logger(LOG_ERR, "cannot set suinfo: %s",
strerror(errno));
goto out_lock;
}
- /* errno == ENOTTY */
- nilfs_gc_logger(LOG_WARNING,
- "set_suinfo ioctl is not supported");
- nilfs_opt_clear_set_suinfo(nilfs);
- if (stat) {
- stat->deferred_segs = 0;
- stat->cleaned_segs = n;
- }
- /* Try nilfs_clean_segments */
+ /*
+ * errno == ENOTTY || errno == EINVAL
+ * nilfs_try_set_suinfo() failed because it is not supported
+ * so try nilfs_clean_segments() instead
+ */
}
ret = nilfs_clean_segments(nilfs,
@@ -830,7 +923,6 @@ out_vec:
nilfs_vector_destroy(bdescv);
nilfs_vector_destroy(periodv);
nilfs_vector_destroy(vblocknrv);
- nilfs_vector_destroy(supv);
/*
* Flags of valid fields in stat->exflags must be unset.
*/
--
2.3.0
--
To unsubscribe from this list: send the line "unsubscribe linux-nilfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2015-02-24 19:04 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-02-24 19:01 [PATCH 0/9] nilfs2: implementation of cost-benefit GC policy Andreas Rohner
[not found] ` <1424804504-10914-1-git-send-email-andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2015-02-24 19:01 ` [PATCH 1/9] nilfs2: refactor nilfs_sufile_updatev() Andreas Rohner
[not found] ` <1424804504-10914-2-git-send-email-andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2015-03-10 15:52 ` Ryusuke Konishi
[not found] ` <20150311.005220.1374468405510151934.konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
2015-03-10 20:40 ` Andreas Rohner
2015-02-24 19:01 ` [PATCH 2/9] nilfs2: add simple cache for modifications to SUFILE Andreas Rohner
[not found] ` <1424804504-10914-3-git-send-email-andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2015-03-14 0:45 ` Ryusuke Konishi
2015-02-24 19:01 ` [PATCH 3/9] nilfs2: extend SUFILE on-disk format to enable counting of live blocks Andreas Rohner
[not found] ` <1424804504-10914-4-git-send-email-andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2015-03-14 4:05 ` Ryusuke Konishi
2015-02-24 19:01 ` [PATCH 4/9] nilfs2: add function to modify su_nlive_blks Andreas Rohner
[not found] ` <1424804504-10914-5-git-send-email-andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2015-03-14 4:57 ` Ryusuke Konishi
2015-02-24 19:01 ` [PATCH 5/9] nilfs2: add simple tracking of block deletions and updates Andreas Rohner
[not found] ` <1424804504-10914-6-git-send-email-andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2015-03-14 3:46 ` Ryusuke Konishi
2015-02-24 19:01 ` [PATCH 6/9] nilfs2: use modification cache to improve performance Andreas Rohner
[not found] ` <1424804504-10914-7-git-send-email-andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2015-03-14 1:04 ` Ryusuke Konishi
2015-02-24 19:01 ` [PATCH 7/9] nilfs2: add additional flags for nilfs_vdesc Andreas Rohner
[not found] ` <1424804504-10914-8-git-send-email-andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2015-03-14 3:21 ` Ryusuke Konishi
2015-02-24 19:01 ` [PATCH 8/9] nilfs2: improve accuracy and correct for invalid GC values Andreas Rohner
[not found] ` <1424804504-10914-9-git-send-email-andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2015-03-14 2:50 ` Ryusuke Konishi
2015-02-24 19:01 ` [PATCH 9/9] nilfs2: prevent starvation of segments protected by snapshots Andreas Rohner
[not found] ` <1424804504-10914-10-git-send-email-andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2015-03-14 3:51 ` Ryusuke Konishi
[not found] ` <20150314.125109.1017248837083480553.konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
2015-03-14 12:36 ` Andreas Rohner
[not found] ` <55042B53.5000101-hi6Y0CQ0nG0@public.gmane.org>
2015-03-14 12:49 ` Ryusuke Konishi
2015-03-14 14:32 ` Ryusuke Konishi
2015-02-24 19:04 ` [PATCH 1/6] nilfs-utils: extend SUFILE on-disk format to enable track live blocks Andreas Rohner
[not found] ` <1424804659-10986-1-git-send-email-andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2015-02-24 19:04 ` [PATCH 2/6] nilfs-utils: add additional flags for nilfs_vdesc Andreas Rohner
2015-02-24 19:04 ` [PATCH 3/6] nilfs-utils: add support for tracking live blocks Andreas Rohner
[not found] ` <1424804659-10986-3-git-send-email-andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2015-03-14 5:52 ` Ryusuke Konishi
2015-02-24 19:04 ` Andreas Rohner [this message]
2015-02-24 19:04 ` [PATCH 5/6] nilfs-utils: add support for greedy/cost-benefit policies Andreas Rohner
2015-02-24 19:04 ` [PATCH 6/6] nilfs-utils: add su_nsnapshot_blks field to indicate starvation Andreas Rohner
2015-02-25 0:18 ` [PATCH 0/9] nilfs2: implementation of cost-benefit GC policy Ryusuke Konishi
[not found] ` <20150225.091804.1850885506186316087.konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
2015-03-10 5:21 ` Ryusuke Konishi
[not found] ` <20150310.142119.813265940569588216.konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
2015-03-10 20:37 ` Andreas Rohner
[not found] ` <54FF561E.7030409-hi6Y0CQ0nG0@public.gmane.org>
2015-03-12 12:54 ` Ryusuke Konishi
[not found] ` <20150312.215431.324210374799651841.konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
2015-03-14 12:24 ` Andreas Rohner
[not found] ` <55042879.90701-hi6Y0CQ0nG0@public.gmane.org>
2015-03-14 15:40 ` Ryusuke Konishi
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=1424804659-10986-4-git-send-email-andreas.rohner@gmx.net \
--to=andreas.rohner-hi6y0cq0ng0@public.gmane.org \
--cc=linux-nilfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).