* [PATCH v4 1/3] nilfs2: add struct nilfs_suinfo_update and flags
@ 2014-01-30 8:42 Andreas Rohner
[not found] ` <a3342d446fd05205886f48a95905ddc71c35bf44.1391071318.git.andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
0 siblings, 1 reply; 7+ messages in thread
From: Andreas Rohner @ 2014-01-30 8:42 UTC (permalink / raw)
To: linux-nilfs-u79uwXL29TY76Z2rM5mHXA; +Cc: Andreas Rohner
This patch adds the nilfs_suinfo_update structure, which contains the
information needed to update one segment usage entry. The flags
specify, which fields need to be updated.
Signed-off-by: Andreas Rohner <andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
---
include/linux/nilfs2_fs.h | 42 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/include/linux/nilfs2_fs.h b/include/linux/nilfs2_fs.h
index 9875576..2526578 100644
--- a/include/linux/nilfs2_fs.h
+++ b/include/linux/nilfs2_fs.h
@@ -710,6 +710,48 @@ static inline int nilfs_suinfo_clean(const struct nilfs_suinfo *si)
}
/* ioctl */
+/**
+ * nilfs_suinfo_update - segment usage information update
+ * @sup_segnum: segment number
+ * @sup_flags: flags for which fields are active in sup_sui
+ * @sup_reserved: reserved necessary for alignment
+ * @sup_sui: segment usage information
+ */
+struct nilfs_suinfo_update {
+ __u64 sup_segnum;
+ __u32 sup_flags;
+ __u32 sup_reserved;
+ struct nilfs_suinfo sup_sui;
+};
+
+enum {
+ NILFS_SUINFO_UPDATE_LASTMOD,
+ NILFS_SUINFO_UPDATE_NBLOCKS,
+ NILFS_SUINFO_UPDATE_FLAGS,
+ __NR_NILFS_SUINFO_UPDATE_FIELDS,
+};
+
+#define NILFS_SUINFO_UPDATE_FNS(flag, name) \
+static inline void \
+nilfs_suinfo_update_set_##name(struct nilfs_suinfo_update *sup) \
+{ \
+ sup->sup_flags |= 1UL << NILFS_SUINFO_UPDATE_##flag; \
+} \
+static inline void \
+nilfs_suinfo_update_clear_##name(struct nilfs_suinfo_update *sup) \
+{ \
+ sup->sup_flags &= ~(1UL << NILFS_SUINFO_UPDATE_##flag); \
+} \
+static inline int \
+nilfs_suinfo_update_##name(const struct nilfs_suinfo_update *sup) \
+{ \
+ return !!(sup->sup_flags & (1UL << NILFS_SUINFO_UPDATE_##flag));\
+}
+
+NILFS_SUINFO_UPDATE_FNS(LASTMOD, lastmod)
+NILFS_SUINFO_UPDATE_FNS(NBLOCKS, nblocks)
+NILFS_SUINFO_UPDATE_FNS(FLAGS, flags)
+
enum {
NILFS_CHECKPOINT,
NILFS_SNAPSHOT,
--
1.8.5.3
--
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
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v4 2/3] nilfs2: add nilfs_sufile_set_suinfo to update segment usage
[not found] ` <a3342d446fd05205886f48a95905ddc71c35bf44.1391071318.git.andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
@ 2014-01-30 8:42 ` Andreas Rohner
[not found] ` <f0bf06d2b7d39ebcca3df36567342c7f411eb657.1391071318.git.andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2014-01-30 8:42 ` [PATCH v4 3/3] nilfs2: implementation of NILFS_IOCTL_SET_SUINFO ioctl Andreas Rohner
1 sibling, 1 reply; 7+ messages in thread
From: Andreas Rohner @ 2014-01-30 8:42 UTC (permalink / raw)
To: linux-nilfs-u79uwXL29TY76Z2rM5mHXA; +Cc: Andreas Rohner
This patch introduces the nilfs_sufile_set_suinfo function, which
expects an array of nilfs_suinfo_update structures and updates the
segment usage information accordingly.
This is basically a helper function for the newly introduced
NILFS_IOCTL_SET_SUINFO ioctl.
Signed-off-by: Andreas Rohner <andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
---
fs/nilfs2/sufile.c | 131 +++++++++++++++++++++++++++++++++++++++++++++++++++++
fs/nilfs2/sufile.h | 1 +
2 files changed, 132 insertions(+)
diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c
index 3127e9f..5ad5d4c 100644
--- a/fs/nilfs2/sufile.c
+++ b/fs/nilfs2/sufile.c
@@ -870,6 +870,137 @@ ssize_t nilfs_sufile_get_suinfo(struct inode *sufile, __u64 segnum, void *buf,
}
/**
+ * nilfs_sufile_set_suinfo - sets segment usage info
+ * @sufile: inode of segment usage file
+ * @buf: array of suinfo_update
+ * @supsz: byte size of suinfo_update
+ * @nsup: size of suinfo_update array
+ *
+ * Description: Takes an array of nilfs_suinfo_update structs and updates
+ * segment usage accordingly. Only the fields indicated by the sup_flags
+ * are updated.
+ *
+ * Return Value: On success, 0 is returned. On error, one of the
+ * following negative error codes is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ *
+ * %-EINVAL - Invalid values in input (segment number, flags or nblocks)
+ */
+ssize_t nilfs_sufile_set_suinfo(struct inode *sufile, void *buf,
+ unsigned supsz, size_t nsup)
+{
+ struct the_nilfs *nilfs = sufile->i_sb->s_fs_info;
+ struct buffer_head *header_bh, *bh;
+ struct nilfs_suinfo_update *sup, *supend = buf + supsz * nsup;
+ struct nilfs_segment_usage *su;
+ void *kaddr;
+ unsigned long blkoff, prev_blkoff;
+ int cleansi, cleansu, dirtysi, dirtysu;
+ unsigned long ncleaned = 0, ndirtied = 0;
+ int ret = 0;
+
+ if (unlikely(nsup == 0))
+ return ret;
+
+ for (sup = buf; sup < supend; sup = (void *)sup + supsz) {
+ if (sup->sup_segnum >= nilfs->ns_nsegments
+ || (sup->sup_flags &
+ (~0UL << __NR_NILFS_SUINFO_UPDATE_FIELDS))
+ || (nilfs_suinfo_update_nblocks(sup) &&
+ sup->sup_sui.sui_nblocks >
+ nilfs->ns_blocks_per_segment))
+ return -EINVAL;
+ }
+
+ down_write(&NILFS_MDT(sufile)->mi_sem);
+
+ ret = nilfs_sufile_get_header_block(sufile, &header_bh);
+ if (ret < 0)
+ goto out_sem;
+
+ sup = buf;
+ blkoff = nilfs_sufile_get_blkoff(sufile, sup->sup_segnum);
+ ret = nilfs_mdt_get_block(sufile, blkoff, 1, NULL, &bh);
+ if (ret < 0)
+ goto out_header;
+
+ for (;;) {
+ kaddr = kmap_atomic(bh->b_page);
+ su = nilfs_sufile_block_get_segment_usage(
+ sufile, sup->sup_segnum, bh, kaddr);
+
+ if (nilfs_suinfo_update_lastmod(sup))
+ su->su_lastmod = cpu_to_le64(sup->sup_sui.sui_lastmod);
+
+ if (nilfs_suinfo_update_nblocks(sup))
+ su->su_nblocks = cpu_to_le32(sup->sup_sui.sui_nblocks);
+
+ if (nilfs_suinfo_update_flags(sup)) {
+ /*
+ * Active flag is a virtual flag projected by running
+ * nilfs kernel code - drop it not to write it to
+ * disk.
+ */
+ sup->sup_sui.sui_flags &=
+ ~(1UL << NILFS_SEGMENT_USAGE_ACTIVE);
+
+ cleansi = nilfs_suinfo_clean(&sup->sup_sui);
+ cleansu = nilfs_segment_usage_clean(su);
+ dirtysi = nilfs_suinfo_dirty(&sup->sup_sui);
+ dirtysu = nilfs_segment_usage_dirty(su);
+
+ if (cleansi && !cleansu)
+ ++ncleaned;
+ else if (!cleansi && cleansu)
+ --ncleaned;
+
+ if (dirtysi && !dirtysu)
+ ++ndirtied;
+ else if (!dirtysi && dirtysu)
+ --ndirtied;
+
+ su->su_flags = cpu_to_le32(sup->sup_sui.sui_flags);
+ }
+
+ kunmap_atomic(kaddr);
+
+ sup = (void *)sup + supsz;
+ if (sup >= supend)
+ break;
+
+ prev_blkoff = blkoff;
+ blkoff = nilfs_sufile_get_blkoff(sufile, sup->sup_segnum);
+ if (blkoff == prev_blkoff)
+ continue;
+
+ /* get different block */
+ mark_buffer_dirty(bh);
+ brelse(bh);
+ ret = nilfs_mdt_get_block(sufile, blkoff, 1, NULL, &bh);
+ if (unlikely(ret < 0))
+ goto out_mark;
+ }
+ mark_buffer_dirty(bh);
+ brelse(bh);
+
+ out_mark:
+ if (ncleaned || ndirtied) {
+ nilfs_sufile_mod_counter(header_bh, (u64)(long)ncleaned,
+ (u64)(long)ndirtied);
+ NILFS_SUI(sufile)->ncleansegs += ncleaned;
+ }
+ nilfs_mdt_mark_dirty(sufile);
+ out_header:
+ brelse(header_bh);
+ out_sem:
+ up_write(&NILFS_MDT(sufile)->mi_sem);
+ return ret;
+}
+
+/**
* nilfs_sufile_read - read or get sufile inode
* @sb: super block instance
* @susize: size of a segment usage entry
diff --git a/fs/nilfs2/sufile.h b/fs/nilfs2/sufile.h
index e84bc5b..366003c 100644
--- a/fs/nilfs2/sufile.h
+++ b/fs/nilfs2/sufile.h
@@ -44,6 +44,7 @@ int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum,
int nilfs_sufile_get_stat(struct inode *, struct nilfs_sustat *);
ssize_t nilfs_sufile_get_suinfo(struct inode *, __u64, void *, unsigned,
size_t);
+ssize_t nilfs_sufile_set_suinfo(struct inode *, void *, unsigned , size_t);
int nilfs_sufile_updatev(struct inode *, __u64 *, size_t, int, size_t *,
void (*dofunc)(struct inode *, __u64,
--
1.8.5.3
--
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
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v4 3/3] nilfs2: implementation of NILFS_IOCTL_SET_SUINFO ioctl
[not found] ` <a3342d446fd05205886f48a95905ddc71c35bf44.1391071318.git.andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2014-01-30 8:42 ` [PATCH v4 2/3] nilfs2: add nilfs_sufile_set_suinfo to update segment usage Andreas Rohner
@ 2014-01-30 8:42 ` Andreas Rohner
[not found] ` <2e3c9382057dac0835fa45176ccb9f0db9ccc9a8.1391071318.git.andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
1 sibling, 1 reply; 7+ messages in thread
From: Andreas Rohner @ 2014-01-30 8:42 UTC (permalink / raw)
To: linux-nilfs-u79uwXL29TY76Z2rM5mHXA; +Cc: Andreas Rohner
With this ioctl the segment usage entries in the SUFILE can be
updated from userspace.
This is useful, because it allows the userspace GC to modify and update
segment usage entries for specific segments, which enables it to avoid
unnecessary write operations.
If a segment needs to be cleaned, but there is no or very little
reclaimable space in it, the cleaning operation basically degrades to
a useless moving operation. In the end the only thing that changes is
the location of the data and a timestamp in the segment usage
information. With this ioctl the GC can skip the cleaning and update
the segment usage entries directly instead.
This is basically a shortcut to cleaning the segment. It is still
necessary to read the segment summary information, but the writing of
the live blocks can be skipped if it's not worth it.
Signed-off-by: Andreas Rohner <andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
---
fs/nilfs2/ioctl.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++
include/linux/nilfs2_fs.h | 2 ++
2 files changed, 94 insertions(+)
diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c
index 2b34021..c19a231 100644
--- a/fs/nilfs2/ioctl.c
+++ b/fs/nilfs2/ioctl.c
@@ -1163,6 +1163,95 @@ static int nilfs_ioctl_get_info(struct inode *inode, struct file *filp,
return ret;
}
+/**
+ * nilfs_ioctl_set_suinfo - set segment usage info
+ * @inode: inode object
+ * @filp: file object
+ * @cmd: ioctl's request code
+ * @argp: pointer on argument from userspace
+ *
+ * Description: Expects an array of nilfs_suinfo_update structures
+ * encapsulated in nilfs_argv and updates the segment usage info
+ * according to the flags in nilfs_suinfo_update.
+ *
+ * Return Value: On success, 0 is returned. On error, one of the
+ * following negative error codes is returned.
+ *
+ * %-EPERM - Not enough permissions
+ *
+ * %-EFAULT - Error copying input data
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ *
+ * %-EINVAL - Invalid values in input (segment number, flags or nblocks)
+ */
+static int nilfs_ioctl_set_suinfo(struct inode *inode, struct file *filp,
+ unsigned int cmd, void __user *argp)
+{
+ struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
+ struct nilfs_transaction_info ti;
+ struct nilfs_argv argv;
+ size_t len;
+ void __user *base;
+ void *kbuf;
+ int ret;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ ret = mnt_want_write_file(filp);
+ if (ret)
+ return ret;
+
+ ret = -EFAULT;
+ if (copy_from_user(&argv, argp, sizeof(argv)))
+ goto out;
+
+ ret = -EINVAL;
+ if (argv.v_size < sizeof(struct nilfs_suinfo_update))
+ goto out;
+
+ if (argv.v_nmembs > nilfs->ns_nsegments)
+ goto out;
+
+ if (argv.v_nmembs >= UINT_MAX / argv.v_size)
+ goto out;
+
+ len = argv.v_size * argv.v_nmembs;
+ if (!len) {
+ ret = 0;
+ goto out;
+ }
+
+ base = (void __user *)(unsigned long)argv.v_base;
+ kbuf = vmalloc(len);
+ if (!kbuf) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ if (copy_from_user(kbuf, base, len)) {
+ ret = -EFAULT;
+ goto out_free;
+ }
+
+ nilfs_transaction_begin(inode->i_sb, &ti, 0);
+ ret = nilfs_sufile_set_suinfo(nilfs->ns_sufile, kbuf, argv.v_size,
+ argv.v_nmembs);
+ if (unlikely(ret < 0))
+ nilfs_transaction_abort(inode->i_sb);
+ else
+ nilfs_transaction_commit(inode->i_sb); /* never fails */
+
+out_free:
+ vfree(kbuf);
+out:
+ mnt_drop_write_file(filp);
+ return ret;
+}
+
long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
struct inode *inode = file_inode(filp);
@@ -1189,6 +1278,8 @@ long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
return nilfs_ioctl_get_info(inode, filp, cmd, argp,
sizeof(struct nilfs_suinfo),
nilfs_ioctl_do_get_suinfo);
+ case NILFS_IOCTL_SET_SUINFO:
+ return nilfs_ioctl_set_suinfo(inode, filp, cmd, argp);
case NILFS_IOCTL_GET_SUSTAT:
return nilfs_ioctl_get_sustat(inode, filp, cmd, argp);
case NILFS_IOCTL_GET_VINFO:
@@ -1228,6 +1319,7 @@ long nilfs_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
case NILFS_IOCTL_GET_CPINFO:
case NILFS_IOCTL_GET_CPSTAT:
case NILFS_IOCTL_GET_SUINFO:
+ case NILFS_IOCTL_SET_SUINFO:
case NILFS_IOCTL_GET_SUSTAT:
case NILFS_IOCTL_GET_VINFO:
case NILFS_IOCTL_GET_BDESCS:
diff --git a/include/linux/nilfs2_fs.h b/include/linux/nilfs2_fs.h
index 2526578..1fb465f 100644
--- a/include/linux/nilfs2_fs.h
+++ b/include/linux/nilfs2_fs.h
@@ -905,5 +905,7 @@ struct nilfs_bdesc {
_IOW(NILFS_IOCTL_IDENT, 0x8B, __u64)
#define NILFS_IOCTL_SET_ALLOC_RANGE \
_IOW(NILFS_IOCTL_IDENT, 0x8C, __u64[2])
+#define NILFS_IOCTL_SET_SUINFO \
+ _IOW(NILFS_IOCTL_IDENT, 0x8D, struct nilfs_argv)
#endif /* _LINUX_NILFS_FS_H */
--
1.8.5.3
--
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
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v4 2/3] nilfs2: add nilfs_sufile_set_suinfo to update segment usage
[not found] ` <f0bf06d2b7d39ebcca3df36567342c7f411eb657.1391071318.git.andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
@ 2014-01-31 8:58 ` Ryusuke Konishi
[not found] ` <20140131.175825.168035651.konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
0 siblings, 1 reply; 7+ messages in thread
From: Ryusuke Konishi @ 2014-01-31 8:58 UTC (permalink / raw)
To: Andreas Rohner; +Cc: linux-nilfs-u79uwXL29TY76Z2rM5mHXA
Hi Andreas,
On Thu, 30 Jan 2014 09:42:49 +0100, Andreas Rohner wrote:
> This patch introduces the nilfs_sufile_set_suinfo function, which
> expects an array of nilfs_suinfo_update structures and updates the
> segment usage information accordingly.
>
> This is basically a helper function for the newly introduced
> NILFS_IOCTL_SET_SUINFO ioctl.
>
> Signed-off-by: Andreas Rohner <andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
> ---
> fs/nilfs2/sufile.c | 131 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> fs/nilfs2/sufile.h | 1 +
> 2 files changed, 132 insertions(+)
>
> diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c
> index 3127e9f..5ad5d4c 100644
> --- a/fs/nilfs2/sufile.c
> +++ b/fs/nilfs2/sufile.c
> @@ -870,6 +870,137 @@ ssize_t nilfs_sufile_get_suinfo(struct inode *sufile, __u64 segnum, void *buf,
> }
>
> /**
> + * nilfs_sufile_set_suinfo - sets segment usage info
> + * @sufile: inode of segment usage file
> + * @buf: array of suinfo_update
> + * @supsz: byte size of suinfo_update
> + * @nsup: size of suinfo_update array
> + *
> + * Description: Takes an array of nilfs_suinfo_update structs and updates
> + * segment usage accordingly. Only the fields indicated by the sup_flags
> + * are updated.
> + *
> + * Return Value: On success, 0 is returned. On error, one of the
> + * following negative error codes is returned.
> + *
> + * %-EIO - I/O error.
> + *
> + * %-ENOMEM - Insufficient amount of memory available.
> + *
> + * %-EINVAL - Invalid values in input (segment number, flags or nblocks)
> + */
> +ssize_t nilfs_sufile_set_suinfo(struct inode *sufile, void *buf,
> + unsigned supsz, size_t nsup)
> +{
> + struct the_nilfs *nilfs = sufile->i_sb->s_fs_info;
> + struct buffer_head *header_bh, *bh;
> + struct nilfs_suinfo_update *sup, *supend = buf + supsz * nsup;
> + struct nilfs_segment_usage *su;
> + void *kaddr;
> + unsigned long blkoff, prev_blkoff;
> + int cleansi, cleansu, dirtysi, dirtysu;
> + unsigned long ncleaned = 0, ndirtied = 0;
> + int ret = 0;
> +
> + if (unlikely(nsup == 0))
> + return ret;
> +
> + for (sup = buf; sup < supend; sup = (void *)sup + supsz) {
> + if (sup->sup_segnum >= nilfs->ns_nsegments
> + || (sup->sup_flags &
> + (~0UL << __NR_NILFS_SUINFO_UPDATE_FIELDS))
> + || (nilfs_suinfo_update_nblocks(sup) &&
> + sup->sup_sui.sui_nblocks >
> + nilfs->ns_blocks_per_segment))
> + return -EINVAL;
> + }
> +
> + down_write(&NILFS_MDT(sufile)->mi_sem);
> +
> + ret = nilfs_sufile_get_header_block(sufile, &header_bh);
> + if (ret < 0)
> + goto out_sem;
> +
> + sup = buf;
> + blkoff = nilfs_sufile_get_blkoff(sufile, sup->sup_segnum);
> + ret = nilfs_mdt_get_block(sufile, blkoff, 1, NULL, &bh);
> + if (ret < 0)
> + goto out_header;
> +
> + for (;;) {
> + kaddr = kmap_atomic(bh->b_page);
> + su = nilfs_sufile_block_get_segment_usage(
> + sufile, sup->sup_segnum, bh, kaddr);
> +
> + if (nilfs_suinfo_update_lastmod(sup))
> + su->su_lastmod = cpu_to_le64(sup->sup_sui.sui_lastmod);
> +
> + if (nilfs_suinfo_update_nblocks(sup))
> + su->su_nblocks = cpu_to_le32(sup->sup_sui.sui_nblocks);
> +
> + if (nilfs_suinfo_update_flags(sup)) {
> + /*
> + * Active flag is a virtual flag projected by running
> + * nilfs kernel code - drop it not to write it to
> + * disk.
> + */
> + sup->sup_sui.sui_flags &=
> + ~(1UL << NILFS_SEGMENT_USAGE_ACTIVE);
> +
> + cleansi = nilfs_suinfo_clean(&sup->sup_sui);
> + cleansu = nilfs_segment_usage_clean(su);
> + dirtysi = nilfs_suinfo_dirty(&sup->sup_sui);
> + dirtysu = nilfs_segment_usage_dirty(su);
> +
> + if (cleansi && !cleansu)
> + ++ncleaned;
> + else if (!cleansi && cleansu)
> + --ncleaned;
> +
> + if (dirtysi && !dirtysu)
> + ++ndirtied;
> + else if (!dirtysi && dirtysu)
> + --ndirtied;
> +
> + su->su_flags = cpu_to_le32(sup->sup_sui.sui_flags);
> + }
> +
> + kunmap_atomic(kaddr);
> +
> + sup = (void *)sup + supsz;
> + if (sup >= supend)
> + break;
> +
> + prev_blkoff = blkoff;
> + blkoff = nilfs_sufile_get_blkoff(sufile, sup->sup_segnum);
> + if (blkoff == prev_blkoff)
> + continue;
> +
> + /* get different block */
> + mark_buffer_dirty(bh);
> + brelse(bh);
> + ret = nilfs_mdt_get_block(sufile, blkoff, 1, NULL, &bh);
> + if (unlikely(ret < 0))
> + goto out_mark;
> + }
> + mark_buffer_dirty(bh);
> + brelse(bh);
> +
> + out_mark:
> + if (ncleaned || ndirtied) {
> + nilfs_sufile_mod_counter(header_bh, (u64)(long)ncleaned,
> + (u64)(long)ndirtied);
May I change the type of ncleaned and ndirtied to "long" ?
Other looks OK to me.
Thanks,
Ryusuke Konishi
> + NILFS_SUI(sufile)->ncleansegs += ncleaned;
> + }
> + nilfs_mdt_mark_dirty(sufile);
> + out_header:
> + brelse(header_bh);
> + out_sem:
> + up_write(&NILFS_MDT(sufile)->mi_sem);
> + return ret;
> +}
> +
> +/**
> * nilfs_sufile_read - read or get sufile inode
> * @sb: super block instance
> * @susize: size of a segment usage entry
> diff --git a/fs/nilfs2/sufile.h b/fs/nilfs2/sufile.h
> index e84bc5b..366003c 100644
> --- a/fs/nilfs2/sufile.h
> +++ b/fs/nilfs2/sufile.h
> @@ -44,6 +44,7 @@ int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum,
> int nilfs_sufile_get_stat(struct inode *, struct nilfs_sustat *);
> ssize_t nilfs_sufile_get_suinfo(struct inode *, __u64, void *, unsigned,
> size_t);
> +ssize_t nilfs_sufile_set_suinfo(struct inode *, void *, unsigned , size_t);
>
> int nilfs_sufile_updatev(struct inode *, __u64 *, size_t, int, size_t *,
> void (*dofunc)(struct inode *, __u64,
> --
> 1.8.5.3
>
> --
> 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
--
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
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v4 3/3] nilfs2: implementation of NILFS_IOCTL_SET_SUINFO ioctl
[not found] ` <2e3c9382057dac0835fa45176ccb9f0db9ccc9a8.1391071318.git.andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
@ 2014-01-31 9:01 ` Ryusuke Konishi
0 siblings, 0 replies; 7+ messages in thread
From: Ryusuke Konishi @ 2014-01-31 9:01 UTC (permalink / raw)
To: Andreas Rohner; +Cc: linux-nilfs-u79uwXL29TY76Z2rM5mHXA
On Thu, 30 Jan 2014 09:42:50 +0100, Andreas Rohner wrote:
> With this ioctl the segment usage entries in the SUFILE can be
> updated from userspace.
>
> This is useful, because it allows the userspace GC to modify and update
> segment usage entries for specific segments, which enables it to avoid
> unnecessary write operations.
>
> If a segment needs to be cleaned, but there is no or very little
> reclaimable space in it, the cleaning operation basically degrades to
> a useless moving operation. In the end the only thing that changes is
> the location of the data and a timestamp in the segment usage
> information. With this ioctl the GC can skip the cleaning and update
> the segment usage entries directly instead.
>
> This is basically a shortcut to cleaning the segment. It is still
> necessary to read the segment summary information, but the writing of
> the live blocks can be skipped if it's not worth it.
>
> Signed-off-by: Andreas Rohner <andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
> ---
> fs/nilfs2/ioctl.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++
> include/linux/nilfs2_fs.h | 2 ++
> 2 files changed, 94 insertions(+)
>
> diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c
> index 2b34021..c19a231 100644
> --- a/fs/nilfs2/ioctl.c
> +++ b/fs/nilfs2/ioctl.c
> @@ -1163,6 +1163,95 @@ static int nilfs_ioctl_get_info(struct inode *inode, struct file *filp,
> return ret;
> }
>
> +/**
> + * nilfs_ioctl_set_suinfo - set segment usage info
> + * @inode: inode object
> + * @filp: file object
> + * @cmd: ioctl's request code
> + * @argp: pointer on argument from userspace
> + *
> + * Description: Expects an array of nilfs_suinfo_update structures
> + * encapsulated in nilfs_argv and updates the segment usage info
> + * according to the flags in nilfs_suinfo_update.
> + *
> + * Return Value: On success, 0 is returned. On error, one of the
> + * following negative error codes is returned.
> + *
> + * %-EPERM - Not enough permissions
> + *
> + * %-EFAULT - Error copying input data
> + *
> + * %-EIO - I/O error.
> + *
> + * %-ENOMEM - Insufficient amount of memory available.
> + *
> + * %-EINVAL - Invalid values in input (segment number, flags or nblocks)
> + */
> +static int nilfs_ioctl_set_suinfo(struct inode *inode, struct file *filp,
> + unsigned int cmd, void __user *argp)
> +{
> + struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
> + struct nilfs_transaction_info ti;
> + struct nilfs_argv argv;
> + size_t len;
> + void __user *base;
> + void *kbuf;
> + int ret;
> +
> + if (!capable(CAP_SYS_ADMIN))
> + return -EPERM;
> +
> + ret = mnt_want_write_file(filp);
> + if (ret)
> + return ret;
> +
> + ret = -EFAULT;
> + if (copy_from_user(&argv, argp, sizeof(argv)))
> + goto out;
> +
> + ret = -EINVAL;
> + if (argv.v_size < sizeof(struct nilfs_suinfo_update))
> + goto out;
> +
> + if (argv.v_nmembs > nilfs->ns_nsegments)
> + goto out;
> +
> + if (argv.v_nmembs >= UINT_MAX / argv.v_size)
> + goto out;
> +
> + len = argv.v_size * argv.v_nmembs;
> + if (!len) {
> + ret = 0;
> + goto out;
> + }
> +
> + base = (void __user *)(unsigned long)argv.v_base;
> + kbuf = vmalloc(len);
> + if (!kbuf) {
> + ret = -ENOMEM;
> + goto out;
> + }
> +
> + if (copy_from_user(kbuf, base, len)) {
> + ret = -EFAULT;
> + goto out_free;
> + }
> +
> + nilfs_transaction_begin(inode->i_sb, &ti, 0);
> + ret = nilfs_sufile_set_suinfo(nilfs->ns_sufile, kbuf, argv.v_size,
> + argv.v_nmembs);
> + if (unlikely(ret < 0))
> + nilfs_transaction_abort(inode->i_sb);
> + else
> + nilfs_transaction_commit(inode->i_sb); /* never fails */
> +
> +out_free:
> + vfree(kbuf);
> +out:
> + mnt_drop_write_file(filp);
> + return ret;
> +}
> +
> long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
> {
> struct inode *inode = file_inode(filp);
> @@ -1189,6 +1278,8 @@ long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
> return nilfs_ioctl_get_info(inode, filp, cmd, argp,
> sizeof(struct nilfs_suinfo),
> nilfs_ioctl_do_get_suinfo);
> + case NILFS_IOCTL_SET_SUINFO:
> + return nilfs_ioctl_set_suinfo(inode, filp, cmd, argp);
> case NILFS_IOCTL_GET_SUSTAT:
> return nilfs_ioctl_get_sustat(inode, filp, cmd, argp);
> case NILFS_IOCTL_GET_VINFO:
> @@ -1228,6 +1319,7 @@ long nilfs_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
> case NILFS_IOCTL_GET_CPINFO:
> case NILFS_IOCTL_GET_CPSTAT:
> case NILFS_IOCTL_GET_SUINFO:
> + case NILFS_IOCTL_SET_SUINFO:
> case NILFS_IOCTL_GET_SUSTAT:
> case NILFS_IOCTL_GET_VINFO:
> case NILFS_IOCTL_GET_BDESCS:
> diff --git a/include/linux/nilfs2_fs.h b/include/linux/nilfs2_fs.h
> index 2526578..1fb465f 100644
> --- a/include/linux/nilfs2_fs.h
> +++ b/include/linux/nilfs2_fs.h
> @@ -905,5 +905,7 @@ struct nilfs_bdesc {
> _IOW(NILFS_IOCTL_IDENT, 0x8B, __u64)
> #define NILFS_IOCTL_SET_ALLOC_RANGE \
> _IOW(NILFS_IOCTL_IDENT, 0x8C, __u64[2])
> +#define NILFS_IOCTL_SET_SUINFO \
> + _IOW(NILFS_IOCTL_IDENT, 0x8D, struct nilfs_argv)
>
> #endif /* _LINUX_NILFS_FS_H */
> --
> 1.8.5.3
Looks OK to me.
> --
> 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
--
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
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v4 2/3] nilfs2: add nilfs_sufile_set_suinfo to update segment usage
[not found] ` <20140131.175825.168035651.konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
@ 2014-01-31 10:14 ` Andreas Rohner
[not found] ` <52EB7795.6020407-hi6Y0CQ0nG0@public.gmane.org>
0 siblings, 1 reply; 7+ messages in thread
From: Andreas Rohner @ 2014-01-31 10:14 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: linux-nilfs-u79uwXL29TY76Z2rM5mHXA
On 2014-01-31 09:58, Ryusuke Konishi wrote:
> Hi Andreas,
> On Thu, 30 Jan 2014 09:42:49 +0100, Andreas Rohner wrote:
>> This patch introduces the nilfs_sufile_set_suinfo function, which
>> expects an array of nilfs_suinfo_update structures and updates the
>> segment usage information accordingly.
>>
>> This is basically a helper function for the newly introduced
>> NILFS_IOCTL_SET_SUINFO ioctl.
>>
>> Signed-off-by: Andreas Rohner <andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
>> ---
>> fs/nilfs2/sufile.c | 131 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>> fs/nilfs2/sufile.h | 1 +
>> 2 files changed, 132 insertions(+)
>>
>> diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c
>> index 3127e9f..5ad5d4c 100644
>> --- a/fs/nilfs2/sufile.c
>> +++ b/fs/nilfs2/sufile.c
>> @@ -870,6 +870,137 @@ ssize_t nilfs_sufile_get_suinfo(struct inode *sufile, __u64 segnum, void *buf,
>> }
>>
>> /**
>> + * nilfs_sufile_set_suinfo - sets segment usage info
>> + * @sufile: inode of segment usage file
>> + * @buf: array of suinfo_update
>> + * @supsz: byte size of suinfo_update
>> + * @nsup: size of suinfo_update array
>> + *
>> + * Description: Takes an array of nilfs_suinfo_update structs and updates
>> + * segment usage accordingly. Only the fields indicated by the sup_flags
>> + * are updated.
>> + *
>> + * Return Value: On success, 0 is returned. On error, one of the
>> + * following negative error codes is returned.
>> + *
>> + * %-EIO - I/O error.
>> + *
>> + * %-ENOMEM - Insufficient amount of memory available.
>> + *
>> + * %-EINVAL - Invalid values in input (segment number, flags or nblocks)
>> + */
>> +ssize_t nilfs_sufile_set_suinfo(struct inode *sufile, void *buf,
>> + unsigned supsz, size_t nsup)
>> +{
>> + struct the_nilfs *nilfs = sufile->i_sb->s_fs_info;
>> + struct buffer_head *header_bh, *bh;
>> + struct nilfs_suinfo_update *sup, *supend = buf + supsz * nsup;
>> + struct nilfs_segment_usage *su;
>> + void *kaddr;
>> + unsigned long blkoff, prev_blkoff;
>> + int cleansi, cleansu, dirtysi, dirtysu;
>> + unsigned long ncleaned = 0, ndirtied = 0;
>> + int ret = 0;
>> +
>> + if (unlikely(nsup == 0))
>> + return ret;
>> +
>> + for (sup = buf; sup < supend; sup = (void *)sup + supsz) {
>> + if (sup->sup_segnum >= nilfs->ns_nsegments
>> + || (sup->sup_flags &
>> + (~0UL << __NR_NILFS_SUINFO_UPDATE_FIELDS))
>> + || (nilfs_suinfo_update_nblocks(sup) &&
>> + sup->sup_sui.sui_nblocks >
>> + nilfs->ns_blocks_per_segment))
>> + return -EINVAL;
>> + }
>> +
>> + down_write(&NILFS_MDT(sufile)->mi_sem);
>> +
>> + ret = nilfs_sufile_get_header_block(sufile, &header_bh);
>> + if (ret < 0)
>> + goto out_sem;
>> +
>> + sup = buf;
>> + blkoff = nilfs_sufile_get_blkoff(sufile, sup->sup_segnum);
>> + ret = nilfs_mdt_get_block(sufile, blkoff, 1, NULL, &bh);
>> + if (ret < 0)
>> + goto out_header;
>> +
>> + for (;;) {
>> + kaddr = kmap_atomic(bh->b_page);
>> + su = nilfs_sufile_block_get_segment_usage(
>> + sufile, sup->sup_segnum, bh, kaddr);
>> +
>> + if (nilfs_suinfo_update_lastmod(sup))
>> + su->su_lastmod = cpu_to_le64(sup->sup_sui.sui_lastmod);
>> +
>> + if (nilfs_suinfo_update_nblocks(sup))
>> + su->su_nblocks = cpu_to_le32(sup->sup_sui.sui_nblocks);
>> +
>> + if (nilfs_suinfo_update_flags(sup)) {
>> + /*
>> + * Active flag is a virtual flag projected by running
>> + * nilfs kernel code - drop it not to write it to
>> + * disk.
>> + */
>> + sup->sup_sui.sui_flags &=
>> + ~(1UL << NILFS_SEGMENT_USAGE_ACTIVE);
>> +
>> + cleansi = nilfs_suinfo_clean(&sup->sup_sui);
>> + cleansu = nilfs_segment_usage_clean(su);
>> + dirtysi = nilfs_suinfo_dirty(&sup->sup_sui);
>> + dirtysu = nilfs_segment_usage_dirty(su);
>> +
>> + if (cleansi && !cleansu)
>> + ++ncleaned;
>> + else if (!cleansi && cleansu)
>> + --ncleaned;
>> +
>> + if (dirtysi && !dirtysu)
>> + ++ndirtied;
>> + else if (!dirtysi && dirtysu)
>> + --ndirtied;
>> +
>> + su->su_flags = cpu_to_le32(sup->sup_sui.sui_flags);
>> + }
>> +
>> + kunmap_atomic(kaddr);
>> +
>> + sup = (void *)sup + supsz;
>> + if (sup >= supend)
>> + break;
>> +
>> + prev_blkoff = blkoff;
>> + blkoff = nilfs_sufile_get_blkoff(sufile, sup->sup_segnum);
>> + if (blkoff == prev_blkoff)
>> + continue;
>> +
>> + /* get different block */
>> + mark_buffer_dirty(bh);
>> + brelse(bh);
>> + ret = nilfs_mdt_get_block(sufile, blkoff, 1, NULL, &bh);
>> + if (unlikely(ret < 0))
>> + goto out_mark;
>> + }
>> + mark_buffer_dirty(bh);
>> + brelse(bh);
>> +
>> + out_mark:
>> + if (ncleaned || ndirtied) {
>> + nilfs_sufile_mod_counter(header_bh, (u64)(long)ncleaned,
>> + (u64)(long)ndirtied);
>
> May I change the type of ncleaned and ndirtied to "long" ?
Sure. Sorry, I misunderstood your last mail on that. I thought you
preferred unsigned long and suggested the arithmetic cast to u64. Shall
I send in a corrected version of the patches?
> Other looks OK to me.
Cool, Thanks.
Best regards,
Andreas Rohner
> Thanks,
> Ryusuke Konishi
>
>> + NILFS_SUI(sufile)->ncleansegs += ncleaned;
>> + }
>> + nilfs_mdt_mark_dirty(sufile);
>> + out_header:
>> + brelse(header_bh);
>> + out_sem:
>> + up_write(&NILFS_MDT(sufile)->mi_sem);
>> + return ret;
>> +}
>> +
>> +/**
>> * nilfs_sufile_read - read or get sufile inode
>> * @sb: super block instance
>> * @susize: size of a segment usage entry
>> diff --git a/fs/nilfs2/sufile.h b/fs/nilfs2/sufile.h
>> index e84bc5b..366003c 100644
>> --- a/fs/nilfs2/sufile.h
>> +++ b/fs/nilfs2/sufile.h
>> @@ -44,6 +44,7 @@ int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum,
>> int nilfs_sufile_get_stat(struct inode *, struct nilfs_sustat *);
>> ssize_t nilfs_sufile_get_suinfo(struct inode *, __u64, void *, unsigned,
>> size_t);
>> +ssize_t nilfs_sufile_set_suinfo(struct inode *, void *, unsigned , size_t);
>>
>> int nilfs_sufile_updatev(struct inode *, __u64 *, size_t, int, size_t *,
>> void (*dofunc)(struct inode *, __u64,
>> --
>> 1.8.5.3
>>
>> --
>> 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
>
--
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
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v4 2/3] nilfs2: add nilfs_sufile_set_suinfo to update segment usage
[not found] ` <52EB7795.6020407-hi6Y0CQ0nG0@public.gmane.org>
@ 2014-01-31 10:25 ` Ryusuke Konishi
0 siblings, 0 replies; 7+ messages in thread
From: Ryusuke Konishi @ 2014-01-31 10:25 UTC (permalink / raw)
To: Andreas Rohner; +Cc: linux-nilfs-u79uwXL29TY76Z2rM5mHXA
On Fri, 31 Jan 2014 11:14:45 +0100, Andreas Rohner wrote:
> On 2014-01-31 09:58, Ryusuke Konishi wrote:
>> Hi Andreas,
>> On Thu, 30 Jan 2014 09:42:49 +0100, Andreas Rohner wrote:
>>> This patch introduces the nilfs_sufile_set_suinfo function, which
>>> expects an array of nilfs_suinfo_update structures and updates the
>>> segment usage information accordingly.
>>>
>>> This is basically a helper function for the newly introduced
>>> NILFS_IOCTL_SET_SUINFO ioctl.
>>>
>>> Signed-off-by: Andreas Rohner <andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
>>> ---
>>> fs/nilfs2/sufile.c | 131 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>>> fs/nilfs2/sufile.h | 1 +
>>> 2 files changed, 132 insertions(+)
>>>
>>> diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c
>>> index 3127e9f..5ad5d4c 100644
>>> --- a/fs/nilfs2/sufile.c
>>> +++ b/fs/nilfs2/sufile.c
>>> @@ -870,6 +870,137 @@ ssize_t nilfs_sufile_get_suinfo(struct inode *sufile, __u64 segnum, void *buf,
>>> }
>>>
>>> /**
>>> + * nilfs_sufile_set_suinfo - sets segment usage info
>>> + * @sufile: inode of segment usage file
>>> + * @buf: array of suinfo_update
>>> + * @supsz: byte size of suinfo_update
>>> + * @nsup: size of suinfo_update array
>>> + *
>>> + * Description: Takes an array of nilfs_suinfo_update structs and updates
>>> + * segment usage accordingly. Only the fields indicated by the sup_flags
>>> + * are updated.
>>> + *
>>> + * Return Value: On success, 0 is returned. On error, one of the
>>> + * following negative error codes is returned.
>>> + *
>>> + * %-EIO - I/O error.
>>> + *
>>> + * %-ENOMEM - Insufficient amount of memory available.
>>> + *
>>> + * %-EINVAL - Invalid values in input (segment number, flags or nblocks)
>>> + */
>>> +ssize_t nilfs_sufile_set_suinfo(struct inode *sufile, void *buf,
>>> + unsigned supsz, size_t nsup)
>>> +{
>>> + struct the_nilfs *nilfs = sufile->i_sb->s_fs_info;
>>> + struct buffer_head *header_bh, *bh;
>>> + struct nilfs_suinfo_update *sup, *supend = buf + supsz * nsup;
>>> + struct nilfs_segment_usage *su;
>>> + void *kaddr;
>>> + unsigned long blkoff, prev_blkoff;
>>> + int cleansi, cleansu, dirtysi, dirtysu;
>>> + unsigned long ncleaned = 0, ndirtied = 0;
>>> + int ret = 0;
>>> +
>>> + if (unlikely(nsup == 0))
>>> + return ret;
>>> +
>>> + for (sup = buf; sup < supend; sup = (void *)sup + supsz) {
>>> + if (sup->sup_segnum >= nilfs->ns_nsegments
>>> + || (sup->sup_flags &
>>> + (~0UL << __NR_NILFS_SUINFO_UPDATE_FIELDS))
>>> + || (nilfs_suinfo_update_nblocks(sup) &&
>>> + sup->sup_sui.sui_nblocks >
>>> + nilfs->ns_blocks_per_segment))
>>> + return -EINVAL;
>>> + }
>>> +
>>> + down_write(&NILFS_MDT(sufile)->mi_sem);
>>> +
>>> + ret = nilfs_sufile_get_header_block(sufile, &header_bh);
>>> + if (ret < 0)
>>> + goto out_sem;
>>> +
>>> + sup = buf;
>>> + blkoff = nilfs_sufile_get_blkoff(sufile, sup->sup_segnum);
>>> + ret = nilfs_mdt_get_block(sufile, blkoff, 1, NULL, &bh);
>>> + if (ret < 0)
>>> + goto out_header;
>>> +
>>> + for (;;) {
>>> + kaddr = kmap_atomic(bh->b_page);
>>> + su = nilfs_sufile_block_get_segment_usage(
>>> + sufile, sup->sup_segnum, bh, kaddr);
>>> +
>>> + if (nilfs_suinfo_update_lastmod(sup))
>>> + su->su_lastmod = cpu_to_le64(sup->sup_sui.sui_lastmod);
>>> +
>>> + if (nilfs_suinfo_update_nblocks(sup))
>>> + su->su_nblocks = cpu_to_le32(sup->sup_sui.sui_nblocks);
>>> +
>>> + if (nilfs_suinfo_update_flags(sup)) {
>>> + /*
>>> + * Active flag is a virtual flag projected by running
>>> + * nilfs kernel code - drop it not to write it to
>>> + * disk.
>>> + */
>>> + sup->sup_sui.sui_flags &=
>>> + ~(1UL << NILFS_SEGMENT_USAGE_ACTIVE);
>>> +
>>> + cleansi = nilfs_suinfo_clean(&sup->sup_sui);
>>> + cleansu = nilfs_segment_usage_clean(su);
>>> + dirtysi = nilfs_suinfo_dirty(&sup->sup_sui);
>>> + dirtysu = nilfs_segment_usage_dirty(su);
>>> +
>>> + if (cleansi && !cleansu)
>>> + ++ncleaned;
>>> + else if (!cleansi && cleansu)
>>> + --ncleaned;
>>> +
>>> + if (dirtysi && !dirtysu)
>>> + ++ndirtied;
>>> + else if (!dirtysi && dirtysu)
>>> + --ndirtied;
>>> +
>>> + su->su_flags = cpu_to_le32(sup->sup_sui.sui_flags);
>>> + }
>>> +
>>> + kunmap_atomic(kaddr);
>>> +
>>> + sup = (void *)sup + supsz;
>>> + if (sup >= supend)
>>> + break;
>>> +
>>> + prev_blkoff = blkoff;
>>> + blkoff = nilfs_sufile_get_blkoff(sufile, sup->sup_segnum);
>>> + if (blkoff == prev_blkoff)
>>> + continue;
>>> +
>>> + /* get different block */
>>> + mark_buffer_dirty(bh);
>>> + brelse(bh);
>>> + ret = nilfs_mdt_get_block(sufile, blkoff, 1, NULL, &bh);
>>> + if (unlikely(ret < 0))
>>> + goto out_mark;
>>> + }
>>> + mark_buffer_dirty(bh);
>>> + brelse(bh);
>>> +
>>> + out_mark:
>>> + if (ncleaned || ndirtied) {
>>> + nilfs_sufile_mod_counter(header_bh, (u64)(long)ncleaned,
>>> + (u64)(long)ndirtied);
>>
>> May I change the type of ncleaned and ndirtied to "long" ?
>
> Sure. Sorry, I misunderstood your last mail on that. I thought you
> preferred unsigned long and suggested the arithmetic cast to u64. Shall
> I send in a corrected version of the patches?
Thanks, please do so.
Sorry for confusing you.
Regards,
Ryusuke Konishi
>> Other looks OK to me.
>
> Cool, Thanks.
>
> Best regards,
> Andreas Rohner
>
>> Thanks,
>> Ryusuke Konishi
>>
>>> + NILFS_SUI(sufile)->ncleansegs += ncleaned;
>>> + }
>>> + nilfs_mdt_mark_dirty(sufile);
>>> + out_header:
>>> + brelse(header_bh);
>>> + out_sem:
>>> + up_write(&NILFS_MDT(sufile)->mi_sem);
>>> + return ret;
>>> +}
>>> +
>>> +/**
>>> * nilfs_sufile_read - read or get sufile inode
>>> * @sb: super block instance
>>> * @susize: size of a segment usage entry
>>> diff --git a/fs/nilfs2/sufile.h b/fs/nilfs2/sufile.h
>>> index e84bc5b..366003c 100644
>>> --- a/fs/nilfs2/sufile.h
>>> +++ b/fs/nilfs2/sufile.h
>>> @@ -44,6 +44,7 @@ int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum,
>>> int nilfs_sufile_get_stat(struct inode *, struct nilfs_sustat *);
>>> ssize_t nilfs_sufile_get_suinfo(struct inode *, __u64, void *, unsigned,
>>> size_t);
>>> +ssize_t nilfs_sufile_set_suinfo(struct inode *, void *, unsigned , size_t);
>>>
>>> int nilfs_sufile_updatev(struct inode *, __u64 *, size_t, int, size_t *,
>>> void (*dofunc)(struct inode *, __u64,
>>> --
>>> 1.8.5.3
>>>
>>> --
>>> 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
>>
>
> --
> 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
--
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
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2014-01-31 10:25 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-01-30 8:42 [PATCH v4 1/3] nilfs2: add struct nilfs_suinfo_update and flags Andreas Rohner
[not found] ` <a3342d446fd05205886f48a95905ddc71c35bf44.1391071318.git.andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2014-01-30 8:42 ` [PATCH v4 2/3] nilfs2: add nilfs_sufile_set_suinfo to update segment usage Andreas Rohner
[not found] ` <f0bf06d2b7d39ebcca3df36567342c7f411eb657.1391071318.git.andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2014-01-31 8:58 ` Ryusuke Konishi
[not found] ` <20140131.175825.168035651.konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
2014-01-31 10:14 ` Andreas Rohner
[not found] ` <52EB7795.6020407-hi6Y0CQ0nG0@public.gmane.org>
2014-01-31 10:25 ` Ryusuke Konishi
2014-01-30 8:42 ` [PATCH v4 3/3] nilfs2: implementation of NILFS_IOCTL_SET_SUINFO ioctl Andreas Rohner
[not found] ` <2e3c9382057dac0835fa45176ccb9f0db9ccc9a8.1391071318.git.andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2014-01-31 9:01 ` Ryusuke Konishi
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.