diff options
-rw-r--r-- | fs/nilfs2/cpfile.c | 33 | ||||
-rw-r--r-- | fs/nilfs2/cpfile.h | 4 | ||||
-rw-r--r-- | fs/nilfs2/dat.c | 21 | ||||
-rw-r--r-- | fs/nilfs2/dat.h | 2 | ||||
-rw-r--r-- | fs/nilfs2/ioctl.c | 9 | ||||
-rw-r--r-- | fs/nilfs2/sufile.c | 22 | ||||
-rw-r--r-- | fs/nilfs2/sufile.h | 2 |
7 files changed, 54 insertions, 39 deletions
diff --git a/fs/nilfs2/cpfile.c b/fs/nilfs2/cpfile.c index 300f1cdfa862..b5a8cd6b474f 100644 --- a/fs/nilfs2/cpfile.c +++ b/fs/nilfs2/cpfile.c | |||
@@ -384,9 +384,10 @@ static void nilfs_cpfile_checkpoint_to_cpinfo(struct inode *cpfile, | |||
384 | } | 384 | } |
385 | 385 | ||
386 | static ssize_t nilfs_cpfile_do_get_cpinfo(struct inode *cpfile, __u64 *cnop, | 386 | static ssize_t nilfs_cpfile_do_get_cpinfo(struct inode *cpfile, __u64 *cnop, |
387 | struct nilfs_cpinfo *ci, size_t nci) | 387 | void *buf, unsigned cisz, size_t nci) |
388 | { | 388 | { |
389 | struct nilfs_checkpoint *cp; | 389 | struct nilfs_checkpoint *cp; |
390 | struct nilfs_cpinfo *ci = buf; | ||
390 | struct buffer_head *bh; | 391 | struct buffer_head *bh; |
391 | size_t cpsz = NILFS_MDT(cpfile)->mi_entry_size; | 392 | size_t cpsz = NILFS_MDT(cpfile)->mi_entry_size; |
392 | __u64 cur_cno = nilfs_mdt_cno(cpfile), cno = *cnop; | 393 | __u64 cur_cno = nilfs_mdt_cno(cpfile), cno = *cnop; |
@@ -410,17 +411,22 @@ static ssize_t nilfs_cpfile_do_get_cpinfo(struct inode *cpfile, __u64 *cnop, | |||
410 | kaddr = kmap_atomic(bh->b_page, KM_USER0); | 411 | kaddr = kmap_atomic(bh->b_page, KM_USER0); |
411 | cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, bh, kaddr); | 412 | cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, bh, kaddr); |
412 | for (i = 0; i < ncps && n < nci; i++, cp = (void *)cp + cpsz) { | 413 | for (i = 0; i < ncps && n < nci; i++, cp = (void *)cp + cpsz) { |
413 | if (!nilfs_checkpoint_invalid(cp)) | 414 | if (!nilfs_checkpoint_invalid(cp)) { |
414 | nilfs_cpfile_checkpoint_to_cpinfo( | 415 | nilfs_cpfile_checkpoint_to_cpinfo(cpfile, cp, |
415 | cpfile, cp, &ci[n++]); | 416 | ci); |
417 | ci = (void *)ci + cisz; | ||
418 | n++; | ||
419 | } | ||
416 | } | 420 | } |
417 | kunmap_atomic(kaddr, KM_USER0); | 421 | kunmap_atomic(kaddr, KM_USER0); |
418 | brelse(bh); | 422 | brelse(bh); |
419 | } | 423 | } |
420 | 424 | ||
421 | ret = n; | 425 | ret = n; |
422 | if (n > 0) | 426 | if (n > 0) { |
423 | *cnop = ci[n - 1].ci_cno + 1; | 427 | ci = (void *)ci - cisz; |
428 | *cnop = ci->ci_cno + 1; | ||
429 | } | ||
424 | 430 | ||
425 | out: | 431 | out: |
426 | up_read(&NILFS_MDT(cpfile)->mi_sem); | 432 | up_read(&NILFS_MDT(cpfile)->mi_sem); |
@@ -428,11 +434,12 @@ static ssize_t nilfs_cpfile_do_get_cpinfo(struct inode *cpfile, __u64 *cnop, | |||
428 | } | 434 | } |
429 | 435 | ||
430 | static ssize_t nilfs_cpfile_do_get_ssinfo(struct inode *cpfile, __u64 *cnop, | 436 | static ssize_t nilfs_cpfile_do_get_ssinfo(struct inode *cpfile, __u64 *cnop, |
431 | struct nilfs_cpinfo *ci, size_t nci) | 437 | void *buf, unsigned cisz, size_t nci) |
432 | { | 438 | { |
433 | struct buffer_head *bh; | 439 | struct buffer_head *bh; |
434 | struct nilfs_cpfile_header *header; | 440 | struct nilfs_cpfile_header *header; |
435 | struct nilfs_checkpoint *cp; | 441 | struct nilfs_checkpoint *cp; |
442 | struct nilfs_cpinfo *ci = buf; | ||
436 | __u64 curr = *cnop, next; | 443 | __u64 curr = *cnop, next; |
437 | unsigned long curr_blkoff, next_blkoff; | 444 | unsigned long curr_blkoff, next_blkoff; |
438 | void *kaddr; | 445 | void *kaddr; |
@@ -472,7 +479,9 @@ static ssize_t nilfs_cpfile_do_get_ssinfo(struct inode *cpfile, __u64 *cnop, | |||
472 | if (unlikely(nilfs_checkpoint_invalid(cp) || | 479 | if (unlikely(nilfs_checkpoint_invalid(cp) || |
473 | !nilfs_checkpoint_snapshot(cp))) | 480 | !nilfs_checkpoint_snapshot(cp))) |
474 | break; | 481 | break; |
475 | nilfs_cpfile_checkpoint_to_cpinfo(cpfile, cp, &ci[n++]); | 482 | nilfs_cpfile_checkpoint_to_cpinfo(cpfile, cp, ci); |
483 | ci = (void *)ci + cisz; | ||
484 | n++; | ||
476 | next = le64_to_cpu(cp->cp_snapshot_list.ssl_next); | 485 | next = le64_to_cpu(cp->cp_snapshot_list.ssl_next); |
477 | if (next == 0) | 486 | if (next == 0) |
478 | break; /* reach end of the snapshot list */ | 487 | break; /* reach end of the snapshot list */ |
@@ -511,13 +520,13 @@ static ssize_t nilfs_cpfile_do_get_ssinfo(struct inode *cpfile, __u64 *cnop, | |||
511 | */ | 520 | */ |
512 | 521 | ||
513 | ssize_t nilfs_cpfile_get_cpinfo(struct inode *cpfile, __u64 *cnop, int mode, | 522 | ssize_t nilfs_cpfile_get_cpinfo(struct inode *cpfile, __u64 *cnop, int mode, |
514 | struct nilfs_cpinfo *ci, size_t nci) | 523 | void *buf, unsigned cisz, size_t nci) |
515 | { | 524 | { |
516 | switch (mode) { | 525 | switch (mode) { |
517 | case NILFS_CHECKPOINT: | 526 | case NILFS_CHECKPOINT: |
518 | return nilfs_cpfile_do_get_cpinfo(cpfile, cnop, ci, nci); | 527 | return nilfs_cpfile_do_get_cpinfo(cpfile, cnop, buf, cisz, nci); |
519 | case NILFS_SNAPSHOT: | 528 | case NILFS_SNAPSHOT: |
520 | return nilfs_cpfile_do_get_ssinfo(cpfile, cnop, ci, nci); | 529 | return nilfs_cpfile_do_get_ssinfo(cpfile, cnop, buf, cisz, nci); |
521 | default: | 530 | default: |
522 | return -EINVAL; | 531 | return -EINVAL; |
523 | } | 532 | } |
@@ -535,7 +544,7 @@ int nilfs_cpfile_delete_checkpoint(struct inode *cpfile, __u64 cno) | |||
535 | ssize_t nci; | 544 | ssize_t nci; |
536 | int ret; | 545 | int ret; |
537 | 546 | ||
538 | nci = nilfs_cpfile_do_get_cpinfo(cpfile, &tcno, &ci, 1); | 547 | nci = nilfs_cpfile_do_get_cpinfo(cpfile, &tcno, &ci, sizeof(ci), 1); |
539 | if (nci < 0) | 548 | if (nci < 0) |
540 | return nci; | 549 | return nci; |
541 | else if (nci == 0 || ci.ci_cno != cno) | 550 | else if (nci == 0 || ci.ci_cno != cno) |
diff --git a/fs/nilfs2/cpfile.h b/fs/nilfs2/cpfile.h index 1a8a1008c342..788a45950197 100644 --- a/fs/nilfs2/cpfile.h +++ b/fs/nilfs2/cpfile.h | |||
@@ -39,7 +39,7 @@ int nilfs_cpfile_delete_checkpoint(struct inode *, __u64); | |||
39 | int nilfs_cpfile_change_cpmode(struct inode *, __u64, int); | 39 | int nilfs_cpfile_change_cpmode(struct inode *, __u64, int); |
40 | int nilfs_cpfile_is_snapshot(struct inode *, __u64); | 40 | int nilfs_cpfile_is_snapshot(struct inode *, __u64); |
41 | int nilfs_cpfile_get_stat(struct inode *, struct nilfs_cpstat *); | 41 | int nilfs_cpfile_get_stat(struct inode *, struct nilfs_cpstat *); |
42 | ssize_t nilfs_cpfile_get_cpinfo(struct inode *, __u64 *, int, | 42 | ssize_t nilfs_cpfile_get_cpinfo(struct inode *, __u64 *, int, void *, unsigned, |
43 | struct nilfs_cpinfo *, size_t); | 43 | size_t); |
44 | 44 | ||
45 | #endif /* _NILFS_CPFILE_H */ | 45 | #endif /* _NILFS_CPFILE_H */ |
diff --git a/fs/nilfs2/dat.c b/fs/nilfs2/dat.c index 1827f62c772d..0b2710e2d565 100644 --- a/fs/nilfs2/dat.c +++ b/fs/nilfs2/dat.c | |||
@@ -376,36 +376,37 @@ int nilfs_dat_translate(struct inode *dat, __u64 vblocknr, sector_t *blocknrp) | |||
376 | return ret; | 376 | return ret; |
377 | } | 377 | } |
378 | 378 | ||
379 | ssize_t nilfs_dat_get_vinfo(struct inode *dat, struct nilfs_vinfo *vinfo, | 379 | ssize_t nilfs_dat_get_vinfo(struct inode *dat, void *buf, unsigned visz, |
380 | size_t nvi) | 380 | size_t nvi) |
381 | { | 381 | { |
382 | struct buffer_head *entry_bh; | 382 | struct buffer_head *entry_bh; |
383 | struct nilfs_dat_entry *entry; | 383 | struct nilfs_dat_entry *entry; |
384 | struct nilfs_vinfo *vinfo = buf; | ||
384 | __u64 first, last; | 385 | __u64 first, last; |
385 | void *kaddr; | 386 | void *kaddr; |
386 | unsigned long entries_per_block = NILFS_MDT(dat)->mi_entries_per_block; | 387 | unsigned long entries_per_block = NILFS_MDT(dat)->mi_entries_per_block; |
387 | int i, j, n, ret; | 388 | int i, j, n, ret; |
388 | 389 | ||
389 | for (i = 0; i < nvi; i += n) { | 390 | for (i = 0; i < nvi; i += n) { |
390 | ret = nilfs_palloc_get_entry_block(dat, vinfo[i].vi_vblocknr, | 391 | ret = nilfs_palloc_get_entry_block(dat, vinfo->vi_vblocknr, |
391 | 0, &entry_bh); | 392 | 0, &entry_bh); |
392 | if (ret < 0) | 393 | if (ret < 0) |
393 | return ret; | 394 | return ret; |
394 | kaddr = kmap_atomic(entry_bh->b_page, KM_USER0); | 395 | kaddr = kmap_atomic(entry_bh->b_page, KM_USER0); |
395 | /* last virtual block number in this block */ | 396 | /* last virtual block number in this block */ |
396 | first = vinfo[i].vi_vblocknr; | 397 | first = vinfo->vi_vblocknr; |
397 | do_div(first, entries_per_block); | 398 | do_div(first, entries_per_block); |
398 | first *= entries_per_block; | 399 | first *= entries_per_block; |
399 | last = first + entries_per_block - 1; | 400 | last = first + entries_per_block - 1; |
400 | for (j = i, n = 0; | 401 | for (j = i, n = 0; |
401 | j < nvi && vinfo[j].vi_vblocknr >= first && | 402 | j < nvi && vinfo->vi_vblocknr >= first && |
402 | vinfo[j].vi_vblocknr <= last; | 403 | vinfo->vi_vblocknr <= last; |
403 | j++, n++) { | 404 | j++, n++, vinfo = (void *)vinfo + visz) { |
404 | entry = nilfs_palloc_block_get_entry( | 405 | entry = nilfs_palloc_block_get_entry( |
405 | dat, vinfo[j].vi_vblocknr, entry_bh, kaddr); | 406 | dat, vinfo->vi_vblocknr, entry_bh, kaddr); |
406 | vinfo[j].vi_start = le64_to_cpu(entry->de_start); | 407 | vinfo->vi_start = le64_to_cpu(entry->de_start); |
407 | vinfo[j].vi_end = le64_to_cpu(entry->de_end); | 408 | vinfo->vi_end = le64_to_cpu(entry->de_end); |
408 | vinfo[j].vi_blocknr = le64_to_cpu(entry->de_blocknr); | 409 | vinfo->vi_blocknr = le64_to_cpu(entry->de_blocknr); |
409 | } | 410 | } |
410 | kunmap_atomic(kaddr, KM_USER0); | 411 | kunmap_atomic(kaddr, KM_USER0); |
411 | brelse(entry_bh); | 412 | brelse(entry_bh); |
diff --git a/fs/nilfs2/dat.h b/fs/nilfs2/dat.h index d9560654a4b7..d328b81eead4 100644 --- a/fs/nilfs2/dat.h +++ b/fs/nilfs2/dat.h | |||
@@ -47,6 +47,6 @@ void nilfs_dat_abort_end(struct inode *, struct nilfs_palloc_req *); | |||
47 | int nilfs_dat_mark_dirty(struct inode *, __u64); | 47 | int nilfs_dat_mark_dirty(struct inode *, __u64); |
48 | int nilfs_dat_freev(struct inode *, __u64 *, size_t); | 48 | int nilfs_dat_freev(struct inode *, __u64 *, size_t); |
49 | int nilfs_dat_move(struct inode *, __u64, sector_t); | 49 | int nilfs_dat_move(struct inode *, __u64, sector_t); |
50 | ssize_t nilfs_dat_get_vinfo(struct inode *, struct nilfs_vinfo *, size_t); | 50 | ssize_t nilfs_dat_get_vinfo(struct inode *, void *, unsigned, size_t); |
51 | 51 | ||
52 | #endif /* _NILFS_DAT_H */ | 52 | #endif /* _NILFS_DAT_H */ |
diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c index bdad7e4980b0..6ea5f872e2de 100644 --- a/fs/nilfs2/ioctl.c +++ b/fs/nilfs2/ioctl.c | |||
@@ -152,7 +152,7 @@ nilfs_ioctl_do_get_cpinfo(struct the_nilfs *nilfs, __u64 *posp, int flags, | |||
152 | 152 | ||
153 | down_read(&nilfs->ns_segctor_sem); | 153 | down_read(&nilfs->ns_segctor_sem); |
154 | ret = nilfs_cpfile_get_cpinfo(nilfs->ns_cpfile, posp, flags, buf, | 154 | ret = nilfs_cpfile_get_cpinfo(nilfs->ns_cpfile, posp, flags, buf, |
155 | nmembs); | 155 | size, nmembs); |
156 | up_read(&nilfs->ns_segctor_sem); | 156 | up_read(&nilfs->ns_segctor_sem); |
157 | return ret; | 157 | return ret; |
158 | } | 158 | } |
@@ -182,7 +182,8 @@ nilfs_ioctl_do_get_suinfo(struct the_nilfs *nilfs, __u64 *posp, int flags, | |||
182 | int ret; | 182 | int ret; |
183 | 183 | ||
184 | down_read(&nilfs->ns_segctor_sem); | 184 | down_read(&nilfs->ns_segctor_sem); |
185 | ret = nilfs_sufile_get_suinfo(nilfs->ns_sufile, *posp, buf, nmembs); | 185 | ret = nilfs_sufile_get_suinfo(nilfs->ns_sufile, *posp, buf, size, |
186 | nmembs); | ||
186 | up_read(&nilfs->ns_segctor_sem); | 187 | up_read(&nilfs->ns_segctor_sem); |
187 | return ret; | 188 | return ret; |
188 | } | 189 | } |
@@ -212,7 +213,7 @@ nilfs_ioctl_do_get_vinfo(struct the_nilfs *nilfs, __u64 *posp, int flags, | |||
212 | int ret; | 213 | int ret; |
213 | 214 | ||
214 | down_read(&nilfs->ns_segctor_sem); | 215 | down_read(&nilfs->ns_segctor_sem); |
215 | ret = nilfs_dat_get_vinfo(nilfs_dat_inode(nilfs), buf, nmembs); | 216 | ret = nilfs_dat_get_vinfo(nilfs_dat_inode(nilfs), buf, size, nmembs); |
216 | up_read(&nilfs->ns_segctor_sem); | 217 | up_read(&nilfs->ns_segctor_sem); |
217 | return ret; | 218 | return ret; |
218 | } | 219 | } |
@@ -589,7 +590,7 @@ static int nilfs_ioctl_get_info(struct inode *inode, struct file *filp, | |||
589 | if (copy_from_user(&argv, argp, sizeof(argv))) | 590 | if (copy_from_user(&argv, argp, sizeof(argv))) |
590 | return -EFAULT; | 591 | return -EFAULT; |
591 | 592 | ||
592 | if (argv.v_size != membsz) | 593 | if (argv.v_size < membsz) |
593 | return -EINVAL; | 594 | return -EINVAL; |
594 | 595 | ||
595 | ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd), dofunc); | 596 | ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd), dofunc); |
diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c index da127325fdaa..37994d4a59cc 100644 --- a/fs/nilfs2/sufile.c +++ b/fs/nilfs2/sufile.c | |||
@@ -587,7 +587,8 @@ void nilfs_sufile_do_set_error(struct inode *sufile, __u64 segnum, | |||
587 | * nilfs_sufile_get_suinfo - | 587 | * nilfs_sufile_get_suinfo - |
588 | * @sufile: inode of segment usage file | 588 | * @sufile: inode of segment usage file |
589 | * @segnum: segment number to start looking | 589 | * @segnum: segment number to start looking |
590 | * @si: array of suinfo | 590 | * @buf: array of suinfo |
591 | * @sisz: byte size of suinfo | ||
591 | * @nsi: size of suinfo array | 592 | * @nsi: size of suinfo array |
592 | * | 593 | * |
593 | * Description: | 594 | * Description: |
@@ -599,11 +600,12 @@ void nilfs_sufile_do_set_error(struct inode *sufile, __u64 segnum, | |||
599 | * | 600 | * |
600 | * %-ENOMEM - Insufficient amount of memory available. | 601 | * %-ENOMEM - Insufficient amount of memory available. |
601 | */ | 602 | */ |
602 | ssize_t nilfs_sufile_get_suinfo(struct inode *sufile, __u64 segnum, | 603 | ssize_t nilfs_sufile_get_suinfo(struct inode *sufile, __u64 segnum, void *buf, |
603 | struct nilfs_suinfo *si, size_t nsi) | 604 | unsigned sisz, size_t nsi) |
604 | { | 605 | { |
605 | struct buffer_head *su_bh; | 606 | struct buffer_head *su_bh; |
606 | struct nilfs_segment_usage *su; | 607 | struct nilfs_segment_usage *su; |
608 | struct nilfs_suinfo *si = buf; | ||
607 | size_t susz = NILFS_MDT(sufile)->mi_entry_size; | 609 | size_t susz = NILFS_MDT(sufile)->mi_entry_size; |
608 | struct the_nilfs *nilfs = NILFS_MDT(sufile)->mi_nilfs; | 610 | struct the_nilfs *nilfs = NILFS_MDT(sufile)->mi_nilfs; |
609 | void *kaddr; | 611 | void *kaddr; |
@@ -628,20 +630,22 @@ ssize_t nilfs_sufile_get_suinfo(struct inode *sufile, __u64 segnum, | |||
628 | if (ret != -ENOENT) | 630 | if (ret != -ENOENT) |
629 | goto out; | 631 | goto out; |
630 | /* hole */ | 632 | /* hole */ |
631 | memset(&si[i], 0, sizeof(struct nilfs_suinfo) * n); | 633 | memset(si, 0, sisz * n); |
634 | si = (void *)si + sisz * n; | ||
632 | continue; | 635 | continue; |
633 | } | 636 | } |
634 | 637 | ||
635 | kaddr = kmap_atomic(su_bh->b_page, KM_USER0); | 638 | kaddr = kmap_atomic(su_bh->b_page, KM_USER0); |
636 | su = nilfs_sufile_block_get_segment_usage( | 639 | su = nilfs_sufile_block_get_segment_usage( |
637 | sufile, segnum, su_bh, kaddr); | 640 | sufile, segnum, su_bh, kaddr); |
638 | for (j = 0; j < n; j++, su = (void *)su + susz) { | 641 | for (j = 0; j < n; |
639 | si[i + j].sui_lastmod = le64_to_cpu(su->su_lastmod); | 642 | j++, su = (void *)su + susz, si = (void *)si + sisz) { |
640 | si[i + j].sui_nblocks = le32_to_cpu(su->su_nblocks); | 643 | si->sui_lastmod = le64_to_cpu(su->su_lastmod); |
641 | si[i + j].sui_flags = le32_to_cpu(su->su_flags) & | 644 | si->sui_nblocks = le32_to_cpu(su->su_nblocks); |
645 | si->sui_flags = le32_to_cpu(su->su_flags) & | ||
642 | ~(1UL << NILFS_SEGMENT_USAGE_ACTIVE); | 646 | ~(1UL << NILFS_SEGMENT_USAGE_ACTIVE); |
643 | if (nilfs_segment_is_active(nilfs, segnum + j)) | 647 | if (nilfs_segment_is_active(nilfs, segnum + j)) |
644 | si[i + j].sui_flags |= | 648 | si->sui_flags |= |
645 | (1UL << NILFS_SEGMENT_USAGE_ACTIVE); | 649 | (1UL << NILFS_SEGMENT_USAGE_ACTIVE); |
646 | } | 650 | } |
647 | kunmap_atomic(kaddr, KM_USER0); | 651 | kunmap_atomic(kaddr, KM_USER0); |
diff --git a/fs/nilfs2/sufile.h b/fs/nilfs2/sufile.h index fd6232e365ca..a2c4d76c3366 100644 --- a/fs/nilfs2/sufile.h +++ b/fs/nilfs2/sufile.h | |||
@@ -43,7 +43,7 @@ void nilfs_sufile_put_segment_usage(struct inode *, __u64, | |||
43 | struct buffer_head *); | 43 | struct buffer_head *); |
44 | int nilfs_sufile_get_stat(struct inode *, struct nilfs_sustat *); | 44 | int nilfs_sufile_get_stat(struct inode *, struct nilfs_sustat *); |
45 | int nilfs_sufile_get_ncleansegs(struct inode *, unsigned long *); | 45 | int nilfs_sufile_get_ncleansegs(struct inode *, unsigned long *); |
46 | ssize_t nilfs_sufile_get_suinfo(struct inode *, __u64, struct nilfs_suinfo *, | 46 | ssize_t nilfs_sufile_get_suinfo(struct inode *, __u64, void *, unsigned, |
47 | size_t); | 47 | size_t); |
48 | 48 | ||
49 | int nilfs_sufile_updatev(struct inode *, __u64 *, size_t, int, size_t *, | 49 | int nilfs_sufile_updatev(struct inode *, __u64 *, size_t, int, size_t *, |