1e9be9d5eSMiklos Szeredi /* 2e9be9d5eSMiklos Szeredi * 3e9be9d5eSMiklos Szeredi * Copyright (C) 2011 Novell Inc. 4e9be9d5eSMiklos Szeredi * 5e9be9d5eSMiklos Szeredi * This program is free software; you can redistribute it and/or modify it 6e9be9d5eSMiklos Szeredi * under the terms of the GNU General Public License version 2 as published by 7e9be9d5eSMiklos Szeredi * the Free Software Foundation. 8e9be9d5eSMiklos Szeredi */ 9e9be9d5eSMiklos Szeredi 10e9be9d5eSMiklos Szeredi #include <linux/fs.h> 11e9be9d5eSMiklos Szeredi #include <linux/namei.h> 12e9be9d5eSMiklos Szeredi #include <linux/xattr.h> 13e9be9d5eSMiklos Szeredi #include <linux/mount.h> 14e9be9d5eSMiklos Szeredi #include <linux/parser.h> 15e9be9d5eSMiklos Szeredi #include <linux/module.h> 16cc259639SAndy Whitcroft #include <linux/statfs.h> 17f45827e8SErez Zadok #include <linux/seq_file.h> 18d837a49bSMiklos Szeredi #include <linux/posix_acl_xattr.h> 19e9be9d5eSMiklos Szeredi #include "overlayfs.h" 20bbb1e54dSMiklos Szeredi #include "ovl_entry.h" 21e9be9d5eSMiklos Szeredi 22e9be9d5eSMiklos Szeredi MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>"); 23e9be9d5eSMiklos Szeredi MODULE_DESCRIPTION("Overlay filesystem"); 24e9be9d5eSMiklos Szeredi MODULE_LICENSE("GPL"); 25e9be9d5eSMiklos Szeredi 26e9be9d5eSMiklos Szeredi 27e9be9d5eSMiklos Szeredi struct ovl_dir_cache; 28e9be9d5eSMiklos Szeredi 29a78d9f0dSMiklos Szeredi #define OVL_MAX_STACK 500 30a78d9f0dSMiklos Szeredi 31e9be9d5eSMiklos Szeredi 32e9be9d5eSMiklos Szeredi static void ovl_dentry_release(struct dentry *dentry) 33e9be9d5eSMiklos Szeredi { 34e9be9d5eSMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 35e9be9d5eSMiklos Szeredi 36e9be9d5eSMiklos Szeredi if (oe) { 37dd662667SMiklos Szeredi unsigned int i; 38dd662667SMiklos Szeredi 39e9be9d5eSMiklos Szeredi dput(oe->__upperdentry); 4002b69b28SMiklos Szeredi kfree(oe->redirect); 41dd662667SMiklos Szeredi for (i = 0; i < oe->numlower; i++) 42dd662667SMiklos Szeredi dput(oe->lowerstack[i].dentry); 43e9be9d5eSMiklos Szeredi kfree_rcu(oe, rcu); 44e9be9d5eSMiklos Szeredi } 45e9be9d5eSMiklos Szeredi } 46e9be9d5eSMiklos Szeredi 472d902671SMiklos Szeredi static struct dentry *ovl_d_real(struct dentry *dentry, 482d902671SMiklos Szeredi const struct inode *inode, 492d902671SMiklos Szeredi unsigned int open_flags) 50d101a125SMiklos Szeredi { 51d101a125SMiklos Szeredi struct dentry *real; 52d101a125SMiklos Szeredi 53ca4c8a3aSMiklos Szeredi if (!d_is_reg(dentry)) { 54d101a125SMiklos Szeredi if (!inode || inode == d_inode(dentry)) 55d101a125SMiklos Szeredi return dentry; 56d101a125SMiklos Szeredi goto bug; 57d101a125SMiklos Szeredi } 58d101a125SMiklos Szeredi 592d902671SMiklos Szeredi if (d_is_negative(dentry)) 602d902671SMiklos Szeredi return dentry; 612d902671SMiklos Szeredi 622d902671SMiklos Szeredi if (open_flags) { 632d902671SMiklos Szeredi int err = ovl_open_maybe_copy_up(dentry, open_flags); 642d902671SMiklos Szeredi 652d902671SMiklos Szeredi if (err) 662d902671SMiklos Szeredi return ERR_PTR(err); 672d902671SMiklos Szeredi } 682d902671SMiklos Szeredi 69d101a125SMiklos Szeredi real = ovl_dentry_upper(dentry); 70d101a125SMiklos Szeredi if (real && (!inode || inode == d_inode(real))) 71d101a125SMiklos Szeredi return real; 72d101a125SMiklos Szeredi 73d101a125SMiklos Szeredi real = ovl_dentry_lower(dentry); 74d101a125SMiklos Szeredi if (!real) 75d101a125SMiklos Szeredi goto bug; 76d101a125SMiklos Szeredi 77c4fcfc16SMiklos Szeredi /* Handle recursion */ 78c4fcfc16SMiklos Szeredi real = d_real(real, inode, open_flags); 79c4fcfc16SMiklos Szeredi 80d101a125SMiklos Szeredi if (!inode || inode == d_inode(real)) 81d101a125SMiklos Szeredi return real; 82d101a125SMiklos Szeredi bug: 83656189d2SMiklos Szeredi WARN(1, "ovl_d_real(%pd4, %s:%lu): real dentry not found\n", dentry, 84d101a125SMiklos Szeredi inode ? inode->i_sb->s_id : "NULL", inode ? inode->i_ino : 0); 85d101a125SMiklos Szeredi return dentry; 86d101a125SMiklos Szeredi } 87d101a125SMiklos Szeredi 887c03b5d4SMiklos Szeredi static int ovl_dentry_revalidate(struct dentry *dentry, unsigned int flags) 897c03b5d4SMiklos Szeredi { 907c03b5d4SMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 917c03b5d4SMiklos Szeredi unsigned int i; 927c03b5d4SMiklos Szeredi int ret = 1; 937c03b5d4SMiklos Szeredi 947c03b5d4SMiklos Szeredi for (i = 0; i < oe->numlower; i++) { 957c03b5d4SMiklos Szeredi struct dentry *d = oe->lowerstack[i].dentry; 967c03b5d4SMiklos Szeredi 977c03b5d4SMiklos Szeredi if (d->d_flags & DCACHE_OP_REVALIDATE) { 987c03b5d4SMiklos Szeredi ret = d->d_op->d_revalidate(d, flags); 997c03b5d4SMiklos Szeredi if (ret < 0) 1007c03b5d4SMiklos Szeredi return ret; 1017c03b5d4SMiklos Szeredi if (!ret) { 1027c03b5d4SMiklos Szeredi if (!(flags & LOOKUP_RCU)) 1037c03b5d4SMiklos Szeredi d_invalidate(d); 1047c03b5d4SMiklos Szeredi return -ESTALE; 1057c03b5d4SMiklos Szeredi } 1067c03b5d4SMiklos Szeredi } 1077c03b5d4SMiklos Szeredi } 1087c03b5d4SMiklos Szeredi return 1; 1097c03b5d4SMiklos Szeredi } 1107c03b5d4SMiklos Szeredi 1117c03b5d4SMiklos Szeredi static int ovl_dentry_weak_revalidate(struct dentry *dentry, unsigned int flags) 1127c03b5d4SMiklos Szeredi { 1137c03b5d4SMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 1147c03b5d4SMiklos Szeredi unsigned int i; 1157c03b5d4SMiklos Szeredi int ret = 1; 1167c03b5d4SMiklos Szeredi 1177c03b5d4SMiklos Szeredi for (i = 0; i < oe->numlower; i++) { 1187c03b5d4SMiklos Szeredi struct dentry *d = oe->lowerstack[i].dentry; 1197c03b5d4SMiklos Szeredi 1207c03b5d4SMiklos Szeredi if (d->d_flags & DCACHE_OP_WEAK_REVALIDATE) { 1217c03b5d4SMiklos Szeredi ret = d->d_op->d_weak_revalidate(d, flags); 1227c03b5d4SMiklos Szeredi if (ret <= 0) 1237c03b5d4SMiklos Szeredi break; 1247c03b5d4SMiklos Szeredi } 1257c03b5d4SMiklos Szeredi } 1267c03b5d4SMiklos Szeredi return ret; 1277c03b5d4SMiklos Szeredi } 1287c03b5d4SMiklos Szeredi 129e9be9d5eSMiklos Szeredi static const struct dentry_operations ovl_dentry_operations = { 130e9be9d5eSMiklos Szeredi .d_release = ovl_dentry_release, 131d101a125SMiklos Szeredi .d_real = ovl_d_real, 132e9be9d5eSMiklos Szeredi }; 133e9be9d5eSMiklos Szeredi 1347c03b5d4SMiklos Szeredi static const struct dentry_operations ovl_reval_dentry_operations = { 1357c03b5d4SMiklos Szeredi .d_release = ovl_dentry_release, 136d101a125SMiklos Szeredi .d_real = ovl_d_real, 1377c03b5d4SMiklos Szeredi .d_revalidate = ovl_dentry_revalidate, 1387c03b5d4SMiklos Szeredi .d_weak_revalidate = ovl_dentry_weak_revalidate, 1397c03b5d4SMiklos Szeredi }; 1407c03b5d4SMiklos Szeredi 141e9be9d5eSMiklos Szeredi static void ovl_put_super(struct super_block *sb) 142e9be9d5eSMiklos Szeredi { 143e9be9d5eSMiklos Szeredi struct ovl_fs *ufs = sb->s_fs_info; 144dd662667SMiklos Szeredi unsigned i; 145e9be9d5eSMiklos Szeredi 146e9be9d5eSMiklos Szeredi dput(ufs->workdir); 147e9be9d5eSMiklos Szeredi mntput(ufs->upper_mnt); 148dd662667SMiklos Szeredi for (i = 0; i < ufs->numlower; i++) 149dd662667SMiklos Szeredi mntput(ufs->lower_mnt[i]); 1505ffdbe8bSKonstantin Khlebnikov kfree(ufs->lower_mnt); 151e9be9d5eSMiklos Szeredi 152f45827e8SErez Zadok kfree(ufs->config.lowerdir); 153f45827e8SErez Zadok kfree(ufs->config.upperdir); 154f45827e8SErez Zadok kfree(ufs->config.workdir); 1553fe6e52fSAntonio Murdaca put_cred(ufs->creator_cred); 156e9be9d5eSMiklos Szeredi kfree(ufs); 157e9be9d5eSMiklos Szeredi } 158e9be9d5eSMiklos Szeredi 159cc259639SAndy Whitcroft /** 160cc259639SAndy Whitcroft * ovl_statfs 161cc259639SAndy Whitcroft * @sb: The overlayfs super block 162cc259639SAndy Whitcroft * @buf: The struct kstatfs to fill in with stats 163cc259639SAndy Whitcroft * 164cc259639SAndy Whitcroft * Get the filesystem statistics. As writes always target the upper layer 1654ebc5818SMiklos Szeredi * filesystem pass the statfs to the upper filesystem (if it exists) 166cc259639SAndy Whitcroft */ 167cc259639SAndy Whitcroft static int ovl_statfs(struct dentry *dentry, struct kstatfs *buf) 168cc259639SAndy Whitcroft { 169cc259639SAndy Whitcroft struct ovl_fs *ofs = dentry->d_sb->s_fs_info; 170cc259639SAndy Whitcroft struct dentry *root_dentry = dentry->d_sb->s_root; 171cc259639SAndy Whitcroft struct path path; 172cc259639SAndy Whitcroft int err; 173cc259639SAndy Whitcroft 1744ebc5818SMiklos Szeredi ovl_path_real(root_dentry, &path); 175cc259639SAndy Whitcroft 176cc259639SAndy Whitcroft err = vfs_statfs(&path, buf); 177cc259639SAndy Whitcroft if (!err) { 1786b2d5fe4SMiklos Szeredi buf->f_namelen = ofs->namelen; 179cc259639SAndy Whitcroft buf->f_type = OVERLAYFS_SUPER_MAGIC; 180cc259639SAndy Whitcroft } 181cc259639SAndy Whitcroft 182cc259639SAndy Whitcroft return err; 183cc259639SAndy Whitcroft } 184cc259639SAndy Whitcroft 185f45827e8SErez Zadok /** 186f45827e8SErez Zadok * ovl_show_options 187f45827e8SErez Zadok * 188f45827e8SErez Zadok * Prints the mount options for a given superblock. 189f45827e8SErez Zadok * Returns zero; does not fail. 190f45827e8SErez Zadok */ 191f45827e8SErez Zadok static int ovl_show_options(struct seq_file *m, struct dentry *dentry) 192f45827e8SErez Zadok { 193f45827e8SErez Zadok struct super_block *sb = dentry->d_sb; 194f45827e8SErez Zadok struct ovl_fs *ufs = sb->s_fs_info; 195f45827e8SErez Zadok 196a068acf2SKees Cook seq_show_option(m, "lowerdir", ufs->config.lowerdir); 19753a08cb9SMiklos Szeredi if (ufs->config.upperdir) { 198a068acf2SKees Cook seq_show_option(m, "upperdir", ufs->config.upperdir); 199a068acf2SKees Cook seq_show_option(m, "workdir", ufs->config.workdir); 20053a08cb9SMiklos Szeredi } 2018d3095f4SMiklos Szeredi if (ufs->config.default_permissions) 2028d3095f4SMiklos Szeredi seq_puts(m, ",default_permissions"); 203f45827e8SErez Zadok return 0; 204f45827e8SErez Zadok } 205f45827e8SErez Zadok 2063cdf6fe9SSeunghun Lee static int ovl_remount(struct super_block *sb, int *flags, char *data) 2073cdf6fe9SSeunghun Lee { 2083cdf6fe9SSeunghun Lee struct ovl_fs *ufs = sb->s_fs_info; 2093cdf6fe9SSeunghun Lee 210cc6f67bcSMiklos Szeredi if (!(*flags & MS_RDONLY) && (!ufs->upper_mnt || !ufs->workdir)) 2113cdf6fe9SSeunghun Lee return -EROFS; 2123cdf6fe9SSeunghun Lee 2133cdf6fe9SSeunghun Lee return 0; 2143cdf6fe9SSeunghun Lee } 2153cdf6fe9SSeunghun Lee 216e9be9d5eSMiklos Szeredi static const struct super_operations ovl_super_operations = { 217e9be9d5eSMiklos Szeredi .put_super = ovl_put_super, 218cc259639SAndy Whitcroft .statfs = ovl_statfs, 219f45827e8SErez Zadok .show_options = ovl_show_options, 2203cdf6fe9SSeunghun Lee .remount_fs = ovl_remount, 221eead4f2dSMiklos Szeredi .drop_inode = generic_delete_inode, 222e9be9d5eSMiklos Szeredi }; 223e9be9d5eSMiklos Szeredi 224e9be9d5eSMiklos Szeredi enum { 225e9be9d5eSMiklos Szeredi OPT_LOWERDIR, 226e9be9d5eSMiklos Szeredi OPT_UPPERDIR, 227e9be9d5eSMiklos Szeredi OPT_WORKDIR, 2288d3095f4SMiklos Szeredi OPT_DEFAULT_PERMISSIONS, 229e9be9d5eSMiklos Szeredi OPT_ERR, 230e9be9d5eSMiklos Szeredi }; 231e9be9d5eSMiklos Szeredi 232e9be9d5eSMiklos Szeredi static const match_table_t ovl_tokens = { 233e9be9d5eSMiklos Szeredi {OPT_LOWERDIR, "lowerdir=%s"}, 234e9be9d5eSMiklos Szeredi {OPT_UPPERDIR, "upperdir=%s"}, 235e9be9d5eSMiklos Szeredi {OPT_WORKDIR, "workdir=%s"}, 2368d3095f4SMiklos Szeredi {OPT_DEFAULT_PERMISSIONS, "default_permissions"}, 237e9be9d5eSMiklos Szeredi {OPT_ERR, NULL} 238e9be9d5eSMiklos Szeredi }; 239e9be9d5eSMiklos Szeredi 24091c77947SMiklos Szeredi static char *ovl_next_opt(char **s) 24191c77947SMiklos Szeredi { 24291c77947SMiklos Szeredi char *sbegin = *s; 24391c77947SMiklos Szeredi char *p; 24491c77947SMiklos Szeredi 24591c77947SMiklos Szeredi if (sbegin == NULL) 24691c77947SMiklos Szeredi return NULL; 24791c77947SMiklos Szeredi 24891c77947SMiklos Szeredi for (p = sbegin; *p; p++) { 24991c77947SMiklos Szeredi if (*p == '\\') { 25091c77947SMiklos Szeredi p++; 25191c77947SMiklos Szeredi if (!*p) 25291c77947SMiklos Szeredi break; 25391c77947SMiklos Szeredi } else if (*p == ',') { 25491c77947SMiklos Szeredi *p = '\0'; 25591c77947SMiklos Szeredi *s = p + 1; 25691c77947SMiklos Szeredi return sbegin; 25791c77947SMiklos Szeredi } 25891c77947SMiklos Szeredi } 25991c77947SMiklos Szeredi *s = NULL; 26091c77947SMiklos Szeredi return sbegin; 26191c77947SMiklos Szeredi } 26291c77947SMiklos Szeredi 263e9be9d5eSMiklos Szeredi static int ovl_parse_opt(char *opt, struct ovl_config *config) 264e9be9d5eSMiklos Szeredi { 265e9be9d5eSMiklos Szeredi char *p; 266e9be9d5eSMiklos Szeredi 26791c77947SMiklos Szeredi while ((p = ovl_next_opt(&opt)) != NULL) { 268e9be9d5eSMiklos Szeredi int token; 269e9be9d5eSMiklos Szeredi substring_t args[MAX_OPT_ARGS]; 270e9be9d5eSMiklos Szeredi 271e9be9d5eSMiklos Szeredi if (!*p) 272e9be9d5eSMiklos Szeredi continue; 273e9be9d5eSMiklos Szeredi 274e9be9d5eSMiklos Szeredi token = match_token(p, ovl_tokens, args); 275e9be9d5eSMiklos Szeredi switch (token) { 276e9be9d5eSMiklos Szeredi case OPT_UPPERDIR: 277e9be9d5eSMiklos Szeredi kfree(config->upperdir); 278e9be9d5eSMiklos Szeredi config->upperdir = match_strdup(&args[0]); 279e9be9d5eSMiklos Szeredi if (!config->upperdir) 280e9be9d5eSMiklos Szeredi return -ENOMEM; 281e9be9d5eSMiklos Szeredi break; 282e9be9d5eSMiklos Szeredi 283e9be9d5eSMiklos Szeredi case OPT_LOWERDIR: 284e9be9d5eSMiklos Szeredi kfree(config->lowerdir); 285e9be9d5eSMiklos Szeredi config->lowerdir = match_strdup(&args[0]); 286e9be9d5eSMiklos Szeredi if (!config->lowerdir) 287e9be9d5eSMiklos Szeredi return -ENOMEM; 288e9be9d5eSMiklos Szeredi break; 289e9be9d5eSMiklos Szeredi 290e9be9d5eSMiklos Szeredi case OPT_WORKDIR: 291e9be9d5eSMiklos Szeredi kfree(config->workdir); 292e9be9d5eSMiklos Szeredi config->workdir = match_strdup(&args[0]); 293e9be9d5eSMiklos Szeredi if (!config->workdir) 294e9be9d5eSMiklos Szeredi return -ENOMEM; 295e9be9d5eSMiklos Szeredi break; 296e9be9d5eSMiklos Szeredi 2978d3095f4SMiklos Szeredi case OPT_DEFAULT_PERMISSIONS: 2988d3095f4SMiklos Szeredi config->default_permissions = true; 2998d3095f4SMiklos Szeredi break; 3008d3095f4SMiklos Szeredi 301e9be9d5eSMiklos Szeredi default: 302bead55efShujianyang pr_err("overlayfs: unrecognized mount option \"%s\" or missing value\n", p); 303e9be9d5eSMiklos Szeredi return -EINVAL; 304e9be9d5eSMiklos Szeredi } 305e9be9d5eSMiklos Szeredi } 30671cbad7eShujianyang 30771cbad7eShujianyang /* Workdir is useless in non-upper mount */ 30871cbad7eShujianyang if (!config->upperdir && config->workdir) { 30971cbad7eShujianyang pr_info("overlayfs: option \"workdir=%s\" is useless in a non-upper mount, ignore\n", 31071cbad7eShujianyang config->workdir); 31171cbad7eShujianyang kfree(config->workdir); 31271cbad7eShujianyang config->workdir = NULL; 31371cbad7eShujianyang } 31471cbad7eShujianyang 315e9be9d5eSMiklos Szeredi return 0; 316e9be9d5eSMiklos Szeredi } 317e9be9d5eSMiklos Szeredi 318e9be9d5eSMiklos Szeredi #define OVL_WORKDIR_NAME "work" 319e9be9d5eSMiklos Szeredi 320e9be9d5eSMiklos Szeredi static struct dentry *ovl_workdir_create(struct vfsmount *mnt, 321e9be9d5eSMiklos Szeredi struct dentry *dentry) 322e9be9d5eSMiklos Szeredi { 323e9be9d5eSMiklos Szeredi struct inode *dir = dentry->d_inode; 324e9be9d5eSMiklos Szeredi struct dentry *work; 325e9be9d5eSMiklos Szeredi int err; 326e9be9d5eSMiklos Szeredi bool retried = false; 327e9be9d5eSMiklos Szeredi 328e9be9d5eSMiklos Szeredi err = mnt_want_write(mnt); 329e9be9d5eSMiklos Szeredi if (err) 330e9be9d5eSMiklos Szeredi return ERR_PTR(err); 331e9be9d5eSMiklos Szeredi 3325955102cSAl Viro inode_lock_nested(dir, I_MUTEX_PARENT); 333e9be9d5eSMiklos Szeredi retry: 334e9be9d5eSMiklos Szeredi work = lookup_one_len(OVL_WORKDIR_NAME, dentry, 335e9be9d5eSMiklos Szeredi strlen(OVL_WORKDIR_NAME)); 336e9be9d5eSMiklos Szeredi 337e9be9d5eSMiklos Szeredi if (!IS_ERR(work)) { 338e9be9d5eSMiklos Szeredi struct kstat stat = { 339e9be9d5eSMiklos Szeredi .mode = S_IFDIR | 0, 340e9be9d5eSMiklos Szeredi }; 341c11b9fddSMiklos Szeredi struct iattr attr = { 342c11b9fddSMiklos Szeredi .ia_valid = ATTR_MODE, 343c11b9fddSMiklos Szeredi .ia_mode = stat.mode, 344c11b9fddSMiklos Szeredi }; 345e9be9d5eSMiklos Szeredi 346e9be9d5eSMiklos Szeredi if (work->d_inode) { 347e9be9d5eSMiklos Szeredi err = -EEXIST; 348e9be9d5eSMiklos Szeredi if (retried) 349e9be9d5eSMiklos Szeredi goto out_dput; 350e9be9d5eSMiklos Szeredi 351e9be9d5eSMiklos Szeredi retried = true; 352eea2fb48SMiklos Szeredi ovl_workdir_cleanup(dir, mnt, work, 0); 353e9be9d5eSMiklos Szeredi dput(work); 354e9be9d5eSMiklos Szeredi goto retry; 355e9be9d5eSMiklos Szeredi } 356e9be9d5eSMiklos Szeredi 357e9be9d5eSMiklos Szeredi err = ovl_create_real(dir, work, &stat, NULL, NULL, true); 358e9be9d5eSMiklos Szeredi if (err) 359e9be9d5eSMiklos Szeredi goto out_dput; 360c11b9fddSMiklos Szeredi 361cb348edbSMiklos Szeredi /* 362cb348edbSMiklos Szeredi * Try to remove POSIX ACL xattrs from workdir. We are good if: 363cb348edbSMiklos Szeredi * 364cb348edbSMiklos Szeredi * a) success (there was a POSIX ACL xattr and was removed) 365cb348edbSMiklos Szeredi * b) -ENODATA (there was no POSIX ACL xattr) 366cb348edbSMiklos Szeredi * c) -EOPNOTSUPP (POSIX ACL xattrs are not supported) 367cb348edbSMiklos Szeredi * 368cb348edbSMiklos Szeredi * There are various other error values that could effectively 369cb348edbSMiklos Szeredi * mean that the xattr doesn't exist (e.g. -ERANGE is returned 370cb348edbSMiklos Szeredi * if the xattr name is too long), but the set of filesystems 371cb348edbSMiklos Szeredi * allowed as upper are limited to "normal" ones, where checking 372cb348edbSMiklos Szeredi * for the above two errors is sufficient. 373cb348edbSMiklos Szeredi */ 374c11b9fddSMiklos Szeredi err = vfs_removexattr(work, XATTR_NAME_POSIX_ACL_DEFAULT); 375e1ff3dd1SMiklos Szeredi if (err && err != -ENODATA && err != -EOPNOTSUPP) 376c11b9fddSMiklos Szeredi goto out_dput; 377c11b9fddSMiklos Szeredi 378c11b9fddSMiklos Szeredi err = vfs_removexattr(work, XATTR_NAME_POSIX_ACL_ACCESS); 379e1ff3dd1SMiklos Szeredi if (err && err != -ENODATA && err != -EOPNOTSUPP) 380c11b9fddSMiklos Szeredi goto out_dput; 381c11b9fddSMiklos Szeredi 382c11b9fddSMiklos Szeredi /* Clear any inherited mode bits */ 383c11b9fddSMiklos Szeredi inode_lock(work->d_inode); 384c11b9fddSMiklos Szeredi err = notify_change(work, &attr, NULL); 385c11b9fddSMiklos Szeredi inode_unlock(work->d_inode); 386c11b9fddSMiklos Szeredi if (err) 387c11b9fddSMiklos Szeredi goto out_dput; 388e9be9d5eSMiklos Szeredi } 389e9be9d5eSMiklos Szeredi out_unlock: 3905955102cSAl Viro inode_unlock(dir); 391e9be9d5eSMiklos Szeredi mnt_drop_write(mnt); 392e9be9d5eSMiklos Szeredi 393e9be9d5eSMiklos Szeredi return work; 394e9be9d5eSMiklos Szeredi 395e9be9d5eSMiklos Szeredi out_dput: 396e9be9d5eSMiklos Szeredi dput(work); 397e9be9d5eSMiklos Szeredi work = ERR_PTR(err); 398e9be9d5eSMiklos Szeredi goto out_unlock; 399e9be9d5eSMiklos Szeredi } 400e9be9d5eSMiklos Szeredi 40191c77947SMiklos Szeredi static void ovl_unescape(char *s) 40291c77947SMiklos Szeredi { 40391c77947SMiklos Szeredi char *d = s; 40491c77947SMiklos Szeredi 40591c77947SMiklos Szeredi for (;; s++, d++) { 40691c77947SMiklos Szeredi if (*s == '\\') 40791c77947SMiklos Szeredi s++; 40891c77947SMiklos Szeredi *d = *s; 40991c77947SMiklos Szeredi if (!*s) 41091c77947SMiklos Szeredi break; 41191c77947SMiklos Szeredi } 41291c77947SMiklos Szeredi } 41391c77947SMiklos Szeredi 414ab508822SMiklos Szeredi static int ovl_mount_dir_noesc(const char *name, struct path *path) 415ab508822SMiklos Szeredi { 416a78d9f0dSMiklos Szeredi int err = -EINVAL; 417ab508822SMiklos Szeredi 418a78d9f0dSMiklos Szeredi if (!*name) { 419a78d9f0dSMiklos Szeredi pr_err("overlayfs: empty lowerdir\n"); 420a78d9f0dSMiklos Szeredi goto out; 421a78d9f0dSMiklos Szeredi } 422ab508822SMiklos Szeredi err = kern_path(name, LOOKUP_FOLLOW, path); 423ab508822SMiklos Szeredi if (err) { 424ab508822SMiklos Szeredi pr_err("overlayfs: failed to resolve '%s': %i\n", name, err); 425ab508822SMiklos Szeredi goto out; 426ab508822SMiklos Szeredi } 427ab508822SMiklos Szeredi err = -EINVAL; 4287c03b5d4SMiklos Szeredi if (ovl_dentry_weird(path->dentry)) { 429ab508822SMiklos Szeredi pr_err("overlayfs: filesystem on '%s' not supported\n", name); 430ab508822SMiklos Szeredi goto out_put; 431ab508822SMiklos Szeredi } 4322b8c30e9SMiklos Szeredi if (!d_is_dir(path->dentry)) { 433ab508822SMiklos Szeredi pr_err("overlayfs: '%s' not a directory\n", name); 434ab508822SMiklos Szeredi goto out_put; 435ab508822SMiklos Szeredi } 436ab508822SMiklos Szeredi return 0; 437ab508822SMiklos Szeredi 438ab508822SMiklos Szeredi out_put: 439ab508822SMiklos Szeredi path_put(path); 440ab508822SMiklos Szeredi out: 441ab508822SMiklos Szeredi return err; 442ab508822SMiklos Szeredi } 443ab508822SMiklos Szeredi 444ab508822SMiklos Szeredi static int ovl_mount_dir(const char *name, struct path *path) 445ab508822SMiklos Szeredi { 446ab508822SMiklos Szeredi int err = -ENOMEM; 447ab508822SMiklos Szeredi char *tmp = kstrdup(name, GFP_KERNEL); 448ab508822SMiklos Szeredi 449ab508822SMiklos Szeredi if (tmp) { 450ab508822SMiklos Szeredi ovl_unescape(tmp); 451ab508822SMiklos Szeredi err = ovl_mount_dir_noesc(tmp, path); 4527c03b5d4SMiklos Szeredi 4537c03b5d4SMiklos Szeredi if (!err) 4547c03b5d4SMiklos Szeredi if (ovl_dentry_remote(path->dentry)) { 4557c03b5d4SMiklos Szeredi pr_err("overlayfs: filesystem on '%s' not supported as upperdir\n", 4567c03b5d4SMiklos Szeredi tmp); 4577c03b5d4SMiklos Szeredi path_put(path); 4587c03b5d4SMiklos Szeredi err = -EINVAL; 4597c03b5d4SMiklos Szeredi } 460ab508822SMiklos Szeredi kfree(tmp); 461ab508822SMiklos Szeredi } 462ab508822SMiklos Szeredi return err; 463ab508822SMiklos Szeredi } 464ab508822SMiklos Szeredi 4656b2d5fe4SMiklos Szeredi static int ovl_check_namelen(struct path *path, struct ovl_fs *ofs, 4666b2d5fe4SMiklos Szeredi const char *name) 4676b2d5fe4SMiklos Szeredi { 4686b2d5fe4SMiklos Szeredi struct kstatfs statfs; 4696b2d5fe4SMiklos Szeredi int err = vfs_statfs(path, &statfs); 4706b2d5fe4SMiklos Szeredi 4716b2d5fe4SMiklos Szeredi if (err) 4726b2d5fe4SMiklos Szeredi pr_err("overlayfs: statfs failed on '%s'\n", name); 4736b2d5fe4SMiklos Szeredi else 4746b2d5fe4SMiklos Szeredi ofs->namelen = max(ofs->namelen, statfs.f_namelen); 4756b2d5fe4SMiklos Szeredi 4766b2d5fe4SMiklos Szeredi return err; 4776b2d5fe4SMiklos Szeredi } 4786b2d5fe4SMiklos Szeredi 4796b2d5fe4SMiklos Szeredi static int ovl_lower_dir(const char *name, struct path *path, 4806b2d5fe4SMiklos Szeredi struct ovl_fs *ofs, int *stack_depth, bool *remote) 481ab508822SMiklos Szeredi { 482ab508822SMiklos Szeredi int err; 483ab508822SMiklos Szeredi 484a78d9f0dSMiklos Szeredi err = ovl_mount_dir_noesc(name, path); 485ab508822SMiklos Szeredi if (err) 486ab508822SMiklos Szeredi goto out; 487ab508822SMiklos Szeredi 4886b2d5fe4SMiklos Szeredi err = ovl_check_namelen(path, ofs, name); 4896b2d5fe4SMiklos Szeredi if (err) 490ab508822SMiklos Szeredi goto out_put; 4916b2d5fe4SMiklos Szeredi 492ab508822SMiklos Szeredi *stack_depth = max(*stack_depth, path->mnt->mnt_sb->s_stack_depth); 493ab508822SMiklos Szeredi 4947c03b5d4SMiklos Szeredi if (ovl_dentry_remote(path->dentry)) 4957c03b5d4SMiklos Szeredi *remote = true; 4967c03b5d4SMiklos Szeredi 497ab508822SMiklos Szeredi return 0; 498ab508822SMiklos Szeredi 499ab508822SMiklos Szeredi out_put: 500ab508822SMiklos Szeredi path_put(path); 501ab508822SMiklos Szeredi out: 502ab508822SMiklos Szeredi return err; 503ab508822SMiklos Szeredi } 504ab508822SMiklos Szeredi 505e9be9d5eSMiklos Szeredi /* Workdir should not be subdir of upperdir and vice versa */ 506e9be9d5eSMiklos Szeredi static bool ovl_workdir_ok(struct dentry *workdir, struct dentry *upperdir) 507e9be9d5eSMiklos Szeredi { 508e9be9d5eSMiklos Szeredi bool ok = false; 509e9be9d5eSMiklos Szeredi 510e9be9d5eSMiklos Szeredi if (workdir != upperdir) { 511e9be9d5eSMiklos Szeredi ok = (lock_rename(workdir, upperdir) == NULL); 512e9be9d5eSMiklos Szeredi unlock_rename(workdir, upperdir); 513e9be9d5eSMiklos Szeredi } 514e9be9d5eSMiklos Szeredi return ok; 515e9be9d5eSMiklos Szeredi } 516e9be9d5eSMiklos Szeredi 517a78d9f0dSMiklos Szeredi static unsigned int ovl_split_lowerdirs(char *str) 518a78d9f0dSMiklos Szeredi { 519a78d9f0dSMiklos Szeredi unsigned int ctr = 1; 520a78d9f0dSMiklos Szeredi char *s, *d; 521a78d9f0dSMiklos Szeredi 522a78d9f0dSMiklos Szeredi for (s = d = str;; s++, d++) { 523a78d9f0dSMiklos Szeredi if (*s == '\\') { 524a78d9f0dSMiklos Szeredi s++; 525a78d9f0dSMiklos Szeredi } else if (*s == ':') { 526a78d9f0dSMiklos Szeredi *d = '\0'; 527a78d9f0dSMiklos Szeredi ctr++; 528a78d9f0dSMiklos Szeredi continue; 529a78d9f0dSMiklos Szeredi } 530a78d9f0dSMiklos Szeredi *d = *s; 531a78d9f0dSMiklos Szeredi if (!*s) 532a78d9f0dSMiklos Szeredi break; 533a78d9f0dSMiklos Szeredi } 534a78d9f0dSMiklos Szeredi return ctr; 535a78d9f0dSMiklos Szeredi } 536a78d9f0dSMiklos Szeredi 5370c97be22SAndreas Gruenbacher static int __maybe_unused 5380eb45fc3SAndreas Gruenbacher ovl_posix_acl_xattr_get(const struct xattr_handler *handler, 5390eb45fc3SAndreas Gruenbacher struct dentry *dentry, struct inode *inode, 5400eb45fc3SAndreas Gruenbacher const char *name, void *buffer, size_t size) 5410eb45fc3SAndreas Gruenbacher { 5420eb45fc3SAndreas Gruenbacher return ovl_xattr_get(dentry, handler->name, buffer, size); 5430eb45fc3SAndreas Gruenbacher } 5440eb45fc3SAndreas Gruenbacher 5450eb45fc3SAndreas Gruenbacher static int __maybe_unused 5460c97be22SAndreas Gruenbacher ovl_posix_acl_xattr_set(const struct xattr_handler *handler, 547d837a49bSMiklos Szeredi struct dentry *dentry, struct inode *inode, 548d837a49bSMiklos Szeredi const char *name, const void *value, 549d837a49bSMiklos Szeredi size_t size, int flags) 550d837a49bSMiklos Szeredi { 551d837a49bSMiklos Szeredi struct dentry *workdir = ovl_workdir(dentry); 552d837a49bSMiklos Szeredi struct inode *realinode = ovl_inode_real(inode, NULL); 553d837a49bSMiklos Szeredi struct posix_acl *acl = NULL; 554d837a49bSMiklos Szeredi int err; 555d837a49bSMiklos Szeredi 556d837a49bSMiklos Szeredi /* Check that everything is OK before copy-up */ 557d837a49bSMiklos Szeredi if (value) { 558d837a49bSMiklos Szeredi acl = posix_acl_from_xattr(&init_user_ns, value, size); 559d837a49bSMiklos Szeredi if (IS_ERR(acl)) 560d837a49bSMiklos Szeredi return PTR_ERR(acl); 561d837a49bSMiklos Szeredi } 562d837a49bSMiklos Szeredi err = -EOPNOTSUPP; 563d837a49bSMiklos Szeredi if (!IS_POSIXACL(d_inode(workdir))) 564d837a49bSMiklos Szeredi goto out_acl_release; 565d837a49bSMiklos Szeredi if (!realinode->i_op->set_acl) 566d837a49bSMiklos Szeredi goto out_acl_release; 567d837a49bSMiklos Szeredi if (handler->flags == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode)) { 568d837a49bSMiklos Szeredi err = acl ? -EACCES : 0; 569d837a49bSMiklos Szeredi goto out_acl_release; 570d837a49bSMiklos Szeredi } 571d837a49bSMiklos Szeredi err = -EPERM; 572d837a49bSMiklos Szeredi if (!inode_owner_or_capable(inode)) 573d837a49bSMiklos Szeredi goto out_acl_release; 574d837a49bSMiklos Szeredi 575d837a49bSMiklos Szeredi posix_acl_release(acl); 576d837a49bSMiklos Szeredi 577fd3220d3SMiklos Szeredi /* 578fd3220d3SMiklos Szeredi * Check if sgid bit needs to be cleared (actual setacl operation will 579fd3220d3SMiklos Szeredi * be done with mounter's capabilities and so that won't do it for us). 580fd3220d3SMiklos Szeredi */ 581fd3220d3SMiklos Szeredi if (unlikely(inode->i_mode & S_ISGID) && 582fd3220d3SMiklos Szeredi handler->flags == ACL_TYPE_ACCESS && 583fd3220d3SMiklos Szeredi !in_group_p(inode->i_gid) && 584fd3220d3SMiklos Szeredi !capable_wrt_inode_uidgid(inode, CAP_FSETID)) { 585fd3220d3SMiklos Szeredi struct iattr iattr = { .ia_valid = ATTR_KILL_SGID }; 586fd3220d3SMiklos Szeredi 587fd3220d3SMiklos Szeredi err = ovl_setattr(dentry, &iattr); 588fd3220d3SMiklos Szeredi if (err) 589fd3220d3SMiklos Szeredi return err; 590fd3220d3SMiklos Szeredi } 591fd3220d3SMiklos Szeredi 592ce31513aSMiklos Szeredi err = ovl_xattr_set(dentry, handler->name, value, size, flags); 593ce31513aSMiklos Szeredi if (!err) 594ce31513aSMiklos Szeredi ovl_copyattr(ovl_inode_real(inode, NULL), inode); 595ce31513aSMiklos Szeredi 596ce31513aSMiklos Szeredi return err; 597d837a49bSMiklos Szeredi 598d837a49bSMiklos Szeredi out_acl_release: 599d837a49bSMiklos Szeredi posix_acl_release(acl); 600d837a49bSMiklos Szeredi return err; 601d837a49bSMiklos Szeredi } 602d837a49bSMiklos Szeredi 6030eb45fc3SAndreas Gruenbacher static int ovl_own_xattr_get(const struct xattr_handler *handler, 6040eb45fc3SAndreas Gruenbacher struct dentry *dentry, struct inode *inode, 6050eb45fc3SAndreas Gruenbacher const char *name, void *buffer, size_t size) 6060eb45fc3SAndreas Gruenbacher { 60748fab5d7SAmir Goldstein return -EOPNOTSUPP; 6080eb45fc3SAndreas Gruenbacher } 6090eb45fc3SAndreas Gruenbacher 610d837a49bSMiklos Szeredi static int ovl_own_xattr_set(const struct xattr_handler *handler, 611d837a49bSMiklos Szeredi struct dentry *dentry, struct inode *inode, 612d837a49bSMiklos Szeredi const char *name, const void *value, 613d837a49bSMiklos Szeredi size_t size, int flags) 614d837a49bSMiklos Szeredi { 61548fab5d7SAmir Goldstein return -EOPNOTSUPP; 616d837a49bSMiklos Szeredi } 617d837a49bSMiklos Szeredi 6180eb45fc3SAndreas Gruenbacher static int ovl_other_xattr_get(const struct xattr_handler *handler, 6190eb45fc3SAndreas Gruenbacher struct dentry *dentry, struct inode *inode, 6200eb45fc3SAndreas Gruenbacher const char *name, void *buffer, size_t size) 6210eb45fc3SAndreas Gruenbacher { 6220eb45fc3SAndreas Gruenbacher return ovl_xattr_get(dentry, name, buffer, size); 6230eb45fc3SAndreas Gruenbacher } 6240eb45fc3SAndreas Gruenbacher 6250e585cccSAndreas Gruenbacher static int ovl_other_xattr_set(const struct xattr_handler *handler, 6260e585cccSAndreas Gruenbacher struct dentry *dentry, struct inode *inode, 6270e585cccSAndreas Gruenbacher const char *name, const void *value, 6280e585cccSAndreas Gruenbacher size_t size, int flags) 6290e585cccSAndreas Gruenbacher { 6300e585cccSAndreas Gruenbacher return ovl_xattr_set(dentry, name, value, size, flags); 6310e585cccSAndreas Gruenbacher } 6320e585cccSAndreas Gruenbacher 6330c97be22SAndreas Gruenbacher static const struct xattr_handler __maybe_unused 6340c97be22SAndreas Gruenbacher ovl_posix_acl_access_xattr_handler = { 635d837a49bSMiklos Szeredi .name = XATTR_NAME_POSIX_ACL_ACCESS, 636d837a49bSMiklos Szeredi .flags = ACL_TYPE_ACCESS, 6370eb45fc3SAndreas Gruenbacher .get = ovl_posix_acl_xattr_get, 638d837a49bSMiklos Szeredi .set = ovl_posix_acl_xattr_set, 639d837a49bSMiklos Szeredi }; 640d837a49bSMiklos Szeredi 6410c97be22SAndreas Gruenbacher static const struct xattr_handler __maybe_unused 6420c97be22SAndreas Gruenbacher ovl_posix_acl_default_xattr_handler = { 643d837a49bSMiklos Szeredi .name = XATTR_NAME_POSIX_ACL_DEFAULT, 644d837a49bSMiklos Szeredi .flags = ACL_TYPE_DEFAULT, 6450eb45fc3SAndreas Gruenbacher .get = ovl_posix_acl_xattr_get, 646d837a49bSMiklos Szeredi .set = ovl_posix_acl_xattr_set, 647d837a49bSMiklos Szeredi }; 648d837a49bSMiklos Szeredi 649d837a49bSMiklos Szeredi static const struct xattr_handler ovl_own_xattr_handler = { 650d837a49bSMiklos Szeredi .prefix = OVL_XATTR_PREFIX, 6510eb45fc3SAndreas Gruenbacher .get = ovl_own_xattr_get, 652d837a49bSMiklos Szeredi .set = ovl_own_xattr_set, 653d837a49bSMiklos Szeredi }; 654d837a49bSMiklos Szeredi 655d837a49bSMiklos Szeredi static const struct xattr_handler ovl_other_xattr_handler = { 656d837a49bSMiklos Szeredi .prefix = "", /* catch all */ 6570eb45fc3SAndreas Gruenbacher .get = ovl_other_xattr_get, 658d837a49bSMiklos Szeredi .set = ovl_other_xattr_set, 659d837a49bSMiklos Szeredi }; 660d837a49bSMiklos Szeredi 661d837a49bSMiklos Szeredi static const struct xattr_handler *ovl_xattr_handlers[] = { 6620c97be22SAndreas Gruenbacher #ifdef CONFIG_FS_POSIX_ACL 663d837a49bSMiklos Szeredi &ovl_posix_acl_access_xattr_handler, 664d837a49bSMiklos Szeredi &ovl_posix_acl_default_xattr_handler, 6650c97be22SAndreas Gruenbacher #endif 666d837a49bSMiklos Szeredi &ovl_own_xattr_handler, 667d837a49bSMiklos Szeredi &ovl_other_xattr_handler, 668d837a49bSMiklos Szeredi NULL 669d837a49bSMiklos Szeredi }; 670d837a49bSMiklos Szeredi 671e9be9d5eSMiklos Szeredi static int ovl_fill_super(struct super_block *sb, void *data, int silent) 672e9be9d5eSMiklos Szeredi { 67353a08cb9SMiklos Szeredi struct path upperpath = { NULL, NULL }; 67453a08cb9SMiklos Szeredi struct path workpath = { NULL, NULL }; 675e9be9d5eSMiklos Szeredi struct dentry *root_dentry; 67639b681f8SMiklos Szeredi struct inode *realinode; 677e9be9d5eSMiklos Szeredi struct ovl_entry *oe; 678e9be9d5eSMiklos Szeredi struct ovl_fs *ufs; 679a78d9f0dSMiklos Szeredi struct path *stack = NULL; 680a78d9f0dSMiklos Szeredi char *lowertmp; 681a78d9f0dSMiklos Szeredi char *lower; 682a78d9f0dSMiklos Szeredi unsigned int numlower; 683a78d9f0dSMiklos Szeredi unsigned int stacklen = 0; 684dd662667SMiklos Szeredi unsigned int i; 6857c03b5d4SMiklos Szeredi bool remote = false; 686e9be9d5eSMiklos Szeredi int err; 687e9be9d5eSMiklos Szeredi 688f45827e8SErez Zadok err = -ENOMEM; 689f45827e8SErez Zadok ufs = kzalloc(sizeof(struct ovl_fs), GFP_KERNEL); 690f45827e8SErez Zadok if (!ufs) 691e9be9d5eSMiklos Szeredi goto out; 692e9be9d5eSMiklos Szeredi 693f45827e8SErez Zadok err = ovl_parse_opt((char *) data, &ufs->config); 694f45827e8SErez Zadok if (err) 695f45827e8SErez Zadok goto out_free_config; 696f45827e8SErez Zadok 697e9be9d5eSMiklos Szeredi err = -EINVAL; 69853a08cb9SMiklos Szeredi if (!ufs->config.lowerdir) { 69907f2af7bSKonstantin Khlebnikov if (!silent) 70053a08cb9SMiklos Szeredi pr_err("overlayfs: missing 'lowerdir'\n"); 70153a08cb9SMiklos Szeredi goto out_free_config; 70253a08cb9SMiklos Szeredi } 70353a08cb9SMiklos Szeredi 70453a08cb9SMiklos Szeredi sb->s_stack_depth = 0; 705cf9a6784SMiklos Szeredi sb->s_maxbytes = MAX_LFS_FILESIZE; 70653a08cb9SMiklos Szeredi if (ufs->config.upperdir) { 70753a08cb9SMiklos Szeredi if (!ufs->config.workdir) { 70853a08cb9SMiklos Szeredi pr_err("overlayfs: missing 'workdir'\n"); 709e9be9d5eSMiklos Szeredi goto out_free_config; 710e9be9d5eSMiklos Szeredi } 711e9be9d5eSMiklos Szeredi 712f45827e8SErez Zadok err = ovl_mount_dir(ufs->config.upperdir, &upperpath); 713e9be9d5eSMiklos Szeredi if (err) 7143b7a9a24SMiklos Szeredi goto out_free_config; 715e9be9d5eSMiklos Szeredi 71671cbad7eShujianyang /* Upper fs should not be r/o */ 71771cbad7eShujianyang if (upperpath.mnt->mnt_sb->s_flags & MS_RDONLY) { 71871cbad7eShujianyang pr_err("overlayfs: upper fs is r/o, try multi-lower layers mount\n"); 71971cbad7eShujianyang err = -EINVAL; 72071cbad7eShujianyang goto out_put_upperpath; 72171cbad7eShujianyang } 72271cbad7eShujianyang 7236b2d5fe4SMiklos Szeredi err = ovl_check_namelen(&upperpath, ufs, ufs->config.upperdir); 7246b2d5fe4SMiklos Szeredi if (err) 7256b2d5fe4SMiklos Szeredi goto out_put_upperpath; 7266b2d5fe4SMiklos Szeredi 727f45827e8SErez Zadok err = ovl_mount_dir(ufs->config.workdir, &workpath); 728e9be9d5eSMiklos Szeredi if (err) 7293b7a9a24SMiklos Szeredi goto out_put_upperpath; 7303b7a9a24SMiklos Szeredi 7312f83fd8cShujianyang err = -EINVAL; 732ab508822SMiklos Szeredi if (upperpath.mnt != workpath.mnt) { 733ab508822SMiklos Szeredi pr_err("overlayfs: workdir and upperdir must reside under the same mount\n"); 734ab508822SMiklos Szeredi goto out_put_workpath; 735ab508822SMiklos Szeredi } 736ab508822SMiklos Szeredi if (!ovl_workdir_ok(workpath.dentry, upperpath.dentry)) { 737ab508822SMiklos Szeredi pr_err("overlayfs: workdir and upperdir must be separate subtrees\n"); 738ab508822SMiklos Szeredi goto out_put_workpath; 739ab508822SMiklos Szeredi } 740ab508822SMiklos Szeredi sb->s_stack_depth = upperpath.mnt->mnt_sb->s_stack_depth; 74153a08cb9SMiklos Szeredi } 742a78d9f0dSMiklos Szeredi err = -ENOMEM; 743a78d9f0dSMiklos Szeredi lowertmp = kstrdup(ufs->config.lowerdir, GFP_KERNEL); 744a78d9f0dSMiklos Szeredi if (!lowertmp) 745a78d9f0dSMiklos Szeredi goto out_put_workpath; 746ab508822SMiklos Szeredi 747a78d9f0dSMiklos Szeredi err = -EINVAL; 748a78d9f0dSMiklos Szeredi stacklen = ovl_split_lowerdirs(lowertmp); 7496be4506eShujianyang if (stacklen > OVL_MAX_STACK) { 750fd36570aSColin Ian King pr_err("overlayfs: too many lower directories, limit is %d\n", 7516be4506eShujianyang OVL_MAX_STACK); 752a78d9f0dSMiklos Szeredi goto out_free_lowertmp; 7536be4506eShujianyang } else if (!ufs->config.upperdir && stacklen == 1) { 7546be4506eShujianyang pr_err("overlayfs: at least 2 lowerdir are needed while upperdir nonexistent\n"); 7556be4506eShujianyang goto out_free_lowertmp; 7566be4506eShujianyang } 757a78d9f0dSMiklos Szeredi 758a78d9f0dSMiklos Szeredi stack = kcalloc(stacklen, sizeof(struct path), GFP_KERNEL); 759a78d9f0dSMiklos Szeredi if (!stack) 760a78d9f0dSMiklos Szeredi goto out_free_lowertmp; 761a78d9f0dSMiklos Szeredi 762a78d9f0dSMiklos Szeredi lower = lowertmp; 763a78d9f0dSMiklos Szeredi for (numlower = 0; numlower < stacklen; numlower++) { 7646b2d5fe4SMiklos Szeredi err = ovl_lower_dir(lower, &stack[numlower], ufs, 7656b2d5fe4SMiklos Szeredi &sb->s_stack_depth, &remote); 7663b7a9a24SMiklos Szeredi if (err) 767a78d9f0dSMiklos Szeredi goto out_put_lowerpath; 768a78d9f0dSMiklos Szeredi 769a78d9f0dSMiklos Szeredi lower = strchr(lower, '\0') + 1; 770a78d9f0dSMiklos Szeredi } 771e9be9d5eSMiklos Szeredi 772e9be9d5eSMiklos Szeredi err = -EINVAL; 773ab508822SMiklos Szeredi sb->s_stack_depth++; 77469c433edSMiklos Szeredi if (sb->s_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) { 77569c433edSMiklos Szeredi pr_err("overlayfs: maximum fs stacking depth exceeded\n"); 7763b7a9a24SMiklos Szeredi goto out_put_lowerpath; 77769c433edSMiklos Szeredi } 77869c433edSMiklos Szeredi 77953a08cb9SMiklos Szeredi if (ufs->config.upperdir) { 780e9be9d5eSMiklos Szeredi ufs->upper_mnt = clone_private_mount(&upperpath); 781e9be9d5eSMiklos Szeredi err = PTR_ERR(ufs->upper_mnt); 782e9be9d5eSMiklos Szeredi if (IS_ERR(ufs->upper_mnt)) { 783e9be9d5eSMiklos Szeredi pr_err("overlayfs: failed to clone upperpath\n"); 7843b7a9a24SMiklos Szeredi goto out_put_lowerpath; 7853b7a9a24SMiklos Szeredi } 786d719e8f2SMiklos Szeredi /* Don't inherit atime flags */ 787d719e8f2SMiklos Szeredi ufs->upper_mnt->mnt_flags &= ~(MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME); 788d719e8f2SMiklos Szeredi 789d719e8f2SMiklos Szeredi sb->s_time_gran = ufs->upper_mnt->mnt_sb->s_time_gran; 7903b7a9a24SMiklos Szeredi 7913b7a9a24SMiklos Szeredi ufs->workdir = ovl_workdir_create(ufs->upper_mnt, workpath.dentry); 7923b7a9a24SMiklos Szeredi err = PTR_ERR(ufs->workdir); 7933b7a9a24SMiklos Szeredi if (IS_ERR(ufs->workdir)) { 794cc6f67bcSMiklos Szeredi pr_warn("overlayfs: failed to create directory %s/%s (errno: %i); mounting read-only\n", 795cc6f67bcSMiklos Szeredi ufs->config.workdir, OVL_WORKDIR_NAME, -err); 796cc6f67bcSMiklos Szeredi sb->s_flags |= MS_RDONLY; 797cc6f67bcSMiklos Szeredi ufs->workdir = NULL; 798e9be9d5eSMiklos Szeredi } 79945aebeafSVivek Goyal 80045aebeafSVivek Goyal /* 80145aebeafSVivek Goyal * Upper should support d_type, else whiteouts are visible. 80245aebeafSVivek Goyal * Given workdir and upper are on same fs, we can do 80321765194SVivek Goyal * iterate_dir() on workdir. This check requires successful 80421765194SVivek Goyal * creation of workdir in previous step. 80545aebeafSVivek Goyal */ 80621765194SVivek Goyal if (ufs->workdir) { 80745aebeafSVivek Goyal err = ovl_check_d_type_supported(&workpath); 80845aebeafSVivek Goyal if (err < 0) 80945aebeafSVivek Goyal goto out_put_workdir; 81045aebeafSVivek Goyal 811e7c0b599SVivek Goyal /* 812e7c0b599SVivek Goyal * We allowed this configuration and don't want to 813e7c0b599SVivek Goyal * break users over kernel upgrade. So warn instead 814e7c0b599SVivek Goyal * of erroring out. 815e7c0b599SVivek Goyal */ 816e7c0b599SVivek Goyal if (!err) 817e7c0b599SVivek Goyal pr_warn("overlayfs: upper fs needs to support d_type.\n"); 81853a08cb9SMiklos Szeredi } 81921765194SVivek Goyal } 820e9be9d5eSMiklos Szeredi 8212f83fd8cShujianyang err = -ENOMEM; 822a78d9f0dSMiklos Szeredi ufs->lower_mnt = kcalloc(numlower, sizeof(struct vfsmount *), GFP_KERNEL); 823dd662667SMiklos Szeredi if (ufs->lower_mnt == NULL) 8243b7a9a24SMiklos Szeredi goto out_put_workdir; 825a78d9f0dSMiklos Szeredi for (i = 0; i < numlower; i++) { 826a78d9f0dSMiklos Szeredi struct vfsmount *mnt = clone_private_mount(&stack[i]); 827dd662667SMiklos Szeredi 8282f83fd8cShujianyang err = PTR_ERR(mnt); 829dd662667SMiklos Szeredi if (IS_ERR(mnt)) { 830dd662667SMiklos Szeredi pr_err("overlayfs: failed to clone lowerpath\n"); 831dd662667SMiklos Szeredi goto out_put_lower_mnt; 832e9be9d5eSMiklos Szeredi } 833dd662667SMiklos Szeredi /* 834dd662667SMiklos Szeredi * Make lower_mnt R/O. That way fchmod/fchown on lower file 835dd662667SMiklos Szeredi * will fail instead of modifying lower fs. 836dd662667SMiklos Szeredi */ 837d719e8f2SMiklos Szeredi mnt->mnt_flags |= MNT_READONLY | MNT_NOATIME; 838dd662667SMiklos Szeredi 839a78d9f0dSMiklos Szeredi ufs->lower_mnt[ufs->numlower] = mnt; 840a78d9f0dSMiklos Szeredi ufs->numlower++; 841a78d9f0dSMiklos Szeredi } 842e9be9d5eSMiklos Szeredi 84371cbad7eShujianyang /* If the upper fs is nonexistent, we mark overlayfs r/o too */ 84471cbad7eShujianyang if (!ufs->upper_mnt) 845e9be9d5eSMiklos Szeredi sb->s_flags |= MS_RDONLY; 846e9be9d5eSMiklos Szeredi 8477c03b5d4SMiklos Szeredi if (remote) 8487c03b5d4SMiklos Szeredi sb->s_d_op = &ovl_reval_dentry_operations; 8497c03b5d4SMiklos Szeredi else 850e9be9d5eSMiklos Szeredi sb->s_d_op = &ovl_dentry_operations; 851e9be9d5eSMiklos Szeredi 8523fe6e52fSAntonio Murdaca ufs->creator_cred = prepare_creds(); 8533fe6e52fSAntonio Murdaca if (!ufs->creator_cred) 8543fe6e52fSAntonio Murdaca goto out_put_lower_mnt; 8553fe6e52fSAntonio Murdaca 856e9be9d5eSMiklos Szeredi err = -ENOMEM; 857a78d9f0dSMiklos Szeredi oe = ovl_alloc_entry(numlower); 8583b7a9a24SMiklos Szeredi if (!oe) 8593fe6e52fSAntonio Murdaca goto out_put_cred; 860e9be9d5eSMiklos Szeredi 861655042ccSVivek Goyal sb->s_magic = OVERLAYFS_SUPER_MAGIC; 862655042ccSVivek Goyal sb->s_op = &ovl_super_operations; 863655042ccSVivek Goyal sb->s_xattr = ovl_xattr_handlers; 864655042ccSVivek Goyal sb->s_fs_info = ufs; 865655042ccSVivek Goyal sb->s_flags |= MS_POSIXACL | MS_NOREMOTELOCK; 866655042ccSVivek Goyal 867ca4c8a3aSMiklos Szeredi root_dentry = d_make_root(ovl_new_inode(sb, S_IFDIR, 0)); 868e9be9d5eSMiklos Szeredi if (!root_dentry) 8693b7a9a24SMiklos Szeredi goto out_free_oe; 870e9be9d5eSMiklos Szeredi 871e9be9d5eSMiklos Szeredi mntput(upperpath.mnt); 872a78d9f0dSMiklos Szeredi for (i = 0; i < numlower; i++) 873a78d9f0dSMiklos Szeredi mntput(stack[i].mnt); 874e9be9d5eSMiklos Szeredi path_put(&workpath); 875a78d9f0dSMiklos Szeredi kfree(lowertmp); 876e9be9d5eSMiklos Szeredi 877e9be9d5eSMiklos Szeredi oe->__upperdentry = upperpath.dentry; 878a78d9f0dSMiklos Szeredi for (i = 0; i < numlower; i++) { 879a78d9f0dSMiklos Szeredi oe->lowerstack[i].dentry = stack[i].dentry; 880a78d9f0dSMiklos Szeredi oe->lowerstack[i].mnt = ufs->lower_mnt[i]; 881a78d9f0dSMiklos Szeredi } 8820f95502aSKonstantin Khlebnikov kfree(stack); 883e9be9d5eSMiklos Szeredi 884e9be9d5eSMiklos Szeredi root_dentry->d_fsdata = oe; 885e9be9d5eSMiklos Szeredi 88639b681f8SMiklos Szeredi realinode = d_inode(ovl_dentry_real(root_dentry)); 88739b681f8SMiklos Szeredi ovl_inode_init(d_inode(root_dentry), realinode, !!upperpath.dentry); 88839b681f8SMiklos Szeredi ovl_copyattr(realinode, d_inode(root_dentry)); 889ed06e069SMiklos Szeredi 890e9be9d5eSMiklos Szeredi sb->s_root = root_dentry; 891e9be9d5eSMiklos Szeredi 892e9be9d5eSMiklos Szeredi return 0; 893e9be9d5eSMiklos Szeredi 8943b7a9a24SMiklos Szeredi out_free_oe: 8953b7a9a24SMiklos Szeredi kfree(oe); 8963fe6e52fSAntonio Murdaca out_put_cred: 8973fe6e52fSAntonio Murdaca put_cred(ufs->creator_cred); 898e9be9d5eSMiklos Szeredi out_put_lower_mnt: 899dd662667SMiklos Szeredi for (i = 0; i < ufs->numlower; i++) 900dd662667SMiklos Szeredi mntput(ufs->lower_mnt[i]); 901dd662667SMiklos Szeredi kfree(ufs->lower_mnt); 9023b7a9a24SMiklos Szeredi out_put_workdir: 9033b7a9a24SMiklos Szeredi dput(ufs->workdir); 904e9be9d5eSMiklos Szeredi mntput(ufs->upper_mnt); 905e9be9d5eSMiklos Szeredi out_put_lowerpath: 906a78d9f0dSMiklos Szeredi for (i = 0; i < numlower; i++) 907a78d9f0dSMiklos Szeredi path_put(&stack[i]); 908a78d9f0dSMiklos Szeredi kfree(stack); 909a78d9f0dSMiklos Szeredi out_free_lowertmp: 910a78d9f0dSMiklos Szeredi kfree(lowertmp); 9113b7a9a24SMiklos Szeredi out_put_workpath: 9123b7a9a24SMiklos Szeredi path_put(&workpath); 913e9be9d5eSMiklos Szeredi out_put_upperpath: 914e9be9d5eSMiklos Szeredi path_put(&upperpath); 915e9be9d5eSMiklos Szeredi out_free_config: 916f45827e8SErez Zadok kfree(ufs->config.lowerdir); 917f45827e8SErez Zadok kfree(ufs->config.upperdir); 918f45827e8SErez Zadok kfree(ufs->config.workdir); 919f45827e8SErez Zadok kfree(ufs); 920e9be9d5eSMiklos Szeredi out: 921e9be9d5eSMiklos Szeredi return err; 922e9be9d5eSMiklos Szeredi } 923e9be9d5eSMiklos Szeredi 924e9be9d5eSMiklos Szeredi static struct dentry *ovl_mount(struct file_system_type *fs_type, int flags, 925e9be9d5eSMiklos Szeredi const char *dev_name, void *raw_data) 926e9be9d5eSMiklos Szeredi { 927e9be9d5eSMiklos Szeredi return mount_nodev(fs_type, flags, raw_data, ovl_fill_super); 928e9be9d5eSMiklos Szeredi } 929e9be9d5eSMiklos Szeredi 930e9be9d5eSMiklos Szeredi static struct file_system_type ovl_fs_type = { 931e9be9d5eSMiklos Szeredi .owner = THIS_MODULE, 932ef94b186SMiklos Szeredi .name = "overlay", 933e9be9d5eSMiklos Szeredi .mount = ovl_mount, 934e9be9d5eSMiklos Szeredi .kill_sb = kill_anon_super, 935e9be9d5eSMiklos Szeredi }; 936ef94b186SMiklos Szeredi MODULE_ALIAS_FS("overlay"); 937e9be9d5eSMiklos Szeredi 938e9be9d5eSMiklos Szeredi static int __init ovl_init(void) 939e9be9d5eSMiklos Szeredi { 940e9be9d5eSMiklos Szeredi return register_filesystem(&ovl_fs_type); 941e9be9d5eSMiklos Szeredi } 942e9be9d5eSMiklos Szeredi 943e9be9d5eSMiklos Szeredi static void __exit ovl_exit(void) 944e9be9d5eSMiklos Szeredi { 945e9be9d5eSMiklos Szeredi unregister_filesystem(&ovl_fs_type); 946e9be9d5eSMiklos Szeredi } 947e9be9d5eSMiklos Szeredi 948e9be9d5eSMiklos Szeredi module_init(ovl_init); 949e9be9d5eSMiklos Szeredi module_exit(ovl_exit); 950