|
7 | 7 | *
|
8 | 8 | *
|
9 | 9 | * IDENTIFICATION
|
10 |
| - * $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.45 1999/06/11 02:39:43 momjian Exp $ |
| 10 | + * $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.46 1999/06/18 16:47:23 momjian Exp $ |
11 | 11 | *
|
12 | 12 | *-------------------------------------------------------------------------
|
13 | 13 | */
|
@@ -674,11 +674,12 @@ mdnblocks(Relation reln)
|
674 | 674 | segno = 0;
|
675 | 675 | for (;;)
|
676 | 676 | {
|
677 |
| - if (v->mdfd_lstbcnt == RELSEG_SIZE |
678 |
| - || (nblocks = _mdnblocks(v->mdfd_vfd, BLCKSZ)) == RELSEG_SIZE) |
| 677 | + nblocks = _mdnblocks(v->mdfd_vfd, BLCKSZ); |
| 678 | + if (nblocks > RELSEG_SIZE) |
| 679 | + elog(FATAL, "segment too big in mdnblocks!"); |
| 680 | + v->mdfd_lstbcnt = nblocks; |
| 681 | + if (nblocks == RELSEG_SIZE) |
679 | 682 | {
|
680 |
| - |
681 |
| - v->mdfd_lstbcnt = RELSEG_SIZE; |
682 | 683 | segno++;
|
683 | 684 |
|
684 | 685 | if (v->mdfd_chain == (MdfdVec *) NULL)
|
@@ -711,22 +712,55 @@ mdtruncate(Relation reln, int nblocks)
|
711 | 712 | MdfdVec *v;
|
712 | 713 |
|
713 | 714 | #ifndef LET_OS_MANAGE_FILESIZE
|
714 |
| - int curnblk; |
| 715 | + int curnblk, |
| 716 | + i, |
| 717 | + oldsegno, |
| 718 | + newsegno, |
| 719 | + lastsegblocks; |
| 720 | + MdfdVec **varray; |
715 | 721 |
|
716 | 722 | curnblk = mdnblocks(reln);
|
717 |
| - if (curnblk / RELSEG_SIZE > 0) |
718 |
| - { |
719 |
| - elog(NOTICE, "Can't truncate multi-segments relation %s", |
720 |
| - reln->rd_rel->relname.data); |
721 |
| - return curnblk; |
722 |
| - } |
| 723 | + if (nblocks > curnblk) |
| 724 | + return -1; |
| 725 | + oldsegno = curnblk / RELSEG_SIZE; |
| 726 | + newsegno = nblocks / RELSEG_SIZE; |
| 727 | + |
723 | 728 | #endif
|
724 | 729 |
|
725 | 730 | fd = RelationGetFile(reln);
|
726 | 731 | v = &Md_fdvec[fd];
|
727 | 732 |
|
| 733 | +#ifndef LET_OS_MANAGE_FILESIZE |
| 734 | + varray = (MdfdVec **)palloc((oldsegno + 1) * sizeof(MdfdVec *)); |
| 735 | + for (i = 0; i <= oldsegno; i++) |
| 736 | + { |
| 737 | + if (!v) |
| 738 | + elog(ERROR,"segment isn't open in mdtruncate!"); |
| 739 | + varray[i] = v; |
| 740 | + v = v->mdfd_chain; |
| 741 | + } |
| 742 | + for (i = oldsegno; i > newsegno; i--) |
| 743 | + { |
| 744 | + v = varray[i]; |
| 745 | + if (FileTruncate(v->mdfd_vfd, 0) < 0) |
| 746 | + { |
| 747 | + pfree(varray); |
| 748 | + return -1; |
| 749 | + } |
| 750 | + v->mdfd_lstbcnt = 0; |
| 751 | + } |
| 752 | + /* Calculate the # of blocks in the last segment */ |
| 753 | + lastsegblocks = nblocks - (newsegno * RELSEG_SIZE); |
| 754 | + v = varray[i]; |
| 755 | + pfree(varray); |
| 756 | + if (FileTruncate(v->mdfd_vfd, lastsegblocks * BLCKSZ) < 0) |
| 757 | + return -1; |
| 758 | + v->mdfd_lstbcnt = lastsegblocks; |
| 759 | +#else |
728 | 760 | if (FileTruncate(v->mdfd_vfd, nblocks * BLCKSZ) < 0)
|
729 | 761 | return -1;
|
| 762 | + v->mdfd_lstbcnt = nblocks; |
| 763 | +#endif |
730 | 764 |
|
731 | 765 | return nblocks;
|
732 | 766 |
|
|
0 commit comments