Skip to content

Commit

Permalink
ovl: store 'has_upper' and 'opaque' as bit flags
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Amir Goldstein authored and Miklos Szeredi committed Jan 24, 2018
1 parent aa3ff3c commit c62520a
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 20 deletions.
7 changes: 4 additions & 3 deletions fs/overlayfs/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -1003,7 +1005,6 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,

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;
Expand All @@ -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))
Expand Down
10 changes: 9 additions & 1 deletion fs/overlayfs/overlayfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,19 @@ 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 */
OVL_WHITEOUTS,
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:
Expand Down Expand Up @@ -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);
Expand Down
8 changes: 6 additions & 2 deletions fs/overlayfs/ovl_entry.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand All @@ -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;
Expand Down
6 changes: 3 additions & 3 deletions fs/overlayfs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
30 changes: 19 additions & 11 deletions fs/overlayfs/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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);
}

/*
Expand All @@ -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)
Expand Down

0 comments on commit c62520a

Please sign in to comment.