1bbb1e54dSMiklos Szeredi /* 2bbb1e54dSMiklos Szeredi * 3bbb1e54dSMiklos Szeredi * Copyright (C) 2011 Novell Inc. 4bbb1e54dSMiklos Szeredi * Copyright (C) 2016 Red Hat, Inc. 5bbb1e54dSMiklos Szeredi * 6bbb1e54dSMiklos Szeredi * This program is free software; you can redistribute it and/or modify it 7bbb1e54dSMiklos Szeredi * under the terms of the GNU General Public License version 2 as published by 8bbb1e54dSMiklos Szeredi * the Free Software Foundation. 9bbb1e54dSMiklos Szeredi */ 10bbb1e54dSMiklos Szeredi 11bbb1e54dSMiklos Szeredi struct ovl_config { 12bbb1e54dSMiklos Szeredi char *lowerdir; 13bbb1e54dSMiklos Szeredi char *upperdir; 14bbb1e54dSMiklos Szeredi char *workdir; 15bbb1e54dSMiklos Szeredi bool default_permissions; 16a6c60655SMiklos Szeredi bool redirect_dir; 17438c84c2SMiklos Szeredi bool redirect_follow; 18438c84c2SMiklos Szeredi const char *redirect_mode; 1902bcd157SAmir Goldstein bool index; 20f168f109SAmir Goldstein bool nfs_export; 21795939a9SAmir Goldstein int xino; 22d5791044SVivek Goyal bool metacopy; 23bbb1e54dSMiklos Szeredi }; 24bbb1e54dSMiklos Szeredi 255148626bSAmir Goldstein struct ovl_sb { 265148626bSAmir Goldstein struct super_block *sb; 275148626bSAmir Goldstein dev_t pseudo_dev; 285148626bSAmir Goldstein }; 295148626bSAmir Goldstein 30b9343632SChandan Rajendra struct ovl_layer { 31b9343632SChandan Rajendra struct vfsmount *mnt; 32146d62e5SAmir Goldstein /* Trap in ovl inode cache */ 33146d62e5SAmir Goldstein struct inode *trap; 345148626bSAmir Goldstein struct ovl_sb *fs; 355148626bSAmir Goldstein /* Index of this layer in fs root (upper idx == 0) */ 36d583ed7dSAmir Goldstein int idx; 375148626bSAmir Goldstein /* One fsid per unique underlying sb (upper fsid == 0) */ 385148626bSAmir Goldstein int fsid; 39b9343632SChandan Rajendra }; 40b9343632SChandan Rajendra 41b9343632SChandan Rajendra struct ovl_path { 42b9343632SChandan Rajendra struct ovl_layer *layer; 43b9343632SChandan Rajendra struct dentry *dentry; 44b9343632SChandan Rajendra }; 45b9343632SChandan Rajendra 46bbb1e54dSMiklos Szeredi /* private information held for overlayfs's superblock */ 47bbb1e54dSMiklos Szeredi struct ovl_fs { 48bbb1e54dSMiklos Szeredi struct vfsmount *upper_mnt; 495148626bSAmir Goldstein unsigned int numlower; 505148626bSAmir Goldstein /* Number of unique lower sb that differ from upper sb */ 515148626bSAmir Goldstein unsigned int numlowerfs; 52b9343632SChandan Rajendra struct ovl_layer *lower_layers; 535148626bSAmir Goldstein struct ovl_sb *lower_fs; 542cac0c00SAmir Goldstein /* workbasedir is the path at workdir= mount option */ 552cac0c00SAmir Goldstein struct dentry *workbasedir; 562cac0c00SAmir Goldstein /* workdir is the 'work' directory under workbasedir */ 57bbb1e54dSMiklos Szeredi struct dentry *workdir; 5802bcd157SAmir Goldstein /* index directory listing overlay inodes by origin file handle */ 5902bcd157SAmir Goldstein struct dentry *indexdir; 606b2d5fe4SMiklos Szeredi long namelen; 61bbb1e54dSMiklos Szeredi /* pathnames of lower and upper dirs, for show_options */ 62bbb1e54dSMiklos Szeredi struct ovl_config config; 63bbb1e54dSMiklos Szeredi /* creds of process who forced instantiation of super block */ 64bbb1e54dSMiklos Szeredi const struct cred *creator_cred; 65e7f52429SAmir Goldstein bool tmpfile; 6682b749b2SAmir Goldstein bool noxattr; 6785fdee1eSAmir Goldstein /* Did we take the inuse lock? */ 6885fdee1eSAmir Goldstein bool upperdir_locked; 6985fdee1eSAmir Goldstein bool workdir_locked; 70146d62e5SAmir Goldstein /* Traps in ovl inode cache */ 71146d62e5SAmir Goldstein struct inode *upperdir_trap; 72146d62e5SAmir Goldstein struct inode *workdir_trap; 73146d62e5SAmir Goldstein struct inode *indexdir_trap; 74e487d889SAmir Goldstein /* Inode numbers in all layers do not use the high xino_bits */ 75e487d889SAmir Goldstein unsigned int xino_bits; 76bbb1e54dSMiklos Szeredi }; 77bbb1e54dSMiklos Szeredi 78bbb1e54dSMiklos Szeredi /* private information held for every overlayfs dentry */ 79bbb1e54dSMiklos Szeredi struct ovl_entry { 80bbb1e54dSMiklos Szeredi union { 8155acc661SMiklos Szeredi struct { 82c62520a8SAmir Goldstein unsigned long flags; 8355acc661SMiklos Szeredi }; 84bbb1e54dSMiklos Szeredi struct rcu_head rcu; 85bbb1e54dSMiklos Szeredi }; 86bbb1e54dSMiklos Szeredi unsigned numlower; 87b9343632SChandan Rajendra struct ovl_path lowerstack[]; 88bbb1e54dSMiklos Szeredi }; 89bbb1e54dSMiklos Szeredi 90bbb1e54dSMiklos Szeredi struct ovl_entry *ovl_alloc_entry(unsigned int numlower); 91bbb1e54dSMiklos Szeredi 92c62520a8SAmir Goldstein static inline struct ovl_entry *OVL_E(struct dentry *dentry) 93c62520a8SAmir Goldstein { 94c62520a8SAmir Goldstein return (struct ovl_entry *) dentry->d_fsdata; 95c62520a8SAmir Goldstein } 96c62520a8SAmir Goldstein 9713cf199dSAmir Goldstein struct ovl_inode { 982664bd08SVivek Goyal union { 992664bd08SVivek Goyal struct ovl_dir_cache *cache; /* directory */ 1002664bd08SVivek Goyal struct inode *lowerdata; /* regular file */ 1012664bd08SVivek Goyal }; 102cf31c463SMiklos Szeredi const char *redirect; 10304a01ac7SMiklos Szeredi u64 version; 10413c72075SMiklos Szeredi unsigned long flags; 10513cf199dSAmir Goldstein struct inode vfs_inode; 10609d8b586SMiklos Szeredi struct dentry *__upperdentry; 10725b7713aSMiklos Szeredi struct inode *lower; 108a015dafcSAmir Goldstein 109a015dafcSAmir Goldstein /* synchronize copy up and more */ 110a015dafcSAmir Goldstein struct mutex lock; 11113cf199dSAmir Goldstein }; 11213cf199dSAmir Goldstein 11313cf199dSAmir Goldstein static inline struct ovl_inode *OVL_I(struct inode *inode) 11413cf199dSAmir Goldstein { 11513cf199dSAmir Goldstein return container_of(inode, struct ovl_inode, vfs_inode); 11613cf199dSAmir Goldstein } 11709d8b586SMiklos Szeredi 11809d8b586SMiklos Szeredi static inline struct dentry *ovl_upperdentry_dereference(struct ovl_inode *oi) 11909d8b586SMiklos Szeredi { 120506458efSWill Deacon return READ_ONCE(oi->__upperdentry); 12109d8b586SMiklos Szeredi } 122