From: Jens Axboe <axboe@kernel.dk>
To: linux-fsdevel@vger.kernel.org
Cc: torvalds@linux-foundation.org, viro@zeniv.linux.org.uk,
Jens Axboe <axboe@kernel.dk>
Subject: [PATCH 4/5] fs: honor LOOKUP_NONBLOCK for the last part of file open
Date: Sat, 12 Dec 2020 09:51:04 -0700 [thread overview]
Message-ID: <20201212165105.902688-5-axboe@kernel.dk> (raw)
In-Reply-To: <20201212165105.902688-1-axboe@kernel.dk>
We handle it for the path resolution itself, but we should also factor
it in for open_last_lookups() and tmpfile open.
We don't allow RESOLVE_NONBLOCK with O_TRUNC, so that case we can safely
ignore.
Signed-off-by: Jens Axboe <axboe@kernel.dk>
---
fs/namei.c | 39 +++++++++++++++++++++++++++++++++------
1 file changed, 33 insertions(+), 6 deletions(-)
diff --git a/fs/namei.c b/fs/namei.c
index 07a1aa874f65..1f976a213eef 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3127,6 +3127,7 @@ static const char *open_last_lookups(struct nameidata *nd,
struct dentry *dir = nd->path.dentry;
int open_flag = op->open_flag;
bool got_write = false;
+ bool nonblock = nd->flags & LOOKUP_NONBLOCK;
unsigned seq;
struct inode *inode;
struct dentry *dentry;
@@ -3164,17 +3165,38 @@ static const char *open_last_lookups(struct nameidata *nd,
}
if (open_flag & (O_CREAT | O_TRUNC | O_WRONLY | O_RDWR)) {
- got_write = !mnt_want_write(nd->path.mnt);
+ if (nonblock) {
+ got_write = !mnt_want_write_trylock(nd->path.mnt);
+ if (!got_write)
+ return ERR_PTR(-EAGAIN);
+ } else {
+ got_write = !mnt_want_write(nd->path.mnt);
+ }
/*
* do _not_ fail yet - we might not need that or fail with
* a different error; let lookup_open() decide; we'll be
* dropping this one anyway.
*/
}
- if (open_flag & O_CREAT)
- inode_lock(dir->d_inode);
- else
- inode_lock_shared(dir->d_inode);
+ if (open_flag & O_CREAT) {
+ if (nonblock) {
+ if (!inode_trylock(dir->d_inode)) {
+ dentry = ERR_PTR(-EAGAIN);
+ goto drop_write;
+ }
+ } else {
+ inode_lock(dir->d_inode);
+ }
+ } else {
+ if (nonblock) {
+ if (!inode_trylock_shared(dir->d_inode)) {
+ dentry = ERR_PTR(-EAGAIN);
+ goto drop_write;
+ }
+ } else {
+ inode_lock_shared(dir->d_inode);
+ }
+ }
dentry = lookup_open(nd, file, op, got_write);
if (!IS_ERR(dentry) && (file->f_mode & FMODE_CREATED))
fsnotify_create(dir->d_inode, dentry);
@@ -3183,6 +3205,7 @@ static const char *open_last_lookups(struct nameidata *nd,
else
inode_unlock_shared(dir->d_inode);
+drop_write:
if (got_write)
mnt_drop_write(nd->path.mnt);
@@ -3242,6 +3265,7 @@ static int do_open(struct nameidata *nd,
open_flag &= ~O_TRUNC;
acc_mode = 0;
} else if (d_is_reg(nd->path.dentry) && open_flag & O_TRUNC) {
+ WARN_ON_ONCE(nd->flags & LOOKUP_NONBLOCK);
error = mnt_want_write(nd->path.mnt);
if (error)
return error;
@@ -3311,7 +3335,10 @@ static int do_tmpfile(struct nameidata *nd, unsigned flags,
int error = path_lookupat(nd, flags | LOOKUP_DIRECTORY, &path);
if (unlikely(error))
return error;
- error = mnt_want_write(path.mnt);
+ if (flags & LOOKUP_NONBLOCK)
+ error = mnt_want_write_trylock(path.mnt);
+ else
+ error = mnt_want_write(path.mnt);
if (unlikely(error))
goto out;
child = vfs_tmpfile(path.dentry, op->mode, op->open_flag);
--
2.29.2
next prev parent reply other threads:[~2020-12-12 16:52 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-12 16:51 [PATCHSET RFC v2 0/5] fs: Support for LOOKUP_NONBLOCK / RESOLVE_NONBLOCK Jens Axboe
2020-12-12 16:51 ` [PATCH 1/5] fs: make unlazy_walk() error handling consistent Jens Axboe
2020-12-12 16:51 ` [PATCH 2/5] fs: add support for LOOKUP_NONBLOCK Jens Axboe
2020-12-12 16:51 ` [PATCH 3/5] fs: add mnt_want_write_trylock() Jens Axboe
2020-12-12 16:51 ` Jens Axboe [this message]
2020-12-12 17:25 ` [PATCH 4/5] fs: honor LOOKUP_NONBLOCK for the last part of file open Al Viro
2020-12-12 17:47 ` Jens Axboe
2020-12-12 18:57 ` Linus Torvalds
2020-12-12 21:25 ` Jens Axboe
2020-12-12 22:03 ` Linus Torvalds
2020-12-13 22:50 ` Dave Chinner
2020-12-14 0:45 ` Linus Torvalds
2020-12-14 1:52 ` Dave Chinner
2020-12-14 18:06 ` Linus Torvalds
2020-12-14 17:43 ` Jens Axboe
2020-12-12 16:51 ` [PATCH 5/5] fs: expose LOOKUP_NONBLOCK through openat2() RESOLVE_NONBLOCK Jens Axboe
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=20201212165105.902688-5-axboe@kernel.dk \
--to=axboe@kernel.dk \
--cc=linux-fsdevel@vger.kernel.org \
--cc=torvalds@linux-foundation.org \
--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.