Beispiel #1
0
NTSTATUS query_lock(files_struct *fsp,
			uint32 *psmbpid,
			SMB_BIG_UINT *pcount,
			SMB_BIG_UINT *poffset,
			enum brl_type *plock_type,
			enum brl_flavour lock_flav)
{
	struct byte_range_lock *br_lck = NULL;
	NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED;

	if (!fsp->can_lock) {
		return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
	}

	if (!lp_locking(fsp->conn->params)) {
		return NT_STATUS_OK;
	}

	br_lck = brl_get_locks_readonly(NULL, fsp);
	if (!br_lck) {
		return NT_STATUS_NO_MEMORY;
	}

	status = brl_lockquery(br_lck,
			psmbpid,
			procid_self(),
			poffset,
			pcount,
			plock_type,
			lock_flav);

	TALLOC_FREE(br_lck);
	return status;
}
Beispiel #2
0
void locking_close_file(struct messaging_context *msg_ctx,
			files_struct *fsp,
			enum file_close_type close_type)
{
	struct byte_range_lock *br_lck;

	if (!lp_locking(fsp->conn->params)) {
		return;
	}

	/* If we have not outstanding locks or pending
	 * locks then we don't need to look in the lock db.
	 */

	if (fsp->current_lock_count == 0) {
		return;
	}

	br_lck = brl_get_locks(talloc_tos(),fsp);

	if (br_lck) {
		cancel_pending_lock_requests_by_fid(fsp, br_lck, close_type);
		brl_close_fnum(msg_ctx, br_lck);
		TALLOC_FREE(br_lck);
	}
}
Beispiel #3
0
BOOL is_locked(uint16 smbpid,
		files_struct * fsp, struct vfs_connection_struct *conn,
	       SMB_BIG_UINT count, SMB_BIG_UINT offset,
	       enum brl_type lock_type)
{
	int snum = conn->snum;
	BOOL ret;

	if (count == 0)
		return (False);

	if (!lp_locking(snum) || !lp_strict_locking(snum))
		return (False);

	ret = !brl_locktest(fsp->sbuf.st_dev, fsp->sbuf.st_ino, fsp->fnum,
			    smbpid, sys_getpid(), conn->snum,
			    offset, count, lock_type);

	/*
	 * There is no lock held by an SMB daemon, check to
	 * see if there is a POSIX lock from a UNIX or NFS process.
	 */

	if (!ret && lp_posix_locking(snum))
		ret = is_posix_locked(fsp, offset, count, lock_type);

	return ret;
}
Beispiel #4
0
struct byte_range_lock *do_lock(files_struct *fsp,
			uint32 lock_pid,
			SMB_BIG_UINT count,
			SMB_BIG_UINT offset,
			enum brl_type lock_type,
			enum brl_flavour lock_flav,
			BOOL blocking_lock,
			NTSTATUS *perr,
			uint32 *plock_pid)
{
	struct byte_range_lock *br_lck = NULL;

	if (!fsp->can_lock) {
		*perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
		return NULL;
	}

	if (!lp_locking(fsp->conn->params)) {
		*perr = NT_STATUS_OK;
		return NULL;
	}

	/* NOTE! 0 byte long ranges ARE allowed and should be stored  */

	DEBUG(10,("do_lock: lock flavour %s lock type %s start=%.0f len=%.0f requested for fnum %d file %s\n",
		lock_flav_name(lock_flav), lock_type_name(lock_type),
		(double)offset, (double)count, fsp->fnum, fsp->fsp_name ));

	br_lck = brl_get_locks(NULL, fsp);
	if (!br_lck) {
		*perr = NT_STATUS_NO_MEMORY;
		return NULL;
	}

	*perr = brl_lock(br_lck,
			lock_pid,
			procid_self(),
			offset,
			count, 
			lock_type,
			lock_flav,
			blocking_lock,
			plock_pid);

	if (lock_flav == WINDOWS_LOCK &&
			fsp->current_lock_count != NO_LOCKING_COUNT) {
		/* blocking ie. pending, locks also count here,
		 * as this is an efficiency counter to avoid checking
		 * the lock db. on close. JRA. */

		fsp->current_lock_count++;
	} else {
		/* Notice that this has had a POSIX lock request.
		 * We can't count locks after this so forget them.
		 */
		fsp->current_lock_count = NO_LOCKING_COUNT;
	}

	return br_lck;
}
Beispiel #5
0
NTSTATUS query_lock(files_struct *fsp,
			uint16 *psmbpid,
			SMB_BIG_UINT *pcount,
			SMB_BIG_UINT *poffset,
			enum brl_type *plock_type,
			enum brl_flavour lock_flav)
{
	struct byte_range_lock *br_lck = NULL;
	NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED;

