From: Amir Goldstein <amir73il@gmail.com>
To: Miklos Szeredi <miklos@szeredi.hu>
Cc: Alexander Larsson <alexl@redhat.com>, linux-unionfs@vger.kernel.org
Subject: [PATCH v2 09/13] ovl: introduce data-only lower layers
Date: Thu, 27 Apr 2023 16:05:35 +0300 [thread overview]
Message-ID: <20230427130539.2798797-10-amir73il@gmail.com> (raw)
In-Reply-To: <20230427130539.2798797-1-amir73il@gmail.com>
Introduce the format lowerdir=lower1:lower2::lowerdata1:lowerdata2
where the lower layers on the right of the :: separator are not merged
into the overlayfs merge dirs.
The files in those layers are only meant to be accessible via absolute
redirect from metacopy files in lower layers. Following changes will
implement lookup in the data layers.
This feature was requested for composefs ostree use case, where the
lower data layer should only be accessiable via absolute redirects
from metacopy inodes.
The lower data layers are not required to a have a unique uuid or any
uuid at all, because they are never used to compose the overlayfs inode
st_ino/st_dev.
Reviewed-by: Alexander Larsson <alexl@redhat.com>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
Documentation/filesystems/overlayfs.rst | 36 +++++++++++++++++++
fs/overlayfs/namei.c | 2 +-
fs/overlayfs/ovl_entry.h | 9 +++++
fs/overlayfs/super.c | 46 +++++++++++++++++++++----
4 files changed, 85 insertions(+), 8 deletions(-)
diff --git a/Documentation/filesystems/overlayfs.rst b/Documentation/filesystems/overlayfs.rst
index 4c76fda07645..bc95343bafba 100644
--- a/Documentation/filesystems/overlayfs.rst
+++ b/Documentation/filesystems/overlayfs.rst
@@ -371,6 +371,42 @@ conflict with metacopy=on, and will result in an error.
[*] redirect_dir=follow only conflicts with metacopy=on if upperdir=... is
given.
+
+Data-only lower layers
+----------------------
+
+With "metacopy" feature enabled, an overlayfs regular file may be a composition
+of information from up to three different layers:
+
+ 1) metadata from a file in the upper layer
+
+ 2) st_ino and st_dev object identifier from a file in a lower layer
+
+ 3) data from a file in another lower layer (further below)
+
+The "lower data" file can be on any lower layer, except from the top most
+lower layer.
+
+Below the top most lower layer, any number of lower most layers may be defined
+as "data-only" lower layers, using the double colon ("::") separator.
+The double colon ("::") separator can only occur once and it must have a
+non-empty list of lower directory paths on the left and a non-empty
+list of "data-only" lower directory paths on the right.
+
+
+For example:
+
+ mount -t overlay overlay -olowerdir=/l1:/l2:/l3::/do1:/do2 /merged
+
+The paths of files in the "data-only" lower layers are not visible in the
+merged overlayfs directories and the metadata and st_ino/st_dev of files
+in the "data-only" lower layers are not visible in overlayfs inodes.
+
+Only the data of the files in the "data-only" lower layers may be visible
+when a "metacopy" file in one of the lower layers above it, has a "redirect"
+to the absolute path of the "lower data" file in the "data-only" lower layer.
+
+
Sharing and copying layers
--------------------------
diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c
index e2b3c8f6753a..6bb07e1c01ee 100644
--- a/fs/overlayfs/namei.c
+++ b/fs/overlayfs/namei.c
@@ -356,7 +356,7 @@ int ovl_check_origin_fh(struct ovl_fs *ofs, struct ovl_fh *fh, bool connected,
struct dentry *origin = NULL;
int i;
- for (i = 1; i < ofs->numlayer; i++) {
+ for (i = 1; i <= ovl_numlowerlayer(ofs); i++) {
/*
* If lower fs uuid is not unique among lower fs we cannot match
* fh->uuid to layer.
diff --git a/fs/overlayfs/ovl_entry.h b/fs/overlayfs/ovl_entry.h
index 548c93e030fc..93ff299da0dd 100644
--- a/fs/overlayfs/ovl_entry.h
+++ b/fs/overlayfs/ovl_entry.h
@@ -57,6 +57,8 @@ struct ovl_fs {
unsigned int numlayer;
/* Number of unique fs among layers including upper fs */
unsigned int numfs;
+ /* Number of data-only lower layers */
+ unsigned int numdatalayer;
const struct ovl_layer *layers;
struct ovl_sb *fs;
/* workbasedir is the path at workdir= mount option */
@@ -90,6 +92,13 @@ struct ovl_fs {
errseq_t errseq;
};
+
+/* Number of lower layers, not including data-only layers */
+static inline unsigned int ovl_numlowerlayer(struct ovl_fs *ofs)
+{
+ return ofs->numlayer - ofs->numdatalayer - 1;
+}
+
static inline struct vfsmount *ovl_upper_mnt(struct ovl_fs *ofs)
{
return ofs->layers[0].mnt;
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index 9b326b857ad6..988edb9e9d23 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -1576,6 +1576,16 @@ static int ovl_get_fsid(struct ovl_fs *ofs, const struct path *path)
return ofs->numfs++;
}
+/*
+ * The fsid after the last lower fsid is used for the data layers.
+ * It is a "null fs" with a null sb, null uuid, and no pseudo dev.
+ */
+static int ovl_get_data_fsid(struct ovl_fs *ofs)
+{
+ return ofs->numfs;
+}
+
+
static int ovl_get_layers(struct super_block *sb, struct ovl_fs *ofs,
struct path *stack, unsigned int numlower,
struct ovl_layer *layers)
@@ -1583,11 +1593,14 @@ static int ovl_get_layers(struct super_block *sb, struct ovl_fs *ofs,
int err;
unsigned int i;
- ofs->fs = kcalloc(numlower + 1, sizeof(struct ovl_sb), GFP_KERNEL);
+ ofs->fs = kcalloc(numlower + 2, sizeof(struct ovl_sb), GFP_KERNEL);
if (ofs->fs == NULL)
return -ENOMEM;
- /* idx/fsid 0 are reserved for upper fs even with lower only overlay */
+ /*
+ * idx/fsid 0 are reserved for upper fs even with lower only overlay
+ * and the last fsid is reserved for "null fs" of the data layers.
+ */
ofs->numfs++;
/*
@@ -1612,7 +1625,10 @@ static int ovl_get_layers(struct super_block *sb, struct ovl_fs *ofs,
struct inode *trap;
int fsid;
- fsid = ovl_get_fsid(ofs, &stack[i]);
+ if (i < numlower - ofs->numdatalayer)
+ fsid = ovl_get_fsid(ofs, &stack[i]);
+ else
+ fsid = ovl_get_data_fsid(ofs);
if (fsid < 0)
return fsid;
@@ -1700,6 +1716,7 @@ static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb,
int err;
struct path *stack = NULL;
struct ovl_path *lowerstack;
+ unsigned int numlowerdata = 0;
unsigned int i;
struct ovl_entry *oe;
@@ -1712,13 +1729,27 @@ static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb,
if (!stack)
return ERR_PTR(-ENOMEM);
- err = -EINVAL;
- for (i = 0; i < numlower; i++) {
+ for (i = 0; i < numlower;) {
err = ovl_lower_dir(lower, &stack[i], ofs, &sb->s_stack_depth);
if (err)
goto out_err;
lower = strchr(lower, '\0') + 1;
+
+ i++;
+ err = -EINVAL;
+ /* :: separator indicates the start of lower data layers */
+ if (!*lower && i < numlower && !numlowerdata) {
+ if (!ofs->config.metacopy) {
+ pr_err("lower data-only dirs require metacopy support.\n");
+ goto out_err;
+ }
+ lower++;
+ numlower--;
+ ofs->numdatalayer = numlowerdata = numlower - i;
+ pr_info("using the lowest %d of %d lowerdirs as data layers\n",
+ numlowerdata, numlower);
+ }
}
err = -EINVAL;
@@ -1733,12 +1764,13 @@ static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb,
goto out_err;
err = -ENOMEM;
- oe = ovl_alloc_entry(numlower);
+ /* Data-only layers are not merged in root directory */
+ oe = ovl_alloc_entry(numlower - numlowerdata);
if (!oe)
goto out_err;
lowerstack = ovl_lowerstack(oe);
- for (i = 0; i < numlower; i++) {
+ for (i = 0; i < numlower - numlowerdata; i++) {
lowerstack[i].dentry = dget(stack[i].dentry);
lowerstack[i].layer = &ofs->layers[i+1];
}
--
2.34.1
next prev parent reply other threads:[~2023-04-27 13:06 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-04-27 13:05 [PATCH v2 00/13] Overlayfs lazy lookup of lowerdata Amir Goldstein
2023-04-27 13:05 ` [PATCH v2 01/13] ovl: update of dentry revalidate flags after copy up Amir Goldstein
2023-04-27 13:05 ` [PATCH v2 02/13] ovl: use OVL_E() and OVL_E_FLAGS() accessors Amir Goldstein
2023-04-27 13:05 ` [PATCH v2 03/13] ovl: use ovl_numlower() and ovl_lowerstack() accessors Amir Goldstein
2023-04-27 13:05 ` [PATCH v2 04/13] ovl: factor out ovl_free_entry() and ovl_stack_*() helpers Amir Goldstein
2023-04-27 13:05 ` [PATCH v2 05/13] ovl: move ovl_entry into ovl_inode Amir Goldstein
2023-04-27 13:05 ` [PATCH v2 06/13] ovl: deduplicate lowerpath and lowerstack[] Amir Goldstein
2023-04-27 13:05 ` [PATCH v2 07/13] ovl: deduplicate lowerdata " Amir Goldstein
2023-04-27 13:05 ` [PATCH v2 08/13] ovl: remove unneeded goto instructions Amir Goldstein
2023-04-27 13:05 ` Amir Goldstein [this message]
2023-05-14 19:13 ` [PATCH v2 09/13] ovl: introduce data-only lower layers Amir Goldstein
2023-05-16 10:18 ` Amir Goldstein
2023-04-27 13:05 ` [PATCH v2 10/13] ovl: implement lookup in data-only layers Amir Goldstein
2023-04-27 13:05 ` [PATCH v2 11/13] ovl: prepare to store lowerdata redirect for lazy lowerdata lookup Amir Goldstein
2023-04-27 13:05 ` [PATCH v2 12/13] ovl: prepare for lazy lookup of lowerdata inode Amir Goldstein
2023-04-27 13:05 ` [PATCH v2 13/13] ovl: implement lazy lookup of lowerdata in data-only layers Amir Goldstein
2023-05-24 17:12 ` [PATCH v2 00/13] Overlayfs lazy lookup of lowerdata Amir Goldstein
2023-05-25 15:21 ` Alexander Larsson
2023-05-25 16:03 ` Amir Goldstein
2023-05-25 16:59 ` Giuseppe Scrivano
2023-05-25 17:27 ` Gao Xiang
2023-05-25 18:03 ` Gao Xiang
2023-05-26 5:12 ` Amir Goldstein
2023-05-26 11:36 ` Alexander Larsson
2023-05-26 18:27 ` Gao Xiang
2023-05-27 14:04 ` Amir Goldstein
2023-05-27 14:30 ` Gao Xiang
2023-05-29 7:22 ` Alexander Larsson
2023-05-30 14:08 ` Miklos Szeredi
2023-05-30 14:15 ` Amir Goldstein
2023-06-09 7:24 ` Miklos Szeredi
2023-06-09 10:54 ` Amir Goldstein
2023-06-09 13:42 ` Amir Goldstein
2023-06-09 13:52 ` Miklos Szeredi
2023-06-17 17:40 ` Amir Goldstein
2023-06-17 19:19 ` Miklos Szeredi
2023-05-30 16:19 ` Christian Brauner
2023-06-09 8:17 ` Alexander Larsson
2023-06-09 9:44 ` Christian Brauner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230427130539.2798797-10-amir73il@gmail.com \
--to=amir73il@gmail.com \
--cc=alexl@redhat.com \
--cc=linux-unionfs@vger.kernel.org \
--cc=miklos@szeredi.hu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox