Tue Sep 1 06:13:09 2015 UTC ()
Fix up indirect block handling in truncate to be 32/64 clean.


(dholland)
diff -r1.20 -r1.21 src/sys/ufs/lfs/lfs_accessors.h
diff -r1.146 -r1.147 src/sys/ufs/lfs/lfs_inode.c

cvs diff -r1.20 -r1.21 src/sys/ufs/lfs/lfs_accessors.h (expand / switch to unified diff)

--- src/sys/ufs/lfs/lfs_accessors.h 2015/09/01 06:12:33 1.20
+++ src/sys/ufs/lfs/lfs_accessors.h 2015/09/01 06:13:09 1.21
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: lfs_accessors.h,v 1.20 2015/09/01 06:12:33 dholland Exp $ */ 1/* $NetBSD: lfs_accessors.h,v 1.21 2015/09/01 06:13:09 dholland Exp $ */
2 2
3/* from NetBSD: lfs.h,v 1.165 2015/07/24 06:59:32 dholland Exp */ 3/* from NetBSD: lfs.h,v 1.165 2015/07/24 06:59:32 dholland Exp */
4/* from NetBSD: dinode.h,v 1.22 2013/01/22 09:39:18 dholland Exp */ 4/* from NetBSD: dinode.h,v 1.22 2013/01/22 09:39:18 dholland Exp */
5/* from NetBSD: dir.h,v 1.21 2009/07/22 04:49:19 dholland Exp */ 5/* from NetBSD: dir.h,v 1.21 2009/07/22 04:49:19 dholland Exp */
6 6
7/*- 7/*-
8 * Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc. 8 * Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * This code is derived from software contributed to The NetBSD Foundation 11 * This code is derived from software contributed to The NetBSD Foundation
12 * by Konrad E. Schroder <perseant@hhhh.org>. 12 * by Konrad E. Schroder <perseant@hhhh.org>.
13 * 13 *
14 * Redistribution and use in source and binary forms, with or without 14 * Redistribution and use in source and binary forms, with or without
@@ -204,31 +204,26 @@ @@ -204,31 +204,26 @@
204/* 204/*
205 * dinodes 205 * dinodes
206 */ 206 */
207 207
208/* 208/*
209 * Maximum length of a symlink that can be stored within the inode. 209 * Maximum length of a symlink that can be stored within the inode.
210 */ 210 */
211#define LFS32_MAXSYMLINKLEN ((ULFS_NDADDR + ULFS_NIADDR) * sizeof(int32_t)) 211#define LFS32_MAXSYMLINKLEN ((ULFS_NDADDR + ULFS_NIADDR) * sizeof(int32_t))
212#define LFS64_MAXSYMLINKLEN ((ULFS_NDADDR + ULFS_NIADDR) * sizeof(int64_t)) 212#define LFS64_MAXSYMLINKLEN ((ULFS_NDADDR + ULFS_NIADDR) * sizeof(int64_t))
213 213
214#define LFS_MAXSYMLINKLEN(fs) \ 214#define LFS_MAXSYMLINKLEN(fs) \
215 ((fs)->lfs_is64 ? LFS64_MAXSYMLINKLEN : LFS32_MAXSYMLINKLEN) 215 ((fs)->lfs_is64 ? LFS64_MAXSYMLINKLEN : LFS32_MAXSYMLINKLEN)
216 216
217/* get rid of this eventually */ 
218#define ULFS_MAXSYMLINKLEN(ip) \ 
219 ((ip)->i_ump->um_fstype == ULFS1) ? \ 
220 LFS32_MAXSYMLINKLEN : LFS64_MAXSYMLINKLEN 
221 
222#define DINOSIZE(fs) ((fs)->lfs_is64 ? sizeof(struct lfs64_dinode) : sizeof(struct lfs32_dinode)) 217#define DINOSIZE(fs) ((fs)->lfs_is64 ? sizeof(struct lfs64_dinode) : sizeof(struct lfs32_dinode))
223 218
224#define DINO_IN_BLOCK(fs, base, ix) \ 219#define DINO_IN_BLOCK(fs, base, ix) \
225 ((union lfs_dinode *)((char *)(base) + DINOSIZE(fs) * (ix))) 220 ((union lfs_dinode *)((char *)(base) + DINOSIZE(fs) * (ix)))
226 221
227static __unused inline void 222static __unused inline void
228lfs_copy_dinode(STRUCT_LFS *fs, 223lfs_copy_dinode(STRUCT_LFS *fs,
229 union lfs_dinode *dst, const union lfs_dinode *src) 224 union lfs_dinode *dst, const union lfs_dinode *src)
230{ 225{
231 /* 226 /*
232 * We can do structure assignment of the structs, but not of 227 * We can do structure assignment of the structs, but not of
233 * the whole union, as the union is the size of the (larger) 228 * the whole union, as the union is the size of the (larger)
234 * 64-bit struct and on a 32-bit fs the upper half of it might 229 * 64-bit struct and on a 32-bit fs the upper half of it might

cvs diff -r1.146 -r1.147 src/sys/ufs/lfs/lfs_inode.c (expand / switch to unified diff)

--- src/sys/ufs/lfs/lfs_inode.c 2015/09/01 06:08:37 1.146
+++ src/sys/ufs/lfs/lfs_inode.c 2015/09/01 06:13:09 1.147
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: lfs_inode.c,v 1.146 2015/09/01 06:08:37 dholland Exp $ */ 1/* $NetBSD: lfs_inode.c,v 1.147 2015/09/01 06:13:09 dholland Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc. 4 * Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Konrad E. Schroder <perseant@hhhh.org>. 8 * by Konrad E. Schroder <perseant@hhhh.org>.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -50,27 +50,27 @@ @@ -50,27 +50,27 @@
50 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 50 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
51 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 51 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
52 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 52 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
53 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 53 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 54 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
55 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 55 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
56 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 56 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
57 * SUCH DAMAGE. 57 * SUCH DAMAGE.
58 * 58 *
59 * @(#)lfs_inode.c 8.9 (Berkeley) 5/8/95 59 * @(#)lfs_inode.c 8.9 (Berkeley) 5/8/95
60 */ 60 */
61 61
62#include <sys/cdefs.h> 62#include <sys/cdefs.h>
63__KERNEL_RCSID(0, "$NetBSD: lfs_inode.c,v 1.146 2015/09/01 06:08:37 dholland Exp $"); 63__KERNEL_RCSID(0, "$NetBSD: lfs_inode.c,v 1.147 2015/09/01 06:13:09 dholland Exp $");
64 64
65#if defined(_KERNEL_OPT) 65#if defined(_KERNEL_OPT)
66#include "opt_quota.h" 66#include "opt_quota.h"
67#endif 67#endif
68 68
69#include <sys/param.h> 69#include <sys/param.h>
70#include <sys/systm.h> 70#include <sys/systm.h>
71#include <sys/mount.h> 71#include <sys/mount.h>
72#include <sys/malloc.h> 72#include <sys/malloc.h>
73#include <sys/proc.h> 73#include <sys/proc.h>
74#include <sys/file.h> 74#include <sys/file.h>
75#include <sys/buf.h> 75#include <sys/buf.h>
76#include <sys/vnode.h> 76#include <sys/vnode.h>
@@ -716,30 +716,30 @@ lfs_finalize_fs_seguse(struct lfs *fs) @@ -716,30 +716,30 @@ lfs_finalize_fs_seguse(struct lfs *fs)
716 * and recursive calls to indirtrunc must be used to cleanse other indirect 716 * and recursive calls to indirtrunc must be used to cleanse other indirect
717 * blocks. 717 * blocks.
718 * 718 *
719 * NB: triple indirect blocks are untested. 719 * NB: triple indirect blocks are untested.
720 */ 720 */
721static int 721static int
722lfs_indirtrunc(struct inode *ip, daddr_t lbn, daddr_t dbn, 722lfs_indirtrunc(struct inode *ip, daddr_t lbn, daddr_t dbn,
723 daddr_t lastbn, int level, daddr_t *countp, 723 daddr_t lastbn, int level, daddr_t *countp,
724 daddr_t *rcountp, long *lastsegp, size_t *bcp) 724 daddr_t *rcountp, long *lastsegp, size_t *bcp)
725{ 725{
726 int i; 726 int i;
727 struct buf *bp; 727 struct buf *bp;
728 struct lfs *fs = ip->i_lfs; 728 struct lfs *fs = ip->i_lfs;
729 int32_t *bap; /* XXX ondisk32 */ 729 void *bap;
 730 bool bap_needs_free;
730 struct vnode *vp; 731 struct vnode *vp;
731 daddr_t nb, nlbn, last; 732 daddr_t nb, nlbn, last;
732 int32_t *copy = NULL; /* XXX ondisk32 */ 
733 daddr_t blkcount, rblkcount, factor; 733 daddr_t blkcount, rblkcount, factor;
734 int nblocks; 734 int nblocks;
735 daddr_t blocksreleased = 0, real_released = 0; 735 daddr_t blocksreleased = 0, real_released = 0;
736 int error = 0, allerror = 0; 736 int error = 0, allerror = 0;
737 737
738 ASSERT_SEGLOCK(fs); 738 ASSERT_SEGLOCK(fs);
739 /* 739 /*
740 * Calculate index in current block of last 740 * Calculate index in current block of last
741 * block to be kept. -1 indicates the entire 741 * block to be kept. -1 indicates the entire
742 * block so we need not calculate the index. 742 * block so we need not calculate the index.
743 */ 743 */
744 factor = 1; 744 factor = 1;
745 for (i = SINGLE; i < level; i++) 745 for (i = SINGLE; i < level; i++)
@@ -767,82 +767,90 @@ lfs_indirtrunc(struct inode *ip, daddr_t @@ -767,82 +767,90 @@ lfs_indirtrunc(struct inode *ip, daddr_t
767 bp->b_flags |= B_READ; 767 bp->b_flags |= B_READ;
768 if (bp->b_bcount > bp->b_bufsize) 768 if (bp->b_bcount > bp->b_bufsize)
769 panic("lfs_indirtrunc: bad buffer size"); 769 panic("lfs_indirtrunc: bad buffer size");
770 bp->b_blkno = LFS_FSBTODB(fs, dbn); 770 bp->b_blkno = LFS_FSBTODB(fs, dbn);
771 VOP_STRATEGY(vp, bp); 771 VOP_STRATEGY(vp, bp);
772 error = biowait(bp); 772 error = biowait(bp);
773 } 773 }
774 if (error) { 774 if (error) {
775 brelse(bp, 0); 775 brelse(bp, 0);
776 *countp = *rcountp = 0; 776 *countp = *rcountp = 0;
777 return (error); 777 return (error);
778 } 778 }
779 779
780 bap = (int32_t *)bp->b_data; /* XXX ondisk32 */ 
781 if (lastbn >= 0) { 780 if (lastbn >= 0) {
782 copy = lfs_malloc(fs, lfs_sb_getbsize(fs), LFS_NB_IBLOCK); 781 /*
783 memcpy((void *)copy, (void *)bap, lfs_sb_getbsize(fs)); 782 * We still need this block, so copy the data for
784 memset((void *)&bap[last + 1], 0, 783 * subsequent processing; then in the original block,
785 /* XXX ondisk32 */ 784 * zero out the dying block pointers and send it off.
786 (u_int)(LFS_NINDIR(fs) - (last + 1)) * sizeof (int32_t)); 785 */
 786 bap = lfs_malloc(fs, lfs_sb_getbsize(fs), LFS_NB_IBLOCK);
 787 memcpy(bap, bp->b_data, lfs_sb_getbsize(fs));
 788 bap_needs_free = true;
 789
 790 for (i = last + 1; i < LFS_NINDIR(fs); i++) {
 791 lfs_iblock_set(fs, bp->b_data, i, 0);
 792 }
787 error = VOP_BWRITE(bp->b_vp, bp); 793 error = VOP_BWRITE(bp->b_vp, bp);
788 if (error) 794 if (error)
789 allerror = error; 795 allerror = error;
790 bap = copy; 796 } else {
 797 bap = bp->b_data;
 798 bap_needs_free = false;
791 } 799 }
792 800
793 /* 801 /*
794 * Recursively free totally unused blocks. 802 * Recursively free totally unused blocks.
795 */ 803 */
796 for (i = LFS_NINDIR(fs) - 1, nlbn = lbn + 1 - i * factor; i > last; 804 for (i = LFS_NINDIR(fs) - 1, nlbn = lbn + 1 - i * factor; i > last;
797 i--, nlbn += factor) { 805 i--, nlbn += factor) {
798 nb = bap[i]; 806 nb = lfs_iblock_get(fs, bap, i);
799 if (nb == 0) 807 if (nb == 0)
800 continue; 808 continue;
801 if (level > SINGLE) { 809 if (level > SINGLE) {
802 error = lfs_indirtrunc(ip, nlbn, nb, 810 error = lfs_indirtrunc(ip, nlbn, nb,
803 (daddr_t)-1, level - 1, 811 (daddr_t)-1, level - 1,
804 &blkcount, &rblkcount, 812 &blkcount, &rblkcount,
805 lastsegp, bcp); 813 lastsegp, bcp);
806 if (error) 814 if (error)
807 allerror = error; 815 allerror = error;
808 blocksreleased += blkcount; 816 blocksreleased += blkcount;
809 real_released += rblkcount; 817 real_released += rblkcount;
810 } 818 }
811 lfs_blkfree(fs, ip, nb, lfs_sb_getbsize(fs), lastsegp, bcp); 819 lfs_blkfree(fs, ip, nb, lfs_sb_getbsize(fs), lastsegp, bcp);
812 if (bap[i] > 0) 820 if (lfs_iblock_get(fs, bap, i) > 0)
813 real_released += nblocks; 821 real_released += nblocks;
814 blocksreleased += nblocks; 822 blocksreleased += nblocks;
815 } 823 }
816 824
817 /* 825 /*
818 * Recursively free last partial block. 826 * Recursively free last partial block.
819 */ 827 */
820 if (level > SINGLE && lastbn >= 0) { 828 if (level > SINGLE && lastbn >= 0) {
821 last = lastbn % factor; 829 last = lastbn % factor;
822 nb = bap[i]; 830 nb = lfs_iblock_get(fs, bap, i);
823 if (nb != 0) { 831 if (nb != 0) {
824 error = lfs_indirtrunc(ip, nlbn, nb, 832 error = lfs_indirtrunc(ip, nlbn, nb,
825 last, level - 1, &blkcount, 833 last, level - 1, &blkcount,
826 &rblkcount, lastsegp, bcp); 834 &rblkcount, lastsegp, bcp);
827 if (error) 835 if (error)
828 allerror = error; 836 allerror = error;
829 real_released += rblkcount; 837 real_released += rblkcount;
830 blocksreleased += blkcount; 838 blocksreleased += blkcount;
831 } 839 }
832 } 840 }
833 841
834 if (copy != NULL) { 842 if (bap_needs_free) {
835 lfs_free(fs, copy, LFS_NB_IBLOCK); 843 lfs_free(fs, bap, LFS_NB_IBLOCK);
836 } else { 844 } else {
837 mutex_enter(&bufcache_lock); 845 mutex_enter(&bufcache_lock);
838 if (bp->b_oflags & BO_DELWRI) { 846 if (bp->b_oflags & BO_DELWRI) {
839 LFS_UNLOCK_BUF(bp); 847 LFS_UNLOCK_BUF(bp);
840 lfs_sb_addavail(fs, lfs_btofsb(fs, bp->b_bcount)); 848 lfs_sb_addavail(fs, lfs_btofsb(fs, bp->b_bcount));
841 wakeup(&fs->lfs_availsleep); 849 wakeup(&fs->lfs_availsleep);
842 } 850 }
843 brelsel(bp, BC_INVAL); 851 brelsel(bp, BC_INVAL);
844 mutex_exit(&bufcache_lock); 852 mutex_exit(&bufcache_lock);
845 } 853 }
846 854
847 *countp = blocksreleased; 855 *countp = blocksreleased;
848 *rcountp = real_released; 856 *rcountp = real_released;