Browse Source

Plan 9 from Bell Labs 2007-05-28

David du Colombier 14 years ago
parent
commit
d80a96aa07
4 changed files with 74 additions and 34 deletions
  1. 1 1
      dist/replica/_plan9.db
  2. 1 1
      dist/replica/plan9.db
  3. 1 0
      dist/replica/plan9.log
  4. 71 32
      sys/src/9/port/devfs.c

+ 1 - 1
dist/replica/_plan9.db

@@ -8168,7 +8168,7 @@ sys/src/9/port/devcons.c - 664 sys sys 1176658321 22943
 sys/src/9/port/devdraw.c - 664 sys sys 1147023550 44447
 sys/src/9/port/devdup.c - 664 sys sys 1014931172 2332
 sys/src/9/port/devenv.c - 664 sys sys 1169498893 7015
-sys/src/9/port/devfs.c - 664 sys sys 1179951300 12209
+sys/src/9/port/devfs.c - 664 sys sys 1180249924 13409
 sys/src/9/port/devkbmap.c - 664 sys sys 1130763846 3064
 sys/src/9/port/devkprof.c - 664 sys sys 1014931173 3111
 sys/src/9/port/devloopback.c - 664 sys sys 1138458368 14579

+ 1 - 1
dist/replica/plan9.db

@@ -8168,7 +8168,7 @@ sys/src/9/port/devcons.c - 664 sys sys 1176658321 22943
 sys/src/9/port/devdraw.c - 664 sys sys 1147023550 44447
 sys/src/9/port/devdup.c - 664 sys sys 1014931172 2332
 sys/src/9/port/devenv.c - 664 sys sys 1169498893 7015
-sys/src/9/port/devfs.c - 664 sys sys 1179951300 12209
+sys/src/9/port/devfs.c - 664 sys sys 1180249924 13409
 sys/src/9/port/devkbmap.c - 664 sys sys 1130763846 3064
 sys/src/9/port/devkprof.c - 664 sys sys 1014931173 3111
 sys/src/9/port/devloopback.c - 664 sys sys 1138458368 14579

+ 1 - 0
dist/replica/plan9.log

@@ -49109,3 +49109,4 @@
 1180209622 0 c 386/bin/fossil/flchk - 775 sys sys 1180209225 237116
 1180209622 1 c 386/bin/fossil/flfmt - 775 sys sys 1180209226 245137
 1180209622 2 c 386/bin/fossil/fossil - 775 sys sys 1180209226 363773
+1180251038 0 c sys/src/9/port/devfs.c - 664 sys sys 1180249924 13409

+ 71 - 32
sys/src/9/port/devfs.c

@@ -260,8 +260,11 @@ mconfig(char* a, long n)	/* "name idev0 idev1" */
 		inprv = &mp->inner[i-1];
 		kstrdup(&inprv->iname, cb->f[i]);
 		inprv->idev = namec(inprv->iname, Aopen, ORDWR, 0);
-		if (inprv->idev == nil)
+		if (inprv->idev == nil) {
+			free(mp->name);
+			mp->name = nil;		/* free mp */
 			error(Egreg);
+		}
 		mp->ndevs++;
 	}
 	setdsize(mp);
