}
ovl_fill_inode(inode, realinode->i_mode, realinode->i_rdev);
ovl_inode_init(inode, upperdentry, lowerdentry);
+
+ if (upperdentry && ovl_is_impuredir(upperdentry))
+ ovl_set_flag(OVL_IMPURE, inode);
+
if (inode->i_state & I_NEW)
unlock_new_inode(inode);
out:
unsigned int ctr = 0;
struct inode *inode = NULL;
bool upperopaque = false;
- bool upperimpure = false;
char *upperredirect = NULL;
struct dentry *this;
unsigned int i;
poe = roe;
}
upperopaque = d.opaque;
- if (upperdentry && d.is_dir)
- upperimpure = ovl_is_impuredir(upperdentry);
}
if (!d.stop && poe->numlower) {
goto out_put;
oe->opaque = upperopaque;
- oe->impure = upperimpure;
memcpy(oe->lowerstack, stack, sizeof(struct path) * ctr);
dentry->d_fsdata = oe;
#define OVL_XATTR_ORIGIN OVL_XATTR_PREFIX "origin"
#define OVL_XATTR_IMPURE OVL_XATTR_PREFIX "impure"
+enum ovl_flag {
+ OVL_IMPURE,
+};
+
/*
* The tuple (fh,uuid) is a universal unique identifier for a copy up origin,
* where:
struct ovl_dir_cache *ovl_dir_cache(struct dentry *dentry);
void ovl_set_dir_cache(struct dentry *dentry, struct ovl_dir_cache *cache);
bool ovl_dentry_is_opaque(struct dentry *dentry);
-bool ovl_dentry_is_impure(struct dentry *dentry);
bool ovl_dentry_is_whiteout(struct dentry *dentry);
void ovl_dentry_set_opaque(struct dentry *dentry);
bool ovl_redirect_dir(struct super_block *sb);
const char *name, const void *value, size_t size,
int xerr);
int ovl_set_impure(struct dentry *dentry, struct dentry *upperdentry);
+void ovl_set_flag(unsigned long flag, struct inode *inode);
+bool ovl_test_flag(unsigned long flag, struct inode *inode);
static inline bool ovl_is_impuredir(struct dentry *dentry)
{
struct {
u64 version;
bool opaque;
- bool impure;
bool copying;
};
struct rcu_head rcu;
struct ovl_inode {
const char *redirect;
+ unsigned long flags;
struct inode vfs_inode;
struct dentry *__upperdentry;
struct inode *lower;
struct ovl_inode *oi = kmem_cache_alloc(ovl_inode_cachep, GFP_KERNEL);
oi->redirect = NULL;
+ oi->flags = 0;
oi->__upperdentry = NULL;
oi->lower = NULL;
kfree(lowertmp);
if (upperpath.dentry) {
- oe->impure = ovl_is_impuredir(upperpath.dentry);
+ if (ovl_is_impuredir(upperpath.dentry))
+ ovl_set_flag(OVL_IMPURE, d_inode(root_dentry));
}
for (i = 0; i < numlower; i++) {
oe->lowerstack[i].dentry = stack[i].dentry;
return oe->opaque;
}
-bool ovl_dentry_is_impure(struct dentry *dentry)
-{
- struct ovl_entry *oe = dentry->d_fsdata;
-
- return oe->impure;
-}
-
bool ovl_dentry_is_whiteout(struct dentry *dentry)
{
return !dentry->d_inode && ovl_dentry_is_opaque(dentry);
int ovl_set_impure(struct dentry *dentry, struct dentry *upperdentry)
{
int err;
- struct ovl_entry *oe = dentry->d_fsdata;
- if (oe->impure)
+ if (ovl_test_flag(OVL_IMPURE, d_inode(dentry)))
return 0;
/*
err = ovl_check_setxattr(dentry, upperdentry, OVL_XATTR_IMPURE,
"y", 1, 0);
if (!err)
- oe->impure = true;
+ ovl_set_flag(OVL_IMPURE, d_inode(dentry));
return err;
}
+
+void ovl_set_flag(unsigned long flag, struct inode *inode)
+{
+ set_bit(flag, &OVL_I(inode)->flags);
+}
+
+bool ovl_test_flag(unsigned long flag, struct inode *inode)
+{
+ return test_bit(flag, &OVL_I(inode)->flags);
+}