mirror of
https://github.com/torvalds/linux.git
synced 2024-12-12 22:23:55 +00:00
ceph: preserve I_COMPLETE across rename
d_move puts the renamed dentry at the end of d_subdirs, screwing with our cached dentry directory offsets. We were just clearing I_COMPLETE to avoid any possibility of trouble. However, assigning the renamed dentry an offset at the end of the directory (to match it's new d_subdirs position) is sufficient to maintain correct behavior and hold onto I_COMPLETE. This is especially important for workloads like rsync, which renames files into place. Before, we would lose I_COMPLETE and do MDS lookups for each file. With this patch we only talk to the MDS on create and rename. Signed-off-by: Sage Weil <sage@newdream.net>
This commit is contained in:
parent
b09734b1f4
commit
09adc80c61
@ -1030,9 +1030,6 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
|
||||
dout("fill_trace doing d_move %p -> %p\n",
|
||||
req->r_old_dentry, dn);
|
||||
|
||||
/* d_move screws up d_subdirs order */
|
||||
ceph_i_clear(dir, CEPH_I_COMPLETE);
|
||||
|
||||
d_move(req->r_old_dentry, dn);
|
||||
dout(" src %p '%.*s' dst %p '%.*s'\n",
|
||||
req->r_old_dentry,
|
||||
@ -1044,12 +1041,15 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
|
||||
rehashing bug in vfs_rename_dir */
|
||||
ceph_invalidate_dentry_lease(dn);
|
||||
|
||||
/* take overwritten dentry's readdir offset */
|
||||
dout("dn %p gets %p offset %lld (old offset %lld)\n",
|
||||
req->r_old_dentry, dn, ceph_dentry(dn)->offset,
|
||||
/*
|
||||
* d_move() puts the renamed dentry at the end of
|
||||
* d_subdirs. We need to assign it an appropriate
|
||||
* directory offset so we can behave when holding
|
||||
* I_COMPLETE.
|
||||
*/
|
||||
ceph_set_dentry_offset(req->r_old_dentry);
|
||||
dout("dn %p gets new offset %lld\n", req->r_old_dentry,
|
||||
ceph_dentry(req->r_old_dentry)->offset);
|
||||
ceph_dentry(req->r_old_dentry)->offset =
|
||||
ceph_dentry(dn)->offset;
|
||||
|
||||
dn = req->r_old_dentry; /* use old_dentry */
|
||||
in = dn->d_inode;
|
||||
|
Loading…
Reference in New Issue
Block a user