mirror of
https://github.com/samba-team/samba.git
synced 2025-08-04 08:22:08 +03:00
r15018: Merge Volker's ipc/trans2/nttrans changes over
into 3.0. Also merge the new POSIX lock code - this
is not enabled unless -DDEVELOPER is defined.
This doesn't yet map onto underlying system POSIX
locks. Updates vfs to allow lock queries.
Jeremy.
(This used to be commit 08e52ead03
)
This commit is contained in:
committed by
Gerald (Jerry) Carter
parent
0f985dcb19
commit
22dbd67708
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,7 @@
|
||||
Unix SMB/CIFS implementation.
|
||||
Locking functions
|
||||
Copyright (C) Andrew Tridgell 1992-2000
|
||||
Copyright (C) Jeremy Allison 1992-2000
|
||||
Copyright (C) Jeremy Allison 1992-2006
|
||||
Copyright (C) Volker Lendecke 2005
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
@ -33,6 +33,7 @@
|
||||
rewrtten completely to use new tdb code. Tridge, Dec '99
|
||||
|
||||
Added POSIX locking support. Jeremy Allison (jeremy@valinux.com), Apr. 2000.
|
||||
Added Unix Extensions POSIX locking support. Jeremy Allison Mar 2006.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
@ -45,120 +46,179 @@ uint16 global_smbpid;
|
||||
static TDB_CONTEXT *tdb;
|
||||
|
||||
/****************************************************************************
|
||||
Debugging aid :-).
|
||||
Debugging aids :-).
|
||||
****************************************************************************/
|
||||
|
||||
static const char *lock_type_name(enum brl_type lock_type)
|
||||
const char *lock_type_name(enum brl_type lock_type)
|
||||
{
|
||||
return (lock_type == READ_LOCK) ? "READ" : "WRITE";
|
||||
switch (lock_type) {
|
||||
case READ_LOCK:
|
||||
return "READ";
|
||||
case WRITE_LOCK:
|
||||
return "WRITE";
|
||||
case PENDING_LOCK:
|
||||
return "PENDING";
|
||||
default:
|
||||
return "other";
|
||||
}
|
||||
}
|
||||
|
||||
const char *lock_flav_name(enum brl_flavour lock_flav)
|
||||
{
|
||||
return (lock_flav == WINDOWS_LOCK) ? "WINDOWS_LOCK" : "POSIX_LOCK";
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Utility function called to see if a file region is locked.
|
||||
Called in the read/write codepath.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL is_locked(files_struct *fsp,connection_struct *conn,
|
||||
SMB_BIG_UINT count,SMB_BIG_UINT offset,
|
||||
enum brl_type lock_type)
|
||||
BOOL is_locked(files_struct *fsp,
|
||||
SMB_BIG_UINT count,
|
||||
SMB_BIG_UINT offset,
|
||||
enum brl_type lock_type)
|
||||
{
|
||||
int snum = SNUM(conn);
|
||||
int snum = SNUM(fsp->conn);
|
||||
int strict_locking = lp_strict_locking(snum);
|
||||
BOOL ret;
|
||||
enum brl_flavour lock_flav = lp_posix_cifsu_locktype();
|
||||
BOOL ret = True;
|
||||
|
||||
if (count == 0)
|
||||
return(False);
|
||||
if (count == 0) {
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!lp_locking(snum) || !strict_locking)
|
||||
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 = 0;
|
||||
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 = 0;
|
||||
ret = False;
|
||||
} else {
|
||||
ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum,
|
||||
global_smbpid, procid_self(), conn->cnum,
|
||||
offset, count, lock_type);
|
||||
struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp);
|
||||
if (!br_lck) {
|
||||
return False;
|
||||
}
|
||||
ret = !brl_locktest(br_lck,
|
||||
global_smbpid,
|
||||
procid_self(),
|
||||
offset,
|
||||
count,
|
||||
lock_type,
|
||||
lock_flav);
|
||||
TALLOC_FREE(br_lck);
|
||||
}
|
||||
} else {
|
||||
ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum,
|
||||
global_smbpid, procid_self(), conn->cnum,
|
||||
offset, count, lock_type);
|
||||
struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp);
|
||||
if (!br_lck) {
|
||||
return False;
|
||||
}
|
||||
ret = !brl_locktest(br_lck,
|
||||
global_smbpid,
|
||||
procid_self(),
|
||||
offset,
|
||||
count,
|
||||
lock_type,
|
||||
lock_flav);
|
||||
TALLOC_FREE(br_lck);
|
||||
}
|
||||
|
||||
DEBUG(10,("is_locked: brl start=%.0f len=%.0f %s for file %s\n",
|
||||
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->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 ));
|
||||
}
|
||||
fsp->fnum, fsp->fsp_name ));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Find out if a lock could be granted - return who is blocking us if we can't.
|
||||
****************************************************************************/
|
||||
|
||||
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(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;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Utility function called by locking requests.
|
||||
****************************************************************************/
|
||||
|
||||
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, BOOL *my_lock_ctx)
|
||||
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 (!lp_locking(SNUM(conn)))
|
||||
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 type %s start=%.0f len=%.0f requested for file %s\n",
|
||||
lock_type_name(lock_type), (double)offset, (double)count, fsp->fsp_name ));
|
||||
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 ));
|
||||
|
||||
if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) {
|
||||
status = brl_lock(fsp->dev, fsp->inode, fsp->fnum,
|
||||
lock_pid, procid_self(), conn->cnum,
|
||||
offset, count,
|
||||
lock_type, my_lock_ctx);
|
||||
|
||||
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)) {
|
||||
if (errno == EACCES || errno == EAGAIN)
|
||||
status = NT_STATUS_FILE_LOCK_CONFLICT;
|
||||
else
|
||||
status = map_nt_error_from_unix(errno);
|
||||
|
||||
/*
|
||||
* We failed to map - we must now remove the brl
|
||||
* lock entry.
|
||||
*/
|
||||
(void)brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
|
||||
lock_pid, procid_self(), conn->cnum,
|
||||
offset, count, False,
|
||||
NULL, NULL);
|
||||
}
|
||||
}
|
||||
br_lck = brl_get_locks(NULL, 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);
|
||||
|
||||
TALLOC_FREE(br_lck);
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -169,20 +229,33 @@ static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_p
|
||||
it, we need this. JRA.
|
||||
****************************************************************************/
|
||||
|
||||
NTSTATUS do_lock_spin(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
|
||||
SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type, BOOL *my_lock_ctx)
|
||||
NTSTATUS do_lock_spin(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)
|
||||
{
|
||||
int j, maxj = lp_lock_spin_count();
|
||||
int sleeptime = lp_lock_sleep_time();
|
||||
NTSTATUS status, ret;
|
||||
|
||||
if (maxj <= 0)
|
||||
if (maxj <= 0) {
|
||||
maxj = 1;
|
||||
}
|
||||
|
||||
ret = NT_STATUS_OK; /* to keep dumb compilers happy */
|
||||
|
||||
for (j = 0; j < maxj; j++) {
|
||||
status = do_lock(fsp, conn, lock_pid, count, offset, lock_type, my_lock_ctx);
|
||||
status = do_lock(fsp,
|
||||
lock_pid,
|
||||
count,
|
||||
offset,
|
||||
lock_type,
|
||||
lock_flav,
|
||||
my_lock_ctx);
|
||||
|
||||
if (!NT_STATUS_EQUAL(status, NT_STATUS_LOCK_NOT_GRANTED) &&
|
||||
!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
|
||||
return status;
|
||||
@ -191,72 +264,66 @@ NTSTATUS do_lock_spin(files_struct *fsp,connection_struct *conn, uint16 lock_pid
|
||||
if (j == 0) {
|
||||
ret = status;
|
||||
/* Don't spin if we blocked ourselves. */
|
||||
if (*my_lock_ctx)
|
||||
if (*my_lock_ctx) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Only spin for Windows locks. */
|
||||
if (lock_flav == POSIX_LOCK) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (sleeptime)
|
||||
|
||||
if (sleeptime) {
|
||||
sys_usleep(sleeptime);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Struct passed to brl_unlock. */
|
||||
struct posix_unlock_data_struct {
|
||||
files_struct *fsp;
|
||||
SMB_BIG_UINT offset;
|
||||
SMB_BIG_UINT count;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
Function passed to brl_unlock to allow POSIX unlock to be done first.
|
||||
****************************************************************************/
|
||||
|
||||
static void posix_unlock(void *pre_data)
|
||||
{
|
||||
struct posix_unlock_data_struct *pdata = (struct posix_unlock_data_struct *)pre_data;
|
||||
|
||||
if (lp_posix_locking(SNUM(pdata->fsp->conn)))
|
||||
release_posix_lock(pdata->fsp, pdata->offset, pdata->count);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Utility function called by unlocking requests.
|
||||
****************************************************************************/
|
||||
|
||||
NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
|
||||
SMB_BIG_UINT count,SMB_BIG_UINT offset)
|
||||
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 posix_unlock_data_struct posix_data;
|
||||
struct byte_range_lock *br_lck = NULL;
|
||||
|
||||
if (!lp_locking(SNUM(conn)))
|
||||
if (!lp_locking(SNUM(fsp->conn))) {
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
if (!OPEN_FSP(fsp) || !fsp->can_lock || (fsp->conn != conn)) {
|
||||
if (!OPEN_FSP(fsp) || !fsp->can_lock) {
|
||||
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 ));
|
||||
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 ));
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
br_lck = brl_get_locks(NULL, fsp);
|
||||
if (!br_lck) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
posix_data.fsp = fsp;
|
||||
posix_data.offset = offset;
|
||||
posix_data.count = count;
|
||||
|
||||
ok = brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
|
||||
lock_pid, procid_self(), conn->cnum, offset, count,
|
||||
False, posix_unlock, (void *)&posix_data);
|
||||
ok = brl_unlock(br_lck,
|
||||
lock_pid,
|
||||
procid_self(),
|
||||
offset,
|
||||
count,
|
||||
lock_flav);
|
||||
|
||||
TALLOC_FREE(br_lck);
|
||||
|
||||
if (!ok) {
|
||||
DEBUG(10,("do_unlock: returning ERRlock.\n" ));
|
||||
return NT_STATUS_RANGE_NOT_LOCKED;
|
||||
}
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
@ -266,6 +333,7 @@ NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
|
||||
|
||||
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)))
|
||||
@ -275,13 +343,14 @@ void locking_close_file(files_struct *fsp)
|
||||
* Just release all the brl locks, no need to release individually.
|
||||
*/
|
||||
|
||||
brl_close(fsp->dev, fsp->inode, pid, fsp->conn->cnum, fsp->fnum);
|
||||
br_lck = brl_get_locks(NULL,fsp);
|
||||
if (br_lck) {
|
||||
brl_close_fnum(br_lck, pid);
|
||||
TALLOC_FREE(br_lck);
|
||||
}
|
||||
|
||||
if(lp_posix_locking(SNUM(fsp->conn))) {
|
||||
|
||||
/*
|
||||
* Release all the POSIX locks.
|
||||
*/
|
||||
/* Release all the POSIX locks.*/
|
||||
posix_locking_close_file(fsp);
|
||||
|
||||
}
|
||||
|
@ -644,8 +644,7 @@ static BOOL posix_lock_in_range(SMB_OFF_T *offset_out, SMB_OFF_T *count_out,
|
||||
|
||||
/****************************************************************************
|
||||
Actual function that does POSIX locks. Copes with 64 -> 32 bit cruft and
|
||||
broken NFS implementations. Returns True if we got the lock or the region
|
||||
is unlocked in the F_GETLK case, False otherwise.
|
||||
broken NFS implementations.
|
||||
****************************************************************************/
|
||||
|
||||
static BOOL posix_fcntl_lock(files_struct *fsp, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
|
||||
@ -654,9 +653,6 @@ static BOOL posix_fcntl_lock(files_struct *fsp, int op, SMB_OFF_T offset, SMB_OF
|
||||
|
||||
DEBUG(8,("posix_fcntl_lock %d %d %.0f %.0f %d\n",fsp->fh->fd,op,(double)offset,(double)count,type));
|
||||
|
||||
/* In the F_GETLK case this returns True if the region
|
||||
was locked, False if unlocked. */
|
||||
|
||||
ret = SMB_VFS_LOCK(fsp,fsp->fh->fd,op,offset,count,type);
|
||||
|
||||
if (!ret && ((errno == EFBIG) || (errno == ENOLCK) || (errno == EINVAL))) {
|
||||
@ -686,39 +682,97 @@ static BOOL posix_fcntl_lock(files_struct *fsp, int op, SMB_OFF_T offset, SMB_OF
|
||||
}
|
||||
|
||||
DEBUG(8,("posix_fcntl_lock: Lock call %s\n", ret ? "successful" : "failed"));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Actual function that gets POSIX locks. Copes with 64 -> 32 bit cruft and
|
||||
broken NFS implementations.
|
||||
****************************************************************************/
|
||||
|
||||
static BOOL posix_fcntl_getlock(files_struct *fsp, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype)
|
||||
{
|
||||
pid_t pid;
|
||||
BOOL ret;
|
||||
|
||||
DEBUG(8,("posix_fcntl_getlock %d %.0f %.0f %d\n",
|
||||
fsp->fh->fd,(double)*poffset,(double)*pcount,*ptype));
|
||||
|
||||
ret = SMB_VFS_GETLOCK(fsp,fsp->fh->fd,poffset,pcount,ptype,&pid);
|
||||
|
||||
if (!ret && ((errno == EFBIG) || (errno == ENOLCK) || (errno == EINVAL))) {
|
||||
|
||||
DEBUG(0,("posix_fcntl_getlock: WARNING: lock request at offset %.0f, length %.0f returned\n",
|
||||
(double)*poffset,(double)*pcount));
|
||||
DEBUG(0,("an %s error. This can happen when using 64 bit lock offsets\n", strerror(errno)));
|
||||
DEBUG(0,("on 32 bit NFS mounted file systems.\n"));
|
||||
|
||||
/*
|
||||
* If the offset is > 0x7FFFFFFF then this will cause problems on
|
||||
* 32 bit NFS mounted filesystems. Just ignore it.
|
||||
*/
|
||||
|
||||
if (*poffset & ~((SMB_OFF_T)0x7fffffff)) {
|
||||
DEBUG(0,("Offset greater than 31 bits. Returning success.\n"));
|
||||
return True;
|
||||
}
|
||||
|
||||
if (*pcount & ~((SMB_OFF_T)0x7fffffff)) {
|
||||
/* 32 bit NFS file system, retry with smaller offset */
|
||||
DEBUG(0,("Count greater than 31 bits - retrying with 31 bit truncated length.\n"));
|
||||
errno = 0;
|
||||
*pcount &= 0x7fffffff;
|
||||
ret = SMB_VFS_GETLOCK(fsp,fsp->fh->fd,poffset,pcount,ptype,&pid);
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG(8,("posix_fcntl_getlock: Lock query call %s\n", ret ? "successful" : "failed"));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
POSIX function to see if a file region is locked. Returns True if the
|
||||
region is locked, False otherwise.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL is_posix_locked(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u_count, enum brl_type lock_type)
|
||||
BOOL is_posix_locked(files_struct *fsp,
|
||||
SMB_BIG_UINT *pu_offset,
|
||||
SMB_BIG_UINT *pu_count,
|
||||
enum brl_type *plock_type,
|
||||
enum brl_flavour lock_flav)
|
||||
{
|
||||
SMB_OFF_T offset;
|
||||
SMB_OFF_T count;
|
||||
int posix_lock_type = map_posix_lock_type(fsp,lock_type);
|
||||
int posix_lock_type = map_posix_lock_type(fsp,*plock_type);
|
||||
|
||||
DEBUG(10,("is_posix_locked: File %s, offset = %.0f, count = %.0f, type = %s\n",
|
||||
fsp->fsp_name, (double)u_offset, (double)u_count, posix_lock_type_name(lock_type) ));
|
||||
fsp->fsp_name, (double)*pu_offset, (double)*pu_count, posix_lock_type_name(*plock_type) ));
|
||||
|
||||
/*
|
||||
* If the requested lock won't fit in the POSIX range, we will
|
||||
* never set it, so presume it is not locked.
|
||||
*/
|
||||
|
||||
if(!posix_lock_in_range(&offset, &count, u_offset, u_count))
|
||||
if(!posix_lock_in_range(&offset, &count, *pu_offset, *pu_count)) {
|
||||
return False;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that most UNIX's can *test* for a write lock on
|
||||
* a read-only fd, just not *set* a write lock on a read-only
|
||||
* fd. So we don't need to use map_lock_type here.
|
||||
*/
|
||||
if (!posix_fcntl_getlock(fsp,&offset,&count,&posix_lock_type)) {
|
||||
return False;
|
||||
}
|
||||
|
||||
return posix_fcntl_lock(fsp,SMB_F_GETLK,offset,count,posix_lock_type);
|
||||
if (posix_lock_type == F_UNLCK) {
|
||||
return False;
|
||||
}
|
||||
|
||||
if (lock_flav == POSIX_LOCK) {
|
||||
/* Only POSIX lock queries need to know the details. */
|
||||
*pu_offset = (SMB_BIG_UINT)offset;
|
||||
*pu_count = (SMB_BIG_UINT)count;
|
||||
*plock_type = (posix_lock_type == F_RDLCK) ? READ_LOCK : WRITE_LOCK;
|
||||
}
|
||||
return True;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -958,9 +1012,14 @@ lock: start = %.0f, size = %.0f\n", (double)l_curr->start, (double)l_curr->size,
|
||||
/****************************************************************************
|
||||
POSIX function to acquire a lock. Returns True if the
|
||||
lock could be granted, False if not.
|
||||
TODO -- Fix POSIX lock flavour semantics.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL set_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u_count, enum brl_type lock_type)
|
||||
BOOL set_posix_lock(files_struct *fsp,
|
||||
SMB_BIG_UINT u_offset,
|
||||
SMB_BIG_UINT u_count,
|
||||
enum brl_type lock_type,
|
||||
enum brl_flavour lock_flav)
|
||||
{
|
||||
SMB_OFF_T offset;
|
||||
SMB_OFF_T count;
|
||||
|
Reference in New Issue
Block a user