]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - fs/ceph/file.c
ceph: fix encoding of ino only (not relative) paths
[linux-2.6.git] / fs / ceph / file.c
index 6c90cf090601996653a033ed13d046ef92c9a4ac..45fbd69daabe97a7dbf93ffc4a4cc08042a087a4 100644 (file)
@@ -122,7 +122,7 @@ int ceph_open(struct inode *inode, struct file *file)
        struct ceph_mds_client *mdsc = fsc->mdsc;
        struct ceph_mds_request *req;
        struct ceph_file_info *cf = file->private_data;
-       struct inode *parent_inode = file->f_dentry->d_parent->d_inode;
+       struct inode *parent_inode = NULL;
        int err;
        int flags, fmode, wanted;
 
@@ -194,7 +194,10 @@ int ceph_open(struct inode *inode, struct file *file)
        req->r_inode = inode;
        ihold(inode);
        req->r_num_caps = 1;
+       if (flags & (O_CREAT|O_TRUNC))
+               parent_inode = ceph_get_dentry_parent_inode(file->f_dentry);
        err = ceph_mdsc_do_request(mdsc, parent_inode, req);
+       iput(parent_inode);
        if (!err)
                err = ceph_init_file(inode, file, req->r_fmode);
        ceph_mdsc_put_request(req);
@@ -222,9 +225,9 @@ struct dentry *ceph_lookup_open(struct inode *dir, struct dentry *dentry,
 {
        struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb);
        struct ceph_mds_client *mdsc = fsc->mdsc;
-       struct file *file = nd->intent.open.file;
-       struct inode *parent_inode = get_dentry_parent_inode(file->f_dentry);
+       struct file *file;
        struct ceph_mds_request *req;
+       struct dentry *ret;
        int err;
        int flags = nd->intent.open.flags - 1;  /* silly vfs! */
 
@@ -242,16 +245,24 @@ struct dentry *ceph_lookup_open(struct inode *dir, struct dentry *dentry,
                req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
        }
        req->r_locked_dir = dir;           /* caller holds dir->i_mutex */
-       err = ceph_mdsc_do_request(mdsc, parent_inode, req);
-       dentry = ceph_finish_lookup(req, dentry, err);
-       if (!err && (flags & O_CREAT) && !req->r_reply_info.head->is_dentry)
+       err = ceph_mdsc_do_request(mdsc,
+                                  (flags & (O_CREAT|O_TRUNC)) ? dir : NULL,
+                                  req);
+       err = ceph_handle_snapdir(req, dentry, err);
+       if (err)
+               goto out;
+       if ((flags & O_CREAT) && !req->r_reply_info.head->is_dentry)
                err = ceph_handle_notrace_create(dir, dentry);
-       if (!err)
-               err = ceph_init_file(req->r_dentry->d_inode, file,
-                                    req->r_fmode);
+       if (err)
+               goto out;
+       file = lookup_instantiate_filp(nd, req->r_dentry, ceph_open);
+       if (IS_ERR(file))
+               err = PTR_ERR(file);
+out:
+       ret = ceph_finish_lookup(req, dentry, err);
        ceph_mdsc_put_request(req);
-       dout("ceph_lookup_open result=%p\n", dentry);
-       return dentry;
+       dout("ceph_lookup_open result=%p\n", ret);
+       return ret;
 }
 
 int ceph_release(struct inode *inode, struct file *file)