r114: Fixes for copy-on-write from Maxim Syrchin (thanks!)
authoryoe <yoe>
Tue, 25 Oct 2005 11:13:44 +0000 (11:13 +0000)
committeryoe <yoe>
Tue, 25 Oct 2005 11:13:44 +0000 (11:13 +0000)
nbd-server.c

index 9fb9517..b40be93 100644 (file)
@@ -533,7 +533,7 @@ int expread(off_t a, char *buf, size_t len, CLIENT *client) {
                } 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;
        }
@@ -663,6 +663,7 @@ int mainloop(CLIENT *client) {
                        if (client->difffile>=0) { 
                                close(client->difffile);
                                unlink(client->difffilename);
+                               free(client->difffilename);
                        }
                        go_on=FALSE;
                        continue;
@@ -756,18 +757,22 @@ int splitexport(CLIENT* client) {
                }
                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;
 }
@@ -798,6 +803,10 @@ void serveconnection(CLIENT *client) {
                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);