aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/snap.c
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2010-08-24 11:44:16 -0400
committerSage Weil <sage@newdream.net>2010-08-24 19:24:18 -0400
commit7d8cb26d7dcb911f110b7762bd5941e8f009d6c3 (patch)
tree2adf2f6303cc96ff14c951dc6966f68a0fc3cf25 /fs/ceph/snap.c
parent07a27e226d1ed210d2d4218bd0642b40f5405c6a (diff)
ceph: maintain i_head_snapc when any caps are dirty, not just for data
We used to use i_head_snapc to keep track of which snapc the current epoch of dirty data was dirtied under. It is used by queue_cap_snap to set up the cap_snap. However, since we queue cap snaps for any dirty caps, not just for dirty file data, we need to keep a valid i_head_snapc anytime we have dirty|flushing caps. This fixes a NULL pointer deref in queue_cap_snap when writing back dirty caps without data (e.g., snaptest-authwb.sh). Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs/ceph/snap.c')
-rw-r--r--fs/ceph/snap.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c
index 6bdbf3ae7082..4868b9dcac5a 100644
--- a/fs/ceph/snap.c
+++ b/fs/ceph/snap.c
@@ -458,6 +458,8 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci)
458 CEPH_CAP_FILE_EXCL|CEPH_CAP_FILE_WR))) { 458 CEPH_CAP_FILE_EXCL|CEPH_CAP_FILE_WR))) {
459 struct ceph_snap_context *snapc = ci->i_head_snapc; 459 struct ceph_snap_context *snapc = ci->i_head_snapc;
460 460
461 dout("queue_cap_snap %p cap_snap %p queuing under %p\n", inode,
462 capsnap, snapc);
461 igrab(inode); 463 igrab(inode);
462 464
463 atomic_set(&capsnap->nref, 1); 465 atomic_set(&capsnap->nref, 1);
@@ -489,7 +491,9 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci)
489 capsnap->dirty_pages = ci->i_wrbuffer_ref_head; 491 capsnap->dirty_pages = ci->i_wrbuffer_ref_head;
490 ci->i_wrbuffer_ref_head = 0; 492 ci->i_wrbuffer_ref_head = 0;
491 capsnap->context = snapc; 493 capsnap->context = snapc;
492 ci->i_head_snapc = NULL; 494 ci->i_head_snapc =
495 ceph_get_snap_context(ci->i_snap_realm->cached_context);
496 dout(" new snapc is %p\n", ci->i_head_snapc);
493 list_add_tail(&capsnap->ci_item, &ci->i_cap_snaps); 497 list_add_tail(&capsnap->ci_item, &ci->i_cap_snaps);
494 498
495 if (used & CEPH_CAP_FILE_WR) { 499 if (used & CEPH_CAP_FILE_WR) {