@@ -412,11 +415,12 @@ mstat(Chan *c, uchar *db, int n)
 static Chan*
 mopen(Chan *c, int omode)
 {
+//	TODO: call devopen()?
 	if((c->qid.type & QTDIR) && omode != OREAD)
 		error(Eperm);
-	if (omode & OTRUNC)
-		omode &= ~OTRUNC;
-	c->mode = openmode(omode);
+//	if (c->flag & COPEN)
+//		return c;
+	c->mode = openmode(omode & ~OTRUNC);
 	c->flag |= COPEN;
 	c->offset = 0;
 	return c;
@@ -436,7 +440,7 @@ io(Fsdev *mp, Inner *in, int isread, void *a, long l, vlong off)
 	Chan *mc = in->idev;
 
 	if (waserror()) {
-		print("#k: %s byte %,lld count %ld (of #k/%s): %s error: %s\n",
+		print("#k: %s: byte %,lld count %ld (of #k/%s): %s error: %s\n",
 			in->iname, off, l, mp->name, (isread? "read": "write"),
 			(up && up->errstr? up->errstr: ""));
 		nexterror();
@@ -524,7 +528,7 @@ interio(Fsdev *mp, int isread, void *a, long n, vlong off)
 static long
 mread(Chan *c, void *a, long n, vlong off)
 {
-	int	i;
+	int	i, retry;
 	long	l, res;
 	Fsdev	*mp;
 	Inner	*in;
@@ -557,19 +561,36 @@ mread(Chan *c, void *a, long n, vlong off)
 		assert(res == n);
 		break;
 	case Fmirror:
-		for (i = 0; i < mp->ndevs; i++){
-			if (waserror())
-				continue;
-			in = &mp->inner[i];
-			l = io(mp, in, Isread, a, n, off);
-			poperror();
-			if (l >= 0){
-				res = l;
-				break;		/* read a good copy */
+		retry = 0;
+		do {
+			if (retry > 0) {
+				print("#k/%s: retry %d read for byte %,lld "
+					"count %ld: %s\n", mp->name, retry, off,
+					n, (up && up->errstr? up->errstr: ""));
+				tsleep(&up->sleep, return0, 0, 2000);
 			}
-		}
-		if (i == mp->ndevs) /* no mirror had a good copy of the block? */
-			error(Eio);	/* RRRT! RRRT!  RAID failure! */
+			for (i = 0; i < mp->ndevs; i++){
+				if (waserror())
+					continue;
+				in = &mp->inner[i];
+				l = io(mp, in, Isread, a, n, off);
+				poperror();
+				if (l >= 0){
+					res = l;
+					break;		/* read a good copy */
+				}
+			}
+		} while (i == mp->ndevs && ++retry < 2);
+		if (i == mp->ndevs) {
+			/* no mirror had a good copy of the block */
+			print("#k/%s: byte %,lld count %ld: CAN'T READ "
+				"from mirror: %s\n", mp->name, off, n,
+				(up && up->errstr? up->errstr: ""));
+			error(Eio);
+		} else if (retry > 0)
+			print("#k/%s: byte %,lld count %ld: retry read OK "
+				"from mirror: %s\n", mp->name, off, n,
+				(up && up->errstr? up->errstr: ""));
 		break;
 	}
 	return res;
@@ -578,7 +599,7 @@ mread(Chan *c, void *a, long n, vlong off)
 static long
 mwrite(Chan *c, void *a, long n, vlong off)
 {
-	int	i, allbad;
+	int	i, allbad, retry;
 	long	l, res;
 	Fsdev	*mp;
 	Inner	*in;
@@ -612,19 +633,37 @@ mwrite(Chan *c, void *a, long n, vlong off)
 			res = n;
 		break;
 	case Fmirror:
-		allbad = 1;
-		for (i = mp->ndevs - 1; i >= 0; i--){
-			if (waserror())
-				continue;
-			in = &mp->inner[i];
-			l = io(mp, in, Iswrite, a, n, off);
-			poperror();
-			if (res > l)
-				res = l;	/* shortest OK write */
-			allbad = 0;		/* wrote a good copy */
-		}
-		if (allbad)	/* no mirror took a good copy of the block? */
-			error(Eio);	/* RRRT! RRRT!  RAID failure! */
+		retry = 0;
+		do {
+			if (retry > 0) {
+				print("#k/%s: retry %d write for byte %,lld "
+					"count %ld: %s\n", mp->name, retry, off,
+					n, (up && up->errstr? up->errstr: ""));
+				tsleep(&up->sleep, return0, 0, 2000);
+			}
+			allbad = 1;
+			for (i = mp->ndevs - 1; i >= 0; i--){
+				if (waserror())
+					continue;
+				in = &mp->inner[i];
+				l = io(mp, in, Iswrite, a, n, off);
+				poperror();
+				if (res > l)
+					res = l;	/* shortest OK write */
+				allbad = 0;		/* wrote a good copy */
+			}
+		} while (allbad && ++retry < 2);
+		if (allbad) {
+			/* no mirror took a good copy of the block */
+			print("#k/%s: byte %,lld count %ld: CAN'T WRITE "
+				"to mirror: %s\n", mp->name, off, n,
+				(up && up->errstr? up->errstr: ""));
+			error(Eio);
+		} else if (retry > 0)
+			print("#k/%s: byte %,lld count %ld: retry wrote OK "
+				"to mirror: %s\n", mp->name, off, n,
+				(up && up->errstr? up->errstr: ""));
+
 		break;
 	}
 	return res;