* [PATCH v3] Btrfs: deal with all 'subvol=xxx' options once
@ 2014-11-26 8:51 Wang Shilong
0 siblings, 0 replies; only message in thread
From: Wang Shilong @ 2014-11-26 8:51 UTC (permalink / raw)
To: linux-btrfs
Steps to reproduce:
# mkfs.btrfs -f /dev/sdb
# mount -t btrfs /dev/sdb /mnt
# btrfs sub create /mnt/dir
# mount -t btrfs /dev/sdb /mnt -o subvol=dir,subvol=dir
It fails with:
mount: mount(2) failed: No such file or directory
Btrfs deal with subvolume mounting in a recursive way,
to avoid looping, it will stripe out 'subvol=xxxx' string,
then next loop will stop.Problem here is it only deal one
string once, if users specify mount option multiple times.
It will loop several times which is not good, and above
reproducing steps will also return confusing results.
Fix this problem by striping out all 'subvol=xxx' options,
only last is valid.
Signed-off-by: Wang Shilong <wangshilong1991@gmail.com>
---
v3: avoid loop way that David addressed.
---
fs/btrfs/super.c | 44 +++++++++++++++++++++++++-------------------
1 file changed, 25 insertions(+), 19 deletions(-)
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 21c60ee..cac8e36 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1117,44 +1117,50 @@ static inline int is_subvolume_inode(struct inode *inode)
*/
static char *setup_root_args(char *args)
{
- unsigned len = strlen(args) + 2 + 1;
- char *src, *dst, *buf;
+ unsigned len;
+ char *src = args;
+ char *p = args;
+ char *dst, *buf;
/*
* We need the same args as before, but with this substitution:
* s!subvol=[^,]+!subvolid=0!
*
* Since the replacement string is up to 2 bytes longer than the
- * original, allocate strlen(args) + 2 + 1 bytes.
+ * original, allocate strlen(args) + 2 * N + 1 bytes.
*/
-
- src = strstr(args, "subvol=");
+ p = strstr(src, "subvol=");
/* This shouldn't happen, but just in case.. */
- if (!src)
+ if (!p)
return NULL;
+ len = strlen(args) + 1;
+ while (p) {
+ len += 2;
+ p = strchr(p, ',');
+ if (!p)
+ break;
+ p = strstr(p, "subvol=");
+ }
+
buf = dst = kmalloc(len, GFP_NOFS);
if (!buf)
return NULL;
- /*
- * If the subvol= arg is not at the start of the string,
- * copy whatever precedes it into buf.
- */
- if (src != args) {
- *src++ = '\0';
- strcpy(buf, args);
- dst += strlen(args);
+ /* loop and replace all subvol=xxx string */
+ while ((p = strstr(src, "subvol="))) {
+ strncat(dst, src, p - src);
+ dst += p - src;
+ strcpy(dst, "subvolid=0");
+ dst += strlen("subvolid=0");
+ src = p = strchr(p, ',');
+ if (!src)
+ break;
}
-
- strcpy(dst, "subvolid=0");
- dst += strlen("subvolid=0");
-
/*
* If there is a "," after the original subvol=... string,
* copy that suffix into our buffer. Otherwise, we're done.
*/
- src = strchr(src, ',');
if (src)
strcpy(dst, src);
--
2.1.0
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2014-11-26 8:53 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-11-26 8:51 [PATCH v3] Btrfs: deal with all 'subvol=xxx' options once Wang Shilong
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).