[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[Nbd] [patch] fix "copy on write" wrong code



Hi,
There are some "bad" places in 2.8.x
- missed memory allocation for diff file name
- wrong place for initialisation of dofmaps
- some problem with expread (only blocksize = DIFFPAGESIZE is supported with '-c' option)
The same problems (except 1-st one presents in 2.7.5)
I tried to fix fix problems - results in attaced patch. Hope it'll be helpful for somebody.
diff -u nbd-2.8.0/nbd-server.c nbd_fix_copy_on_write/nbd-server.c
--- nbd-2.8.0/nbd-server.c	2005-10-19 16:36:04.858192672 +0400
+++ nbd_fix_copy_on_write/nbd-server.c	2005-10-19 16:38:21.296450904 +0400
@@ -536,7 +536,7 @@
 		} else { /* the block is not there */
 			DEBUG2("Page %Lu is not here, we read the original one\n",
 			       (unsigned long long)mapcnt);
-			return rawexpread(a, buf, rdlen, client);
+			if(rawexpread(a, buf, rdlen, client)) return -1;
 		}
 		len-=rdlen; a+=rdlen; buf+=rdlen;
 	}
@@ -666,6 +666,7 @@
                 	if (client->difffile>=0) { 
                 		close(client->difffile);
 				unlink(client->difffilename);
+				free(client->difffilename);
 			}
 			go_on=FALSE;
 			continue;
@@ -758,18 +759,22 @@
 		}
 		g_free(tmpname);
 	}
-
-	if (client->server->flags & F_COPYONWRITE) {
-		snprintf(client->difffilename, 1024, "%s-%s-%d.diff",client->exportname,client->clientname,
-			(int)getpid()) ;
-		client->difffilename[1023]='\0';
-		msg3(LOG_INFO,"About to create map and diff file %s",client->difffilename) ;
-		client->difffile=open(client->difffilename,O_RDWR | O_CREAT | O_TRUNC,0600) ;
-		if (client->difffile<0) err("Could not create diff file (%m)") ;
-		if ((client->difmap=calloc(client->exportsize/DIFFPAGESIZE,sizeof(u32)))==NULL)
-			err("Could not allocate memory") ;
-		for (i=0;i<client->exportsize/DIFFPAGESIZE;i++) client->difmap[i]=(u32)-1 ;
-	}
+	return 0;
+}
+int copyonwrite_prepare(CLIENT* client)
+{
+	off_t i;
+	if ((client->difffilename = malloc(1024))==NULL)
+		err("Failed to allocate string for diff file name");
+	snprintf(client->difffilename, 1024, "%s-%s-%d.diff",client->exportname,client->clientname,
+		(int)getpid()) ;
+	client->difffilename[1023]='\0';
+	msg3(LOG_INFO,"About to create map and diff file %s",client->difffilename) ;
+	client->difffile=open(client->difffilename,O_RDWR | O_CREAT | O_TRUNC,0600) ;
+	if (client->difffile<0) err("Could not create diff file (%m)") ;
+	if ((client->difmap=calloc(client->exportsize/DIFFPAGESIZE,sizeof(u32)))==NULL)
+		err("Could not allocate memory") ;
+	for (i=0;i<client->exportsize/DIFFPAGESIZE;i++) client->difmap[i]=(u32)-1 ;
 
 	return 0;
 }
@@ -801,6 +806,10 @@
 		msg3(LOG_INFO, "size of exported file/device is %lu", (unsigned long long)client->exportsize);
 	}
 
+	if (client->server->flags & F_COPYONWRITE) {
+		copyonwrite_prepare(client);
+	}
+
 	setmysockopt(client->net);
 
 	mainloop(client);

Reply to: