aboutsummaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/btrfs-tools/btrfs-tools/upstream-tmp/0011-Add-the-btrfs-filesystem-label-command.patch
blob: 40ccb5b92afbca55da5fcd899b88157dae238508 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
Upstream-Status: Inappropriate [Backport]
From d1dc6a9cff7e2fe4f335ca783a4b033457b3e184 Mon Sep 17 00:00:00 2001
From: Goffredo Baroncelli <kreijack@inwind.it>
Date: Sun, 5 Dec 2010 17:46:44 +0000
Subject: [PATCH 11/15] Add the "btrfs filesystem label" command

Hi all,

this patch adds the command "btrfs filesystem label" to change (or show) the
label of a filesystem.
This patch is a subset of the one written previously by Morey Roof. I
included the user space part only. So it is possible only to change/show a
label of a *single device* and *unounted* filesystem.

The reason of excluding the kernel space part, is to simplify the patch in
order to speed the check and then the merging of the patch itself. In fact I
have to point out that in the past there was almost three attempts to propose
this patch, without success neither complaints.

Chris, let me know how you want to proceed. I know that you are very busy,
and you prefer to work to stabilize btrfs instead adding new feature. But I
think that changing a label is a *essential* feature for a filesystem
managing tool. Think about a mount by LABEL.

To show a label

$ btrfs filesystem label <device>

To set a label

$ btrfs filesystem label <device> <newlabel>

Please guys, give a look to the source.
Comments are welcome.

You can pull the source from the branch "label" of the repository
http://cassiopea.homelinux.net/git/btrfs-progs-unstable.git

Regards
G.Baroncelli

Signed-off-by: Chris Mason <chris.mason@oracle.com>
---
 Makefile       |    2 +-
 btrfs.c        |    5 --
 btrfs_cmds.c   |   16 +++++++
 btrfs_cmds.h   |    1 +
 btrfslabel.c   |  121 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 btrfslabel.h   |    5 ++
 man/btrfs.8.in |   19 +++++++++
 utils.c        |   57 ++++++++++++++++++++++++++
 utils.h        |    2 +
 9 files changed, 222 insertions(+), 6 deletions(-)
 create mode 100644 btrfslabel.c
 create mode 100644 btrfslabel.h

diff --git a/Makefile b/Makefile
index d65f6a2..4b95d2f 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@ CFLAGS = -g -Werror -Os
 objects = ctree.o disk-io.o radix-tree.o extent-tree.o print-tree.o \
 	  root-tree.o dir-item.o file-item.o inode-item.o \
 	  inode-map.o crc32c.o rbtree.o extent-cache.o extent_io.o \
-	  volumes.o utils.o btrfs-list.o
+	  volumes.o utils.o btrfs-list.o btrfslabel.o
 
 #
 CHECKFLAGS=-D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ -Wbitwise \
diff --git a/btrfs.c b/btrfs.c
index 62140ef..4cd4210 100644
--- a/btrfs.c
+++ b/btrfs.c
@@ -108,11 +108,6 @@ static struct Command commands[] = {
 	  "device delete", "<device> [<device>...] <path>\n"
 		"Remove a device from a filesystem."
 	},
-	/* coming soon
-	{ 2, "filesystem label", "<label> <path>\n"
-		"Set the label of a filesystem"
-	}
-	*/
 	{ 0, 0 , 0 }
 };
 
diff --git a/btrfs_cmds.c b/btrfs_cmds.c
index 26d4fcc..6de73f4 100644
--- a/btrfs_cmds.c
+++ b/btrfs_cmds.c
@@ -40,6 +40,7 @@
 #include "volumes.h"
 
 #include "btrfs_cmds.h"
+#include "btrfslabel.h"
 
 #ifdef __CHECKER__
 #define BLKGETSIZE64 0
@@ -874,6 +875,21 @@ int do_set_default_subvol(int nargs, char **argv)
 	return 0;
 }
 
