Btrfs-progs: allow btrfstune to set persistent mount options
RFC PATCH 1/1 Btrfs-progs: allow btrfstune to set persistent mount options
This is the complement to the corresponding kernel patch that adds support for permanent options.
NOTE: Like the corresponding kernel patch, this is a WIP with the goal o gathering feedback.
Signed-off-by Filipe David Borba Manana <[email protected]>
--- btrfstune.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- ctree.h | 8 +++++ print-tree.c | 9 +++++ 3 files changed, 120 insertions(+), 2 deletions(-)
btrfstune.c +103 -2
@@ -97,12 +97,100 @@ int enable_skinny_metadata(struct btrfs_root *root)return 0 ; } +static int set_persistent_mount_options (struct btrfs_root *root, +const char *options) +{ +int ret; +struct btrfs_trans_handle *trans =NULL ; +struct btrfs_path *path; +struct btrfs_key key, location; +struct extent_buffer *leaf; +struct btrfs_dir_item *dir_item; +struct btrfs_disk_key disk_key; +struct btrfs_root *tree_root = root->fs_info->tree_root; +unsigned long data_ptr; +u32 data_size, data_len; + + path =btrfs_alloc_path (); +if (!path) +return -ENOMEM ; + + trans =btrfs_start_transaction (root,1 ); +if (!trans) { + ret = -ENOMEM ; + goto out; + } + + key.objectid =BTRFS_PERSISTENT_OPTIONS_OBJECTID ; + key.type =0 ; + key.offset =0 ; + + ret =btrfs_search_slot (trans, tree_root, &key, path,-1 ,1 ); +if (ret <0 ) + goto out; +if (!ret) { +char *buf; + + leaf = path->nodes[0 ]; + dir_item =btrfs_item_ptr (leaf, path->slots[0 ], + struct btrfs_dir_item); + buf = (char *)malloc (btrfs_dir_data_len (leaf, dir_item)); +if (!buf) { + ret = -ENOMEM ; + goto out; + } +read_extent_buffer (leaf, buf, + (unsigned long )((char *)(dir_item +1 )), +btrfs_dir_data_len (leaf, dir_item)); +printf ("Current persistent options: %.*s\n" , +btrfs_dir_data_len (leaf, dir_item), buf); +free (buf); + ret =btrfs_del_item (trans, tree_root, path); +if (ret) + goto out; + } + +btrfs_release_path (root, path); + + data_len =strlen (options); + data_size =sizeof (*dir_item) + data_len; + ret =btrfs_insert_empty_item (trans, tree_root, path, &key, data_size); +if (ret) + goto out; + + leaf = path->nodes[0 ]; + dir_item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dir_item); + +memset (&location,0 ,sizeof (location)); +btrfs_cpu_key_to_disk (&disk_key, &location); +btrfs_set_dir_item_key (leaf, dir_item, &disk_key); +btrfs_set_dir_type (leaf, dir_item,BTRFS_FT_UNKNOWN ); +btrfs_set_dir_name_len (leaf, dir_item,0 ); +btrfs_set_dir_data_len (leaf, dir_item, data_len); + data_ptr = (unsigned long )((char *)(dir_item +1 )); + +write_extent_buffer (leaf, options, data_ptr, data_len); +btrfs_mark_buffer_dirty (leaf); + +out: +if (!ret && trans) + ret =btrfs_commit_transaction (trans, root); +else if (trans) +btrfs_free_transaction (root, trans); +btrfs_free_path (path); +if (!ret) +printf ("New persistent options: %s\n" , options); + +return ret; +} +static void print_usage (void ) {fprintf (stderr,"usage: btrfstune [options] device\n" );fprintf (stderr,"\t-S value\tenable/disable seeding\n" );fprintf (stderr,"\t-r \t\tenable extended inode refs\n" ); -fprintf (stderr,"\t-x enable skinny metadata extent refs\n" ); +fprintf (stderr,"\t-x \t\tenable skinny metadata extent refs\n" ); +fprintf (stderr,"\t-o options\tset persistent mount options\n" ); }int main (int argc,char *argv[])
@@ -114,9 +202,10 @@ int main(int argc, char *argv[])int seeding_value =0 ;int skinny_flag =0 ;int ret; +char *options =NULL ;while (1 ) { -int c =getopt (argc, argv,"S:rx" ); +int c =getopt (argc, argv,"S:rxo:" );if (c <0 )break ;switch (c) {
@@ -130,6 +219,9 @@ int main(int argc, char *argv[])case 'x' : skinny_flag =1 ;break ; +case 'o' : + options = optarg; +break ;default :print_usage ();return 1 ;
@@ -171,6 +263,15 @@ int main(int argc, char *argv[]) success++; } +if (options) { + ret =set_persistent_mount_options (root, options); +if (ret) +fprintf (stderr, +"Error setting persistent options: %d\n" , ret); +else + success++; + } +if (success >0 ) { ret =0 ; }else {
ctree.h +8 -0
@@ -102,6 +102,14 @@ struct btrfs_free_space_ctl;*/ #define BTRFS_FREE_INO_OBJECTID -12ULL +/* +* Item that stores permanent mount options. These options +* have effect if they are not specified as well at mount +* time (that is, if a permanent option is also specified at +* mount time, the later wins). +*/ +#define BTRFS_PERSISTENT_OPTIONS_OBJECTID -13ULL +/* dummy objectid represents multiple objectids */ #define BTRFS_MULTIPLE_OBJECTIDS -255ULL
print-tree.c +9 -0
@@ -585,6 +585,9 @@ static void print_objectid(u64 objectid, u8 type)case BTRFS_MULTIPLE_OBJECTIDS :printf ("MULTIPLE" );break ; +case BTRFS_PERSISTENT_OPTIONS_OBJECTID : +printf ("PERSISTENT_OPTIONS" ); +break ;case (u64)-1 :printf ("-1" );break ;
@@ -849,6 +852,12 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l)case BTRFS_DEV_STATS_KEY :printf ("\t\tdevice stats\n" );break ; +case 0 : +if (objectid ==BTRFS_PERSISTENT_OPTIONS_OBJECTID ) { + di = btrfs_item_ptr(l, i, struct btrfs_dir_item); +print_dir_item (l, item, di); + } +break ; };fflush (stdout); }
Signature · 1 line
1.7.9.5