diff options
author | Jeff Layton <jlayton@kernel.org> | 2021-03-01 08:01:54 -0500 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2021-04-27 23:52:23 +0200 |
commit | aa60cfc3f7ee32766766f71e6bfbea963b4f94bc (patch) | |
tree | eab5168f12d68b2371ace2eb91a5eea95e560d7d /fs/ceph/file.c | |
parent | d3c51ae1b8cce5bdaf91a1ce32b33cf5626075dc (diff) |
ceph: don't use d_add in ceph_handle_snapdir
It's possible ceph_get_snapdir could end up finding a (disconnected)
inode that already exists in the cache. Change the prototype for
ceph_handle_snapdir to return a dentry pointer and have it use
d_splice_alias so we don't end up with an aliased dentry in the cache.
Reported-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs/ceph/file.c')
-rw-r--r-- | fs/ceph/file.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 209535d5b8d3..a6ef1d143308 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -739,9 +739,12 @@ retry: err = ceph_mdsc_do_request(mdsc, (flags & (O_CREAT|O_TRUNC)) ? dir : NULL, req); - err = ceph_handle_snapdir(req, dentry, err); - if (err) + dentry = ceph_handle_snapdir(req, dentry, err); + if (IS_ERR(dentry)) { + err = PTR_ERR(dentry); goto out_req; + } + err = 0; if ((flags & O_CREAT) && !req->r_reply_info.head->is_dentry) err = ceph_handle_notrace_create(dir, dentry); |