aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--fs/ceph/caps.c2
-rw-r--r--fs/ceph/snap.c23
-rw-r--r--fs/ceph/super.h8
-rw-r--r--fs/ceph/xattr.c1
4 files changed, 23 insertions, 11 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 0ac2703f3bdf..ba5bbf318fe1 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -1282,7 +1282,7 @@ retry:
1282 &capsnap->mtime, &capsnap->atime, 1282 &capsnap->mtime, &capsnap->atime,
1283 capsnap->time_warp_seq, 1283 capsnap->time_warp_seq,
1284 capsnap->uid, capsnap->gid, capsnap->mode, 1284 capsnap->uid, capsnap->gid, capsnap->mode,
1285 0, NULL, 1285 capsnap->xattr_version, capsnap->xattr_blob,
1286 capsnap->follows); 1286 capsnap->follows);
1287 1287
1288 next_follows = capsnap->follows + 1; 1288 next_follows = capsnap->follows + 1;
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
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
index 2482d696f0de..b33929d8f287 100644
--- a/fs/ceph/super.h
+++ b/fs/ceph/super.h
@@ -216,8 +216,7 @@ struct ceph_cap_snap {
216 uid_t uid; 216 uid_t uid;
217 gid_t gid; 217 gid_t gid;
218 218
219 void *xattr_blob; 219 struct ceph_buffer *xattr_blob;
220 int xattr_len;
221 u64 xattr_version; 220 u64 xattr_version;
222 221
223 u64 size; 222 u64 size;
@@ -229,8 +228,11 @@ struct ceph_cap_snap {
229 228
230static inline void ceph_put_cap_snap(struct ceph_cap_snap *capsnap) 229static inline void ceph_put_cap_snap(struct ceph_cap_snap *capsnap)
231{ 230{
232 if (atomic_dec_and_test(&capsnap->nref)) 231 if (atomic_dec_and_test(&capsnap->nref)) {
232 if (capsnap->xattr_blob)
233 ceph_buffer_put(capsnap->xattr_blob);
233 kfree(capsnap); 234 kfree(capsnap);
235 }
234} 236}
235 237
236/* 238/*
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c
index 097a2654c00f..9578af610b73 100644
--- a/fs/ceph/xattr.c
+++ b/fs/ceph/xattr.c
@@ -485,6 +485,7 @@ void __ceph_build_xattrs_blob(struct ceph_inode_info *ci)
485 ci->i_xattrs.blob = ci->i_xattrs.prealloc_blob; 485 ci->i_xattrs.blob = ci->i_xattrs.prealloc_blob;
486 ci->i_xattrs.prealloc_blob = NULL; 486 ci->i_xattrs.prealloc_blob = NULL;
487 ci->i_xattrs.dirty = false; 487 ci->i_xattrs.dirty = false;
488 ci->i_xattrs.version++;
488 } 489 }
489} 490}
490 491