[SCM] Samba Shared Repository - branch master updated

Björn Jacke bjacke at samba.org
Mon Mar 8 09:21:04 MST 2010


The branch, master has been updated
       via  2f1fa4f... s3: add man page for vfs_crossrename
       via  0769a18... s3: add vfs_crossrename
       via  583de7b... s3: remove cross-device rename support from vfs_default
      from  f4cb528... samba: remove cifs-utils tools from build systems

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


- Log -----------------------------------------------------------------
commit 2f1fa4f8ca020c5d96bd3ac8706c54cd881aaa03
Author: Björn Jacke <bj at sernet.de>
Date:   Mon Mar 8 12:38:38 2010 +0100

    s3: add man page for vfs_crossrename

commit 0769a1833aff2057e7f6ab05713d7fd6886d6040
Author: Björn Jacke <bj at sernet.de>
Date:   Mon Mar 8 12:59:40 2010 +0100

    s3: add vfs_crossrename
    
    this module adds optional server-side support for limited rename operations
    beyond filesystem boundaries, which was the previously the default.

commit 583de7b582956d3bec7e875d88ef16b3b8ac6e53
Author: Björn Jacke <bj at sernet.de>
Date:   Mon Mar 8 12:52:13 2010 +0100

    s3: remove cross-device rename support from vfs_default
    
    cross-device rename support has some major limitations:
    
    - on huge files clients will timeout or hang
    - ACLs and EA information is not retained
    
    Usually a client will have to handle this. A Windows Server with a reparse
    point will also just return NT_STATUS_NOT_SAME_DEVICE. We will now by default
    do the same.
    
    I will add a vfs module which will restore the old cross-device renames.

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

Summary of changes:
 docs-xml/manpages-3/vfs_crossrename.8.xml |  115 +++++++++++++++++
 source3/configure.in                      |    2 +
 source3/modules/vfs_crossrename.c         |  200 +++++++++++++++++++++++++++++
 source3/modules/vfs_default.c             |  116 -----------------
 4 files changed, 317 insertions(+), 116 deletions(-)
 create mode 100644 docs-xml/manpages-3/vfs_crossrename.8.xml
 create mode 100644 source3/modules/vfs_crossrename.c


Changeset truncated at 500 lines:

diff --git a/docs-xml/manpages-3/vfs_crossrename.8.xml b/docs-xml/manpages-3/vfs_crossrename.8.xml
new file mode 100644
index 0000000..675c92e
--- /dev/null
+++ b/docs-xml/manpages-3/vfs_crossrename.8.xml
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE refentry PUBLIC "-//Samba-Team//DTD DocBook V4.2-Based Variant V1.0//EN" "http://www.samba.org/samba/DTD/samba-doc">
+<refentry id="vfs_crossrename.8">
+
+<refmeta>
+	<refentrytitle>vfs_crossrename</refentrytitle>
+	<manvolnum>8</manvolnum>
+	<refmiscinfo class="source">Samba</refmiscinfo>
+	<refmiscinfo class="manual">System Administration tools</refmiscinfo>
+	<refmiscinfo class="version">3.6</refmiscinfo>
+</refmeta>
+
+
+<refnamediv>
+	<refname>vfs_crossrename</refname>
+	<refpurpose>server side rename files across filesystem boundaries</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+	<cmdsynopsis>
+		<command>vfs objects = crossrename</command>
+	</cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+	<title>DESCRIPTION</title>
+
+	<para>This VFS module is part of the
+	<citerefentry><refentrytitle>samba</refentrytitle>
+	<manvolnum>7</manvolnum></citerefentry> suite.</para>
+
+	<para>The <command>vfs_crossrename</command> VFS module allows
+	server side rename operations even if source and target are on
+	differen physical devices. A "move" in Explorer is usually a
+	rename operation if it is inside of a single share or device.
+	Usually such a rename operation returns
+	NT_STATUS_NOT_SAME_DEVICE and the client has to move the file by
+	manual copy and delete operations. If the rename by copy is done by the
+	server this can be much more efficient. vfs_crossrename tries to do
+	this server-side cross-device rename operation. There are however
+	limitations that this module currently does not solve:
+
+	<variablelist>
+		<varlistentry>
+		the ACLs of files are not preserved
+		</varlistentry>
+		<varlistentry>
+		meta data in EAs are not preserved
+		</varlistentry>
+		<varlistentry>
+		renames of whole subdirectories cannot be done recursively,
+		in that case we still return STATUS_NOT_SAME_DEVICE and
+		let the client decide what to do
+		</varlistentry>
+		<varlistentry>
+		rename operations of huge files can cause hangs on the
+		client because clients expect a rename operation to
+		return fast
+		</varlistentry>
+	</variablelist>
+	</para>
+
+	<para>This module is stackable.</para>
+
+</refsect1>
+
+
+<refsect1>
+	<title>OPTIONS</title>
+
+	<variablelist>
+
+		<varlistentry>
+		<term>crossrename:sizelimit = BYTES</term>
+		<listitem>
+		<para>server-side cross-device-renames are only done
+		for files if the filesize is not larger than the defined
+		size in MiB to prevent timeouts. The default sizelimit is
+		20 (MiB)
+		</para>
+		</varlistentry>
+	</variablelist>
+</refsect1>
+
+<refsect1>
+	<title>EXAMPLES</title>
+
+	<para>To add server-side cross-device renames inside of a share
+	for all files sized up to 50MB:</para>
+
+<programlisting>
+        <smbconfsection name="[testshare]"/>
+	<smbconfoption name="path">/data/mounts</smbconfoption>
+	<smbconfoption name="vfs objects">crossrename</smbconfoption>
+	<smbconfoption name="crossrename:sizelimit">50</smbconfoption>
+</programlisting>
+</refsect1>
+
+<refsect1>
+	<title>VERSION</title>
+	<para>This man page is correct for version 3.6.0 of the Samba suite.
+	</para>
+</refsect1>
+
+<refsect1>
+	<title>AUTHOR</title>
+
+	<para>The original Samba software and related utilities
+	were created by Andrew Tridgell. Samba is now developed
+	by the Samba Team as an Open Source project similar
+	to the way the Linux kernel is developed.</para>
+
+</refsect1>
+
+</refentry>
diff --git a/source3/configure.in b/source3/configure.in
index a1a4d44..436f708 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -440,6 +440,7 @@ default_shared_modules="$default_shared_modules vfs_smb_traffic_analyzer"
 default_shared_modules="$default_shared_modules vfs_preopen"
 default_shared_modules="$default_shared_modules vfs_catia"
 default_shared_modules="$default_shared_modules vfs_scannedonly"
