aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nilfs2/cpfile.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/fs/nilfs2/cpfile.c b/fs/nilfs2/cpfile.c
index a4c9550fd774..50dff147744f 100644
--- a/fs/nilfs2/cpfile.c
+++ b/fs/nilfs2/cpfile.c
@@ -431,7 +431,7 @@ static ssize_t nilfs_cpfile_do_get_ssinfo(struct inode *cpfile, __u64 *cnop,
431 __u64 curr = *cnop, next; 431 __u64 curr = *cnop, next;
432 unsigned long curr_blkoff, next_blkoff; 432 unsigned long curr_blkoff, next_blkoff;
433 void *kaddr; 433 void *kaddr;
434 int n, ret; 434 int n = 0, ret;
435 435
436 down_read(&NILFS_MDT(cpfile)->mi_sem); 436 down_read(&NILFS_MDT(cpfile)->mi_sem);
437 437
@@ -455,27 +455,33 @@ static ssize_t nilfs_cpfile_do_get_ssinfo(struct inode *cpfile, __u64 *cnop,
455 455
456 curr_blkoff = nilfs_cpfile_get_blkoff(cpfile, curr); 456 curr_blkoff = nilfs_cpfile_get_blkoff(cpfile, curr);
457 ret = nilfs_cpfile_get_checkpoint_block(cpfile, curr, 0, &bh); 457 ret = nilfs_cpfile_get_checkpoint_block(cpfile, curr, 0, &bh);
458 if (ret < 0) 458 if (unlikely(ret < 0)) {
459 if (ret == -ENOENT)
460 ret = 0; /* No snapshots (started from a hole block) */
459 goto out; 461 goto out;
462 }
460 kaddr = kmap_atomic(bh->b_page, KM_USER0); 463 kaddr = kmap_atomic(bh->b_page, KM_USER0);
461 for (n = 0; n < nci; n++) { 464 while (n < nci) {
462 cp = nilfs_cpfile_block_get_checkpoint( 465 cp = nilfs_cpfile_block_get_checkpoint(cpfile, curr, bh, kaddr);
463 cpfile, curr, bh, kaddr); 466 curr = ~(__u64)0; /* Terminator */
464 nilfs_cpfile_checkpoint_to_cpinfo(cpfile, cp, &ci[n]); 467 if (unlikely(nilfs_checkpoint_invalid(cp) ||
465 next = le64_to_cpu(cp->cp_snapshot_list.ssl_next); 468 !nilfs_checkpoint_snapshot(cp)))
466 if (next == 0) {
467 curr = ~(__u64)0; /* Terminator */
468 n++;
469 break; 469 break;
470 } 470 nilfs_cpfile_checkpoint_to_cpinfo(cpfile, cp, &ci[n++]);
471 next = le64_to_cpu(cp->cp_snapshot_list.ssl_next);
472 if (next == 0)
473 break; /* reach end of the snapshot list */
474
471 next_blkoff = nilfs_cpfile_get_blkoff(cpfile, next); 475 next_blkoff = nilfs_cpfile_get_blkoff(cpfile, next);
472 if (curr_blkoff != next_blkoff) { 476 if (curr_blkoff != next_blkoff) {
473 kunmap_atomic(kaddr, KM_USER0); 477 kunmap_atomic(kaddr, KM_USER0);
474 brelse(bh); 478 brelse(bh);
475 ret = nilfs_cpfile_get_checkpoint_block(cpfile, next, 479 ret = nilfs_cpfile_get_checkpoint_block(cpfile, next,
476 0, &bh); 480 0, &bh);
477 if (ret < 0) 481 if (unlikely(ret < 0)) {
482 WARN_ON(ret == -ENOENT);
478 goto out; 483 goto out;
484 }
479 kaddr = kmap_atomic(bh->b_page, KM_USER0); 485 kaddr = kmap_atomic(bh->b_page, KM_USER0);
480 } 486 }
481 curr = next; 487 curr = next;