	if (!OPEN_FSP(fsp) || !fsp->can_lock) {
		return NT_STATUS_INVALID_HANDLE;
	}

	if (!lp_locking(SNUM(fsp->conn))) {
		return NT_STATUS_OK;
	}

	br_lck = brl_get_locks(fsp);
	if (!br_lck) {
		return NT_STATUS_NO_MEMORY;
	}

	status = brl_lockquery(br_lck,
			psmbpid,
			procid_self(),
			poffset,
			pcount,
			plock_type,
			lock_flav);

	byte_range_lock_destructor(br_lck);
	return status;
}
Beispiel #6
0
NTSTATUS query_lock(files_struct *fsp,
			uint64_t *psmblctx,
			uint64_t *pcount,
			uint64_t *poffset,
			enum brl_type *plock_type,
			enum brl_flavour lock_flav)
{
	struct byte_range_lock *br_lck = NULL;

	if (!fsp->can_lock) {
		return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
	}

	if (!lp_locking(fsp->conn->params)) {
		return NT_STATUS_OK;
	}

	br_lck = brl_get_locks_readonly(fsp);
	if (!br_lck) {
		return NT_STATUS_NO_MEMORY;
	}

	return brl_lockquery(br_lck,
			psmblctx,
			messaging_server_id(fsp->conn->sconn->msg_ctx),
			poffset,
			pcount,
			plock_type,
			lock_flav);
}
Beispiel #7
0
NTSTATUS do_lock_cancel(files_struct *fsp,
			uint32 lock_pid,
			SMB_BIG_UINT count,
			SMB_BIG_UINT offset,
			enum brl_flavour lock_flav)
{
	BOOL ok = False;
	struct byte_range_lock *br_lck = NULL;
	
	if (!fsp->can_lock) {
		return fsp->is_directory ?
			NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
	}
	
	if (!lp_locking(fsp->conn->params)) {
		return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
	}

	DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for fnum %d file %s\n",
		  (double)offset, (double)count, fsp->fnum, fsp->fsp_name ));

	br_lck = brl_get_locks(NULL, fsp);
	if (!br_lck) {
		return NT_STATUS_NO_MEMORY;
	}

	ok = brl_lock_cancel(br_lck,
			lock_pid,
			procid_self(),
			offset,
			count,
			lock_flav);
   
	TALLOC_FREE(br_lck);

	if (!ok) {
		DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" ));
		return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
	}

	if (lock_flav == WINDOWS_LOCK &&
			fsp->current_lock_count != NO_LOCKING_COUNT) {
		SMB_ASSERT(fsp->current_lock_count > 0);
		fsp->current_lock_count--;
	}

	return NT_STATUS_OK;
}
Beispiel #8
0
NTSTATUS do_lock_cancel(files_struct *fsp,
			uint64 smblctx,
			uint64_t count,
			uint64_t offset,
			enum brl_flavour lock_flav,
			struct blocking_lock_record *blr)
{
	bool ok = False;
	struct byte_range_lock *br_lck = NULL;

	if (!fsp->can_lock) {
		return fsp->is_directory ?
			NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
	}

	if (!lp_locking(fsp->conn->params)) {
		return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
	}

	DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for %s file %s\n",
		  (double)offset, (double)count, fsp_fnum_dbg(fsp),
		  fsp_str_dbg(fsp)));

	br_lck = brl_get_locks(talloc_tos(), fsp);
	if (!br_lck) {
		return NT_STATUS_NO_MEMORY;
	}

	ok = brl_lock_cancel(br_lck,
			smblctx,
			messaging_server_id(fsp->conn->sconn->msg_ctx),
			offset,
			count,
			lock_flav,
			blr);

	TALLOC_FREE(br_lck);

	if (!ok) {
		DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" ));
		return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
	}

	decrement_current_lock_count(fsp, lock_flav);
	return NT_STATUS_OK;
}
Beispiel #9
0
NTSTATUS do_unlock(struct messaging_context *msg_ctx,
			files_struct *fsp,
			uint64_t smblctx,
			uint64_t count,
			uint64_t offset,
			enum brl_flavour lock_flav)
{
	bool ok = False;
	struct byte_range_lock *br_lck = NULL;

	if (!fsp->can_lock) {
		return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
	}

	if (!lp_locking(fsp->conn->params)) {
		return NT_STATUS_OK;
	}

	DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for %s file %s\n",
		  (double)offset, (double)count, fsp_fnum_dbg(fsp),
		  fsp_str_dbg(fsp)));

	br_lck = brl_get_locks(talloc_tos(), fsp);
	if (!br_lck) {
		return NT_STATUS_NO_MEMORY;
	}

	ok = brl_unlock(msg_ctx,
			br_lck,
			smblctx,
			messaging_server_id(fsp->conn->sconn->msg_ctx),
			offset,
			count,
			lock_flav);

	TALLOC_FREE(br_lck);

	if (!ok) {
		DEBUG(10,("do_unlock: returning ERRlock.\n" ));
		return NT_STATUS_RANGE_NOT_LOCKED;
	}

	decrement_current_lock_count(fsp, lock_flav);
	return NT_STATUS_OK;
}
Beispiel #10
0
BOOL do_unlock(uint16 smbpid,
		files_struct * fsp, struct vfs_connection_struct *conn,
	       SMB_BIG_UINT count, SMB_BIG_UINT offset, uint32 *err)
{
	BOOL ok = False;

	if (!lp_locking(conn->snum))
		return (True);

	if (!OPEN_FSP(fsp) || !fsp->can_lock || (fsp->conn != conn))
	{
		*err = NT_STATUS_NOT_LOCKED;
		return False;
	}

	DEBUG(10,
	      ("do_unlock: unlock start=%.0f len=%.0f requested for file %s\n",
	       (double)offset, (double)count, smbstrA(fsp->fsp_name)));

	/*
	 * Remove the existing lock record from the tdb lockdb
	 * before looking at POSIX locks. If this record doesn't
	 * match then don't bother looking to remove POSIX locks.
	 */

	ok = brl_unlock(fsp->sbuf.st_dev, fsp->sbuf.st_ino, fsp->fnum,
			smbpid, sys_getpid(), conn->snum, offset,
			count);

	if (!ok)
	{
		DEBUG(10, ("do_unlock: returning ERRlock.\n"));
		*err = NT_STATUS_RANGE_NOT_LOCKED;
		return False;
	}

	if (!lp_posix_locking(conn->snum))
		return True;

	(void)release_posix_lock(fsp, offset, count);

	return True;		/* Did unlock */
}
Beispiel #11
0
static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
		 SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type)
{
	NTSTATUS status;

	if (!lp_locking(SNUM(conn)))
		return NT_STATUS_OK;

	/* NOTE! 0 byte long ranges ARE allowed and should be stored  */


	DEBUG(10,("do_lock: lock type %s start=%.0f len=%.0f requested for file %s\n",
		  lock_type_name(lock_type), (double)offset, (double)count, fsp->fsp_name ));

	if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) {
		status = brl_lock(fsp->dev, fsp->inode, fsp->fnum,
				  lock_pid, sys_getpid(), conn->cnum,
				  offset, count,
				  lock_type);

		if (NT_STATUS_IS_OK(status) && lp_posix_locking(SNUM(conn))) {

			/*
			 * Try and get a POSIX lock on this range.
			 * Note that this is ok if it is a read lock
			 * overlapping on a different fd. JRA.
			 */

			if (!set_posix_lock(fsp, offset, count, lock_type)) {
				status = NT_STATUS_LOCK_NOT_GRANTED;
				/*
				 * We failed to map - we must now remove the brl
				 * lock entry.
				 */
				(void)brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
								lock_pid, sys_getpid(), conn->cnum,
								offset, count, False);
			}
		}
	}

	return status;
}
Beispiel #12
0
NTSTATUS do_lock(files_struct *fsp,
			uint16 lock_pid,
			SMB_BIG_UINT count,
			SMB_BIG_UINT offset,
			enum brl_type lock_type,
			enum brl_flavour lock_flav,
			BOOL *my_lock_ctx)
{
	struct byte_range_lock *br_lck = NULL;
	NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED;

	if (!OPEN_FSP(fsp) || !fsp->can_lock) {
		return NT_STATUS_INVALID_HANDLE;
	}

	if (!lp_locking(SNUM(fsp->conn))) {
		return NT_STATUS_OK;
	}

	/* NOTE! 0 byte long ranges ARE allowed and should be stored  */

	DEBUG(10,("do_lock: lock flavour %s lock type %s start=%.0f len=%.0f requested for fnum %d file %s\n",
		lock_flav_name(lock_flav), lock_type_name(lock_type),
		(double)offset, (double)count, fsp->fnum, fsp->fsp_name ));

	br_lck = brl_get_locks(fsp);
	if (!br_lck) {
		return NT_STATUS_NO_MEMORY;
	}

	status = brl_lock(br_lck,
			lock_pid,
			procid_self(),
			offset,
			count, 
			lock_type,
			lock_flav,
			my_lock_ctx);

	byte_range_lock_destructor(br_lck);
	return status;
}
Beispiel #13
0
NTSTATUS do_unlock(files_struct *fsp,
			uint16 lock_pid,
			SMB_BIG_UINT count,
			SMB_BIG_UINT offset,
			enum brl_flavour lock_flav)
{
	BOOL ok = False;
	struct byte_range_lock *br_lck = NULL;
	
