Ejemplo n.º 1
0
Archivo: vfs.c Proyecto: 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;
		}
	}
Ejemplo n.º 2
0
static void release_file_oplock(files_struct *fsp)
{
	struct smbd_server_connection *sconn = fsp->conn->sconn;
	struct kernel_oplocks *koplocks = sconn->oplocks.kernel_ops;

	if ((fsp->oplock_type != NO_OPLOCK) &&
	    koplocks) {
		koplocks->ops->release_oplock(koplocks, fsp, NO_OPLOCK);
	}

	if (fsp->oplock_type == LEVEL_II_OPLOCK) {
		sconn->oplocks.level_II_open--;
	} else if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
		sconn->oplocks.exclusive_open--;
	}

	SMB_ASSERT(sconn->oplocks.exclusive_open>=0);
	SMB_ASSERT(sconn->oplocks.level_II_open>=0);

	fsp->oplock_type = NO_OPLOCK;
	fsp->sent_oplock_break = NO_BREAK_SENT;

	flush_write_cache(fsp, SAMBA_OPLOCK_RELEASE_FLUSH);
	delete_write_cache(fsp);

	TALLOC_FREE(fsp->oplock_timeout);
}
Ejemplo n.º 3
0
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;

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

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

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

	contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);

	flush_write_cache(fsp, SIZECHANGE_FLUSH);

	if (!sparse_buf) {
		sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
		if (!sparse_buf) {
			errno = ENOMEM;
			ret = -1;
			goto out;
		}
	}
