예제 #1
0
파일: vfs.c 프로젝트: hajuuk/R7000
int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len)
{
	int ret;
	SMB_STRUCT_STAT st;
	SMB_OFF_T offset;
	size_t total;
	size_t num_to_write;
	ssize_t pwrite_ret;

	release_level_2_oplocks_on_change(fsp);
	ret = SMB_VFS_FSTAT(fsp,fsp->fh->fd,&st);
	if (ret == -1) {
		return ret;
	}

	if (len <= st.st_size) {
		return 0;
	}

	DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to len %.0f (%.0f bytes)\n",
		fsp->fsp_name, (double)st.st_size, (double)len, (double)(len - st.st_size)));

	flush_write_cache(fsp, SIZECHANGE_FLUSH);

	if (!sparse_buf) {
		sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
		if (!sparse_buf) {
			errno = ENOMEM;
			return -1;
		}
	}
예제 #2
0
파일: vfs.c 프로젝트: hajuuk/R7000
int vfs_set_filelen(files_struct *fsp, SMB_OFF_T len)
{
	int ret;

	release_level_2_oplocks_on_change(fsp);
	DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n", fsp->fsp_name, (double)len));
	flush_write_cache(fsp, SIZECHANGE_FLUSH);
	 if (len > 0 && len < 0x1000000) {
		if ((ret = SMB_VFS_FTRUNCATE(fsp, fsp->fh->fd, len)) != -1) {
			set_filelen_write_cache(fsp, len);
			notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
				     FILE_NOTIFY_CHANGE_SIZE
				     | FILE_NOTIFY_CHANGE_ATTRIBUTES,
				     fsp->fsp_name);
		}
	}else
		ret=0;

	return ret;
}
예제 #3
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] ));
    }
예제 #4
0
파일: vfs.c 프로젝트: hajuuk/R7000
int vfs_allocate_file_space(files_struct *fsp, SMB_BIG_UINT len)
{
	int ret;
	SMB_STRUCT_STAT st;
	connection_struct *conn = fsp->conn;
	SMB_BIG_UINT space_avail;
	SMB_BIG_UINT bsize,dfree,dsize;

	release_level_2_oplocks_on_change(fsp);

	/*
	 * Actually try and commit the space on disk....
	 */

	DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n", fsp->fsp_name, (double)len ));

    /* Foxconn removed start pling 11/18/2009 */
    /* Don't check negative length, to avoid "disk full" error 
     * when copy file from Vista/Win7 to USB.
     */
#if 0
	if (((SMB_OFF_T)len) < 0) {
		DEBUG(0,("vfs_allocate_file_space: %s negative len requested.\n", fsp->fsp_name ));
		errno = EINVAL;
		return -1;
	}
#endif
    /* Foxconn removed end pling 11/18/2009 */

	ret = SMB_VFS_FSTAT(fsp,fsp->fh->fd,&st);
	if (ret == -1)
		return ret;

	if (len == (SMB_BIG_UINT)st.st_size)
		return 0;

	if (len < (SMB_BIG_UINT)st.st_size) {
		/* Shrink - use ftruncate. */

		DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current size %.0f\n",
				fsp->fsp_name, (double)st.st_size ));

		flush_write_cache(fsp, SIZECHANGE_FLUSH);
		if ((ret = SMB_VFS_FTRUNCATE(fsp, fsp->fh->fd, (SMB_OFF_T)len)) != -1) {
			set_filelen_write_cache(fsp, len);
		}
		return ret;
	}

	/* Grow - we need to test if we have enough space. */

	if (!lp_strict_allocate(SNUM(fsp->conn)))
		return 0;

	len -= st.st_size;
	len /= 1024; /* Len is now number of 1k blocks needed. */
	space_avail = get_dfree_info(conn,fsp->fsp_name,False,&bsize,&dfree,&dsize);
	if (space_avail == (SMB_BIG_UINT)-1) {
		return -1;
	}

	DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, needed blocks = %.0f, space avail = %.0f\n",
			fsp->fsp_name, (double)st.st_size, (double)len, (double)space_avail ));

	if (len > space_avail) {
		errno = ENOSPC;
		return -1;
	}

	return 0;
}