	if (!lp_locking(SNUM(fsp->conn))) {
		return NT_STATUS_OK;
	}
	
	if (!OPEN_FSP(fsp) || !fsp->can_lock) {
		return NT_STATUS_INVALID_HANDLE;
	}
	
	DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n",
		  (double)offset, (double)count, fsp->fnum, fsp->fsp_name ));

	br_lck = brl_get_locks(fsp);
	if (!br_lck) {
		return NT_STATUS_NO_MEMORY;
	}

	ok = brl_unlock(br_lck,
			lock_pid,
			procid_self(),
			offset,
			count,
			lock_flav);
   
	byte_range_lock_destructor(br_lck);

	if (!ok) {
		DEBUG(10,("do_unlock: returning ERRlock.\n" ));
		return NT_STATUS_RANGE_NOT_LOCKED;
	}

	return NT_STATUS_OK;
}
Beispiel #14
0
void locking_close_file(files_struct *fsp)
{
	pid_t pid = sys_getpid();

	if (!lp_locking(SNUM(fsp->conn)))
		return;

	/*
	 * Just release all the brl locks, no need to release individually.
	 */

	brl_close(fsp->dev, fsp->inode, pid, fsp->conn->cnum, fsp->fnum);

	if(lp_posix_locking(SNUM(fsp->conn))) {

		/*
		 * Release all the POSIX locks.
		 */
		posix_locking_close_file(fsp);

	}
}
Beispiel #15
0
void locking_close_file(files_struct *fsp)
{
	struct byte_range_lock *br_lck;

	if (!lp_locking(fsp->conn->params)) {
		return;
	}

	/* If we have not outstanding locks or pending
	 * locks then we don't need to look in the lock db.
	 */

	if (fsp->current_lock_count == 0) {
		return;
	}

	br_lck = brl_get_locks(NULL,fsp);

	if (br_lck) {
		cancel_pending_lock_requests_by_fid(fsp, br_lck);
		brl_close_fnum(br_lck);
		TALLOC_FREE(br_lck);
	}
}
Beispiel #16
0
NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
		   SMB_BIG_UINT count,SMB_BIG_UINT offset)
{
	BOOL ok = False;

	if (!lp_locking(SNUM(conn)))
		return NT_STATUS_OK;

	if (!OPEN_FSP(fsp) || !fsp->can_lock || (fsp->conn != conn)) {
		return NT_STATUS_INVALID_HANDLE;
	}

	DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for file %s\n",
		  (double)offset, (double)count, fsp->fsp_name ));

	/*
	 * Remove the existing lock record from the tdb lockdb
	 * before looking at POSIX locks. If this record doesn't
	 * match then don't bother looking to remove POSIX locks.
	 */

	ok = brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
			lock_pid, sys_getpid(), conn->cnum, offset, count, False);

	if (!ok) {
		DEBUG(10,("do_unlock: returning ERRlock.\n" ));
		return NT_STATUS_RANGE_NOT_LOCKED;
	}

	if (!lp_posix_locking(SNUM(conn)))
		return NT_STATUS_OK;

	(void)release_posix_lock(fsp, offset, count);

	return NT_STATUS_OK;
}
Beispiel #17
0
BOOL is_locked(files_struct *fsp,connection_struct *conn,
	       SMB_BIG_UINT count,SMB_BIG_UINT offset,
	       enum brl_type lock_type, BOOL check_self)
{
	int snum = SNUM(conn);
	BOOL ret;

