[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha6-987-g053e187

Steven Danneman sdanneman at samba.org
Thu Feb 19 05:08:59 GMT 2009


The branch, master has been updated
       via  053e1873c5dd30e7bb3102692ba79e280034c392 (commit)
       via  176e8857203944bc332844b700749120ce90c891 (commit)
       via  8e8aa27e1b1366c8c4e3cf6d8a681fec80cca858 (commit)
      from  c19214424b0f8ca0dfa5970880e54807880c443c (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 053e1873c5dd30e7bb3102692ba79e280034c392
Author: Zack Kirsch <zack.kirsch at isilon.com>
Date:   Wed Feb 18 20:39:20 2009 -0800

    s3: OneFS: Pass in the client's fnum to the ifs_cbrl syscall.

commit 176e8857203944bc332844b700749120ce90c891
Author: Aravind Srinivasan <aravind.srinivasan at isilon.com>
Date:   Wed Feb 18 18:26:39 2009 -0800

    s3: Fix OneFS bug opening streams with truncating disposition
    
    Do not attempt to delete streams on a truncating open, if the name we're
    opening is itself a stream

commit 8e8aa27e1b1366c8c4e3cf6d8a681fec80cca858
Author: Aravind Srinivasan <aravind.srinivasan at isilon.com>
Date:   Wed Feb 18 17:36:25 2009 -0800

    s3: Fix streams enumeration bug in OneFS implementation
    
    Previously, we didn’t call SMB_VFS_OPEN_DIR from the streams module,
    instead we called fdopendir(). As a result we failed to populate the
    dir_state list in the readdirplus module. So when we tried to view the
    stream data, we will always returned NULL.
    
    To solve this I separated onefs_opendir() and the initialization of
    the dir_state list. This is done by introducing a new utility function
    “onefs_rdp_add_dir_state()”, which initializes the dir_state structure
    and adds it to the dir_state list.  This function is called from the
    streams module before calling readdir().

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

Summary of changes:
 source3/modules/onefs.h         |    3 ++
 source3/modules/onefs_cbrl.c    |    7 ++--
 source3/modules/onefs_dir.c     |   70 +++++++++++++++++++++++++++++----------
 source3/modules/onefs_open.c    |    2 +-
 source3/modules/onefs_streams.c |   13 +++++++
 5 files changed, 73 insertions(+), 22 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/modules/onefs.h b/source3/modules/onefs.h
index b979cfd..c002739 100644
--- a/source3/modules/onefs.h
+++ b/source3/modules/onefs.h
@@ -224,6 +224,9 @@ NTSTATUS onefs_split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
 
 bool onefs_get_config(int snum, int config_type,
 		      struct onefs_vfs_config *cfg);
+
+int onefs_rdp_add_dir_state(connection_struct *conn, SMB_STRUCT_DIR *dirp);
+
 /*
  * System Interfaces
  */
diff --git a/source3/modules/onefs_cbrl.c b/source3/modules/onefs_cbrl.c
index 539b1a7..a860023 100644
--- a/source3/modules/onefs_cbrl.c
+++ b/source3/modules/onefs_cbrl.c
@@ -318,7 +318,8 @@ NTSTATUS onefs_brl_lock_windows(vfs_handle_struct *handle,
 
 	DEBUG(10, ("Calling ifs_cbrl(LOCK)..."));
 	error = ifs_cbrl(fd, CBRL_OP_LOCK, exclusive, plock->start,
-	    plock->size, async, id, plock->context.smbpid, plock->context.tid);
+	    plock->size, async, id, plock->context.smbpid, plock->context.tid,
+	    plock->fnum);
 	if (!error) {
 		goto success;
 	} else if (errno == EWOULDBLOCK) {
@@ -376,7 +377,7 @@ bool onefs_brl_unlock_windows(vfs_handle_struct *handle,
 	DEBUG(10, ("Calling ifs_cbrl(UNLOCK)..."));
 	error = ifs_cbrl(fd, CBRL_OP_UNLOCK, CBRL_NOTYPE,
 	    plock->start, plock->size, CBRL_NOTYPE, 0, plock->context.smbpid,
-	    plock->context.tid);
+	    plock->context.tid, plock->fnum);
 	if (error) {
 		DEBUG(10, ("returning false.\n"));
 		return false;
@@ -425,7 +426,7 @@ bool onefs_brl_cancel_windows(vfs_handle_struct *handle,
 	DEBUG(10, ("Calling ifs_cbrl(CANCEL)..."));
 	error = ifs_cbrl(fd, CBRL_OP_CANCEL, CBRL_NOTYPE, plock->start,
 	    plock->size, CBRL_NOTYPE, bs->id, plock->context.smbpid,
-	    plock->context.tid);
+	    plock->context.tid, plock->fnum);
 	if (error) {
 		DEBUG(10, ("returning false\n"));
 		bs->state = ONEFS_CBRL_ERROR;
diff --git a/source3/modules/onefs_dir.c b/source3/modules/onefs_dir.c
index 3c1a836..83622b2 100644
--- a/source3/modules/onefs_dir.c
+++ b/source3/modules/onefs_dir.c
@@ -183,6 +183,54 @@ rdp_fill_cache(struct rdp_dir_state *dsp)
 }
 
 /**
+ * Create a dir_state to track an open directory that we're enumerating.
+ *
+ * This utility function is globally accessible for use by other parts of the
+ * onefs.so module to initialize a dir_state when a directory is opened through
+ * a path other than the VFS layer.
+ *
+ * @return 0 on success and errno on failure
+ *
+ * @note: Callers of this function MUST cleanup the dir_state through a proper
+ * call to VFS_CLOSEDIR().
+ */
+int
+onefs_rdp_add_dir_state(connection_struct *conn, SMB_STRUCT_DIR *dirp)
+{
+	int ret = 0;
+	struct rdp_dir_state *dsp = NULL;
+
+	/* No-op if readdirplus is disabled */
+	if (!lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
+	    PARM_USE_READDIRPLUS, PARM_USE_READDIRPLUS_DEFAULT))
+	{
+		return 0;
+	}
+
+	/* Create a struct dir_state */
+	dsp = SMB_MALLOC_P(struct rdp_dir_state);
+	if (!dsp) {
+		DEBUG(0, ("Error allocating struct rdp_dir_state.\n"));
+		return ENOMEM;
+	}
+
+	/* Initialize the dir_state structure and add it to the list */
+	ret = rdp_init(dsp);
+	if (ret) {
+		DEBUG(0, ("Error initializing readdirplus() buffers: %s\n",
+			 strerror(ret)));
+		return ret;
+	}
+
+	/* Set the SMB_STRUCT_DIR in the dsp */
+	dsp->dirp = dirp;
+
+	DLIST_ADD(dirstatelist, dsp);
+
+	return 0;
+}
+
+/**
  * Open a directory for enumeration.
  *
  * Create a state struct to track the state of this directory for the life
@@ -201,7 +249,6 @@ onefs_opendir(vfs_handle_struct *handle, const char *fname, const char *mask,
 {
 	int ret = 0;
 	SMB_STRUCT_DIR *ret_dirp;
-	struct rdp_dir_state *dsp = NULL;
 
 	/* Fallback to default system routines if readdirplus is disabled */
 	if (!lp_parm_bool(SNUM(handle->conn), PARM_ONEFS_TYPE,
@@ -210,13 +257,6 @@ onefs_opendir(vfs_handle_struct *handle, const char *fname, const char *mask,
 		return SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr);
 	}
 
-	/* Create a struct dir_state */
-	dsp = SMB_MALLOC_P(struct rdp_dir_state);
-	if (!dsp) {
-		DEBUG(0, ("Error allocating struct rdp_dir_state.\n"));
-		return NULL;
-	}
-
 	/* Open the directory */
 	ret_dirp = SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr);
 	if (!ret_dirp) {
@@ -224,21 +264,15 @@ onefs_opendir(vfs_handle_struct *handle, const char *fname, const char *mask,
 		return NULL;
 	}
 
-	/* Initialize the dir_state structure and add it to the list */
-	ret = rdp_init(dsp);
+	/* Create the dir_state struct and add it to the list */
+	ret = onefs_rdp_add_dir_state(handle->conn, ret_dirp);
 	if (ret) {
-		DEBUG(0, ("Error initializing readdirplus() buffers: %s\n",
-		    strerror(ret)));
+		DEBUG(0, ("Error adding dir_state to the list\n"));
 		return NULL;
 	}
 
-	/* Set the SMB_STRUCT_DIR in the dsp */
-	dsp->dirp = ret_dirp;
-
-	DLIST_ADD(dirstatelist, dsp);
-
 	DEBUG(9, ("Opened handle on directory: \"%s\", DIR %p\n",
-		 fname, dsp->dirp));
+		 fname, ret_dirp));
 
 	return ret_dirp;
 }
diff --git a/source3/modules/onefs_open.c b/source3/modules/onefs_open.c
index 1f5f855..382ecc6 100644
--- a/source3/modules/onefs_open.c
+++ b/source3/modules/onefs_open.c
@@ -1185,7 +1185,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
 	SMB_ASSERT(lck != NULL);
 
 	/* Delete streams if create_disposition requires it */
-	if (file_existed && clear_ads) {
+	if (file_existed && clear_ads && !is_ntfs_stream_name(fname)) {
 		status = delete_all_streams(conn, fname);
 		if (!NT_STATUS_IS_OK(status)) {
 			TALLOC_FREE(lck);
diff --git a/source3/modules/onefs_streams.c b/source3/modules/onefs_streams.c
index d0dd75f..9616ca4 100644
--- a/source3/modules/onefs_streams.c
+++ b/source3/modules/onefs_streams.c
@@ -540,6 +540,19 @@ static NTSTATUS walk_onefs_streams(connection_struct *conn, files_struct *fsp,
 		goto out;
 	}
 
+	/* Initialize the dir state struct and add it to the list.
+	 * This is a layer violation, and really should be handled by a
+	 * VFS_FDOPENDIR() call which would properly setup the dir state.
+	 * But since this is all within the onefs.so module, we cheat for
+	 * now and call directly into the readdirplus code.
+	 * NOTE: This state MUST be freed by a proper VFS_CLOSEDIR() call. */
+	ret = onefs_rdp_add_dir_state(conn, dirp);
+	if (ret) {
+		DEBUG(0, ("Error adding dir_state to the list\n"));
+		status = map_nt_error_from_unix(errno);
+		goto out;
+	}
+
 	fake_fs.conn = conn;
 	fake_fs.fh = &fake_fh;
 	fake_fs.fsp_name = SMB_STRDUP(fname);


-- 
Samba Shared Repository


More information about the samba-cvs mailing list