[SCM] Samba Shared Repository - branch v3-4-test updated - release-4-0-0alpha7-1008-gf223438

Volker Lendecke vlendec at samba.org
Mon May 18 08:46:08 GMT 2009


The branch, v3-4-test has been updated
       via  f22343874833397afb2010a43ee0057fa5d8471e (commit)
       via  413a76cef78de56087574a875a1c478603d5d090 (commit)
       via  f64959ee16214b224225d5b43dfb822ecd772d99 (commit)
      from  7d791d813e9ca9cb1733d312dc040737b67f4bf4 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-4-test


- Log -----------------------------------------------------------------
commit f22343874833397afb2010a43ee0057fa5d8471e
Author: Volker Lendecke <vl at samba.org>
Date:   Mon May 18 09:49:23 2009 +0200

    In aio_fork, we have to close all fd's, we might hold a gpfs share mode
    
    Keeping such an fd open prohibits another open of that same file.

commit 413a76cef78de56087574a875a1c478603d5d090
Author: Volker Lendecke <vl at samba.org>
Date:   Mon May 18 09:46:05 2009 +0200

    Add "file_walk_table" to do stuff with all open files

commit f64959ee16214b224225d5b43dfb822ecd772d99
Author: Volker Lendecke <vl at samba.org>
Date:   Mon May 18 09:36:16 2009 +0200

    Fix a race condition in vfs_aio_fork with gpfs share modes

-----------------------------------------------------------------------

Summary of changes:
 source3/include/proto.h        |    4 ++++
 source3/modules/vfs_aio_fork.c |   26 ++++++++++++++++++++++++--
 source3/smbd/files.c           |   22 ++++++++++++++++++++++
 3 files changed, 50 insertions(+), 2 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/proto.h b/source3/include/proto.h
index 718e0a9..99cd1aa 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -6368,6 +6368,10 @@ void file_close_pid(uint16 smbpid, int vuid);
 void file_init(void);
 void file_close_user(int vuid);
 void file_dump_open_table(void);
+struct files_struct *file_walk_table(
+	struct files_struct *(*fn)(struct files_struct *fsp,
+				   void *private_data),
+	void *private_data);
 files_struct *file_find_fd(int fd);
 files_struct *file_find_dif(struct file_id id, unsigned long gen_id);
 files_struct *file_find_fsp(files_struct *orig_fsp);
diff --git a/source3/modules/vfs_aio_fork.c b/source3/modules/vfs_aio_fork.c
index e29ce5e..578059a 100644
--- a/source3/modules/vfs_aio_fork.c
+++ b/source3/modules/vfs_aio_fork.c
@@ -357,6 +357,14 @@ static void aio_child_loop(int sockfd, struct mmap_area *map)
 			ret_struct.ret_errno = errno;
 		}
 
+		/*
+		 * Close the fd before telling our parent we're done. The
+		 * parent might close and re-open the file very quickly, and
+		 * with system-level share modes (GPFS) we would get an
+		 * unjustified SHARING_VIOLATION.
+		 */
+		close(fd);
+
 		ret = write_data(sockfd, (char *)&ret_struct,
 				 sizeof(ret_struct));
 		if (ret != sizeof(ret_struct)) {
@@ -364,8 +372,6 @@ static void aio_child_loop(int sockfd, struct mmap_area *map)
 				   strerror(errno)));
 			exit(2);
 		}
-
-		close(fd);
 	}
 }
 
@@ -417,6 +423,21 @@ static int aio_child_destructor(struct aio_child *child)
 	return 0;
 }
 
+/*
+ * We have to close all fd's in open files, we might incorrectly hold a system
+ * level share mode on a file.
+ */
+
+static struct files_struct *close_fsp_fd(struct files_struct *fsp,
+					 void *private_data)
+{
+	if ((fsp->fh != NULL) && (fsp->fh->fd != -1)) {
+		close(fsp->fh->fd);
+		fsp->fh->fd = -1;
+	}
+	return NULL;
+}
+
 static NTSTATUS create_aio_child(struct aio_child_list *children,
 				 size_t map_size,
 				 struct aio_child **presult)
@@ -455,6 +476,7 @@ static NTSTATUS create_aio_child(struct aio_child_list *children,
 	if (result->pid == 0) {
 		close(fdpair[0]);
 		result->sockfd = fdpair[1];
+		file_walk_table(close_fsp_fd, NULL);
 		aio_child_loop(result->sockfd, result->map);
 	}
 
diff --git a/source3/smbd/files.c b/source3/smbd/files.c
index 36e80a0..a2200fc 100644
--- a/source3/smbd/files.c
+++ b/source3/smbd/files.c
@@ -204,6 +204,28 @@ void file_close_user(int vuid)
 	}
 }
 
+/*
+ * Walk the files table until "fn" returns non-NULL
+ */
+
+struct files_struct *file_walk_table(
+	struct files_struct *(*fn)(struct files_struct *fsp,
+				   void *private_data),
+	void *private_data)
+{
+	struct files_struct *fsp, *next;
+
+	for (fsp = Files; fsp; fsp = next) {
+		struct files_struct *ret;
+		next = fsp->next;
+		ret = fn(fsp, private_data);
+		if (ret != NULL) {
+			return ret;
+		}
+	}
+	return NULL;
+}
+
 /****************************************************************************
  Debug to enumerate all open files in the smbd.
 ****************************************************************************/


-- 
Samba Shared Repository


More information about the samba-cvs mailing list