+int do_change_label(int nargs, char **argv)
+{
+	/* check the number of argument */
+	if ( nargs > 3 ){
+		fprintf(stderr, "ERROR: '%s' requires maximum 2 args\n",
+			argv[0]);
+		return -2;
+	}else if (nargs == 2){
+		return get_label(argv[1]);
+	} else {	/* nargs == 0 */
+		return set_label(argv[1], argv[2]);
+	}
+}
+
+
 int do_df_filesystem(int nargs, char **argv)
 {
 	struct btrfs_ioctl_space_args *sargs;
diff --git a/btrfs_cmds.h b/btrfs_cmds.h
index 7bde191..ab722d4 100644
--- a/btrfs_cmds.h
+++ b/btrfs_cmds.h
@@ -32,3 +32,4 @@ int list_subvols(int fd);
 int do_df_filesystem(int nargs, char **argv);
 int find_updated_files(int fd, u64 root_id, u64 oldest_gen);
 int do_find_newer(int argc, char **argv);
+int do_change_label(int argc, char **argv);
diff --git a/btrfslabel.c b/btrfslabel.c
new file mode 100644
index 0000000..c9f4684
--- /dev/null
+++ b/btrfslabel.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2008 Morey Roof.   All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+
+#define _GNU_SOURCE
+
+#ifndef __CHECKER__
+#include <sys/ioctl.h>
+#include <sys/mount.h>
+#include "ioctl.h"
+#endif /* __CHECKER__ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <linux/fs.h>
+#include <linux/limits.h>
+#include <ctype.h>
+#include "kerncompat.h"
+#include "ctree.h"
+#include "utils.h"
+#include "version.h"
+#include "disk-io.h"
+#include "transaction.h"
+
+#define MOUNTED                        1
+#define UNMOUNTED                      2
+#define GET_LABEL                      3
+#define SET_LABEL                      4
+
+static void change_label_unmounted(char *dev, char *nLabel)
+{
+       struct btrfs_root *root;
+       struct btrfs_trans_handle *trans;
+
+       /* Open the super_block at the default location
+        * and as read-write.
+        */
+       root = open_ctree(dev, 0, 1);
+
+       trans = btrfs_start_transaction(root, 1);
+       strncpy(root->fs_info->super_copy.label, nLabel, BTRFS_LABEL_SIZE);
+       btrfs_commit_transaction(trans, root);
+
+       /* Now we close it since we are done. */
+       close_ctree(root);
+}
+
+static void get_label_unmounted(char *dev)
+{
+       struct btrfs_root *root;
+
+       /* Open the super_block at the default location
+        * and as read-only.
+        */
+       root = open_ctree(dev, 0, 0);
+
+       fprintf(stdout, "%s\n", root->fs_info->super_copy.label);
+
+       /* Now we close it since we are done. */
+       close_ctree(root);
+}
+
+int get_label(char *btrfs_dev)
+{
+
+	int ret;
+	ret = check_mounted(btrfs_dev);
+	if (ret < 0)
+	{
+	       fprintf(stderr, "FATAL: error checking %s mount status\n", btrfs_dev);
+	       return -1;
+	}
+
+	if(ret != 0)
+	{
+	       fprintf(stderr, "FATAL: the filesystem has to be unmounted\n");
+	       return -2;
+	}
+	get_label_unmounted(btrfs_dev);
+	return 0;
+}
+
+
+int set_label(char *btrfs_dev, char *nLabel)
+{
+
+	int ret;
+	ret = check_mounted(btrfs_dev);
+	if (ret < 0)
+	{
+	       fprintf(stderr, "FATAL: error checking %s mount status\n", btrfs_dev);
+	       return -1;
+	}
+
+	if(ret != 0)
+	{
+	       fprintf(stderr, "FATAL: the filesystem has to be unmounted\n");
+	       return -2;
+	}
+	change_label_unmounted(btrfs_dev, nLabel);
+	return 0;
+}
diff --git a/btrfslabel.h b/btrfslabel.h
new file mode 100644
index 0000000..abf43ad
--- /dev/null
+++ b/btrfslabel.h
@@ -0,0 +1,5 @@
+/* btrflabel.h */
+
+
+int get_label(char *btrfs_dev);
+int set_label(char *btrfs_dev, char *nLabel);
\ No newline at end of file
diff --git a/man/btrfs.8.in b/man/btrfs.8.in
index b9b8913..6f92f91 100644
--- a/man/btrfs.8.in
+++ b/man/btrfs.8.in
@@ -19,6 +19,8 @@ btrfs \- control a btrfs filesystem
 .PP
 \fBbtrfs\fP \fBfilesystem resize\fP\fI [+/\-]<size>[gkm]|max <filesystem>\fP
 .PP
+\fBbtrfs\fP \fBfilesystem label\fP\fI <dev> [newlabel]\fP
+.PP
 \fBbtrfs\fP \fBfilesystem defrag\fP\fI [options] <file>|<dir> [<file>|<dir>...]\fP
 .PP
 \fBbtrfs\fP \fBsubvolume find-new\fP\fI <subvolume> <last_gen>\fP
@@ -164,6 +166,23 @@ can expand the partition before enlarging the filesystem and shrink the
 partition after reducing the size of the filesystem.
 .TP
 
+\fBbtrfs\fP \fBfilesystem label\fP\fI <dev> [newlabel]\fP
+Show or update the label of a filesystem. \fI<dev>\fR is used to identify the
+filesystem. 
+If a \fInewlabel\fR optional argument is passed, the label is changed. The
+following costraints exist for a label:
+.IP
+- the maximum allowable lenght shall be less or equal than 256 chars
+.IP
+- the label shall not  contain the '/' or '\\' characters.
+
+NOTE: Currently there are the following limitations:
+.IP
+- the filesystem has to be unmounted
+.IP
+- the filesystem should not have more than one device.
+.TP
+
 \fBfilesystem show\fR [<uuid>|<label>]\fR
 Show the btrfs filesystem with some additional info. If no UUID or label is
 passed, \fBbtrfs\fR show info of all the btrfs filesystem.
diff --git a/utils.c b/utils.c
index ad980ae..13373c9 100644
--- a/utils.c
+++ b/utils.c
@@ -812,6 +812,39 @@ out_mntloop_err:
 	return ret;
 }
 
