Changeset 745 for trunk/server/source3/modules/vfs_default.c
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source3/modules/vfs_default.c
r596 r745 20 20 21 21 #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" 22 27 23 28 #undef DBGC_CLASS … … 80 85 } 81 86 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) 87 static 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) 83 91 { 84 92 errno = ENOSYS; … … 168 176 } 169 177 178 static 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 170 192 static SMB_STRUCT_DIRENT *vfswrap_readdir(vfs_handle_struct *handle, 171 193 SMB_STRUCT_DIR *dirp, … … 299 321 uint32_t oplock_request, 300 322 uint64_t allocation_size, 323 uint32_t private_flags, 301 324 struct security_descriptor *sd, 302 325 struct ea_list *ea_list, … … 308 331 create_disposition, create_options, 309 332 file_attributes, oplock_request, 310 allocation_size, sd, ea_list, result, 333 allocation_size, private_flags, 334 sd, ea_list, result, 311 335 pinfo); 312 336 } … … 476 500 } 477 501 478 /*********************************************************479 For rename across filesystems Patch from Warren Birnbaum480 <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_NOFOLLOW503 if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, 0600)) < 0 )504 #else505 if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC , 0600)) < 0 )506 #endif507 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_FCHOWN518 if ((fchown(ofd, source_stats.st_ex_uid, source_stats.st_ex_gid) == -1) && (errno != EPERM))519 #else520 if ((chown(dest, source_stats.st_ex_uid, source_stats.st_ex_gid) == -1) && (errno != EPERM))521 #endif522 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 #else532 if (chmod (dest, source_stats.st_ex_mode & 07777))533 #endif534 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_LUTIMES558 lutimes(dest, tv);559 #else560 utimes(dest, tv);561 #endif562 }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 #endif572 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 589 502 static int vfswrap_rename(vfs_handle_struct *handle, 590 503 const struct smb_filename *smb_fname_src, … … 601 514 602 515 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 }608 516 609 517 out: … … 869 777 } 870 778 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 } 890 800 } 891 801 … … 944 854 static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T len) 945 855 { 946 SMB_STRUCT_STAT st;947 SMB_OFF_T currpos = SMB_VFS_LSEEK(fsp, 0, SEEK_CUR);948 unsigned char zero_space[4096];949 856 SMB_OFF_T space_to_write; 950 857 uint64_t space_avail; 951 858 uint64_t bsize,dfree,dsize; 952 859 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)) { 955 865 return -1; 956 957 if (SMB_VFS_FSTAT(fsp, &st) == -1) 958 return -1; 866 } 867 pst = &fsp->fsp_name->st; 959 868 960 869 #ifdef S_ISFIFO 961 if (S_ISFIFO( st.st_ex_mode))870 if (S_ISFIFO(pst->st_ex_mode)) 962 871 return 0; 963 872 #endif 964 873 965 if ( st.st_ex_size == len)874 if (pst->st_ex_size == len) 966 875 return 0; 967 876 968 877 /* Shrink - just ftruncate. */ 969 if ( st.st_ex_size > len)878 if (pst->st_ex_size > len) 970 879 return sys_ftruncate(fsp->fh->fd, len); 971 880 972 space_to_write = len - st.st_ex_size;973 974 /* for allocation try posix_fallocate first. This can fail on some881 space_to_write = len - pst->st_ex_size; 882 883 /* for allocation try fallocate first. This can fail on some 975 884 platforms e.g. when the filesystem doesn't support it and no 976 885 emulation is being done by the libc (like on AIX with JFS1). In that 977 case we do our own emulation. posix_fallocate implementations can886 case we do our own emulation. fallocate implementations can 978 887 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); 980 890 if (ret == ENOSPC) { 981 891 errno = ENOSPC; … … 985 895 return 0; 986 896 } 987 DEBUG(10,("strict_allocate_ftruncate: sys_posix_fallocatefailed with "897 DEBUG(10,("strict_allocate_ftruncate: SMB_VFS_FALLOCATE failed with " 988 898 "error %d. Falling back to slow manual allocation\n", ret)); 989 899 … … 1000 910 1001 911 /* 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 } 1020 917 1021 918 return 0; … … 1025 922 { 1026 923 int result = -1; 1027 SMB_STRUCT_STAT st; 924 SMB_STRUCT_STAT *pst; 925 NTSTATUS status; 1028 926 char c = 0; 1029 SMB_OFF_T currpos;1030 927 1031 928 START_PROFILE(syscall_ftruncate); 1032 929 1033 if (lp_strict_allocate(SNUM(fsp->conn)) ) {930 if (lp_strict_allocate(SNUM(fsp->conn)) && !fsp->is_sparse) { 1034 931 result = strict_allocate_ftruncate(handle, fsp, len); 1035 932 END_PROFILE(syscall_ftruncate); … … 1050 947 extend a file with ftruncate. Provide alternate implementation 1051 948 for this */ 1052 currpos = SMB_VFS_LSEEK(fsp, 0, SEEK_CUR);1053 if (currpos == -1) {1054 goto done;1055 }1056 949 1057 950 /* Do an fstat to see if the file is longer than the requested … … 1059 952 succeeded or shorter, in which case seek to len - 1 and 1060 953 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)) { 1062 956 goto done; 1063 957 } 958 pst = &fsp->fsp_name->st; 1064 959 1065 960 #ifdef S_ISFIFO 1066 if (S_ISFIFO( st.st_ex_mode)) {961 if (S_ISFIFO(pst->st_ex_mode)) { 1067 962 result = 0; 1068 963 goto done; … … 1070 965 #endif 1071 966 1072 if ( st.st_ex_size == len) {967 if (pst->st_ex_size == len) { 1073 968 result = 0; 1074 969 goto done; 1075 970 } 1076 971 1077 if ( st.st_ex_size > len) {972 if (pst->st_ex_size > len) { 1078 973 /* the sys_ftruncate should have worked */ 1079 974 goto done; 1080 975 } 1081 976 1082 if (SMB_VFS_ LSEEK(fsp, len-1, SEEK_SET) != len -1)977 if (SMB_VFS_PWRITE(fsp, &c, 1, len-1)!=1) { 1083 978 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 1091 981 result = 0; 1092 982 … … 1094 984 1095 985 END_PROFILE(syscall_ftruncate); 986 return result; 987 } 988 989 static 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); 1096 1007 return result; 1097 1008 } … … 1187 1098 } 1188 1099 1189 static char *vfswrap_realpath(vfs_handle_struct *handle, const char *path , char *resolved_path)1100 static char *vfswrap_realpath(vfs_handle_struct *handle, const char *path) 1190 1101 { 1191 1102 char *result; 1192 1103 1193 1104 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 1195 1119 END_PROFILE(syscall_realpath); 1196 1120 return result; … … 1394 1318 static NTSTATUS vfswrap_fget_nt_acl(vfs_handle_struct *handle, 1395 1319 files_struct *fsp, 1396 uint32 security_info, SEC_DESC **ppdesc) 1320 uint32 security_info, 1321 struct security_descriptor **ppdesc) 1397 1322 { 1398 1323 NTSTATUS result; … … 1406 1331 static NTSTATUS vfswrap_get_nt_acl(vfs_handle_struct *handle, 1407 1332 const char *name, 1408 uint32 security_info, SEC_DESC **ppdesc) 1333 uint32 security_info, 1334 struct security_descriptor **ppdesc) 1409 1335 { 1410 1336 NTSTATUS result; … … 1416 1342 } 1417 1343 1418 static NTSTATUS vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info_sent, const SEC_DESC*psd)1344 static NTSTATUS vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info_sent, const struct security_descriptor *psd) 1419 1345 { 1420 1346 NTSTATUS result; … … 1590 1516 } 1591 1517 1592 s size_t vfswrap_llistxattr(struct vfs_handle_struct *handle, const char *path, char *list, size_t size)1518 static ssize_t vfswrap_llistxattr(struct vfs_handle_struct *handle, const char *path, char *list, size_t size) 1593 1519 { 1594 1520 return sys_llistxattr(path, list, size); 1595 1521 } 1596 1522 1597 s size_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, char *list, size_t size)1523 static ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, char *list, size_t size) 1598 1524 { 1599 1525 return sys_flistxattr(fsp->fh->fd, list, size); … … 1690 1616 } 1691 1617 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)) { 1618 static 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)) { 1695 1626 return false; 1696 1627 } … … 1703 1634 } 1704 1635 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 1705 1642 return (dmapi_file_flags(path) & FILE_ATTRIBUTE_OFFLINE) != 0; 1706 1643 } 1707 1644 1708 static int vfswrap_set_offline(struct vfs_handle_struct *handle, const char *path) 1645 static int vfswrap_set_offline(struct vfs_handle_struct *handle, 1646 const struct smb_filename *fname) 1709 1647 { 1710 1648 /* We don't know how to set offline bit by default, needs to be overriden in the vfs modules */ … … 1730 1668 1731 1669 .opendir = vfswrap_opendir, 1670 .fdopendir = vfswrap_fdopendir, 1732 1671 .readdir = vfswrap_readdir, 1733 1672 .seekdir = vfswrap_seekdir, … … 1741 1680 /* File operations */ 1742 1681 1743 .open = vfswrap_open,1682 .open_fn = vfswrap_open, 1744 1683 .create_file = vfswrap_create_file, 1745 1684 .close_fn = vfswrap_close, … … 1767 1706 .ntimes = vfswrap_ntimes, 1768 1707 .ftruncate = vfswrap_ftruncate, 1708 .fallocate = vfswrap_fallocate, 1769 1709 .lock = vfswrap_lock, 1770 1710 .kernel_flock = vfswrap_kernel_flock,
Note:
See TracChangeset
for help on using the changeset viewer.