git: 9front

Download patch

ref: b502c2e324fc96405044ecfe8cb0c7af64a97211
parent: 1cc7c33cb3f79649766b1cf714f6d7d08424a557
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Thu Jul 18 11:04:37 EDT 2013

cwfs: add rtmp flag for check command to remove temporary files after recover

--- a/sys/man/8/fs
+++ b/sys/man/8/fs
@@ -277,6 +277,17 @@
 .B "check free"
 afterward will construct a new free list that contains no
 blocks outside the new, smaller file system.
+.TP
+.B rtmp
+Removes temporary files after a recovery from worm.
+After a cache ream and recover, temporary files and directories
+refer to invalid data blocks producing checktag errors
+on access. To get rid of these errors, the
+.I rtmp
+flag can be used with the
+.I check
+command which will truncate temporary directories
+and remove temporary files.
 .PP
 .I Clean
 prints the block numbers in
--- a/sys/src/cmd/cwfs/chk.c
+++ b/sys/src/cmd/cwfs/chk.c
@@ -81,11 +81,12 @@
 	Cpfile	= (1<<2),	/* print files */
 	Cpdir	= (1<<3),	/* print directories */
 	Cfree	= (1<<4),	/* rebuild free list */
-//	Csetqid	= (1<<5),	/* resequence qids */
+	Csetqid	= (1<<5),	/* resequence qids */
 	Cream	= (1<<6),	/* clear all bad tags */
 	Cbad	= (1<<7),	/* clear all bad blocks */
 	Ctouch	= (1<<8),	/* touch old dir and indir */
-	Ctrim	= (1<<9),   /* trim fsize back to fit when checking free list */
+	Ctrim	= (1<<9),	/* trim fsize back to fit when checking free list */
+	Crtmp	= (1<<10),	/* clear temporary files (after recover) */
 };
 
 static struct {
@@ -102,6 +103,7 @@
 	"bad",		Cbad,
 	"touch",	Ctouch,
 	"trim",		Ctrim,
+	"rtmp",		Crtmp,
 	0,
 };
 
@@ -351,15 +353,16 @@
 	if (p1 = xtag(a, tag, ed->qpath)) {
 		for(i=0; i<INDPERBUF; i++) {
 			a = blkck(&((Off *)p1->iobuf)[i], &p1->flags);
-			if (a)
+			if (a) {
 				/*
 				 * check each block named in this
 				 * indirect(^n) block (a).
 				 */
 				if (tag == Tind1)
-					dmod +=   dirck(ed, a);
+					dmod += dirck(ed, a);
 				else
 					dmod += indirck(ed, a, tag-1);
+			}
 		}
 		putbuf(p1);
 	}
@@ -434,6 +437,21 @@
 	if(edent.qpath > maxq)
 		maxq = edent.qpath;
 
+	/* clear temporary files (after recover) */
+	if((d->mode & DTMP) && (flags & Crtmp)){
+		for(i=0; i<NDBLOCK; i++)
+			d->dblock[i] = 0;
+		for(i=0; i<NIBLOCK; i++)
+			d->iblocks[i] = 0;
+		d->size = 0;
+
+		/* if not directory, delete file */
+		if((d->mode & DDIR) == 0)
+			memset(d, 0, sizeof(Dentry));
+
+		return 1;
+	}
+
 	/* check direct blocks (the common case) */
 	dmod = 0;
 	{
@@ -656,7 +674,7 @@
 	Iobuf *p;
 	Dentry *d;
 
-	if(!(flags & Cbad))
+	if(!(flags & (Cbad|Crtmp)))
 		return;
 	p = getbuf(dev, a, Brd);
 	d = getdir(p, s);
--