1bbb1e54dSMiklos Szeredi /* 2bbb1e54dSMiklos Szeredi * Copyright (C) 2011 Novell Inc. 3bbb1e54dSMiklos Szeredi * Copyright (C) 2016 Red Hat, Inc. 4bbb1e54dSMiklos Szeredi * 5bbb1e54dSMiklos Szeredi * This program is free software; you can redistribute it and/or modify it 6bbb1e54dSMiklos Szeredi * under the terms of the GNU General Public License version 2 as published by 7bbb1e54dSMiklos Szeredi * the Free Software Foundation. 8bbb1e54dSMiklos Szeredi */ 9bbb1e54dSMiklos Szeredi 10bbb1e54dSMiklos Szeredi #include <linux/fs.h> 11bbb1e54dSMiklos Szeredi #include <linux/mount.h> 12bbb1e54dSMiklos Szeredi #include <linux/slab.h> 135b825c3aSIngo Molnar #include <linux/cred.h> 14bbb1e54dSMiklos Szeredi #include <linux/xattr.h> 15bbb1e54dSMiklos Szeredi #include "overlayfs.h" 16bbb1e54dSMiklos Szeredi #include "ovl_entry.h" 17bbb1e54dSMiklos Szeredi 18bbb1e54dSMiklos Szeredi int ovl_want_write(struct dentry *dentry) 19bbb1e54dSMiklos Szeredi { 20bbb1e54dSMiklos Szeredi struct ovl_fs *ofs = dentry->d_sb->s_fs_info; 21bbb1e54dSMiklos Szeredi return mnt_want_write(ofs->upper_mnt); 22bbb1e54dSMiklos Szeredi } 23bbb1e54dSMiklos Szeredi 24bbb1e54dSMiklos Szeredi void ovl_drop_write(struct dentry *dentry) 25bbb1e54dSMiklos Szeredi { 26bbb1e54dSMiklos Szeredi struct ovl_fs *ofs = dentry->d_sb->s_fs_info; 27bbb1e54dSMiklos Szeredi mnt_drop_write(ofs->upper_mnt); 28bbb1e54dSMiklos Szeredi } 29bbb1e54dSMiklos Szeredi 30bbb1e54dSMiklos Szeredi struct dentry *ovl_workdir(struct dentry *dentry) 31bbb1e54dSMiklos Szeredi { 32bbb1e54dSMiklos Szeredi struct ovl_fs *ofs = dentry->d_sb->s_fs_info; 33bbb1e54dSMiklos Szeredi return ofs->workdir; 34bbb1e54dSMiklos Szeredi } 35bbb1e54dSMiklos Szeredi 36bbb1e54dSMiklos Szeredi const struct cred *ovl_override_creds(struct super_block *sb) 37bbb1e54dSMiklos Szeredi { 38bbb1e54dSMiklos Szeredi struct ovl_fs *ofs = sb->s_fs_info; 39bbb1e54dSMiklos Szeredi 40bbb1e54dSMiklos Szeredi return override_creds(ofs->creator_cred); 41bbb1e54dSMiklos Szeredi } 42bbb1e54dSMiklos Szeredi 437bcd74b9SAmir Goldstein struct super_block *ovl_same_sb(struct super_block *sb) 447bcd74b9SAmir Goldstein { 457bcd74b9SAmir Goldstein struct ovl_fs *ofs = sb->s_fs_info; 467bcd74b9SAmir Goldstein 477bcd74b9SAmir Goldstein return ofs->same_sb; 487bcd74b9SAmir Goldstein } 497bcd74b9SAmir Goldstein 50bbb1e54dSMiklos Szeredi struct ovl_entry *ovl_alloc_entry(unsigned int numlower) 51bbb1e54dSMiklos Szeredi { 52bbb1e54dSMiklos Szeredi size_t size = offsetof(struct ovl_entry, lowerstack[numlower]); 53bbb1e54dSMiklos Szeredi struct ovl_entry *oe = kzalloc(size, GFP_KERNEL); 54bbb1e54dSMiklos Szeredi 55bbb1e54dSMiklos Szeredi if (oe) 56bbb1e54dSMiklos Szeredi oe->numlower = numlower; 57bbb1e54dSMiklos Szeredi 58bbb1e54dSMiklos Szeredi return oe; 59bbb1e54dSMiklos Szeredi } 60bbb1e54dSMiklos Szeredi 61bbb1e54dSMiklos Szeredi bool ovl_dentry_remote(struct dentry *dentry) 62bbb1e54dSMiklos Szeredi { 63bbb1e54dSMiklos Szeredi return dentry->d_flags & 64bbb1e54dSMiklos Szeredi (DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE | 65bbb1e54dSMiklos Szeredi DCACHE_OP_REAL); 66bbb1e54dSMiklos Szeredi } 67bbb1e54dSMiklos Szeredi 68bbb1e54dSMiklos Szeredi bool ovl_dentry_weird(struct dentry *dentry) 69bbb1e54dSMiklos Szeredi { 70bbb1e54dSMiklos Szeredi return dentry->d_flags & (DCACHE_NEED_AUTOMOUNT | 71bbb1e54dSMiklos Szeredi DCACHE_MANAGE_TRANSIT | 72bbb1e54dSMiklos Szeredi DCACHE_OP_HASH | 73bbb1e54dSMiklos Szeredi DCACHE_OP_COMPARE); 74bbb1e54dSMiklos Szeredi } 75bbb1e54dSMiklos Szeredi 76bbb1e54dSMiklos Szeredi enum ovl_path_type ovl_path_type(struct dentry *dentry) 77bbb1e54dSMiklos Szeredi { 78bbb1e54dSMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 79bbb1e54dSMiklos Szeredi enum ovl_path_type type = 0; 80bbb1e54dSMiklos Szeredi 81bbb1e54dSMiklos Szeredi if (oe->__upperdentry) { 82bbb1e54dSMiklos Szeredi type = __OVL_PATH_UPPER; 83bbb1e54dSMiklos Szeredi 84bbb1e54dSMiklos Szeredi /* 8559548503SAmir Goldstein * Non-dir dentry can hold lower dentry of its copy up origin. 86bbb1e54dSMiklos Szeredi */ 8759548503SAmir Goldstein if (oe->numlower) { 8859548503SAmir Goldstein type |= __OVL_PATH_ORIGIN; 8959548503SAmir Goldstein if (d_is_dir(dentry)) 90bbb1e54dSMiklos Szeredi type |= __OVL_PATH_MERGE; 9159548503SAmir Goldstein } 92bbb1e54dSMiklos Szeredi } else { 93bbb1e54dSMiklos Szeredi if (oe->numlower > 1) 94bbb1e54dSMiklos Szeredi type |= __OVL_PATH_MERGE; 95bbb1e54dSMiklos Szeredi } 96bbb1e54dSMiklos Szeredi return type; 97bbb1e54dSMiklos Szeredi } 98bbb1e54dSMiklos Szeredi 99bbb1e54dSMiklos Szeredi void ovl_path_upper(struct dentry *dentry, struct path *path) 100bbb1e54dSMiklos Szeredi { 101bbb1e54dSMiklos Szeredi struct ovl_fs *ofs = dentry->d_sb->s_fs_info; 102bbb1e54dSMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 103bbb1e54dSMiklos Szeredi 104bbb1e54dSMiklos Szeredi path->mnt = ofs->upper_mnt; 105bbb1e54dSMiklos Szeredi path->dentry = ovl_upperdentry_dereference(oe); 106bbb1e54dSMiklos Szeredi } 107bbb1e54dSMiklos Szeredi 108bbb1e54dSMiklos Szeredi void ovl_path_lower(struct dentry *dentry, struct path *path) 109bbb1e54dSMiklos Szeredi { 110bbb1e54dSMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 111bbb1e54dSMiklos Szeredi 11233006cdfSKees Cook *path = oe->numlower ? oe->lowerstack[0] : (struct path) { }; 113bbb1e54dSMiklos Szeredi } 114bbb1e54dSMiklos Szeredi 115bbb1e54dSMiklos Szeredi enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path) 116bbb1e54dSMiklos Szeredi { 117bbb1e54dSMiklos Szeredi enum ovl_path_type type = ovl_path_type(dentry); 118bbb1e54dSMiklos Szeredi 119bbb1e54dSMiklos Szeredi if (!OVL_TYPE_UPPER(type)) 120bbb1e54dSMiklos Szeredi ovl_path_lower(dentry, path); 121bbb1e54dSMiklos Szeredi else 122bbb1e54dSMiklos Szeredi ovl_path_upper(dentry, path); 123bbb1e54dSMiklos Szeredi 124bbb1e54dSMiklos Szeredi return type; 125bbb1e54dSMiklos Szeredi } 126bbb1e54dSMiklos Szeredi 127bbb1e54dSMiklos Szeredi struct dentry *ovl_dentry_upper(struct dentry *dentry) 128bbb1e54dSMiklos Szeredi { 129bbb1e54dSMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 130bbb1e54dSMiklos Szeredi 131bbb1e54dSMiklos Szeredi return ovl_upperdentry_dereference(oe); 132bbb1e54dSMiklos Szeredi } 133bbb1e54dSMiklos Szeredi 134bbb1e54dSMiklos Szeredi static struct dentry *__ovl_dentry_lower(struct ovl_entry *oe) 135bbb1e54dSMiklos Szeredi { 136bbb1e54dSMiklos Szeredi return oe->numlower ? oe->lowerstack[0].dentry : NULL; 137bbb1e54dSMiklos Szeredi } 138bbb1e54dSMiklos Szeredi 139bbb1e54dSMiklos Szeredi struct dentry *ovl_dentry_lower(struct dentry *dentry) 140bbb1e54dSMiklos Szeredi { 141bbb1e54dSMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 142bbb1e54dSMiklos Szeredi 143bbb1e54dSMiklos Szeredi return __ovl_dentry_lower(oe); 144bbb1e54dSMiklos Szeredi } 145bbb1e54dSMiklos Szeredi 146bbb1e54dSMiklos Szeredi struct dentry *ovl_dentry_real(struct dentry *dentry) 147bbb1e54dSMiklos Szeredi { 148bbb1e54dSMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 149bbb1e54dSMiklos Szeredi struct dentry *realdentry; 150bbb1e54dSMiklos Szeredi 151bbb1e54dSMiklos Szeredi realdentry = ovl_upperdentry_dereference(oe); 152bbb1e54dSMiklos Szeredi if (!realdentry) 153bbb1e54dSMiklos Szeredi realdentry = __ovl_dentry_lower(oe); 154bbb1e54dSMiklos Szeredi 155bbb1e54dSMiklos Szeredi return realdentry; 156bbb1e54dSMiklos Szeredi } 157bbb1e54dSMiklos Szeredi 15825b7713aSMiklos Szeredi struct inode *ovl_inode_real(struct inode *inode, bool *is_upper) 15925b7713aSMiklos Szeredi { 16025b7713aSMiklos Szeredi struct inode *realinode = lockless_dereference(OVL_I(inode)->upper); 16125b7713aSMiklos Szeredi bool isup = false; 16225b7713aSMiklos Szeredi 16325b7713aSMiklos Szeredi if (!realinode) 16425b7713aSMiklos Szeredi realinode = OVL_I(inode)->lower; 16525b7713aSMiklos Szeredi else 16625b7713aSMiklos Szeredi isup = true; 16725b7713aSMiklos Szeredi 16825b7713aSMiklos Szeredi if (is_upper) 16925b7713aSMiklos Szeredi *is_upper = isup; 17025b7713aSMiklos Szeredi 17125b7713aSMiklos Szeredi return realinode; 17225b7713aSMiklos Szeredi } 17325b7713aSMiklos Szeredi 174bbb1e54dSMiklos Szeredi struct ovl_dir_cache *ovl_dir_cache(struct dentry *dentry) 175bbb1e54dSMiklos Szeredi { 176bbb1e54dSMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 177bbb1e54dSMiklos Szeredi 178bbb1e54dSMiklos Szeredi return oe->cache; 179bbb1e54dSMiklos Szeredi } 180bbb1e54dSMiklos Szeredi 181bbb1e54dSMiklos Szeredi void ovl_set_dir_cache(struct dentry *dentry, struct ovl_dir_cache *cache) 182bbb1e54dSMiklos Szeredi { 183bbb1e54dSMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 184bbb1e54dSMiklos Szeredi 185bbb1e54dSMiklos Szeredi oe->cache = cache; 186bbb1e54dSMiklos Szeredi } 187bbb1e54dSMiklos Szeredi 188bbb1e54dSMiklos Szeredi bool ovl_dentry_is_opaque(struct dentry *dentry) 189bbb1e54dSMiklos Szeredi { 190bbb1e54dSMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 191bbb1e54dSMiklos Szeredi return oe->opaque; 192bbb1e54dSMiklos Szeredi } 193bbb1e54dSMiklos Szeredi 194ee1d6d37SAmir Goldstein bool ovl_dentry_is_impure(struct dentry *dentry) 195ee1d6d37SAmir Goldstein { 196ee1d6d37SAmir Goldstein struct ovl_entry *oe = dentry->d_fsdata; 197ee1d6d37SAmir Goldstein 198ee1d6d37SAmir Goldstein return oe->impure; 199ee1d6d37SAmir Goldstein } 200ee1d6d37SAmir Goldstein 201bbb1e54dSMiklos Szeredi bool ovl_dentry_is_whiteout(struct dentry *dentry) 202bbb1e54dSMiklos Szeredi { 203bbb1e54dSMiklos Szeredi return !dentry->d_inode && ovl_dentry_is_opaque(dentry); 204bbb1e54dSMiklos Szeredi } 205bbb1e54dSMiklos Szeredi 2065cf5b477SMiklos Szeredi void ovl_dentry_set_opaque(struct dentry *dentry) 207bbb1e54dSMiklos Szeredi { 208bbb1e54dSMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 2095cf5b477SMiklos Szeredi 2105cf5b477SMiklos Szeredi oe->opaque = true; 211bbb1e54dSMiklos Szeredi } 212bbb1e54dSMiklos Szeredi 213a6c60655SMiklos Szeredi bool ovl_redirect_dir(struct super_block *sb) 214a6c60655SMiklos Szeredi { 215a6c60655SMiklos Szeredi struct ovl_fs *ofs = sb->s_fs_info; 216a6c60655SMiklos Szeredi 21721a22878SAmir Goldstein return ofs->config.redirect_dir && !ofs->noxattr; 218a6c60655SMiklos Szeredi } 219a6c60655SMiklos Szeredi 220a6c60655SMiklos Szeredi const char *ovl_dentry_get_redirect(struct dentry *dentry) 221a6c60655SMiklos Szeredi { 222a6c60655SMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 223a6c60655SMiklos Szeredi 224a6c60655SMiklos Szeredi return oe->redirect; 225a6c60655SMiklos Szeredi } 226a6c60655SMiklos Szeredi 227a6c60655SMiklos Szeredi void ovl_dentry_set_redirect(struct dentry *dentry, const char *redirect) 228a6c60655SMiklos Szeredi { 229a6c60655SMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 230a6c60655SMiklos Szeredi 231a6c60655SMiklos Szeredi kfree(oe->redirect); 232a6c60655SMiklos Szeredi oe->redirect = redirect; 233a6c60655SMiklos Szeredi } 234a6c60655SMiklos Szeredi 235bbb1e54dSMiklos Szeredi void ovl_dentry_update(struct dentry *dentry, struct dentry *upperdentry) 236bbb1e54dSMiklos Szeredi { 237bbb1e54dSMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 238bbb1e54dSMiklos Szeredi 239bbb1e54dSMiklos Szeredi WARN_ON(!inode_is_locked(upperdentry->d_parent->d_inode)); 240bbb1e54dSMiklos Szeredi WARN_ON(oe->__upperdentry); 241bbb1e54dSMiklos Szeredi /* 242bbb1e54dSMiklos Szeredi * Make sure upperdentry is consistent before making it visible to 243bbb1e54dSMiklos Szeredi * ovl_upperdentry_dereference(). 244bbb1e54dSMiklos Szeredi */ 245bbb1e54dSMiklos Szeredi smp_wmb(); 246bbb1e54dSMiklos Szeredi oe->__upperdentry = upperdentry; 247bbb1e54dSMiklos Szeredi } 248bbb1e54dSMiklos Szeredi 249e6d2ebddSMiklos Szeredi void ovl_inode_init(struct inode *inode, struct dentry *dentry) 250bbb1e54dSMiklos Szeredi { 251e6d2ebddSMiklos Szeredi struct inode *realinode = d_inode(ovl_dentry_real(dentry)); 252e6d2ebddSMiklos Szeredi 25325b7713aSMiklos Szeredi if (ovl_dentry_upper(dentry)) 25425b7713aSMiklos Szeredi OVL_I(inode)->upper = realinode; 25525b7713aSMiklos Szeredi else 25625b7713aSMiklos Szeredi OVL_I(inode)->lower = realinode; 257e6d2ebddSMiklos Szeredi 258e6d2ebddSMiklos Szeredi ovl_copyattr(realinode, inode); 259bbb1e54dSMiklos Szeredi } 260bbb1e54dSMiklos Szeredi 261bbb1e54dSMiklos Szeredi void ovl_inode_update(struct inode *inode, struct inode *upperinode) 262bbb1e54dSMiklos Szeredi { 263bbb1e54dSMiklos Szeredi WARN_ON(!upperinode); 264bbb1e54dSMiklos Szeredi WARN_ON(!inode_unhashed(inode)); 26525b7713aSMiklos Szeredi /* 26625b7713aSMiklos Szeredi * Make sure upperinode is consistent before making it visible to 26725b7713aSMiklos Szeredi * ovl_inode_real(); 26825b7713aSMiklos Szeredi */ 26925b7713aSMiklos Szeredi smp_wmb(); 27025b7713aSMiklos Szeredi OVL_I(inode)->upper = upperinode; 27125b7713aSMiklos Szeredi if (!S_ISDIR(upperinode->i_mode)) { 27225b7713aSMiklos Szeredi inode->i_private = upperinode; 273bbb1e54dSMiklos Szeredi __insert_inode_hash(inode, (unsigned long) upperinode); 274bbb1e54dSMiklos Szeredi } 27525b7713aSMiklos Szeredi } 276bbb1e54dSMiklos Szeredi 277bbb1e54dSMiklos Szeredi void ovl_dentry_version_inc(struct dentry *dentry) 278bbb1e54dSMiklos Szeredi { 279bbb1e54dSMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 280bbb1e54dSMiklos Szeredi 281bbb1e54dSMiklos Szeredi WARN_ON(!inode_is_locked(dentry->d_inode)); 282bbb1e54dSMiklos Szeredi oe->version++; 283bbb1e54dSMiklos Szeredi } 284bbb1e54dSMiklos Szeredi 285bbb1e54dSMiklos Szeredi u64 ovl_dentry_version_get(struct dentry *dentry) 286bbb1e54dSMiklos Szeredi { 287bbb1e54dSMiklos Szeredi struct ovl_entry *oe = dentry->d_fsdata; 288bbb1e54dSMiklos Szeredi 289bbb1e54dSMiklos Szeredi WARN_ON(!inode_is_locked(dentry->d_inode)); 290bbb1e54dSMiklos Szeredi return oe->version; 291bbb1e54dSMiklos Szeredi } 292bbb1e54dSMiklos Szeredi 293bbb1e54dSMiklos Szeredi bool ovl_is_whiteout(struct dentry *dentry) 294bbb1e54dSMiklos Szeredi { 295bbb1e54dSMiklos Szeredi struct inode *inode = dentry->d_inode; 296bbb1e54dSMiklos Szeredi 297bbb1e54dSMiklos Szeredi return inode && IS_WHITEOUT(inode); 298bbb1e54dSMiklos Szeredi } 299bbb1e54dSMiklos Szeredi 300bbb1e54dSMiklos Szeredi struct file *ovl_path_open(struct path *path, int flags) 301bbb1e54dSMiklos Szeredi { 302bbb1e54dSMiklos Szeredi return dentry_open(path, flags | O_NOATIME, current_cred()); 303bbb1e54dSMiklos Szeredi } 30439d3d60aSAmir Goldstein 30539d3d60aSAmir Goldstein int ovl_copy_up_start(struct dentry *dentry) 30639d3d60aSAmir Goldstein { 30739d3d60aSAmir Goldstein struct ovl_fs *ofs = dentry->d_sb->s_fs_info; 30839d3d60aSAmir Goldstein struct ovl_entry *oe = dentry->d_fsdata; 30939d3d60aSAmir Goldstein int err; 31039d3d60aSAmir Goldstein 31139d3d60aSAmir Goldstein spin_lock(&ofs->copyup_wq.lock); 31239d3d60aSAmir Goldstein err = wait_event_interruptible_locked(ofs->copyup_wq, !oe->copying); 31339d3d60aSAmir Goldstein if (!err) { 31439d3d60aSAmir Goldstein if (oe->__upperdentry) 31539d3d60aSAmir Goldstein err = 1; /* Already copied up */ 31639d3d60aSAmir Goldstein else 31739d3d60aSAmir Goldstein oe->copying = true; 31839d3d60aSAmir Goldstein } 31939d3d60aSAmir Goldstein spin_unlock(&ofs->copyup_wq.lock); 32039d3d60aSAmir Goldstein 32139d3d60aSAmir Goldstein return err; 32239d3d60aSAmir Goldstein } 32339d3d60aSAmir Goldstein 32439d3d60aSAmir Goldstein void ovl_copy_up_end(struct dentry *dentry) 32539d3d60aSAmir Goldstein { 32639d3d60aSAmir Goldstein struct ovl_fs *ofs = dentry->d_sb->s_fs_info; 32739d3d60aSAmir Goldstein struct ovl_entry *oe = dentry->d_fsdata; 32839d3d60aSAmir Goldstein 32939d3d60aSAmir Goldstein spin_lock(&ofs->copyup_wq.lock); 33039d3d60aSAmir Goldstein oe->copying = false; 33139d3d60aSAmir Goldstein wake_up_locked(&ofs->copyup_wq); 33239d3d60aSAmir Goldstein spin_unlock(&ofs->copyup_wq.lock); 33339d3d60aSAmir Goldstein } 33482b749b2SAmir Goldstein 335f3a15685SAmir Goldstein bool ovl_check_dir_xattr(struct dentry *dentry, const char *name) 336f3a15685SAmir Goldstein { 337f3a15685SAmir Goldstein int res; 338f3a15685SAmir Goldstein char val; 339f3a15685SAmir Goldstein 340f3a15685SAmir Goldstein if (!d_is_dir(dentry)) 341f3a15685SAmir Goldstein return false; 342f3a15685SAmir Goldstein 343f3a15685SAmir Goldstein res = vfs_getxattr(dentry, name, &val, 1); 344f3a15685SAmir Goldstein if (res == 1 && val == 'y') 345f3a15685SAmir Goldstein return true; 346f3a15685SAmir Goldstein 347f3a15685SAmir Goldstein return false; 348f3a15685SAmir Goldstein } 349f3a15685SAmir Goldstein 35082b749b2SAmir Goldstein int ovl_check_setxattr(struct dentry *dentry, struct dentry *upperdentry, 35182b749b2SAmir Goldstein const char *name, const void *value, size_t size, 35282b749b2SAmir Goldstein int xerr) 35382b749b2SAmir Goldstein { 35482b749b2SAmir Goldstein int err; 35582b749b2SAmir Goldstein struct ovl_fs *ofs = dentry->d_sb->s_fs_info; 35682b749b2SAmir Goldstein 35782b749b2SAmir Goldstein if (ofs->noxattr) 35882b749b2SAmir Goldstein return xerr; 35982b749b2SAmir Goldstein 36082b749b2SAmir Goldstein err = ovl_do_setxattr(upperdentry, name, value, size, 0); 36182b749b2SAmir Goldstein 36282b749b2SAmir Goldstein if (err == -EOPNOTSUPP) { 36382b749b2SAmir Goldstein pr_warn("overlayfs: cannot set %s xattr on upper\n", name); 36482b749b2SAmir Goldstein ofs->noxattr = true; 36582b749b2SAmir Goldstein return xerr; 36682b749b2SAmir Goldstein } 36782b749b2SAmir Goldstein 36882b749b2SAmir Goldstein return err; 36982b749b2SAmir Goldstein } 370f3a15685SAmir Goldstein 371f3a15685SAmir Goldstein int ovl_set_impure(struct dentry *dentry, struct dentry *upperdentry) 372f3a15685SAmir Goldstein { 373f3a15685SAmir Goldstein int err; 374f3a15685SAmir Goldstein struct ovl_entry *oe = dentry->d_fsdata; 375f3a15685SAmir Goldstein 376f3a15685SAmir Goldstein if (oe->impure) 377f3a15685SAmir Goldstein return 0; 378f3a15685SAmir Goldstein 379f3a15685SAmir Goldstein /* 380f3a15685SAmir Goldstein * Do not fail when upper doesn't support xattrs. 381f3a15685SAmir Goldstein * Upper inodes won't have origin nor redirect xattr anyway. 382f3a15685SAmir Goldstein */ 383f3a15685SAmir Goldstein err = ovl_check_setxattr(dentry, upperdentry, OVL_XATTR_IMPURE, 384f3a15685SAmir Goldstein "y", 1, 0); 385f3a15685SAmir Goldstein if (!err) 386f3a15685SAmir Goldstein oe->impure = true; 387f3a15685SAmir Goldstein 388f3a15685SAmir Goldstein return err; 389f3a15685SAmir Goldstein } 390