diff options
author | Björn Jacke <bj@sernet.de> | 2010-03-08 12:52:13 +0100 |
---|---|---|
committer | Björn Jacke <bj@sernet.de> | 2010-03-08 17:17:52 +0100 |
commit | 583de7b582956d3bec7e875d88ef16b3b8ac6e53 (patch) | |
tree | 688e24ee116c54a720e33fb9d9443421c48cad73 | |
parent | f4cb528ac510d3381a92a303e858edaf9e3d908a (diff) | |
download | samba-583de7b582956d3bec7e875d88ef16b3b8ac6e53.tar.gz samba-583de7b582956d3bec7e875d88ef16b3b8ac6e53.tar.bz2 samba-583de7b582956d3bec7e875d88ef16b3b8ac6e53.zip |
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.
-rw-r--r-- | source3/modules/vfs_default.c | 116 |
1 files changed, 0 insertions, 116 deletions
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index ed9bb36d48..2b57f6bf36 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@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); |