+default_shared_modules="$default_shared_modules vfs_crossrename"
 
 if test "x$developer" = xyes; then
    default_static_modules="$default_static_modules rpc_rpcecho pdb_ads"
@@ -6514,6 +6515,7 @@ SMB_MODULE(vfs_onefs, \$(VFS_ONEFS), "bin/onefs.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_onefs_shadow_copy, \$(VFS_ONEFS_SHADOW_COPY), "bin/onefs_shadow_copy.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_dirsort, \$(VFS_DIRSORT_OBJ), "bin/dirsort.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_scannedonly, \$(VFS_SCANNEDONLY_OBJ), "bin/scannedonly.$SHLIBEXT", VFS)
+SMB_MODULE(vfs_crossrename, \$(VFS_CROSSRENAME_OBJ), "bin/crossrename.$SHLIBEXT", VFS)
 
 SMB_SUBSYSTEM(VFS,smbd/vfs.o)
 
diff --git a/source3/modules/vfs_crossrename.c b/source3/modules/vfs_crossrename.c
new file mode 100644
index 0000000..323ceb1
--- /dev/null
+++ b/source3/modules/vfs_crossrename.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) Björn Jacke 2010
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "includes.h"
+
+
+#define MODULE "crossrename"
+static SMB_OFF_T module_sizelimit;
+
+static int crossrename_connect(
+                struct vfs_handle_struct *  handle,
+                const char *                service,
+                const char *                user)
+{
+	int ret = SMB_VFS_NEXT_CONNECT(handle, service, user);
+
+	if (ret < 0) {
+		return ret;
+	}
+
+	module_sizelimit = (SMB_OFF_T) lp_parm_int(SNUM(handle->conn),
+					MODULE, "sizelimit", 20);
+	/* convert from MiB to byte: */
+	module_sizelimit *= 1048576;
+
+	return 0;
+}
+
+/*********************************************************
+ For rename across filesystems initial Patch from Warren Birnbaum
+ <warrenb at hpcvscdp.cv.hp.com>
+**********************************************************/
+
+static int copy_reg(const char *source, const char *dest)
+{
+	SMB_STRUCT_STAT source_stats;
+	int saved_errno;
+	int ifd = -1;
+	int ofd = -1;
+
+	if (sys_lstat(source, &source_stats, false) == -1)
+		return -1;
+
+	if (!S_ISREG (source_stats.st_ex_mode))
+		return -1;
+
+	if (source_stats.st_ex_size > module_sizelimit) {
+		DEBUG(5,
+			("%s: size of %s larger than sizelimit (%lld > %lld), rename prohititted\n",
+			MODULE, source,
+			(long long)source_stats.st_ex_size,
+			(long long)module_sizelimit));
+		return -1;
+	}
+
+	if((ifd = sys_open (source, O_RDONLY, 0)) < 0)
+		return -1;
+
+	if (unlink (dest) && errno != ENOENT)
+		return -1;
+
+#ifdef O_NOFOLLOW
+	if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, 0600)) < 0 )
+#else
+	if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC , 0600)) < 0 )
+#endif
+		goto err;
+
+	if (transfer_file(ifd, ofd, (size_t)-1) == -1)
+		goto err;
+
+	/*
+	 * Try to preserve ownership.  For non-root it might fail, but that's ok.
+	 * But root probably wants to know, e.g. if NFS disallows it.
+	 */
+
+#ifdef HAVE_FCHOWN
+	if ((fchown(ofd, source_stats.st_ex_uid, source_stats.st_ex_gid) == -1) && (errno != EPERM))
+#else
+	if ((chown(dest, source_stats.st_ex_uid, source_stats.st_ex_gid) == -1) && (errno != EPERM))
+#endif
+		goto err;
+
+	/*
+	 * fchown turns off set[ug]id bits for non-root,
+	 * so do the chmod last.
+	 */
+
+#if defined(HAVE_FCHMOD)
+	if (fchmod (ofd, source_stats.st_ex_mode & 07777))
+#else
+	if (chmod (dest, source_stats.st_ex_mode & 07777))
+#endif
+		goto err;
+
+	if (close (ifd) == -1)
+		goto err;
+
+	if (close (ofd) == -1)
+		return -1;
+
+	/* Try to copy the old file's modtime and access time.  */
+#if defined(HAVE_UTIMENSAT)
+	{
+		struct timespec ts[2];
+
+		ts[0] = source_stats.st_ex_atime;
+		ts[1] = source_stats.st_ex_mtime;
+		utimensat(AT_FDCWD, dest, ts, AT_SYMLINK_NOFOLLOW);
+	}
+#elif defined(HAVE_UTIMES)
+	{
+		struct timeval tv[2];
+
+		tv[0] = convert_timespec_to_timeval(source_stats.st_ex_atime);
+		tv[1] = convert_timespec_to_timeval(source_stats.st_ex_mtime);
+#ifdef HAVE_LUTIMES
+		lutimes(dest, tv);
+#else
+		utimes(dest, tv);
+#endif
+	}
+#elif defined(HAVE_UTIME)
+	{
+		struct utimbuf tv;
+
+		tv.actime = convert_timespec_to_time_t(source_stats.st_ex_atime);
+		tv.modtime = convert_timespec_to_time_t(source_stats.st_ex_mtime);
+		utime(dest, &tv);
+	}
+#endif
+
+	if (unlink (source) == -1)
+		return -1;
+
+	return 0;
+
+  err:
+
+	saved_errno = errno;
+	if (ifd != -1)
+		close(ifd);
+	if (ofd != -1)
+		close(ofd);
+	errno = saved_errno;
+	return -1;
+}
+
+
+static int crossrename_rename(vfs_handle_struct *handle,
+			  const struct smb_filename *smb_fname_src,
+			  const struct smb_filename *smb_fname_dst)
+{
+	int result = -1;
+
+	START_PROFILE(syscall_rename);
+
+	if (smb_fname_src->stream_name || smb_fname_dst->stream_name) {
+		errno = ENOENT;
+		goto out;
+	}
+
+	result = rename(smb_fname_src->base_name, smb_fname_dst->base_name);
+	if ((result == -1) && (errno == EXDEV)) {
+		/* Rename across filesystems needed. */
+		result = copy_reg(smb_fname_src->base_name,
+				  smb_fname_dst->base_name);
+	}
+
+ out:
+	END_PROFILE(syscall_rename);
+	return result;
+}
+
+static struct vfs_fn_pointers vfs_crossrename_fns = {
+	.connect_fn = crossrename_connect,
+	.rename = crossrename_rename
+};
+
+NTSTATUS vfs_crossrename_init(void);
+NTSTATUS vfs_crossrename_init(void)
+{
+	return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, MODULE,
+				&vfs_crossrename_fns);
+}
+
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index ed9bb36..2b57f6b 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -477,117 +477,6 @@ static ssize_t vfswrap_recvfile(vfs_handle_struct *handle,
 	return result;
 }
 
