|
@@ -176,6 +176,8 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
|
|
struct btrfs_trans_handle *trans;
|
|
struct btrfs_trans_handle *trans;
|
|
unsigned int flags, oldflags;
|
|
unsigned int flags, oldflags;
|
|
int ret;
|
|
int ret;
|
|
|
|
+ u64 ip_oldflags;
|
|
|
|
+ unsigned int i_oldflags;
|
|
|
|
|
|
if (btrfs_root_readonly(root))
|
|
if (btrfs_root_readonly(root))
|
|
return -EROFS;
|
|
return -EROFS;
|
|
@@ -192,6 +194,9 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
|
|
|
|
|
|
mutex_lock(&inode->i_mutex);
|
|
mutex_lock(&inode->i_mutex);
|
|
|
|
|
|
|
|
+ ip_oldflags = ip->flags;
|
|
|
|
+ i_oldflags = inode->i_flags;
|
|
|
|
+
|
|
flags = btrfs_mask_flags(inode->i_mode, flags);
|
|
flags = btrfs_mask_flags(inode->i_mode, flags);
|
|
oldflags = btrfs_flags_to_ioctl(ip->flags);
|
|
oldflags = btrfs_flags_to_ioctl(ip->flags);
|
|
if ((flags ^ oldflags) & (FS_APPEND_FL | FS_IMMUTABLE_FL)) {
|
|
if ((flags ^ oldflags) & (FS_APPEND_FL | FS_IMMUTABLE_FL)) {
|
|
@@ -250,18 +255,23 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
|
|
}
|
|
}
|
|
|
|
|
|
trans = btrfs_join_transaction(root);
|
|
trans = btrfs_join_transaction(root);
|
|
- BUG_ON(IS_ERR(trans));
|
|
|
|
|
|
+ if (IS_ERR(trans)) {
|
|
|
|
+ ret = PTR_ERR(trans);
|
|
|
|
+ goto out_drop;
|
|
|
|
+ }
|
|
|
|
|
|
btrfs_update_iflags(inode);
|
|
btrfs_update_iflags(inode);
|
|
inode->i_ctime = CURRENT_TIME;
|
|
inode->i_ctime = CURRENT_TIME;
|
|
ret = btrfs_update_inode(trans, root, inode);
|
|
ret = btrfs_update_inode(trans, root, inode);
|
|
- BUG_ON(ret);
|
|
|
|
|
|
|
|
btrfs_end_transaction(trans, root);
|
|
btrfs_end_transaction(trans, root);
|
|
|
|
+ out_drop:
|
|
|
|
+ if (ret) {
|
|
|
|
+ ip->flags = ip_oldflags;
|
|
|
|
+ inode->i_flags = i_oldflags;
|
|
|
|
+ }
|
|
|
|
|
|
mnt_drop_write(file->f_path.mnt);
|
|
mnt_drop_write(file->f_path.mnt);
|
|
-
|
|
|
|
- ret = 0;
|
|
|
|
out_unlock:
|
|
out_unlock:
|
|
mutex_unlock(&inode->i_mutex);
|
|
mutex_unlock(&inode->i_mutex);
|
|
return ret;
|
|
return ret;
|