@@ -954,19 +954,20 @@ static const char * const cmd_subvol_show_usage[] = {
954954
955955static int cmd_subvol_show (int argc , char * * argv )
956956{
957- struct root_info get_ri ;
958- struct btrfs_list_filter_set * filter_set = NULL ;
959957 char tstr [256 ];
960958 char uuidparse [BTRFS_UUID_UNPARSED_SIZE ];
961959 char * fullpath = NULL ;
962- char raw_prefix [] = "\t\t\t\t" ;
963960 int fd = -1 ;
964961 int ret = 1 ;
965962 DIR * dirstream1 = NULL ;
966963 int by_rootid = 0 ;
967964 int by_uuid = 0 ;
968- u64 rootid_arg ;
965+ u64 rootid_arg = 0 ;
969966 u8 uuid_arg [BTRFS_UUID_SIZE ];
967+ struct btrfs_util_subvolume_iterator * iter ;
968+ struct btrfs_util_subvolume_info subvol ;
969+ char * subvol_path = NULL ;
970+ enum btrfs_util_error err ;
970971
971972 while (1 ) {
972973 int c ;
@@ -1003,96 +1004,142 @@ static int cmd_subvol_show(int argc, char **argv)
10031004 usage (cmd_subvol_show_usage );
10041005 }
10051006
1006- memset (& get_ri , 0 , sizeof (get_ri ));
10071007 fullpath = realpath (argv [optind ], NULL );
10081008 if (!fullpath ) {
10091009 error ("cannot find real path for '%s': %m" , argv [optind ]);
10101010 goto out ;
10111011 }
10121012
1013- if (by_rootid ) {
1014- ret = get_subvol_info_by_rootid (fullpath , & get_ri , rootid_arg );
1015- } else if (by_uuid ) {
1016- ret = get_subvol_info_by_uuid (fullpath , & get_ri , uuid_arg );
1017- } else {
1018- ret = get_subvol_info (fullpath , & get_ri );
1013+ fd = open_file_or_dir (fullpath , & dirstream1 );
1014+ if (fd < 0 ) {
1015+ error ("can't access '%s'" , fullpath );
1016+ goto out ;
10191017 }
10201018
1021- if (ret ) {
1022- if (ret < 0 ) {
1023- error ("Failed to get subvol info %s: %s" ,
1024- fullpath , strerror (- ret ));
1025- } else {
1026- error ("Failed to get subvol info %s: %d" ,
1027- fullpath , ret );
1019+ if (by_uuid ) {
1020+ err = btrfs_util_create_subvolume_iterator_fd (fd ,
1021+ BTRFS_FS_TREE_OBJECTID ,
1022+ 0 , & iter );
1023+ if (err ) {
1024+ error_btrfs_util (err );
1025+ goto out ;
1026+ }
1027+
1028+ for (;;) {
1029+ err = btrfs_util_subvolume_iterator_next_info (iter ,
1030+ & subvol_path ,
1031+ & subvol );
1032+ if (err == BTRFS_UTIL_ERROR_STOP_ITERATION ) {
1033+ uuid_unparse (uuid_arg , uuidparse );
1034+ error ("can't find uuid '%s' on '%s'" , uuidparse ,
1035+ fullpath );
1036+ btrfs_util_destroy_subvolume_iterator (iter );
1037+ goto out ;
1038+ } else if (err ) {
1039+ error_btrfs_util (err );
1040+ btrfs_util_destroy_subvolume_iterator (iter );
1041+ goto out ;
1042+ }
1043+
1044+ if (uuid_compare (subvol .uuid , uuid_arg ) == 0 )
1045+ break ;
1046+
1047+ free (subvol_path );
1048+ }
1049+ btrfs_util_destroy_subvolume_iterator (iter );
1050+ } else {
1051+ /*
1052+ * If !by_rootid, rootid_arg = 0, which means find the
1053+ * subvolume ID of the fd and use that.
1054+ */
1055+ err = btrfs_util_subvolume_info_fd (fd , rootid_arg , & subvol );
1056+ if (err ) {
1057+ error_btrfs_util (err );
1058+ goto out ;
10281059 }
1029- return ret ;
1060+
1061+ err = btrfs_util_subvolume_path_fd (fd , subvol .id , & subvol_path );
1062+ if (err ) {
1063+ error_btrfs_util (err );
1064+ goto out ;
1065+ }
1066+
10301067 }
10311068
10321069 /* print the info */
1033- printf ("%s\n" , get_ri .full_path );
1034- printf ("\tName: \t\t\t%s\n" , get_ri .name );
1070+ printf ("%s\n" , subvol .id == BTRFS_FS_TREE_OBJECTID ? "/" : subvol_path );
1071+ printf ("\tName: \t\t\t%s\n" ,
1072+ (subvol .id == BTRFS_FS_TREE_OBJECTID ? "<FS_TREE>" :
1073+ basename (subvol_path )));
10351074
1036- if (uuid_is_null (get_ri .uuid ))
1075+ if (uuid_is_null (subvol .uuid ))
10371076 strcpy (uuidparse , "-" );
10381077 else
1039- uuid_unparse (get_ri .uuid , uuidparse );
1078+ uuid_unparse (subvol .uuid , uuidparse );
10401079 printf ("\tUUID: \t\t\t%s\n" , uuidparse );
10411080
1042- if (uuid_is_null (get_ri . puuid ))
1081+ if (uuid_is_null (subvol . parent_uuid ))
10431082 strcpy (uuidparse , "-" );
10441083 else
1045- uuid_unparse (get_ri . puuid , uuidparse );
1084+ uuid_unparse (subvol . parent_uuid , uuidparse );
10461085 printf ("\tParent UUID: \t\t%s\n" , uuidparse );
10471086
1048- if (uuid_is_null (get_ri . ruuid ))
1087+ if (uuid_is_null (subvol . received_uuid ))
10491088 strcpy (uuidparse , "-" );
10501089 else
1051- uuid_unparse (get_ri . ruuid , uuidparse );
1090+ uuid_unparse (subvol . received_uuid , uuidparse );
10521091 printf ("\tReceived UUID: \t\t%s\n" , uuidparse );
10531092
1054- if (get_ri .otime ) {
1093+ if (subvol .otime . tv_sec ) {
10551094 struct tm tm ;
10561095
1057- localtime_r (& get_ri .otime , & tm );
1096+ localtime_r (& subvol .otime . tv_sec , & tm );
10581097 strftime (tstr , 256 , "%Y-%m-%d %X %z" , & tm );
10591098 } else
10601099 strcpy (tstr , "-" );
10611100 printf ("\tCreation time: \t\t%s\n" , tstr );
10621101
1063- printf ("\tSubvolume ID: \t\t%llu \n" , get_ri . root_id );
1064- printf ("\tGeneration: \t\t%llu \n" , get_ri . gen );
1065- printf ("\tGen at creation: \t%llu \n" , get_ri . ogen );
1066- printf ("\tParent ID: \t\t%llu \n" , get_ri . ref_tree );
1067- printf ("\tTop level ID: \t\t%llu \n" , get_ri . top_id );
1102+ printf ("\tSubvolume ID: \t\t%" PRIu64 " \n" , subvol . id );
1103+ printf ("\tGeneration: \t\t%" PRIu64 " \n" , subvol . generation );
1104+ printf ("\tGen at creation: \t%" PRIu64 " \n" , subvol . otransid );
1105+ printf ("\tParent ID: \t\t%" PRIu64 " \n" , subvol . parent_id );
1106+ printf ("\tTop level ID: \t\t%" PRIu64 " \n" , subvol . parent_id );
10681107
1069- if (get_ri .flags & BTRFS_ROOT_SUBVOL_RDONLY )
1108+ if (subvol .flags & BTRFS_ROOT_SUBVOL_RDONLY )
10701109 printf ("\tFlags: \t\t\treadonly\n" );
10711110 else
10721111 printf ("\tFlags: \t\t\t-\n" );
10731112
10741113 /* print the snapshots of the given subvol if any*/
10751114 printf ("\tSnapshot(s):\n" );
1076- filter_set = btrfs_list_alloc_filter_set ();
1077- btrfs_list_setup_filter (& filter_set , BTRFS_LIST_FILTER_BY_PARENT ,
1078- (u64 )(unsigned long )get_ri .uuid );
1079- btrfs_list_setup_print_column (BTRFS_LIST_PATH );
10801115
1081- fd = open_file_or_dir (fullpath , & dirstream1 );
1082- if (fd < 0 ) {
1083- fprintf (stderr , "ERROR: can't access '%s'\n" , fullpath );
1084- goto out ;
1116+ err = btrfs_util_create_subvolume_iterator_fd (fd ,
1117+ BTRFS_FS_TREE_OBJECTID , 0 ,
1118+ & iter );
1119+
1120+ for (;;) {
1121+ struct btrfs_util_subvolume_info subvol2 ;
1122+ char * path ;
1123+
1124+ err = btrfs_util_subvolume_iterator_next_info (iter , & path , & subvol2 );
1125+ if (err == BTRFS_UTIL_ERROR_STOP_ITERATION ) {
1126+ break ;
1127+ } else if (err ) {
1128+ error_btrfs_util (err );
1129+ btrfs_util_destroy_subvolume_iterator (iter );
1130+ goto out ;
1131+ }
1132+
1133+ if (uuid_compare (subvol2 .parent_uuid , subvol .uuid ) == 0 )
1134+ printf ("\t\t\t\t%s\n" , path );
1135+
1136+ free (path );
10851137 }
1086- btrfs_list_subvols_print (fd , filter_set , NULL , BTRFS_LIST_LAYOUT_RAW ,
1087- 1 , raw_prefix );
1138+ btrfs_util_destroy_subvolume_iterator (iter );
10881139
1140+ ret = 0 ;
10891141out :
1090- /* clean up */
1091- free (get_ri .path );
1092- free (get_ri .name );
1093- free (get_ri .full_path );
1094- free (filter_set );
1095-
1142+ free (subvol_path );
10961143 close_file_or_dir (fd , dirstream1 );
10971144 free (fullpath );
10981145 return !!ret ;
0 commit comments