	if (count == 0)
		return(False);

	if (!lp_locking(snum) || !lp_strict_locking(snum))
		return(False);

	ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum,
			     global_smbpid, sys_getpid(), conn->cnum,
			     offset, count, lock_type, check_self);

	DEBUG(10,("is_locked: brl start=%.0f len=%.0f %s for file %s\n",
			(double)offset, (double)count, ret ? "locked" : "unlocked",
			fsp->fsp_name ));

	/*
	 * There is no lock held by an SMB daemon, check to
	 * see if there is a POSIX lock from a UNIX or NFS process.
	 */

	if(!ret && lp_posix_locking(snum)) {
		ret = is_posix_locked(fsp, offset, count, lock_type);

		DEBUG(10,("is_locked: posix start=%.0f len=%.0f %s for file %s\n",
				(double)offset, (double)count, ret ? "locked" : "unlocked",
				fsp->fsp_name ));
	}

	return ret;
}
Beispiel #18
0
void locking_close_file(files_struct *fsp)
{
	struct byte_range_lock *br_lck;
	struct process_id pid = procid_self();

	if (!lp_locking(SNUM(fsp->conn)))
		return;

	/*
	 * Just release all the brl locks, no need to release individually.
	 */

	br_lck = brl_get_locks(fsp);
	if (br_lck) {
		brl_close_fnum(br_lck, pid);
		byte_range_lock_destructor(br_lck);
	}

	if(lp_posix_locking(SNUM(fsp->conn))) {
	 	/* Release all the POSIX locks.*/
		posix_locking_close_file(fsp);

	}
}
Beispiel #19
0
struct byte_range_lock *do_lock(struct messaging_context *msg_ctx,
			files_struct *fsp,
			uint64_t smblctx,
			uint64_t count,
			uint64_t offset,
			enum brl_type lock_type,
			enum brl_flavour lock_flav,
			bool blocking_lock,
			NTSTATUS *perr,
			uint64_t *psmblctx,
			struct blocking_lock_record *blr)
{
	struct byte_range_lock *br_lck = NULL;

	/* silently return ok on print files as we don't do locking there */
	if (fsp->print_file) {
		*perr = NT_STATUS_OK;
		return NULL;
	}

	if (!fsp->can_lock) {
		*perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
		return NULL;
	}

	if (!lp_locking(fsp->conn->params)) {
		*perr = NT_STATUS_OK;
		return NULL;
	}

	/* NOTE! 0 byte long ranges ARE allowed and should be stored  */

