summaryrefslogtreecommitdiff
path: root/fs/overlayfs
diff options
context:
space:
mode:
authorAmir Goldstein <amir73il@gmail.com>2018-01-18 13:14:55 +0200
committerMiklos Szeredi <mszeredi@redhat.com>2018-01-24 11:26:01 +0100
commitb305e8443f3a87e794927085106db7ebc99a4f74 (patch)
tree275ef00af6ebcff564cc7443389e913b6ec3fbee /fs/overlayfs
parent3985b70a3e3f58109dc6ae347eafe6e8610be41e (diff)
ovl: encode non-indexed upper file handles
We only need to encode origin if there is a chance that the same object was encoded pre copy up and then we need to stay consistent with the same encoding also after copy up. In case a non-pure upper is not indexed, then it was copied up before NFS export support was enabled. In that case, we don't need to worry about staying consistent with pre copy up encoding and we encode an upper file handle. This mitigates the problem that with no index, we cannot find an upper inode from origin inode, so we cannot decode a non-indexed upper from origin file handle. Signed-off-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'fs/overlayfs')
-rw-r--r--fs/overlayfs/export.c40
1 files changed, 35 insertions, 5 deletions
diff --git a/fs/overlayfs/export.c b/fs/overlayfs/export.c
index 09fbfa83eeff..862c368883c9 100644
--- a/fs/overlayfs/export.c
+++ b/fs/overlayfs/export.c
@@ -19,6 +19,40 @@
#include <linux/ratelimit.h>
#include "overlayfs.h"
+/*
+ * We only need to encode origin if there is a chance that the same object was
+ * encoded pre copy up and then we need to stay consistent with the same
+ * encoding also after copy up. If non-pure upper is not indexed, then it was
+ * copied up before NFS export was enabled. In that case we don't need to worry
+ * about staying consistent with pre copy up encoding and we encode an upper
+ * file handle. Overlay root dentry is a private case of non-indexed upper.
+ *
+ * The following table summarizes the different file handle encodings used for
+ * different overlay object types:
+ *
+ * Object type | Encoding
+ * --------------------------------
+ * Pure upper | U
+ * Non-indexed upper | U
+ * Indexed upper | L
+ * Non-upper | L
+ *
+ * U = upper file handle
+ * L = lower file handle
+ */
+static bool ovl_should_encode_origin(struct dentry *dentry)
+{
+ if (!ovl_dentry_lower(dentry))
+ return false;
+
+ /* Decoding a non-indexed upper from origin is not implemented */
+ if (ovl_dentry_upper(dentry) &&
+ !ovl_test_flag(OVL_INDEX, d_inode(dentry)))
+ return false;
+
+ return true;
+}
+
static int ovl_d_to_fh(struct dentry *dentry, char *buf, int buflen)
{
struct dentry *upper = ovl_dentry_upper(dentry);
@@ -26,11 +60,7 @@ static int ovl_d_to_fh(struct dentry *dentry, char *buf, int buflen)
struct ovl_fh *fh = NULL;
int err;
- /*
- * On overlay with an upper layer, overlay root inode is encoded as
- * an upper file handle, because upper root dir is not indexed.
- */
- if (dentry == dentry->d_sb->s_root && upper)
+ if (!ovl_should_encode_origin(dentry))
origin = NULL;
err = -EACCES;