Beispiel #1
0
ssize_t write_file(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) {
#ifdef AVM_NO_PRINTING
        errno = EBADF;
        return -1;
#else
        fstring sharename;
        uint32 jobid;

        if (!rap_to_pjobid(fsp->rap_print_jobid, sharename, &jobid)) {
            DEBUG(3,("write_file: Unable to map RAP jobid %u to jobid.\n",
                     (unsigned int)fsp->rap_print_jobid ));
            errno = EBADF;
            return -1;
        }

        return print_job_write(SNUM(fsp->conn), jobid, data, pos, n);
#endif /* AVM_NO_PRINTING */
    }

    if (!fsp->can_write) {
        errno = EPERM;
        return(0);
    }

    if (!fsp->modified) {
        SMB_STRUCT_STAT st;
        fsp->modified = True;

        if (SMB_VFS_FSTAT(fsp,fsp->fh->fd,&st) == 0) {
            int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st);
            if ((lp_store_dos_attributes(SNUM(fsp->conn)) || MAP_ARCHIVE(fsp->conn)) && !IS_DOS_ARCHIVE(dosmode)) {
                file_set_dosmode(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st, 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, st.st_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.
     */

    release_level_2_oplocks_on_change(fsp);

#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] ));
    }
Beispiel #2
0
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] ));
	}
ssize_t write_file(struct smb_request *req,
			files_struct *fsp,
			const char *data,
			off_t pos,
			size_t n)
{
	struct 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 this is the first write and we have an exclusive oplock
	 * then setup the write cache.
	 */

	if (!fsp->modified &&
	    EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) &&
	    (wcp == NULL)) {
		setup_write_cache(fsp, fsp->fsp_name->st.st_ex_size);
		wcp = fsp->wcp;
	}

	mark_file_modified(fsp);

#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] ));
	}