[SCM] Samba Shared Repository - branch v3-2-test updated - release-3-2-0pre2-3210-g8a60128

Jeremy Allison jra at samba.org
Mon Dec 1 21:54:58 GMT 2008


The branch, v3-2-test has been updated
       via  8a60128ff7960f2f19055f8e320d1d58fd87c84f (commit)
      from  b095db2f9db084798a8e6d2bc44a6215f4038658 (commit)

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


- Log -----------------------------------------------------------------
commit 8a60128ff7960f2f19055f8e320d1d58fd87c84f
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Dec 1 13:54:19 2008 -0800

    s3:streams_xattr: add support for renaming streams
    
    metze

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

Summary of changes:
 source/modules/vfs_streams_xattr.c |  143 +++++++++++++++++++++++++++++++++++-
 1 files changed, 142 insertions(+), 1 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/modules/vfs_streams_xattr.c b/source/modules/vfs_streams_xattr.c
index 2ea5336..e96f616 100644
--- a/source/modules/vfs_streams_xattr.c
+++ b/source/modules/vfs_streams_xattr.c
@@ -94,7 +94,7 @@ static int streams_xattr_fstat(vfs_handle_struct *handle, files_struct *fsp,
 
 	DEBUG(10, ("streams_xattr_fstat called for %d\n", fsp->fh->fd));
 
-	if (io == NULL) {
+	if (io == NULL || fsp->base_fsp == NULL) {
 		return SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
 	}
 
@@ -136,6 +136,10 @@ static int streams_xattr_stat(vfs_handle_struct *handle, const char *fname,
 		return -1;
 	}
 
+	if (sname == NULL){
+		return SMB_VFS_NEXT_STAT(handle, base, sbuf);
+	}
+
 	if (SMB_VFS_STAT(handle->conn, base, sbuf) == -1) {
 		goto fail;
 	}
@@ -183,6 +187,10 @@ static int streams_xattr_lstat(vfs_handle_struct *handle, const char *fname,
 		goto fail;
 	}
 
+	if (sname == NULL){
+		return SMB_VFS_NEXT_LSTAT(handle, base, sbuf);
+	}
+
 	if (SMB_VFS_LSTAT(handle->conn, base, sbuf) == -1) {
 		goto fail;
 	}
@@ -239,6 +247,12 @@ static int streams_xattr_open(vfs_handle_struct *handle,  const char *fname,
 		goto fail;
 	}
 
+	if (sname == NULL) {
+		hostfd = SMB_VFS_NEXT_OPEN(handle, base, fsp, flags, mode);
+		talloc_free(frame);
+		return hostfd;
+	}
+
 	xattr_name = talloc_asprintf(talloc_tos(), "%s%s",
 				     SAMBA_XATTR_DOSSTREAM_PREFIX, sname);
 	if (xattr_name == NULL) {
@@ -391,6 +405,10 @@ static int streams_xattr_unlink(vfs_handle_struct *handle,  const char *fname)
 		goto fail;
 	}
 
+	if (sname == NULL){
+		return SMB_VFS_NEXT_UNLINK(handle, base);
+	}
+
 	xattr_name = talloc_asprintf(talloc_tos(), "%s%s",
 				     SAMBA_XATTR_DOSSTREAM_PREFIX, sname);
 	if (xattr_name == NULL) {
@@ -413,6 +431,127 @@ static int streams_xattr_unlink(vfs_handle_struct *handle,  const char *fname)
 	return ret;
 }
 
+static int streams_xattr_rename(vfs_handle_struct *handle,
+				const char *oldname,
+				const char *newname)
+{
+	NTSTATUS status;
+	TALLOC_CTX *frame = NULL;
+	char *obase;
+	char *ostream;
+	char *nbase;
+	char *nstream;
+	const char *base;
+	int ret = -1;
+	char *oxattr_name;
+	char *nxattr_name;
+	bool o_is_stream;
+	bool n_is_stream;
+	ssize_t oret;
+	ssize_t nret;
+	struct ea_struct ea;
+
+	o_is_stream = is_ntfs_stream_name(oldname);
+	n_is_stream = is_ntfs_stream_name(newname);
+
+	if (!o_is_stream && !n_is_stream) {
+		return SMB_VFS_NEXT_RENAME(handle, oldname, newname);
+	}
+
+	if (!(o_is_stream && n_is_stream)) {
+		errno = ENOSYS;
+		goto fail;
+	}
+
+	frame = talloc_stackframe();
+	if (!frame) {
+		goto fail;
+	}
+
+	status = split_ntfs_stream_name(talloc_tos(), oldname, &obase, &ostream);
+	if (!NT_STATUS_IS_OK(status)) {
+		errno = EINVAL;
+		goto fail;
+	}
+
+	status = split_ntfs_stream_name(talloc_tos(), newname, &nbase, &nstream);
+	if (!NT_STATUS_IS_OK(status)) {
+		errno = EINVAL;
+		goto fail;
+	}
+
+	/*TODO: maybe call SMB_VFS_NEXT_RENAME() both streams are NULL (::$DATA) */
+	if (ostream == NULL) {
+		errno = ENOSYS;
+		goto fail;
+	}
+
+	if (nstream == NULL) {
+		errno = ENOSYS;
+		goto fail;
+	}
+
+	/* the new base should be empty */
+	if (StrCaseCmp(obase, nbase) != 0) {
+		errno = ENOSYS;
+		goto fail;
+	}
+
+	if (StrCaseCmp(ostream, nstream) == 0) {
+		goto done;
+	}
+
+	base = obase;
+
+	oxattr_name = talloc_asprintf(talloc_tos(), "%s%s",
+				      SAMBA_XATTR_DOSSTREAM_PREFIX, ostream);
+	if (oxattr_name == NULL) {
+		errno = ENOMEM;
+		goto fail;
+	}
+
+	nxattr_name = talloc_asprintf(talloc_tos(), "%s%s",
+				      SAMBA_XATTR_DOSSTREAM_PREFIX, nstream);
+	if (nxattr_name == NULL) {
+		errno = ENOMEM;
+		goto fail;
+	}
+
+	/* read the old stream */
+	status = get_ea_value(talloc_tos(), handle->conn, NULL,
+			      base, oxattr_name, &ea);
+	if (!NT_STATUS_IS_OK(status)) {
+		errno = ENOENT;
+		goto fail;
+	}
+
+	/* (over)write the new stream */
+	nret = SMB_VFS_SETXATTR(handle->conn, base, nxattr_name,
+				ea.value.data, ea.value.length, 0);
+	if (nret < 0) {
+		if (errno == ENOATTR) {
+			errno = ENOENT;
+		}
+		goto fail;
+	}
+
+	/* remove the old stream */
+	oret = SMB_VFS_REMOVEXATTR(handle->conn, base, oxattr_name);
+	if (oret < 0) {
+		if (errno == ENOATTR) {
+			errno = ENOENT;
+		}
+		goto fail;
+	}
+
+ done:
+	errno = 0;
+	ret = 0;
+ fail:
+	TALLOC_FREE(frame);
+	return ret;
+}
+
 static NTSTATUS walk_xattr_streams(connection_struct *conn, files_struct *fsp,
 				   const char *fname,
 				   bool (*fn)(struct ea_struct *ea,
@@ -761,6 +900,8 @@ static vfs_op_tuple streams_xattr_ops[] = {
 	 SMB_VFS_LAYER_TRANSPARENT},
 	{SMB_VFS_OP(streams_xattr_unlink), SMB_VFS_OP_UNLINK,
 	 SMB_VFS_LAYER_TRANSPARENT},
+	{SMB_VFS_OP(streams_xattr_rename), SMB_VFS_OP_RENAME,
+	 SMB_VFS_LAYER_TRANSPARENT},
         {SMB_VFS_OP(streams_xattr_ftruncate),  SMB_VFS_OP_FTRUNCATE,
          SMB_VFS_LAYER_TRANSPARENT},
 	{SMB_VFS_OP(streams_xattr_streaminfo), SMB_VFS_OP_STREAMINFO,


-- 
Samba Shared Repository


More information about the samba-cvs mailing list