btrfs-progs: mkfs: add ro flag to --subvol
Adds a flag to mkfs.btrfs --subvol to allow subvolumes to be created readonly. Signed-off-by: Mark Harmstone <maharmstone@fb.com>
This commit is contained in:
parent
fa70df7e78
commit
ec8a6b1536
|
@ -163,6 +163,7 @@ OPTIONS
|
||||||
*flags* is an optional comma-separated list of modifiers. Valid choices are:
|
*flags* is an optional comma-separated list of modifiers. Valid choices are:
|
||||||
|
|
||||||
* *default*: create as default subvolume (this can only be specified once)
|
* *default*: create as default subvolume (this can only be specified once)
|
||||||
|
* *ro*: create as readonly subvolume
|
||||||
|
|
||||||
--shrink
|
--shrink
|
||||||
Shrink the filesystem to its minimal size, only works with *--rootdir* option.
|
Shrink the filesystem to its minimal size, only works with *--rootdir* option.
|
||||||
|
|
|
@ -66,7 +66,8 @@ error:
|
||||||
* The created tree root would have its root_ref as 1.
|
* The created tree root would have its root_ref as 1.
|
||||||
* Thus for subvolumes caller needs to properly add ROOT_BACKREF items.
|
* Thus for subvolumes caller needs to properly add ROOT_BACKREF items.
|
||||||
*/
|
*/
|
||||||
int btrfs_make_subvolume(struct btrfs_trans_handle *trans, u64 objectid)
|
int btrfs_make_subvolume(struct btrfs_trans_handle *trans, u64 objectid,
|
||||||
|
bool readonly)
|
||||||
{
|
{
|
||||||
struct btrfs_fs_info *fs_info = trans->fs_info;
|
struct btrfs_fs_info *fs_info = trans->fs_info;
|
||||||
struct btrfs_root *root;
|
struct btrfs_root *root;
|
||||||
|
@ -98,6 +99,13 @@ int btrfs_make_subvolume(struct btrfs_trans_handle *trans, u64 objectid)
|
||||||
ret = btrfs_make_root_dir(trans, root, BTRFS_FIRST_FREE_OBJECTID);
|
ret = btrfs_make_root_dir(trans, root, BTRFS_FIRST_FREE_OBJECTID);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
btrfs_set_stack_inode_flags(&root->root_item.inode,
|
||||||
|
BTRFS_INODE_ROOT_ITEM_INIT);
|
||||||
|
|
||||||
|
if (readonly)
|
||||||
|
btrfs_set_root_flags(&root->root_item, BTRFS_ROOT_SUBVOL_RDONLY);
|
||||||
|
|
||||||
ret = btrfs_update_root(trans, fs_info->tree_root, &root->root_key,
|
ret = btrfs_update_root(trans, fs_info->tree_root, &root->root_key,
|
||||||
&root->root_item);
|
&root->root_item);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
|
|
@ -21,7 +21,8 @@
|
||||||
|
|
||||||
int btrfs_make_root_dir(struct btrfs_trans_handle *trans,
|
int btrfs_make_root_dir(struct btrfs_trans_handle *trans,
|
||||||
struct btrfs_root *root, u64 objectid);
|
struct btrfs_root *root, u64 objectid);
|
||||||
int btrfs_make_subvolume(struct btrfs_trans_handle *trans, u64 objectid);
|
int btrfs_make_subvolume(struct btrfs_trans_handle *trans, u64 objectid,
|
||||||
|
bool readonly);
|
||||||
int btrfs_link_subvolume(struct btrfs_trans_handle *trans,
|
int btrfs_link_subvolume(struct btrfs_trans_handle *trans,
|
||||||
struct btrfs_root *parent_root,
|
struct btrfs_root *parent_root,
|
||||||
u64 parent_dir, const char *name,
|
u64 parent_dir, const char *name,
|
||||||
|
|
|
@ -1022,13 +1022,14 @@ static int init_btrfs(struct btrfs_mkfs_config *cfg, struct btrfs_root *root,
|
||||||
BTRFS_FIRST_FREE_OBJECTID);
|
BTRFS_FIRST_FREE_OBJECTID);
|
||||||
|
|
||||||
/* subvol for fs image file */
|
/* subvol for fs image file */
|
||||||
ret = btrfs_make_subvolume(trans, CONV_IMAGE_SUBVOL_OBJECTID);
|
ret = btrfs_make_subvolume(trans, CONV_IMAGE_SUBVOL_OBJECTID, false);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error("failed to create subvolume image root: %d", ret);
|
error("failed to create subvolume image root: %d", ret);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
/* subvol for data relocation tree */
|
/* subvol for data relocation tree */
|
||||||
ret = btrfs_make_subvolume(trans, BTRFS_DATA_RELOC_TREE_OBJECTID);
|
ret = btrfs_make_subvolume(trans, BTRFS_DATA_RELOC_TREE_OBJECTID,
|
||||||
|
false);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error("failed to create DATA_RELOC root: %d", ret);
|
error("failed to create DATA_RELOC root: %d", ret);
|
||||||
goto err;
|
goto err;
|
||||||
|
|
|
@ -1036,6 +1036,8 @@ static int parse_subvol_flags(struct rootdir_subvol *subvol, const char *flags)
|
||||||
|
|
||||||
if (!strcmp(buf, "default")) {
|
if (!strcmp(buf, "default")) {
|
||||||
subvol->is_default = true;
|
subvol->is_default = true;
|
||||||
|
} else if (!strcmp(buf, "ro")) {
|
||||||
|
subvol->readonly = true;
|
||||||
} else if (buf[0] != 0) {
|
} else if (buf[0] != 0) {
|
||||||
error("unrecognized subvol flag \"%s\"", buf);
|
error("unrecognized subvol flag \"%s\"", buf);
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
@ -1988,7 +1990,8 @@ raid_groups:
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = btrfs_make_subvolume(trans, BTRFS_DATA_RELOC_TREE_OBJECTID);
|
ret = btrfs_make_subvolume(trans, BTRFS_DATA_RELOC_TREE_OBJECTID,
|
||||||
|
false);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
error("unable to create data reloc tree: %d", ret);
|
error("unable to create data reloc tree: %d", ret);
|
||||||
goto out;
|
goto out;
|
||||||
|
|
|
@ -430,7 +430,7 @@ static int ftw_add_subvol(const char *full_path, const struct stat *st,
|
||||||
|
|
||||||
subvol_id = next_subvol_id++;
|
subvol_id = next_subvol_id++;
|
||||||
|
|
||||||
ret = btrfs_make_subvolume(g_trans, subvol_id);
|
ret = btrfs_make_subvolume(g_trans, subvol_id, subvol->readonly);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
errno = -ret;
|
errno = -ret;
|
||||||
error("failed to create subvolume: %m");
|
error("failed to create subvolume: %m");
|
||||||
|
|
|
@ -33,6 +33,7 @@ struct rootdir_subvol {
|
||||||
char *dir;
|
char *dir;
|
||||||
char *full_path;
|
char *full_path;
|
||||||
bool is_default;
|
bool is_default;
|
||||||
|
bool readonly;
|
||||||
};
|
};
|
||||||
|
|
||||||
int btrfs_mkfs_fill_dir(struct btrfs_trans_handle *trans, const char *source_dir,
|
int btrfs_mkfs_fill_dir(struct btrfs_trans_handle *trans, const char *source_dir,
|
||||||
|
|
Loading…
Reference in New Issue