btrfs-progs: mkfs: avoid dynamic allocation when doing --subvol
Reworks mkfs.btrfs --subvol so that dir and full_path in struct rootdir_subvol are stored as arrays rather than pointers. Signed-off-by: Mark Harmstone <maharmstone@fb.com>
This commit is contained in:
parent
59f74c25af
commit
6a1d4adad1
49
mkfs/main.c
49
mkfs/main.c
|
@ -1056,7 +1056,6 @@ int BOX_MAIN(mkfs)(int argc, char **argv)
|
||||||
char *label = NULL;
|
char *label = NULL;
|
||||||
int nr_global_roots = sysconf(_SC_NPROCESSORS_ONLN);
|
int nr_global_roots = sysconf(_SC_NPROCESSORS_ONLN);
|
||||||
char *source_dir = NULL;
|
char *source_dir = NULL;
|
||||||
size_t source_dir_len = 0;
|
|
||||||
struct rootdir_subvol *rds;
|
struct rootdir_subvol *rds;
|
||||||
bool has_default_subvol = false;
|
bool has_default_subvol = false;
|
||||||
LIST_HEAD(subvols);
|
LIST_HEAD(subvols);
|
||||||
|
@ -1245,10 +1244,12 @@ int BOX_MAIN(mkfs)(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valid_prefix)
|
if (arg_copy_path(subvol->dir, valid_prefix ? colon + 1 : optarg,
|
||||||
subvol->dir = strndup(colon + 1, strlen(colon + 1));
|
sizeof(subvol->dir))) {
|
||||||
else
|
error("--subvol path too long");
|
||||||
subvol->dir = strdup(optarg);
|
ret = 1;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
if (subvol->is_default) {
|
if (subvol->is_default) {
|
||||||
if (has_default_subvol) {
|
if (has_default_subvol) {
|
||||||
|
@ -1343,57 +1344,37 @@ int BOX_MAIN(mkfs)(int argc, char **argv)
|
||||||
|
|
||||||
free(source_dir);
|
free(source_dir);
|
||||||
source_dir = canonical;
|
source_dir = canonical;
|
||||||
source_dir_len = strlen(source_dir);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry(rds, &subvols, list) {
|
list_for_each_entry(rds, &subvols, list) {
|
||||||
char *path, *canonical;
|
char path[PATH_MAX];
|
||||||
struct rootdir_subvol *rds2;
|
struct rootdir_subvol *rds2;
|
||||||
size_t dir_len;
|
|
||||||
|
|
||||||
dir_len = strlen(rds->dir);
|
if (path_cat_out(path, source_dir, rds->dir)) {
|
||||||
|
error("path invalid");
|
||||||
path = malloc(source_dir_len + 1 + dir_len + 1);
|
|
||||||
if (!path) {
|
|
||||||
error_msg(ERROR_MSG_MEMORY, NULL);
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(path, source_dir, source_dir_len);
|
if (!realpath(path, rds->full_path)) {
|
||||||
path[source_dir_len] = '/';
|
|
||||||
memcpy(path + source_dir_len + 1, rds->dir, dir_len + 1);
|
|
||||||
|
|
||||||
canonical = realpath(path, NULL);
|
|
||||||
if (!canonical) {
|
|
||||||
error("could not get canonical path to %s", rds->dir);
|
error("could not get canonical path to %s", rds->dir);
|
||||||
free(path);
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(path);
|
if (!path_exists(rds->full_path)) {
|
||||||
path = canonical;
|
|
||||||
|
|
||||||
if (!path_exists(path)) {
|
|
||||||
error("subvolume %s does not exist", rds->dir);
|
error("subvolume %s does not exist", rds->dir);
|
||||||
free(path);
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!path_is_dir(path)) {
|
if (!path_is_dir(rds->full_path)) {
|
||||||
error("subvolume %s is not a directory", rds->dir);
|
error("subvolume %s is not a directory", rds->dir);
|
||||||
free(path);
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
rds->full_path = path;
|
if (!path_is_in_dir(source_dir, rds->full_path)) {
|
||||||
|
|
||||||
if (strlen(path) < source_dir_len + 1 ||
|
|
||||||
memcmp(path, source_dir, source_dir_len) != 0 ||
|
|
||||||
path[source_dir_len] != '/') {
|
|
||||||
error("subvolume %s is not a child of %s", rds->dir, source_dir);
|
error("subvolume %s is not a child of %s", rds->dir, source_dir);
|
||||||
ret = 1;
|
ret = 1;
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -1402,7 +1383,7 @@ int BOX_MAIN(mkfs)(int argc, char **argv)
|
||||||
for (rds2 = list_first_entry(&subvols, struct rootdir_subvol, list);
|
for (rds2 = list_first_entry(&subvols, struct rootdir_subvol, list);
|
||||||
rds2 != rds;
|
rds2 != rds;
|
||||||
rds2 = list_next_entry(rds2, list)) {
|
rds2 = list_next_entry(rds2, list)) {
|
||||||
if (strcmp(rds2->full_path, path) == 0) {
|
if (strcmp(rds2->full_path, rds->full_path) == 0) {
|
||||||
error("subvolume %s specified more than once", rds->dir);
|
error("subvolume %s specified more than once", rds->dir);
|
||||||
ret = 1;
|
ret = 1;
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -2113,8 +2094,6 @@ error:
|
||||||
struct rootdir_subvol *head;
|
struct rootdir_subvol *head;
|
||||||
|
|
||||||
head = list_entry(subvols.next, struct rootdir_subvol, list);
|
head = list_entry(subvols.next, struct rootdir_subvol, list);
|
||||||
free(head->dir);
|
|
||||||
free(head->full_path);
|
|
||||||
list_del(&head->list);
|
list_del(&head->list);
|
||||||
free(head);
|
free(head);
|
||||||
}
|
}
|
||||||
|
|
|
@ -711,9 +711,6 @@ static int ftw_add_inode(const char *full_path, const struct stat *st,
|
||||||
ret = ftw_add_subvol(full_path, st, typeflag,
|
ret = ftw_add_subvol(full_path, st, typeflag,
|
||||||
ftwbuf, rds);
|
ftwbuf, rds);
|
||||||
|
|
||||||
free(rds->dir);
|
|
||||||
free(rds->full_path);
|
|
||||||
|
|
||||||
list_del(&rds->list);
|
list_del(&rds->list);
|
||||||
free(rds);
|
free(rds);
|
||||||
|
|
||||||
|
|
|
@ -30,8 +30,8 @@ struct btrfs_root;
|
||||||
|
|
||||||
struct rootdir_subvol {
|
struct rootdir_subvol {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
char *dir;
|
char dir[PATH_MAX];
|
||||||
char *full_path;
|
char full_path[PATH_MAX];
|
||||||
bool is_default;
|
bool is_default;
|
||||||
bool readonly;
|
bool readonly;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue