aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/snap.c
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2010-08-22 18:03:56 -0400
committerSage Weil <sage@newdream.net>2010-08-22 18:16:46 -0400
commit4a625be47243e0e07dedd0a1a6b94c66c2ab93ba (patch)
tree4224efef4f83bcf629934d6da17d2c122b49ba5c /fs/ceph/snap.c
parent082afec92d1052305af1195f591602f4d0f44277 (diff)
ceph: include dirty xattrs state in snapped caps
When we snapshot dirty metadata that needs to be written back to the MDS, include dirty xattr metadata. Make the capsnap reference the encoded xattr blob so that it will be written back in the FLUSHSNAP op. Also fix the capsnap creation guard to include dirty auth or file bits, not just tests specific to dirty file data or file writes in progress (this fixes auth metadata writeback). Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs/ceph/snap.c')
-rw-r--r--fs/ceph/snap.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c
index c0b26b6badba..2cb190c2bd99 100644
--- a/fs/ceph/snap.c
+++ b/fs/ceph/snap.c
@@ -435,7 +435,7 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci)
435{ 435{
436 struct inode *inode = &ci->vfs_inode; 436 struct inode *inode = &ci->vfs_inode;
437 struct ceph_cap_snap *capsnap; 437 struct ceph_cap_snap *capsnap;
438 int used; 438 int used, dirty;
439 439
440 capsnap = kzalloc(sizeof(*capsnap), GFP_NOFS); 440 capsnap = kzalloc(sizeof(*capsnap), GFP_NOFS);
441 if (!capsnap) { 441 if (!capsnap) {
@@ -445,6 +445,7 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci)
445 445
446 spin_lock(&inode->i_lock); 446 spin_lock(&inode->i_lock);
447 used = __ceph_caps_used(ci); 447 used = __ceph_caps_used(ci);
448 dirty = __ceph_caps_dirty(ci);
448 if (__ceph_have_pending_cap_snap(ci)) { 449 if (__ceph_have_pending_cap_snap(ci)) {
449 /* there is no point in queuing multiple "pending" cap_snaps, 450 /* there is no point in queuing multiple "pending" cap_snaps,
450 as no new writes are allowed to start when pending, so any 451 as no new writes are allowed to start when pending, so any
@@ -452,11 +453,13 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci)
452 cap_snap. lucky us. */ 453 cap_snap. lucky us. */
453 dout("queue_cap_snap %p already pending\n", inode); 454 dout("queue_cap_snap %p already pending\n", inode);
454 kfree(capsnap); 455 kfree(capsnap);
455 } else if (ci->i_wrbuffer_ref_head || (used & CEPH_CAP_FILE_WR)) { 456 } else if (ci->i_wrbuffer_ref_head || (used & CEPH_CAP_FILE_WR) ||
457 (dirty & (CEPH_CAP_AUTH_EXCL|CEPH_CAP_XATTR_EXCL|
458 CEPH_CAP_FILE_EXCL|CEPH_CAP_FILE_WR))) {
456 struct ceph_snap_context *snapc = ci->i_head_snapc; 459 struct ceph_snap_context *snapc = ci->i_head_snapc;
457 460
458 igrab(inode); 461 igrab(inode);
459 462
460 atomic_set(&capsnap->nref, 1); 463 atomic_set(&capsnap->nref, 1);
461 capsnap->ci = ci; 464 capsnap->ci = ci;
462 INIT_LIST_HEAD(&capsnap->ci_item); 465 INIT_LIST_HEAD(&capsnap->ci_item);
@@ -464,15 +467,21 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci)
464 467
465 capsnap->follows = snapc->seq - 1; 468 capsnap->follows = snapc->seq - 1;
466 capsnap->issued = __ceph_caps_issued(ci, NULL); 469 capsnap->issued = __ceph_caps_issued(ci, NULL);
467 capsnap->dirty = __ceph_caps_dirty(ci); 470 capsnap->dirty = dirty;
468 471
469 capsnap->mode = inode->i_mode; 472 capsnap->mode = inode->i_mode;
470 capsnap->uid = inode->i_uid; 473 capsnap->uid = inode->i_uid;
471 capsnap->gid = inode->i_gid; 474 capsnap->gid = inode->i_gid;
472 475
473 /* fixme? */ 476 if (dirty & CEPH_CAP_XATTR_EXCL) {
474 capsnap->xattr_blob = NULL; 477 __ceph_build_xattrs_blob(ci);
475 capsnap->xattr_len = 0; 478 capsnap->xattr_blob =
479 ceph_buffer_get(ci->i_xattrs.blob);
480 capsnap->xattr_version = ci->i_xattrs.version;
481 } else {
482 capsnap->xattr_blob = NULL;
483 capsnap->xattr_version = 0;
484 }
476 485
477 /* dirty page count moved from _head to this cap_snap; 486 /* dirty page count moved from _head to this cap_snap;
478 all subsequent writes page dirties occur _after_ this 487 all subsequent writes page dirties occur _after_ this