Unified · Split
| @@ -947,16 +947,20 @@ static int ceph_rename(struct inode *old_dir, struct dentry *old_dentry, · 946 unmodified lines | ||
| 947 | 947 | struct ceph_fs_client *fsc = ceph_sb_to_client(old_dir->i_sb); |
| 948 | 948 | struct ceph_mds_client *mdsc = fsc->mdsc; |
| 949 | 949 | struct ceph_mds_request *req; |
| 950 | + int op = CEPH_MDS_OP_RENAME; | |
| 950 | 951 | int err; |
| 951 | 952 | |
| 952 | 953 | if (ceph_snap(old_dir) != ceph_snap(new_dir)) |
| 953 | 954 | return -EXDEV; |
| 954 | − if (ceph_snap(old_dir) != CEPH_NOSNAP || | |
| 955 | − ceph_snap(new_dir) != CEPH_NOSNAP) | |
| 956 | − return -EROFS; | |
| 955 | + if (ceph_snap(old_dir) != CEPH_NOSNAP) { | |
| 956 | + if (old_dir == new_dir && ceph_snap(old_dir) == CEPH_SNAPDIR) | |
| 957 | + op = CEPH_MDS_OP_RENAMESNAP; | |
| 958 | + else | |
| 959 | + return -EROFS; | |
| 960 | + } | |
| 957 | 961 | dout("rename dir %p dentry %p to dir %p dentry %p\n", |
| 958 | 962 | old_dir, old_dentry, new_dir, new_dentry); |
| 959 | − req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_RENAME, USE_AUTH_MDS); | |
| 963 | + req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS); | |
| 960 | 964 | if (IS_ERR(req)) |
| 961 | 965 | return PTR_ERR(req); |
| 962 | 966 | ihold(old_dir); |
| @@ -1387,6 +1391,7 @@ const struct inode_operations ceph_snapdir_iops = { · 424 unmodified lines | ||
| 1387 | 1391 | .getattr = ceph_getattr, |
| 1388 | 1392 | .mkdir = ceph_mkdir, |
| 1389 | 1393 | .rmdir = ceph_unlink, |
| 1394 | + .rename = ceph_rename, | |
| 1390 | 1395 | }; |
| 1391 | 1396 | |
| 1392 | 1397 | const struct dentry_operations ceph_dentry_ops = { |
| @@ -75,6 +75,7 @@ const char *ceph_mds_op_name(int op) · 74 unmodified lines | ||
| 75 | 75 | case CEPH_MDS_OP_LSSNAP: return "lssnap"; |
| 76 | 76 | case CEPH_MDS_OP_MKSNAP: return "mksnap"; |
| 77 | 77 | case CEPH_MDS_OP_RMSNAP: return "rmsnap"; |
| 78 | + case CEPH_MDS_OP_RENAMESNAP: return "renamesnap"; | |
| 78 | 79 | case CEPH_MDS_OP_SETFILELOCK: return "setfilelock"; |
| 79 | 80 | case CEPH_MDS_OP_GETFILELOCK: return "getfilelock"; |
| 80 | 81 | } |
| @@ -323,6 +323,7 @@ enum { · 322 unmodified lines | ||
| 323 | 323 | CEPH_MDS_OP_MKSNAP = 0x01400, |
| 324 | 324 | CEPH_MDS_OP_RMSNAP = 0x01401, |
| 325 | 325 | CEPH_MDS_OP_LSSNAP = 0x00402, |
| 326 | + CEPH_MDS_OP_RENAMESNAP = 0x01403, | |
| 326 | 327 | }; |
| 327 | 328 | |
| 328 | 329 | extern const char *ceph_mds_op_name(int op); |