On Tue, 24 Feb 2015 20:01:42 +0100, Andreas Rohner wrote:
> This patch adds support for additional bit-flags to the
> nilfs_vdesc structure used by the GC to communicate block
> information from userspace. The field vd_flags cannot be used for
> this purpose, because it does not support bit-flags, and changing
> that would break backwards compatibility. Therefore the padding
> field is renamed to vd_blk_flags to contain more flags.
>
> Unfortunately older versions of the userspace tools do not
> initialize the padding field to zero. So it is necessary to signal
> to the kernel if the new vd_blk_flags field contains usable flags
> or just random data. Since the vd_period field is only used in
> userspace, and is guaranteed to contain a value that is > 0
> (NILFS_CNO_MIN == 1), it can be used to give the kernel a hint. So
> if the userspace tools set vd_period.p_start to 0, the
> vd_blk_flags field will be interpreted.
>
> To make the flags available for later stages of the GC process,
> they are mapped to corresponding buffer_head flags.
>
> Signed-off-by: Andreas Rohner <[email protected]>
> ---
> fs/nilfs2/ioctl.c | 23 ++++++++++++++++---
> fs/nilfs2/page.h | 6 ++++-
> include/linux/nilfs2_fs.h | 58
> +++++++++++++++++++++++++++++++++++++++++++++--
> 3 files changed, 81 insertions(+), 6 deletions(-)
>
> diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c
> index f6ee54e..63b1c77 100644
> --- a/fs/nilfs2/ioctl.c
> +++ b/fs/nilfs2/ioctl.c
> @@ -578,7 +578,7 @@ static int nilfs_ioctl_move_inode_block(struct inode
> *inode,
> struct buffer_head *bh;
> int ret;
>
> - if (vdesc->vd_flags == 0)
> + if (nilfs_vdesc_data(vdesc))
> ret = nilfs_gccache_submit_read_data(
> inode, vdesc->vd_offset, vdesc->vd_blocknr,
> vdesc->vd_vblocknr, &bh);
> @@ -592,7 +592,8 @@ static int nilfs_ioctl_move_inode_block(struct inode
> *inode,
> "%s: invalid virtual block address (%s): "
> "ino=%llu, cno=%llu, offset=%llu, "
> "blocknr=%llu, vblocknr=%llu\n",
> - __func__, vdesc->vd_flags ? "node" : "data",
> + __func__,
> + nilfs_vdesc_node(vdesc) ? "node" : "data",
> (unsigned long long)vdesc->vd_ino,
> (unsigned long long)vdesc->vd_cno,
> (unsigned long long)vdesc->vd_offset,
> @@ -603,7 +604,8 @@ static int nilfs_ioctl_move_inode_block(struct inode
> *inode,
> if (unlikely(!list_empty(&bh->b_assoc_buffers))) {
> printk(KERN_CRIT "%s: conflicting %s buffer: ino=%llu, "
> "cno=%llu, offset=%llu, blocknr=%llu, vblocknr=%llu\n",
> - __func__, vdesc->vd_flags ? "node" : "data",
> + __func__,
> + nilfs_vdesc_node(vdesc) ? "node" : "data",
> (unsigned long long)vdesc->vd_ino,
> (unsigned long long)vdesc->vd_cno,
> (unsigned long long)vdesc->vd_offset,
> @@ -612,6 +614,12 @@ static int nilfs_ioctl_move_inode_block(struct inode
> *inode,
> brelse(bh);
> return -EEXIST;
> }
> +
> + if (nilfs_vdesc_snapshot(vdesc))
> + set_buffer_nilfs_snapshot(bh);
> + if (nilfs_vdesc_protection_period(vdesc))
> + set_buffer_nilfs_protection_period(bh);
> +
> list_add_tail(&bh->b_assoc_buffers, buffers);
> return 0;
> }
> @@ -662,6 +670,15 @@ static int nilfs_ioctl_move_blocks(struct super_block
> *sb,
> }
>
> do {
> + /*
> + * old user space tools to not initialize vd_blk_flags
> + * if vd_period.p_start > 0 then vd_blk_flags was
> + * not initialized properly and may contain invalid
> + * flags
> + */
> + if (vdesc->vd_period.p_start > 0)
> + vdesc->vd_blk_flags = 0;
> +
> ret = nilfs_ioctl_move_inode_block(inode, vdesc,
> &buffers);
> if (unlikely(ret < 0)) {
> diff --git a/fs/nilfs2/page.h b/fs/nilfs2/page.h
> index a43b828..b9117e6 100644
> --- a/fs/nilfs2/page.h
> +++ b/fs/nilfs2/page.h
> @@ -36,13 +36,17 @@ enum {
> BH_NILFS_Volatile,
> BH_NILFS_Checked,
> BH_NILFS_Redirected,
> + BH_NILFS_Snapshot,
> + BH_NILFS_Protection_Period,
> };
>
> BUFFER_FNS(NILFS_Node, nilfs_node) /* nilfs node buffers */
> BUFFER_FNS(NILFS_Volatile, nilfs_volatile)
> BUFFER_FNS(NILFS_Checked, nilfs_checked) /* buffer is verified */
> BUFFER_FNS(NILFS_Redirected, nilfs_redirected) /* redirected to a copy
> */
> -
> +BUFFER_FNS(NILFS_Snapshot, nilfs_snapshot) /* belongs to a snapshot */
> +BUFFER_FNS(NILFS_Protection_Period, nilfs_protection_period) /* protected by
> + protection period */
>
I propose alternative names: "snapshot_protected", and
"period_protected" (or "time_protected") respectively to clarify
meaning of the flags.
> int __nilfs_clear_page_dirty(struct page *);
>
> diff --git a/include/linux/nilfs2_fs.h b/include/linux/nilfs2_fs.h
> index 6ccb2ad..6ffdc09 100644
> --- a/include/linux/nilfs2_fs.h
> +++ b/include/linux/nilfs2_fs.h
> @@ -900,7 +900,7 @@ struct nilfs_vinfo {
> * @vd_blocknr: disk block number
> * @vd_offset: logical block offset inside a file
> * @vd_flags: flags (data or node block)
> - * @vd_pad: padding
> + * @vd_blk_flags: additional flags
> */
> struct nilfs_vdesc {
> __u64 vd_ino;
> @@ -910,9 +910,63 @@ struct nilfs_vdesc {
> __u64 vd_blocknr;
> __u64 vd_offset;
> __u32 vd_flags;
> - __u32 vd_pad;
> + /*
> + * vd_blk_flags needed because vd_flags doesn't support
> + * bit-flags because of backwards compatibility
> + */
> + __u32 vd_blk_flags;
> };
>
> +/* vdesc flags */
> +enum {
> + NILFS_VDESC_DATA,
> + NILFS_VDESC_NODE,
> +
> + /* ... */
> +};
> +enum {
> + NILFS_VDESC_SNAPSHOT,
> + NILFS_VDESC_PROTECTION_PERIOD,
> +
> + /* ... */
> +
> + __NR_NILFS_VDESC_FIELDS,
> +};
> +
> +#define NILFS_VDESC_FNS(flag, name) \
> +static inline void \
> +nilfs_vdesc_set_##name(struct nilfs_vdesc *vdesc) \
> +{ \
> + vdesc->vd_flags = NILFS_VDESC_##flag; \
> +} \
> +static inline int \
> +nilfs_vdesc_##name(const struct nilfs_vdesc *vdesc) \
> +{ \
> + return vdesc->vd_flags == NILFS_VDESC_##flag; \
> +}
> +
Do not add definitions for vd_flags, leave them, and
simplify your patch.
Regards,
Ryusuke Konishi
> +#define NILFS_VDESC_FNS2(flag, name) \
> +static inline void \
> +nilfs_vdesc_set_##name(struct nilfs_vdesc *vdesc) \
> +{ \
> + vdesc->vd_blk_flags |= (1UL << NILFS_VDESC_##flag); \
> +} \
> +static inline void \
> +nilfs_vdesc_clear_##name(struct nilfs_vdesc *vdesc) \
> +{ \
> + vdesc->vd_blk_flags &= ~(1UL << NILFS_VDESC_##flag); \
> +} \
> +static inline int \
> +nilfs_vdesc_##name(const struct nilfs_vdesc *vdesc) \
> +{ \
> + return !!(vdesc->vd_blk_flags & (1UL << NILFS_VDESC_##flag)); \
> +}
> +
> +NILFS_VDESC_FNS(DATA, data)
> +NILFS_VDESC_FNS(NODE, node)
> +NILFS_VDESC_FNS2(SNAPSHOT, snapshot)
> +NILFS_VDESC_FNS2(PROTECTION_PERIOD, protection_period)
> +
> /**
> * struct nilfs_bdesc - descriptor of disk block number
> * @bd_ino: inode number
> --
> 2.3.0
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nilfs" in
> the body of a message to [email protected]
> 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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html