]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
client: implement ceph_dir_link
authorSage Weil <sage@newdream.net>
Mon, 17 Mar 2008 18:46:06 +0000 (11:46 -0700)
committerSage Weil <sage@newdream.net>
Mon, 17 Mar 2008 18:46:06 +0000 (11:46 -0700)
src/TODO
src/kernel/dir.c

index a86e35a3b850d16ab5fcbf552e94fb9642410e98..4df949f57560632f5ab0ff814073b20040d89592 100644 (file)
--- a/src/TODO
+++ b/src/TODO
@@ -10,7 +10,7 @@ code cleanup
 - fix ceph_lookup_open
 
 kernel client
-- some bugs
+- make sure link/unlink results reflected by inode/dentry cache  (let fill_trace do it?  invalidate?  do actual update?)
 - procfs/debugfs
   - adjust granular debug levels too
     - should we be using debugfs?
index daad8746877335d316a845a91a2a35e27ee6cc60..86c45b8a49bdff094702a68afb31cda875fca249 100644 (file)
@@ -412,6 +412,43 @@ static int ceph_dir_mkdir(struct inode *dir, struct dentry *dentry, int mode)
        return err;
 }
 
+static int ceph_dir_link(struct dentry *old_dentry, struct inode *dir,
+                        struct dentry *dentry)
+{
+       struct ceph_client *client = ceph_sb_to_client(dir->i_sb);
+       struct ceph_mds_client *mdsc = &client->mdsc;
+       struct ceph_mds_request *req;
+       char *oldpath, *path;
+       int oldpathlen, pathlen;
+       int err;
+
+       dout(5, "dir_link in dir %p old_dentry %p dentry %p\n", dir, 
+            old_dentry, dentry);
+       oldpath = ceph_build_dentry_path(old_dentry, &oldpathlen);
+       if (IS_ERR(oldpath))
+               return PTR_ERR(oldpath);
+       path = ceph_build_dentry_path(dentry, &pathlen);
+       if (IS_ERR(path)) {
+               kfree(oldpath);
+               return PTR_ERR(path);
+       }
+       req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LINK,
+                                      ceph_ino(dir->i_sb->s_root->d_inode),
+                                      path,
+                                      ceph_ino(dir->i_sb->s_root->d_inode),
+                                      oldpath);
+       kfree(oldpath);
+       kfree(path);
+       if (IS_ERR(req)) {
+               d_drop(dentry);
+               return PTR_ERR(req);
+       }
+       err = ceph_mdsc_do_request(mdsc, req);
+       ceph_mdsc_put_request(req);
+       if (err < 0)
+               d_drop(dentry);
+       return err;
+}
 
 static int ceph_dir_unlink(struct inode *dir, struct dentry *dentry)
 {
@@ -535,6 +572,7 @@ const struct inode_operations ceph_dir_iops = {
        .mknod = ceph_dir_mknod,
        .symlink = ceph_dir_symlink,
        .mkdir = ceph_dir_mkdir,
+       .link = ceph_dir_link,
        .unlink = ceph_dir_unlink,
        .rmdir = ceph_dir_unlink,
        .rename = ceph_dir_rename,