ovl: store 'has_upper' and 'opaque' as bit flags

We need to make some room in struct ovl_entry to store information
about redirected ancestors for NFS export, so cram two booleans as
bit flags.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:
Amir Goldstein 2018-01-14 19:25:31 +02:00 committed by Miklos Szeredi
parent aa3ff3c152
commit c62520a83b
5 changed files with 41 additions and 20 deletions

View File

@ -957,10 +957,12 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
if (!oe)
goto out_put;
oe->opaque = upperopaque;
memcpy(oe->lowerstack, stack, sizeof(struct ovl_path) * ctr);
dentry->d_fsdata = oe;
if (upperopaque)
ovl_dentry_set_opaque(dentry);
if (upperdentry)
ovl_dentry_set_upper_alias(dentry);
else if (index)
@ -1003,7 +1005,6 @@ out:
bool ovl_lower_positive(struct dentry *dentry)
{
struct ovl_entry *oe = dentry->d_fsdata;
struct ovl_entry *poe = dentry->d_parent->d_fsdata;
const struct qstr *name = &dentry->d_name;
const struct cred *old_cred;
@ -1016,7 +1017,7 @@ bool ovl_lower_positive(struct dentry *dentry)
* whiteout.
*/
if (!dentry->d_inode)
return oe->opaque;
return ovl_dentry_is_opaque(dentry);
/* Negative upper -> positive lower */
if (!ovl_dentry_upper(dentry))

View File

@ -29,7 +29,7 @@ enum ovl_path_type {
#define OVL_XATTR_NLINK OVL_XATTR_PREFIX "nlink"
#define OVL_XATTR_UPPER OVL_XATTR_PREFIX "upper"
enum ovl_flag {
enum ovl_inode_flag {
/* Pure upper dir that may contain non pure upper entries */
OVL_IMPURE,
/* Non-merge dir that may contain whiteout entries */
@ -37,6 +37,11 @@ enum ovl_flag {
OVL_INDEX,
};
enum ovl_entry_flag {
OVL_E_UPPER_ALIAS,
OVL_E_OPAQUE,
};
/*
* The tuple (fh,uuid) is a universal unique identifier for a copy up origin,
* where:
@ -213,6 +218,9 @@ struct inode *ovl_inode_lower(struct inode *inode);
struct inode *ovl_inode_real(struct inode *inode);
struct ovl_dir_cache *ovl_dir_cache(struct inode *inode);
void ovl_set_dir_cache(struct inode *inode, struct ovl_dir_cache *cache);
void ovl_dentry_set_flag(unsigned long flag, struct dentry *dentry);
void ovl_dentry_clear_flag(unsigned long flag, struct dentry *dentry);
bool ovl_dentry_test_flag(unsigned long flag, struct dentry *dentry);
bool ovl_dentry_is_opaque(struct dentry *dentry);
bool ovl_dentry_is_whiteout(struct dentry *dentry);
void ovl_dentry_set_opaque(struct dentry *dentry);

View File

@ -61,8 +61,7 @@ struct ovl_fs {
struct ovl_entry {
union {
struct {
unsigned long has_upper;
bool opaque;
unsigned long flags;
};
struct rcu_head rcu;
};
@ -72,6 +71,11 @@ struct ovl_entry {
struct ovl_entry *ovl_alloc_entry(unsigned int numlower);
static inline struct ovl_entry *OVL_E(struct dentry *dentry)
{
return (struct ovl_entry *) dentry->d_fsdata;
}
struct ovl_inode {
struct ovl_dir_cache *cache;
const char *redirect;

View File

@ -1345,15 +1345,15 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
if (!root_dentry)
goto out_free_oe;
root_dentry->d_fsdata = oe;
mntput(upperpath.mnt);
if (upperpath.dentry) {
oe->has_upper = true;
ovl_dentry_set_upper_alias(root_dentry);
if (ovl_is_impuredir(upperpath.dentry))
ovl_set_flag(OVL_IMPURE, d_inode(root_dentry));
}
root_dentry->d_fsdata = oe;
/* Root is always merge -> can have whiteouts */
ovl_set_flag(OVL_WHITEOUTS, d_inode(root_dentry));
ovl_inode_init(d_inode(root_dentry), upperpath.dentry,

View File

@ -210,10 +210,24 @@ void ovl_set_dir_cache(struct inode *inode, struct ovl_dir_cache *cache)
OVL_I(inode)->cache = cache;
}
void ovl_dentry_set_flag(unsigned long flag, struct dentry *dentry)
{
set_bit(flag, &OVL_E(dentry)->flags);
}
void ovl_dentry_clear_flag(unsigned long flag, struct dentry *dentry)
{
clear_bit(flag, &OVL_E(dentry)->flags);
}
bool ovl_dentry_test_flag(unsigned long flag, struct dentry *dentry)
{
return test_bit(flag, &OVL_E(dentry)->flags);
}
bool ovl_dentry_is_opaque(struct dentry *dentry)
{
struct ovl_entry *oe = dentry->d_fsdata;
return oe->opaque;
return ovl_dentry_test_flag(OVL_E_OPAQUE, dentry);
}
bool ovl_dentry_is_whiteout(struct dentry *dentry)
@ -223,9 +237,7 @@ bool ovl_dentry_is_whiteout(struct dentry *dentry)
void ovl_dentry_set_opaque(struct dentry *dentry)
{
struct ovl_entry *oe = dentry->d_fsdata;
oe->opaque = true;
ovl_dentry_set_flag(OVL_E_OPAQUE, dentry);
}
/*
@ -236,16 +248,12 @@ void ovl_dentry_set_opaque(struct dentry *dentry)
*/
bool ovl_dentry_has_upper_alias(struct dentry *dentry)
{
struct ovl_entry *oe = dentry->d_fsdata;
return oe->has_upper;
return ovl_dentry_test_flag(OVL_E_UPPER_ALIAS, dentry);
}
void ovl_dentry_set_upper_alias(struct dentry *dentry)
{
struct ovl_entry *oe = dentry->d_fsdata;
oe->has_upper = true;
ovl_dentry_set_flag(OVL_E_UPPER_ALIAS, dentry);
}
bool ovl_redirect_dir(struct super_block *sb)