[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: