ceph: fix error handling in ceph_atomic_open and ceph_lookup
Commitaa60cfc3f7
broke the error handling in these functions such that they don't handle non-ENOENT errors from ceph_mdsc_do_request properly. Move the checking of -ENOENT out of ceph_handle_snapdir and into the callers, and if we get a different error, return it immediately. Fixes:aa60cfc3f7
("ceph: don't use d_add in ceph_handle_snapdir") Signed-off-by: Jeff Layton <jlayton@kernel.org> Reviewed-by: Ilya Dryomov <idryomov@gmail.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
This commit is contained in:
parent
27171ae6a0
commit
7a971e2c07
@ -668,14 +668,13 @@ out:
|
||||
* Handle lookups for the hidden .snap directory.
|
||||
*/
|
||||
struct dentry *ceph_handle_snapdir(struct ceph_mds_request *req,
|
||||
struct dentry *dentry, int err)
|
||||
struct dentry *dentry)
|
||||
{
|
||||
struct ceph_fs_client *fsc = ceph_sb_to_client(dentry->d_sb);
|
||||
struct inode *parent = d_inode(dentry->d_parent); /* we hold i_mutex */
|
||||
|
||||
/* .snap dir? */
|
||||
if (err == -ENOENT &&
|
||||
ceph_snap(parent) == CEPH_NOSNAP &&
|
||||
if (ceph_snap(parent) == CEPH_NOSNAP &&
|
||||
strcmp(dentry->d_name.name, fsc->mount_options->snapdir_name) == 0) {
|
||||
struct dentry *res;
|
||||
struct inode *inode = ceph_get_snapdir(parent);
|
||||
@ -742,7 +741,6 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry,
|
||||
struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb);
|
||||
struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(dir->i_sb);
|
||||
struct ceph_mds_request *req;
|
||||
struct dentry *res;
|
||||
int op;
|
||||
int mask;
|
||||
int err;
|
||||
@ -793,12 +791,16 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry,
|
||||
req->r_parent = dir;
|
||||
set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
|
||||
err = ceph_mdsc_do_request(mdsc, NULL, req);
|
||||
res = ceph_handle_snapdir(req, dentry, err);
|
||||
if (IS_ERR(res)) {
|
||||
err = PTR_ERR(res);
|
||||
} else {
|
||||
dentry = res;
|
||||
err = 0;
|
||||
if (err == -ENOENT) {
|
||||
struct dentry *res;
|
||||
|
||||
res = ceph_handle_snapdir(req, dentry);
|
||||
if (IS_ERR(res)) {
|
||||
err = PTR_ERR(res);
|
||||
} else {
|
||||
dentry = res;
|
||||
err = 0;
|
||||
}
|
||||
}
|
||||
dentry = ceph_finish_lookup(req, dentry, err);
|
||||
ceph_mdsc_put_request(req); /* will dput(dentry) */
|
||||
|
@ -742,14 +742,16 @@ retry:
|
||||
err = ceph_mdsc_do_request(mdsc,
|
||||
(flags & (O_CREAT|O_TRUNC)) ? dir : NULL,
|
||||
req);
|
||||
dentry = ceph_handle_snapdir(req, dentry, err);
|
||||
if (IS_ERR(dentry)) {
|
||||
err = PTR_ERR(dentry);
|
||||
goto out_req;
|
||||
if (err == -ENOENT) {
|
||||
dentry = ceph_handle_snapdir(req, dentry);
|
||||
if (IS_ERR(dentry)) {
|
||||
err = PTR_ERR(dentry);
|
||||
goto out_req;
|
||||
}
|
||||
err = 0;
|
||||
}
|
||||
err = 0;
|
||||
|
||||
if ((flags & O_CREAT) && !req->r_reply_info.head->is_dentry)
|
||||
if (!err && (flags & O_CREAT) && !req->r_reply_info.head->is_dentry)
|
||||
err = ceph_handle_notrace_create(dir, dentry);
|
||||
|
||||
if (d_in_lookup(dentry)) {
|
||||
|
@ -1218,7 +1218,7 @@ extern const struct dentry_operations ceph_dentry_ops;
|
||||
extern loff_t ceph_make_fpos(unsigned high, unsigned off, bool hash_order);
|
||||
extern int ceph_handle_notrace_create(struct inode *dir, struct dentry *dentry);
|
||||
extern struct dentry *ceph_handle_snapdir(struct ceph_mds_request *req,
|
||||
struct dentry *dentry, int err);
|
||||
struct dentry *dentry);
|
||||
extern struct dentry *ceph_finish_lookup(struct ceph_mds_request *req,
|
||||
struct dentry *dentry, int err);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user