Skip to content

Commit

Permalink
ceph: fix up error handling with snapdirs
Browse files Browse the repository at this point in the history
There are several warts in the snapdir error handling. The -EOPNOTSUPP
return in __snapfh_to_dentry is currently lost, and the call to
ceph_handle_snapdir is not currently checked at all.

Fix all of this up and eliminate a BUG_ON in ceph_get_snapdir. We can
handle that case with a warning and return an error.

Signed-off-by: Jeff Layton <[email protected]>
Signed-off-by: Al Viro <[email protected]>
  • Loading branch information
jtlayton authored and Al Viro committed Mar 8, 2021
1 parent 6e3e2c4 commit 3e10a15
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 5 deletions.
2 changes: 2 additions & 0 deletions fs/ceph/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,8 @@ int ceph_handle_snapdir(struct ceph_mds_request *req,
strcmp(dentry->d_name.name,
fsc->mount_options->snapdir_name) == 0) {
struct inode *inode = ceph_get_snapdir(parent);
if (IS_ERR(inode))
return PTR_ERR(inode);
dout("ENOENT on snapdir %p '%pd', linking to snapdir %p\n",
dentry, dentry, inode);
BUG_ON(!d_unhashed(dentry));
Expand Down
9 changes: 5 additions & 4 deletions fs/ceph/export.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,9 +248,10 @@ static struct dentry *__snapfh_to_dentry(struct super_block *sb,
ihold(inode);
} else {
/* mds does not support lookup snapped inode */
err = -EOPNOTSUPP;
inode = NULL;
inode = ERR_PTR(-EOPNOTSUPP);
}
} else {
inode = ERR_PTR(-ESTALE);
}
ceph_mdsc_put_request(req);

Expand All @@ -261,8 +262,8 @@ static struct dentry *__snapfh_to_dentry(struct super_block *sb,
dout("snapfh_to_dentry %llx.%llx parent %llx hash %x err=%d",
vino.ino, vino.snap, sfh->parent_ino, sfh->hash, err);
}
if (!inode)
return ERR_PTR(-ESTALE);
if (IS_ERR(inode))
return ERR_CAST(inode);
/* see comments in ceph_get_parent() */
return unlinked ? d_obtain_root(inode) : d_obtain_alias(inode);
}
Expand Down
14 changes: 13 additions & 1 deletion fs/ceph/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,21 @@ struct inode *ceph_get_snapdir(struct inode *parent)
struct inode *inode = ceph_get_inode(parent->i_sb, vino);
struct ceph_inode_info *ci = ceph_inode(inode);

BUG_ON(!S_ISDIR(parent->i_mode));
if (IS_ERR(inode))
return inode;

if (!S_ISDIR(parent->i_mode)) {
pr_warn_once("bad snapdir parent type (mode=0%o)\n",
parent->i_mode);
return ERR_PTR(-ENOTDIR);
}

if (!(inode->i_state & I_NEW) && !S_ISDIR(inode->i_mode)) {
pr_warn_once("bad snapdir inode type (mode=0%o)\n",
inode->i_mode);
return ERR_PTR(-ENOTDIR);
}

inode->i_mode = parent->i_mode;
inode->i_uid = parent->i_uid;
inode->i_gid = parent->i_gid;
Expand Down

0 comments on commit 3e10a15

Please sign in to comment.