|
@@ -1133,52 +1133,36 @@ static inline int is_subvolume_inode(struct inode *inode)
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
- * This will strip out the subvol=%s argument for an argument string and add
|
|
|
|
- * subvolid=0 to make sure we get the actual tree root for path walking to the
|
|
|
|
- * subvol we want.
|
|
|
|
|
|
+ * This will add subvolid=0 to the argument string while removing any subvol=
|
|
|
|
+ * and subvolid= arguments to make sure we get the top-level root for path
|
|
|
|
+ * walking to the subvol we want.
|
|
*/
|
|
*/
|
|
static char *setup_root_args(char *args)
|
|
static char *setup_root_args(char *args)
|
|
{
|
|
{
|
|
- unsigned len = strlen(args) + 2 + 1;
|
|
|
|
- char *src, *dst, *buf;
|
|
|
|
|
|
+ char *buf, *dst, *sep;
|
|
|
|
|
|
- /*
|
|
|
|
- * 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.
|
|
|
|
- */
|
|
|
|
-
|
|
|
|
- src = strstr(args, "subvol=");
|
|
|
|
- /* This shouldn't happen, but just in case.. */
|
|
|
|
- if (!src)
|
|
|
|
- return NULL;
|
|
|
|
|
|
+ if (!args)
|
|
|
|
+ return kstrdup("subvolid=0", GFP_NOFS);
|
|
|
|
|
|
- buf = dst = kmalloc(len, GFP_NOFS);
|
|
|
|
|
|
+ /* The worst case is that we add ",subvolid=0" to the end. */
|
|
|
|
+ buf = dst = kmalloc(strlen(args) + strlen(",subvolid=0") + 1, GFP_NOFS);
|
|
if (!buf)
|
|
if (!buf)
|
|
return NULL;
|
|
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);
|
|
|
|
|
|
+ while (1) {
|
|
|
|
+ sep = strchrnul(args, ',');
|
|
|
|
+ if (!strstarts(args, "subvol=") &&
|
|
|
|
+ !strstarts(args, "subvolid=")) {
|
|
|
|
+ memcpy(dst, args, sep - args);
|
|
|
|
+ dst += sep - args;
|
|
|
|
+ *dst++ = ',';
|
|
|
|
+ }
|
|
|
|
+ if (*sep)
|
|
|
|
+ args = sep + 1;
|
|
|
|
+ else
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
-
|
|
|
|
strcpy(dst, "subvolid=0");
|
|
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);
|
|
|
|
|
|
|
|
return buf;
|
|
return buf;
|
|
}
|
|
}
|