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> 12cf9a6784SMiklos Szeredi #include <linux/pagemap.h> 13e9be9d5eSMiklos Szeredi #include <linux/xattr.h> 14e9be9d5eSMiklos Szeredi #include <linux/security.h> 15e9be9d5eSMiklos Szeredi #include <linux/mount.h> 16e9be9d5eSMiklos Szeredi #include <linux/slab.h> 17e9be9d5eSMiklos Szeredi #include <linux/parser.h> 18e9be9d5eSMiklos Szeredi #include <linux/module.h> 19e458bcd1SAndrew Morton #include <linux/pagemap.h> 20e9be9d5eSMiklos Szeredi #include <linux/sched.h> 21cc259639SAndy Whitcroft #include <linux/statfs.h> 22f45827e8SErez Zadok #include <linux/seq_file.h> 23e9be9d5eSMiklos Szeredi #include "overlayfs.h" 24e9be9d5eSMiklos Szeredi 25e9be9d5eSMiklos Szeredi MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>"); 26e9be9d5eSMiklos Szeredi MODULE_DESCRIPTION("Overlay filesystem"); 27e9be9d5eSMiklos Szeredi MODULE_LICENSE("GPL"); 28e9be9d5eSMiklos Szeredi 29f45827e8SErez Zadok struct ovl_config { 30f45827e8SErez Zadok char *lowerdir; 31f45827e8SErez Zadok char *upperdir; 32f45827e8SErez Zadok char *workdir; 338d3095f4SMiklos Szeredi bool default_permissions; 34f45827e8SErez Zadok }; 35f45827e8SErez Zadok 36e9be9d5eSMiklos Szeredi /* private information held for overlayfs's superblock */ 37e9be9d5eSMiklos Szeredi struct ovl_fs { 38e9be9d5eSMiklos Szeredi struct vfsmount *upper_mnt; 39dd662667SMiklos Szeredi unsigned numlower; 40dd662667SMiklos Szeredi struct vfsmount **lower_mnt; 41e9be9d5eSMiklos Szeredi struct dentry *workdir; 42cc259639SAndy Whitcroft long lower_namelen; 43f45827e8SErez Zadok /* pathnames of lower and upper dirs, for show_options */ 44f45827e8SErez Zadok struct ovl_config config; 45e9be9d5eSMiklos Szeredi }; 46e9be9d5eSMiklos Szeredi 47e9be9d5eSMiklos Szeredi struct ovl_dir_cache; 48e9be9d5eSMiklos Szeredi 49e9be9d5eSMiklos Szeredi /* private information held for every overlayfs dentry */ 50e9be9d5eSMiklos Szeredi struct ovl_entry { 51e9be9d5eSMiklos Szeredi struct dentry *__upperdentry; 52e9be9d5eSMiklos Szeredi struct ovl_dir_cache *cache; 53e9be9d5eSMiklos Szeredi union { 54e9be9d5eSMiklos Szeredi struct { 55e9be9d5eSMiklos Szeredi u64 version; 56e9be9d5eSMiklos Szeredi bool opaque; 57e9be9d5eSMiklos Szeredi }; 58e9be9d5eSMiklos Szeredi struct rcu_head rcu; 59e9be9d5eSMiklos Szeredi }; 60dd662667SMiklos Szeredi unsigned numlower; 61dd662667SMiklos Szeredi struct path lowerstack[]; 62e9be9d5eSMiklos Szeredi }; 63e9be9d5eSMiklos Szeredi 64a78d9f0dSMiklos Szeredi #define OVL_MAX_STACK 500 65a78d9f0dSMiklos Szeredi 66dd662667SMiklos Szeredi static struct dentry *__ovl_dentry_lower(struct ovl_entry *oe) 67dd662667SMiklos Szeredi { 68dd662667SMiklos Szeredi return oe->numlower ? oe->lowerstack[0].dentry : NULL; 69dd662667SMiklos Szeredi } 70e9be9d5eSMiklos Szeredi 71e9be9d5eSMiklos Szeredi enum ovl_path_type ovl_path_type(struct dentry *dentry) 72e9be9d5eSMiklos Szeredi { 73e9be9d5eSMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 741afaba1eSMiklos Szeredi enum ovl_path_type type = 0; 75e9be9d5eSMiklos Szeredi 76e9be9d5eSMiklos Szeredi if (oe->__upperdentry) { 771afaba1eSMiklos Szeredi type = __OVL_PATH_UPPER; 781afaba1eSMiklos Szeredi 7945d11738SKonstantin Khlebnikov /* 8045d11738SKonstantin Khlebnikov * Non-dir dentry can hold lower dentry from previous 8145d11738SKonstantin Khlebnikov * location. Its purity depends only on opaque flag. 8245d11738SKonstantin Khlebnikov */ 8345d11738SKonstantin Khlebnikov if (oe->numlower && S_ISDIR(dentry->d_inode->i_mode)) 841afaba1eSMiklos Szeredi type |= __OVL_PATH_MERGE; 8545d11738SKonstantin Khlebnikov else if (!oe->opaque) 861afaba1eSMiklos Szeredi type |= __OVL_PATH_PURE; 879d7459d8SMiklos Szeredi } else { 889d7459d8SMiklos Szeredi if (oe->numlower > 1) 899d7459d8SMiklos Szeredi type |= __OVL_PATH_MERGE; 90e9be9d5eSMiklos Szeredi } 911afaba1eSMiklos Szeredi return type; 92e9be9d5eSMiklos Szeredi } 93e9be9d5eSMiklos Szeredi 94e9be9d5eSMiklos Szeredi static struct dentry *ovl_upperdentry_dereference(struct ovl_entry *oe) 95e9be9d5eSMiklos Szeredi { 9671d50928SMiklos Szeredi return lockless_dereference(oe->__upperdentry); 97e9be9d5eSMiklos Szeredi } 98e9be9d5eSMiklos Szeredi 99e9be9d5eSMiklos Szeredi void ovl_path_upper(struct dentry *dentry, struct path *path) 100e9be9d5eSMiklos Szeredi { 101e9be9d5eSMiklos Szeredi struct ovl_fs *ofs = dentry->d_sb->s_fs_info; 102e9be9d5eSMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 103e9be9d5eSMiklos Szeredi 104e9be9d5eSMiklos Szeredi path->mnt = ofs->upper_mnt; 105e9be9d5eSMiklos Szeredi path->dentry = ovl_upperdentry_dereference(oe); 106e9be9d5eSMiklos Szeredi } 107e9be9d5eSMiklos Szeredi 108e9be9d5eSMiklos Szeredi enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path) 109e9be9d5eSMiklos Szeredi { 110e9be9d5eSMiklos Szeredi enum ovl_path_type type = ovl_path_type(dentry); 111e9be9d5eSMiklos Szeredi 1121afaba1eSMiklos Szeredi if (!OVL_TYPE_UPPER(type)) 113e9be9d5eSMiklos Szeredi ovl_path_lower(dentry, path); 114e9be9d5eSMiklos Szeredi else 115e9be9d5eSMiklos Szeredi ovl_path_upper(dentry, path); 116e9be9d5eSMiklos Szeredi 117e9be9d5eSMiklos Szeredi return type; 118e9be9d5eSMiklos Szeredi } 119e9be9d5eSMiklos Szeredi 120e9be9d5eSMiklos Szeredi struct dentry *ovl_dentry_upper(struct dentry *dentry) 121e9be9d5eSMiklos Szeredi { 122e9be9d5eSMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 123e9be9d5eSMiklos Szeredi 124e9be9d5eSMiklos Szeredi return ovl_upperdentry_dereference(oe); 125e9be9d5eSMiklos Szeredi } 126e9be9d5eSMiklos Szeredi 127e9be9d5eSMiklos Szeredi struct dentry *ovl_dentry_lower(struct dentry *dentry) 128e9be9d5eSMiklos Szeredi { 129e9be9d5eSMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 130e9be9d5eSMiklos Szeredi 131dd662667SMiklos Szeredi return __ovl_dentry_lower(oe); 132e9be9d5eSMiklos Szeredi } 133e9be9d5eSMiklos Szeredi 134e9be9d5eSMiklos Szeredi struct dentry *ovl_dentry_real(struct dentry *dentry) 135e9be9d5eSMiklos Szeredi { 136e9be9d5eSMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 137e9be9d5eSMiklos Szeredi struct dentry *realdentry; 138e9be9d5eSMiklos Szeredi 139e9be9d5eSMiklos Szeredi realdentry = ovl_upperdentry_dereference(oe); 140e9be9d5eSMiklos Szeredi if (!realdentry) 141dd662667SMiklos Szeredi realdentry = __ovl_dentry_lower(oe); 142e9be9d5eSMiklos Szeredi 143e9be9d5eSMiklos Szeredi return realdentry; 144e9be9d5eSMiklos Szeredi } 145e9be9d5eSMiklos Szeredi 146e9be9d5eSMiklos Szeredi struct dentry *ovl_entry_real(struct ovl_entry *oe, bool *is_upper) 147e9be9d5eSMiklos Szeredi { 148e9be9d5eSMiklos Szeredi struct dentry *realdentry; 149e9be9d5eSMiklos Szeredi 150e9be9d5eSMiklos Szeredi realdentry = ovl_upperdentry_dereference(oe); 151e9be9d5eSMiklos Szeredi if (realdentry) { 152e9be9d5eSMiklos Szeredi *is_upper = true; 153e9be9d5eSMiklos Szeredi } else { 154dd662667SMiklos Szeredi realdentry = __ovl_dentry_lower(oe); 155e9be9d5eSMiklos Szeredi *is_upper = false; 156e9be9d5eSMiklos Szeredi } 157e9be9d5eSMiklos Szeredi return realdentry; 158e9be9d5eSMiklos Szeredi } 159e9be9d5eSMiklos Szeredi 1608d3095f4SMiklos Szeredi struct vfsmount *ovl_entry_mnt_real(struct ovl_entry *oe, struct inode *inode, 1618d3095f4SMiklos Szeredi bool is_upper) 1628d3095f4SMiklos Szeredi { 1638d3095f4SMiklos Szeredi if (is_upper) { 1648d3095f4SMiklos Szeredi struct ovl_fs *ofs = inode->i_sb->s_fs_info; 1658d3095f4SMiklos Szeredi 1668d3095f4SMiklos Szeredi return ofs->upper_mnt; 1678d3095f4SMiklos Szeredi } else { 1688d3095f4SMiklos Szeredi return oe->numlower ? oe->lowerstack[0].mnt : NULL; 1698d3095f4SMiklos Szeredi } 1708d3095f4SMiklos Szeredi } 1718d3095f4SMiklos Szeredi 172e9be9d5eSMiklos Szeredi struct ovl_dir_cache *ovl_dir_cache(struct dentry *dentry) 173e9be9d5eSMiklos Szeredi { 174e9be9d5eSMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 175e9be9d5eSMiklos Szeredi 176e9be9d5eSMiklos Szeredi return oe->cache; 177e9be9d5eSMiklos Szeredi } 178e9be9d5eSMiklos Szeredi 1798d3095f4SMiklos Szeredi bool ovl_is_default_permissions(struct inode *inode) 1808d3095f4SMiklos Szeredi { 1818d3095f4SMiklos Szeredi struct ovl_fs *ofs = inode->i_sb->s_fs_info; 1828d3095f4SMiklos Szeredi 1838d3095f4SMiklos Szeredi return ofs->config.default_permissions; 1848d3095f4SMiklos Szeredi } 1858d3095f4SMiklos Szeredi 186e9be9d5eSMiklos Szeredi void ovl_set_dir_cache(struct dentry *dentry, struct ovl_dir_cache *cache) 187e9be9d5eSMiklos Szeredi { 188e9be9d5eSMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 189e9be9d5eSMiklos Szeredi 190e9be9d5eSMiklos Szeredi oe->cache = cache; 191e9be9d5eSMiklos Szeredi } 192e9be9d5eSMiklos Szeredi 193e9be9d5eSMiklos Szeredi void ovl_path_lower(struct dentry *dentry, struct path *path) 194e9be9d5eSMiklos Szeredi { 195e9be9d5eSMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 196e9be9d5eSMiklos Szeredi 197dd662667SMiklos Szeredi *path = oe->numlower ? oe->lowerstack[0] : (struct path) { NULL, NULL }; 198e9be9d5eSMiklos Szeredi } 199e9be9d5eSMiklos Szeredi 200e9be9d5eSMiklos Szeredi int ovl_want_write(struct dentry *dentry) 201e9be9d5eSMiklos Szeredi { 202e9be9d5eSMiklos Szeredi struct ovl_fs *ofs = dentry->d_sb->s_fs_info; 203e9be9d5eSMiklos Szeredi return mnt_want_write(ofs->upper_mnt); 204e9be9d5eSMiklos Szeredi } 205e9be9d5eSMiklos Szeredi 206e9be9d5eSMiklos Szeredi void ovl_drop_write(struct dentry *dentry) 207e9be9d5eSMiklos Szeredi { 208e9be9d5eSMiklos Szeredi struct ovl_fs *ofs = dentry->d_sb->s_fs_info; 209e9be9d5eSMiklos Szeredi mnt_drop_write(ofs->upper_mnt); 210e9be9d5eSMiklos Szeredi } 211e9be9d5eSMiklos Szeredi 212e9be9d5eSMiklos Szeredi struct dentry *ovl_workdir(struct dentry *dentry) 213e9be9d5eSMiklos Szeredi { 214e9be9d5eSMiklos Szeredi struct ovl_fs *ofs = dentry->d_sb->s_fs_info; 215e9be9d5eSMiklos Szeredi return ofs->workdir; 216e9be9d5eSMiklos Szeredi } 217e9be9d5eSMiklos Szeredi 218e9be9d5eSMiklos Szeredi bool ovl_dentry_is_opaque(struct dentry *dentry) 219e9be9d5eSMiklos Szeredi { 220e9be9d5eSMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 221e9be9d5eSMiklos Szeredi return oe->opaque; 222e9be9d5eSMiklos Szeredi } 223e9be9d5eSMiklos Szeredi 224e9be9d5eSMiklos Szeredi void ovl_dentry_set_opaque(struct dentry *dentry, bool opaque) 225e9be9d5eSMiklos Szeredi { 226e9be9d5eSMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 227e9be9d5eSMiklos Szeredi oe->opaque = opaque; 228e9be9d5eSMiklos Szeredi } 229e9be9d5eSMiklos Szeredi 230e9be9d5eSMiklos Szeredi void ovl_dentry_update(struct dentry *dentry, struct dentry *upperdentry) 231e9be9d5eSMiklos Szeredi { 232e9be9d5eSMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 233e9be9d5eSMiklos Szeredi 2345955102cSAl Viro WARN_ON(!inode_is_locked(upperdentry->d_parent->d_inode)); 235e9be9d5eSMiklos Szeredi WARN_ON(oe->__upperdentry); 236e9be9d5eSMiklos Szeredi BUG_ON(!upperdentry->d_inode); 237e9be9d5eSMiklos Szeredi /* 238e9be9d5eSMiklos Szeredi * Make sure upperdentry is consistent before making it visible to 239e9be9d5eSMiklos Szeredi * ovl_upperdentry_dereference(). 240e9be9d5eSMiklos Szeredi */ 241e9be9d5eSMiklos Szeredi smp_wmb(); 242e9be9d5eSMiklos Szeredi oe->__upperdentry = upperdentry; 243e9be9d5eSMiklos Szeredi } 244e9be9d5eSMiklos Szeredi 245e9be9d5eSMiklos Szeredi void ovl_dentry_version_inc(struct dentry *dentry) 246e9be9d5eSMiklos Szeredi { 247e9be9d5eSMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 248e9be9d5eSMiklos Szeredi 2495955102cSAl Viro WARN_ON(!inode_is_locked(dentry->d_inode)); 250e9be9d5eSMiklos Szeredi oe->version++; 251e9be9d5eSMiklos Szeredi } 252e9be9d5eSMiklos Szeredi 253e9be9d5eSMiklos Szeredi u64 ovl_dentry_version_get(struct dentry *dentry) 254e9be9d5eSMiklos Szeredi { 255e9be9d5eSMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 256e9be9d5eSMiklos Szeredi 2575955102cSAl Viro WARN_ON(!inode_is_locked(dentry->d_inode)); 258e9be9d5eSMiklos Szeredi return oe->version; 259e9be9d5eSMiklos Szeredi } 260e9be9d5eSMiklos Szeredi 261e9be9d5eSMiklos Szeredi bool ovl_is_whiteout(struct dentry *dentry) 262e9be9d5eSMiklos Szeredi { 263e9be9d5eSMiklos Szeredi struct inode *inode = dentry->d_inode; 264e9be9d5eSMiklos Szeredi 265e9be9d5eSMiklos Szeredi return inode && IS_WHITEOUT(inode); 266e9be9d5eSMiklos Szeredi } 267e9be9d5eSMiklos Szeredi 268e9be9d5eSMiklos Szeredi static bool ovl_is_opaquedir(struct dentry *dentry) 269e9be9d5eSMiklos Szeredi { 270e9be9d5eSMiklos Szeredi int res; 271e9be9d5eSMiklos Szeredi char val; 272e9be9d5eSMiklos Szeredi struct inode *inode = dentry->d_inode; 273e9be9d5eSMiklos Szeredi 274e9be9d5eSMiklos Szeredi if (!S_ISDIR(inode->i_mode) || !inode->i_op->getxattr) 275e9be9d5eSMiklos Szeredi return false; 276e9be9d5eSMiklos Szeredi 277cead89bbShujianyang res = inode->i_op->getxattr(dentry, OVL_XATTR_OPAQUE, &val, 1); 278e9be9d5eSMiklos Szeredi if (res == 1 && val == 'y') 279e9be9d5eSMiklos Szeredi return true; 280e9be9d5eSMiklos Szeredi 281e9be9d5eSMiklos Szeredi return false; 282e9be9d5eSMiklos Szeredi } 283e9be9d5eSMiklos Szeredi 284e9be9d5eSMiklos Szeredi static void ovl_dentry_release(struct dentry *dentry) 285e9be9d5eSMiklos Szeredi { 286e9be9d5eSMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 287e9be9d5eSMiklos Szeredi 288e9be9d5eSMiklos Szeredi if (oe) { 289dd662667SMiklos Szeredi unsigned int i; 290dd662667SMiklos Szeredi 291e9be9d5eSMiklos Szeredi dput(oe->__upperdentry); 292dd662667SMiklos Szeredi for (i = 0; i < oe->numlower; i++) 293dd662667SMiklos Szeredi dput(oe->lowerstack[i].dentry); 294e9be9d5eSMiklos Szeredi kfree_rcu(oe, rcu); 295e9be9d5eSMiklos Szeredi } 296e9be9d5eSMiklos Szeredi } 297e9be9d5eSMiklos Szeredi 298d101a125SMiklos Szeredi static struct dentry *ovl_d_real(struct dentry *dentry, struct inode *inode) 299d101a125SMiklos Szeredi { 300d101a125SMiklos Szeredi struct dentry *real; 301d101a125SMiklos Szeredi 302d101a125SMiklos Szeredi if (d_is_dir(dentry)) { 303d101a125SMiklos Szeredi if (!inode || inode == d_inode(dentry)) 304d101a125SMiklos Szeredi return dentry; 305d101a125SMiklos Szeredi goto bug; 306d101a125SMiklos Szeredi } 307d101a125SMiklos Szeredi 308d101a125SMiklos Szeredi real = ovl_dentry_upper(dentry); 309d101a125SMiklos Szeredi if (real && (!inode || inode == d_inode(real))) 310d101a125SMiklos Szeredi return real; 311d101a125SMiklos Szeredi 312d101a125SMiklos Szeredi real = ovl_dentry_lower(dentry); 313d101a125SMiklos Szeredi if (!real) 314d101a125SMiklos Szeredi goto bug; 315d101a125SMiklos Szeredi 316d101a125SMiklos Szeredi if (!inode || inode == d_inode(real)) 317d101a125SMiklos Szeredi return real; 318d101a125SMiklos Szeredi 319d101a125SMiklos Szeredi /* Handle recursion */ 320d101a125SMiklos Szeredi if (real->d_flags & DCACHE_OP_REAL) 321d101a125SMiklos Szeredi return real->d_op->d_real(real, inode); 322d101a125SMiklos Szeredi 323d101a125SMiklos Szeredi bug: 324d101a125SMiklos Szeredi WARN(1, "ovl_d_real(%pd4, %s:%lu\n): real dentry not found\n", dentry, 325d101a125SMiklos Szeredi inode ? inode->i_sb->s_id : "NULL", inode ? inode->i_ino : 0); 326d101a125SMiklos Szeredi return dentry; 327d101a125SMiklos Szeredi } 328d101a125SMiklos Szeredi 3297c03b5d4SMiklos Szeredi static int ovl_dentry_revalidate(struct dentry *dentry, unsigned int flags) 3307c03b5d4SMiklos Szeredi { 3317c03b5d4SMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 3327c03b5d4SMiklos Szeredi unsigned int i; 3337c03b5d4SMiklos Szeredi int ret = 1; 3347c03b5d4SMiklos Szeredi 3357c03b5d4SMiklos Szeredi for (i = 0; i < oe->numlower; i++) { 3367c03b5d4SMiklos Szeredi struct dentry *d = oe->lowerstack[i].dentry; 3377c03b5d4SMiklos Szeredi 3387c03b5d4SMiklos Szeredi if (d->d_flags & DCACHE_OP_REVALIDATE) { 3397c03b5d4SMiklos Szeredi ret = d->d_op->d_revalidate(d, flags); 3407c03b5d4SMiklos Szeredi if (ret < 0) 3417c03b5d4SMiklos Szeredi return ret; 3427c03b5d4SMiklos Szeredi if (!ret) { 3437c03b5d4SMiklos Szeredi if (!(flags & LOOKUP_RCU)) 3447c03b5d4SMiklos Szeredi d_invalidate(d); 3457c03b5d4SMiklos Szeredi return -ESTALE; 3467c03b5d4SMiklos Szeredi } 3477c03b5d4SMiklos Szeredi } 3487c03b5d4SMiklos Szeredi } 3497c03b5d4SMiklos Szeredi return 1; 3507c03b5d4SMiklos Szeredi } 3517c03b5d4SMiklos Szeredi 3527c03b5d4SMiklos Szeredi static int ovl_dentry_weak_revalidate(struct dentry *dentry, unsigned int flags) 3537c03b5d4SMiklos Szeredi { 3547c03b5d4SMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 3557c03b5d4SMiklos Szeredi unsigned int i; 3567c03b5d4SMiklos Szeredi int ret = 1; 3577c03b5d4SMiklos Szeredi 3587c03b5d4SMiklos Szeredi for (i = 0; i < oe->numlower; i++) { 3597c03b5d4SMiklos Szeredi struct dentry *d = oe->lowerstack[i].dentry; 3607c03b5d4SMiklos Szeredi 3617c03b5d4SMiklos Szeredi if (d->d_flags & DCACHE_OP_WEAK_REVALIDATE) { 3627c03b5d4SMiklos Szeredi ret = d->d_op->d_weak_revalidate(d, flags); 3637c03b5d4SMiklos Szeredi if (ret <= 0) 3647c03b5d4SMiklos Szeredi break; 3657c03b5d4SMiklos Szeredi } 3667c03b5d4SMiklos Szeredi } 3677c03b5d4SMiklos Szeredi return ret; 3687c03b5d4SMiklos Szeredi } 3697c03b5d4SMiklos Szeredi 370e9be9d5eSMiklos Szeredi static const struct dentry_operations ovl_dentry_operations = { 371e9be9d5eSMiklos Szeredi .d_release = ovl_dentry_release, 3724bacc9c9SDavid Howells .d_select_inode = ovl_d_select_inode, 373d101a125SMiklos Szeredi .d_real = ovl_d_real, 374e9be9d5eSMiklos Szeredi }; 375e9be9d5eSMiklos Szeredi 3767c03b5d4SMiklos Szeredi static const struct dentry_operations ovl_reval_dentry_operations = { 3777c03b5d4SMiklos Szeredi .d_release = ovl_dentry_release, 378b5891cfaSKonstantin Khlebnikov .d_select_inode = ovl_d_select_inode, 379d101a125SMiklos Szeredi .d_real = ovl_d_real, 3807c03b5d4SMiklos Szeredi .d_revalidate = ovl_dentry_revalidate, 3817c03b5d4SMiklos Szeredi .d_weak_revalidate = ovl_dentry_weak_revalidate, 3827c03b5d4SMiklos Szeredi }; 3837c03b5d4SMiklos Szeredi 384dd662667SMiklos Szeredi static struct ovl_entry *ovl_alloc_entry(unsigned int numlower) 385e9be9d5eSMiklos Szeredi { 386dd662667SMiklos Szeredi size_t size = offsetof(struct ovl_entry, lowerstack[numlower]); 387dd662667SMiklos Szeredi struct ovl_entry *oe = kzalloc(size, GFP_KERNEL); 388dd662667SMiklos Szeredi 389dd662667SMiklos Szeredi if (oe) 390dd662667SMiklos Szeredi oe->numlower = numlower; 391dd662667SMiklos Szeredi 392dd662667SMiklos Szeredi return oe; 393e9be9d5eSMiklos Szeredi } 394e9be9d5eSMiklos Szeredi 3957c03b5d4SMiklos Szeredi static bool ovl_dentry_remote(struct dentry *dentry) 3967c03b5d4SMiklos Szeredi { 3977c03b5d4SMiklos Szeredi return dentry->d_flags & 3987c03b5d4SMiklos Szeredi (DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE); 3997c03b5d4SMiklos Szeredi } 4007c03b5d4SMiklos Szeredi 4017c03b5d4SMiklos Szeredi static bool ovl_dentry_weird(struct dentry *dentry) 4027c03b5d4SMiklos Szeredi { 4037c03b5d4SMiklos Szeredi return dentry->d_flags & (DCACHE_NEED_AUTOMOUNT | 4047c03b5d4SMiklos Szeredi DCACHE_MANAGE_TRANSIT | 4057c03b5d4SMiklos Szeredi DCACHE_OP_HASH | 4067c03b5d4SMiklos Szeredi DCACHE_OP_COMPARE); 4077c03b5d4SMiklos Szeredi } 4087c03b5d4SMiklos Szeredi 409e9be9d5eSMiklos Szeredi static inline struct dentry *ovl_lookup_real(struct dentry *dir, 410e9be9d5eSMiklos Szeredi struct qstr *name) 411e9be9d5eSMiklos Szeredi { 412e9be9d5eSMiklos Szeredi struct dentry *dentry; 413e9be9d5eSMiklos Szeredi 4145955102cSAl Viro inode_lock(dir->d_inode); 415e9be9d5eSMiklos Szeredi dentry = lookup_one_len(name->name, dir, name->len); 4165955102cSAl Viro inode_unlock(dir->d_inode); 417e9be9d5eSMiklos Szeredi 418e9be9d5eSMiklos Szeredi if (IS_ERR(dentry)) { 419e9be9d5eSMiklos Szeredi if (PTR_ERR(dentry) == -ENOENT) 420e9be9d5eSMiklos Szeredi dentry = NULL; 421e9be9d5eSMiklos Szeredi } else if (!dentry->d_inode) { 422e9be9d5eSMiklos Szeredi dput(dentry); 423e9be9d5eSMiklos Szeredi dentry = NULL; 4247c03b5d4SMiklos Szeredi } else if (ovl_dentry_weird(dentry)) { 425a6f15d9aSMiklos Szeredi dput(dentry); 4267c03b5d4SMiklos Szeredi /* Don't support traversing automounts and other weirdness */ 427a6f15d9aSMiklos Szeredi dentry = ERR_PTR(-EREMOTE); 428e9be9d5eSMiklos Szeredi } 429e9be9d5eSMiklos Szeredi return dentry; 430e9be9d5eSMiklos Szeredi } 431e9be9d5eSMiklos Szeredi 4325ef88da5SMiklos Szeredi /* 4335ef88da5SMiklos Szeredi * Returns next layer in stack starting from top. 4345ef88da5SMiklos Szeredi * Returns -1 if this is the last layer. 4355ef88da5SMiklos Szeredi */ 4365ef88da5SMiklos Szeredi int ovl_path_next(int idx, struct dentry *dentry, struct path *path) 4375ef88da5SMiklos Szeredi { 4385ef88da5SMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 4395ef88da5SMiklos Szeredi 4405ef88da5SMiklos Szeredi BUG_ON(idx < 0); 4415ef88da5SMiklos Szeredi if (idx == 0) { 4425ef88da5SMiklos Szeredi ovl_path_upper(dentry, path); 4435ef88da5SMiklos Szeredi if (path->dentry) 4445ef88da5SMiklos Szeredi return oe->numlower ? 1 : -1; 4455ef88da5SMiklos Szeredi idx++; 4465ef88da5SMiklos Szeredi } 4475ef88da5SMiklos Szeredi BUG_ON(idx > oe->numlower); 4485ef88da5SMiklos Szeredi *path = oe->lowerstack[idx - 1]; 4495ef88da5SMiklos Szeredi 4505ef88da5SMiklos Szeredi return (idx < oe->numlower) ? idx + 1 : -1; 4515ef88da5SMiklos Szeredi } 4525ef88da5SMiklos Szeredi 453e9be9d5eSMiklos Szeredi struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, 454e9be9d5eSMiklos Szeredi unsigned int flags) 455e9be9d5eSMiklos Szeredi { 456e9be9d5eSMiklos Szeredi struct ovl_entry *oe; 4573d3c6b89SMiklos Szeredi struct ovl_entry *poe = dentry->d_parent->d_fsdata; 4583d3c6b89SMiklos Szeredi struct path *stack = NULL; 4593d3c6b89SMiklos Szeredi struct dentry *upperdir, *upperdentry = NULL; 4603d3c6b89SMiklos Szeredi unsigned int ctr = 0; 461e9be9d5eSMiklos Szeredi struct inode *inode = NULL; 4623d3c6b89SMiklos Szeredi bool upperopaque = false; 4633d3c6b89SMiklos Szeredi struct dentry *this, *prev = NULL; 4643d3c6b89SMiklos Szeredi unsigned int i; 465e9be9d5eSMiklos Szeredi int err; 466e9be9d5eSMiklos Szeredi 4673d3c6b89SMiklos Szeredi upperdir = ovl_upperdentry_dereference(poe); 4683d3c6b89SMiklos Szeredi if (upperdir) { 4693d3c6b89SMiklos Szeredi this = ovl_lookup_real(upperdir, &dentry->d_name); 4703d3c6b89SMiklos Szeredi err = PTR_ERR(this); 4713d3c6b89SMiklos Szeredi if (IS_ERR(this)) 472e9be9d5eSMiklos Szeredi goto out; 473e9be9d5eSMiklos Szeredi 4743e01cee3SMiklos Szeredi if (this) { 4757c03b5d4SMiklos Szeredi if (unlikely(ovl_dentry_remote(this))) { 4767c03b5d4SMiklos Szeredi dput(this); 4777c03b5d4SMiklos Szeredi err = -EREMOTE; 4787c03b5d4SMiklos Szeredi goto out; 4797c03b5d4SMiklos Szeredi } 4803d3c6b89SMiklos Szeredi if (ovl_is_whiteout(this)) { 4813d3c6b89SMiklos Szeredi dput(this); 4823d3c6b89SMiklos Szeredi this = NULL; 4833d3c6b89SMiklos Szeredi upperopaque = true; 4843e01cee3SMiklos Szeredi } else if (poe->numlower && ovl_is_opaquedir(this)) { 4853d3c6b89SMiklos Szeredi upperopaque = true; 486e9be9d5eSMiklos Szeredi } 487e9be9d5eSMiklos Szeredi } 4883d3c6b89SMiklos Szeredi upperdentry = prev = this; 489e9be9d5eSMiklos Szeredi } 490e9be9d5eSMiklos Szeredi 4913d3c6b89SMiklos Szeredi if (!upperopaque && poe->numlower) { 4923d3c6b89SMiklos Szeredi err = -ENOMEM; 4933d3c6b89SMiklos Szeredi stack = kcalloc(poe->numlower, sizeof(struct path), GFP_KERNEL); 4943d3c6b89SMiklos Szeredi if (!stack) 4953d3c6b89SMiklos Szeredi goto out_put_upper; 496e9be9d5eSMiklos Szeredi } 497e9be9d5eSMiklos Szeredi 4983d3c6b89SMiklos Szeredi for (i = 0; !upperopaque && i < poe->numlower; i++) { 4993d3c6b89SMiklos Szeredi bool opaque = false; 5003d3c6b89SMiklos Szeredi struct path lowerpath = poe->lowerstack[i]; 5013d3c6b89SMiklos Szeredi 5023d3c6b89SMiklos Szeredi this = ovl_lookup_real(lowerpath.dentry, &dentry->d_name); 5033d3c6b89SMiklos Szeredi err = PTR_ERR(this); 50409e10322SMiklos Szeredi if (IS_ERR(this)) { 50509e10322SMiklos Szeredi /* 50609e10322SMiklos Szeredi * If it's positive, then treat ENAMETOOLONG as ENOENT. 50709e10322SMiklos Szeredi */ 50809e10322SMiklos Szeredi if (err == -ENAMETOOLONG && (upperdentry || ctr)) 50909e10322SMiklos Szeredi continue; 5103d3c6b89SMiklos Szeredi goto out_put; 51109e10322SMiklos Szeredi } 5123d3c6b89SMiklos Szeredi if (!this) 5133d3c6b89SMiklos Szeredi continue; 5143d3c6b89SMiklos Szeredi if (ovl_is_whiteout(this)) { 5153d3c6b89SMiklos Szeredi dput(this); 5163d3c6b89SMiklos Szeredi break; 5173e01cee3SMiklos Szeredi } 5183e01cee3SMiklos Szeredi /* 5193e01cee3SMiklos Szeredi * Only makes sense to check opaque dir if this is not the 5203e01cee3SMiklos Szeredi * lowermost layer. 5213e01cee3SMiklos Szeredi */ 5223e01cee3SMiklos Szeredi if (i < poe->numlower - 1 && ovl_is_opaquedir(this)) 5233d3c6b89SMiklos Szeredi opaque = true; 524a425c037Shujianyang 525a425c037Shujianyang if (prev && (!S_ISDIR(prev->d_inode->i_mode) || 5263d3c6b89SMiklos Szeredi !S_ISDIR(this->d_inode->i_mode))) { 527a425c037Shujianyang /* 528a425c037Shujianyang * FIXME: check for upper-opaqueness maybe better done 529a425c037Shujianyang * in remove code. 530a425c037Shujianyang */ 5313d3c6b89SMiklos Szeredi if (prev == upperdentry) 5323d3c6b89SMiklos Szeredi upperopaque = true; 5333d3c6b89SMiklos Szeredi dput(this); 5343d3c6b89SMiklos Szeredi break; 5353d3c6b89SMiklos Szeredi } 536a425c037Shujianyang /* 537a425c037Shujianyang * If this is a non-directory then stop here. 538a425c037Shujianyang */ 539a425c037Shujianyang if (!S_ISDIR(this->d_inode->i_mode)) 540a425c037Shujianyang opaque = true; 541a425c037Shujianyang 5423d3c6b89SMiklos Szeredi stack[ctr].dentry = this; 5433d3c6b89SMiklos Szeredi stack[ctr].mnt = lowerpath.mnt; 5443d3c6b89SMiklos Szeredi ctr++; 5453d3c6b89SMiklos Szeredi prev = this; 5463d3c6b89SMiklos Szeredi if (opaque) 5473d3c6b89SMiklos Szeredi break; 5483d3c6b89SMiklos Szeredi } 5493d3c6b89SMiklos Szeredi 5503d3c6b89SMiklos Szeredi oe = ovl_alloc_entry(ctr); 5513d3c6b89SMiklos Szeredi err = -ENOMEM; 5523d3c6b89SMiklos Szeredi if (!oe) 5533d3c6b89SMiklos Szeredi goto out_put; 5543d3c6b89SMiklos Szeredi 5553d3c6b89SMiklos Szeredi if (upperdentry || ctr) { 556e9be9d5eSMiklos Szeredi struct dentry *realdentry; 557e9be9d5eSMiklos Szeredi 5583d3c6b89SMiklos Szeredi realdentry = upperdentry ? upperdentry : stack[0].dentry; 5593d3c6b89SMiklos Szeredi 560e9be9d5eSMiklos Szeredi err = -ENOMEM; 561e9be9d5eSMiklos Szeredi inode = ovl_new_inode(dentry->d_sb, realdentry->d_inode->i_mode, 562e9be9d5eSMiklos Szeredi oe); 563e9be9d5eSMiklos Szeredi if (!inode) 5643d3c6b89SMiklos Szeredi goto out_free_oe; 565e9be9d5eSMiklos Szeredi ovl_copyattr(realdentry->d_inode, inode); 566e9be9d5eSMiklos Szeredi } 567e9be9d5eSMiklos Szeredi 5683d3c6b89SMiklos Szeredi oe->opaque = upperopaque; 569e9be9d5eSMiklos Szeredi oe->__upperdentry = upperdentry; 5703d3c6b89SMiklos Szeredi memcpy(oe->lowerstack, stack, sizeof(struct path) * ctr); 5713d3c6b89SMiklos Szeredi kfree(stack); 572e9be9d5eSMiklos Szeredi dentry->d_fsdata = oe; 573e9be9d5eSMiklos Szeredi d_add(dentry, inode); 574e9be9d5eSMiklos Szeredi 575e9be9d5eSMiklos Szeredi return NULL; 576e9be9d5eSMiklos Szeredi 5773d3c6b89SMiklos Szeredi out_free_oe: 578e9be9d5eSMiklos Szeredi kfree(oe); 5793d3c6b89SMiklos Szeredi out_put: 5803d3c6b89SMiklos Szeredi for (i = 0; i < ctr; i++) 5813d3c6b89SMiklos Szeredi dput(stack[i].dentry); 5823d3c6b89SMiklos Szeredi kfree(stack); 5833d3c6b89SMiklos Szeredi out_put_upper: 5843d3c6b89SMiklos Szeredi dput(upperdentry); 585e9be9d5eSMiklos Szeredi out: 586e9be9d5eSMiklos Szeredi return ERR_PTR(err); 587e9be9d5eSMiklos Szeredi } 588e9be9d5eSMiklos Szeredi 589e9be9d5eSMiklos Szeredi struct file *ovl_path_open(struct path *path, int flags) 590e9be9d5eSMiklos Szeredi { 591e9be9d5eSMiklos Szeredi return dentry_open(path, flags, current_cred()); 592e9be9d5eSMiklos Szeredi } 593e9be9d5eSMiklos Szeredi 594e9be9d5eSMiklos Szeredi static void ovl_put_super(struct super_block *sb) 595e9be9d5eSMiklos Szeredi { 596e9be9d5eSMiklos Szeredi struct ovl_fs *ufs = sb->s_fs_info; 597dd662667SMiklos Szeredi unsigned i; 598e9be9d5eSMiklos Szeredi 599e9be9d5eSMiklos Szeredi dput(ufs->workdir); 600e9be9d5eSMiklos Szeredi mntput(ufs->upper_mnt); 601dd662667SMiklos Szeredi for (i = 0; i < ufs->numlower; i++) 602dd662667SMiklos Szeredi mntput(ufs->lower_mnt[i]); 6035ffdbe8bSKonstantin Khlebnikov kfree(ufs->lower_mnt); 604e9be9d5eSMiklos Szeredi 605f45827e8SErez Zadok kfree(ufs->config.lowerdir); 606f45827e8SErez Zadok kfree(ufs->config.upperdir); 607f45827e8SErez Zadok kfree(ufs->config.workdir); 608e9be9d5eSMiklos Szeredi kfree(ufs); 609e9be9d5eSMiklos Szeredi } 610e9be9d5eSMiklos Szeredi 611cc259639SAndy Whitcroft /** 612cc259639SAndy Whitcroft * ovl_statfs 613cc259639SAndy Whitcroft * @sb: The overlayfs super block 614cc259639SAndy Whitcroft * @buf: The struct kstatfs to fill in with stats 615cc259639SAndy Whitcroft * 616cc259639SAndy Whitcroft * Get the filesystem statistics. As writes always target the upper layer 6174ebc5818SMiklos Szeredi * filesystem pass the statfs to the upper filesystem (if it exists) 618cc259639SAndy Whitcroft */ 619cc259639SAndy Whitcroft static int ovl_statfs(struct dentry *dentry, struct kstatfs *buf) 620cc259639SAndy Whitcroft { 621cc259639SAndy Whitcroft struct ovl_fs *ofs = dentry->d_sb->s_fs_info; 622cc259639SAndy Whitcroft struct dentry *root_dentry = dentry->d_sb->s_root; 623cc259639SAndy Whitcroft struct path path; 624cc259639SAndy Whitcroft int err; 625cc259639SAndy Whitcroft 6264ebc5818SMiklos Szeredi ovl_path_real(root_dentry, &path); 627cc259639SAndy Whitcroft 628cc259639SAndy Whitcroft err = vfs_statfs(&path, buf); 629cc259639SAndy Whitcroft if (!err) { 630cc259639SAndy Whitcroft buf->f_namelen = max(buf->f_namelen, ofs->lower_namelen); 631cc259639SAndy Whitcroft buf->f_type = OVERLAYFS_SUPER_MAGIC; 632cc259639SAndy Whitcroft } 633cc259639SAndy Whitcroft 634cc259639SAndy Whitcroft return err; 635cc259639SAndy Whitcroft } 636cc259639SAndy Whitcroft 637f45827e8SErez Zadok /** 638f45827e8SErez Zadok * ovl_show_options 639f45827e8SErez Zadok * 640f45827e8SErez Zadok * Prints the mount options for a given superblock. 641f45827e8SErez Zadok * Returns zero; does not fail. 642f45827e8SErez Zadok */ 643f45827e8SErez Zadok static int ovl_show_options(struct seq_file *m, struct dentry *dentry) 644f45827e8SErez Zadok { 645f45827e8SErez Zadok struct super_block *sb = dentry->d_sb; 646f45827e8SErez Zadok struct ovl_fs *ufs = sb->s_fs_info; 647f45827e8SErez Zadok 648a068acf2SKees Cook seq_show_option(m, "lowerdir", ufs->config.lowerdir); 64953a08cb9SMiklos Szeredi if (ufs->config.upperdir) { 650a068acf2SKees Cook seq_show_option(m, "upperdir", ufs->config.upperdir); 651a068acf2SKees Cook seq_show_option(m, "workdir", ufs->config.workdir); 65253a08cb9SMiklos Szeredi } 6538d3095f4SMiklos Szeredi if (ufs->config.default_permissions) 6548d3095f4SMiklos Szeredi seq_puts(m, ",default_permissions"); 655f45827e8SErez Zadok return 0; 656f45827e8SErez Zadok } 657f45827e8SErez Zadok 6583cdf6fe9SSeunghun Lee static int ovl_remount(struct super_block *sb, int *flags, char *data) 6593cdf6fe9SSeunghun Lee { 6603cdf6fe9SSeunghun Lee struct ovl_fs *ufs = sb->s_fs_info; 6613cdf6fe9SSeunghun Lee 662cc6f67bcSMiklos Szeredi if (!(*flags & MS_RDONLY) && (!ufs->upper_mnt || !ufs->workdir)) 6633cdf6fe9SSeunghun Lee return -EROFS; 6643cdf6fe9SSeunghun Lee 6653cdf6fe9SSeunghun Lee return 0; 6663cdf6fe9SSeunghun Lee } 6673cdf6fe9SSeunghun Lee 668e9be9d5eSMiklos Szeredi static const struct super_operations ovl_super_operations = { 669e9be9d5eSMiklos Szeredi .put_super = ovl_put_super, 670cc259639SAndy Whitcroft .statfs = ovl_statfs, 671f45827e8SErez Zadok .show_options = ovl_show_options, 6723cdf6fe9SSeunghun Lee .remount_fs = ovl_remount, 673e9be9d5eSMiklos Szeredi }; 674e9be9d5eSMiklos Szeredi 675e9be9d5eSMiklos Szeredi enum { 676e9be9d5eSMiklos Szeredi OPT_LOWERDIR, 677e9be9d5eSMiklos Szeredi OPT_UPPERDIR, 678e9be9d5eSMiklos Szeredi OPT_WORKDIR, 6798d3095f4SMiklos Szeredi OPT_DEFAULT_PERMISSIONS, 680e9be9d5eSMiklos Szeredi OPT_ERR, 681e9be9d5eSMiklos Szeredi }; 682e9be9d5eSMiklos Szeredi 683e9be9d5eSMiklos Szeredi static const match_table_t ovl_tokens = { 684e9be9d5eSMiklos Szeredi {OPT_LOWERDIR, "lowerdir=%s"}, 685e9be9d5eSMiklos Szeredi {OPT_UPPERDIR, "upperdir=%s"}, 686e9be9d5eSMiklos Szeredi {OPT_WORKDIR, "workdir=%s"}, 6878d3095f4SMiklos Szeredi {OPT_DEFAULT_PERMISSIONS, "default_permissions"}, 688e9be9d5eSMiklos Szeredi {OPT_ERR, NULL} 689e9be9d5eSMiklos Szeredi }; 690e9be9d5eSMiklos Szeredi 69191c77947SMiklos Szeredi static char *ovl_next_opt(char **s) 69291c77947SMiklos Szeredi { 69391c77947SMiklos Szeredi char *sbegin = *s; 69491c77947SMiklos Szeredi char *p; 69591c77947SMiklos Szeredi 69691c77947SMiklos Szeredi if (sbegin == NULL) 69791c77947SMiklos Szeredi return NULL; 69891c77947SMiklos Szeredi 69991c77947SMiklos Szeredi for (p = sbegin; *p; p++) { 70091c77947SMiklos Szeredi if (*p == '\\') { 70191c77947SMiklos Szeredi p++; 70291c77947SMiklos Szeredi if (!*p) 70391c77947SMiklos Szeredi break; 70491c77947SMiklos Szeredi } else if (*p == ',') { 70591c77947SMiklos Szeredi *p = '\0'; 70691c77947SMiklos Szeredi *s = p + 1; 70791c77947SMiklos Szeredi return sbegin; 70891c77947SMiklos Szeredi } 70991c77947SMiklos Szeredi } 71091c77947SMiklos Szeredi *s = NULL; 71191c77947SMiklos Szeredi return sbegin; 71291c77947SMiklos Szeredi } 71391c77947SMiklos Szeredi 714e9be9d5eSMiklos Szeredi static int ovl_parse_opt(char *opt, struct ovl_config *config) 715e9be9d5eSMiklos Szeredi { 716e9be9d5eSMiklos Szeredi char *p; 717e9be9d5eSMiklos Szeredi 71891c77947SMiklos Szeredi while ((p = ovl_next_opt(&opt)) != NULL) { 719e9be9d5eSMiklos Szeredi int token; 720e9be9d5eSMiklos Szeredi substring_t args[MAX_OPT_ARGS]; 721e9be9d5eSMiklos Szeredi 722e9be9d5eSMiklos Szeredi if (!*p) 723e9be9d5eSMiklos Szeredi continue; 724e9be9d5eSMiklos Szeredi 725e9be9d5eSMiklos Szeredi token = match_token(p, ovl_tokens, args); 726e9be9d5eSMiklos Szeredi switch (token) { 727e9be9d5eSMiklos Szeredi case OPT_UPPERDIR: 728e9be9d5eSMiklos Szeredi kfree(config->upperdir); 729e9be9d5eSMiklos Szeredi config->upperdir = match_strdup(&args[0]); 730e9be9d5eSMiklos Szeredi if (!config->upperdir) 731e9be9d5eSMiklos Szeredi return -ENOMEM; 732e9be9d5eSMiklos Szeredi break; 733e9be9d5eSMiklos Szeredi 734e9be9d5eSMiklos Szeredi case OPT_LOWERDIR: 735e9be9d5eSMiklos Szeredi kfree(config->lowerdir); 736e9be9d5eSMiklos Szeredi config->lowerdir = match_strdup(&args[0]); 737e9be9d5eSMiklos Szeredi if (!config->lowerdir) 738e9be9d5eSMiklos Szeredi return -ENOMEM; 739e9be9d5eSMiklos Szeredi break; 740e9be9d5eSMiklos Szeredi 741e9be9d5eSMiklos Szeredi case OPT_WORKDIR: 742e9be9d5eSMiklos Szeredi kfree(config->workdir); 743e9be9d5eSMiklos Szeredi config->workdir = match_strdup(&args[0]); 744e9be9d5eSMiklos Szeredi if (!config->workdir) 745e9be9d5eSMiklos Szeredi return -ENOMEM; 746e9be9d5eSMiklos Szeredi break; 747e9be9d5eSMiklos Szeredi 7488d3095f4SMiklos Szeredi case OPT_DEFAULT_PERMISSIONS: 7498d3095f4SMiklos Szeredi config->default_permissions = true; 7508d3095f4SMiklos Szeredi break; 7518d3095f4SMiklos Szeredi 752e9be9d5eSMiklos Szeredi default: 753bead55efShujianyang pr_err("overlayfs: unrecognized mount option \"%s\" or missing value\n", p); 754e9be9d5eSMiklos Szeredi return -EINVAL; 755e9be9d5eSMiklos Szeredi } 756e9be9d5eSMiklos Szeredi } 75771cbad7eShujianyang 75871cbad7eShujianyang /* Workdir is useless in non-upper mount */ 75971cbad7eShujianyang if (!config->upperdir && config->workdir) { 76071cbad7eShujianyang pr_info("overlayfs: option \"workdir=%s\" is useless in a non-upper mount, ignore\n", 76171cbad7eShujianyang config->workdir); 76271cbad7eShujianyang kfree(config->workdir); 76371cbad7eShujianyang config->workdir = NULL; 76471cbad7eShujianyang } 76571cbad7eShujianyang 766e9be9d5eSMiklos Szeredi return 0; 767e9be9d5eSMiklos Szeredi } 768e9be9d5eSMiklos Szeredi 769e9be9d5eSMiklos Szeredi #define OVL_WORKDIR_NAME "work" 770e9be9d5eSMiklos Szeredi 771e9be9d5eSMiklos Szeredi static struct dentry *ovl_workdir_create(struct vfsmount *mnt, 772e9be9d5eSMiklos Szeredi struct dentry *dentry) 773e9be9d5eSMiklos Szeredi { 774e9be9d5eSMiklos Szeredi struct inode *dir = dentry->d_inode; 775e9be9d5eSMiklos Szeredi struct dentry *work; 776e9be9d5eSMiklos Szeredi int err; 777e9be9d5eSMiklos Szeredi bool retried = false; 778e9be9d5eSMiklos Szeredi 779e9be9d5eSMiklos Szeredi err = mnt_want_write(mnt); 780e9be9d5eSMiklos Szeredi if (err) 781e9be9d5eSMiklos Szeredi return ERR_PTR(err); 782e9be9d5eSMiklos Szeredi 7835955102cSAl Viro inode_lock_nested(dir, I_MUTEX_PARENT); 784e9be9d5eSMiklos Szeredi retry: 785e9be9d5eSMiklos Szeredi work = lookup_one_len(OVL_WORKDIR_NAME, dentry, 786e9be9d5eSMiklos Szeredi strlen(OVL_WORKDIR_NAME)); 787e9be9d5eSMiklos Szeredi 788e9be9d5eSMiklos Szeredi if (!IS_ERR(work)) { 789e9be9d5eSMiklos Szeredi struct kstat stat = { 790e9be9d5eSMiklos Szeredi .mode = S_IFDIR | 0, 791e9be9d5eSMiklos Szeredi }; 792e9be9d5eSMiklos Szeredi 793e9be9d5eSMiklos Szeredi if (work->d_inode) { 794e9be9d5eSMiklos Szeredi err = -EEXIST; 795e9be9d5eSMiklos Szeredi if (retried) 796e9be9d5eSMiklos Szeredi goto out_dput; 797e9be9d5eSMiklos Szeredi 798e9be9d5eSMiklos Szeredi retried = true; 799e9be9d5eSMiklos Szeredi ovl_cleanup(dir, work); 800e9be9d5eSMiklos Szeredi dput(work); 801e9be9d5eSMiklos Szeredi goto retry; 802e9be9d5eSMiklos Szeredi } 803e9be9d5eSMiklos Szeredi 804e9be9d5eSMiklos Szeredi err = ovl_create_real(dir, work, &stat, NULL, NULL, true); 805e9be9d5eSMiklos Szeredi if (err) 806e9be9d5eSMiklos Szeredi goto out_dput; 807e9be9d5eSMiklos Szeredi } 808e9be9d5eSMiklos Szeredi out_unlock: 8095955102cSAl Viro inode_unlock(dir); 810e9be9d5eSMiklos Szeredi mnt_drop_write(mnt); 811e9be9d5eSMiklos Szeredi 812e9be9d5eSMiklos Szeredi return work; 813e9be9d5eSMiklos Szeredi 814e9be9d5eSMiklos Szeredi out_dput: 815e9be9d5eSMiklos Szeredi dput(work); 816e9be9d5eSMiklos Szeredi work = ERR_PTR(err); 817e9be9d5eSMiklos Szeredi goto out_unlock; 818e9be9d5eSMiklos Szeredi } 819e9be9d5eSMiklos Szeredi 82091c77947SMiklos Szeredi static void ovl_unescape(char *s) 82191c77947SMiklos Szeredi { 82291c77947SMiklos Szeredi char *d = s; 82391c77947SMiklos Szeredi 82491c77947SMiklos Szeredi for (;; s++, d++) { 82591c77947SMiklos Szeredi if (*s == '\\') 82691c77947SMiklos Szeredi s++; 82791c77947SMiklos Szeredi *d = *s; 82891c77947SMiklos Szeredi if (!*s) 82991c77947SMiklos Szeredi break; 83091c77947SMiklos Szeredi } 83191c77947SMiklos Szeredi } 83291c77947SMiklos Szeredi 833ab508822SMiklos Szeredi static int ovl_mount_dir_noesc(const char *name, struct path *path) 834ab508822SMiklos Szeredi { 835a78d9f0dSMiklos Szeredi int err = -EINVAL; 836ab508822SMiklos Szeredi 837a78d9f0dSMiklos Szeredi if (!*name) { 838a78d9f0dSMiklos Szeredi pr_err("overlayfs: empty lowerdir\n"); 839a78d9f0dSMiklos Szeredi goto out; 840a78d9f0dSMiklos Szeredi } 841ab508822SMiklos Szeredi err = kern_path(name, LOOKUP_FOLLOW, path); 842ab508822SMiklos Szeredi if (err) { 843ab508822SMiklos Szeredi pr_err("overlayfs: failed to resolve '%s': %i\n", name, err); 844ab508822SMiklos Szeredi goto out; 845ab508822SMiklos Szeredi } 846ab508822SMiklos Szeredi err = -EINVAL; 8477c03b5d4SMiklos Szeredi if (ovl_dentry_weird(path->dentry)) { 848ab508822SMiklos Szeredi pr_err("overlayfs: filesystem on '%s' not supported\n", name); 849ab508822SMiklos Szeredi goto out_put; 850ab508822SMiklos Szeredi } 851ab508822SMiklos Szeredi if (!S_ISDIR(path->dentry->d_inode->i_mode)) { 852ab508822SMiklos Szeredi pr_err("overlayfs: '%s' not a directory\n", name); 853ab508822SMiklos Szeredi goto out_put; 854ab508822SMiklos Szeredi } 855ab508822SMiklos Szeredi return 0; 856ab508822SMiklos Szeredi 857ab508822SMiklos Szeredi out_put: 858ab508822SMiklos Szeredi path_put(path); 859ab508822SMiklos Szeredi out: 860ab508822SMiklos Szeredi return err; 861ab508822SMiklos Szeredi } 862ab508822SMiklos Szeredi 863ab508822SMiklos Szeredi static int ovl_mount_dir(const char *name, struct path *path) 864ab508822SMiklos Szeredi { 865ab508822SMiklos Szeredi int err = -ENOMEM; 866ab508822SMiklos Szeredi char *tmp = kstrdup(name, GFP_KERNEL); 867ab508822SMiklos Szeredi 868ab508822SMiklos Szeredi if (tmp) { 869ab508822SMiklos Szeredi ovl_unescape(tmp); 870ab508822SMiklos Szeredi err = ovl_mount_dir_noesc(tmp, path); 8717c03b5d4SMiklos Szeredi 8727c03b5d4SMiklos Szeredi if (!err) 8737c03b5d4SMiklos Szeredi if (ovl_dentry_remote(path->dentry)) { 8747c03b5d4SMiklos Szeredi pr_err("overlayfs: filesystem on '%s' not supported as upperdir\n", 8757c03b5d4SMiklos Szeredi tmp); 8767c03b5d4SMiklos Szeredi path_put(path); 8777c03b5d4SMiklos Szeredi err = -EINVAL; 8787c03b5d4SMiklos Szeredi } 879ab508822SMiklos Szeredi kfree(tmp); 880ab508822SMiklos Szeredi } 881ab508822SMiklos Szeredi return err; 882ab508822SMiklos Szeredi } 883ab508822SMiklos Szeredi 884ab508822SMiklos Szeredi static int ovl_lower_dir(const char *name, struct path *path, long *namelen, 8857c03b5d4SMiklos Szeredi int *stack_depth, bool *remote) 886ab508822SMiklos Szeredi { 887ab508822SMiklos Szeredi int err; 888ab508822SMiklos Szeredi struct kstatfs statfs; 889ab508822SMiklos Szeredi 890a78d9f0dSMiklos Szeredi err = ovl_mount_dir_noesc(name, path); 891ab508822SMiklos Szeredi if (err) 892ab508822SMiklos Szeredi goto out; 893ab508822SMiklos Szeredi 894ab508822SMiklos Szeredi err = vfs_statfs(path, &statfs); 895ab508822SMiklos Szeredi if (err) { 896ab508822SMiklos Szeredi pr_err("overlayfs: statfs failed on '%s'\n", name); 897ab508822SMiklos Szeredi goto out_put; 898ab508822SMiklos Szeredi } 899ab508822SMiklos Szeredi *namelen = max(*namelen, statfs.f_namelen); 900ab508822SMiklos Szeredi *stack_depth = max(*stack_depth, path->mnt->mnt_sb->s_stack_depth); 901ab508822SMiklos Szeredi 9027c03b5d4SMiklos Szeredi if (ovl_dentry_remote(path->dentry)) 9037c03b5d4SMiklos Szeredi *remote = true; 9047c03b5d4SMiklos Szeredi 905ab508822SMiklos Szeredi return 0; 906ab508822SMiklos Szeredi 907ab508822SMiklos Szeredi out_put: 908ab508822SMiklos Szeredi path_put(path); 909ab508822SMiklos Szeredi out: 910ab508822SMiklos Szeredi return err; 911ab508822SMiklos Szeredi } 912ab508822SMiklos Szeredi 913e9be9d5eSMiklos Szeredi /* Workdir should not be subdir of upperdir and vice versa */ 914e9be9d5eSMiklos Szeredi static bool ovl_workdir_ok(struct dentry *workdir, struct dentry *upperdir) 915e9be9d5eSMiklos Szeredi { 916e9be9d5eSMiklos Szeredi bool ok = false; 917e9be9d5eSMiklos Szeredi 918e9be9d5eSMiklos Szeredi if (workdir != upperdir) { 919e9be9d5eSMiklos Szeredi ok = (lock_rename(workdir, upperdir) == NULL); 920e9be9d5eSMiklos Szeredi unlock_rename(workdir, upperdir); 921e9be9d5eSMiklos Szeredi } 922e9be9d5eSMiklos Szeredi return ok; 923e9be9d5eSMiklos Szeredi } 924e9be9d5eSMiklos Szeredi 925a78d9f0dSMiklos Szeredi static unsigned int ovl_split_lowerdirs(char *str) 926a78d9f0dSMiklos Szeredi { 927a78d9f0dSMiklos Szeredi unsigned int ctr = 1; 928a78d9f0dSMiklos Szeredi char *s, *d; 929a78d9f0dSMiklos Szeredi 930a78d9f0dSMiklos Szeredi for (s = d = str;; s++, d++) { 931a78d9f0dSMiklos Szeredi if (*s == '\\') { 932a78d9f0dSMiklos Szeredi s++; 933a78d9f0dSMiklos Szeredi } else if (*s == ':') { 934a78d9f0dSMiklos Szeredi *d = '\0'; 935a78d9f0dSMiklos Szeredi ctr++; 936a78d9f0dSMiklos Szeredi continue; 937a78d9f0dSMiklos Szeredi } 938a78d9f0dSMiklos Szeredi *d = *s; 939a78d9f0dSMiklos Szeredi if (!*s) 940a78d9f0dSMiklos Szeredi break; 941a78d9f0dSMiklos Szeredi } 942a78d9f0dSMiklos Szeredi return ctr; 943a78d9f0dSMiklos Szeredi } 944a78d9f0dSMiklos Szeredi 945e9be9d5eSMiklos Szeredi static int ovl_fill_super(struct super_block *sb, void *data, int silent) 946e9be9d5eSMiklos Szeredi { 94753a08cb9SMiklos Szeredi struct path upperpath = { NULL, NULL }; 94853a08cb9SMiklos Szeredi struct path workpath = { NULL, NULL }; 949e9be9d5eSMiklos Szeredi struct dentry *root_dentry; 950e9be9d5eSMiklos Szeredi struct ovl_entry *oe; 951e9be9d5eSMiklos Szeredi struct ovl_fs *ufs; 952a78d9f0dSMiklos Szeredi struct path *stack = NULL; 953a78d9f0dSMiklos Szeredi char *lowertmp; 954a78d9f0dSMiklos Szeredi char *lower; 955a78d9f0dSMiklos Szeredi unsigned int numlower; 956a78d9f0dSMiklos Szeredi unsigned int stacklen = 0; 957dd662667SMiklos Szeredi unsigned int i; 9587c03b5d4SMiklos Szeredi bool remote = false; 959e9be9d5eSMiklos Szeredi int err; 960e9be9d5eSMiklos Szeredi 961f45827e8SErez Zadok err = -ENOMEM; 962f45827e8SErez Zadok ufs = kzalloc(sizeof(struct ovl_fs), GFP_KERNEL); 963f45827e8SErez Zadok if (!ufs) 964e9be9d5eSMiklos Szeredi goto out; 965e9be9d5eSMiklos Szeredi 966f45827e8SErez Zadok err = ovl_parse_opt((char *) data, &ufs->config); 967f45827e8SErez Zadok if (err) 968f45827e8SErez Zadok goto out_free_config; 969f45827e8SErez Zadok 970e9be9d5eSMiklos Szeredi err = -EINVAL; 97153a08cb9SMiklos Szeredi if (!ufs->config.lowerdir) { 97207f2af7bSKonstantin Khlebnikov if (!silent) 97353a08cb9SMiklos Szeredi pr_err("overlayfs: missing 'lowerdir'\n"); 97453a08cb9SMiklos Szeredi goto out_free_config; 97553a08cb9SMiklos Szeredi } 97653a08cb9SMiklos Szeredi 97753a08cb9SMiklos Szeredi sb->s_stack_depth = 0; 978cf9a6784SMiklos Szeredi sb->s_maxbytes = MAX_LFS_FILESIZE; 97953a08cb9SMiklos Szeredi if (ufs->config.upperdir) { 98053a08cb9SMiklos Szeredi if (!ufs->config.workdir) { 98153a08cb9SMiklos Szeredi pr_err("overlayfs: missing 'workdir'\n"); 982e9be9d5eSMiklos Szeredi goto out_free_config; 983e9be9d5eSMiklos Szeredi } 984e9be9d5eSMiklos Szeredi 985f45827e8SErez Zadok err = ovl_mount_dir(ufs->config.upperdir, &upperpath); 986e9be9d5eSMiklos Szeredi if (err) 9873b7a9a24SMiklos Szeredi goto out_free_config; 988e9be9d5eSMiklos Szeredi 98971cbad7eShujianyang /* Upper fs should not be r/o */ 99071cbad7eShujianyang if (upperpath.mnt->mnt_sb->s_flags & MS_RDONLY) { 99171cbad7eShujianyang pr_err("overlayfs: upper fs is r/o, try multi-lower layers mount\n"); 99271cbad7eShujianyang err = -EINVAL; 99371cbad7eShujianyang goto out_put_upperpath; 99471cbad7eShujianyang } 99571cbad7eShujianyang 996f45827e8SErez Zadok err = ovl_mount_dir(ufs->config.workdir, &workpath); 997e9be9d5eSMiklos Szeredi if (err) 9983b7a9a24SMiklos Szeredi goto out_put_upperpath; 9993b7a9a24SMiklos Szeredi 10002f83fd8cShujianyang err = -EINVAL; 1001ab508822SMiklos Szeredi if (upperpath.mnt != workpath.mnt) { 1002ab508822SMiklos Szeredi pr_err("overlayfs: workdir and upperdir must reside under the same mount\n"); 1003ab508822SMiklos Szeredi goto out_put_workpath; 1004ab508822SMiklos Szeredi } 1005ab508822SMiklos Szeredi if (!ovl_workdir_ok(workpath.dentry, upperpath.dentry)) { 1006ab508822SMiklos Szeredi pr_err("overlayfs: workdir and upperdir must be separate subtrees\n"); 1007ab508822SMiklos Szeredi goto out_put_workpath; 1008ab508822SMiklos Szeredi } 1009ab508822SMiklos Szeredi sb->s_stack_depth = upperpath.mnt->mnt_sb->s_stack_depth; 101053a08cb9SMiklos Szeredi } 1011a78d9f0dSMiklos Szeredi err = -ENOMEM; 1012a78d9f0dSMiklos Szeredi lowertmp = kstrdup(ufs->config.lowerdir, GFP_KERNEL); 1013a78d9f0dSMiklos Szeredi if (!lowertmp) 1014a78d9f0dSMiklos Szeredi goto out_put_workpath; 1015ab508822SMiklos Szeredi 1016a78d9f0dSMiklos Szeredi err = -EINVAL; 1017a78d9f0dSMiklos Szeredi stacklen = ovl_split_lowerdirs(lowertmp); 10186be4506eShujianyang if (stacklen > OVL_MAX_STACK) { 10196be4506eShujianyang pr_err("overlayfs: too many lower directries, limit is %d\n", 10206be4506eShujianyang OVL_MAX_STACK); 1021a78d9f0dSMiklos Szeredi goto out_free_lowertmp; 10226be4506eShujianyang } else if (!ufs->config.upperdir && stacklen == 1) { 10236be4506eShujianyang pr_err("overlayfs: at least 2 lowerdir are needed while upperdir nonexistent\n"); 10246be4506eShujianyang goto out_free_lowertmp; 10256be4506eShujianyang } 1026a78d9f0dSMiklos Szeredi 1027a78d9f0dSMiklos Szeredi stack = kcalloc(stacklen, sizeof(struct path), GFP_KERNEL); 1028a78d9f0dSMiklos Szeredi if (!stack) 1029a78d9f0dSMiklos Szeredi goto out_free_lowertmp; 1030a78d9f0dSMiklos Szeredi 1031a78d9f0dSMiklos Szeredi lower = lowertmp; 1032a78d9f0dSMiklos Szeredi for (numlower = 0; numlower < stacklen; numlower++) { 1033a78d9f0dSMiklos Szeredi err = ovl_lower_dir(lower, &stack[numlower], 10347c03b5d4SMiklos Szeredi &ufs->lower_namelen, &sb->s_stack_depth, 10357c03b5d4SMiklos Szeredi &remote); 10363b7a9a24SMiklos Szeredi if (err) 1037a78d9f0dSMiklos Szeredi goto out_put_lowerpath; 1038a78d9f0dSMiklos Szeredi 1039a78d9f0dSMiklos Szeredi lower = strchr(lower, '\0') + 1; 1040a78d9f0dSMiklos Szeredi } 1041e9be9d5eSMiklos Szeredi 1042e9be9d5eSMiklos Szeredi err = -EINVAL; 1043ab508822SMiklos Szeredi sb->s_stack_depth++; 104469c433edSMiklos Szeredi if (sb->s_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) { 104569c433edSMiklos Szeredi pr_err("overlayfs: maximum fs stacking depth exceeded\n"); 10463b7a9a24SMiklos Szeredi goto out_put_lowerpath; 104769c433edSMiklos Szeredi } 104869c433edSMiklos Szeredi 104953a08cb9SMiklos Szeredi if (ufs->config.upperdir) { 1050e9be9d5eSMiklos Szeredi ufs->upper_mnt = clone_private_mount(&upperpath); 1051e9be9d5eSMiklos Szeredi err = PTR_ERR(ufs->upper_mnt); 1052e9be9d5eSMiklos Szeredi if (IS_ERR(ufs->upper_mnt)) { 1053e9be9d5eSMiklos Szeredi pr_err("overlayfs: failed to clone upperpath\n"); 10543b7a9a24SMiklos Szeredi goto out_put_lowerpath; 10553b7a9a24SMiklos Szeredi } 10563b7a9a24SMiklos Szeredi 10573b7a9a24SMiklos Szeredi ufs->workdir = ovl_workdir_create(ufs->upper_mnt, workpath.dentry); 10583b7a9a24SMiklos Szeredi err = PTR_ERR(ufs->workdir); 10593b7a9a24SMiklos Szeredi if (IS_ERR(ufs->workdir)) { 1060cc6f67bcSMiklos Szeredi pr_warn("overlayfs: failed to create directory %s/%s (errno: %i); mounting read-only\n", 1061cc6f67bcSMiklos Szeredi ufs->config.workdir, OVL_WORKDIR_NAME, -err); 1062cc6f67bcSMiklos Szeredi sb->s_flags |= MS_RDONLY; 1063cc6f67bcSMiklos Szeredi ufs->workdir = NULL; 1064e9be9d5eSMiklos Szeredi } 106545aebeafSVivek Goyal 106645aebeafSVivek Goyal /* 106745aebeafSVivek Goyal * Upper should support d_type, else whiteouts are visible. 106845aebeafSVivek Goyal * Given workdir and upper are on same fs, we can do 106945aebeafSVivek Goyal * iterate_dir() on workdir. 107045aebeafSVivek Goyal */ 107145aebeafSVivek Goyal err = ovl_check_d_type_supported(&workpath); 107245aebeafSVivek Goyal if (err < 0) 107345aebeafSVivek Goyal goto out_put_workdir; 107445aebeafSVivek Goyal 107545aebeafSVivek Goyal if (!err) { 107645aebeafSVivek Goyal pr_err("overlayfs: upper fs needs to support d_type.\n"); 107745aebeafSVivek Goyal err = -EINVAL; 107845aebeafSVivek Goyal goto out_put_workdir; 107945aebeafSVivek Goyal } 108053a08cb9SMiklos Szeredi } 1081e9be9d5eSMiklos Szeredi 10822f83fd8cShujianyang err = -ENOMEM; 1083a78d9f0dSMiklos Szeredi ufs->lower_mnt = kcalloc(numlower, sizeof(struct vfsmount *), GFP_KERNEL); 1084dd662667SMiklos Szeredi if (ufs->lower_mnt == NULL) 10853b7a9a24SMiklos Szeredi goto out_put_workdir; 1086a78d9f0dSMiklos Szeredi for (i = 0; i < numlower; i++) { 1087a78d9f0dSMiklos Szeredi struct vfsmount *mnt = clone_private_mount(&stack[i]); 1088dd662667SMiklos Szeredi 10892f83fd8cShujianyang err = PTR_ERR(mnt); 1090dd662667SMiklos Szeredi if (IS_ERR(mnt)) { 1091dd662667SMiklos Szeredi pr_err("overlayfs: failed to clone lowerpath\n"); 1092dd662667SMiklos Szeredi goto out_put_lower_mnt; 1093e9be9d5eSMiklos Szeredi } 1094dd662667SMiklos Szeredi /* 1095dd662667SMiklos Szeredi * Make lower_mnt R/O. That way fchmod/fchown on lower file 1096dd662667SMiklos Szeredi * will fail instead of modifying lower fs. 1097dd662667SMiklos Szeredi */ 1098dd662667SMiklos Szeredi mnt->mnt_flags |= MNT_READONLY; 1099dd662667SMiklos Szeredi 1100a78d9f0dSMiklos Szeredi ufs->lower_mnt[ufs->numlower] = mnt; 1101a78d9f0dSMiklos Szeredi ufs->numlower++; 1102a78d9f0dSMiklos Szeredi } 1103e9be9d5eSMiklos Szeredi 110471cbad7eShujianyang /* If the upper fs is nonexistent, we mark overlayfs r/o too */ 110571cbad7eShujianyang if (!ufs->upper_mnt) 1106e9be9d5eSMiklos Szeredi sb->s_flags |= MS_RDONLY; 1107e9be9d5eSMiklos Szeredi 11087c03b5d4SMiklos Szeredi if (remote) 11097c03b5d4SMiklos Szeredi sb->s_d_op = &ovl_reval_dentry_operations; 11107c03b5d4SMiklos Szeredi else 1111e9be9d5eSMiklos Szeredi sb->s_d_op = &ovl_dentry_operations; 1112e9be9d5eSMiklos Szeredi 1113e9be9d5eSMiklos Szeredi err = -ENOMEM; 1114a78d9f0dSMiklos Szeredi oe = ovl_alloc_entry(numlower); 11153b7a9a24SMiklos Szeredi if (!oe) 11163b7a9a24SMiklos Szeredi goto out_put_lower_mnt; 1117e9be9d5eSMiklos Szeredi 11183b7a9a24SMiklos Szeredi root_dentry = d_make_root(ovl_new_inode(sb, S_IFDIR, oe)); 1119e9be9d5eSMiklos Szeredi if (!root_dentry) 11203b7a9a24SMiklos Szeredi goto out_free_oe; 1121e9be9d5eSMiklos Szeredi 1122e9be9d5eSMiklos Szeredi mntput(upperpath.mnt); 1123a78d9f0dSMiklos Szeredi for (i = 0; i < numlower; i++) 1124a78d9f0dSMiklos Szeredi mntput(stack[i].mnt); 1125e9be9d5eSMiklos Szeredi path_put(&workpath); 1126a78d9f0dSMiklos Szeredi kfree(lowertmp); 1127e9be9d5eSMiklos Szeredi 1128e9be9d5eSMiklos Szeredi oe->__upperdentry = upperpath.dentry; 1129a78d9f0dSMiklos Szeredi for (i = 0; i < numlower; i++) { 1130a78d9f0dSMiklos Szeredi oe->lowerstack[i].dentry = stack[i].dentry; 1131a78d9f0dSMiklos Szeredi oe->lowerstack[i].mnt = ufs->lower_mnt[i]; 1132a78d9f0dSMiklos Szeredi } 11330f95502aSKonstantin Khlebnikov kfree(stack); 1134e9be9d5eSMiklos Szeredi 1135e9be9d5eSMiklos Szeredi root_dentry->d_fsdata = oe; 1136e9be9d5eSMiklos Szeredi 1137ed06e069SMiklos Szeredi ovl_copyattr(ovl_dentry_real(root_dentry)->d_inode, 1138ed06e069SMiklos Szeredi root_dentry->d_inode); 1139ed06e069SMiklos Szeredi 1140cc259639SAndy Whitcroft sb->s_magic = OVERLAYFS_SUPER_MAGIC; 1141e9be9d5eSMiklos Szeredi sb->s_op = &ovl_super_operations; 1142e9be9d5eSMiklos Szeredi sb->s_root = root_dentry; 1143e9be9d5eSMiklos Szeredi sb->s_fs_info = ufs; 1144e9be9d5eSMiklos Szeredi 1145e9be9d5eSMiklos Szeredi return 0; 1146e9be9d5eSMiklos Szeredi 11473b7a9a24SMiklos Szeredi out_free_oe: 11483b7a9a24SMiklos Szeredi kfree(oe); 1149e9be9d5eSMiklos Szeredi out_put_lower_mnt: 1150dd662667SMiklos Szeredi for (i = 0; i < ufs->numlower; i++) 1151dd662667SMiklos Szeredi mntput(ufs->lower_mnt[i]); 1152dd662667SMiklos Szeredi kfree(ufs->lower_mnt); 11533b7a9a24SMiklos Szeredi out_put_workdir: 11543b7a9a24SMiklos Szeredi dput(ufs->workdir); 1155e9be9d5eSMiklos Szeredi mntput(ufs->upper_mnt); 1156e9be9d5eSMiklos Szeredi out_put_lowerpath: 1157a78d9f0dSMiklos Szeredi for (i = 0; i < numlower; i++) 1158a78d9f0dSMiklos Szeredi path_put(&stack[i]); 1159a78d9f0dSMiklos Szeredi kfree(stack); 1160a78d9f0dSMiklos Szeredi out_free_lowertmp: 1161a78d9f0dSMiklos Szeredi kfree(lowertmp); 11623b7a9a24SMiklos Szeredi out_put_workpath: 11633b7a9a24SMiklos Szeredi path_put(&workpath); 1164e9be9d5eSMiklos Szeredi out_put_upperpath: 1165e9be9d5eSMiklos Szeredi path_put(&upperpath); 1166e9be9d5eSMiklos Szeredi out_free_config: 1167f45827e8SErez Zadok kfree(ufs->config.lowerdir); 1168f45827e8SErez Zadok kfree(ufs->config.upperdir); 1169f45827e8SErez Zadok kfree(ufs->config.workdir); 1170f45827e8SErez Zadok kfree(ufs); 1171e9be9d5eSMiklos Szeredi out: 1172e9be9d5eSMiklos Szeredi return err; 1173e9be9d5eSMiklos Szeredi } 1174e9be9d5eSMiklos Szeredi 1175e9be9d5eSMiklos Szeredi static struct dentry *ovl_mount(struct file_system_type *fs_type, int flags, 1176e9be9d5eSMiklos Szeredi const char *dev_name, void *raw_data) 1177e9be9d5eSMiklos Szeredi { 1178e9be9d5eSMiklos Szeredi return mount_nodev(fs_type, flags, raw_data, ovl_fill_super); 1179e9be9d5eSMiklos Szeredi } 1180e9be9d5eSMiklos Szeredi 1181e9be9d5eSMiklos Szeredi static struct file_system_type ovl_fs_type = { 1182e9be9d5eSMiklos Szeredi .owner = THIS_MODULE, 1183ef94b186SMiklos Szeredi .name = "overlay", 1184e9be9d5eSMiklos Szeredi .mount = ovl_mount, 1185e9be9d5eSMiklos Szeredi .kill_sb = kill_anon_super, 1186e9be9d5eSMiklos Szeredi }; 1187ef94b186SMiklos Szeredi MODULE_ALIAS_FS("overlay"); 1188e9be9d5eSMiklos Szeredi 1189e9be9d5eSMiklos Szeredi static int __init ovl_init(void) 1190e9be9d5eSMiklos Szeredi { 1191e9be9d5eSMiklos Szeredi return register_filesystem(&ovl_fs_type); 1192e9be9d5eSMiklos Szeredi } 1193e9be9d5eSMiklos Szeredi 1194e9be9d5eSMiklos Szeredi static void __exit ovl_exit(void) 1195e9be9d5eSMiklos Szeredi { 1196e9be9d5eSMiklos Szeredi unregister_filesystem(&ovl_fs_type); 1197e9be9d5eSMiklos Szeredi } 1198e9be9d5eSMiklos Szeredi 1199e9be9d5eSMiklos Szeredi module_init(ovl_init); 1200e9be9d5eSMiklos Szeredi module_exit(ovl_exit); 1201