Changeset 988 for vendor/current/source3/smbd/fileio.c
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/smbd/fileio.c
r740 r988 26 26 #include "smbprofile.h" 27 27 28 static bool setup_write_cache(files_struct *, SMB_OFF_T); 28 struct write_cache { 29 off_t file_size; 30 off_t offset; 31 size_t alloc_size; 32 size_t data_size; 33 char *data; 34 }; 35 36 static bool setup_write_cache(files_struct *, off_t); 29 37 30 38 /**************************************************************************** … … 32 40 ****************************************************************************/ 33 41 34 static bool read_from_write_cache(files_struct *fsp,char *data, SMB_OFF_Tpos,size_t n)35 { 36 write_cache *wcp = fsp->wcp;42 static bool read_from_write_cache(files_struct *fsp,char *data,off_t pos,size_t n) 43 { 44 struct write_cache *wcp = fsp->wcp; 37 45 38 46 if(!wcp) { … … 46 54 memcpy(data, wcp->data + (pos - wcp->offset), n); 47 55 48 DO_PROFILE_INC(writecache_ read_hits);56 DO_PROFILE_INC(writecache_cached_reads); 49 57 50 58 return True; … … 55 63 ****************************************************************************/ 56 64 57 ssize_t read_file(files_struct *fsp,char *data, SMB_OFF_Tpos,size_t n)58 { 59 ssize_t ret =0,readret;65 ssize_t read_file(files_struct *fsp,char *data,off_t pos,size_t n) 66 { 67 ssize_t ret = 0; 60 68 61 69 /* you can't read from print files */ … … 75 83 } 76 84 77 flush_write_cache(fsp, READ_FLUSH);85 flush_write_cache(fsp, SAMBA_READ_FLUSH); 78 86 79 87 fsp->fh->pos = pos; 80 88 81 89 if (n > 0) { 82 #ifdef DMF_FIX 83 int numretries = 3; 84 tryagain: 85 readret = SMB_VFS_PREAD(fsp,data,n,pos); 86 87 if (readret == -1) { 88 if ((errno == EAGAIN) && numretries) { 89 DEBUG(3,("read_file EAGAIN retry in 10 seconds\n")); 90 (void)sleep(10); 91 --numretries; 92 goto tryagain; 93 } 90 ret = SMB_VFS_PREAD(fsp,data,n,pos); 91 92 if (ret == -1) { 94 93 return -1; 95 }96 #else /* NO DMF fix. */97 readret = SMB_VFS_PREAD(fsp,data,n,pos);98 99 if (readret == -1) {100 return -1;101 }102 #endif103 if (readret > 0) {104 ret += readret;105 94 } 106 95 } … … 122 111 files_struct *fsp, 123 112 const char *data, 124 SMB_OFF_Tpos,113 off_t pos, 125 114 size_t n) 126 115 { … … 164 153 { 165 154 int ret; 166 write_cache *wcp = fsp->wcp;155 struct write_cache *wcp = fsp->wcp; 167 156 168 157 wcp->file_size = wcp->offset + wcp->data_size; … … 176 165 } 177 166 178 void update_write_time_handler(struct event_context *ctx,179 struct t imed_event*te,167 void update_write_time_handler(struct tevent_context *ctx, 168 struct tevent_timer *te, 180 169 struct timeval now, 181 170 void *private_data) … … 205 194 int delay; 206 195 207 if (fsp->posix_ open) {196 if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) { 208 197 /* Don't use delayed writes on POSIX files. */ 209 198 return; … … 241 230 /* trigger the update 2 seconds later */ 242 231 fsp->update_write_time_event = 243 event_add_timed(smbd_event_context(), NULL,244 timeval_current_ofs(0,delay),245 update_write_time_handler, fsp);232 tevent_add_timer(fsp->conn->sconn->ev_ctx, NULL, 233 timeval_current_ofs_usec(delay), 234 update_write_time_handler, fsp); 246 235 } 247 236 … … 250 239 struct smb_file_time ft; 251 240 252 if (fsp->posix_ open) {241 if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) { 253 242 /* Don't use delayed writes on POSIX files. */ 254 243 return; … … 281 270 } 282 271 272 void mark_file_modified(files_struct *fsp) 273 { 274 int dosmode; 275 276 if (fsp->modified) { 277 return; 278 } 279 280 fsp->modified = true; 281 282 if (SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) { 283 return; 284 } 285 trigger_write_time_update(fsp); 286 287 if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) { 288 return; 289 } 290 if (!(lp_store_dos_attributes(SNUM(fsp->conn)) || 291 MAP_ARCHIVE(fsp->conn))) { 292 return; 293 } 294 295 dosmode = dos_mode(fsp->conn, fsp->fsp_name); 296 if (IS_DOS_ARCHIVE(dosmode)) { 297 return; 298 } 299 file_set_dosmode(fsp->conn, fsp->fsp_name, 300 dosmode | FILE_ATTRIBUTE_ARCHIVE, NULL, false); 301 } 302 283 303 /**************************************************************************** 284 304 Write to a file. … … 288 308 files_struct *fsp, 289 309 const char *data, 290 SMB_OFF_Tpos,310 off_t pos, 291 311 size_t n) 292 312 { 293 write_cache *wcp = fsp->wcp;313 struct write_cache *wcp = fsp->wcp; 294 314 ssize_t total_written = 0; 295 315 int write_path = -1; … … 312 332 } 313 333 314 if (!fsp->modified) { 315 fsp->modified = True; 316 317 if (SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) == 0) { 318 trigger_write_time_update(fsp); 319 if (!fsp->posix_open && 320 (lp_store_dos_attributes(SNUM(fsp->conn)) || 321 MAP_ARCHIVE(fsp->conn))) { 322 int dosmode = dos_mode(fsp->conn, fsp->fsp_name); 323 if (!IS_DOS_ARCHIVE(dosmode)) { 324 file_set_dosmode(fsp->conn, fsp->fsp_name, 325 dosmode | FILE_ATTRIBUTE_ARCHIVE, NULL, false); 326 } 327 } 328 329 /* 330 * If this is the first write and we have an exclusive oplock then setup 331 * the write cache. 332 */ 333 334 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && !wcp) { 335 setup_write_cache(fsp, 336 fsp->fsp_name->st.st_ex_size); 337 wcp = fsp->wcp; 338 } 339 } 340 } 341 342 #ifdef WITH_PROFILE 334 /* 335 * If this is the first write and we have an exclusive oplock 336 * then setup the write cache. 337 */ 338 339 if (!fsp->modified && 340 EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && 341 (wcp == NULL)) { 342 /* 343 * Note: no write cache with leases! 344 * as the handles would have to share the write cache 345 * that's possible but an improvement for another day... 346 */ 347 setup_write_cache(fsp, fsp->fsp_name->st.st_ex_size); 348 wcp = fsp->wcp; 349 } 350 351 mark_file_modified(fsp); 352 343 353 DO_PROFILE_INC(writecache_total_writes); 344 354 if (!fsp->oplock_type) { 345 355 DO_PROFILE_INC(writecache_non_oplock_writes); 346 356 } 347 #endif348 357 349 358 /* … … 359 368 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_WRITE); 360 369 361 #ifdef WITH_PROFILE362 if (profile_p && profile_p->writecache_total_writes % 500 == 0) {363 DEBUG(3,("WRITECACHE: initwrites=%u abutted=%u total=%u \364 nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n",365 profile_p->writecache_init_writes,366 profile_p->writecache_abutted_writes,367 profile_p->writecache_total_writes,368 profile_p->writecache_non_oplock_writes,369 profile_p->writecache_allocated_write_caches,370 profile_p->writecache_num_write_caches,371 profile_p->writecache_direct_writes,372 profile_p->writecache_num_perfect_writes,373 profile_p->writecache_read_hits ));374 375 DEBUG(3,("WRITECACHE: Flushes SEEK=%d, READ=%d, WRITE=%d, READRAW=%d, OPLOCK=%d, CLOSE=%d, SYNC=%d\n",376 profile_p->writecache_flushed_writes[SEEK_FLUSH],377 profile_p->writecache_flushed_writes[READ_FLUSH],378 profile_p->writecache_flushed_writes[WRITE_FLUSH],379 profile_p->writecache_flushed_writes[READRAW_FLUSH],380 profile_p->writecache_flushed_writes[OPLOCK_RELEASE_FLUSH],381 profile_p->writecache_flushed_writes[CLOSE_FLUSH],382 profile_p->writecache_flushed_writes[SYNC_FLUSH] ));383 }384 #endif385 386 370 if (wcp && req->unread_bytes) { 387 371 /* If we're using receivefile don't 388 372 * deal with a write cache. 389 373 */ 390 flush_write_cache(fsp, WRITE_FLUSH);374 flush_write_cache(fsp, SAMBA_WRITE_FLUSH); 391 375 delete_write_cache(fsp); 392 376 wcp = NULL; … … 684 668 */ 685 669 686 flush_write_cache(fsp, WRITE_FLUSH);670 flush_write_cache(fsp, SAMBA_WRITE_FLUSH); 687 671 wcp->offset = wcp->file_size; 688 672 wcp->data_size = pos - wcp->file_size + 1; … … 788 772 789 773 if (cache_flush_needed) { 790 DEBUG(3,(" WRITE_FLUSH:%d: due to noncontinuous write: fd = %d, size = %.0f, pos = %.0f, \774 DEBUG(3,("SAMBA_WRITE_FLUSH:%d: due to noncontinuous write: fd = %d, size = %.0f, pos = %.0f, \ 791 775 n = %u, wcp->offset=%.0f, wcp->data_size=%u\n", 792 776 write_path, fsp->fh->fd, (double)wcp->file_size, (double)pos, (unsigned int)n, 793 777 (double)wcp->offset, (unsigned int)wcp->data_size )); 794 778 795 flush_write_cache(fsp, WRITE_FLUSH);779 flush_write_cache(fsp, SAMBA_WRITE_FLUSH); 796 780 } 797 781 } … … 821 805 822 806 if (n) { 823 #ifdef WITH_PROFILE 807 DO_PROFILE_INC(writecache_cached_writes); 824 808 if (wcp->data_size) { 825 809 DO_PROFILE_INC(writecache_abutted_writes); … … 827 811 DO_PROFILE_INC(writecache_init_writes); 828 812 } 829 #endif830 813 831 814 if ((wcp->data_size == 0) … … 851 834 if (wcp->data_size == 0) { 852 835 wcp->offset = pos; 853 DO_PROFILE_INC(writecache_num_write_caches);854 836 } 855 837 wcp->data_size += n; … … 880 862 void delete_write_cache(files_struct *fsp) 881 863 { 882 write_cache *wcp;864 struct write_cache *wcp; 883 865 884 866 if(!fsp) { … … 890 872 } 891 873 892 DO_PROFILE_ DEC(writecache_allocated_write_caches);874 DO_PROFILE_INC(writecache_deallocations); 893 875 allocated_write_caches--; 894 876 … … 906 888 ****************************************************************************/ 907 889 908 static bool setup_write_cache(files_struct *fsp, SMB_OFF_Tfile_size)890 static bool setup_write_cache(files_struct *fsp, off_t file_size) 909 891 { 910 892 ssize_t alloc_size = lp_write_cache_size(SNUM(fsp->conn)); 911 write_cache *wcp;893 struct write_cache *wcp; 912 894 913 895 if (allocated_write_caches >= MAX_WRITE_CACHES) { … … 919 901 } 920 902 921 if((wcp = SMB_MALLOC_P( write_cache)) == NULL) {903 if((wcp = SMB_MALLOC_P(struct write_cache)) == NULL) { 922 904 DEBUG(0,("setup_write_cache: malloc fail.\n")); 923 905 return False; … … 938 920 939 921 fsp->wcp = wcp; 940 DO_PROFILE_INC(writecache_allocat ed_write_caches);922 DO_PROFILE_INC(writecache_allocations); 941 923 allocated_write_caches++; 942 924 … … 951 933 ****************************************************************************/ 952 934 953 void set_filelen_write_cache(files_struct *fsp, SMB_OFF_Tfile_size)935 void set_filelen_write_cache(files_struct *fsp, off_t file_size) 954 936 { 955 937 if(fsp->wcp) { … … 976 958 ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason) 977 959 { 978 write_cache *wcp = fsp->wcp;960 struct write_cache *wcp = fsp->wcp; 979 961 size_t data_size; 980 962 ssize_t ret; … … 987 969 wcp->data_size = 0; 988 970 989 DO_PROFILE_DEC_INC(writecache_num_write_caches,writecache_flushed_writes[reason]); 971 switch (reason) { 972 case SAMBA_SEEK_FLUSH: 973 DO_PROFILE_INC(writecache_flush_reason_seek); 974 break; 975 case SAMBA_READ_FLUSH: 976 DO_PROFILE_INC(writecache_flush_reason_read); 977 break; 978 case SAMBA_WRITE_FLUSH: 979 DO_PROFILE_INC(writecache_flush_reason_write);; 980 break; 981 case SAMBA_READRAW_FLUSH: 982 DO_PROFILE_INC(writecache_flush_reason_readraw); 983 break; 984 case SAMBA_OPLOCK_RELEASE_FLUSH: 985 DO_PROFILE_INC(writecache_flush_reason_oplock); 986 break; 987 case SAMBA_CLOSE_FLUSH: 988 DO_PROFILE_INC(writecache_flush_reason_close); 989 break; 990 case SAMBA_SYNC_FLUSH: 991 DO_PROFILE_INC(writecache_flush_reason_sync); 992 break; 993 case SAMBA_SIZECHANGE_FLUSH: 994 DO_PROFILE_INC(writecache_flush_reason_sizechange); 995 break; 996 default: 997 break; 998 } 990 999 991 1000 DEBUG(9,("flushing write cache: fd = %d, off=%.0f, size=%u\n", 992 1001 fsp->fh->fd, (double)wcp->offset, (unsigned int)data_size)); 993 1002 994 #ifdef WITH_PROFILE995 1003 if(data_size == wcp->alloc_size) { 996 DO_PROFILE_INC(writecache_num_perfect_writes); 997 } 998 #endif 1004 DO_PROFILE_INC(writecache_perfect_writes); 1005 } 999 1006 1000 1007 ret = real_write_file(NULL, fsp, wcp->data, wcp->offset, data_size); … … 1021 1028 1022 1029 if (lp_strict_sync(SNUM(conn)) && 1023 (lp_sync always(SNUM(conn)) || write_through)) {1024 int ret = flush_write_cache(fsp, S YNC_FLUSH);1030 (lp_sync_always(SNUM(conn)) || write_through)) { 1031 int ret = flush_write_cache(fsp, SAMBA_SYNC_FLUSH); 1025 1032 if (ret == -1) { 1026 1033 return map_nt_error_from_unix(errno); … … 1041 1048 { 1042 1049 if (fsp->fh->fd == -1) { 1043 if (fsp->posix_ open) {1050 if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) { 1044 1051 return SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name); 1045 1052 } else {
Note:
See TracChangeset
for help on using the changeset viewer.