overlayfs: support more than one read-only layer
Subsystems (3)
Miklos Szeredi
maintainerRFC PATCH 1/1 overlayfs: support more than one read-only layer
Apparently this is the top feature request, and is relateively easy to do.
This is the first iteration of the patch, and quite possibly buggy. Testing and review is welcome.
Usage: -olowerdirs=/top:/middle:/bottom...
Now the upperdir and workdir options can be omitted to get a read-only overlay.
Thanks,
Miklos
----
fs/overlayfs/copy_up.c +2 -2
@@ -385,7 +385,7 @@ int ovl_copy_up(struct dentry *dentry)struct kstat stat;enum ovl_path_type type =ovl_path_type (dentry); -if (type !=OVL_PATH_LOWER ) +if (OVL_TYPE_UPPER (type))break ; next =dget (dentry);
@@ -394,7 +394,7 @@ int ovl_copy_up(struct dentry *dentry) parent =dget_parent (next); type =ovl_path_type (parent); -if (type !=OVL_PATH_LOWER ) +if (OVL_TYPE_UPPER (type))break ;dput (next);
fs/overlayfs/dir.c +30 -23
146 lines not on this page · raw message
fs/overlayfs/inode.c +23 -11
@@ -235,26 +235,39 @@ out:return err; } +static bool ovl_need_xattr_filter (struct dentry *dentry, +enum ovl_path_type type) +{ +if ((type & (__OVL_PATH_PURE | __OVL_PATH_UPPER)) == __OVL_PATH_UPPER) +return S_ISDIR (dentry->d_inode->i_mode); +else +return false; +} +ssize_t ovl_getxattr (struct dentry *dentry,const char *name,void *value,size_t size) { -if (ovl_path_type (dentry->d_parent) ==OVL_PATH_MERGE && -ovl_is_private_xattr (name)) +struct path realpath; +enum ovl_path_type type =ovl_path_real (dentry, &realpath); + +if (ovl_need_xattr_filter (dentry, type) &&ovl_is_private_xattr (name))return -ENODATA ; -return vfs_getxattr (ovl_dentry_real (dentry), name, value, size); +return vfs_getxattr (realpath.dentry, name, value, size); }ssize_t ovl_listxattr (struct dentry *dentry,char *list,size_t size) { +struct path realpath; +enum ovl_path_type type =ovl_path_real (dentry, &realpath);ssize_t res;int off; - res =vfs_listxattr (ovl_dentry_real (dentry), list, size); + res =vfs_listxattr (realpath.dentry, list, size);if (res <=0 || size ==0 )return res; -if (ovl_path_type (dentry->d_parent) !=OVL_PATH_MERGE ) +if (!ovl_need_xattr_filter (dentry, type))return res;/* filter out private xattrs */
@@ -279,18 +292,17 @@ int ovl_removexattr(struct dentry *dentry, const char *name) {int err;struct path realpath; -enum ovl_path_type type; +enum ovl_path_type type =ovl_path_real (dentry, &realpath); err =ovl_want_write (dentry);if (err) goto out; -if (ovl_path_type (dentry->d_parent) ==OVL_PATH_MERGE && -ovl_is_private_xattr (name)) + err = -ENODATA ; +if (ovl_need_xattr_filter (dentry, type) &&ovl_is_private_xattr (name)) goto out_drop_write; - type =ovl_path_real (dentry, &realpath); -if (type ==OVL_PATH_LOWER ) { +if (!OVL_TYPE_UPPER (type)) { err =vfs_getxattr (realpath.dentry, name,NULL ,0 );if (err <0 ) goto out_drop_write;
@@ -312,7 +324,7 @@ out:static bool ovl_open_need_copy_up (int flags,enum ovl_path_type type,struct dentry *realdentry) { -if (type !=OVL_PATH_LOWER ) +if (OVL_TYPE_UPPER (type))return false;if (special_file (realdentry->d_inode->i_mode))
fs/overlayfs/overlayfs.h +10 -4
@@ -12,12 +12,17 @@struct ovl_entry ;enum ovl_path_type { -OVL_PATH_PURE_UPPER , -OVL_PATH_UPPER , -OVL_PATH_MERGE , -OVL_PATH_LOWER , + __OVL_PATH_PURE = (1 <<0 ), + __OVL_PATH_UPPER = (1 <<1 ), + __OVL_PATH_MERGE = (1 <<2 ), }; +#define OVL_TYPE_UPPER (type) ((type) & __OVL_PATH_UPPER) +#define OVL_TYPE_MERGE (type) ((type) & __OVL_PATH_MERGE) +#define OVL_TYPE_PURE_UPPER (type) ((type) & __OVL_PATH_PURE) +#define OVL_TYPE_MERGE_OR_LOWER (type) \ + (OVL_TYPE_MERGE(type) || !OVL_TYPE_UPPER(type)) +extern const char *ovl_opaque_xattr;static inline int ovl_do_rmdir (struct inode *dir,struct dentry *dentry)
@@ -130,6 +135,7 @@ void ovl_dentry_version_inc(struct dentry *dentry);void ovl_path_upper (struct dentry *dentry,struct path *path);void ovl_path_lower (struct dentry *dentry,struct path *path);enum ovl_path_type ovl_path_real (struct dentry *dentry,struct path *path); +int ovl_path_next (int *idx,struct dentry *dentry,struct path *path);struct dentry *ovl_dentry_upper (struct dentry *dentry);struct dentry *ovl_dentry_lower (struct dentry *dentry);struct dentry *ovl_dentry_real (struct dentry *dentry);
fs/overlayfs/readdir.c +53 -82
203 lines not on this page · raw message
fs/overlayfs/super.c +340 -185
756 lines not on this page · raw message
Hello,
my name is Patrick, I'm new on the list. A few days ago I asked Miklos
for the inclusion of multiple read-only branches in overlayfs and I promised to test, when code is available.
So, well, he's quick with the delivery:-) ... I applied the patch to kernel 3.18-rc3, everything works fine, I was able to mount a few directories (72 to be precise) together but failed to mount 311 directories due to length limitations of the mount command. I tried to avoid that by doing a kind of chaining recursion like so:
mount -t overlayfs -olowerdirs=/dir1 none /chain/1 mount -t overlayfs -olowerdirs=/dir2,/chain/1 none /chain/2
...
This doesn't work, i got the following kernel trace:
[ 342.374984] CPU: 3 PID: 3090 Comm: mount Tainted: G D 3.18.0-rc3 #1 [ 342.385589] Hardware name: Packard Bell Easynote TE69BM/Easynote TE69BM, BIOS V2.05 12/25/2013 [ 342.396324] task: ffff88016e312800 ti: ffff88003685c000 task.ti: ffff88003685c000 [ 342.407201] RIP: 0010:[<ffffffff811f6ca5>] [<ffffffff811f6ca5>] statfs_by_dentry+0x5/0xa0 [ 342.407207] RSP: 0018:ffff88003685fb50 EFLAGS: 00010246 [ 342.407212] RAX: 0000000000000000 RBX: ffff88003685fbf8 RCX: 0000000000000000 [ 342.407216] RDX: ffff8800679e2f40 RSI: ffff88003685fbf8 RDI: 0000000000000000 [ 342.407221] RBP: ffff88003685fb68 R08: 0000000000000000 R09: ffff88016e312800 [ 342.407226] R10: 8080808080808080 R11: fefefefefefefeff R12: ffff88003685fb80 [ 342.407230] R13: ffff88017812c260 R14: ffff88016f40f970 R15: ffff880064885d9e [ 342.407238] FS: 00007f3793d28780(0000) GS:ffff88017fd80000(0000) knlGS:0000000000000000 [ 342.407243] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 342.407247] CR2: 0000000000000068 CR3: 00000000648a9000 CR4: 00000000001007e0 [ 342.407250] Stack: [ 342.407263] ffffffff811f6d5b ffff88003685fbf8 ffff88006a9dab40 ffff88003685fba8 [ 342.407272] ffffffffa0cb51c7 ffff88003685fba8 0000000000000000 0000000000000000 [ 342.407282] 000000009e277ae4 ffff88003685fbf8 ffff8800666f70c0 ffff88003685fbc8 [ 342.407285] Call Trace: [ 342.407299] [<ffffffff811f6d5b>] ? vfs_statfs+0x1b/0xb0 [ 342.407318] [<ffffffffa0cb51c7>] ovl_statfs+0x57/0xa0 [overlayfs] [ 342.407329] [<ffffffff811f6d12>] statfs_by_dentry+0x72/0xa0 [ 342.407338] [<ffffffff811f6d5b>] vfs_statfs+0x1b/0xb0 [ 342.407352] [<ffffffffa0cb54d3>] ovl_lower_dir.part.2+0x43/0xb0 [overlayfs] [ 342.407367] [<ffffffffa0cb5576>] ovl_lower_dir+0x36/0x40 [overlayfs] [ 342.407381] [<ffffffffa0cb5e10>] ovl_fill_super+0x890/0x960 [overlayfs] [ 342.407395] [<ffffffff811c75c0>] ? sget+0x3b0/0x3f0 [ 342.407405] [<ffffffff811c68d0>] ? get_anon_bdev+0x120/0x120 [ 342.407418] [<ffffffffa0cb5580>] ? ovl_lower_dir+0x40/0x40 [overlayfs] [ 342.407429] [<ffffffff811c770e>] mount_nodev+0x4e/0xa0 [ 342.407443] [<ffffffffa0cb5058>] ovl_mount+0x18/0x20 [overlayfs] [ 342.407454] [<ffffffff811c8448>] mount_fs+0x38/0x1c0 [ 342.407467] [<ffffffff811e3c2b>] vfs_kern_mount+0x6b/0x120 [ 342.407478] [<ffffffff811e6bb4>] do_mount+0x224/0xb20 [ 342.407488] [<ffffffff811e77be>] SyS_mount+0x7e/0xe0 [ 342.407503] [<ffffffff8150c169>] system_call_fastpath+0x12/0x17 [ 342.407607] Code: 01 19 c0 f7 d0 83 e0 f2 48 8b 4d f8 65 48 33 0c 25 28 00 00 00 75 02 c9 c3 e8 08 2d e7 ff 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 <48> 8b 47 68 48 8b 40 30 48 83 78 50 00 74 7c 55 48 89 f1 31 c0 [ 342.407617] RIP [<ffffffff811f6ca5>] statfs_by_dentry+0x5/0xa0 [ 342.407620] RSP <ffff88003685fb50> [ 342.407623] CR2: 0000000000000068 [ 342.407720] ---[ end trace 8d18589ddc4cd155 ]---
Hope, this helps in any way.
As I already said to Miklos, thank you all for your hard work for the linux community, I'm just one of them.
bye,
P.
EL Fri, 7 Nov 2014 18:02:42 +0100
Miklos Szeredi <[email protected]> escrigué:
Quoted 3 lines
This is the first iteration of the patch, and quite possibly buggy. Testing and review is welcome.
Hello,
I did light tests on this patch applied to kernel 3.18-rc3, it works.
Observations:
- option lowerdirs is an extended case of lowerdir, then we can use only a name for that option and discard the other, for compatibility with older versions may be lowerdir.
- overlayfs changes fast the mount options that we should specify, an overlayfs version number will help the implementer to control it.
- limit filesystem depth by a kernel config parameter, allowing nomax.
- print more detailed error message
Following patches are included to better explain some points, you can use the idea and make your best,
Regards,
Jordi Pujol
modinfo --field=version overlayfs
busybox modinfo -F version /lib/modules/$(uname -r)/kernel/fs/overlayfs.ko | awk '{print $NF}'
fs/overlayfs/super.c +1 -0
@@ -23,6 +23,7 @@MODULE_AUTHOR ("Miklos Szeredi <[email protected]>" );MODULE_DESCRIPTION ("Overlay filesystem" );MODULE_LICENSE ("GPL" ); +MODULE_VERSION (OVERLAYFS_VERSION );#define OVERLAYFS_SUPER_MAGIC 0x794c764f
fs/overlayfs/overlayfs.h +2 -0
@@ -9,6 +9,8 @@#include <linux/kernel.h> +#define OVERLAYFS_VERSION "25" +struct ovl_entry ;enum ovl_path_type {
fs/overlayfs/super.c +4 -1
@@ -728,7 +728,10 @@ static int ovl_fill_super(struct super_b }if (!ufs->config.upperdir && !ufs->config.lowerdir && !ufs->config.lowerdirs) { -pr_err ("overlayfs: no 'upperdir', 'lowerdir' or 'lowerdirs' specified\n" ); +pr_err ("overlayfs: missing%s%s%s\n" , + ufs->config.upperdir ?"" :" upperdir" , + ufs->config.lowerdir ?"" :" lowerdir" , + ufs->config.lowerdirs ?"" :" lowerdirs" ); goto out_free_config; }
include/linux/fs.h +0 -6
@@ -246,12 +246,6 @@ struct iattr {*/ #include <linux/quota.h> -/* -* Maximum number of layers of fs stack. Needs to be limited to -* prevent kernel stack overflow -*/ -#define FILESYSTEM_MAX_STACK_DEPTH 2 -/** * enum positive_aop_returns - aop return codes with specific semantics *
init/Kconfig +6 -0
@@ -44,6 +44,12 @@ config INIT_ENV_ARG_LIMIT Maximum of each of the number of arguments and environment variables passed to init from the kernel command line. +config FILESYSTEM_MAX_STACK_DEPTH + int "Maximum number of layers of fs stack" + default 2 + help + Maximum number of layers of fs stack. Needs to be limited to + prevent kernel stack overflow. Set to 0 for no limit. config CROSS_COMPILE string "Cross-compiler tool prefix"
fs/ecryptfs/main.c +3 -2
@@ -568,8 +568,9 @@ static struct dentry *ecryptfs_mount(str s->s_magic =ECRYPTFS_SUPER_MAGIC ; s->s_stack_depth = path.dentry->d_sb->s_stack_depth +1 ; - rc = -EINVAL ; -if (s->s_stack_depth >FILESYSTEM_MAX_STACK_DEPTH ) { +if (CONFIG_FILESYSTEM_MAX_STACK_DEPTH >0 && + s->s_stack_depth >CONFIG_FILESYSTEM_MAX_STACK_DEPTH ) { + rc = -EINVAL ;pr_err ("eCryptfs: maximum fs stacking depth exceeded\n" ); goto out_free; }
fs/overlayfs/super.c +2 -1
@@ -818,7 +818,8 @@ static int ovl_fill_super(struct super_b } err = -EINVAL ; -if (sb->s_stack_depth >FILESYSTEM_MAX_STACK_DEPTH ) { +if (CONFIG_FILESYSTEM_MAX_STACK_DEPTH >0 && + sb->s_stack_depth >CONFIG_FILESYSTEM_MAX_STACK_DEPTH ) {pr_err ("overlayfs: maximum fs stacking depth exceeded\n" ); goto out_put_lowerpath; }
Miklos Szeredi
maintainerThanks to everyone for testing.
Here's an updated patch to fix the statfs Oops.
Maybe it wasn't clear, but the number of lower layers isn't limited by FILESYSTEM_MAX_STACK_DEPTH, only by the max size of the mount option buffer in the kernel (1 page, usually 4096bytes). So you could have a hundred read-only layers stacked in a single overlayfs mount.
As for changing the stacking while the overlayfs is mounted: currently this is not supported, the layers specified at the mount time remain there until the overlay is unmounted. Currently there's no possibility to add or remove layers in a dynamic way, and it is definitely more tricky to implement than the static configuration.
Thanks,
Miklos
----
fs/overlayfs/copy_up.c +2 -2
@@ -385,7 +385,7 @@ int ovl_copy_up(struct dentry *dentry)struct kstat stat;enum ovl_path_type type =ovl_path_type (dentry); -if (type !=OVL_PATH_LOWER ) +if (OVL_TYPE_UPPER (type))break ; next =dget (dentry);
@@ -394,7 +394,7 @@ int ovl_copy_up(struct dentry *dentry) parent =dget_parent (next); type =ovl_path_type (parent); -if (type !=OVL_PATH_LOWER ) +if (OVL_TYPE_UPPER (type))break ;dput (next);
fs/overlayfs/dir.c +30 -23
146 lines not on this page · raw message
fs/overlayfs/inode.c +23 -11
@@ -235,26 +235,39 @@ out:return err; } +static bool ovl_need_xattr_filter (struct dentry *dentry, +enum ovl_path_type type) +{ +if ((type & (__OVL_PATH_PURE | __OVL_PATH_UPPER)) == __OVL_PATH_UPPER) +return S_ISDIR (dentry->d_inode->i_mode); +else +return false; +} +ssize_t ovl_getxattr (struct dentry *dentry,const char *name,void *value,size_t size) { -if (ovl_path_type (dentry->d_parent) ==OVL_PATH_MERGE && -ovl_is_private_xattr (name)) +struct path realpath; +enum ovl_path_type type =ovl_path_real (dentry, &realpath); + +if (ovl_need_xattr_filter (dentry, type) &&ovl_is_private_xattr (name))return -ENODATA ; -return vfs_getxattr (ovl_dentry_real (dentry), name, value, size); +return vfs_getxattr (realpath.dentry, name, value, size); }ssize_t ovl_listxattr (struct dentry *dentry,char *list,size_t size) { +struct path realpath; +enum ovl_path_type type =ovl_path_real (dentry, &realpath);ssize_t res;int off; - res =vfs_listxattr (ovl_dentry_real (dentry), list, size); + res =vfs_listxattr (realpath.dentry, list, size);if (res <=0 || size ==0 )return res; -if (ovl_path_type (dentry->d_parent) !=OVL_PATH_MERGE ) +if (!ovl_need_xattr_filter (dentry, type))return res;/* filter out private xattrs */
@@ -279,18 +292,17 @@ int ovl_removexattr(struct dentry *dentry, const char *name) {int err;struct path realpath; -enum ovl_path_type type; +enum ovl_path_type type =ovl_path_real (dentry, &realpath); err =ovl_want_write (dentry);if (err) goto out; -if (ovl_path_type (dentry->d_parent) ==OVL_PATH_MERGE && -ovl_is_private_xattr (name)) + err = -ENODATA ; +if (ovl_need_xattr_filter (dentry, type) &&ovl_is_private_xattr (name)) goto out_drop_write; - type =ovl_path_real (dentry, &realpath); -if (type ==OVL_PATH_LOWER ) { +if (!OVL_TYPE_UPPER (type)) { err =vfs_getxattr (realpath.dentry, name,NULL ,0 );if (err <0 ) goto out_drop_write;
@@ -312,7 +324,7 @@ out:static bool ovl_open_need_copy_up (int flags,enum ovl_path_type type,struct dentry *realdentry) { -if (type !=OVL_PATH_LOWER ) +if (OVL_TYPE_UPPER (type))return false;if (special_file (realdentry->d_inode->i_mode))
fs/overlayfs/overlayfs.h +10 -4
@@ -12,12 +12,17 @@struct ovl_entry ;enum ovl_path_type { -OVL_PATH_PURE_UPPER , -OVL_PATH_UPPER , -OVL_PATH_MERGE , -OVL_PATH_LOWER , + __OVL_PATH_PURE = (1 <<0 ), + __OVL_PATH_UPPER = (1 <<1 ), + __OVL_PATH_MERGE = (1 <<2 ), }; +#define OVL_TYPE_UPPER (type) ((type) & __OVL_PATH_UPPER) +#define OVL_TYPE_MERGE (type) ((type) & __OVL_PATH_MERGE) +#define OVL_TYPE_PURE_UPPER (type) ((type) & __OVL_PATH_PURE) +#define OVL_TYPE_MERGE_OR_LOWER (type) \ + (OVL_TYPE_MERGE(type) || !OVL_TYPE_UPPER(type)) +extern const char *ovl_opaque_xattr;static inline int ovl_do_rmdir (struct inode *dir,struct dentry *dentry)
@@ -130,6 +135,7 @@ void ovl_dentry_version_inc(struct dentry *dentry);void ovl_path_upper (struct dentry *dentry,struct path *path);void ovl_path_lower (struct dentry *dentry,struct path *path);enum ovl_path_type ovl_path_real (struct dentry *dentry,struct path *path); +int ovl_path_next (int *idx,struct dentry *dentry,struct path *path);struct dentry *ovl_dentry_upper (struct dentry *dentry);struct dentry *ovl_dentry_lower (struct dentry *dentry);struct dentry *ovl_dentry_real (struct dentry *dentry);
fs/overlayfs/readdir.c +53 -82
203 lines not on this page · raw message
fs/overlayfs/super.c +341 -186
764 lines not on this page · raw message
Indeed, Miklos, changing layers dynamically is VERY tricky. Unionfs supports that, but a good amount of its code all over is dedicated to handling dynamic layer changes. I advise you to avoid supporting this feature for a while, if ever: get a small, functional, working overlayfs first.
I personally never liked the idea of changing layers dynamically: it’s like asking a file system to remain consistent and detect all lower changes when someone goes and hand-edits disk blocks. Too messy. The pain of developing and supporting such a feature is much greater than the annoyance to users who have to unmount and remount back their layers to form a new structure.
Cheers,
Erez.
Quoted 10 lines · Miklos Szeredi
As for changing the stacking while the overlayfs is mounted: currently this is not supported, the layers specified at the mount time remain there until the overlay is unmounted. Currently there's no possibility to add or remove layers in a dynamic way, and it is definitely more tricky to implement than the static configuration.
Thanks,
Miklos
EL Mon, 10 Nov 2014 10:09:54 +0100
Miklos Szeredi <[email protected]> escrigué:
Quoted 2 lines
Maybe it wasn't clear, but the number of lower layers isn't limited by
FILESYSTEM_MAX_STACK_DEPTH,
sorry, you have been clear, it's me that have not explained the purpose of that patch. This idea is also valid for the main overlayfs development.
Consider that we have an encrypted partition and a live OS that uses overlayfs and works over it, when the OS is started already reaches the maximum stacking depth (2). Also, hardcoding parameters into the code may be annoying because a change implies creating and mantaining patches, otherwise when the parameter is configurable we can change it in a config value.
Also, I include a patch to explain better my first statement, would say lowerdirs has extended the functionality of lowerdir, therefore we can discard the lowerdir case that only works with one lower layer and rename lowerdirs to lowerdir. It's more simple and all the functionality is preserved.
Regards,
Jordi Pujol
fs/overlayfs/super.c +4 -29
@@ -29,7 +29,6 @@ MODULE_VERSION(OVERLAYFS_VERSION);struct ovl_config {char *lowerdir; -char *lowerdirs;char *upperdir;char *workdir; };
@@ -497,8 +496,6 @@ static int ovl_show_options(struct seq_fif (ufs->config.lowerdir)seq_printf (m,",lowerdir=%s" , ufs->config.lowerdir); -if (ufs->config.lowerdirs) -seq_printf (m,",lowerdirs=%s" , ufs->config.lowerdirs);if (ufs->config.upperdir) {seq_printf (m,",upperdir=%s" , ufs->config.upperdir);seq_printf (m,",workdir=%s" , ufs->config.workdir);
@@ -522,7 +519,6 @@ enum {static const match_table_t ovl_tokens = { {OPT_LOWERDIR ,"lowerdir=%s" }, - {OPT_LOWERDIRS ,"lowerdirs=%s" }, {OPT_UPPERDIR ,"upperdir=%s" }, {OPT_WORKDIR ,"workdir=%s" }, {OPT_ERR ,NULL }
@@ -555,13 +551,6 @@ static int ovl_parse_opt(char *opt, strureturn -ENOMEM ;break ; -case OPT_LOWERDIRS : -kfree (config->lowerdirs); - config->lowerdirs =match_strdup (&args[0 ]); -if (!config->lowerdirs) -return -ENOMEM ; -break ; -case OPT_WORKDIR :kfree (config->workdir); config->workdir =match_strdup (&args[0 ]);
@@ -718,24 +707,18 @@ static int ovl_fill_super(struct super_b goto out_free_config; err = -EINVAL ; -if (ufs->config.lowerdir && ufs->config.lowerdirs) { -pr_err ("overlayfs: both 'lowerdir' and 'lowerdirs' not allowed\n" ); - goto out_free_config; - }if (ufs->config.upperdir && !ufs->config.workdir) {pr_err ("overlayfs: missing 'workdir'\n" ); goto out_free_config; }if (!ufs->config.upperdir && - !ufs->config.lowerdir && !ufs->config.lowerdirs) { -pr_err ("overlayfs: no 'upperdir', 'lowerdir' or 'lowerdirs' specified\n" ); + !ufs->config.lowerdir) { +pr_err ("overlayfs: no 'upperdir' or 'lowerdir' specified\n" ); goto out_free_config; }if (ufs->config.lowerdir) { - stacklen =1 ; - }else if (ufs->config.lowerdirs) { -char *p = ufs->config.lowerdirs; +char *p = ufs->config.lowerdir;for (;;) { stacklen++;
@@ -780,15 +763,7 @@ static int ovl_fill_super(struct super_b }if (ufs->config.lowerdir) { -BUG_ON (numlower >= stacklen); - - err =ovl_lower_dir (ufs->config.lowerdir, &stack[numlower], &ufs->lower_namelen, &sb->s_stack_depth); -if (err) - goto out_put_workpath; - - numlower++; - }else if (ufs->config.lowerdirs) { -char *p = ufs->config.lowerdirs; +char *p = ufs->config.lowerdir;for (;;) {char *next =strchr (p,':' );
Miklos Szeredi
maintainerQuoted 5 lines · Jordi Pujol Palomer
EL Mon, 10 Nov 2014 10:09:54 +0100
Miklos Szeredi <[email protected]> escrigué:Quoted 2 lines
Maybe it wasn't clear, but the number of lower layers isn't limited by
FILESYSTEM_MAX_STACK_DEPTH,
Quoted 9 lines
sorry, you have been clear, it's me that have not explained the purpose of that patch. This idea is also valid for the main overlayfs development.
Consider that we have an encrypted partition and a live OS that uses overlayfs and works over it, when the OS is started already reaches the maximum stacking depth (2). Also, hardcoding parameters into the code may be annoying because a change implies creating and mantaining patches, otherwise when the parameter is configurable we can change it in a config value.
Before allowing a change to FILESYSTEM_MAX_STACK_DEPTH we'd need to analyze the kernel stack usage of anything taking part in the filesystem stack. Not something that can be expected of users before they set a kernel config variable.
'Course we can change overlayfs and/or ecryptfs to use a new context for operations done on underlying layers. Not sure how much work that would be...
Quoted 5 lines
Also, I include a patch to explain better my first statement, would say lowerdirs has extended the functionality of lowerdir, therefore we can discard the lowerdir case that only works with one lower layer and rename lowerdirs to lowerdir. It's more simple and all the functionality is preserved.
Yeah. But we also need some escaping in 'lowerdir=' argument to allow filenames with comma and colon. Current patch doesn't yet have that, but will work on it.
Thanks,
Miklos
--
To unsubscribe from this list: send the line "unsubscribe linux-unionfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html