git: 9front

Download patch

ref: 5957ab2e134978dae940f8fa758f2068947067dc
parent: 15db432de0a8add7d221b1397114f3f6c240b923
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Mon Jan 30 18:17:18 EST 2017

cwfs: handle worm exhaustion more gracefully

don't deadlock when cwgrow() detects we'r out of worm space
by releasing the cache superblock buffer.

don't allocate space beyond the worm device when dumping by
having slit() check. after cwrecur(), we check if there are
enougth blocks remaining to write the dump date directories
and superblocks.

--- a/sys/src/cmd/cwfs/cw.c
+++ b/sys/src/cmd/cwfs/cw.c
@@ -55,6 +55,7 @@
  * following are cached variables for dumps
  */
 	Off	fsize;
+	Off	wsize;
 	Off	ndump;
 	int	depth;
 	int	all;		/* local flag to recur on modified dirs */
@@ -440,6 +441,7 @@
 		h->wsize = l;
 		cb->flags |= Bmod;
 	}
+	cw->wsize = l;
 
 	for(m=0; m<h->msize; m++) {
 		p = getbuf(cw->cdev, h->maddr + m/BKPERBLK, Brd);
@@ -768,8 +770,10 @@
 	h = (Cache*)cb->iobuf;
 	ws = h->wsize;
 	fs = h->fsize;
-	if(fs >= ws)
+	if(fs >= ws){
+		putbuf(cb);
 		return 0;
+	}
 	nfs = fs + ADDFREE;
 	if(nfs >= ws)
 		nfs = ws;
@@ -1259,6 +1263,10 @@
 
 	case Cdump1:
 	case Cwrite:
+		/* worm full */
+		if(cw->fsize >= cw->wsize)
+			break;
+
 		/*
 		 * botch.. could be done by relabeling
 		 */
@@ -1269,9 +1277,7 @@
 				break;
 			}
 		}
-
-		na = cw->fsize;
-		cw->fsize = na+1;
+		na = cw->fsize++;
 		cwio(cw->dev, na, 0, Ogrow);
 		cwio(cw->dev, na, p->iobuf, Owrite);
 		cwio(cw->dev, na, 0, Odump);
@@ -1523,6 +1529,11 @@
 	h->cwraddr = rba;
 	putbuf(p);
 
+	if(cw->fsize+50 > cw->wsize){
+		fprint(2, "dump: worm full after dump\n");
+		goto done;
+	}
+
 	/*
 	 * ro root
 	 */
@@ -1642,8 +1653,7 @@
 	s = (Superb*)p->iobuf;
 	s->last = a;
 	sba = s->next;
-	s->next = cw->fsize;
-	cw->fsize++;
+	s->next = cw->fsize++;
 	s->fsize = cw->fsize;
 	s->roraddr = roa;
 
@@ -1667,6 +1677,7 @@
 	h->sbaddr = sba;
 	putbuf(p);
 
+done:
 	rewalk(cw);
 	sync("all done");
 
--