diff mbox

[2/6] ovl: check if upperdir fs supports O_TMPFILE

Message ID 1484488652-611-3-git-send-email-amir73il@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Amir Goldstein Jan. 15, 2017, 1:57 p.m. UTC
This is needed for choosing between concurrent copyup
using O_TMPFILE and legacy copyup using workdir+rename.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 fs/overlayfs/overlayfs.h |  9 +++++++++
 fs/overlayfs/ovl_entry.h |  1 +
 fs/overlayfs/super.c     | 10 ++++++++++
 fs/overlayfs/util.c      | 18 ++++++++++++++++++
 4 files changed, 38 insertions(+)

Comments

Miklos Szeredi Jan. 16, 2017, 2:02 p.m. UTC | #1
On Sun, Jan 15, 2017 at 2:57 PM, Amir Goldstein <amir73il@gmail.com> wrote:
> This is needed for choosing between concurrent copyup
> using O_TMPFILE and legacy copyup using workdir+rename.

I'm really wondering if we should constrain upper fs to those that:

 - can do RENAME_EXCHANGE and RENAME_WHITEOUT
 - can do ->tmpfile() which is currently a superset of the above
 - can do xattr, again a superset

The question is whether anybody actually using it with an fs that
doesn't have all of the above.  Because if so, we need to keep
supporting them.  Perhaps we should add warnings about deprecation and
if nobody complains we can remove support for non-conformant fs.

Thanks,
Miklos
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Amir Goldstein Jan. 16, 2017, 2:16 p.m. UTC | #2
On Mon, Jan 16, 2017 at 4:02 PM, Miklos Szeredi <miklos@szeredi.hu> wrote:
> On Sun, Jan 15, 2017 at 2:57 PM, Amir Goldstein <amir73il@gmail.com> wrote:
>> This is needed for choosing between concurrent copyup
>> using O_TMPFILE and legacy copyup using workdir+rename.
>
> I'm really wondering if we should constrain upper fs to those that:
>
>  - can do RENAME_EXCHANGE and RENAME_WHITEOUT
>  - can do ->tmpfile() which is currently a superset of the above
>  - can do xattr, again a superset

Makes sense to me.
Let me know if you want me to add the rename flag test.

>
> The question is whether anybody actually using it with an fs that
> doesn't have all of the above.  Because if so, we need to keep
> supporting them.  Perhaps we should add warnings about deprecation and
> if nobody complains we can remove support for non-conformant fs.
>


But how exactly do we "support" those fs right now?
Any attempt to use them would result in -EINVAL, because we will
bw requesting RENAME_EXCHANGE and RENAME_WHITEOUT
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Miklos Szeredi Jan. 16, 2017, 2:29 p.m. UTC | #3
On Mon, Jan 16, 2017 at 3:16 PM, Amir Goldstein <amir73il@gmail.com> wrote:
>> The question is whether anybody actually using it with an fs that
>> doesn't have all of the above.  Because if so, we need to keep
>> supporting them.  Perhaps we should add warnings about deprecation and
>> if nobody complains we can remove support for non-conformant fs.
>>
>
>
> But how exactly do we "support" those fs right now?
> Any attempt to use them would result in -EINVAL, because we will
> bw requesting RENAME_EXCHANGE and RENAME_WHITEOUT

Not unless whiteout/opaque objects are involved, and in fact those are
not very common, so I can imagine a limited usage that doesn't involve
those and will work fine.  But I don't think this scenario is likely,
so we should try deprecating it.

Thanks,
Miklos
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
index 8af450b..190b03f 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -127,6 +127,14 @@  static inline int ovl_do_whiteout(struct inode *dir, struct dentry *dentry)
 	return err;
 }
 
+static inline int ovl_do_tmpfile(struct inode *dir, struct dentry *dentry,
+				 umode_t mode)
+{
+	int err = vfs_tmpfile(dir, dentry, mode);
+	pr_debug("tmpfile(%pd2, 0%o) = %i\n", dentry, mode, err);
+	return err;
+}
+
 static inline struct inode *ovl_inode_real(struct inode *inode, bool *is_upper)
 {
 	unsigned long x = (unsigned long) READ_ONCE(inode->i_private);
@@ -169,6 +177,7 @@  void ovl_dentry_version_inc(struct dentry *dentry);
 u64 ovl_dentry_version_get(struct dentry *dentry);
 bool ovl_is_whiteout(struct dentry *dentry);
 struct file *ovl_path_open(struct path *path, int flags);
+struct dentry *ovl_alloc_tmpfile(struct dentry *parent, umode_t mode);
 
 /* namei.c */
 int ovl_path_next(int idx, struct dentry *dentry, struct path *path);
diff --git a/fs/overlayfs/ovl_entry.h b/fs/overlayfs/ovl_entry.h
index d14bca1..65f24000 100644
--- a/fs/overlayfs/ovl_entry.h
+++ b/fs/overlayfs/ovl_entry.h
@@ -27,6 +27,7 @@  struct ovl_fs {
 	struct ovl_config config;
 	/* creds of process who forced instantiation of super block */
 	const struct cred *creator_cred;
+	bool tmpfile;
 };
 
 /* private information held for every overlayfs dentry */
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index 20f48ab..a6c42f5 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -825,6 +825,8 @@  static int ovl_fill_super(struct super_block *sb, void *data, int silent)
 		 * creation of workdir in previous step.
 		 */
 		if (ufs->workdir) {
+			struct dentry *temp;
+
 			err = ovl_check_d_type_supported(&workpath);
 			if (err < 0)
 				goto out_put_workdir;
@@ -836,6 +838,14 @@  static int ovl_fill_super(struct super_block *sb, void *data, int silent)
 			 */
 			if (!err)
 				pr_warn("overlayfs: upper fs needs to support d_type.\n");
+
+			/* Check if upper/work fs supports O_TMPFILE */
+			temp = ovl_alloc_tmpfile(ufs->workdir, S_IFREG | 0);
+			ufs->tmpfile = !IS_ERR(temp);
+			if (ufs->tmpfile)
+				dput(temp);
+			else
+				pr_warn("overlayfs: upper fs does not support tmpfile.\n");
 		}
 	}
 
diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c
index 952286f..e6facb1 100644
--- a/fs/overlayfs/util.c
+++ b/fs/overlayfs/util.c
@@ -263,3 +263,21 @@  struct file *ovl_path_open(struct path *path, int flags)
 {
 	return dentry_open(path, flags | O_NOATIME, current_cred());
 }
+
+struct dentry *ovl_alloc_tmpfile(struct dentry *parent, umode_t mode)
+{
+	static const struct qstr name = QSTR_INIT("/", 1);
+	struct dentry *temp;
+	struct inode *dir = parent->d_inode;
+	int err;
+
+	temp = d_alloc(parent, &name);
+	if (unlikely(!temp))
+		return ERR_PTR(-ENOMEM);
+
+	err = ovl_do_tmpfile(dir, temp, mode);
+	if (unlikely(err))
+		return ERR_PTR(err);
+
+	return temp;
+}