+/* Gets the mount point of btrfs filesystem that is using the specified device.
+ * Returns 0 is everything is good, <0 if we have an error.
+ * TODO: Fix this fucntion and check_mounted to work with multiple drive BTRFS
+ * setups.
+ */
+int get_mountpt(char *dev, char *mntpt, size_t size)
+{
+       struct mntent *mnt;
+       FILE *f;
+       int ret = 0;
+
+       f = setmntent("/proc/mounts", "r");
+       if (f == NULL)
+               return -errno;
+
+       while ((mnt = getmntent(f)) != NULL )
+       {
+               if (strcmp(dev, mnt->mnt_fsname) == 0)
+               {
+                       strncpy(mntpt, mnt->mnt_dir, size);
+                       break;
+               }
+       }
+
+       if (mnt == NULL)
+       {
+               /* We didn't find an entry so lets report an error */
+               ret = -1;
+       }
+
+       return ret;
+}
+
 struct pending_dir {
 	struct list_head list;
 	char name[256];
@@ -1002,3 +1035,27 @@ char *pretty_sizes(u64 size)
 	return pretty;
 }
 
+/*
+ * Checks to make sure that the label matches our requirements.
+ * Returns:
+       0    if everything is safe and usable
+      -1    if the label is too long
+      -2    if the label contains an invalid character
+ */
+int check_label(char *input)
+{
+       int i;
+       int len = strlen(input);
+
+       if (len > BTRFS_LABEL_SIZE) {
+               return -1;
+       }
+
+       for (i = 0; i < len; i++) {
+               if (input[i] == '/' || input[i] == '\\') {
+                       return -2;
+               }
+       }
+
+       return 0;
+}
diff --git a/utils.h b/utils.h
index a28d7f4..c3004ae 100644
--- a/utils.h
+++ b/utils.h
@@ -40,4 +40,6 @@ int check_mounted(const char *devicename);
 int btrfs_device_already_in_root(struct btrfs_root *root, int fd,
 				 int super_offset);
 char *pretty_sizes(u64 size);
+int check_label(char *input);
+int get_mountpt(char *dev, char *mntpt, size_t size);
 #endif
-- 
1.7.2.3