kfree(newpath);
if (IS_ERR(req))
return PTR_ERR(req);
+ dget(old_dentry);
+ req->r_old_dentry = old_dentry;
+ dget(new_dentry);
+ req->r_last_dentry = new_dentry;
ceph_mdsc_lease_release(mdsc, old_dir, old_dentry,
CEPH_LOCK_DN|CEPH_LOCK_ICONTENT);
if (new_dentry->d_inode)
/* dentry */
ininfo = rinfo->trace_in[d+1].in;
- if (d == rinfo->trace_numd-1 &&
- req->r_last_dentry) {
+ if (d == rinfo->trace_numd-1 && req->r_last_dentry) {
dout(10, "fill_trace using provided dentry\n");
dn = req->r_last_dentry;
ceph_init_dentry(dn); /* just in case */
req->r_last_dentry = NULL;
+ if (req->r_old_dentry) {
+ dout(10, "fill_trace doing d_move %p -> %p\n",
+ req->r_old_dentry, dn);
+ d_move(req->r_old_dentry, dn);
+ }
} else {
dname.name = rinfo->trace_dname[d];
dname.len = rinfo->trace_dname_len[d];
ceph_init_dentry(dn);
}
}
- ceph_update_dentry_lease(dn, rinfo->trace_dlease[d],
- session, req->r_from_time);
+ if (dn->d_parent == parent)
+ ceph_update_dentry_lease(dn, rinfo->trace_dlease[d],
+ session, req->r_from_time);
/* inode */
if (d+1 == rinfo->trace_numi) {
dput(parent);
dout(10, "fill_trace done, last dn %p in %p\n", dn, in);
+ if (req->r_old_dentry)
+ dput(req->r_old_dentry);
if (req->r_last_dentry)
dput(req->r_last_dentry);
if (req->r_last_inode)
*/
struct ceph_mds_request {
__u64 r_tid;
- struct ceph_msg * r_request; /* original request */
- struct ceph_msg * r_reply;
+ struct ceph_msg *r_request; /* original request */
+ struct ceph_msg *r_reply;
struct ceph_mds_reply_info r_reply_info;
- struct inode * r_last_inode;
- struct dentry * r_last_dentry;
- int r_expects_cap;
+ struct inode *r_last_inode;
+ struct dentry *r_last_dentry;
+ struct dentry *r_old_dentry; /* for rename */
+ int r_expects_cap;
unsigned long r_from_time;
- struct ceph_inode_cap * r_cap;
- struct ceph_mds_session * r_session;
- struct ceph_mds_session * r_mds[2];
+ struct ceph_inode_cap *r_cap;
+ struct ceph_mds_session *r_session;
+ struct ceph_mds_session *r_mds[2];
int r_num_mds; /* items in r_mds */
int r_attempts; /* resend attempts */