diff options
Diffstat (limited to 'fs/ceph/snap.c')
-rw-r--r-- | fs/ceph/snap.c | 26 |
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 | |||
292 | static 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 | ||
377 | done: | ||
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 | ||
941 | int __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 | 950 | void ceph_snap_exit(void) | |
951 | { | ||
952 | ceph_put_snap_context(empty_snapc); | ||
953 | } | ||