shithub: riscv

Download patch

ref: 118063142163382a1b21f205e982c818fecb4f09
parent: db971a6189e63802b4c7c0ee41bf00e9864f52a7
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Oct 23 11:12:27 EDT 2021

devswap: improve setswapchan()

- check for unusable file types like directories and append-only files.
- we should eigther error without any side effects or succeed.

--- a/sys/src/9/port/devswap.c
+++ b/sys/src/9/port/devswap.c
@@ -383,17 +383,16 @@
 static void
 setswapchan(Chan *c)
 {
+	uvlong s;
+
 	if(waserror()){
 		cclose(c);
 		nexterror();
 	}
-	if(swapimage.c != nil) {
-		if(swapalloc.free != conf.nswap)
-			error(Einuse);
-		cclose(swapimage.c);
-		swapimage.c = nil;
-	}
 
+	if(c->qid.type & (QTDIR|QTAPPEND|QTAUTH))
+		error(Ebadarg);
+
 	/*
 	 *  if this isn't a file, set the swap space
 	 *  to be at most the size of the partition
@@ -400,17 +399,28 @@
 	 */
 	if(devtab[c->type]->dc != L'M'){
 		Dir *d = dirchanstat(c);
-		if(d->length < (vlong)conf.nswppo*BY2PG){
-			free(d);
-			error("swap device too small");
-		}
-		if(d->length < (vlong)conf.nswap*BY2PG){
-			conf.nswap = d->length/BY2PG;
-			swapalloc.top = &swapalloc.swmap[conf.nswap];
-			swapalloc.free = conf.nswap;
-		}
+		s = d->length / BY2PG;
 		free(d);
+	} else {
+		s = conf.nswap;
 	}
+
+	if(s < conf.nswppo)
+		error("swap device too small");
+
+	if(swapimage.c != nil) {
+		if(swapalloc.free != conf.nswap)
+			error(Einuse);
+		cclose(swapimage.c);
+		swapimage.c = nil;
+	}
+
+	if(s < conf.nswap){
+		conf.nswap = s;
+		swapalloc.top = &swapalloc.swmap[conf.nswap];
+		swapalloc.free = conf.nswap;
+	}
+
 	c->flag &= ~CCACHE;
 	cclunk(c);
 	poperror();