All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeff Layton <jlayton@kernel.org>
To: Alexander Viro <viro@zeniv.linux.org.uk>,
	 Christian Brauner <brauner@kernel.org>, Jan Kara <jack@suse.cz>,
	 Chuck Lever <chuck.lever@oracle.com>,
	 Alexander Aring <alex.aring@gmail.com>,
	 Trond Myklebust <trond.myklebust@hammerspace.com>,
	 Anna Schumaker <anna@kernel.org>,
	Steve French <sfrench@samba.org>,
	 Paulo Alcantara <pc@manguebit.com>,
	 Ronnie Sahlberg <ronniesahlberg@gmail.com>,
	 Shyam Prasad N <sprasad@microsoft.com>,
	Tom Talpey <tom@talpey.com>,
	 Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	 "Rafael J. Wysocki" <rafael@kernel.org>,
	 David Howells <dhowells@redhat.com>,
	Tyler Hicks <code@tyhicks.com>,  Neil Brown <neilb@suse.de>,
	Olga Kornievskaia <kolga@netapp.com>,
	 Dai Ngo <Dai.Ngo@oracle.com>, Miklos Szeredi <miklos@szeredi.hu>,
	 Amir Goldstein <amir73il@gmail.com>,
	Namjae Jeon <linkinjeon@kernel.org>,
	 Sergey Senozhatsky <senozhatsky@chromium.org>,
	 "David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	 Jakub Kicinski <kuba@kernel.org>,
	Paolo Abeni <pabeni@redhat.com>
Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
	 linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org,
	 samba-technical@lists.samba.org, netfs@lists.linux.dev,
	 ecryptfs@vger.kernel.org, linux-unionfs@vger.kernel.org,
	 netdev@vger.kernel.org, Jeff Layton <jlayton@kernel.org>
Subject: [PATCH RFC 05/24] vfs: allow rmdir to wait for delegation break on parent
Date: Fri, 15 Mar 2024 12:52:56 -0400	[thread overview]
Message-ID: <20240315-dir-deleg-v1-5-a1d6209a3654@kernel.org> (raw)
In-Reply-To: <20240315-dir-deleg-v1-0-a1d6209a3654@kernel.org>

In order to add directory delegation support, we need to break
delegations on the parent whenever there is going to be a change in the
directory.

Add a new delegated_inode parameter to vfs_rmdir. Most callers will set
that to NULL, but do_rmdir can use that to wait for the delegation
break to complete and then retry.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 drivers/base/devtmpfs.c  |  2 +-
 fs/ecryptfs/inode.c      |  2 +-
 fs/namei.c               | 16 ++++++++++++++--
 fs/nfsd/nfs4recover.c    |  4 ++--
 fs/nfsd/vfs.c            |  2 +-
 fs/overlayfs/overlayfs.h |  2 +-
 fs/smb/server/vfs.c      |  4 ++--
 include/linux/fs.h       |  3 ++-
 8 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
index 8d1dbcad69f7..c00126796f79 100644
--- a/drivers/base/devtmpfs.c
+++ b/drivers/base/devtmpfs.c
@@ -248,7 +248,7 @@ static int dev_rmdir(const char *name)
 	if (d_really_is_positive(dentry)) {
 		if (d_inode(dentry)->i_private == &thread)
 			err = vfs_rmdir(&nop_mnt_idmap, d_inode(parent.dentry),
-					dentry);
+					dentry, NULL);
 		else
 			err = -EPERM;
 	} else {
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index d26b4484fa60..3d0cddbf037c 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -541,7 +541,7 @@ static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry)
 		if (d_unhashed(lower_dentry))
 			rc = -EINVAL;
 		else
