[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