]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
kclient: mkdir to mksnap
authorSage Weil <sage@newdream.net>
Mon, 11 Aug 2008 22:00:03 +0000 (15:00 -0700)
committerSage Weil <sage@newdream.net>
Mon, 11 Aug 2008 22:00:03 +0000 (15:00 -0700)
src/kernel/dir.c

index 82a0f649bac7743cbdae1d1225f58bebc623928b..2fc97595c08bc20a5a0e50db5ece9e27727ffc44 100644 (file)
@@ -483,6 +483,54 @@ static int ceph_symlink(struct inode *dir, struct dentry *dentry,
        return err;
 }
 
+static int ceph_mksnap(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;
+       struct ceph_mds_request_head *rhead;
+       char *path;
+       int pathlen;
+       u64 pathbase;
+       int err;
+       char *snap;
+       int snaplen;
+       struct dentry *dirdentry = d_find_alias(dir);
+
+       snaplen = dentry->d_name.len;
+       snap = kmalloc(snaplen + 1, GFP_NOFS);
+       memcpy(snap, dentry->d_name.name, snaplen);
+       snap[snaplen] = 0;
+
+       dout(5, "dir_mksnap in dir %p name '%s' dn %p\n", dir, snap, dentry);
+       path = ceph_build_dentry_path(dirdentry, &pathlen, &pathbase, 1);
+       if (IS_ERR(path))
+               return PTR_ERR(path);
+       req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_MKSNAP,
+                                      pathbase, path, 
+                                      0, snap,
+                                      dentry, USE_AUTH_MDS);
+       kfree(path);
+       if (IS_ERR(req)) {
+               dout(40, "d_drop %p\n", dentry);
+               d_drop(dentry);
+               return PTR_ERR(req);
+       }
+
+       dget(dentry);                /* to match put_request below */
+       req->r_last_dentry = dentry; /* use this dentry in fill_trace */
+       req->r_locked_dir = dir;
+       rhead = req->r_request->front.iov_base;
+       err = ceph_mdsc_do_request(mdsc, req);
+       ceph_mdsc_put_request(req);
+       if (err < 0) {
+               dout(40, "d_drop %p\n", dentry);
+               d_drop(dentry);
+       }
+       return err;
+
+}
+
 static int ceph_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 {
        struct ceph_client *client = ceph_sb_to_client(dir->i_sb);
@@ -494,6 +542,9 @@ static int ceph_mkdir(struct inode *dir, struct dentry *dentry, int mode)
        u64 pathbase;
        int err;
 
+       if (ceph_vino(dir).snap == CEPH_SNAPDIR)
+               return ceph_mksnap(dir, dentry);
+
        dout(5, "dir_mkdir in dir %p dentry %p mode 0%o\n", dir, dentry, mode);
        path = ceph_build_dentry_path(dentry, &pathlen, &pathbase, 1);
        if (IS_ERR(path))