linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: David Sterba <dsterba@suse.cz>
To: Chandan Jay Sharma <chandansbg@gmail.com>
Cc: linux-btrfs@vger.kernel.org, dsterba@suse.cz
Subject: Re: [PATCH] btrfs: adds FS_IOC_FSSETXATTR/FS_IOC_FSGETXATTR ioctl interface support
Date: Wed, 5 Apr 2017 15:01:10 +0200	[thread overview]
Message-ID: <20170405130110.GD4781@twin.jikos.cz> (raw)
In-Reply-To: <20170404160639.12155-1-chandansbg@gmail.com>

On Tue, Apr 04, 2017 at 09:36:39PM +0530, Chandan Jay Sharma wrote:
> This patch adds FS_IOC_FSSETXATTR/FS_IOC_FSGETXATTR ioctl interface support
> for btrfs. Extended file attributes are 32 bit values (FS_XFLAGS_SYNC,
> FS_XFLAG_IMMUTABLE, etc) which have one-to-one mapping to the flag values
> that can be stored in inode->i_flags (i.e. S_SYNC, S_IMMUTABLE, etc).
> The flags can be set/unset to enable/disable file attributes.
> These attributes are listed/modified by lsattr/chattr.

Ok.

> Signed-off-by: Chandan Jay Sharma <chandansbg@gmail.com>
> ---
>  fs/btrfs/ioctl.c | 148 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 148 insertions(+)
> 
> diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
> index dabfc7a..5d8486b 100644
> --- a/fs/btrfs/ioctl.c
> +++ b/fs/btrfs/ioctl.c
> @@ -132,6 +132,25 @@ static unsigned int btrfs_flags_to_ioctl(unsigned int flags)
>  	return iflags;
>  }
>  
> +/* Transfer ioctl flags to btrfs internal flags */

Please mention which ioctl as we now have 2 that do a similar thing.

