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
36fac9e9
Commit
36fac9e9
authored
May 16, 2016
by
David Sterba
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'foreign/anand/dev-del-by-id-ext' into for-chris-4.7-20160516
parents
5ef64a3e
88acff64
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
324 additions
and
242 deletions
+324
-242
fs/btrfs/dev-replace.c
fs/btrfs/dev-replace.c
+44
-55
fs/btrfs/dev-replace.h
fs/btrfs/dev-replace.h
+3
-1
fs/btrfs/ioctl.c
fs/btrfs/ioctl.c
+58
-2
fs/btrfs/volumes.c
fs/btrfs/volumes.c
+198
-181
fs/btrfs/volumes.h
fs/btrfs/volumes.h
+7
-2
include/uapi/linux/btrfs.h
include/uapi/linux/btrfs.h
+14
-1
No files found.
fs/btrfs/dev-replace.c
View file @
36fac9e9
...
...
@@ -44,9 +44,6 @@ static void btrfs_dev_replace_update_device_in_mapping_tree(
struct
btrfs_fs_info
*
fs_info
,
struct
btrfs_device
*
srcdev
,
struct
btrfs_device
*
tgtdev
);
static
int
btrfs_dev_replace_find_srcdev
(
struct
btrfs_root
*
root
,
u64
srcdevid
,
char
*
srcdev_name
,
struct
btrfs_device
**
device
);
static
u64
__btrfs_dev_replace_cancel
(
struct
btrfs_fs_info
*
fs_info
);
static
int
btrfs_dev_replace_kthread
(
void
*
data
);
static
int
btrfs_dev_replace_continue_on_mount
(
struct
btrfs_fs_info
*
fs_info
);
...
...
@@ -305,8 +302,8 @@ void btrfs_after_dev_replace_commit(struct btrfs_fs_info *fs_info)
dev_replace
->
cursor_left_last_write_of_item
;
}
int
btrfs_dev_replace_start
(
struct
btrfs_root
*
root
,
struct
btrfs_ioctl_dev_replace_args
*
args
)
int
btrfs_dev_replace_start
(
struct
btrfs_root
*
root
,
char
*
tgtdev_name
,
u64
srcdevid
,
char
*
srcdev_name
,
int
read_src
)
{
struct
btrfs_trans_handle
*
trans
;
struct
btrfs_fs_info
*
fs_info
=
root
->
fs_info
;
...
...
@@ -315,29 +312,16 @@ int btrfs_dev_replace_start(struct btrfs_root *root,
struct
btrfs_device
*
tgt_device
=
NULL
;
struct
btrfs_device
*
src_device
=
NULL
;
switch
(
args
->
start
.
cont_reading_from_srcdev_mode
)
{
case
BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_ALWAYS
:
case
BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_AVOID
:
break
;
default:
return
-
EINVAL
;
}
if
((
args
->
start
.
srcdevid
==
0
&&
args
->
start
.
srcdev_name
[
0
]
==
'\0'
)
||
args
->
start
.
tgtdev_name
[
0
]
==
'\0'
)
return
-
EINVAL
;
/* the disk copy procedure reuses the scrub code */
mutex_lock
(
&
fs_info
->
volume_mutex
);
ret
=
btrfs_dev_replace_find_srcdev
(
root
,
args
->
start
.
srcdevid
,
args
->
start
.
srcdev_name
,
&
src_device
);
ret
=
btrfs_find_device_by_devspec
(
root
,
srcdevid
,
srcdev_name
,
&
src_device
);
if
(
ret
)
{
mutex_unlock
(
&
fs_info
->
volume_mutex
);
return
ret
;
}
ret
=
btrfs_init_dev_replace_tgtdev
(
root
,
args
->
start
.
tgtdev_name
,
ret
=
btrfs_init_dev_replace_tgtdev
(
root
,
tgtdev_name
,
src_device
,
&
tgt_device
);
mutex_unlock
(
&
fs_info
->
volume_mutex
);
if
(
ret
)
...
...
@@ -364,18 +348,17 @@ int btrfs_dev_replace_start(struct btrfs_root *root,
break
;
case
BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED
:
case
BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED
:
args
->
resul
t
=
BTRFS_IOCTL_DEV_REPLACE_RESULT_ALREADY_STARTED
;
re
t
=
BTRFS_IOCTL_DEV_REPLACE_RESULT_ALREADY_STARTED
;
goto
leave
;
}
dev_replace
->
cont_reading_from_srcdev_mode
=
args
->
start
.
cont_reading_from_srcdev_mode
;
dev_replace
->
cont_reading_from_srcdev_mode
=
read_src
;
WARN_ON
(
!
src_device
);
dev_replace
->
srcdev
=
src_device
;
WARN_ON
(
!
tgt_device
);
dev_replace
->
tgtdev
=
tgt_device
;
btrfs_info_in_rcu
(
root
->
fs_info
,
btrfs_info_in_rcu
(
fs_info
,
"dev_replace from %s (devid %llu) to %s started"
,
src_device
->
missing
?
"<missing disk>"
:
rcu_str_deref
(
src_device
->
name
),
...
...
@@ -396,14 +379,13 @@ int btrfs_dev_replace_start(struct btrfs_root *root,
dev_replace
->
item_needs_writeback
=
1
;
atomic64_set
(
&
dev_replace
->
num_write_errors
,
0
);
atomic64_set
(
&
dev_replace
->
num_uncorrectable_read_errors
,
0
);
args
->
result
=
BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR
;
btrfs_dev_replace_unlock
(
dev_replace
,
1
);
ret
=
btrfs_sysfs_add_device_link
(
tgt_device
->
fs_devices
,
tgt_device
);
if
(
ret
)
btrfs_err
(
root
->
fs_info
,
"kobj add dev failed %d
\n
"
,
ret
);
btrfs_err
(
fs_info
,
"kobj add dev failed %d
\n
"
,
ret
);
btrfs_wait_ordered_roots
(
root
->
fs_info
,
-
1
);
btrfs_wait_ordered_roots
(
fs_info
,
-
1
);
/* force writing the updated state information to disk */
trans
=
btrfs_start_transaction
(
root
,
0
);
...
...
@@ -421,11 +403,9 @@ int btrfs_dev_replace_start(struct btrfs_root *root,
btrfs_device_get_total_bytes
(
src_device
),
&
dev_replace
->
scrub_progress
,
0
,
1
);
ret
=
btrfs_dev_replace_finishing
(
root
->
fs_info
,
ret
);
/* don't warn if EINPROGRESS, someone else might be running scrub */
ret
=
btrfs_dev_replace_finishing
(
fs_info
,
ret
);
if
(
ret
==
-
EINPROGRESS
)
{
args
->
result
=
BTRFS_IOCTL_DEV_REPLACE_RESULT_SCRUB_INPROGRESS
;
ret
=
0
;
ret
=
BTRFS_IOCTL_DEV_REPLACE_RESULT_SCRUB_INPROGRESS
;
}
else
{
WARN_ON
(
ret
);
}
...
...
@@ -440,6 +420,35 @@ int btrfs_dev_replace_start(struct btrfs_root *root,
return
ret
;
}
int
btrfs_dev_replace_by_ioctl
(
struct
btrfs_root
*
root
,
struct
btrfs_ioctl_dev_replace_args
*
args
)
{
int
ret
;
switch
(
args
->
start
.
cont_reading_from_srcdev_mode
)
{
case
BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_ALWAYS
:
case
BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_AVOID
:
break
;
default:
return
-
EINVAL
;
}
if
((
args
->
start
.
srcdevid
==
0
&&
args
->
start
.
srcdev_name
[
0
]
==
'\0'
)
||
args
->
start
.
tgtdev_name
[
0
]
==
'\0'
)
return
-
EINVAL
;
ret
=
btrfs_dev_replace_start
(
root
,
args
->
start
.
tgtdev_name
,
args
->
start
.
srcdevid
,
args
->
start
.
srcdev_name
,
args
->
start
.
cont_reading_from_srcdev_mode
);
args
->
result
=
ret
;
/* don't warn if EINPROGRESS, someone else might be running scrub */
if
(
ret
==
BTRFS_IOCTL_DEV_REPLACE_RESULT_SCRUB_INPROGRESS
)
ret
=
0
;
return
ret
;
}
/*
* blocked until all flighting bios are finished.
*/
...
...
@@ -560,10 +569,9 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
ASSERT
(
list_empty
(
&
src_device
->
resized_list
));
tgt_device
->
commit_total_bytes
=
src_device
->
commit_total_bytes
;
tgt_device
->
commit_bytes_used
=
src_device
->
bytes_used
;
if
(
fs_info
->
sb
->
s_bdev
==
src_device
->
bdev
)
fs_info
->
sb
->
s_bdev
=
tgt_device
->
bdev
;
if
(
fs_info
->
fs_devices
->
latest_bdev
==
src_device
->
bdev
)
fs_info
->
fs_devices
->
latest_bdev
=
tgt_device
->
bdev
;
btrfs_assign_next_active_device
(
fs_info
,
src_device
,
tgt_device
);
list_add
(
&
tgt_device
->
dev_alloc_list
,
&
fs_info
->
fs_devices
->
alloc_list
);
fs_info
->
fs_devices
->
rw_devices
++
;
...
...
@@ -626,25 +634,6 @@ static void btrfs_dev_replace_update_device_in_mapping_tree(
write_unlock
(
&
em_tree
->
lock
);
}
static
int
btrfs_dev_replace_find_srcdev
(
struct
btrfs_root
*
root
,
u64
srcdevid
,
char
*
srcdev_name
,
struct
btrfs_device
**
device
)
{
int
ret
;
if
(
srcdevid
)
{
ret
=
0
;
*
device
=
btrfs_find_device
(
root
->
fs_info
,
srcdevid
,
NULL
,
NULL
);
if
(
!*
device
)
ret
=
-
ENOENT
;
}
else
{
ret
=
btrfs_find_device_missing_or_by_path
(
root
,
srcdev_name
,
device
);
}
return
ret
;
}
void
btrfs_dev_replace_status
(
struct
btrfs_fs_info
*
fs_info
,
struct
btrfs_ioctl_dev_replace_args
*
args
)
{
...
...
fs/btrfs/dev-replace.h
View file @
36fac9e9
...
...
@@ -25,8 +25,10 @@ int btrfs_init_dev_replace(struct btrfs_fs_info *fs_info);
int
btrfs_run_dev_replace
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_fs_info
*
fs_info
);
void
btrfs_after_dev_replace_commit
(
struct
btrfs_fs_info
*
fs_info
);
int
btrfs_dev_replace_
start
(
struct
btrfs_root
*
root
,
int
btrfs_dev_replace_
by_ioctl
(
struct
btrfs_root
*
root
,
struct
btrfs_ioctl_dev_replace_args
*
args
);
int
btrfs_dev_replace_start
(
struct
btrfs_root
*
root
,
char
*
tgtdev_name
,
u64
srcdevid
,
char
*
srcdev_name
,
int
read_src
);
void
btrfs_dev_replace_status
(
struct
btrfs_fs_info
*
fs_info
,
struct
btrfs_ioctl_dev_replace_args
*
args
);
int
btrfs_dev_replace_cancel
(
struct
btrfs_fs_info
*
fs_info
,
...
...
fs/btrfs/ioctl.c
View file @
36fac9e9
...
...
@@ -2676,6 +2676,60 @@ static long btrfs_ioctl_add_dev(struct btrfs_root *root, void __user *arg)
return
ret
;
}
static
long
btrfs_ioctl_rm_dev_v2
(
struct
file
*
file
,
void
__user
*
arg
)
{
struct
btrfs_root
*
root
=
BTRFS_I
(
file_inode
(
file
))
->
root
;
struct
btrfs_ioctl_vol_args_v2
*
vol_args
;
int
ret
;
if
(
!
capable
(
CAP_SYS_ADMIN
))
return
-
EPERM
;
ret
=
mnt_want_write_file
(
file
);
if
(
ret
)
return
ret
;
vol_args
=
memdup_user
(
arg
,
sizeof
(
*
vol_args
));
if
(
IS_ERR
(
vol_args
))
{
ret
=
PTR_ERR
(
vol_args
);
goto
err_drop
;
}
/* Check for compatibility reject unknown flags */
if
(
vol_args
->
flags
&
~
BTRFS_VOL_ARG_V2_FLAGS_SUPPORTED
)
return
-
EOPNOTSUPP
;
if
(
atomic_xchg
(
&
root
->
fs_info
->
mutually_exclusive_operation_running
,
1
))
{
ret
=
BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS
;
goto
out
;
}
mutex_lock
(
&
root
->
fs_info
->
volume_mutex
);
if
(
vol_args
->
flags
&
BTRFS_DEVICE_SPEC_BY_ID
)
{
ret
=
btrfs_rm_device
(
root
,
NULL
,
vol_args
->
devid
);
}
else
{
vol_args
->
name
[
BTRFS_SUBVOL_NAME_MAX
]
=
'\0'
;
ret
=
btrfs_rm_device
(
root
,
vol_args
->
name
,
0
);
}
mutex_unlock
(
&
root
->
fs_info
->
volume_mutex
);
atomic_set
(
&
root
->
fs_info
->
mutually_exclusive_operation_running
,
0
);
if
(
!
ret
)
{
if
(
vol_args
->
flags
&
BTRFS_DEVICE_SPEC_BY_ID
)
btrfs_info
(
root
->
fs_info
,
"device deleted: id %llu"
,
vol_args
->
devid
);
else
btrfs_info
(
root
->
fs_info
,
"device deleted: %s"
,
vol_args
->
name
);
}
out:
kfree
(
vol_args
);
err_drop:
mnt_drop_write_file
(
file
);
return
ret
;
}
static
long
btrfs_ioctl_rm_dev
(
struct
file
*
file
,
void
__user
*
arg
)
{
struct
btrfs_root
*
root
=
BTRFS_I
(
file_inode
(
file
))
->
root
;
...
...
@@ -2703,7 +2757,7 @@ static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg)
vol_args
->
name
[
BTRFS_PATH_NAME_MAX
]
=
'\0'
;
mutex_lock
(
&
root
->
fs_info
->
volume_mutex
);
ret
=
btrfs_rm_device
(
root
,
vol_args
->
name
);
ret
=
btrfs_rm_device
(
root
,
vol_args
->
name
,
0
);
mutex_unlock
(
&
root
->
fs_info
->
volume_mutex
);
if
(
!
ret
)
...
...
@@ -4387,7 +4441,7 @@ static long btrfs_ioctl_dev_replace(struct btrfs_root *root, void __user *arg)
1
))
{
ret
=
BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS
;
}
else
{
ret
=
btrfs_dev_replace_
start
(
root
,
p
);
ret
=
btrfs_dev_replace_
by_ioctl
(
root
,
p
);
atomic_set
(
&
root
->
fs_info
->
mutually_exclusive_operation_running
,
0
);
...
...
@@ -5480,6 +5534,8 @@ long btrfs_ioctl(struct file *file, unsigned int
return
btrfs_ioctl_add_dev
(
root
,
argp
);
case
BTRFS_IOC_RM_DEV
:
return
btrfs_ioctl_rm_dev
(
file
,
argp
);
case
BTRFS_IOC_RM_DEV_V2
:
return
btrfs_ioctl_rm_dev_v2
(
file
,
argp
);
case
BTRFS_IOC_FS_INFO
:
return
btrfs_ioctl_fs_info
(
root
,
argp
);
case
BTRFS_IOC_DEV_INFO
:
...
...
fs/btrfs/volumes.c
View file @
36fac9e9
This diff is collapsed.
Click to expand it.
fs/btrfs/volumes.h
View file @
36fac9e9
...
...
@@ -340,7 +340,7 @@ struct btrfs_raid_attr {
};
extern
const
struct
btrfs_raid_attr
btrfs_raid_array
[
BTRFS_NR_RAID_TYPES
];
extern
const
int
btrfs_raid_mindev_error
[
BTRFS_NR_RAID_TYPES
];
extern
const
u64
btrfs_raid_group
[
BTRFS_NR_RAID_TYPES
];
struct
map_lookup
{
...
...
@@ -445,13 +445,18 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
struct
btrfs_fs_devices
**
fs_devices_ret
);
int
btrfs_close_devices
(
struct
btrfs_fs_devices
*
fs_devices
);
void
btrfs_close_extra_devices
(
struct
btrfs_fs_devices
*
fs_devices
,
int
step
);
void
btrfs_assign_next_active_device
(
struct
btrfs_fs_info
*
fs_info
,
struct
btrfs_device
*
device
,
struct
btrfs_device
*
this_dev
);
int
btrfs_find_device_missing_or_by_path
(
struct
btrfs_root
*
root
,
char
*
device_path
,
struct
btrfs_device
**
device
);
int
btrfs_find_device_by_devspec
(
struct
btrfs_root
*
root
,
u64
devid
,
char
*
devpath
,
struct
btrfs_device
**
device
);
struct
btrfs_device
*
btrfs_alloc_device
(
struct
btrfs_fs_info
*
fs_info
,
const
u64
*
devid
,
const
u8
*
uuid
);
int
btrfs_rm_device
(
struct
btrfs_root
*
root
,
char
*
device_path
);
int
btrfs_rm_device
(
struct
btrfs_root
*
root
,
char
*
device_path
,
u64
devid
);
void
btrfs_cleanup_fs_uuids
(
void
);
int
btrfs_num_copies
(
struct
btrfs_fs_info
*
fs_info
,
u64
logical
,
u64
len
);
int
btrfs_grow_device
(
struct
btrfs_trans_handle
*
trans
,
...
...
include/uapi/linux/btrfs.h
View file @
36fac9e9
...
...
@@ -36,6 +36,14 @@ struct btrfs_ioctl_vol_args {
#define BTRFS_SUBVOL_CREATE_ASYNC (1ULL << 0)
#define BTRFS_SUBVOL_RDONLY (1ULL << 1)
#define BTRFS_SUBVOL_QGROUP_INHERIT (1ULL << 2)
#define BTRFS_DEVICE_SPEC_BY_ID (1ULL << 3)
#define BTRFS_VOL_ARG_V2_FLAGS_SUPPORTED \
(BTRFS_SUBVOL_CREATE_ASYNC | \
BTRFS_SUBVOL_RDONLY | \
BTRFS_SUBVOL_QGROUP_INHERIT | \
BTRFS_DEVICE_SPEC_BY_ID)
#define BTRFS_FSID_SIZE 16
#define BTRFS_UUID_SIZE 16
#define BTRFS_UUID_UNPARSED_SIZE 37
...
...
@@ -76,7 +84,10 @@ struct btrfs_ioctl_vol_args_v2 {
};
__u64
unused
[
4
];
};
char
name
[
BTRFS_SUBVOL_NAME_MAX
+
1
];
union
{
char
name
[
BTRFS_SUBVOL_NAME_MAX
+
1
];
u64
devid
;
};
};
/*
...
...
@@ -659,5 +670,7 @@ static inline char *btrfs_err_str(enum btrfs_err_code err_code)
struct btrfs_ioctl_feature_flags[2])
#define BTRFS_IOC_GET_SUPPORTED_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 57, \
struct btrfs_ioctl_feature_flags[3])
#define BTRFS_IOC_RM_DEV_V2 _IOW(BTRFS_IOCTL_MAGIC, 58, \
struct btrfs_ioctl_vol_args_v2)
#endif
/* _UAPI_LINUX_BTRFS_H */
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