	DEBUG(10,("do_lock: lock flavour %s lock type %s start=%.0f len=%.0f "
		"blocking_lock=%s requested for %s file %s\n",
		lock_flav_name(lock_flav), lock_type_name(lock_type),
		(double)offset, (double)count, blocking_lock ? "true" :
		"false", fsp_fnum_dbg(fsp), fsp_str_dbg(fsp)));

	br_lck = brl_get_locks(talloc_tos(), fsp);
	if (!br_lck) {
		*perr = NT_STATUS_NO_MEMORY;
		return NULL;
	}

	*perr = brl_lock(msg_ctx,
			br_lck,
			smblctx,
			messaging_server_id(fsp->conn->sconn->msg_ctx),
			offset,
			count,
			lock_type,
			lock_flav,
			blocking_lock,
			psmblctx,
			blr);

	DEBUG(10, ("do_lock: returning status=%s\n", nt_errstr(*perr)));

	increment_current_lock_count(fsp, lock_flav);
	return br_lck;
}
Beispiel #20
0
BOOL do_lock(uint16 smbpid,
		files_struct * fsp, struct vfs_connection_struct *conn,
	     SMB_BIG_UINT count, SMB_BIG_UINT offset, enum brl_type lock_type,
	     uint32 *err)
{
	BOOL ok = False;

	if (!lp_locking(conn->snum))
		return (True);

	if (count == 0)
	{
		*err = NT_STATUS_ACCESS_DENIED;
		return False;
	}

	DEBUG(10,
	      ("do_lock: lock type %s start=%.0f len=%.0f requested for file %s\n",
	       lock_type_name(lock_type), (double)offset, (double)count,
	       smbstrA(fsp->fsp_name)));

	if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn))
	{
		ok = brl_lock(fsp->sbuf.st_dev, fsp->sbuf.st_ino, fsp->fnum,
			      smbpid, sys_getpid(), conn->snum,
			      offset, count, lock_type);

		if (ok && lp_posix_locking(conn->snum))
		{

			/*
			 * Try and get a POSIX lock on this range.
			 * Note that this is ok if it is a read lock
			 * overlapping on a different fd. JRA.
			 */

			ok = set_posix_lock(fsp, offset, count, lock_type);

			if (!ok)
			{
				/*
				 * We failed to map - we must now remove the brl
				 * lock entry.
				 */
				
					(void)brl_unlock(fsp->sbuf.st_dev,
							 fsp->sbuf.st_ino,
							 fsp->fnum,
							 smbpid,
							 sys_getpid(),
							 conn->snum, offset,
							 count);
			}
		}
	}

	if (!ok)
	{
		*err = NT_STATUS_LOCK_NOT_GRANTED;
		return False;
	}
	return True;		/* Got lock */
}
Beispiel #21
0
bool strict_lock_default(files_struct *fsp, struct lock_struct *plock)
{
	int strict_locking = lp_strict_locking(fsp->conn->params);
	bool ret = False;

	if (plock->size == 0) {
		return True;
	}

	if (!lp_locking(fsp->conn->params) || !strict_locking) {
		return True;
	}

	if (strict_locking == Auto) {
		if  (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (plock->lock_type == READ_LOCK || plock->lock_type == WRITE_LOCK)) {
			DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp_str_dbg(fsp)));
			ret = True;
		} else if ((fsp->oplock_type == LEVEL_II_OPLOCK) &&
			   (plock->lock_type == READ_LOCK)) {
			DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp_str_dbg(fsp)));
			ret = True;
		} else {
			struct byte_range_lock *br_lck;

			br_lck = brl_get_locks_readonly(fsp);
			if (!br_lck) {
				return True;
			}
			ret = brl_locktest(br_lck,
					plock->context.smblctx,
					plock->context.pid,
					plock->start,
					plock->size,
					plock->lock_type,
					plock->lock_flav);
		}
	} else {
		struct byte_range_lock *br_lck;

		br_lck = brl_get_locks_readonly(fsp);
		if (!br_lck) {
			return True;
		}
		ret = brl_locktest(br_lck,
				plock->context.smblctx,
				plock->context.pid,
				plock->start,
				plock->size,
				plock->lock_type,
				plock->lock_flav);
	}

	DEBUG(10,("strict_lock_default: flavour = %s brl start=%.0f "
			"len=%.0f %s for fnum %llu file %s\n",
			lock_flav_name(plock->lock_flav),
			(double)plock->start, (double)plock->size,
			ret ? "unlocked" : "locked",
			(unsigned long long)plock->fnum, fsp_str_dbg(fsp)));

	return ret;
}
Beispiel #22
0
BOOL is_locked(files_struct *fsp,
		SMB_BIG_UINT count,
		SMB_BIG_UINT offset, 
		enum brl_type lock_type)
{
	int snum = SNUM(fsp->conn);
	int strict_locking = lp_strict_locking(snum);
	enum brl_flavour lock_flav = lp_posix_cifsu_locktype();
	BOOL ret = True;
	
