Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
83bfccb5
Commit
83bfccb5
authored
Jan 21, 2013
by
Chris Mason
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'mutex-ops@next-for-chris' of
git://github.com/idryomov/btrfs-unstable
into linus
parents
daf2c089
25122d15
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
86 additions
and
31 deletions
+86
-31
fs/btrfs/ioctl.c
fs/btrfs/ioctl.c
+79
-28
fs/btrfs/volumes.c
fs/btrfs/volumes.c
+7
-3
No files found.
fs/btrfs/ioctl.c
View file @
83bfccb5
...
@@ -1340,7 +1340,7 @@ static noinline int btrfs_ioctl_resize(struct file *file,
...
@@ -1340,7 +1340,7 @@ static noinline int btrfs_ioctl_resize(struct file *file,
1
))
{
1
))
{
pr_info
(
"btrfs: dev add/delete/balance/replace/resize operation in progress
\n
"
);
pr_info
(
"btrfs: dev add/delete/balance/replace/resize operation in progress
\n
"
);
mnt_drop_write_file
(
file
);
mnt_drop_write_file
(
file
);
return
-
EIN
PROGRESS
;
return
-
EIN
VAL
;
}
}
mutex_lock
(
&
root
->
fs_info
->
volume_mutex
);
mutex_lock
(
&
root
->
fs_info
->
volume_mutex
);
...
@@ -1446,8 +1446,8 @@ static noinline int btrfs_ioctl_resize(struct file *file,
...
@@ -1446,8 +1446,8 @@ static noinline int btrfs_ioctl_resize(struct file *file,
kfree
(
vol_args
);
kfree
(
vol_args
);
out:
out:
mutex_unlock
(
&
root
->
fs_info
->
volume_mutex
);
mutex_unlock
(
&
root
->
fs_info
->
volume_mutex
);
mnt_drop_write_file
(
file
);
atomic_set
(
&
root
->
fs_info
->
mutually_exclusive_operation_running
,
0
);
atomic_set
(
&
root
->
fs_info
->
mutually_exclusive_operation_running
,
0
);
mnt_drop_write_file
(
file
);
return
ret
;
return
ret
;
}
}
...
@@ -2186,19 +2186,20 @@ static int btrfs_ioctl_defrag(struct file *file, void __user *argp)
...
@@ -2186,19 +2186,20 @@ static int btrfs_ioctl_defrag(struct file *file, void __user *argp)
struct
btrfs_ioctl_defrag_range_args
*
range
;
struct
btrfs_ioctl_defrag_range_args
*
range
;
int
ret
;
int
ret
;
if
(
btrfs_root_readonly
(
root
))
ret
=
mnt_want_write_file
(
file
);
return
-
EROFS
;
if
(
ret
)
return
ret
;
if
(
atomic_xchg
(
&
root
->
fs_info
->
mutually_exclusive_operation_running
,
if
(
atomic_xchg
(
&
root
->
fs_info
->
mutually_exclusive_operation_running
,
1
))
{
1
))
{
pr_info
(
"btrfs: dev add/delete/balance/replace/resize operation in progress
\n
"
);
pr_info
(
"btrfs: dev add/delete/balance/replace/resize operation in progress
\n
"
);
return
-
EINPROGRESS
;
mnt_drop_write_file
(
file
);
return
-
EINVAL
;
}
}
ret
=
mnt_want_write_file
(
file
);
if
(
ret
)
{
if
(
btrfs_root_readonly
(
root
))
{
atomic_set
(
&
root
->
fs_info
->
mutually_exclusive_operation_running
,
ret
=
-
EROFS
;
0
);
goto
out
;
return
ret
;
}
}
switch
(
inode
->
i_mode
&
S_IFMT
)
{
switch
(
inode
->
i_mode
&
S_IFMT
)
{
...
@@ -2250,8 +2251,8 @@ static int btrfs_ioctl_defrag(struct file *file, void __user *argp)
...
@@ -2250,8 +2251,8 @@ static int btrfs_ioctl_defrag(struct file *file, void __user *argp)
ret
=
-
EINVAL
;
ret
=
-
EINVAL
;
}
}
out:
out:
mnt_drop_write_file
(
file
);
atomic_set
(
&
root
->
fs_info
->
mutually_exclusive_operation_running
,
0
);
atomic_set
(
&
root
->
fs_info
->
mutually_exclusive_operation_running
,
0
);
mnt_drop_write_file
(
file
);
return
ret
;
return
ret
;
}
}
...
@@ -2266,7 +2267,7 @@ static long btrfs_ioctl_add_dev(struct btrfs_root *root, void __user *arg)
...
@@ -2266,7 +2267,7 @@ static long btrfs_ioctl_add_dev(struct btrfs_root *root, void __user *arg)
if
(
atomic_xchg
(
&
root
->
fs_info
->
mutually_exclusive_operation_running
,
if
(
atomic_xchg
(
&
root
->
fs_info
->
mutually_exclusive_operation_running
,
1
))
{
1
))
{
pr_info
(
"btrfs: dev add/delete/balance/replace/resize operation in progress
\n
"
);
pr_info
(
"btrfs: dev add/delete/balance/replace/resize operation in progress
\n
"
);
return
-
EIN
PROGRESS
;
return
-
EIN
VAL
;
}
}
mutex_lock
(
&
root
->
fs_info
->
volume_mutex
);
mutex_lock
(
&
root
->
fs_info
->
volume_mutex
);
...
@@ -2303,7 +2304,7 @@ static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg)
...
@@ -2303,7 +2304,7 @@ static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg)
1
))
{
1
))
{
pr_info
(
"btrfs: dev add/delete/balance/replace/resize operation in progress
\n
"
);
pr_info
(
"btrfs: dev add/delete/balance/replace/resize operation in progress
\n
"
);
mnt_drop_write_file
(
file
);
mnt_drop_write_file
(
file
);
return
-
EIN
PROGRESS
;
return
-
EIN
VAL
;
}
}
mutex_lock
(
&
root
->
fs_info
->
volume_mutex
);
mutex_lock
(
&
root
->
fs_info
->
volume_mutex
);
...
@@ -2319,8 +2320,8 @@ static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg)
...
@@ -2319,8 +2320,8 @@ static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg)
kfree
(
vol_args
);
kfree
(
vol_args
);
out:
out:
mutex_unlock
(
&
root
->
fs_info
->
volume_mutex
);
mutex_unlock
(
&
root
->
fs_info
->
volume_mutex
);
mnt_drop_write_file
(
file
);
atomic_set
(
&
root
->
fs_info
->
mutually_exclusive_operation_running
,
0
);
atomic_set
(
&
root
->
fs_info
->
mutually_exclusive_operation_running
,
0
);
mnt_drop_write_file
(
file
);
return
ret
;
return
ret
;
}
}
...
@@ -3440,8 +3441,8 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg)
...
@@ -3440,8 +3441,8 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg)
struct
btrfs_fs_info
*
fs_info
=
root
->
fs_info
;
struct
btrfs_fs_info
*
fs_info
=
root
->
fs_info
;
struct
btrfs_ioctl_balance_args
*
bargs
;
struct
btrfs_ioctl_balance_args
*
bargs
;
struct
btrfs_balance_control
*
bctl
;
struct
btrfs_balance_control
*
bctl
;
bool
need_unlock
;
/* for mut. excl. ops lock */
int
ret
;
int
ret
;
int
need_to_clear_lock
=
0
;
if
(
!
capable
(
CAP_SYS_ADMIN
))
if
(
!
capable
(
CAP_SYS_ADMIN
))
return
-
EPERM
;
return
-
EPERM
;
...
@@ -3450,14 +3451,61 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg)
...
@@ -3450,14 +3451,61 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg)
if
(
ret
)
if
(
ret
)
return
ret
;
return
ret
;
again:
if
(
!
atomic_xchg
(
&
fs_info
->
mutually_exclusive_operation_running
,
1
))
{
mutex_lock
(
&
fs_info
->
volume_mutex
);
mutex_lock
(
&
fs_info
->
volume_mutex
);
mutex_lock
(
&
fs_info
->
balance_mutex
);
mutex_lock
(
&
fs_info
->
balance_mutex
);
need_unlock
=
true
;
goto
locked
;
}
/*
* mut. excl. ops lock is locked. Three possibilites:
* (1) some other op is running
* (2) balance is running
* (3) balance is paused -- special case (think resume)
*/
mutex_lock
(
&
fs_info
->
balance_mutex
);
if
(
fs_info
->
balance_ctl
)
{
/* this is either (2) or (3) */
if
(
!
atomic_read
(
&
fs_info
->
balance_running
))
{
mutex_unlock
(
&
fs_info
->
balance_mutex
);
if
(
!
mutex_trylock
(
&
fs_info
->
volume_mutex
))
goto
again
;
mutex_lock
(
&
fs_info
->
balance_mutex
);
if
(
fs_info
->
balance_ctl
&&
!
atomic_read
(
&
fs_info
->
balance_running
))
{
/* this is (3) */
need_unlock
=
false
;
goto
locked
;
}
mutex_unlock
(
&
fs_info
->
balance_mutex
);
mutex_unlock
(
&
fs_info
->
volume_mutex
);
goto
again
;
}
else
{
/* this is (2) */
mutex_unlock
(
&
fs_info
->
balance_mutex
);
ret
=
-
EINPROGRESS
;
goto
out
;
}
}
else
{
/* this is (1) */
mutex_unlock
(
&
fs_info
->
balance_mutex
);
pr_info
(
"btrfs: dev add/delete/balance/replace/resize operation in progress
\n
"
);
ret
=
-
EINVAL
;
goto
out
;
}
locked:
BUG_ON
(
!
atomic_read
(
&
fs_info
->
mutually_exclusive_operation_running
));
if
(
arg
)
{
if
(
arg
)
{
bargs
=
memdup_user
(
arg
,
sizeof
(
*
bargs
));
bargs
=
memdup_user
(
arg
,
sizeof
(
*
bargs
));
if
(
IS_ERR
(
bargs
))
{
if
(
IS_ERR
(
bargs
))
{
ret
=
PTR_ERR
(
bargs
);
ret
=
PTR_ERR
(
bargs
);
goto
out
;
goto
out
_unlock
;
}
}
if
(
bargs
->
flags
&
BTRFS_BALANCE_RESUME
)
{
if
(
bargs
->
flags
&
BTRFS_BALANCE_RESUME
)
{
...
@@ -3477,13 +3525,10 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg)
...
@@ -3477,13 +3525,10 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg)
bargs
=
NULL
;
bargs
=
NULL
;
}
}
if
(
atomic_xchg
(
&
root
->
fs_info
->
mutually_exclusive_operation_running
,
if
(
fs_info
->
balance_ctl
)
{
1
))
{
pr_info
(
"btrfs: dev add/delete/balance/replace/resize operation in progress
\n
"
);
ret
=
-
EINPROGRESS
;
ret
=
-
EINPROGRESS
;
goto
out_bargs
;
goto
out_bargs
;
}
}
need_to_clear_lock
=
1
;
bctl
=
kzalloc
(
sizeof
(
*
bctl
),
GFP_NOFS
);
bctl
=
kzalloc
(
sizeof
(
*
bctl
),
GFP_NOFS
);
if
(
!
bctl
)
{
if
(
!
bctl
)
{
...
@@ -3504,11 +3549,17 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg)
...
@@ -3504,11 +3549,17 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg)
}
}
do_balance:
do_balance:
ret
=
btrfs_balance
(
bctl
,
bargs
);
/*
/*
* bctl is freed in __cancel_balance or in free_fs_info if
* Ownership of bctl and mutually_exclusive_operation_running
* restriper was paused all the way until unmount
* goes to to btrfs_balance. bctl is freed in __cancel_balance,
* or, if restriper was paused all the way until unmount, in
* free_fs_info. mutually_exclusive_operation_running is
* cleared in __cancel_balance.
*/
*/
need_unlock
=
false
;
ret
=
btrfs_balance
(
bctl
,
bargs
);
if
(
arg
)
{
if
(
arg
)
{
if
(
copy_to_user
(
arg
,
bargs
,
sizeof
(
*
bargs
)))
if
(
copy_to_user
(
arg
,
bargs
,
sizeof
(
*
bargs
)))
ret
=
-
EFAULT
;
ret
=
-
EFAULT
;
...
@@ -3516,12 +3567,12 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg)
...
@@ -3516,12 +3567,12 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg)
out_bargs:
out_bargs:
kfree
(
bargs
);
kfree
(
bargs
);
out:
out_unlock:
if
(
need_to_clear_lock
)
atomic_set
(
&
root
->
fs_info
->
mutually_exclusive_operation_running
,
0
);
mutex_unlock
(
&
fs_info
->
balance_mutex
);
mutex_unlock
(
&
fs_info
->
balance_mutex
);
mutex_unlock
(
&
fs_info
->
volume_mutex
);
mutex_unlock
(
&
fs_info
->
volume_mutex
);
if
(
need_unlock
)
atomic_set
(
&
fs_info
->
mutually_exclusive_operation_running
,
0
);
out:
mnt_drop_write_file
(
file
);
mnt_drop_write_file
(
file
);
return
ret
;
return
ret
;
}
}
...
...
fs/btrfs/volumes.c
View file @
83bfccb5
...
@@ -2959,6 +2959,8 @@ static void __cancel_balance(struct btrfs_fs_info *fs_info)
...
@@ -2959,6 +2959,8 @@ static void __cancel_balance(struct btrfs_fs_info *fs_info)
unset_balance_control
(
fs_info
);
unset_balance_control
(
fs_info
);
ret
=
del_balance_item
(
fs_info
->
tree_root
);
ret
=
del_balance_item
(
fs_info
->
tree_root
);
BUG_ON
(
ret
);
BUG_ON
(
ret
);
atomic_set
(
&
fs_info
->
mutually_exclusive_operation_running
,
0
);
}
}
void
update_ioctl_balance_args
(
struct
btrfs_fs_info
*
fs_info
,
int
lock
,
void
update_ioctl_balance_args
(
struct
btrfs_fs_info
*
fs_info
,
int
lock
,
...
@@ -3138,8 +3140,10 @@ int btrfs_balance(struct btrfs_balance_control *bctl,
...
@@ -3138,8 +3140,10 @@ int btrfs_balance(struct btrfs_balance_control *bctl,
out:
out:
if
(
bctl
->
flags
&
BTRFS_BALANCE_RESUME
)
if
(
bctl
->
flags
&
BTRFS_BALANCE_RESUME
)
__cancel_balance
(
fs_info
);
__cancel_balance
(
fs_info
);
else
else
{
kfree
(
bctl
);
kfree
(
bctl
);
atomic_set
(
&
fs_info
->
mutually_exclusive_operation_running
,
0
);
}
return
ret
;
return
ret
;
}
}
...
@@ -3156,7 +3160,6 @@ static int balance_kthread(void *data)
...
@@ -3156,7 +3160,6 @@ static int balance_kthread(void *data)
ret
=
btrfs_balance
(
fs_info
->
balance_ctl
,
NULL
);
ret
=
btrfs_balance
(
fs_info
->
balance_ctl
,
NULL
);
}
}
atomic_set
(
&
fs_info
->
mutually_exclusive_operation_running
,
0
);
mutex_unlock
(
&
fs_info
->
balance_mutex
);
mutex_unlock
(
&
fs_info
->
balance_mutex
);
mutex_unlock
(
&
fs_info
->
volume_mutex
);
mutex_unlock
(
&
fs_info
->
volume_mutex
);
...
@@ -3179,7 +3182,6 @@ int btrfs_resume_balance_async(struct btrfs_fs_info *fs_info)
...
@@ -3179,7 +3182,6 @@ int btrfs_resume_balance_async(struct btrfs_fs_info *fs_info)
return
0
;
return
0
;
}
}
WARN_ON
(
atomic_xchg
(
&
fs_info
->
mutually_exclusive_operation_running
,
1
));
tsk
=
kthread_run
(
balance_kthread
,
fs_info
,
"btrfs-balance"
);
tsk
=
kthread_run
(
balance_kthread
,
fs_info
,
"btrfs-balance"
);
if
(
IS_ERR
(
tsk
))
if
(
IS_ERR
(
tsk
))
return
PTR_ERR
(
tsk
);
return
PTR_ERR
(
tsk
);
...
@@ -3233,6 +3235,8 @@ int btrfs_recover_balance(struct btrfs_fs_info *fs_info)
...
@@ -3233,6 +3235,8 @@ int btrfs_recover_balance(struct btrfs_fs_info *fs_info)
btrfs_balance_sys
(
leaf
,
item
,
&
disk_bargs
);
btrfs_balance_sys
(
leaf
,
item
,
&
disk_bargs
);
btrfs_disk_balance_args_to_cpu
(
&
bctl
->
sys
,
&
disk_bargs
);
btrfs_disk_balance_args_to_cpu
(
&
bctl
->
sys
,
&
disk_bargs
);
WARN_ON
(
atomic_xchg
(
&
fs_info
->
mutually_exclusive_operation_running
,
1
));
mutex_lock
(
&
fs_info
->
volume_mutex
);
mutex_lock
(
&
fs_info
->
volume_mutex
);
mutex_lock
(
&
fs_info
->
balance_mutex
);
mutex_lock
(
&
fs_info
->
balance_mutex
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment