smb_write.c revision 2c2961f8403049d948b9f3e6c35d6488b6b7e1aa
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <smbsrv/smb_incl.h>
#include <smbsrv/smb_fsops.h>
#define SMB_WRMODE_WRITE_THRU 0x0001
#define SMB_WRMODE_IS_STABLE(M) ((M) & SMB_WRMODE_WRITE_THRU)
/*
* The limit in bytes that the marshalling will grow the buffer
* chain to accomodate incoming data on SmbWriteX requests.
* This sets the upper limit for the data-count per SmbWriteX
* request.
*/
#define SMB_WRITEX_MAX 102400
/*
* Write count bytes at the specified offset in a file. The offset is
* limited to 32-bits. If the count is zero, the file is truncated to
* the length specified by the offset.
*
* The response count indicates the actual number of bytes written, which
* will equal the requested count on success. If request and response
* counts differ but there is no error, the client will assume that the
* server encountered a resource issue.
*/
{
int rc;
smb_rw_param_t *, param);
}
void
{
}
{
int rc;
return (SDRC_ERROR);
}
} else {
return (SDRC_ERROR);
}
}
if (rc != 0) {
return (SDRC_ERROR);
}
}
/*
* Write count bytes to a file and then close the file. This function
* can only be used to write to 32-bit offsets and the client must set
* WordCount (6 or 12) correctly in order to locate the data to be
* written. If an error occurs on the write, the file should still be
* closed. If Count is 0, the file is truncated (or extended) to offset.
*
* If the last_write time is non-zero, last_write should be used to set
* the mtime. Otherwise the file system stamps the mtime. Failure to
* set mtime should not result in an error response.
*/
{
int rc;
} else {
}
smb_rw_param_t *, param);
}
void
{
}
{
int rc = 0;
return (SDRC_ERROR);
}
} else {
/*
* There may be a bug here: should this be "3.#B"?
*/
return (SDRC_ERROR);
}
}
if (rc != 0) {
return (SDRC_ERROR);
}
}
/*
* Write count bytes to a file at the specified offset and then unlock
* them. Write behind is safe because the client should have the range
* locked and this request is allowed to extend the file - note that
* offset is limited to 32-bits.
*
* Spec advice: it is an error for count to be zero. For compatibility,
* we take no action and return success.
*
* The SmbLockAndRead/SmbWriteAndUnlock sub-dialect is only valid on disk
* files. Reject any attempt to use it on other shares.
*
* The response count indicates the actual number of bytes written, which
* will equal the requested count on success. If request and response
* counts differ but there is no error, the client will assume that the
* server encountered a resource issue.
*/
{
int rc;
smb_rw_param_t *, param);
}
void
{
}
{
int rc = 0;
return (SDRC_ERROR);
}
return (SDRC_ERROR);
}
}
return (SDRC_ERROR);
}
return (SDRC_ERROR);
}
if (status != NT_STATUS_SUCCESS) {
return (SDRC_ERROR);
}
}
/*
* Write bytes to a file (SMB Core). This request was extended in
* LM 0.12 to support 64-bit offsets, indicated by sending a wct of
* 14, instead of 12, and including additional offset information.
*
* A ByteCount of 0 does not truncate the file - use SMB_COM_WRITE
* to truncate a file. A zero length merely transfers zero bytes.
*
* If bit 0 of WriteMode is set, Fid must refer to a disk file and
* the data must be on stable storage before responding.
*
* MS-SMB 3.3.5.8 update to LM 0.12 4.2.5:
* If CAP_LARGE_WRITEX is set, the byte count may be larger than the
* negotiated buffer size and the server is expected to write the
* number of bytes specified.
*/
{
int rc;
} else {
}
smb_rw_param_t *, param);
}
void
{
}
{
int rc;
return (SDRC_ERROR);
}
return (SDRC_ERROR);
}
return (SDRC_ERROR);
}
return (SDRC_ERROR);
}
}
}
/*
*
* Returns errno values.
*/
static int
{
int stability = 0;
int rc = 0;
case STYPE_DISKTREE:
if (rc != NT_STATUS_SUCCESS) {
return (EACCES);
}
}
}
if (rc)
return (rc);
}
}
break;
case STYPE_IPC:
break;
default:
break;
}
if (rc != 0)
return (rc);
return (rc);
}
/*
* Truncate a disk file to the specified offset.
* Typically, w_count will be zero here.
*
* Returns errno values.
*/
static int
{
int rc;
return (0);
if (status != NT_STATUS_SUCCESS) {
if (status != NT_STATUS_SUCCESS)
return (EACCES);
else
}
return (EACCES);
}
if (status != NT_STATUS_SUCCESS) {
return (EACCES);
}
}
return (rc);
return (0);
}
/*
* Set the file size using the value in the node. The file will only be
* updated if NODE_FLAGS_SET_SIZE is set. It is safe to pass a null node
* pointer, we just return success.
*
* The node attributes are refreshed here from the file system. So any
* attributes that are affected by file size changes, i.e. the mtime,
* will be current.
*
* Note that smb_write_andx cannot be used to reduce the file size so,
* if this is required, smb_write is called with a count of zero and
* the appropriate file length in offset. The file should be resized
* to the length specified by the offset.
*/
int
{
return (0);
return (0);
}