aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/snap.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ceph/snap.c')
-rw-r--r--fs/ceph/snap.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c
index c1cc993225e3..f64576e72b79 100644
--- a/fs/ceph/snap.c
+++ b/fs/ceph/snap.c
@@ -288,6 +288,9 @@ static int cmpu64_rev(const void *a, const void *b)
288 return 0; 288 return 0;
289} 289}
290 290
291
292static struct ceph_snap_context *empty_snapc;
293
291/* 294/*
292 * build the snap context for a given realm. 295 * build the snap context for a given realm.
293 */ 296 */
@@ -328,6 +331,12 @@ static int build_snap_context(struct ceph_snap_realm *realm)
328 return 0; 331 return 0;
329 } 332 }
330 333
334 if (num == 0 && realm->seq == empty_snapc->seq) {
335 ceph_get_snap_context(empty_snapc);
336 snapc = empty_snapc;
337 goto done;
338 }
339
331 /* alloc new snap context */ 340 /* alloc new snap context */
332 err = -ENOMEM; 341 err = -ENOMEM;
333 if (num > (SIZE_MAX - sizeof(*snapc)) / sizeof(u64)) 342 if (num > (SIZE_MAX - sizeof(*snapc)) / sizeof(u64))
@@ -365,6 +374,7 @@ static int build_snap_context(struct ceph_snap_realm *realm)
365 realm->ino, realm, snapc, snapc->seq, 374 realm->ino, realm, snapc, snapc->seq,
366 (unsigned int) snapc->num_snaps); 375 (unsigned int) snapc->num_snaps);
367 376
377done:
368 ceph_put_snap_context(realm->cached_context); 378 ceph_put_snap_context(realm->cached_context);
369 realm->cached_context = snapc; 379 realm->cached_context = snapc;
370 return 0; 380 return 0;
@@ -465,6 +475,9 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci)
465 cap_snap. lucky us. */ 475 cap_snap. lucky us. */
466 dout("queue_cap_snap %p already pending\n", inode); 476 dout("queue_cap_snap %p already pending\n", inode);
467 kfree(capsnap); 477 kfree(capsnap);
478 } else if (ci->i_snap_realm->cached_context == empty_snapc) {
479 dout("queue_cap_snap %p empty snapc\n", inode);
480 kfree(capsnap);
468 } else if (dirty & (CEPH_CAP_AUTH_EXCL|CEPH_CAP_XATTR_EXCL| 481 } else if (dirty & (CEPH_CAP_AUTH_EXCL|CEPH_CAP_XATTR_EXCL|
469 CEPH_CAP_FILE_EXCL|CEPH_CAP_FILE_WR)) { 482 CEPH_CAP_FILE_EXCL|CEPH_CAP_FILE_WR)) {
470 struct ceph_snap_context *snapc = ci->i_head_snapc; 483 struct ceph_snap_context *snapc = ci->i_head_snapc;
@@ -925,5 +938,16 @@ out:
925 return; 938 return;
926} 939}
927 940
941int __init ceph_snap_init(void)
942{
943 empty_snapc = ceph_create_snap_context(0, GFP_NOFS);
944 if (!empty_snapc)
945 return -ENOMEM;
946 empty_snapc->seq = 1;
947 return 0;
948}
928 949
929 950void ceph_snap_exit(void)
951{
952 ceph_put_snap_context(empty_snapc);
953}