Fix up indirect block handling in truncate to be 32/64 clean.
This commit is contained in:
parent
30c3aa6e8a
commit
98320d1917
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: lfs_accessors.h,v 1.20 2015/09/01 06:12:33 dholland Exp $ */
|
/* $NetBSD: lfs_accessors.h,v 1.21 2015/09/01 06:13:09 dholland Exp $ */
|
||||||
|
|
||||||
/* from NetBSD: lfs.h,v 1.165 2015/07/24 06:59:32 dholland Exp */
|
/* from NetBSD: lfs.h,v 1.165 2015/07/24 06:59:32 dholland Exp */
|
||||||
/* from NetBSD: dinode.h,v 1.22 2013/01/22 09:39:18 dholland Exp */
|
/* from NetBSD: dinode.h,v 1.22 2013/01/22 09:39:18 dholland Exp */
|
||||||
|
@ -214,11 +214,6 @@
|
||||||
#define LFS_MAXSYMLINKLEN(fs) \
|
#define LFS_MAXSYMLINKLEN(fs) \
|
||||||
((fs)->lfs_is64 ? LFS64_MAXSYMLINKLEN : LFS32_MAXSYMLINKLEN)
|
((fs)->lfs_is64 ? LFS64_MAXSYMLINKLEN : LFS32_MAXSYMLINKLEN)
|
||||||
|
|
||||||
/* get rid of this eventually */
|
|
||||||
#define ULFS_MAXSYMLINKLEN(ip) \
|
|
||||||
((ip)->i_ump->um_fstype == ULFS1) ? \
|
|
||||||
LFS32_MAXSYMLINKLEN : LFS64_MAXSYMLINKLEN
|
|
||||||
|
|
||||||
#define DINOSIZE(fs) ((fs)->lfs_is64 ? sizeof(struct lfs64_dinode) : sizeof(struct lfs32_dinode))
|
#define DINOSIZE(fs) ((fs)->lfs_is64 ? sizeof(struct lfs64_dinode) : sizeof(struct lfs32_dinode))
|
||||||
|
|
||||||
#define DINO_IN_BLOCK(fs, base, ix) \
|
#define DINO_IN_BLOCK(fs, base, ix) \
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: lfs_inode.c,v 1.146 2015/09/01 06:08:37 dholland Exp $ */
|
/* $NetBSD: lfs_inode.c,v 1.147 2015/09/01 06:13:09 dholland Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
|
* Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
|
||||||
|
@ -60,7 +60,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: lfs_inode.c,v 1.146 2015/09/01 06:08:37 dholland Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: lfs_inode.c,v 1.147 2015/09/01 06:13:09 dholland Exp $");
|
||||||
|
|
||||||
#if defined(_KERNEL_OPT)
|
#if defined(_KERNEL_OPT)
|
||||||
#include "opt_quota.h"
|
#include "opt_quota.h"
|
||||||
|
@ -726,10 +726,10 @@ lfs_indirtrunc(struct inode *ip, daddr_t lbn, daddr_t dbn,
|
||||||
int i;
|
int i;
|
||||||
struct buf *bp;
|
struct buf *bp;
|
||||||
struct lfs *fs = ip->i_lfs;
|
struct lfs *fs = ip->i_lfs;
|
||||||
int32_t *bap; /* XXX ondisk32 */
|
void *bap;
|
||||||
|
bool bap_needs_free;
|
||||||
struct vnode *vp;
|
struct vnode *vp;
|
||||||
daddr_t nb, nlbn, last;
|
daddr_t nb, nlbn, last;
|
||||||
int32_t *copy = NULL; /* XXX ondisk32 */
|
|
||||||
daddr_t blkcount, rblkcount, factor;
|
daddr_t blkcount, rblkcount, factor;
|
||||||
int nblocks;
|
int nblocks;
|
||||||
daddr_t blocksreleased = 0, real_released = 0;
|
daddr_t blocksreleased = 0, real_released = 0;
|
||||||
|
@ -777,17 +777,25 @@ lfs_indirtrunc(struct inode *ip, daddr_t lbn, daddr_t dbn,
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
bap = (int32_t *)bp->b_data; /* XXX ondisk32 */
|
|
||||||
if (lastbn >= 0) {
|
if (lastbn >= 0) {
|
||||||
copy = lfs_malloc(fs, lfs_sb_getbsize(fs), LFS_NB_IBLOCK);
|
/*
|
||||||
memcpy((void *)copy, (void *)bap, lfs_sb_getbsize(fs));
|
* We still need this block, so copy the data for
|
||||||
memset((void *)&bap[last + 1], 0,
|
* subsequent processing; then in the original block,
|
||||||
/* XXX ondisk32 */
|
* zero out the dying block pointers and send it off.
|
||||||
(u_int)(LFS_NINDIR(fs) - (last + 1)) * sizeof (int32_t));
|
*/
|
||||||
|
bap = lfs_malloc(fs, lfs_sb_getbsize(fs), LFS_NB_IBLOCK);
|
||||||
|
memcpy(bap, bp->b_data, lfs_sb_getbsize(fs));
|
||||||
|
bap_needs_free = true;
|
||||||
|
|
||||||
|
for (i = last + 1; i < LFS_NINDIR(fs); i++) {
|
||||||
|
lfs_iblock_set(fs, bp->b_data, i, 0);
|
||||||
|
}
|
||||||
error = VOP_BWRITE(bp->b_vp, bp);
|
error = VOP_BWRITE(bp->b_vp, bp);
|
||||||
if (error)
|
if (error)
|
||||||
allerror = error;
|
allerror = error;
|
||||||
bap = copy;
|
} else {
|
||||||
|
bap = bp->b_data;
|
||||||
|
bap_needs_free = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -795,7 +803,7 @@ lfs_indirtrunc(struct inode *ip, daddr_t lbn, daddr_t dbn,
|
||||||
*/
|
*/
|
||||||
for (i = LFS_NINDIR(fs) - 1, nlbn = lbn + 1 - i * factor; i > last;
|
for (i = LFS_NINDIR(fs) - 1, nlbn = lbn + 1 - i * factor; i > last;
|
||||||
i--, nlbn += factor) {
|
i--, nlbn += factor) {
|
||||||
nb = bap[i];
|
nb = lfs_iblock_get(fs, bap, i);
|
||||||
if (nb == 0)
|
if (nb == 0)
|
||||||
continue;
|
continue;
|
||||||
if (level > SINGLE) {
|
if (level > SINGLE) {
|
||||||
|
@ -809,7 +817,7 @@ lfs_indirtrunc(struct inode *ip, daddr_t lbn, daddr_t dbn,
|
||||||
real_released += rblkcount;
|
real_released += rblkcount;
|
||||||
}
|
}
|
||||||
lfs_blkfree(fs, ip, nb, lfs_sb_getbsize(fs), lastsegp, bcp);
|
lfs_blkfree(fs, ip, nb, lfs_sb_getbsize(fs), lastsegp, bcp);
|
||||||
if (bap[i] > 0)
|
if (lfs_iblock_get(fs, bap, i) > 0)
|
||||||
real_released += nblocks;
|
real_released += nblocks;
|
||||||
blocksreleased += nblocks;
|
blocksreleased += nblocks;
|
||||||
}
|
}
|
||||||
|
@ -819,7 +827,7 @@ lfs_indirtrunc(struct inode *ip, daddr_t lbn, daddr_t dbn,
|
||||||
*/
|
*/
|
||||||
if (level > SINGLE && lastbn >= 0) {
|
if (level > SINGLE && lastbn >= 0) {
|
||||||
last = lastbn % factor;
|
last = lastbn % factor;
|
||||||
nb = bap[i];
|
nb = lfs_iblock_get(fs, bap, i);
|
||||||
if (nb != 0) {
|
if (nb != 0) {
|
||||||
error = lfs_indirtrunc(ip, nlbn, nb,
|
error = lfs_indirtrunc(ip, nlbn, nb,
|
||||||
last, level - 1, &blkcount,
|
last, level - 1, &blkcount,
|
||||||
|
@ -831,8 +839,8 @@ lfs_indirtrunc(struct inode *ip, daddr_t lbn, daddr_t dbn,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (copy != NULL) {
|
if (bap_needs_free) {
|
||||||
lfs_free(fs, copy, LFS_NB_IBLOCK);
|
lfs_free(fs, bap, LFS_NB_IBLOCK);
|
||||||
} else {
|
} else {
|
||||||
mutex_enter(&bufcache_lock);
|
mutex_enter(&bufcache_lock);
|
||||||
if (bp->b_oflags & BO_DELWRI) {
|
if (bp->b_oflags & BO_DELWRI) {
|
||||||
|
|
Loading…
Reference in New Issue