On Mon, Apr 23, 2018 at 11:42:42AM +0900, Misono Tomohiro wrote: > On 2018/04/21 2:02, David Sterba wrote: > > The new ioctl is an extension to the FS_IOC_SETFLAGS and adds new > > flags and is extensible. Don't get fooled by the XATTR in the name, it > > does not have anything in common with the extended attributes, > > incidentally also abbreviated as XATTRs. > > > > This patch allows to set the xflags portion of the fsxattr structure, > > other items have no meaning and non-zero values will result in > > EOPNOTSUPP. > > > > Currently supported xflags: > > > > - APPEND > > - IMMUTABLE > > - NOATIME > > - NODUMP > > - SYNC > > > > The structure of btrfs_ioctl_fssetxattr copies btrfs_ioctl_setflags but > > is simpler on the flag setting side. > > > > The original patch was written by Chandan Jay Sharma but was incomplete > > and no further revision has been sent. > > > > Based-on-patches-by: Chandan Jay Sharma <chandan...@gmail.com> > > Signed-off-by: David Sterba <dste...@suse.com> > > --- > > fs/btrfs/ioctl.c | 94 > > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > > 1 file changed, 94 insertions(+) > > > > diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c > > index 52b12ab9b82b..4fd61f191bba 100644 > > --- a/fs/btrfs/ioctl.c > > +++ b/fs/btrfs/ioctl.c > > @@ -388,6 +388,98 @@ static int btrfs_ioctl_fsgetxattr(struct file *file, > > void __user *arg) > > return 0; > > } > > > > +static int btrfs_ioctl_fssetxattr(struct file *file, void __user *arg) > > +{ > > + struct inode *inode = file_inode(file); > > + struct btrfs_inode *binode = BTRFS_I(inode); > > + struct btrfs_root *root = binode->root; > > + struct btrfs_trans_handle *trans; > > + struct fsxattr fa; > > + unsigned oldflags; > > + unsigned old_i_flags; > > + int ret = 0; > > + > > + if (!inode_owner_or_capable(inode)) > > + return -EPERM; > > + > > + if (btrfs_root_readonly(root)) > > + return -EROFS; > > + > > + memset(&fa, 0, sizeof(fa)); > > + if (copy_from_user(&fa, arg, sizeof(fa))) > > + return -EFAULT; > > + > > + ret = check_xflags(fa.fsx_xflags); > > + if (ret) > > + return ret; > > + > > + if (fa.fsx_extsize != 0 || fa.fsx_projid != 0 || fa.fsx_cowextsize != 0) > > + return -EOPNOTSUPP; > > + > > + ret = mnt_want_write_file(file); > > + if (ret) > > + return ret; > > + > > + inode_lock(inode); > > + > > + oldflags = binode->flags; > > + old_i_flags = inode->i_flags; > > + > > + /* We need the capabilities to change append-only or immutable inode */ > > + if (((oldflags & (BTRFS_INODE_APPEND | BTRFS_INODE_IMMUTABLE)) || > > + (fa.fsx_xflags & (FS_XFLAG_APPEND | FS_XFLAG_IMMUTABLE))) && > > + !capable(CAP_LINUX_IMMUTABLE)) { > > + ret = -EPERM; > > + goto out_unlock; > > + } > > + > > + if (fa.fsx_xflags & FS_XFLAG_SYNC) > > + binode->flags |= BTRFS_INODE_SYNC; > > + else > > + binode->flags &= ~BTRFS_INODE_SYNC; > > + if (fa.fsx_xflags & FS_XFLAG_IMMUTABLE) > > + binode->flags |= BTRFS_INODE_IMMUTABLE; > > + else > > + binode->flags &= ~BTRFS_INODE_IMMUTABLE; > > + if (fa.fsx_xflags & FS_XFLAG_APPEND) > > + binode->flags |= BTRFS_INODE_APPEND; > > + else > > + binode->flags &= ~BTRFS_INODE_APPEND; > > + if (fa.fsx_xflags & FS_XFLAG_NODUMP) > > + binode->flags |= BTRFS_INODE_NODUMP; > > + else > > + binode->flags &= ~BTRFS_INODE_NODUMP; > > + if (fa.fsx_xflags & FS_XFLAG_NOATIME) > > + binode->flags |= BTRFS_INODE_NOATIME; > > + else > > + binode->flags &= ~BTRFS_INODE_NOATIME; > > + > > + /* 1 item for the inode */ > > + trans = btrfs_start_transaction(root, 1); > > + if (IS_ERR(trans)) { > > + ret = PTR_ERR(trans); > > + goto out_drop; > > + } > > + > > + btrfs_sync_inode_flags_to_i_flags(inode); > > + inode_inc_iversion(inode); > > + inode->i_ctime = current_time(inode); > > + ret = btrfs_update_inode(trans, root, inode); > > + > > + btrfs_end_transaction(trans); > > Shouldn't out_drop label be here? > Otherwise, above "goto out_drop" won't unlock nor restore the flag value.
Right, will fix, thanks. -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html