Skip to content

Commit 0cea4c0

Browse files
committed
ovl: store and show the user provided lowerdir mount option
We are about to add new mount options for adding lowerdir one by one, but those mount options will not support escaping. For the existing case, where lowerdir mount option is provided as a colon separated list, store the user provided (possibly escaped) string and display it as is when showing the lowerdir mount option. Signed-off-by: Amir Goldstein <[email protected]>
1 parent c835110 commit 0cea4c0

File tree

3 files changed

+28
-24
lines changed

3 files changed

+28
-24
lines changed

fs/overlayfs/params.c

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -332,12 +332,18 @@ static int ovl_parse_param_upperdir(const char *name, struct fs_context *fc,
332332
return 0;
333333
}
334334

335-
static void ovl_parse_param_drop_lowerdir(struct ovl_fs_context *ctx)
335+
static void ovl_reset_lowerdirs(struct ovl_fs_context *ctx)
336336
{
337-
for (size_t nr = 0; nr < ctx->nr; nr++) {
338-
path_put(&ctx->lower[nr].path);
339-
kfree(ctx->lower[nr].name);
340-
ctx->lower[nr].name = NULL;
337+
struct ovl_fs_context_layer *l = ctx->lower;
338+
339+
// Reset old user provided lowerdir string
340+
kfree(ctx->lowerdir_all);
341+
ctx->lowerdir_all = NULL;
342+
343+
for (size_t nr = 0; nr < ctx->nr; nr++, l++) {
344+
path_put(&l->path);
345+
kfree(l->name);
346+
l->name = NULL;
341347
}
342348
ctx->nr = 0;
343349
ctx->nr_data = 0;
@@ -366,7 +372,7 @@ static int ovl_parse_param_lowerdir(const char *name, struct fs_context *fc)
366372
*/
367373

368374
/* drop all existing lower layers */
369-
ovl_parse_param_drop_lowerdir(ctx);
375+
ovl_reset_lowerdirs(ctx);
370376

371377
if (!*name)
372378
return 0;
@@ -376,6 +382,11 @@ static int ovl_parse_param_lowerdir(const char *name, struct fs_context *fc)
376382
return -EINVAL;
377383
}
378384

385+
// Store user provided lowerdir string to show in mount options
386+
ctx->lowerdir_all = kstrdup(name, GFP_KERNEL);
387+
if (!ctx->lowerdir_all)
388+
return -ENOMEM;
389+
379390
dup = kstrdup(name, GFP_KERNEL);
380391
if (!dup)
381392
return -ENOMEM;
@@ -448,7 +459,7 @@ static int ovl_parse_param_lowerdir(const char *name, struct fs_context *fc)
448459
return 0;
449460

450461
out_put:
451-
ovl_parse_param_drop_lowerdir(ctx);
462+
ovl_reset_lowerdirs(ctx);
452463

453464
out_err:
454465
kfree(dup);
@@ -554,7 +565,7 @@ static int ovl_get_tree(struct fs_context *fc)
554565

555566
static inline void ovl_fs_context_free(struct ovl_fs_context *ctx)
556567
{
557-
ovl_parse_param_drop_lowerdir(ctx);
568+
ovl_reset_lowerdirs(ctx);
558569
path_put(&ctx->upper);
559570
path_put(&ctx->work);
560571
kfree(ctx->lower);
@@ -870,24 +881,13 @@ int ovl_show_options(struct seq_file *m, struct dentry *dentry)
870881
{
871882
struct super_block *sb = dentry->d_sb;
872883
struct ovl_fs *ofs = OVL_FS(sb);
873-
size_t nr, nr_merged_lower = ofs->numlayer - ofs->numdatalayer;
884+
char **lowerdirs = ofs->config.lowerdirs;
874885

875886
/*
876-
* lowerdirs[] starts from offset 1, then
877-
* >= 0 regular lower layers prefixed with : and
878-
* >= 0 data-only lower layers prefixed with ::
879-
*
880-
* we need to escase comma and space like seq_show_option() does and
881-
* we also need to escape the colon separator from lowerdir paths.
887+
* lowerdirs[0] holds the colon separated list that user provided
888+
* with lowerdir mount option.
882889
*/
883-
seq_puts(m, ",lowerdir=");
884-
for (nr = 1; nr < ofs->numlayer; nr++) {
885-
if (nr > 1)
886-
seq_putc(m, ':');
887-
if (nr >= nr_merged_lower)
888-
seq_putc(m, ':');
889-
seq_escape(m, ofs->config.lowerdirs[nr], ":, \t\n\\");
890-
}
890+
seq_show_option(m, "lowerdir", lowerdirs[0]);
891891
if (ofs->config.upperdir) {
892892
seq_show_option(m, "upperdir", ofs->config.upperdir);
893893
seq_show_option(m, "workdir", ofs->config.workdir);

fs/overlayfs/params.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ struct ovl_fs_context {
3232
size_t nr_data;
3333
struct ovl_opt_set set;
3434
struct ovl_fs_context_layer *lower;
35+
char *lowerdir_all; /* user provided lowerdir string */
3536
};
3637

3738
int ovl_init_fs_context(struct fs_context *fc);

fs/overlayfs/super.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1328,8 +1328,11 @@ int ovl_fill_super(struct super_block *sb, struct fs_context *fc)
13281328
ofs->layers = layers;
13291329
/*
13301330
* Layer 0 is reserved for upper even if there's no upper.
1331-
* For consistency, config.lowerdirs[0] is NULL.
1331+
* config.lowerdirs[0] is used for storing the user provided colon
1332+
* separated lowerdir string.
13321333
*/
1334+
ofs->config.lowerdirs[0] = ctx->lowerdir_all;
1335+
ctx->lowerdir_all = NULL;
13331336
ofs->numlayer = 1;
13341337

13351338
sb->s_stack_depth = 0;

0 commit comments

Comments
 (0)