diff options
author | Li Zefan <lizf@cn.fujitsu.com> | 2011-12-29 13:36:45 +0800 |
---|---|---|
committer | Li Zefan <lizf@cn.fujitsu.com> | 2012-01-11 10:26:38 +0800 |
commit | f062abf089ff705e09bbaa6fa1e2fd7688a0f2ea (patch) | |
tree | 02ed40f0c73ed1d6f8dbdaf5ce725b520036a9b7 /fs | |
parent | 706efc6630c2722602541a6a2fc5900a4e38456a (diff) | |
download | linux-f062abf089ff705e09bbaa6fa1e2fd7688a0f2ea.tar.gz linux-f062abf089ff705e09bbaa6fa1e2fd7688a0f2ea.tar.bz2 linux-f062abf089ff705e09bbaa6fa1e2fd7688a0f2ea.zip |
Btrfs: remove BUG_ON()s in btrfs_ioctl_setflags()
We can recover from errors and return -errno to user space.
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/ioctl.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index c04f02c7d5bb..9619fb03a5d6 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -176,6 +176,8 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) struct btrfs_trans_handle *trans; unsigned int flags, oldflags; int ret; + u64 ip_oldflags; + unsigned int i_oldflags; if (btrfs_root_readonly(root)) return -EROFS; @@ -192,6 +194,9 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) mutex_lock(&inode->i_mutex); + ip_oldflags = ip->flags; + i_oldflags = inode->i_flags; + flags = btrfs_mask_flags(inode->i_mode, flags); oldflags = btrfs_flags_to_ioctl(ip->flags); 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); - BUG_ON(IS_ERR(trans)); + if (IS_ERR(trans)) { + ret = PTR_ERR(trans); + goto out_drop; + } btrfs_update_iflags(inode); inode->i_ctime = CURRENT_TIME; ret = btrfs_update_inode(trans, root, inode); - BUG_ON(ret); 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); - - ret = 0; out_unlock: mutex_unlock(&inode->i_mutex); return ret; |