ovl: store 'has_upper' and 'opaque' as bit flags
authorAmir Goldstein <amir73il@gmail.com>
Sun, 14 Jan 2018 17:25:31 +0000 (19:25 +0200)
committerMiklos Szeredi <mszeredi@redhat.com>
Wed, 24 Jan 2018 10:25:58 +0000 (11:25 +0100)
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>
fs/overlayfs/namei.c
fs/overlayfs/overlayfs.h
fs/overlayfs/ovl_entry.h
fs/overlayfs/super.c
fs/overlayfs/util.c

index 9d3ccbd..ca15893 100644 (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))
index f9fce7a..2dddcd2 100644 (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);
index 6dd60fc..bfef6ed 100644 (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;
index 170c184..fccdcfa 100644 (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,
index 68541eb..930784a 100644 (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)