Ejemplo n.º 4
0
ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n)
{
	ssize_t ret=0,readret;

	/* you can't read from print files */
	if (fsp->print_file) {
		errno = EBADF;
		return -1;
	}

	/*
	 * Serve from write cache if we can.
	 */

	if(read_from_write_cache(fsp, data, pos, n)) {
		fsp->fh->pos = pos + n;
		fsp->fh->position_information = fsp->fh->pos;
		return n;
	}

	flush_write_cache(fsp, READ_FLUSH);

	fsp->fh->pos = pos;

	if (n > 0) {
#ifdef DMF_FIX
		int numretries = 3;
tryagain:
		readret = SMB_VFS_PREAD(fsp,data,n,pos);

		if (readret == -1) {
			if ((errno == EAGAIN) && numretries) {
				DEBUG(3,("read_file EAGAIN retry in 10 seconds\n"));
				(void)sleep(10);
				--numretries;
				goto tryagain;
			}
			return -1;
		}
#else /* NO DMF fix. */
		readret = SMB_VFS_PREAD(fsp,data,n,pos);

		if (readret == -1) {
			return -1;
		}
#endif
		if (readret > 0) {
			ret += readret;
		}
	}

	DEBUG(10,("read_file (%s): pos = %.0f, size = %lu, returned %lu\n",
		  fsp_str_dbg(fsp), (double)pos, (unsigned long)n, (long)ret));

	fsp->fh->pos += ret;
	fsp->fh->position_information = fsp->fh->pos;

	return(ret);
}
Ejemplo n.º 5
0
static NTSTATUS close_filestruct(files_struct *fsp)
{
	NTSTATUS status = NT_STATUS_OK;

	if (fsp->fh->fd != -1) {
		if(flush_write_cache(fsp, SAMBA_CLOSE_FLUSH) == -1) {
			status = map_nt_error_from_unix(errno);
		}
		delete_write_cache(fsp);
	}

	return status;
}
Ejemplo n.º 6
0
static NTSTATUS close_filestruct(files_struct *fsp)
{   
	NTSTATUS status = NT_STATUS_OK;
	connection_struct *conn = fsp->conn;
    
	if (fsp->fh->fd != -1) {
		if(flush_write_cache(fsp, CLOSE_FLUSH) == -1) {
			status = map_nt_error_from_unix(errno);
		}
		delete_write_cache(fsp);
	}

	conn->num_files_open--;
	SAFE_FREE(fsp->wbmpx_ptr);
	return status;
}    
Ejemplo n.º 7
0
static int close_filestruct(files_struct *fsp)
{   
	connection_struct *conn = fsp->conn;
	int ret = 0;
    
	if (fsp->fh->fd != -1) {
		if(flush_write_cache(fsp, CLOSE_FLUSH) == -1)
			ret = -1;

		delete_write_cache(fsp);
	}

	conn->num_files_open--;
	SAFE_FREE(fsp->wbmpx_ptr);

	return ret;
}    
Ejemplo n.º 8
0
Archivo: vfs.c Proyecto: 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;
}
Ejemplo n.º 9
0
int vfs_set_filelen(files_struct *fsp, SMB_OFF_T len)
{
	int ret;

	contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);

	DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
		  fsp_str_dbg(fsp), (double)len));
	flush_write_cache(fsp, SIZECHANGE_FLUSH);
	if ((ret = SMB_VFS_FTRUNCATE(fsp, 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->base_name);
	}

	contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);

	return ret;
}
Ejemplo n.º 10
0
ssize_t read_file(files_struct *fsp,char *data,off_t pos,size_t n)
{
	ssize_t ret = 0;

	/* you can't read from print files */
	if (fsp->print_file) {
		errno = EBADF;
		return -1;
	}

	/*
	 * Serve from write cache if we can.
	 */

	if(read_from_write_cache(fsp, data, pos, n)) {
		fsp->fh->pos = pos + n;
		fsp->fh->position_information = fsp->fh->pos;
		return n;
	}

	flush_write_cache(fsp, READ_FLUSH);

	fsp->fh->pos = pos;

	if (n > 0) {
		ret = SMB_VFS_PREAD(fsp,data,n,pos);

		if (ret == -1) {
			return -1;
		}
	}

	DEBUG(10,("read_file (%s): pos = %.0f, size = %lu, returned %lu\n",
		  fsp_str_dbg(fsp), (double)pos, (unsigned long)n, (long)ret));

	fsp->fh->pos += ret;
	fsp->fh->position_information = fsp->fh->pos;

	return(ret);
}
Ejemplo n.º 11
0
static void downgrade_file_oplock(files_struct *fsp)
{
	struct smbd_server_connection *sconn = fsp->conn->sconn;
	struct kernel_oplocks *koplocks = sconn->oplocks.kernel_ops;

	if (!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
		DEBUG(0, ("trying to downgrade an already-downgraded oplock!\n"));
		return;
	}

	if (koplocks) {
		koplocks->ops->release_oplock(koplocks, fsp, LEVEL_II_OPLOCK);
	}
	fsp->oplock_type = LEVEL_II_OPLOCK;
	sconn->oplocks.exclusive_open--;
	sconn->oplocks.level_II_open++;
	fsp->sent_oplock_break = NO_BREAK_SENT;

	flush_write_cache(fsp, SAMBA_OPLOCK_RELEASE_FLUSH);
	delete_write_cache(fsp);

	TALLOC_FREE(fsp->oplock_timeout);
}
Ejemplo n.º 12
0
Archivo: vfs.c Proyecto: 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;
}
Ejemplo n.º 13
0
int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
{
	int ret;
	SMB_STRUCT_STAT st;
	connection_struct *conn = fsp->conn;
	uint64_t space_avail;
	uint64_t bsize,dfree,dsize;

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

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

	if (((SMB_OFF_T)len) < 0) {
		DEBUG(0,("vfs_allocate_file_space: %s negative len "
			 "requested.\n", fsp_str_dbg(fsp)));
		errno = EINVAL;
		return -1;
	}

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

	if (len == (uint64_t)st.st_ex_size)
		return 0;

	if (len < (uint64_t)st.st_ex_size) {
		/* Shrink - use ftruncate. */

		DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
			  "size %.0f\n", fsp_str_dbg(fsp),
			  (double)st.st_ex_size));

		contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);

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

		contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);

		return ret;
	}

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

	contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
	contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);

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

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

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

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

	return 0;
}