mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	btrfs: convert to fileattr
Use the fileattr API to let the VFS handle locking, permission checking and conversion. Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> Cc: David Sterba <dsterba@suse.com>
This commit is contained in:
		
							parent
							
								
									66dbfabf10
								
							
						
					
					
						commit
						97fc297754
					
				
					 3 changed files with 42 additions and 193 deletions
				
			
		| 
						 | 
					@ -3189,6 +3189,9 @@ void btrfs_update_inode_bytes(struct btrfs_inode *inode,
 | 
				
			||||||
/* ioctl.c */
 | 
					/* ioctl.c */
 | 
				
			||||||
long btrfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
 | 
					long btrfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
 | 
				
			||||||
long btrfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
 | 
					long btrfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
 | 
				
			||||||
 | 
					int btrfs_fileattr_get(struct dentry *dentry, struct fileattr *fa);
 | 
				
			||||||
 | 
					int btrfs_fileattr_set(struct user_namespace *mnt_userns,
 | 
				
			||||||
 | 
							       struct dentry *dentry, struct fileattr *fa);
 | 
				
			||||||
int btrfs_ioctl_get_supported_features(void __user *arg);
 | 
					int btrfs_ioctl_get_supported_features(void __user *arg);
 | 
				
			||||||
void btrfs_sync_inode_flags_to_i_flags(struct inode *inode);
 | 
					void btrfs_sync_inode_flags_to_i_flags(struct inode *inode);
 | 
				
			||||||
int __pure btrfs_is_empty_uuid(u8 *uuid);
 | 
					int __pure btrfs_is_empty_uuid(u8 *uuid);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10603,6 +10603,8 @@ static const struct inode_operations btrfs_dir_inode_operations = {
 | 
				
			||||||
	.set_acl	= btrfs_set_acl,
 | 
						.set_acl	= btrfs_set_acl,
 | 
				
			||||||
	.update_time	= btrfs_update_time,
 | 
						.update_time	= btrfs_update_time,
 | 
				
			||||||
	.tmpfile        = btrfs_tmpfile,
 | 
						.tmpfile        = btrfs_tmpfile,
 | 
				
			||||||
 | 
						.fileattr_get	= btrfs_fileattr_get,
 | 
				
			||||||
 | 
						.fileattr_set	= btrfs_fileattr_set,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct file_operations btrfs_dir_file_operations = {
 | 
					static const struct file_operations btrfs_dir_file_operations = {
 | 
				
			||||||
| 
						 | 
					@ -10656,6 +10658,8 @@ static const struct inode_operations btrfs_file_inode_operations = {
 | 
				
			||||||
	.get_acl	= btrfs_get_acl,
 | 
						.get_acl	= btrfs_get_acl,
 | 
				
			||||||
	.set_acl	= btrfs_set_acl,
 | 
						.set_acl	= btrfs_set_acl,
 | 
				
			||||||
	.update_time	= btrfs_update_time,
 | 
						.update_time	= btrfs_update_time,
 | 
				
			||||||
 | 
						.fileattr_get	= btrfs_fileattr_get,
 | 
				
			||||||
 | 
						.fileattr_set	= btrfs_fileattr_set,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
static const struct inode_operations btrfs_special_inode_operations = {
 | 
					static const struct inode_operations btrfs_special_inode_operations = {
 | 
				
			||||||
	.getattr	= btrfs_getattr,
 | 
						.getattr	= btrfs_getattr,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										228
									
								
								fs/btrfs/ioctl.c
									
									
									
									
									
								
							
							
						
						
									
										228
									
								
								fs/btrfs/ioctl.c
									
									
									
									
									
								
							| 
						 | 
					@ -26,6 +26,7 @@
 | 
				
			||||||
#include <linux/btrfs.h>
 | 
					#include <linux/btrfs.h>
 | 
				
			||||||
#include <linux/uaccess.h>
 | 
					#include <linux/uaccess.h>
 | 
				
			||||||
#include <linux/iversion.h>
 | 
					#include <linux/iversion.h>
 | 
				
			||||||
 | 
					#include <linux/fileattr.h>
 | 
				
			||||||
#include "ctree.h"
 | 
					#include "ctree.h"
 | 
				
			||||||
#include "disk-io.h"
 | 
					#include "disk-io.h"
 | 
				
			||||||
#include "export.h"
 | 
					#include "export.h"
 | 
				
			||||||
| 
						 | 
					@ -153,16 +154,6 @@ void btrfs_sync_inode_flags_to_i_flags(struct inode *inode)
 | 
				
			||||||
		      new_fl);
 | 
							      new_fl);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int btrfs_ioctl_getflags(struct file *file, void __user *arg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct btrfs_inode *binode = BTRFS_I(file_inode(file));
 | 
					 | 
				
			||||||
	unsigned int flags = btrfs_inode_flags_to_fsflags(binode->flags);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (copy_to_user(arg, &flags, sizeof(flags)))
 | 
					 | 
				
			||||||
		return -EFAULT;
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Check if @flags are a supported and valid set of FS_*_FL flags and that
 | 
					 * Check if @flags are a supported and valid set of FS_*_FL flags and that
 | 
				
			||||||
 * the old and new flags are not conflicting
 | 
					 * the old and new flags are not conflicting
 | 
				
			||||||
| 
						 | 
					@ -201,9 +192,22 @@ static int check_fsflags_compatible(struct btrfs_fs_info *fs_info,
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
 | 
					/*
 | 
				
			||||||
 | 
					 * Set flags/xflags from the internal inode flags. The remaining items of
 | 
				
			||||||
 | 
					 * fsxattr are zeroed.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int btrfs_fileattr_get(struct dentry *dentry, struct fileattr *fa)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct inode *inode = file_inode(file);
 | 
						struct btrfs_inode *binode = BTRFS_I(d_inode(dentry));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fileattr_fill_flags(fa, btrfs_inode_flags_to_fsflags(binode->flags));
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int btrfs_fileattr_set(struct user_namespace *mnt_userns,
 | 
				
			||||||
 | 
							       struct dentry *dentry, struct fileattr *fa)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct inode *inode = d_inode(dentry);
 | 
				
			||||||
	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
 | 
						struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
 | 
				
			||||||
	struct btrfs_inode *binode = BTRFS_I(inode);
 | 
						struct btrfs_inode *binode = BTRFS_I(inode);
 | 
				
			||||||
	struct btrfs_root *root = binode->root;
 | 
						struct btrfs_root *root = binode->root;
 | 
				
			||||||
| 
						 | 
					@ -213,34 +217,21 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
 | 
				
			||||||
	const char *comp = NULL;
 | 
						const char *comp = NULL;
 | 
				
			||||||
	u32 binode_flags;
 | 
						u32 binode_flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!inode_owner_or_capable(&init_user_ns, inode))
 | 
					 | 
				
			||||||
		return -EPERM;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (btrfs_root_readonly(root))
 | 
						if (btrfs_root_readonly(root))
 | 
				
			||||||
		return -EROFS;
 | 
							return -EROFS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (copy_from_user(&fsflags, arg, sizeof(fsflags)))
 | 
						if (fileattr_has_fsx(fa))
 | 
				
			||||||
		return -EFAULT;
 | 
							return -EOPNOTSUPP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = mnt_want_write_file(file);
 | 
						fsflags = btrfs_mask_fsflags_for_type(inode, fa->flags);
 | 
				
			||||||
 | 
						old_fsflags = btrfs_inode_flags_to_fsflags(binode->flags);
 | 
				
			||||||
 | 
						ret = check_fsflags(old_fsflags, fsflags);
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inode_lock(inode);
 | 
					 | 
				
			||||||
	fsflags = btrfs_mask_fsflags_for_type(inode, fsflags);
 | 
					 | 
				
			||||||
	old_fsflags = btrfs_inode_flags_to_fsflags(binode->flags);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ret = vfs_ioc_setflags_prepare(inode, old_fsflags, fsflags);
 | 
					 | 
				
			||||||
	if (ret)
 | 
					 | 
				
			||||||
		goto out_unlock;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ret = check_fsflags(old_fsflags, fsflags);
 | 
					 | 
				
			||||||
	if (ret)
 | 
					 | 
				
			||||||
		goto out_unlock;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ret = check_fsflags_compatible(fs_info, fsflags);
 | 
						ret = check_fsflags_compatible(fs_info, fsflags);
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		goto out_unlock;
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	binode_flags = binode->flags;
 | 
						binode_flags = binode->flags;
 | 
				
			||||||
	if (fsflags & FS_SYNC_FL)
 | 
						if (fsflags & FS_SYNC_FL)
 | 
				
			||||||
| 
						 | 
					@ -263,6 +254,14 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
 | 
				
			||||||
		binode_flags |= BTRFS_INODE_NOATIME;
 | 
							binode_flags |= BTRFS_INODE_NOATIME;
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		binode_flags &= ~BTRFS_INODE_NOATIME;
 | 
							binode_flags &= ~BTRFS_INODE_NOATIME;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* If coming from FS_IOC_FSSETXATTR then skip unconverted flags */
 | 
				
			||||||
 | 
						if (!fa->flags_valid) {
 | 
				
			||||||
 | 
							/* 1 item for the inode */
 | 
				
			||||||
 | 
							trans = btrfs_start_transaction(root, 1);
 | 
				
			||||||
 | 
							goto update_flags;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (fsflags & FS_DIRSYNC_FL)
 | 
						if (fsflags & FS_DIRSYNC_FL)
 | 
				
			||||||
		binode_flags |= BTRFS_INODE_DIRSYNC;
 | 
							binode_flags |= BTRFS_INODE_DIRSYNC;
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
| 
						 | 
					@ -303,10 +302,8 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
 | 
				
			||||||
		binode_flags |= BTRFS_INODE_NOCOMPRESS;
 | 
							binode_flags |= BTRFS_INODE_NOCOMPRESS;
 | 
				
			||||||
	} else if (fsflags & FS_COMPR_FL) {
 | 
						} else if (fsflags & FS_COMPR_FL) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (IS_SWAPFILE(inode)) {
 | 
							if (IS_SWAPFILE(inode))
 | 
				
			||||||
			ret = -ETXTBSY;
 | 
								return -ETXTBSY;
 | 
				
			||||||
			goto out_unlock;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		binode_flags |= BTRFS_INODE_COMPRESS;
 | 
							binode_flags |= BTRFS_INODE_COMPRESS;
 | 
				
			||||||
		binode_flags &= ~BTRFS_INODE_NOCOMPRESS;
 | 
							binode_flags &= ~BTRFS_INODE_NOCOMPRESS;
 | 
				
			||||||
| 
						 | 
					@ -323,10 +320,8 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
 | 
				
			||||||
	 * 2 for properties
 | 
						 * 2 for properties
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	trans = btrfs_start_transaction(root, 3);
 | 
						trans = btrfs_start_transaction(root, 3);
 | 
				
			||||||
	if (IS_ERR(trans)) {
 | 
						if (IS_ERR(trans))
 | 
				
			||||||
		ret = PTR_ERR(trans);
 | 
							return PTR_ERR(trans);
 | 
				
			||||||
		goto out_unlock;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (comp) {
 | 
						if (comp) {
 | 
				
			||||||
		ret = btrfs_set_prop(trans, inode, "btrfs.compression", comp,
 | 
							ret = btrfs_set_prop(trans, inode, "btrfs.compression", comp,
 | 
				
			||||||
| 
						 | 
					@ -344,6 +339,7 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					update_flags:
 | 
				
			||||||
	binode->flags = binode_flags;
 | 
						binode->flags = binode_flags;
 | 
				
			||||||
	btrfs_sync_inode_flags_to_i_flags(inode);
 | 
						btrfs_sync_inode_flags_to_i_flags(inode);
 | 
				
			||||||
	inode_inc_iversion(inode);
 | 
						inode_inc_iversion(inode);
 | 
				
			||||||
| 
						 | 
					@ -352,44 +348,9 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 out_end_trans:
 | 
					 out_end_trans:
 | 
				
			||||||
	btrfs_end_transaction(trans);
 | 
						btrfs_end_transaction(trans);
 | 
				
			||||||
 out_unlock:
 | 
					 | 
				
			||||||
	inode_unlock(inode);
 | 
					 | 
				
			||||||
	mnt_drop_write_file(file);
 | 
					 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Translate btrfs internal inode flags to xflags as expected by the
 | 
					 | 
				
			||||||
 * FS_IOC_FSGETXATT ioctl. Filter only the supported ones, unknown flags are
 | 
					 | 
				
			||||||
 * silently dropped.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static unsigned int btrfs_inode_flags_to_xflags(unsigned int flags)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	unsigned int xflags = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (flags & BTRFS_INODE_APPEND)
 | 
					 | 
				
			||||||
		xflags |= FS_XFLAG_APPEND;
 | 
					 | 
				
			||||||
	if (flags & BTRFS_INODE_IMMUTABLE)
 | 
					 | 
				
			||||||
		xflags |= FS_XFLAG_IMMUTABLE;
 | 
					 | 
				
			||||||
	if (flags & BTRFS_INODE_NOATIME)
 | 
					 | 
				
			||||||
		xflags |= FS_XFLAG_NOATIME;
 | 
					 | 
				
			||||||
	if (flags & BTRFS_INODE_NODUMP)
 | 
					 | 
				
			||||||
		xflags |= FS_XFLAG_NODUMP;
 | 
					 | 
				
			||||||
	if (flags & BTRFS_INODE_SYNC)
 | 
					 | 
				
			||||||
		xflags |= FS_XFLAG_SYNC;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return xflags;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Check if @flags are a supported and valid set of FS_XFLAGS_* flags */
 | 
					 | 
				
			||||||
static int check_xflags(unsigned int flags)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (flags & ~(FS_XFLAG_APPEND | FS_XFLAG_IMMUTABLE | FS_XFLAG_NOATIME |
 | 
					 | 
				
			||||||
		      FS_XFLAG_NODUMP | FS_XFLAG_SYNC))
 | 
					 | 
				
			||||||
		return -EOPNOTSUPP;
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool btrfs_exclop_start(struct btrfs_fs_info *fs_info,
 | 
					bool btrfs_exclop_start(struct btrfs_fs_info *fs_info,
 | 
				
			||||||
			enum btrfs_exclusive_operation type)
 | 
								enum btrfs_exclusive_operation type)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -402,111 +363,6 @@ void btrfs_exclop_finish(struct btrfs_fs_info *fs_info)
 | 
				
			||||||
	sysfs_notify(&fs_info->fs_devices->fsid_kobj, NULL, "exclusive_operation");
 | 
						sysfs_notify(&fs_info->fs_devices->fsid_kobj, NULL, "exclusive_operation");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Set the xflags from the internal inode flags. The remaining items of fsxattr
 | 
					 | 
				
			||||||
 * are zeroed.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static int btrfs_ioctl_fsgetxattr(struct file *file, void __user *arg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct btrfs_inode *binode = BTRFS_I(file_inode(file));
 | 
					 | 
				
			||||||
	struct fsxattr fa;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	simple_fill_fsxattr(&fa, btrfs_inode_flags_to_xflags(binode->flags));
 | 
					 | 
				
			||||||
	if (copy_to_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 *binode = BTRFS_I(inode);
 | 
					 | 
				
			||||||
	struct btrfs_root *root = binode->root;
 | 
					 | 
				
			||||||
	struct btrfs_trans_handle *trans;
 | 
					 | 
				
			||||||
	struct fsxattr fa, old_fa;
 | 
					 | 
				
			||||||
	unsigned old_flags;
 | 
					 | 
				
			||||||
	unsigned old_i_flags;
 | 
					 | 
				
			||||||
	int ret = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!inode_owner_or_capable(&init_user_ns, inode))
 | 
					 | 
				
			||||||
		return -EPERM;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (btrfs_root_readonly(root))
 | 
					 | 
				
			||||||
		return -EROFS;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	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);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	old_flags = binode->flags;
 | 
					 | 
				
			||||||
	old_i_flags = inode->i_flags;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	simple_fill_fsxattr(&old_fa,
 | 
					 | 
				
			||||||
			    btrfs_inode_flags_to_xflags(binode->flags));
 | 
					 | 
				
			||||||
	ret = vfs_ioc_fssetxattr_check(inode, &old_fa, &fa);
 | 
					 | 
				
			||||||
	if (ret)
 | 
					 | 
				
			||||||
		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_unlock;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	btrfs_sync_inode_flags_to_i_flags(inode);
 | 
					 | 
				
			||||||
	inode_inc_iversion(inode);
 | 
					 | 
				
			||||||
	inode->i_ctime = current_time(inode);
 | 
					 | 
				
			||||||
	ret = btrfs_update_inode(trans, root, BTRFS_I(inode));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	btrfs_end_transaction(trans);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
out_unlock:
 | 
					 | 
				
			||||||
	if (ret) {
 | 
					 | 
				
			||||||
		binode->flags = old_flags;
 | 
					 | 
				
			||||||
		inode->i_flags = old_i_flags;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	inode_unlock(inode);
 | 
					 | 
				
			||||||
	mnt_drop_write_file(file);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return ret;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int btrfs_ioctl_getversion(struct file *file, int __user *arg)
 | 
					static int btrfs_ioctl_getversion(struct file *file, int __user *arg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct inode *inode = file_inode(file);
 | 
						struct inode *inode = file_inode(file);
 | 
				
			||||||
| 
						 | 
					@ -4915,10 +4771,6 @@ long btrfs_ioctl(struct file *file, unsigned int
 | 
				
			||||||
	void __user *argp = (void __user *)arg;
 | 
						void __user *argp = (void __user *)arg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (cmd) {
 | 
						switch (cmd) {
 | 
				
			||||||
	case FS_IOC_GETFLAGS:
 | 
					 | 
				
			||||||
		return btrfs_ioctl_getflags(file, argp);
 | 
					 | 
				
			||||||
	case FS_IOC_SETFLAGS:
 | 
					 | 
				
			||||||
		return btrfs_ioctl_setflags(file, argp);
 | 
					 | 
				
			||||||
	case FS_IOC_GETVERSION:
 | 
						case FS_IOC_GETVERSION:
 | 
				
			||||||
		return btrfs_ioctl_getversion(file, argp);
 | 
							return btrfs_ioctl_getversion(file, argp);
 | 
				
			||||||
	case FS_IOC_GETFSLABEL:
 | 
						case FS_IOC_GETFSLABEL:
 | 
				
			||||||
| 
						 | 
					@ -5044,10 +4896,6 @@ long btrfs_ioctl(struct file *file, unsigned int
 | 
				
			||||||
		return btrfs_ioctl_get_features(fs_info, argp);
 | 
							return btrfs_ioctl_get_features(fs_info, argp);
 | 
				
			||||||
	case BTRFS_IOC_SET_FEATURES:
 | 
						case BTRFS_IOC_SET_FEATURES:
 | 
				
			||||||
		return btrfs_ioctl_set_features(file, argp);
 | 
							return btrfs_ioctl_set_features(file, argp);
 | 
				
			||||||
	case FS_IOC_FSGETXATTR:
 | 
					 | 
				
			||||||
		return btrfs_ioctl_fsgetxattr(file, argp);
 | 
					 | 
				
			||||||
	case FS_IOC_FSSETXATTR:
 | 
					 | 
				
			||||||
		return btrfs_ioctl_fssetxattr(file, argp);
 | 
					 | 
				
			||||||
	case BTRFS_IOC_GET_SUBVOL_INFO:
 | 
						case BTRFS_IOC_GET_SUBVOL_INFO:
 | 
				
			||||||
		return btrfs_ioctl_get_subvol_info(file, argp);
 | 
							return btrfs_ioctl_get_subvol_info(file, argp);
 | 
				
			||||||
	case BTRFS_IOC_GET_SUBVOL_ROOTREF:
 | 
						case BTRFS_IOC_GET_SUBVOL_ROOTREF:
 | 
				
			||||||
| 
						 | 
					@ -5067,12 +4915,6 @@ long btrfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 | 
				
			||||||
	 * handling is necessary.
 | 
						 * handling is necessary.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	switch (cmd) {
 | 
						switch (cmd) {
 | 
				
			||||||
	case FS_IOC32_GETFLAGS:
 | 
					 | 
				
			||||||
		cmd = FS_IOC_GETFLAGS;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case FS_IOC32_SETFLAGS:
 | 
					 | 
				
			||||||
		cmd = FS_IOC_SETFLAGS;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case FS_IOC32_GETVERSION:
 | 
						case FS_IOC32_GETVERSION:
 | 
				
			||||||
		cmd = FS_IOC_GETVERSION;
 | 
							cmd = FS_IOC_GETVERSION;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue