ceph: rename snapshot support
authorYan, Zheng <zyan@redhat.com>
Tue, 7 Apr 2015 07:36:32 +0000 (15:36 +0800)
committerIlya Dryomov <idryomov@gmail.com>
Wed, 22 Apr 2015 15:33:41 +0000 (18:33 +0300)
Signed-off-by: Yan, Zheng <zyan@redhat.com>
fs/ceph/dir.c
fs/ceph/strings.c
include/linux/ceph/ceph_fs.h

index 98c71e895e81f73823318ef26c08918072a4b1b1..e729b79812b4eb60bc02d55be0489e9c32f47297 100644 (file)
@@ -947,16 +947,20 @@ static int ceph_rename(struct inode *old_dir, struct dentry *old_dentry,
        struct ceph_fs_client *fsc = ceph_sb_to_client(old_dir->i_sb);
        struct ceph_mds_client *mdsc = fsc->mdsc;
        struct ceph_mds_request *req;
+       int op = CEPH_MDS_OP_RENAME;
        int err;
 
        if (ceph_snap(old_dir) != ceph_snap(new_dir))
                return -EXDEV;
-       if (ceph_snap(old_dir) != CEPH_NOSNAP ||
-           ceph_snap(new_dir) != CEPH_NOSNAP)
-               return -EROFS;
+       if (ceph_snap(old_dir) != CEPH_NOSNAP) {
+               if (old_dir == new_dir && ceph_snap(old_dir) == CEPH_SNAPDIR)
+                       op = CEPH_MDS_OP_RENAMESNAP;
+               else
+                       return -EROFS;
+       }
        dout("rename dir %p dentry %p to dir %p dentry %p\n",
             old_dir, old_dentry, new_dir, new_dentry);
-       req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_RENAME, USE_AUTH_MDS);
+       req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS);
        if (IS_ERR(req))
                return PTR_ERR(req);
        ihold(old_dir);
@@ -1387,6 +1391,7 @@ const struct inode_operations ceph_snapdir_iops = {
        .getattr = ceph_getattr,
        .mkdir = ceph_mkdir,
        .rmdir = ceph_unlink,
+       .rename = ceph_rename,
 };
 
 const struct dentry_operations ceph_dentry_ops = {
index 51cc23e4811147ad537fdc0d49ffb2f07bcc9dcf..89e6bc321df30fba6ef2555d4c376cd474d50366 100644 (file)
@@ -75,6 +75,7 @@ const char *ceph_mds_op_name(int op)
        case CEPH_MDS_OP_LSSNAP: return "lssnap";
        case CEPH_MDS_OP_MKSNAP: return "mksnap";
        case CEPH_MDS_OP_RMSNAP: return "rmsnap";
+       case CEPH_MDS_OP_RENAMESNAP: return "renamesnap";
        case CEPH_MDS_OP_SETFILELOCK: return "setfilelock";
        case CEPH_MDS_OP_GETFILELOCK: return "getfilelock";
        }
index 31eb03d0c7662dddd02fb126a24bc4198ffc65d8..d7d072a25c2717734139e98b01dd2724f2c43844 100644 (file)
@@ -323,6 +323,7 @@ enum {
        CEPH_MDS_OP_MKSNAP     = 0x01400,
        CEPH_MDS_OP_RMSNAP     = 0x01401,
        CEPH_MDS_OP_LSSNAP     = 0x00402,
+       CEPH_MDS_OP_RENAMESNAP = 0x01403,
 };
 
 extern const char *ceph_mds_op_name(int op);