summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-01-09 16:34:32 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2012-01-09 16:36:12 -0500
commit3c5184ef1216dd476c9c67f22a199d90ac4d5892 (patch)
treef6bd6d77ee9d1260892c8e8589497eaa2f5efbab
parent94bf608a18fa4421315275a81c5489734599297a (diff)
downloadlinux-3.10-3c5184ef1216dd476c9c67f22a199d90ac4d5892.tar.gz
linux-3.10-3c5184ef1216dd476c9c67f22a199d90ac4d5892.tar.bz2
linux-3.10-3c5184ef1216dd476c9c67f22a199d90ac4d5892.zip
ceph: d_alloc_root() may fail
... and ceph_init_dentry(NULL) will oops Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/ceph/super.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/fs/ceph/super.c b/fs/ceph/super.c
index 11bd0fc4853..48f61a12af6 100644
--- a/fs/ceph/super.c
+++ b/fs/ceph/super.c
@@ -636,19 +636,26 @@ static struct dentry *open_root_dentry(struct ceph_fs_client *fsc,
req->r_num_caps = 2;
err = ceph_mdsc_do_request(mdsc, NULL, req);
if (err == 0) {
+ struct inode *inode = req->r_target_inode;
+ req->r_target_inode = NULL;
dout("open_root_inode success\n");
- if (ceph_ino(req->r_target_inode) == CEPH_INO_ROOT &&
+ if (ceph_ino(inode) == CEPH_INO_ROOT &&
fsc->sb->s_root == NULL) {
- root = d_alloc_root(req->r_target_inode);
+ root = d_alloc_root(inode);
+ if (!root) {
+ iput(inode);
+ root = ERR_PTR(-ENOMEM);
+ goto out;
+ }
ceph_init_dentry(root);
} else {
- root = d_obtain_alias(req->r_target_inode);
+ root = d_obtain_alias(inode);
}
- req->r_target_inode = NULL;
dout("open_root_inode success, root dentry is %p\n", root);
} else {
root = ERR_PTR(err);
}
+out:
ceph_mdsc_put_request(req);
return root;
}