[vhffs-dev] [1287] Fixed a bug when a file is moved while it is being uploaded.

[ Thread Index | Date Index | More vhffs.org/vhffs-dev Archives ]


Revision: 1287
Author:   gradator
Date:     2008-10-15 22:59:19 +0200 (Wed, 15 Oct 2008)

Log Message:
-----------
Fixed a bug when a file is moved while it is being uploaded. Both the master and the slave now keep a FILE* opened while sending/receiving the file. Therefore it also improves slighty the performance of the slave by reducing drastically the amount of useless fopen/fclose. However, in case of massive changes, it can reach the maximum number of opened fd...

Modified Paths:
--------------
    trunk/vhffs-fssync/vhffsfssync_master.c
    trunk/vhffs-fssync/vhffsfssync_slave.c


Modified: trunk/vhffs-fssync/vhffsfssync_master.c
===================================================================
--- trunk/vhffs-fssync/vhffsfssync_master.c	2008-10-15 05:25:31 UTC (rev 1286)
+++ trunk/vhffs-fssync/vhffsfssync_master.c	2008-10-15 20:59:19 UTC (rev 1287)
@@ -432,6 +432,7 @@
 		}
 	}
 
+	vhffsfssync_net_send_event(conn, g_strdup_printf("close%c%s%c", '\0', filemsg->file_pathname, '\0') , VHFFSFSSYNC_NET_PRIO_MEDIUM);
 	vhffsfssync_net_file_close(conn, filemsg->file_stream);
 	free(filemsg->file_pathname);
 	free(filemsg);
@@ -462,7 +463,7 @@
 			if(msg->msg_family == VHFFSFSSYNC_NET_MESSAGE_FILE)  {
 				vhffsfssync_net_message_file *filemsg = (vhffsfssync_net_message_file*)msg;
 
-				if(filemsg->file_stream  &&  filemsg->file_chunksize < 0) {
+				if(filemsg->file_stream  &&  !filemsg->file_offset  &&  filemsg->file_chunksize < 0) {
 					vhffsfssync_net_file_close(conn, filemsg->file_stream);
 					filemsg->file_stream = NULL;
 					break;

Modified: trunk/vhffs-fssync/vhffsfssync_slave.c
===================================================================
--- trunk/vhffs-fssync/vhffsfssync_slave.c	2008-10-15 05:25:31 UTC (rev 1286)
+++ trunk/vhffs-fssync/vhffsfssync_slave.c	2008-10-15 20:59:19 UTC (rev 1287)
@@ -49,6 +49,8 @@
 	vhffsfssync_net_message **messages;
 	uint32_t messages_begin;
 	uint32_t messages_end;
+
+	GHashTable *openfiles;
 } vhffsfssync_conn;
 
 // network protos
@@ -341,14 +343,27 @@
 		char *pathname = args[1];
 		int fd;
 
-		fd = open(pathname, O_CREAT|O_WRONLY|O_TRUNC, 0644);
-		if(fd >= 0) {
-			close(fd);
+		if( !g_hash_table_lookup(conn->openfiles, pathname) ) {
+			fd = open(pathname, O_CREAT|O_WRONLY|O_TRUNC, 0644);
+			if(fd >= 0) {
+				FILE *f = fdopen(fd, "w");
+				if(f) {
+					g_hash_table_insert(conn->openfiles, strdup(pathname), f);
+				}
+				else {
+					fprintf(stderr, "fdopen() failed on %s: %s\n", pathname, strerror(errno));
+					close(fd);
+				}
+			}
+			else {
+				fprintf(stderr, "open() failed on %s: %s\n", pathname, strerror(errno));
+			}
 		}
-		else {
-			fprintf(stderr, "open() failed on %s: %s\n", pathname, strerror(errno));
-		}
 	}
+	else if(!strcmp(args[0], "close")) {
+		char *pathname = args[1];
+		g_hash_table_remove(conn->openfiles, pathname);
+	}
 	else if(!strcmp(args[0], "mkdir")) {
 		char *path = args[1];
 		vhffsfssync_mkdir(path, 0755);
@@ -369,19 +384,23 @@
 		ssize_t size = atol(args[3]);
 		int fd;
 
+		//printf("FILE: %s %lld %d\n", pathname, offset, size);
+
 		conn->chunk_stilltoread = size;
 
-		//printf("FILE: %s %lld %d\n", pathname, offset, size);
-		if(size > 0) {
-			fd = open(pathname, O_CREAT|O_WRONLY, 0644);
+		conn->chunk_file = g_hash_table_lookup(conn->openfiles, pathname);
+		if(!conn->chunk_file) {
+			int flags;
+
+			flags = O_CREAT|O_WRONLY;
+			if(!size) flags |= O_TRUNC;   // just in case
+
+			fd = open(pathname, flags, 0644);
 			if(fd >= 0) {
-				conn->chunk_file = fdopen(fd, "w");
-				if(conn->chunk_file) {
-					if( fseeko(conn->chunk_file, offset, SEEK_SET) < 0 ) {
-						fprintf(stderr, "fseeko() on %lld failed on file %s: %s\n", (long long int)offset, pathname, strerror(errno));
-						fclose(conn->chunk_file);
-						conn->chunk_file = NULL;
-					}
+				FILE *f = fdopen(fd, "w");
+				if(f) {
+					g_hash_table_insert(conn->openfiles, strdup(pathname), f);
+					conn->chunk_file = f;
 				}
 				else {
 					fprintf(stderr, "fdopen() failed on %s: %s\n", pathname, strerror(errno));
@@ -392,14 +411,11 @@
 				fprintf(stderr, "open() failed on %s: %s\n", pathname, strerror(errno));
 			}
 		}
-		else {
-			fd = open(pathname, O_CREAT|O_WRONLY|O_TRUNC, 0644);
-			if(fd >= 0) {
-				close(fd);
-			}
-			else {
-				fprintf(stderr, "open() failed on %s: %s\n", pathname, strerror(errno));
-			}
+
+		if(conn->chunk_file  &&  fseeko(conn->chunk_file, offset, SEEK_SET) < 0 ) {
+			fprintf(stderr, "fseeko() on %lld failed on file %s: %s\n", (long long int)offset, pathname, strerror(errno));
+			g_hash_table_remove(conn->openfiles, pathname);
+			conn->chunk_file = NULL;
 		}
 	}
 	else if(!strcmp(args[0], "ls")) {
@@ -535,10 +551,6 @@
 					fprintf(stderr, "fwrite() failed: %s\n", strerror(errno));
 				}
 				if(!conn->chunk_stilltoread) {
-#if DEBUG_EVENTS
-					printf("  closing file\n");
-#endif
-					fclose(conn->chunk_file);
 					conn->chunk_file = NULL;
 				}
 			}
@@ -592,6 +604,7 @@
 	conn->messages = NULL;
 	conn->messages_begin = 0;
 	conn->messages_end = 0;
+	conn->openfiles = NULL;
 
 	/* -- main loop -- */
 	while(1)  {
@@ -602,7 +615,8 @@
 		}
 		conn->fd = -1;
 
-		if(conn->chunk_file) fclose(conn->chunk_file);
+		if(conn->openfiles) g_hash_table_destroy( conn->openfiles );
+		conn->openfiles = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (gpointer)fclose);
 		conn->chunk_file = NULL;
 
 		if(conn->messages) {


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/