> +static unsigned int btrfs_ioctl_to_flags(unsigned int iflags)
> +{
> +	unsigned int flags = 0;
> +
> +	if (iflags & FS_SYNC_FL)
> +		flags |= BTRFS_INODE_SYNC;
> +	if (iflags & FS_IMMUTABLE_FL)
> +		flags |= BTRFS_INODE_IMMUTABLE;
> +	if (iflags & FS_APPEND_FL)
> +		flags |= BTRFS_INODE_APPEND;
> +	if (iflags & FS_NODUMP_FL)
> +		flags |= BTRFS_INODE_NODUMP;
> +	if (iflags & FS_NOATIME_FL)
> +		flags |= BTRFS_INODE_NOATIME;
> +
> +	return flags;
> +}
> +
>  /*
>   * Update inode->i_flags based on the btrfs internal flags.
>   */
> @@ -157,6 +176,75 @@ void btrfs_update_iflags(struct inode *inode)
>  }
>  
>  /*
> + * Propagate flags from i_flags to BTRFS_I(inode)->flags
> + */
> +void btrfs_get_inode_flags(struct btrfs_inode *ip)
> +{
> +	unsigned int vfs_fl;
> +	unsigned long old_fl, new_fl;
> +
> +	do {
> +		vfs_fl = ip->vfs_inode.i_flags;
> +		old_fl = ip->flags;
> +		new_fl = old_fl & ~(BTRFS_INODE_SYNC|BTRFS_INODE_APPEND|
> +				BTRFS_INODE_IMMUTABLE|BTRFS_INODE_NOATIME|
> +				BTRFS_INODE_DIRSYNC);

The list of supported flags should be declared in a header, something
like

#define BTRFS_INODE_FLAGS_MASK (BTRFS_INODE_SYNC |
				BTRFS_INODE_APPEND |
				BTRFS_INODE_IMMUTABLE |
				BTRFS_INODE_NOATIME |
				BTRFS_INODE_DIRSYNC)

> +		if (vfs_fl & S_SYNC)
> +			new_fl |= BTRFS_INODE_SYNC;
> +		if (vfs_fl & S_APPEND)
> +			new_fl |= BTRFS_INODE_APPEND;
> +		if (vfs_fl & S_IMMUTABLE)
> +			new_fl |= BTRFS_INODE_IMMUTABLE;
> +		if (vfs_fl & S_NOATIME)
> +			new_fl |= BTRFS_INODE_NOATIME;
> +		if (vfs_fl & S_DIRSYNC)
> +			new_fl |= BTRFS_INODE_DIRSYNC;
> +	} while (cmpxchg(&ip->flags, old_fl, new_fl) != old_fl);
> +}
> +
> +/*
> + * Translate btrfs internal flags BTRFS_I(inode)->flags to xflags.

Maybe also reference the related ioctl.

> + */
> +static inline unsigned int btrfs_flags_to_xflags(unsigned int flags)
> +{
> +	unsigned int xflags = 0;
> +
> +	if (flags & BTRFS_INODE_SYNC)
> +		xflags |= FS_XFLAG_SYNC;
> +	if (flags & BTRFS_INODE_IMMUTABLE)
> +		xflags |= FS_XFLAG_IMMUTABLE;
> +	if (flags & BTRFS_INODE_APPEND)
> +		xflags |= FS_XFLAG_APPEND;
> +	if (flags & BTRFS_INODE_NODUMP)
> +		xflags |= FS_XFLAG_NODUMP;
> +	if (flags & BTRFS_INODE_NOATIME)
> +		xflags |= FS_XFLAG_NOATIME;
> +
> +	return xflags;
> +}
> +
> +/*
> + * Transfer xflags flags to ioctl flags.
> + */
> +static inline unsigned int btrfs_xflags_to_ioctl(unsigned int xflags)
> +{
> +	unsigned int flags = 0;
> +
> +	if (xflags & FS_XFLAG_SYNC)
> +		flags |= FS_SYNC_FL;
> +	if (xflags & FS_XFLAG_IMMUTABLE)
> +		flags |= FS_IMMUTABLE_FL;
> +	if (xflags & FS_XFLAG_APPEND)
> +		flags |= FS_APPEND_FL;
> +	if (xflags & FS_XFLAG_NODUMP)
> +		flags |= FS_NODUMP_FL;
> +	if (xflags & FS_XFLAG_NOATIME)
> +		flags |= FS_NOATIME_FL;
> +
> +	return flags;
> +}
> +
> +/*
>   * Inherit flags from the parent inode.
>   *
>   * Currently only the compression flags and the cow flags are inherited.
> @@ -5504,6 +5592,62 @@ static int btrfs_ioctl_set_features(struct file *file, void __user *arg)
>  	return ret;
>  }
>  
> +static int btrfs_ioctl_fsgetxattr(struct file *file, void __user *arg)
> +{
> +	struct fsxattr fa;
> +	struct btrfs_inode *ip = BTRFS_I(file_inode(file));
> +
> +	memset(&fa, 0, sizeof(struct fsxattr));
> +	btrfs_get_inode_flags(ip);
> +	fa.fsx_xflags = btrfs_flags_to_xflags(ip->flags);
> +
> +	if (copy_to_user((struct fsxattr __user *)arg,
> +			&fa, sizeof(fa)))
> +		return -EFAULT;
> +
> +	return 0;
> +}
> +
> +static int btrfs_ioctl_fssetxattr(struct file *file, void __user *arg)
> +{
> +	struct inode *inode = file_inode(file);
> +	struct btrfs_inode *ip = BTRFS_I(inode);
> +	struct btrfs_root *root = ip->root;
> +	struct fsxattr fa;
> +	unsigned int flags;
> +	int err;
> +
> +	/* Make sure caller has proper permission */
> +	if (!inode_owner_or_capable(inode))
> +		return -EPERM;
> +
> +	if (btrfs_root_readonly(root))
> +		return -EROFS;
> +
> +	memset(&fa, 0, sizeof(struct fsxattr));
> +	if (copy_from_user(&fa, (struct fsxattr __user *)arg,
> +			sizeof(fa)))
> +		return -EFAULT;
> +
> +	flags = btrfs_xflags_to_ioctl(fa.fsx_xflags);
> +
> +	if (btrfs_mask_flags(inode->i_mode, flags) != flags)
> +		return -EOPNOTSUPP;

Please see btrfs_ioctl_setflags what's needs do be done here

- verify that the requested flags are supported
- start transaction
- update the flags
- inode_inc_iversion
- update ctime
- update the inode
- end transaction

> +	err = mnt_want_write_file(file);
> +	if (err)
> +		return err;
> +
> +	inode_lock(inode);
> +	ip->flags = (ip->flags | btrfs_ioctl_to_flags(flags));
> +	btrfs_update_iflags(inode);
> +	inode_unlock(inode);
> +
> +	mnt_drop_write_file(file);
> +
> +	return 0;
> +}

      reply	other threads:[~2017-04-05 13:01 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-04 16:06 [PATCH] btrfs: adds FS_IOC_FSSETXATTR/FS_IOC_FSGETXATTR ioctl interface support Chandan Jay Sharma
2017-04-05 13:01 ` David Sterba [this message]

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=20170405130110.GD4781@twin.jikos.cz \
    --to=dsterba@suse.cz \
    --cc=chandansbg@gmail.com \
    --cc=linux-btrfs@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 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).