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 04/24] vfs: allow mkdir to wait for delegation break on parent
Date: Fri, 15 Mar 2024 12:52:55 -0400 [thread overview]
Message-ID: <20240315-dir-deleg-v1-4-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_mkdir. Most callers will set
that to NULL, but do_mkdirat 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/cachefiles/namei.c | 2 +-
fs/ecryptfs/inode.c | 2 +-
fs/init.c | 2 +-
fs/namei.c | 17 +++++++++++++----
fs/nfsd/nfs4recover.c | 2 +-
fs/nfsd/vfs.c | 2 +-
fs/overlayfs/overlayfs.h | 2 +-
fs/smb/server/vfs.c | 2 +-
include/linux/fs.h | 2 +-
10 files changed, 22 insertions(+), 13 deletions(-)
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
index b848764ef018..8d1dbcad69f7 100644
--- a/drivers/base/devtmpfs.c
+++ b/drivers/base/devtmpfs.c
@@ -166,7 +166,7 @@ static int dev_mkdir(const char *name, umode_t mode)
if (IS_ERR(dentry))
return PTR_ERR(dentry);
- err = vfs_mkdir(&nop_mnt_idmap, d_inode(path.dentry), dentry, mode);
+ err = vfs_mkdir(&nop_mnt_idmap, d_inode(path.dentry), dentry, mode, NULL);
if (!err)
/* mark as kernel-created inode */
d_inode(dentry)->i_private = &thread;
diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c
index 7ade836beb58..4e3e31320275 100644
--- a/fs/cachefiles/namei.c
+++ b/fs/cachefiles/namei.c
@@ -130,7 +130,7 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
goto mkdir_error;
ret = cachefiles_inject_write_error();
if (ret == 0)
- ret = vfs_mkdir(&nop_mnt_idmap, d_inode(dir), subdir, 0700);
+ ret = vfs_mkdir(&nop_mnt_idmap, d_inode(dir), subdir, 0700, NULL);
if (ret < 0) {
trace_cachefiles_vfs_error(NULL, d_inode(dir), ret,
cachefiles_trace_mkdir_error);
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index 5ed1e4cf6c0b..d26b4484fa60 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -513,7 +513,7 @@ static int ecryptfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
rc = lock_parent(dentry, &lower_dentry, &lower_dir);
if (!rc)
rc = vfs_mkdir(&nop_mnt_idmap, lower_dir,
- lower_dentry, mode);
+ lower_dentry, mode, NULL);
if (rc || d_really_is_negative(lower_dentry))
goto out;
rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb);
diff --git a/fs/init.c b/fs/init.c
index e9387b6c4f30..325c9e4d9b20 100644
--- a/fs/init.c
+++ b/fs/init.c
@@ -232,7 +232,7 @@ int __init init_mkdir(const char *pathname, umode_t mode)
error = security_path_mkdir(&path, dentry, mode);
if (!error)
error = vfs_mkdir(mnt_idmap(path.mnt), path.dentry->d_inode,
- dentry, mode);
+ dentry, mode, NULL);
done_path_create(&path, dentry);
return error;
}
diff --git a/fs/namei.c b/fs/namei.c
index 56d3ebed7bac..6a22517f9938 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -4103,7 +4103,7 @@ SYSCALL_DEFINE3(mknod, const char __user *, filename, umode_t, mode, unsigned, d
* raw inode simply pass @nop_mnt_idmap.
*/
int vfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
- struct dentry *dentry, umode_t mode)
+ struct dentry *dentry, umode_t mode, struct inode **delegated_inode)
{
int error;
unsigned max_links = dir->i_sb->s_max_links;
@@ -4123,6 +4123,10 @@ int vfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
if (max_links && dir->i_nlink >= max_links)
return -EMLINK;
+ error = try_break_deleg(dir, delegated_inode);
+ if (error)
+ return error;
+
error = dir->i_op->mkdir(idmap, dir, dentry, mode);
if (!error)
fsnotify_mkdir(dir, dentry);
@@ -4136,6 +4140,7 @@ int do_mkdirat(int dfd, struct filename *name, umode_t mode)
struct path path;
int error;
unsigned int lookup_flags = LOOKUP_DIRECTORY;
+ struct inode *delegated_inode = NULL;
retry:
dentry = filename_create(dfd, name, &path, lookup_flags);
@@ -4145,11 +4150,15 @@ int do_mkdirat(int dfd, struct filename *name, umode_t mode)
error = security_path_mkdir(&path, dentry,
mode_strip_umask(path.dentry->d_inode, mode));
- if (!error) {
+ if (!error)
error = vfs_mkdir(mnt_idmap(path.mnt), path.dentry->d_inode,
- dentry, mode);
- }
+ dentry, mode, &delegated_inode);
done_path_create(&path, dentry);
+ 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 2c060e0b1604..5bfced783a70 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -234,7 +234,7 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
* as well be forgiving and just succeed silently.
*/
goto out_put;
- status = vfs_mkdir(&nop_mnt_idmap, d_inode(dir), dentry, S_IRWXU);
+ status = vfs_mkdir(&nop_mnt_idmap, d_inode(dir), dentry, S_IRWXU, NULL);
out_put:
dput(dentry);
out_unlock:
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 6a4c506038e0..e42e58825590 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1496,7 +1496,7 @@ nfsd_create_locked(struct svc_rqst *rqstp, struct svc_fh *fhp,
nfsd_check_ignore_resizing(iap);
break;
case S_IFDIR:
- host_err = vfs_mkdir(&nop_mnt_idmap, dirp, dchild, iap->ia_mode);
+ host_err = vfs_mkdir(&nop_mnt_idmap, dirp, dchild, iap->ia_mode, NULL);
if (!host_err && unlikely(d_unhashed(dchild))) {
struct dentry *d;
d = lookup_one_len(dchild->d_name.name,
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
index ee949f3e7c77..baa371947f86 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -242,7 +242,7 @@ static inline int ovl_do_mkdir(struct ovl_fs *ofs,
struct inode *dir, struct dentry *dentry,
umode_t mode)
{
- int err = vfs_mkdir(ovl_upper_mnt_idmap(ofs), dir, dentry, mode);
+ int err = vfs_mkdir(ovl_upper_mnt_idmap(ofs), dir, dentry, mode, NULL);
pr_debug("mkdir(%pd2, 0%o) = %i\n", dentry, mode, err);
return err;
}
diff --git a/fs/smb/server/vfs.c b/fs/smb/server/vfs.c
index c487e834331a..3760e0dda349 100644
--- a/fs/smb/server/vfs.c
+++ b/fs/smb/server/vfs.c
@@ -227,7 +227,7 @@ int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode)
idmap = mnt_idmap(path.mnt);
mode |= S_IFDIR;
- err = vfs_mkdir(idmap, d_inode(path.dentry), dentry, mode);
+ err = vfs_mkdir(idmap, d_inode(path.dentry), dentry, mode, NULL);
if (!err && d_unhashed(dentry)) {
struct dentry *d;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 8dfcddafdb3d..18eb7d628290 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1839,7 +1839,7 @@ bool inode_owner_or_capable(struct mnt_idmap *idmap,
int vfs_create(struct mnt_idmap *, struct inode *,
struct dentry *, umode_t, bool);
int vfs_mkdir(struct mnt_idmap *, struct inode *,
- struct dentry *, umode_t);
+ struct dentry *, umode_t, struct inode **);
int vfs_mknod(struct mnt_idmap *, struct inode *, struct dentry *,
umode_t, dev_t);
int vfs_symlink(struct mnt_idmap *, struct inode *,
--
2.44.0
next prev 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 ` Jeff Layton [this message]
2024-03-15 16:52 ` [PATCH RFC 05/24] vfs: allow rmdir to wait for delegation break on parent Jeff Layton
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-4-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.