Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source3/modules/vfs_default.c

    r596 r745  
    2020
    2121#include "includes.h"
     22#include "system/time.h"
     23#include "system/filesys.h"
     24#include "smbd/smbd.h"
     25#include "ntioctl.h"
     26#include "smbprofile.h"
    2227
    2328#undef DBGC_CLASS
     
    8085}
    8186
    82 static int vfswrap_get_shadow_copy_data(struct vfs_handle_struct *handle, struct files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, bool labels)
     87static int vfswrap_get_shadow_copy_data(struct vfs_handle_struct *handle,
     88                                        struct files_struct *fsp,
     89                                        struct shadow_copy_data *shadow_copy_data,
     90                                        bool labels)
    8391{
    8492        errno = ENOSYS;
     
    168176}
    169177
     178static SMB_STRUCT_DIR *vfswrap_fdopendir(vfs_handle_struct *handle,
     179                        files_struct *fsp,
     180                        const char *mask,
     181                        uint32 attr)
     182{
     183        SMB_STRUCT_DIR *result;
     184
     185        START_PROFILE(syscall_fdopendir);
     186        result = sys_fdopendir(fsp->fh->fd);
     187        END_PROFILE(syscall_fdopendir);
     188        return result;
     189}
     190
     191
    170192static SMB_STRUCT_DIRENT *vfswrap_readdir(vfs_handle_struct *handle,
    171193                                          SMB_STRUCT_DIR *dirp,
     
    299321                                    uint32_t oplock_request,
    300322                                    uint64_t allocation_size,
     323                                    uint32_t private_flags,
    301324                                    struct security_descriptor *sd,
    302325                                    struct ea_list *ea_list,
     
    308331                                   create_disposition, create_options,
    309332                                   file_attributes, oplock_request,
    310                                    allocation_size, sd, ea_list, result,
     333                                   allocation_size, private_flags,
     334                                   sd, ea_list, result,
    311335                                   pinfo);
    312336}
     
    476500}
    477501
    478 /*********************************************************
    479  For rename across filesystems Patch from Warren Birnbaum
    480  <warrenb@hpcvscdp.cv.hp.com>
    481 **********************************************************/
    482 
    483 static int copy_reg(const char *source, const char *dest)
    484 {
    485         SMB_STRUCT_STAT source_stats;
    486         int saved_errno;
    487         int ifd = -1;
    488         int ofd = -1;
    489 
    490         if (sys_lstat(source, &source_stats, false) == -1)
    491                 return -1;
    492 
    493         if (!S_ISREG (source_stats.st_ex_mode))
    494                 return -1;
    495 
    496         if((ifd = sys_open (source, O_RDONLY, 0)) < 0)
    497                 return -1;
    498 
    499         if (unlink (dest) && errno != ENOENT)
    500                 return -1;
    501 
    502 #ifdef O_NOFOLLOW
    503         if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, 0600)) < 0 )
    504 #else
    505         if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC , 0600)) < 0 )
    506 #endif
    507                 goto err;
    508 
    509         if (transfer_file(ifd, ofd, (size_t)-1) == -1)
    510                 goto err;
    511 
    512         /*
    513          * Try to preserve ownership.  For non-root it might fail, but that's ok.
    514          * But root probably wants to know, e.g. if NFS disallows it.
    515          */
    516 
    517 #ifdef HAVE_FCHOWN
    518         if ((fchown(ofd, source_stats.st_ex_uid, source_stats.st_ex_gid) == -1) && (errno != EPERM))
    519 #else
    520         if ((chown(dest, source_stats.st_ex_uid, source_stats.st_ex_gid) == -1) && (errno != EPERM))
    521 #endif
    522                 goto err;
    523 
    524         /*
    525          * fchown turns off set[ug]id bits for non-root,
    526          * so do the chmod last.
    527          */
    528 
    529 #if defined(HAVE_FCHMOD)
    530         if (fchmod (ofd, source_stats.st_ex_mode & 07777))
    531 #else
    532         if (chmod (dest, source_stats.st_ex_mode & 07777))
    533 #endif
    534                 goto err;
    535 
    536         if (close (ifd) == -1)
    537                 goto err;
    538 
    539         if (close (ofd) == -1)
    540                 return -1;
    541 
    542         /* Try to copy the old file's modtime and access time.  */
    543 #if defined(HAVE_UTIMENSAT)
    544         {
    545                 struct timespec ts[2];
    546 
    547                 ts[0] = source_stats.st_ex_atime;
    548                 ts[1] = source_stats.st_ex_mtime;
    549                 utimensat(AT_FDCWD, dest, ts, AT_SYMLINK_NOFOLLOW);
    550         }
    551 #elif defined(HAVE_UTIMES)
    552         {
    553                 struct timeval tv[2];
    554 
    555                 tv[0] = convert_timespec_to_timeval(source_stats.st_ex_atime);
    556                 tv[1] = convert_timespec_to_timeval(source_stats.st_ex_mtime);
    557 #ifdef HAVE_LUTIMES
    558                 lutimes(dest, tv);
    559 #else
    560                 utimes(dest, tv);
    561 #endif
    562         }
    563 #elif defined(HAVE_UTIME)
    564         {
    565                 struct utimbuf tv;
    566 
    567                 tv.actime = convert_timespec_to_time_t(source_stats.st_ex_atime);
    568                 tv.modtime = convert_timespec_to_time_t(source_stats.st_ex_mtime);
    569                 utime(dest, &tv);
    570         }
    571 #endif
    572 
    573         if (unlink (source) == -1)
    574                 return -1;
    575 
    576         return 0;
    577 
    578   err:
    579 
    580         saved_errno = errno;
    581         if (ifd != -1)
    582                 close(ifd);
    583         if (ofd != -1)
    584                 close(ofd);
    585         errno = saved_errno;
    586         return -1;
    587 }
    588 
    589502static int vfswrap_rename(vfs_handle_struct *handle,
    590503                          const struct smb_filename *smb_fname_src,
     
    601514
    602515        result = rename(smb_fname_src->base_name, smb_fname_dst->base_name);
    603         if ((result == -1) && (errno == EXDEV)) {
    604                 /* Rename across filesystems needed. */
    605                 result = copy_reg(smb_fname_src->base_name,
    606                                   smb_fname_dst->base_name);
    607         }
    608516
    609517 out:
     
    869777        }
    870778
    871         if (null_timespec(ft->atime)) {
    872                 ft->atime= smb_fname->st.st_ex_atime;
    873         }
    874 
    875         if (null_timespec(ft->mtime)) {
    876                 ft->mtime = smb_fname->st.st_ex_mtime;
    877         }
    878 
    879         if (!null_timespec(ft->create_time)) {
    880                 set_create_timespec_ea(handle->conn,
    881                                 smb_fname,
    882                                 ft->create_time);
    883         }
    884 
    885         if ((timespec_compare(&ft->atime,
    886                                 &smb_fname->st.st_ex_atime) == 0) &&
    887                         (timespec_compare(&ft->mtime,
    888                                 &smb_fname->st.st_ex_mtime) == 0)) {
    889                 return 0;
     779        if (ft != NULL) {
     780                if (null_timespec(ft->atime)) {
     781                        ft->atime= smb_fname->st.st_ex_atime;
     782                }
     783
     784                if (null_timespec(ft->mtime)) {
     785                        ft->mtime = smb_fname->st.st_ex_mtime;
     786                }
     787
     788                if (!null_timespec(ft->create_time)) {
     789                        set_create_timespec_ea(handle->conn,
     790                                               smb_fname,
     791                                               ft->create_time);
     792                }
     793
     794                if ((timespec_compare(&ft->atime,
     795                                      &smb_fname->st.st_ex_atime) == 0) &&
     796                    (timespec_compare(&ft->mtime,
     797                                      &smb_fname->st.st_ex_mtime) == 0)) {
     798                        return 0;
     799                }
    890800        }
    891801
     
    944854static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T len)
    945855{
    946         SMB_STRUCT_STAT st;
    947         SMB_OFF_T currpos = SMB_VFS_LSEEK(fsp, 0, SEEK_CUR);
    948         unsigned char zero_space[4096];
    949856        SMB_OFF_T space_to_write;
    950857        uint64_t space_avail;
    951858        uint64_t bsize,dfree,dsize;
    952859        int ret;
    953 
    954         if (currpos == -1)
     860        NTSTATUS status;
     861        SMB_STRUCT_STAT *pst;
     862
     863        status = vfs_stat_fsp(fsp);
     864        if (!NT_STATUS_IS_OK(status)) {
    955865                return -1;
    956 
    957         if (SMB_VFS_FSTAT(fsp, &st) == -1)
    958                 return -1;
     866        }
     867        pst = &fsp->fsp_name->st;
    959868
    960869#ifdef S_ISFIFO
    961         if (S_ISFIFO(st.st_ex_mode))
     870        if (S_ISFIFO(pst->st_ex_mode))
    962871                return 0;
    963872#endif
    964873
    965         if (st.st_ex_size == len)
     874        if (pst->st_ex_size == len)
    966875                return 0;
    967876
    968877        /* Shrink - just ftruncate. */
    969         if (st.st_ex_size > len)
     878        if (pst->st_ex_size > len)
    970879                return sys_ftruncate(fsp->fh->fd, len);
    971880
    972         space_to_write = len - st.st_ex_size;
    973 
    974         /* for allocation try posix_fallocate first. This can fail on some
     881        space_to_write = len - pst->st_ex_size;
     882
     883        /* for allocation try fallocate first. This can fail on some
    975884           platforms e.g. when the filesystem doesn't support it and no
    976885           emulation is being done by the libc (like on AIX with JFS1). In that
    977            case we do our own emulation. posix_fallocate implementations can
     886           case we do our own emulation. fallocate implementations can
    978887           return ENOTSUP or EINVAL in cases like that. */
    979         ret = sys_posix_fallocate(fsp->fh->fd, st.st_ex_size, space_to_write);
     888        ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
     889                                pst->st_ex_size, space_to_write);
    980890        if (ret == ENOSPC) {
    981891                errno = ENOSPC;
     
    985895                return 0;
    986896        }
    987         DEBUG(10,("strict_allocate_ftruncate: sys_posix_fallocate failed with "
     897        DEBUG(10,("strict_allocate_ftruncate: SMB_VFS_FALLOCATE failed with "
    988898                "error %d. Falling back to slow manual allocation\n", ret));
    989899
     
    1000910
    1001911        /* Write out the real space on disk. */
    1002         if (SMB_VFS_LSEEK(fsp, st.st_ex_size, SEEK_SET) != st.st_ex_size)
    1003                 return -1;
    1004 
    1005         memset(zero_space, '\0', sizeof(zero_space));
    1006         while ( space_to_write > 0) {
    1007                 SMB_OFF_T retlen;
    1008                 SMB_OFF_T current_len_to_write = MIN(sizeof(zero_space),space_to_write);
    1009 
    1010                 retlen = SMB_VFS_WRITE(fsp,(char *)zero_space,current_len_to_write);
    1011                 if (retlen <= 0)
    1012                         return -1;
    1013 
    1014                 space_to_write -= retlen;
    1015         }
    1016 
    1017         /* Seek to where we were */
    1018         if (SMB_VFS_LSEEK(fsp, currpos, SEEK_SET) != currpos)
    1019                 return -1;
     912        ret = vfs_slow_fallocate(fsp, pst->st_ex_size, space_to_write);
     913        if (ret != 0) {
     914                errno = ret;
     915                ret = -1;
     916        }
    1020917
    1021918        return 0;
     
    1025922{
    1026923        int result = -1;
    1027         SMB_STRUCT_STAT st;
     924        SMB_STRUCT_STAT *pst;
     925        NTSTATUS status;
    1028926        char c = 0;
    1029         SMB_OFF_T currpos;
    1030927
    1031928        START_PROFILE(syscall_ftruncate);
    1032929
    1033         if (lp_strict_allocate(SNUM(fsp->conn))) {
     930        if (lp_strict_allocate(SNUM(fsp->conn)) && !fsp->is_sparse) {
    1034931                result = strict_allocate_ftruncate(handle, fsp, len);
    1035932                END_PROFILE(syscall_ftruncate);
     
    1050947           extend a file with ftruncate. Provide alternate implementation
    1051948           for this */
    1052         currpos = SMB_VFS_LSEEK(fsp, 0, SEEK_CUR);
    1053         if (currpos == -1) {
    1054                 goto done;
    1055         }
    1056949
    1057950        /* Do an fstat to see if the file is longer than the requested
     
    1059952           succeeded or shorter, in which case seek to len - 1 and
    1060953           write 1 byte of zero */
    1061         if (SMB_VFS_FSTAT(fsp, &st) == -1) {
     954        status = vfs_stat_fsp(fsp);
     955        if (!NT_STATUS_IS_OK(status)) {
    1062956                goto done;
    1063957        }
     958        pst = &fsp->fsp_name->st;
    1064959
    1065960#ifdef S_ISFIFO
    1066         if (S_ISFIFO(st.st_ex_mode)) {
     961        if (S_ISFIFO(pst->st_ex_mode)) {
    1067962                result = 0;
    1068963                goto done;
     
    1070965#endif
    1071966
    1072         if (st.st_ex_size == len) {
     967        if (pst->st_ex_size == len) {
    1073968                result = 0;
    1074969                goto done;
    1075970        }
    1076971
    1077         if (st.st_ex_size > len) {
     972        if (pst->st_ex_size > len) {
    1078973                /* the sys_ftruncate should have worked */
    1079974                goto done;
    1080975        }
    1081976
    1082         if (SMB_VFS_LSEEK(fsp, len-1, SEEK_SET) != len -1)
     977        if (SMB_VFS_PWRITE(fsp, &c, 1, len-1)!=1) {
    1083978                goto done;
    1084 
    1085         if (SMB_VFS_WRITE(fsp, &c, 1)!=1)
    1086                 goto done;
    1087 
    1088         /* Seek to where we were */
    1089         if (SMB_VFS_LSEEK(fsp, currpos, SEEK_SET) != currpos)
    1090                 goto done;
     979        }
     980
    1091981        result = 0;
    1092982
     
    1094984
    1095985        END_PROFILE(syscall_ftruncate);
     986        return result;
     987}
     988
     989static int vfswrap_fallocate(vfs_handle_struct *handle,
     990                        files_struct *fsp,
     991                        enum vfs_fallocate_mode mode,
     992                        SMB_OFF_T offset,
     993                        SMB_OFF_T len)
     994{
     995        int result;
     996
     997        START_PROFILE(syscall_fallocate);
     998        if (mode == VFS_FALLOCATE_EXTEND_SIZE) {
     999                result = sys_posix_fallocate(fsp->fh->fd, offset, len);
     1000        } else if (mode == VFS_FALLOCATE_KEEP_SIZE) {
     1001                result = sys_fallocate(fsp->fh->fd, mode, offset, len);
     1002        } else {
     1003                errno = EINVAL;
     1004                result = -1;
     1005        }
     1006        END_PROFILE(syscall_fallocate);
    10961007        return result;
    10971008}
     
    11871098}
    11881099
    1189 static char *vfswrap_realpath(vfs_handle_struct *handle,  const char *path, char *resolved_path)
     1100static char *vfswrap_realpath(vfs_handle_struct *handle,  const char *path)
    11901101{
    11911102        char *result;
    11921103
    11931104        START_PROFILE(syscall_realpath);
    1194         result = realpath(path, resolved_path);
     1105#ifdef REALPATH_TAKES_NULL
     1106        result = realpath(path, NULL);
     1107#else
     1108        result = SMB_MALLOC_ARRAY(char, PATH_MAX+1);
     1109        if (result) {
     1110                char *resolved_path = realpath(path, result);
     1111                if (!resolved_path) {
     1112                        SAFE_FREE(result);
     1113                } else {
     1114                        /* SMB_ASSERT(result == resolved_path) ? */
     1115                        result = resolved_path;
     1116                }
     1117        }
     1118#endif
    11951119        END_PROFILE(syscall_realpath);
    11961120        return result;
     
    13941318static NTSTATUS vfswrap_fget_nt_acl(vfs_handle_struct *handle,
    13951319                                    files_struct *fsp,
    1396                                     uint32 security_info, SEC_DESC **ppdesc)
     1320                                    uint32 security_info,
     1321                                    struct security_descriptor **ppdesc)
    13971322{
    13981323        NTSTATUS result;
     
    14061331static NTSTATUS vfswrap_get_nt_acl(vfs_handle_struct *handle,
    14071332                                   const char *name,
    1408                                    uint32 security_info, SEC_DESC **ppdesc)
     1333                                   uint32 security_info,
     1334                                   struct security_descriptor **ppdesc)
    14091335{
    14101336        NTSTATUS result;
     
    14161342}
    14171343
    1418 static NTSTATUS vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info_sent, const SEC_DESC *psd)
     1344static NTSTATUS vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info_sent, const struct security_descriptor *psd)
    14191345{
    14201346        NTSTATUS result;
     
    15901516}
    15911517
    1592 ssize_t vfswrap_llistxattr(struct vfs_handle_struct *handle, const char *path, char *list, size_t size)
     1518static ssize_t vfswrap_llistxattr(struct vfs_handle_struct *handle, const char *path, char *list, size_t size)
    15931519{
    15941520        return sys_llistxattr(path, list, size);
    15951521}
    15961522
    1597 ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, char *list, size_t size)
     1523static ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, char *list, size_t size)
    15981524{
    15991525        return sys_flistxattr(fsp->fh->fd, list, size);
     
    16901616}
    16911617
    1692 static bool vfswrap_is_offline(struct vfs_handle_struct *handle, const char *path, SMB_STRUCT_STAT *sbuf)
    1693 {
    1694         if (ISDOT(path) || ISDOTDOT(path)) {
     1618static bool vfswrap_is_offline(struct vfs_handle_struct *handle,
     1619                               const struct smb_filename *fname,
     1620                               SMB_STRUCT_STAT *sbuf)
     1621{
     1622        NTSTATUS status;
     1623        char *path;
     1624
     1625        if (ISDOT(fname->base_name) || ISDOTDOT(fname->base_name)) {
    16951626                return false;
    16961627        }
     
    17031634        }
    17041635
     1636        status = get_full_smb_filename(talloc_tos(), fname, &path);
     1637        if (!NT_STATUS_IS_OK(status)) {
     1638                errno = map_errno_from_nt_status(status);
     1639                return false;
     1640        }
     1641
    17051642        return (dmapi_file_flags(path) & FILE_ATTRIBUTE_OFFLINE) != 0;
    17061643}
    17071644
    1708 static int vfswrap_set_offline(struct vfs_handle_struct *handle, const char *path)
     1645static int vfswrap_set_offline(struct vfs_handle_struct *handle,
     1646                               const struct smb_filename *fname)
    17091647{
    17101648        /* We don't know how to set offline bit by default, needs to be overriden in the vfs modules */
     
    17301668
    17311669        .opendir = vfswrap_opendir,
     1670        .fdopendir = vfswrap_fdopendir,
    17321671        .readdir = vfswrap_readdir,
    17331672        .seekdir = vfswrap_seekdir,
     
    17411680        /* File operations */
    17421681
    1743         .open = vfswrap_open,
     1682        .open_fn = vfswrap_open,
    17441683        .create_file = vfswrap_create_file,
    17451684        .close_fn = vfswrap_close,
     
    17671706        .ntimes = vfswrap_ntimes,
    17681707        .ftruncate = vfswrap_ftruncate,
     1708        .fallocate = vfswrap_fallocate,
    17691709        .lock = vfswrap_lock,
    17701710        .kernel_flock = vfswrap_kernel_flock,
Note: See TracChangeset for help on using the changeset viewer.