-/*********************************************************
- For rename across filesystems Patch from Warren Birnbaum
- <warrenb at hpcvscdp.cv.hp.com>
-**********************************************************/
-
-static int copy_reg(const char *source, const char *dest)
-{
-	SMB_STRUCT_STAT source_stats;
-	int saved_errno;
-	int ifd = -1;
-	int ofd = -1;
-
-	if (sys_lstat(source, &source_stats, false) == -1)
-		return -1;
-
-	if (!S_ISREG (source_stats.st_ex_mode))
-		return -1;
-
-	if((ifd = sys_open (source, O_RDONLY, 0)) < 0)
-		return -1;
-
-	if (unlink (dest) && errno != ENOENT)
-		return -1;
-
-#ifdef O_NOFOLLOW
-	if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, 0600)) < 0 )
-#else
-	if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC , 0600)) < 0 )
-#endif
-		goto err;
-
-	if (transfer_file(ifd, ofd, (size_t)-1) == -1)
-		goto err;
-
-	/*
-	 * Try to preserve ownership.  For non-root it might fail, but that's ok.
-	 * But root probably wants to know, e.g. if NFS disallows it.
-	 */
-
-#ifdef HAVE_FCHOWN
-	if ((fchown(ofd, source_stats.st_ex_uid, source_stats.st_ex_gid) == -1) && (errno != EPERM))
-#else
-	if ((chown(dest, source_stats.st_ex_uid, source_stats.st_ex_gid) == -1) && (errno != EPERM))
-#endif
-		goto err;
-
-	/*
-	 * fchown turns off set[ug]id bits for non-root,
-	 * so do the chmod last.
-	 */
-
-#if defined(HAVE_FCHMOD)
-	if (fchmod (ofd, source_stats.st_ex_mode & 07777))
-#else
-	if (chmod (dest, source_stats.st_ex_mode & 07777))
-#endif
-		goto err;
-
-	if (close (ifd) == -1)
-		goto err;
-
-	if (close (ofd) == -1)
-		return -1;
-
-	/* Try to copy the old file's modtime and access time.  */
-#if defined(HAVE_UTIMENSAT)
-	{
-		struct timespec ts[2];
-
-		ts[0] = source_stats.st_ex_atime;
-		ts[1] = source_stats.st_ex_mtime;
-		utimensat(AT_FDCWD, dest, ts, AT_SYMLINK_NOFOLLOW);
-	}
-#elif defined(HAVE_UTIMES)
-	{
-		struct timeval tv[2];
-
-		tv[0] = convert_timespec_to_timeval(source_stats.st_ex_atime);
-		tv[1] = convert_timespec_to_timeval(source_stats.st_ex_mtime);
-#ifdef HAVE_LUTIMES
-		lutimes(dest, tv);
-#else
-		utimes(dest, tv);
-#endif
-	}
-#elif defined(HAVE_UTIME)
-	{
-		struct utimbuf tv;
-
-		tv.actime = convert_timespec_to_time_t(source_stats.st_ex_atime);
-		tv.modtime = convert_timespec_to_time_t(source_stats.st_ex_mtime);
-		utime(dest, &tv);
-	}
-#endif
-
-	if (unlink (source) == -1)
-		return -1;
-
-	return 0;
-
-  err:
-
-	saved_errno = errno;
-	if (ifd != -1)
-		close(ifd);
-	if (ofd != -1)
-		close(ofd);
-	errno = saved_errno;
-	return -1;
-}
-
 static int vfswrap_rename(vfs_handle_struct *handle,
 			  const struct smb_filename *smb_fname_src,
 			  const struct smb_filename *smb_fname_dst)
@@ -602,11 +491,6 @@ static int vfswrap_rename(vfs_handle_struct *handle,
 	}
 
 	result = rename(smb_fname_src->base_name, smb_fname_dst->base_name);
-	if ((result == -1) && (errno == EXDEV)) {
-		/* Rename across filesystems needed. */
-		result = copy_reg(smb_fname_src->base_name,
-				  smb_fname_dst->base_name);
-	}
 
  out:
 	END_PROFILE(syscall_rename);


-- 
Samba Shared Repository


More information about the samba-cvs mailing list