diff options
Diffstat (limited to 'fs/ceph/snap.c')
-rw-r--r-- | fs/ceph/snap.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c index 54b14de2e729..e26437191333 100644 --- a/fs/ceph/snap.c +++ b/fs/ceph/snap.c | |||
@@ -449,6 +449,15 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci) | |||
449 | spin_lock(&inode->i_lock); | 449 | spin_lock(&inode->i_lock); |
450 | used = __ceph_caps_used(ci); | 450 | used = __ceph_caps_used(ci); |
451 | dirty = __ceph_caps_dirty(ci); | 451 | dirty = __ceph_caps_dirty(ci); |
452 | |||
453 | /* | ||
454 | * If there is a write in progress, treat that as a dirty Fw, | ||
455 | * even though it hasn't completed yet; by the time we finish | ||
456 | * up this capsnap it will be. | ||
457 | */ | ||
458 | if (used & CEPH_CAP_FILE_WR) | ||
459 | dirty |= CEPH_CAP_FILE_WR; | ||
460 | |||
452 | if (__ceph_have_pending_cap_snap(ci)) { | 461 | if (__ceph_have_pending_cap_snap(ci)) { |
453 | /* there is no point in queuing multiple "pending" cap_snaps, | 462 | /* there is no point in queuing multiple "pending" cap_snaps, |
454 | as no new writes are allowed to start when pending, so any | 463 | as no new writes are allowed to start when pending, so any |
@@ -456,13 +465,19 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci) | |||
456 | cap_snap. lucky us. */ | 465 | cap_snap. lucky us. */ |
457 | dout("queue_cap_snap %p already pending\n", inode); | 466 | dout("queue_cap_snap %p already pending\n", inode); |
458 | kfree(capsnap); | 467 | kfree(capsnap); |
459 | } else if (ci->i_wrbuffer_ref_head || (used & CEPH_CAP_FILE_WR) || | 468 | } else if (dirty & (CEPH_CAP_AUTH_EXCL|CEPH_CAP_XATTR_EXCL| |
460 | (dirty & (CEPH_CAP_AUTH_EXCL|CEPH_CAP_XATTR_EXCL| | 469 | CEPH_CAP_FILE_EXCL|CEPH_CAP_FILE_WR)) { |
461 | CEPH_CAP_FILE_EXCL|CEPH_CAP_FILE_WR))) { | ||
462 | struct ceph_snap_context *snapc = ci->i_head_snapc; | 470 | struct ceph_snap_context *snapc = ci->i_head_snapc; |
463 | 471 | ||
464 | dout("queue_cap_snap %p cap_snap %p queuing under %p\n", inode, | 472 | /* |
465 | capsnap, snapc); | 473 | * if we are a sync write, we may need to go to the snaprealm |
474 | * to get the current snapc. | ||
475 | */ | ||
476 | if (!snapc) | ||
477 | snapc = ci->i_snap_realm->cached_context; | ||
478 | |||
479 | dout("queue_cap_snap %p cap_snap %p queuing under %p %s\n", | ||
480 | inode, capsnap, snapc, ceph_cap_string(dirty)); | ||
466 | ihold(inode); | 481 | ihold(inode); |
467 | 482 | ||
468 | atomic_set(&capsnap->nref, 1); | 483 | atomic_set(&capsnap->nref, 1); |