aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nilfs2/cpfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nilfs2/cpfile.c')
-rw-r--r--fs/nilfs2/cpfile.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/fs/nilfs2/cpfile.c b/fs/nilfs2/cpfile.c
index 82462acd06ee..a4c9550fd774 100644
--- a/fs/nilfs2/cpfile.c
+++ b/fs/nilfs2/cpfile.c
@@ -422,20 +422,20 @@ static ssize_t nilfs_cpfile_do_get_cpinfo(struct inode *cpfile, __u64 cno,
422 return ret; 422 return ret;
423} 423}
424 424
425static ssize_t nilfs_cpfile_do_get_ssinfo(struct inode *cpfile, __u64 cno, 425static ssize_t nilfs_cpfile_do_get_ssinfo(struct inode *cpfile, __u64 *cnop,
426 struct nilfs_cpinfo *ci, size_t nci) 426 struct nilfs_cpinfo *ci, size_t nci)
427{ 427{
428 struct buffer_head *bh; 428 struct buffer_head *bh;
429 struct nilfs_cpfile_header *header; 429 struct nilfs_cpfile_header *header;
430 struct nilfs_checkpoint *cp; 430 struct nilfs_checkpoint *cp;
431 __u64 curr, 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, ret;
435 435
436 down_read(&NILFS_MDT(cpfile)->mi_sem); 436 down_read(&NILFS_MDT(cpfile)->mi_sem);
437 437
438 if (cno == 0) { 438 if (curr == 0) {
439 ret = nilfs_cpfile_get_header_block(cpfile, &bh); 439 ret = nilfs_cpfile_get_header_block(cpfile, &bh);
440 if (ret < 0) 440 if (ret < 0)
441 goto out; 441 goto out;
@@ -448,8 +448,11 @@ static ssize_t nilfs_cpfile_do_get_ssinfo(struct inode *cpfile, __u64 cno,
448 ret = 0; 448 ret = 0;
449 goto out; 449 goto out;
450 } 450 }
451 } else 451 } else if (unlikely(curr == ~(__u64)0)) {
452 curr = cno; 452 ret = 0;
453 goto out;
454 }
455
453 curr_blkoff = nilfs_cpfile_get_blkoff(cpfile, curr); 456 curr_blkoff = nilfs_cpfile_get_blkoff(cpfile, curr);
454 ret = nilfs_cpfile_get_checkpoint_block(cpfile, curr, 0, &bh); 457 ret = nilfs_cpfile_get_checkpoint_block(cpfile, curr, 0, &bh);
455 if (ret < 0) 458 if (ret < 0)
@@ -461,7 +464,7 @@ static ssize_t nilfs_cpfile_do_get_ssinfo(struct inode *cpfile, __u64 cno,
461 nilfs_cpfile_checkpoint_to_cpinfo(cpfile, cp, &ci[n]); 464 nilfs_cpfile_checkpoint_to_cpinfo(cpfile, cp, &ci[n]);
462 next = le64_to_cpu(cp->cp_snapshot_list.ssl_next); 465 next = le64_to_cpu(cp->cp_snapshot_list.ssl_next);
463 if (next == 0) { 466 if (next == 0) {
464 curr = next; 467 curr = ~(__u64)0; /* Terminator */
465 n++; 468 n++;
466 break; 469 break;
467 } 470 }
@@ -480,6 +483,7 @@ static ssize_t nilfs_cpfile_do_get_ssinfo(struct inode *cpfile, __u64 cno,
480 } 483 }
481 kunmap_atomic(kaddr, KM_USER0); 484 kunmap_atomic(kaddr, KM_USER0);
482 brelse(bh); 485 brelse(bh);
486 *cnop = curr;
483 ret = n; 487 ret = n;
484 488
485 out: 489 out:
@@ -494,15 +498,15 @@ static ssize_t nilfs_cpfile_do_get_ssinfo(struct inode *cpfile, __u64 cno,
494 * @ci: 498 * @ci:
495 * @nci: 499 * @nci:
496 */ 500 */
497ssize_t nilfs_cpfile_get_cpinfo(struct inode *cpfile, 501
498 __u64 cno, int mode, 502ssize_t nilfs_cpfile_get_cpinfo(struct inode *cpfile, __u64 *cnop, int mode,
499 struct nilfs_cpinfo *ci, size_t nci) 503 struct nilfs_cpinfo *ci, size_t nci)
500{ 504{
501 switch (mode) { 505 switch (mode) {
502 case NILFS_CHECKPOINT: 506 case NILFS_CHECKPOINT:
503 return nilfs_cpfile_do_get_cpinfo(cpfile, cno, ci, nci); 507 return nilfs_cpfile_do_get_cpinfo(cpfile, *cnop, ci, nci);
504 case NILFS_SNAPSHOT: 508 case NILFS_SNAPSHOT:
505 return nilfs_cpfile_do_get_ssinfo(cpfile, cno, ci, nci); 509 return nilfs_cpfile_do_get_ssinfo(cpfile, cnop, ci, nci);
506 default: 510 default:
507 return -EINVAL; 511 return -EINVAL;
508 } 512 }