	if (count == 0) {
		return False;
	}

	if (!lp_locking(snum) || !strict_locking) {
		return False;
	}

	if (strict_locking == Auto) {
		if  (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (lock_type == READ_LOCK || lock_type == WRITE_LOCK)) {
			DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp->fsp_name ));
			ret = False;
		} else if ((fsp->oplock_type == LEVEL_II_OPLOCK) &&
			   (lock_type == READ_LOCK)) {
			DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name ));
			ret = False;
		} else {
			struct byte_range_lock *br_lck = brl_get_locks(fsp);
			if (!br_lck) {
				return False;
			}
			ret = !brl_locktest(br_lck,
					global_smbpid,
					procid_self(),
					offset,
					count,
					lock_type,
					lock_flav);
			byte_range_lock_destructor(br_lck);
		}
	} else {
		struct byte_range_lock *br_lck = brl_get_locks(fsp);
		if (!br_lck) {
			return False;
		}
		ret = !brl_locktest(br_lck,
				global_smbpid,
				procid_self(),
				offset,
				count,
				lock_type,
				lock_flav);
		byte_range_lock_destructor(br_lck);
	}

	DEBUG(10,("is_locked: flavour = %s brl start=%.0f len=%.0f %s for fnum %d file %s\n",
			lock_flav_name(lock_flav),
			(double)offset, (double)count, ret ? "locked" : "unlocked",
			fsp->fnum, fsp->fsp_name ));

	return ret;
}
Beispiel #23
0
int fd_close_posix(struct files_struct *fsp)
{
	int saved_errno = 0;
	int ret;
	int *fd_array = NULL;
	size_t count, i;

	if (!lp_locking(fsp->conn->params) ||
	    !lp_posix_locking(fsp->conn->params))
	{
		/*
		 * No locking or POSIX to worry about or we want POSIX semantics
		 * which will lose all locks on all fd's open on this dev/inode,
		 * just close.
		 */
		return close(fsp->fh->fd);
	}

	if (get_windows_lock_ref_count(fsp)) {

		/*
		 * There are outstanding locks on this dev/inode pair on
		 * other fds. Add our fd to the pending close tdb and set
		 * fsp->fh->fd to -1.
		 */

		add_fd_to_close_entry(fsp);
		return 0;
	}

	/*
	 * No outstanding locks. Get the pending close fd's
	 * from the tdb and close them all.
	 */

	count = get_posix_pending_close_entries(talloc_tos(), fsp, &fd_array);

	if (count) {
		DEBUG(10,("fd_close_posix: doing close on %u fd's.\n",
			  (unsigned int)count));

		for(i = 0; i < count; i++) {
			if (close(fd_array[i]) == -1) {
				saved_errno = errno;
			}
		}

		/*
		 * Delete all fd's stored in the tdb
		 * for this dev/inode pair.
		 */

		delete_close_entries(fsp);
	}

	TALLOC_FREE(fd_array);

	/* Don't need a lock ref count on this dev/ino anymore. */
	delete_windows_lock_ref_count(fsp);

	/*
	 * Finally close the fd associated with this fsp.
	 */

	ret = close(fsp->fh->fd);

	if (ret == 0 && saved_errno != 0) {
		errno = saved_errno;
		ret = -1;
	}

	return ret;
}