void mark_file_modified(files_struct *fsp) { int dosmode; if (fsp->modified) { return; } fsp->modified = true; if (SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) { return; } trigger_write_time_update(fsp); if (fsp->posix_open) { return; } if (!(lp_store_dos_attributes(SNUM(fsp->conn)) || MAP_ARCHIVE(fsp->conn))) { return; } dosmode = dos_mode(fsp->conn, fsp->fsp_name); if (IS_DOS_ARCHIVE(dosmode)) { return; } file_set_dosmode(fsp->conn, fsp->fsp_name, dosmode | FILE_ATTRIBUTE_ARCHIVE, NULL, false); }
ssize_t write_file(struct smb_request *req, files_struct *fsp, const char *data, SMB_OFF_T pos, size_t n) { write_cache *wcp = fsp->wcp; ssize_t total_written = 0; int write_path = -1; if (fsp->print_file) { uint32_t t; int ret; ret = print_spool_write(fsp, data, n, pos, &t); if (ret) { errno = ret; return -1; } return t; } if (!fsp->can_write) { errno = EPERM; return -1; } if (!fsp->modified) { fsp->modified = True; if (SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) == 0) { trigger_write_time_update(fsp); if (!fsp->posix_open && (lp_store_dos_attributes(SNUM(fsp->conn)) || MAP_ARCHIVE(fsp->conn))) { int dosmode = dos_mode(fsp->conn, fsp->fsp_name); if (!IS_DOS_ARCHIVE(dosmode)) { file_set_dosmode(fsp->conn, fsp->fsp_name, dosmode | FILE_ATTRIBUTE_ARCHIVE, NULL, false); } } /* * If this is the first write and we have an exclusive oplock then setup * the write cache. */ if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && !wcp) { setup_write_cache(fsp, fsp->fsp_name->st.st_ex_size); wcp = fsp->wcp; } } } #ifdef WITH_PROFILE DO_PROFILE_INC(writecache_total_writes); if (!fsp->oplock_type) { DO_PROFILE_INC(writecache_non_oplock_writes); } #endif /* * If this file is level II oplocked then we need * to grab the shared memory lock and inform all * other files with a level II lock that they need * to flush their read caches. We keep the lock over * the shared memory area whilst doing this. */ /* This should actually be improved to span the write. */ contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_WRITE); contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_WRITE); #ifdef WITH_PROFILE if (profile_p && profile_p->writecache_total_writes % 500 == 0) { DEBUG(3,("WRITECACHE: initwrites=%u abutted=%u total=%u \ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", profile_p->writecache_init_writes, profile_p->writecache_abutted_writes, profile_p->writecache_total_writes, profile_p->writecache_non_oplock_writes, profile_p->writecache_allocated_write_caches, profile_p->writecache_num_write_caches, profile_p->writecache_direct_writes, profile_p->writecache_num_perfect_writes, profile_p->writecache_read_hits )); DEBUG(3,("WRITECACHE: Flushes SEEK=%d, READ=%d, WRITE=%d, READRAW=%d, OPLOCK=%d, CLOSE=%d, SYNC=%d\n", profile_p->writecache_flushed_writes[SEEK_FLUSH], profile_p->writecache_flushed_writes[READ_FLUSH], profile_p->writecache_flushed_writes[WRITE_FLUSH], profile_p->writecache_flushed_writes[READRAW_FLUSH], profile_p->writecache_flushed_writes[OPLOCK_RELEASE_FLUSH], profile_p->writecache_flushed_writes[CLOSE_FLUSH], profile_p->writecache_flushed_writes[SYNC_FLUSH] )); }