Module Name:    src
Committed By:   ttoth
Date:           Wed Aug 22 09:20:13 UTC 2012

Modified Files:
        src/sys/ufs/chfs: chfs_readinode.c chfs_subr.c

Log Message:
chfs: fixed truncating


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/sys/ufs/chfs/chfs_readinode.c
cvs rdiff -u -r1.6 -r1.7 src/sys/ufs/chfs/chfs_subr.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/ufs/chfs/chfs_readinode.c
diff -u src/sys/ufs/chfs/chfs_readinode.c:1.4 src/sys/ufs/chfs/chfs_readinode.c:1.5
--- src/sys/ufs/chfs/chfs_readinode.c:1.4	Mon Aug 13 13:12:51 2012
+++ src/sys/ufs/chfs/chfs_readinode.c	Wed Aug 22 09:20:13 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: chfs_readinode.c,v 1.4 2012/08/13 13:12:51 ttoth Exp $	*/
+/*	$NetBSD: chfs_readinode.c,v 1.5 2012/08/22 09:20:13 ttoth Exp $	*/
 
 /*-
  * Copyright (c) 2010 Department of Software Engineering,
@@ -604,6 +604,10 @@ chfs_remove_frags_of_node(struct chfs_mo
 	KASSERT(mutex_owned(&chmp->chm_lock_mountfields));
 	struct chfs_node_frag *this, *next;
 
+	if (nref == NULL) {
+		return;
+	}
+
 	this = (struct chfs_node_frag *)RB_TREE_MIN(fragtree);
 	while (this) {
 		next = frag_next(fragtree, this);
@@ -1086,6 +1090,7 @@ chfs_read_data(struct chfs_mount* chmp, 
 	frag = (struct chfs_node_frag *)rb_tree_find_node_leq(&ip->fragtree, &ofs);
 
 	if (!frag || frag->ofs > ofs || frag->ofs + frag->size <= ofs) {
+		bp->b_resid = 0;
 		dbg("not found in frag tree\n");
 		return 0;
 	}

Index: src/sys/ufs/chfs/chfs_subr.c
diff -u src/sys/ufs/chfs/chfs_subr.c:1.6 src/sys/ufs/chfs/chfs_subr.c:1.7
--- src/sys/ufs/chfs/chfs_subr.c:1.6	Mon Aug 13 13:12:51 2012
+++ src/sys/ufs/chfs/chfs_subr.c	Wed Aug 22 09:20:13 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: chfs_subr.c,v 1.6 2012/08/13 13:12:51 ttoth Exp $	*/
+/*	$NetBSD: chfs_subr.c,v 1.7 2012/08/22 09:20:13 ttoth Exp $	*/
 
 /*-
  * Copyright (c) 2010 Department of Software Engineering,
@@ -216,11 +216,6 @@ chfs_chsize(struct vnode *vp, u_quad_t s
 {
 	struct chfs_mount *chmp;
 	struct chfs_inode *ip;
-	struct buf *bp;
-	int blknum, append;
-	int error = 0;
-	char *buf = NULL;
-	struct chfs_full_dnode *fd;
 
 	ip = VTOI(vp);
 	chmp = ip->chmp;
@@ -246,104 +241,25 @@ chfs_chsize(struct vnode *vp, u_quad_t s
 	vflushbuf(vp, 0);
 
 	mutex_enter(&chmp->chm_lock_mountfields);
-	chfs_flush_pending_wbuf(chmp);
 
-	/* handle truncate to zero as a special case */
-	if (size == 0) {
-		dbg("truncate to zero");
-		chfs_truncate_fragtree(ip->chmp,
-		    &ip->fragtree, size);
+	if (ip->size < size) {
+		uvm_vnp_setsize(vp, size);
 		chfs_set_vnode_size(vp, size);
+		ip->iflag |= IN_CHANGE | IN_UPDATE;
 
 		mutex_exit(&chmp->chm_lock_mountfields);
-
 		return 0;
 	}
 
-
-	/* allocate zeros for the new data */
-	buf = kmem_zalloc(size, KM_SLEEP);
-	bp = getiobuf(vp, true);
-
-	if (ip->size != 0) {
-		/* read the whole data */
-		bp->b_blkno = 0;
-		bp->b_bufsize = bp->b_resid = bp->b_bcount = ip->size;
-		bp->b_data = kmem_alloc(ip->size, KM_SLEEP);
-
-		error = chfs_read_data(chmp, vp, bp);
-		if (error) {
-			mutex_exit(&chmp->chm_lock_mountfields);
-			putiobuf(bp);
-
-			return error;
-		}
-
-		/* create the new data */
-		dbg("create new data vap%llu ip%llu\n",
-			(unsigned long long)size, (unsigned long long)ip->size);
-		append = size - ip->size;
-		if (append > 0) {
-			memcpy(buf, bp->b_data, ip->size);
-		} else {
-			memcpy(buf, bp->b_data, size);
-			chfs_truncate_fragtree(ip->chmp,
-				&ip->fragtree, size);
-		}
-
-		kmem_free(bp->b_data, ip->size);
-
-		struct chfs_node_frag *lastfrag = frag_last(&ip->fragtree);
-		fd = lastfrag->node;
-
-		// remove from the list
-		mutex_enter(&chmp->chm_lock_vnocache);
-		chfs_remove_frags_of_node(chmp, &ip->fragtree, fd->nref);
-		// don't obsolete here, because setattr will obsolete this node
-		chfs_remove_node_from_list(chmp, ip->chvc, fd->nref, &ip->chvc->dnode);
-		mutex_exit(&chmp->chm_lock_vnocache);
-
-		blknum = lastfrag->ofs / PAGE_SIZE;
-		lastfrag->size = append > PAGE_SIZE ? PAGE_SIZE : size % PAGE_SIZE;
-	} else {
-		fd = chfs_alloc_full_dnode();
-		blknum = 0;
+	if (size != 0) {
+		ubc_zerorange(&vp->v_uobj, size, ip->size - size, UBC_UNMAP_FLAG(vp));
 	}
-
+	
+	chfs_truncate_fragtree(ip->chmp, &ip->fragtree, size);
+	uvm_vnp_setsize(vp, size);
 	chfs_set_vnode_size(vp, size);
-
-	// write the new data
-	for (bp->b_blkno = blknum; bp->b_blkno * PAGE_SIZE < size; bp->b_blkno++) {
-		uint64_t writesize = MIN(size - bp->b_blkno * PAGE_SIZE, PAGE_SIZE);
-
-		bp->b_bufsize = bp->b_resid = bp->b_bcount = writesize;
-		bp->b_data = kmem_alloc(writesize, KM_SLEEP);
-
-		memcpy(bp->b_data, buf + (bp->b_blkno * PAGE_SIZE), writesize);
-
-		if (bp->b_blkno != blknum) {
-			fd = chfs_alloc_full_dnode();
-		}
-
-		error = chfs_write_flash_dnode(chmp, vp, bp, fd);
-		if (error) {
-			mutex_exit(&chmp->chm_lock_mountfields);
-			kmem_free(bp->b_data, writesize);
-			putiobuf(bp);
-
-			return error;
-		}
-		if (bp->b_blkno != blknum) {
-			chfs_add_full_dnode_to_inode(chmp, ip, fd);
-		}
-		kmem_free(bp->b_data, writesize);
-	}
-
+	ip->iflag |= IN_CHANGE | IN_UPDATE;
 	mutex_exit(&chmp->chm_lock_mountfields);
-
-	kmem_free(buf, size);
-	putiobuf(bp);
-
 	return 0;
 }
 #if 0

Reply via email to