shithub: riscv

Download patch

ref: f97798e710929c0acb2b110c1cc16b1b267039a0
parent: 318cd6fbde65ee5c7a4bd513d185fa57cc61c4cd
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Sun May 19 16:59:55 EDT 2013

devsd: don't raise Enomem error if sdmalloc() fails, instead wait for the memory to become available

filesystems do not handle i/o errors well (cwfs will abandon the blocks),
and temporary exhaustion of kernel memory (because of too many i/o's in
parallel) causes read and write on the partition to fail.

i think it is better to wait for the memory to become available in
this case. the single allocation is at max SDmaxio bytes, which makes
it likely to become available. if we havnt even enought fo that, then
rebooting the machine would be the best option. (aux/reboot)

--- a/sys/src/9/port/devsd.c
+++ b/sys/src/9/port/devsd.c
@@ -847,9 +847,12 @@
 		b = (uchar*)a;
 		allocd = 0;
 	}else{
-		b = sdmalloc(nb*unit->secsize);
-		if(b == nil)
-			error(Enomem);
+		while((b = sdmalloc(nb*unit->secsize)) == nil){
+			if(!waserror()){
+				tsleep(&up->sleep, return0, 0, 100);
+				poperror();
+			}
+		}
 		allocd = 1;
 	}
 	if(waserror()){
@@ -929,8 +932,12 @@
 	}
 
 	data = nil;
-	if(n > 0 && (data = sdmalloc(n)) == nil)
-		error(Enomem);
+	while(n > 0 && (data = sdmalloc(n)) == nil){
+		if(!waserror()){
+			tsleep(&up->sleep, return0, 0, 100);
+			poperror();
+		}
+	}
 	if(waserror()){
 		sdfree(data);
 		r->data = nil;
@@ -1484,8 +1491,7 @@
 			}		
 			if(n < 6 || n > sizeof(req->cmd))
 				error(Ebadarg);
-			if((req = malloc(sizeof(SDreq))) == nil)
-				error(Enomem);
+			req = smalloc(sizeof(SDreq));
 			req->unit = unit;
 			if(waserror()){
 				free(req);
--- a/sys/src/9/port/sdscsi.c
+++ b/sys/src/9/port/sdscsi.c
@@ -384,8 +384,7 @@
 	SDreq *r;
 	long rlen;
 
-	if((r = malloc(sizeof(SDreq))) == nil)
-		error(Enomem);
+	r = smalloc(sizeof(SDreq));
 	r->unit = unit;
 	r->lun = lun;
 again:
--