/*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms of version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy of the CDDL is also available via the Internet at
*/
/*
* Copyright 2014 Nexenta Systems, Inc. All rights reserved.
*/
/*
* Dispatch function for SMB2_LOCK
*/
#include <smbsrv/smb2_kproto.h>
struct SMB2_LOCK_ELEMENT {
};
/*
* This is a somewhat arbitrary sanity limit on the length of the
* SMB2_LOCK_ELEMENT array. It usually has length one or two.
*/
{
uint16_t i;
int rc = 0;
/*
* SMB2 Lock request
*/
&StructSize, /* w */
&LockCount, /* w */
&LockSequence, /* l */
return (SDRC_ERROR);
if (status)
goto errout;
goto errout;
}
if (LockCount > smb2_lock_max_elem) {
goto errout;
}
/*
* Process the array of SMB2_LOCK_ELEMENT structs
* We do this twice. (it's always a short list)
* The first time, just validate the flags, and check
* if any of the locking request might need to block.
* The second time (either here, or in the async
* handler function) process the locks for real.
*/
for (i = 0; i < LockCount; i++) {
if (rc) {
goto errout;
}
/*
* Make sure the flags are valid;
* Find out if we might block.
*/
break;
/* BEGIN CSTYLED */
case SMB2_LOCKFLAG_SHARED_LOCK |
case SMB2_LOCKFLAG_EXCLUSIVE_LOCK |
case SMB2_LOCKFLAG_UNLOCK:
/* END CSTYLED */
break;
default:
goto errout;
}
}
if (MayBlock) {
/*
* May need to block. "Go async".
*/
goto errout;
}
if (status)
goto errout;
/*
* SMB2 Lock reply (sync)
*/
StructSize = 4;
(void) smb_mbc_encodef(
StructSize); /* w */
/* reserved .. */
return (SDRC_SUCCESS);
return (SDRC_SUCCESS);
}
static smb_sdrc_t
{
int rc = 0;
/*
* Decode the lock request again. It should all decode
* exactly the same as the first time we saw it. If not,
* report an "internal error".
*/
&StructSize, /* w */
&LockCount, /* w */
&LockSequence, /* l */
return (SDRC_ERROR);
if (status)
goto errout;
goto errout;
}
if (status)
goto errout;
/*
* SMB2 Lock reply (async)
*/
StructSize = 4;
(void) smb_mbc_encodef(
StructSize); /* w */
/* reserved .. */
return (SDRC_SUCCESS);
return (SDRC_SUCCESS);
}
/*
* Execute the vector of locks. This is the common function called by
* either the sync or async code paths. We've already decoded this
* request once when we get here, so if there are any decode errors
* then it's some kind of internal error.
*/
static uint32_t
{
uint16_t i;
int rc;
/*
* On entry, out position in the input data should be
* after both the SMB2 header and the fixed part of
* the SMB Lock request header (24).
*/
/*
* This is checked by our callers, but let's make sure.
*/
for (i = 0; i < LockCount; i++) {
if (rc) {
break;
}
if (status)
break;
}
return (status);
}
static uint32_t
{
/* FALLTHROUGH */
break;
/* FALLTHROUGH */
break;
case SMB2_LOCKFLAG_UNLOCK:
break;
/*
* We've already checked the flags previously, so any
* surprises here are some kind of internal error.
*/
default:
break;
}
return (status);
}