]> code.ossystems Code Review - openembedded-core.git/blob
40ccb5b92afbca55da5fcd899b88157dae238508
[openembedded-core.git] /
1 Upstream-Status: Inappropriate [Backport]
2 From d1dc6a9cff7e2fe4f335ca783a4b033457b3e184 Mon Sep 17 00:00:00 2001
3 From: Goffredo Baroncelli <kreijack@inwind.it>
4 Date: Sun, 5 Dec 2010 17:46:44 +0000
5 Subject: [PATCH 11/15] Add the "btrfs filesystem label" command
6
7 Hi all,
8
9 this patch adds the command "btrfs filesystem label" to change (or show) the
10 label of a filesystem.
11 This patch is a subset of the one written previously by Morey Roof. I
12 included the user space part only. So it is possible only to change/show a
13 label of a *single device* and *unounted* filesystem.
14
15 The reason of excluding the kernel space part, is to simplify the patch in
16 order to speed the check and then the merging of the patch itself. In fact I
17 have to point out that in the past there was almost three attempts to propose
18 this patch, without success neither complaints.
19
20 Chris, let me know how you want to proceed. I know that you are very busy,
21 and you prefer to work to stabilize btrfs instead adding new feature. But I
22 think that changing a label is a *essential* feature for a filesystem
23 managing tool. Think about a mount by LABEL.
24
25 To show a label
26
27 $ btrfs filesystem label <device>
28
29 To set a label
30
31 $ btrfs filesystem label <device> <newlabel>
32
33 Please guys, give a look to the source.
34 Comments are welcome.
35
36 You can pull the source from the branch "label" of the repository
37 http://cassiopea.homelinux.net/git/btrfs-progs-unstable.git
38
39 Regards
40 G.Baroncelli
41
42 Signed-off-by: Chris Mason <chris.mason@oracle.com>
43 ---
44  Makefile       |    2 +-
45  btrfs.c        |    5 --
46  btrfs_cmds.c   |   16 +++++++
47  btrfs_cmds.h   |    1 +
48  btrfslabel.c   |  121 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
49  btrfslabel.h   |    5 ++
50  man/btrfs.8.in |   19 +++++++++
51  utils.c        |   57 ++++++++++++++++++++++++++
52  utils.h        |    2 +
53  9 files changed, 222 insertions(+), 6 deletions(-)
54  create mode 100644 btrfslabel.c
55  create mode 100644 btrfslabel.h
56
57 diff --git a/Makefile b/Makefile
58 index d65f6a2..4b95d2f 100644
59 --- a/Makefile
60 +++ b/Makefile
61 @@ -4,7 +4,7 @@ CFLAGS = -g -Werror -Os
62  objects = ctree.o disk-io.o radix-tree.o extent-tree.o print-tree.o \
63           root-tree.o dir-item.o file-item.o inode-item.o \
64           inode-map.o crc32c.o rbtree.o extent-cache.o extent_io.o \
65 -         volumes.o utils.o btrfs-list.o
66 +         volumes.o utils.o btrfs-list.o btrfslabel.o
67  
68  #
69  CHECKFLAGS=-D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ -Wbitwise \
70 diff --git a/btrfs.c b/btrfs.c
71 index 62140ef..4cd4210 100644
72 --- a/btrfs.c
73 +++ b/btrfs.c
74 @@ -108,11 +108,6 @@ static struct Command commands[] = {
75           "device delete", "<device> [<device>...] <path>\n"
76                 "Remove a device from a filesystem."
77         },
78 -       /* coming soon
79 -       { 2, "filesystem label", "<label> <path>\n"
80 -               "Set the label of a filesystem"
81 -       }
82 -       */
83         { 0, 0 , 0 }
84  };
85  
86 diff --git a/btrfs_cmds.c b/btrfs_cmds.c
87 index 26d4fcc..6de73f4 100644
88 --- a/btrfs_cmds.c
89 +++ b/btrfs_cmds.c
90 @@ -40,6 +40,7 @@
91  #include "volumes.h"
92  
93  #include "btrfs_cmds.h"
94 +#include "btrfslabel.h"
95  
96  #ifdef __CHECKER__
97  #define BLKGETSIZE64 0
98 @@ -874,6 +875,21 @@ int do_set_default_subvol(int nargs, char **argv)
99         return 0;
100  }
101  
102 +int do_change_label(int nargs, char **argv)
103 +{
104 +       /* check the number of argument */
105 +       if ( nargs > 3 ){
106 +               fprintf(stderr, "ERROR: '%s' requires maximum 2 args\n",
107 +                       argv[0]);
108 +               return -2;
109 +       }else if (nargs == 2){
110 +               return get_label(argv[1]);
111 +       } else {        /* nargs == 0 */
112 +               return set_label(argv[1], argv[2]);
113 +       }
114 +}
115 +
116 +
117  int do_df_filesystem(int nargs, char **argv)
118  {
119         struct btrfs_ioctl_space_args *sargs;
120 diff --git a/btrfs_cmds.h b/btrfs_cmds.h
121 index 7bde191..ab722d4 100644
122 --- a/btrfs_cmds.h
123 +++ b/btrfs_cmds.h
124 @@ -32,3 +32,4 @@ int list_subvols(int fd);
125  int do_df_filesystem(int nargs, char **argv);
126  int find_updated_files(int fd, u64 root_id, u64 oldest_gen);
127  int do_find_newer(int argc, char **argv);
128 +int do_change_label(int argc, char **argv);
129 diff --git a/btrfslabel.c b/btrfslabel.c
130 new file mode 100644
131 index 0000000..c9f4684
132 --- /dev/null
133 +++ b/btrfslabel.c
134 @@ -0,0 +1,121 @@
135 +/*
136 + * Copyright (C) 2008 Morey Roof.   All rights reserved.
137 + *
138 + * This program is free software; you can redistribute it and/or
139 + * modify it under the terms of the GNU General Public
140 + * License v2 as published by the Free Software Foundation.
141 + *
142 + * This program is distributed in the hope that it will be useful,
143 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
144 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
145 + * General Public License for more details.
146 + *
147 + * You should have received a copy of the GNU General Public
148 + * License along with this program; if not, write to the
149 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
150 + * Boston, MA 021110-1307, USA.
151 + */
152 +
153 +#define _GNU_SOURCE
154 +
155 +#ifndef __CHECKER__
156 +#include <sys/ioctl.h>
157 +#include <sys/mount.h>
158 +#include "ioctl.h"
159 +#endif /* __CHECKER__ */
160 +
161 +#include <stdio.h>
162 +#include <stdlib.h>
163 +#include <sys/types.h>
164 +#include <sys/stat.h>
165 +#include <dirent.h>
166 +#include <fcntl.h>
167 +#include <unistd.h>
168 +#include <linux/fs.h>
169 +#include <linux/limits.h>
170 +#include <ctype.h>
171 +#include "kerncompat.h"
172 +#include "ctree.h"
173 +#include "utils.h"
174 +#include "version.h"
175 +#include "disk-io.h"
176 +#include "transaction.h"
177 +
178 +#define MOUNTED                        1
179 +#define UNMOUNTED                      2
180 +#define GET_LABEL                      3
181 +#define SET_LABEL                      4
182 +
183 +static void change_label_unmounted(char *dev, char *nLabel)
184 +{
185 +       struct btrfs_root *root;
186 +       struct btrfs_trans_handle *trans;
187 +
188 +       /* Open the super_block at the default location
189 +        * and as read-write.
190 +        */
191 +       root = open_ctree(dev, 0, 1);
192 +
193 +       trans = btrfs_start_transaction(root, 1);
194 +       strncpy(root->fs_info->super_copy.label, nLabel, BTRFS_LABEL_SIZE);
195 +       btrfs_commit_transaction(trans, root);
196 +
197 +       /* Now we close it since we are done. */
198 +       close_ctree(root);
199 +}
200 +
201 +static void get_label_unmounted(char *dev)
202 +{
203 +       struct btrfs_root *root;
204 +
205 +       /* Open the super_block at the default location
206 +        * and as read-only.
207 +        */
208 +       root = open_ctree(dev, 0, 0);
209 +
210 +       fprintf(stdout, "%s\n", root->fs_info->super_copy.label);
211 +
212 +       /* Now we close it since we are done. */
213 +       close_ctree(root);
214 +}
215 +
216 +int get_label(char *btrfs_dev)
217 +{
218 +
219 +       int ret;
220 +       ret = check_mounted(btrfs_dev);
221 +       if (ret < 0)
222 +       {
223 +              fprintf(stderr, "FATAL: error checking %s mount status\n", btrfs_dev);
224 +              return -1;
225 +       }
226 +
227 +       if(ret != 0)
228 +       {
229 +              fprintf(stderr, "FATAL: the filesystem has to be unmounted\n");
230 +              return -2;
231 +       }
232 +       get_label_unmounted(btrfs_dev);
233 +       return 0;
234 +}
235 +
236 +
237 +int set_label(char *btrfs_dev, char *nLabel)
238 +{
239 +
240 +       int ret;
241 +       ret = check_mounted(btrfs_dev);
242 +       if (ret < 0)
243 +       {
244 +              fprintf(stderr, "FATAL: error checking %s mount status\n", btrfs_dev);
245 +              return -1;
246 +       }
247 +
248 +       if(ret != 0)
249 +       {
250 +              fprintf(stderr, "FATAL: the filesystem has to be unmounted\n");
251 +              return -2;
252 +       }
253 +       change_label_unmounted(btrfs_dev, nLabel);
254 +       return 0;
255 +}
256 diff --git a/btrfslabel.h b/btrfslabel.h
257 new file mode 100644
258 index 0000000..abf43ad
259 --- /dev/null
260 +++ b/btrfslabel.h
261 @@ -0,0 +1,5 @@
262 +/* btrflabel.h */
263 +
264 +
265 +int get_label(char *btrfs_dev);
266 +int set_label(char *btrfs_dev, char *nLabel);
267 \ No newline at end of file
268 diff --git a/man/btrfs.8.in b/man/btrfs.8.in
269 index b9b8913..6f92f91 100644
270 --- a/man/btrfs.8.in
271 +++ b/man/btrfs.8.in
272 @@ -19,6 +19,8 @@ btrfs \- control a btrfs filesystem
273  .PP
274  \fBbtrfs\fP \fBfilesystem resize\fP\fI [+/\-]<size>[gkm]|max <filesystem>\fP
275  .PP
276 +\fBbtrfs\fP \fBfilesystem label\fP\fI <dev> [newlabel]\fP
277 +.PP
278  \fBbtrfs\fP \fBfilesystem defrag\fP\fI [options] <file>|<dir> [<file>|<dir>...]\fP
279  .PP
280  \fBbtrfs\fP \fBsubvolume find-new\fP\fI <subvolume> <last_gen>\fP
281 @@ -164,6 +166,23 @@ can expand the partition before enlarging the filesystem and shrink the
282  partition after reducing the size of the filesystem.
283  .TP
284  
285 +\fBbtrfs\fP \fBfilesystem label\fP\fI <dev> [newlabel]\fP
286 +Show or update the label of a filesystem. \fI<dev>\fR is used to identify the
287 +filesystem. 
288 +If a \fInewlabel\fR optional argument is passed, the label is changed. The
289 +following costraints exist for a label:
290 +.IP
291 +- the maximum allowable lenght shall be less or equal than 256 chars
292 +.IP
293 +- the label shall not  contain the '/' or '\\' characters.
294 +
295 +NOTE: Currently there are the following limitations:
296 +.IP
297 +- the filesystem has to be unmounted
298 +.IP
299 +- the filesystem should not have more than one device.
300 +.TP
301 +
302  \fBfilesystem show\fR [<uuid>|<label>]\fR
303  Show the btrfs filesystem with some additional info. If no UUID or label is
304  passed, \fBbtrfs\fR show info of all the btrfs filesystem.
305 diff --git a/utils.c b/utils.c
306 index ad980ae..13373c9 100644
307 --- a/utils.c
308 +++ b/utils.c
309 @@ -812,6 +812,39 @@ out_mntloop_err:
310         return ret;
311  }
312  
313 +/* Gets the mount point of btrfs filesystem that is using the specified device.
314 + * Returns 0 is everything is good, <0 if we have an error.
315 + * TODO: Fix this fucntion and check_mounted to work with multiple drive BTRFS
316 + * setups.
317 + */
318 +int get_mountpt(char *dev, char *mntpt, size_t size)
319 +{
320 +       struct mntent *mnt;
321 +       FILE *f;
322 +       int ret = 0;
323 +
324 +       f = setmntent("/proc/mounts", "r");
325 +       if (f == NULL)
326 +               return -errno;
327 +
328 +       while ((mnt = getmntent(f)) != NULL )
329 +       {
330 +               if (strcmp(dev, mnt->mnt_fsname) == 0)
331 +               {
332 +                       strncpy(mntpt, mnt->mnt_dir, size);
333 +                       break;
334 +               }
335 +       }
336 +
337 +       if (mnt == NULL)
338 +       {
339 +               /* We didn't find an entry so lets report an error */
340 +               ret = -1;
341 +       }
342 +
343 +       return ret;
344 +}
345 +
346  struct pending_dir {
347         struct list_head list;
348         char name[256];
349 @@ -1002,3 +1035,27 @@ char *pretty_sizes(u64 size)
350         return pretty;
351  }
352  
353 +/*
354 + * Checks to make sure that the label matches our requirements.
355 + * Returns:
356 +       0    if everything is safe and usable
357 +      -1    if the label is too long
358 +      -2    if the label contains an invalid character
359 + */
360 +int check_label(char *input)
361 +{
362 +       int i;
363 +       int len = strlen(input);
364 +
365 +       if (len > BTRFS_LABEL_SIZE) {
366 +               return -1;
367 +       }
368 +
369 +       for (i = 0; i < len; i++) {
370 +               if (input[i] == '/' || input[i] == '\\') {
371 +                       return -2;
372 +               }
373 +       }
374 +
375 +       return 0;
376 +}
377 diff --git a/utils.h b/utils.h
378 index a28d7f4..c3004ae 100644
379 --- a/utils.h
380 +++ b/utils.h
381 @@ -40,4 +40,6 @@ int check_mounted(const char *devicename);
382  int btrfs_device_already_in_root(struct btrfs_root *root, int fd,
383                                  int super_offset);
384  char *pretty_sizes(u64 size);
385 +int check_label(char *input);
386 +int get_mountpt(char *dev, char *mntpt, size_t size);
387  #endif
388 -- 
389 1.7.2.3
390