-			rc = vfs_rmdir(&nop_mnt_idmap, lower_dir, lower_dentry);
+			rc = vfs_rmdir(&nop_mnt_idmap, lower_dir, lower_dentry, NULL);
 	}
 	if (!rc) {
 		clear_nlink(d_inode(dentry));
diff --git a/fs/namei.c b/fs/namei.c
index 6a22517f9938..f00d8d708001 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -4183,6 +4183,7 @@ SYSCALL_DEFINE2(mkdir, const char __user *, pathname, umode_t, mode)
  * @idmap:	idmap of the mount the inode was found from
  * @dir:	inode of @dentry
  * @dentry:	pointer to dentry of the base directory
+ * @delegated_inode: return pointer for delegated inode
  *
  * Remove a directory.
  *
@@ -4193,7 +4194,7 @@ SYSCALL_DEFINE2(mkdir, const char __user *, pathname, umode_t, mode)
  * raw inode simply pass @nop_mnt_idmap.
  */
 int vfs_rmdir(struct mnt_idmap *idmap, struct inode *dir,
-		     struct dentry *dentry)
+		     struct dentry *dentry, struct inode **delegated_inode)
 {
 	int error = may_delete(idmap, dir, dentry, 1);
 
@@ -4215,6 +4216,10 @@ int vfs_rmdir(struct mnt_idmap *idmap, struct inode *dir,
 	if (error)
 		goto out;
 
+	error = try_break_deleg(dir, delegated_inode);
+	if (error)
+		goto out;
+
 	error = dir->i_op->rmdir(dir, dentry);
 	if (error)
 		goto out;
@@ -4241,6 +4246,7 @@ int do_rmdir(int dfd, struct filename *name)
 	struct qstr last;
 	int type;
 	unsigned int lookup_flags = 0;
+	struct inode *delegated_inode = NULL;
 retry:
 	error = filename_parentat(dfd, name, lookup_flags, &path, &last, &type);
 	if (error)
@@ -4274,7 +4280,8 @@ int do_rmdir(int dfd, struct filename *name)
 	error = security_path_rmdir(&path, dentry);
 	if (error)
 		goto exit4;
-	error = vfs_rmdir(mnt_idmap(path.mnt), path.dentry->d_inode, dentry);
+	error = vfs_rmdir(mnt_idmap(path.mnt), path.dentry->d_inode,
+			  dentry, &delegated_inode);
 exit4:
 	dput(dentry);
 exit3:
@@ -4282,6 +4289,11 @@ int do_rmdir(int dfd, struct filename *name)
 	mnt_drop_write(path.mnt);
 exit2:
 	path_put(&path);
+	if (delegated_inode) {
+		error = break_deleg_wait(&delegated_inode);
+		if (!error)
+			goto retry;
+	}
 	if (retry_estale(error, lookup_flags)) {
 		lookup_flags |= LOOKUP_REVAL;
 		goto retry;
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 5bfced783a70..0e82f79471cf 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -354,7 +354,7 @@ nfsd4_unlink_clid_dir(char *name, int namlen, struct nfsd_net *nn)
 	status = -ENOENT;
 	if (d_really_is_negative(dentry))
 		goto out;
-	status = vfs_rmdir(&nop_mnt_idmap, d_inode(dir), dentry);
+	status = vfs_rmdir(&nop_mnt_idmap, d_inode(dir), dentry, NULL);
 out:
 	dput(dentry);
 out_unlock:
@@ -444,7 +444,7 @@ purge_old(struct dentry *parent, struct dentry *child, struct nfsd_net *nn)
 	if (nfs4_has_reclaimed_state(name, nn))
 		goto out_free;
 
-	status = vfs_rmdir(&nop_mnt_idmap, d_inode(parent), child);
+	status = vfs_rmdir(&nop_mnt_idmap, d_inode(parent), child, NULL);
 	if (status)
 		printk("failed to remove client recovery directory %pd\n",
 				child);
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index e42e58825590..34cc2d1a4944 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -2003,7 +2003,7 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
 				break;
 		}
 	} else {
-		host_err = vfs_rmdir(&nop_mnt_idmap, dirp, rdentry);
+		host_err = vfs_rmdir(&nop_mnt_idmap, dirp, rdentry, NULL);
 	}
 	fh_fill_post_attrs(fhp);
 
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
index baa371947f86..5b1f56294c4d 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -203,7 +203,7 @@ static inline int ovl_do_notify_change(struct ovl_fs *ofs,
 static inline int ovl_do_rmdir(struct ovl_fs *ofs,
 			       struct inode *dir, struct dentry *dentry)
 {
-	int err = vfs_rmdir(ovl_upper_mnt_idmap(ofs), dir, dentry);
+	int err = vfs_rmdir(ovl_upper_mnt_idmap(ofs), dir, dentry, NULL);
 
 	pr_debug("rmdir(%pd2) = %i\n", dentry, err);
 	return err;
diff --git a/fs/smb/server/vfs.c b/fs/smb/server/vfs.c
index 3760e0dda349..5b4e5876c2ac 100644
--- a/fs/smb/server/vfs.c
+++ b/fs/smb/server/vfs.c
@@ -611,7 +611,7 @@ int ksmbd_vfs_remove_file(struct ksmbd_work *work, const struct path *path)
 
 	idmap = mnt_idmap(path->mnt);
 	if (S_ISDIR(d_inode(path->dentry)->i_mode)) {
-		err = vfs_rmdir(idmap, d_inode(parent), path->dentry);
+		err = vfs_rmdir(idmap, d_inode(parent), path->dentry, NULL);
 		if (err && err != -ENOTEMPTY)
 			ksmbd_debug(VFS, "rmdir failed, err %d\n", err);
 	} else {
@@ -1084,7 +1084,7 @@ int ksmbd_vfs_unlink(struct file *filp)
 	dget(dentry);
 
 	if (S_ISDIR(d_inode(dentry)->i_mode))
-		err = vfs_rmdir(idmap, d_inode(dir), dentry);
+		err = vfs_rmdir(idmap, d_inode(dir), dentry, NULL);
 	else
 		err = vfs_unlink(idmap, d_inode(dir), dentry, NULL);
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 18eb7d628290..e72c825476de 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1846,7 +1846,8 @@ int vfs_symlink(struct mnt_idmap *, struct inode *,
 		struct dentry *, const char *);
 int vfs_link(struct dentry *, struct mnt_idmap *, struct inode *,
 	     struct dentry *, struct inode **);
-int vfs_rmdir(struct mnt_idmap *, struct inode *, struct dentry *);
+int vfs_rmdir(struct mnt_idmap *, struct inode *, struct dentry *,
+	       struct inode **);
 int vfs_unlink(struct mnt_idmap *, struct inode *, struct dentry *,
 	       struct inode **);
 

-- 
2.44.0


  parent reply	other threads:[~2024-03-15 16:53 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-15 16:52 [PATCH RFC 00/24] vfs, nfsd, nfs: implement directory delegations Jeff Layton
2024-03-15 16:52 ` [PATCH RFC 01/24] filelock: push the S_ISREG check down to ->setlease handlers Jeff Layton
2024-03-15 16:52 ` [PATCH RFC 02/24] filelock: add a lm_set_conflict lease_manager callback Jeff Layton
2024-03-17 14:56   ` Chuck Lever
2024-03-18 11:07     ` Jeff Layton
2024-03-20 13:13   ` Christian Brauner
2024-03-20 13:17     ` Jeff Layton
2024-03-15 16:52 ` [PATCH RFC 03/24] vfs: add try_break_deleg calls for parents to vfs_{link,rename,unlink} Jeff Layton
2024-03-16 23:57   ` Al Viro
2024-03-17 14:09     ` Jeff Layton
2024-03-15 16:52 ` [PATCH RFC 04/24] vfs: allow mkdir to wait for delegation break on parent Jeff Layton
2024-03-15 16:52 ` Jeff Layton [this message]
2024-03-15 16:52 ` [PATCH RFC 06/24] vfs: break parent dir delegations in open(..., O_CREAT) codepath Jeff Layton
2024-03-17  0:19   ` Al Viro
2024-03-17 12:23     ` Jeff Layton
2024-03-18  8:25   ` Stefan Metzmacher
2024-03-18 10:21     ` Jeff Layton
2024-03-15 16:52 ` [PATCH RFC 07/24] vfs: make vfs_create break delegations on parent directory Jeff Layton
2024-03-15 16:52 ` [PATCH RFC 08/24] vfs: make vfs_mknod " Jeff Layton
2024-03-20 13:42   ` Christian Brauner
2024-03-20 20:12     ` Jeff Layton
2024-03-22 14:13       ` Christian Brauner
2024-03-15 16:53 ` [PATCH RFC 09/24] filelock: lift the ban on directory leases in generic_setlease Jeff Layton
2024-03-15 16:53 ` [PATCH RFC 10/24] nfsd: allow filecache to hold S_IFDIR files Jeff Layton
2024-03-15 16:53 ` [PATCH RFC 11/24] nfsd: allow DELEGRETURN on directories Jeff Layton
2024-03-17 15:09   ` Chuck Lever
2024-03-17 16:03     ` Trond Myklebust
2024-03-18 11:22       ` Jeff Layton
2024-03-15 16:53 ` [PATCH RFC 12/24] nfsd: encoders and decoders for GET_DIR_DELEGATION Jeff Layton
2024-03-17 15:34   ` Chuck Lever
2024-03-18 16:12     ` Jeff Layton
2024-03-18 16:19       ` Chuck Lever
2024-03-15 16:53 ` [PATCH RFC 13/24] nfsd: check for delegation conflicts vs. the same client Jeff Layton
2024-03-15 16:53 ` [PATCH RFC 14/24] nfsd: wire up GET_DIR_DELEGATION handling Jeff Layton
2024-03-17 15:42   ` Chuck Lever
2024-03-15 16:53 ` [PATCH RFC 15/24] nfs: fix nfs_stateid_hash prototype when CONFIG_CRC32 isn't set Jeff Layton
2024-03-15 16:53 ` [PATCH RFC 16/24] nfs: remove unused NFS_CALL macro Jeff Layton
2024-03-15 16:53 ` [PATCH RFC 17/24] nfs: add cache_validity to the nfs_inode_event tracepoints Jeff Layton
2024-03-15 16:53 ` [PATCH RFC 18/24] nfs: add a tracepoint to nfs_inode_detach_delegation_locked Jeff Layton
2024-03-15 16:53 ` [PATCH RFC 19/24] nfs: new tracepoint in nfs_delegation_need_return Jeff Layton
2024-03-15 16:53 ` [PATCH RFC 20/24] nfs: new tracepoint in match_stateid operation Jeff Layton
2024-03-15 16:53 ` [PATCH RFC 21/24] nfs: add a GDD_GETATTR rpc operation Jeff Layton
2024-03-15 20:50   ` Anna Schumaker
2024-03-15 21:29     ` Jeff Layton
2024-03-15 16:53 ` [PATCH RFC 22/24] nfs: skip dentry revalidation when parent dir has a delegation Jeff Layton
2024-03-15 16:53 ` [PATCH RFC 23/24] nfs: optionally request a delegation on GETATTR Jeff Layton
2024-03-15 16:53 ` [PATCH RFC 24/24] nfs: add a module parameter to disable directory delegations Jeff Layton

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=20240315-dir-deleg-v1-5-a1d6209a3654@kernel.org \
    --to=jlayton@kernel.org \
    --cc=Dai.Ngo@oracle.com \
    --cc=alex.aring@gmail.com \
    --cc=amir73il@gmail.com \
    --cc=anna@kernel.org \
    --cc=brauner@kernel.org \
    --cc=chuck.lever@oracle.com \
    --cc=code@tyhicks.com \
    --cc=davem@davemloft.net \
    --cc=dhowells@redhat.com \
    --cc=ecryptfs@vger.kernel.org \
    --cc=edumazet@google.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=jack@suse.cz \
    --cc=kolga@netapp.com \
    --cc=kuba@kernel.org \
    --cc=linkinjeon@kernel.org \
    --cc=linux-cifs@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=linux-unionfs@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    --cc=neilb@suse.de \
    --cc=netdev@vger.kernel.org \
    --cc=netfs@lists.linux.dev \
    --cc=pabeni@redhat.com \
    --cc=pc@manguebit.com \
    --cc=rafael@kernel.org \
    --cc=ronniesahlberg@gmail.com \
    --cc=samba-technical@lists.samba.org \
    --cc=senozhatsky@chromium.org \
    --cc=sfrench@samba.org \
    --cc=sprasad@microsoft.com \
    --cc=tom@talpey.com \
    --cc=trond.myklebust@hammerspace.com \
    --cc=viro@zeniv.linux.org.uk \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.