aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@suse.cz>2014-12-12 18:59:52 -0500
committerMiklos Szeredi <mszeredi@suse.cz>2014-12-12 18:59:52 -0500
commita78d9f0d5d5ca9054703376c7c23c901807ddd87 (patch)
tree956a4d1e7517b9ead6f6f101dbfc1f344bec87fd /fs
parent53a08cb9b8bccfe58f1228c7c27baf34a83da78b (diff)
ovl: support multiple lower layers
Allow "lowerdir=" option to contain multiple lower directories separated by a colon (e.g. "lowerdir=/bin:/usr/bin"). Colon characters in filenames can be escaped with a backslash. Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Diffstat (limited to 'fs')
-rw-r--r--fs/overlayfs/super.c110
1 files changed, 83 insertions, 27 deletions
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index 35bb0adf10cf..5c495a17a5a3 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -60,6 +60,8 @@ struct ovl_entry {
60 struct path lowerstack[]; 60 struct path lowerstack[];
61}; 61};
62 62
63#define OVL_MAX_STACK 500
64
63const char *ovl_opaque_xattr = "trusted.overlay.opaque"; 65const char *ovl_opaque_xattr = "trusted.overlay.opaque";
64 66
65static struct dentry *__ovl_dentry_lower(struct ovl_entry *oe) 67static struct dentry *__ovl_dentry_lower(struct ovl_entry *oe)
@@ -692,8 +694,12 @@ static bool ovl_is_allowed_fs_type(struct dentry *root)
692 694
693static int ovl_mount_dir_noesc(const char *name, struct path *path) 695static int ovl_mount_dir_noesc(const char *name, struct path *path)
694{ 696{
695 int err; 697 int err = -EINVAL;
696 698
699 if (!*name) {
700 pr_err("overlayfs: empty lowerdir\n");
701 goto out;
702 }
697 err = kern_path(name, LOOKUP_FOLLOW, path); 703 err = kern_path(name, LOOKUP_FOLLOW, path);
698 if (err) { 704 if (err) {
699 pr_err("overlayfs: failed to resolve '%s': %i\n", name, err); 705 pr_err("overlayfs: failed to resolve '%s': %i\n", name, err);
@@ -735,7 +741,7 @@ static int ovl_lower_dir(const char *name, struct path *path, long *namelen,
735 int err; 741 int err;
736 struct kstatfs statfs; 742 struct kstatfs statfs;
737 743
738 err = ovl_mount_dir(name, path); 744 err = ovl_mount_dir_noesc(name, path);
739 if (err) 745 if (err)
740 goto out; 746 goto out;
741 747
@@ -767,15 +773,38 @@ static bool ovl_workdir_ok(struct dentry *workdir, struct dentry *upperdir)
767 return ok; 773 return ok;
768} 774}
769 775
776static unsigned int ovl_split_lowerdirs(char *str)
777{
778 unsigned int ctr = 1;
779 char *s, *d;
780
781 for (s = d = str;; s++, d++) {
782 if (*s == '\\') {
783 s++;
784 } else if (*s == ':') {
785 *d = '\0';
786 ctr++;
787 continue;
788 }
789 *d = *s;
790 if (!*s)
791 break;
792 }
793 return ctr;
794}
795
770static int ovl_fill_super(struct super_block *sb, void *data, int silent) 796static int ovl_fill_super(struct super_block *sb, void *data, int silent)
771{ 797{
772 struct path lowerpath;
773 struct path upperpath = { NULL, NULL }; 798 struct path upperpath = { NULL, NULL };
774 struct path workpath = { NULL, NULL }; 799 struct path workpath = { NULL, NULL };
775 struct dentry *root_dentry; 800 struct dentry *root_dentry;
776 struct ovl_entry *oe; 801 struct ovl_entry *oe;
777 struct ovl_fs *ufs; 802 struct ovl_fs *ufs;
778 struct vfsmount *mnt; 803 struct path *stack = NULL;
804 char *lowertmp;
805 char *lower;
806 unsigned int numlower;
807 unsigned int stacklen = 0;
779 unsigned int i; 808 unsigned int i;
780 int err; 809 int err;
781 810
@@ -820,13 +849,31 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
820 } 849 }
821 sb->s_stack_depth = upperpath.mnt->mnt_sb->s_stack_depth; 850 sb->s_stack_depth = upperpath.mnt->mnt_sb->s_stack_depth;
822 } 851 }
823 852 err = -ENOMEM;
824 err = ovl_lower_dir(ufs->config.lowerdir, &lowerpath, 853 lowertmp = kstrdup(ufs->config.lowerdir, GFP_KERNEL);
825 &ufs->lower_namelen, &sb->s_stack_depth); 854 if (!lowertmp)
826 if (err)
827 goto out_put_workpath; 855 goto out_put_workpath;
828 856
829 err = -EINVAL; 857 err = -EINVAL;
858 stacklen = ovl_split_lowerdirs(lowertmp);
859 if (stacklen > OVL_MAX_STACK)
860 goto out_free_lowertmp;
861
862 stack = kcalloc(stacklen, sizeof(struct path), GFP_KERNEL);
863 if (!stack)
864 goto out_free_lowertmp;
865
866 lower = lowertmp;
867 for (numlower = 0; numlower < stacklen; numlower++) {
868 err = ovl_lower_dir(lower, &stack[numlower],
869 &ufs->lower_namelen, &sb->s_stack_depth);
870 if (err)
871 goto out_put_lowerpath;
872
873 lower = strchr(lower, '\0') + 1;
874 }
875
876 err = -EINVAL;
830 sb->s_stack_depth++; 877 sb->s_stack_depth++;
831 if (sb->s_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) { 878 if (sb->s_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) {
832 pr_err("overlayfs: maximum fs stacking depth exceeded\n"); 879 pr_err("overlayfs: maximum fs stacking depth exceeded\n");
@@ -850,24 +897,25 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
850 } 897 }
851 } 898 }
852 899
853 ufs->lower_mnt = kcalloc(1, sizeof(struct vfsmount *), GFP_KERNEL); 900 ufs->lower_mnt = kcalloc(numlower, sizeof(struct vfsmount *), GFP_KERNEL);
854 if (ufs->lower_mnt == NULL) 901 if (ufs->lower_mnt == NULL)
855 goto out_put_workdir; 902 goto out_put_workdir;
903 for (i = 0; i < numlower; i++) {
904 struct vfsmount *mnt = clone_private_mount(&stack[i]);
856 905
857 mnt = clone_private_mount(&lowerpath); 906 if (IS_ERR(mnt)) {
858 err = PTR_ERR(mnt); 907 pr_err("overlayfs: failed to clone lowerpath\n");
859 if (IS_ERR(mnt)) { 908 goto out_put_lower_mnt;
860 pr_err("overlayfs: failed to clone lowerpath\n"); 909 }
861 goto out_put_lower_mnt; 910 /*
862 } 911 * Make lower_mnt R/O. That way fchmod/fchown on lower file
863 /* 912 * will fail instead of modifying lower fs.
864 * Make lower_mnt R/O. That way fchmod/fchown on lower file 913 */
865 * will fail instead of modifying lower fs. 914 mnt->mnt_flags |= MNT_READONLY;
866 */
867 mnt->mnt_flags |= MNT_READONLY;
868 915
869 ufs->lower_mnt[0] = mnt; 916 ufs->lower_mnt[ufs->numlower] = mnt;
870 ufs->numlower = 1; 917 ufs->numlower++;
918 }
871 919
872 /* If the upper fs is r/o or nonexistent, we mark overlayfs r/o too */ 920 /* If the upper fs is r/o or nonexistent, we mark overlayfs r/o too */
873 if (!ufs->upper_mnt || (ufs->upper_mnt->mnt_sb->s_flags & MS_RDONLY)) 921 if (!ufs->upper_mnt || (ufs->upper_mnt->mnt_sb->s_flags & MS_RDONLY))
@@ -876,7 +924,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
876 sb->s_d_op = &ovl_dentry_operations; 924 sb->s_d_op = &ovl_dentry_operations;
877 925
878 err = -ENOMEM; 926 err = -ENOMEM;
879 oe = ovl_alloc_entry(1); 927 oe = ovl_alloc_entry(numlower);
880 if (!oe) 928 if (!oe)
881 goto out_put_lower_mnt; 929 goto out_put_lower_mnt;
882 930
@@ -885,12 +933,16 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
885 goto out_free_oe; 933 goto out_free_oe;
886 934
887 mntput(upperpath.mnt); 935 mntput(upperpath.mnt);
888 mntput(lowerpath.mnt); 936 for (i = 0; i < numlower; i++)
937 mntput(stack[i].mnt);
889 path_put(&workpath); 938 path_put(&workpath);
939 kfree(lowertmp);
890 940
891 oe->__upperdentry = upperpath.dentry; 941 oe->__upperdentry = upperpath.dentry;
892 oe->lowerstack[0].dentry = lowerpath.dentry; 942 for (i = 0; i < numlower; i++) {
893 oe->lowerstack[0].mnt = ufs->lower_mnt[0]; 943 oe->lowerstack[i].dentry = stack[i].dentry;
944 oe->lowerstack[i].mnt = ufs->lower_mnt[i];
945 }
894 946
895 root_dentry->d_fsdata = oe; 947 root_dentry->d_fsdata = oe;
896 948
@@ -912,7 +964,11 @@ out_put_workdir:
912out_put_upper_mnt: 964out_put_upper_mnt:
913 mntput(ufs->upper_mnt); 965 mntput(ufs->upper_mnt);
914out_put_lowerpath: 966out_put_lowerpath:
915 path_put(&lowerpath); 967 for (i = 0; i < numlower; i++)
968 path_put(&stack[i]);
969 kfree(stack);
970out_free_lowertmp:
971 kfree(lowertmp);
916out_put_workpath: 972out_put_workpath:
917 path_put(&workpath); 973 path_put(&workpath);
918out_put_upperpath: 974out_put_upperpath: