summaryrefslogtreecommitdiffstats
path: root/source/locking/locking.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/locking/locking.c')
-rw-r--r--source/locking/locking.c74
1 files changed, 47 insertions, 27 deletions
diff --git a/source/locking/locking.c b/source/locking/locking.c
index 189ac0bcfe7..d5d767d2cc3 100644
--- a/source/locking/locking.c
+++ b/source/locking/locking.c
@@ -39,11 +39,13 @@ extern files_struct Files[];
static struct share_ops *share_ops;
/****************************************************************************
- utility function called to see if a file region is locked
+ Utility function called to see if a file region is locked.
****************************************************************************/
-BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset)
+
+BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset, int lock_type)
{
int snum = SNUM(cnum);
+ files_struct *fsp = &Files[fnum];
if (count == 0)
return(False);
@@ -51,17 +53,22 @@ BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset)
if (!lp_locking(snum) || !lp_strict_locking(snum))
return(False);
- return(fcntl_lock(Files[fnum].fd_ptr->fd,F_GETLK,offset,count,
- (Files[fnum].can_write?F_WRLCK:F_RDLCK)));
+ if((lock_type == F_WRLCK) && !fsp->can_write)
+ lock_type = F_RDLCK;
+
+ return(fcntl_lock(fsp->fd_ptr->fd,F_GETLK,offset,count,lock_type));
}
/****************************************************************************
- utility function called by locking requests
+ Utility function called by locking requests.
****************************************************************************/
-BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode)
+
+BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int lock_type,
+ int *eclass,uint32 *ecode)
{
BOOL ok = False;
+ files_struct *fsp = &Files[fnum];
if (!lp_locking(SNUM(cnum)))
return(True);
@@ -72,9 +79,12 @@ BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ec
return False;
}
- if (Files[fnum].can_lock && OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum))
- ok = fcntl_lock(Files[fnum].fd_ptr->fd,F_SETLK,offset,count,
- (Files[fnum].can_write?F_WRLCK:F_RDLCK));
+ if (OPEN_FNUM(fnum) && fsp->can_lock && (fsp->cnum == cnum)) {
+ if(lock_type == F_WRLCK && !fsp->can_write)
+ lock_type = F_RDLCK;
+
+ ok = fcntl_lock(fsp->fd_ptr->fd,F_SETLK,offset,count,lock_type);
+ }
if (!ok) {
*eclass = ERRDOS;
@@ -86,17 +96,19 @@ BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ec
/****************************************************************************
- utility function called by unlocking requests
+ Utility function called by unlocking requests.
****************************************************************************/
+
BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode)
{
BOOL ok = False;
+ files_struct *fsp = &Files[fnum];
if (!lp_locking(SNUM(cnum)))
return(True);
- if (Files[fnum].can_lock && OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum))
- ok = fcntl_lock(Files[fnum].fd_ptr->fd,F_SETLK,offset,count,F_UNLCK);
+ if (OPEN_FNUM(fnum) && fsp->can_lock && (fsp->cnum == cnum))
+ ok = fcntl_lock(fsp->fd_ptr->fd,F_SETLK,offset,count,F_UNLCK);
if (!ok) {
*eclass = ERRDOS;
@@ -109,8 +121,9 @@ BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *
/****************************************************************************
- initialise the locking functions
+ Initialise the locking functions.
****************************************************************************/
+
BOOL locking_init(int read_only)
{
if (share_ops) return True;
@@ -133,8 +146,9 @@ BOOL locking_init(int read_only)
}
/*******************************************************************
- deinitialize the share_mode management
- ******************************************************************/
+ Deinitialize the share_mode management.
+******************************************************************/
+
BOOL locking_end(void)
{
if (share_ops)
@@ -144,24 +158,27 @@ BOOL locking_end(void)
/*******************************************************************
- lock a hash bucket entry
- ******************************************************************/
+ Lock a hash bucket entry.
+******************************************************************/
+
BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, int *ptok)
{
return share_ops->lock_entry(cnum, dev, inode, ptok);
}
/*******************************************************************
- unlock a hash bucket entry
- ******************************************************************/
+ Unlock a hash bucket entry.
+******************************************************************/
+
BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, int token)
{
return share_ops->unlock_entry(cnum, dev, inode, token);
}
/*******************************************************************
-get all share mode entries for a dev/inode pair.
+ Get all share mode entries for a dev/inode pair.
********************************************************************/
+
int get_share_modes(int cnum, int token, uint32 dev, uint32 inode,
share_mode_entry **shares)
{
@@ -169,42 +186,45 @@ int get_share_modes(int cnum, int token, uint32 dev, uint32 inode,
}
/*******************************************************************
-del the share mode of a file.
+ Del the share mode of a file.
********************************************************************/
+
void del_share_mode(int token, int fnum)
{
share_ops->del_entry(token, fnum);
}
/*******************************************************************
-set the share mode of a file. Return False on fail, True on success.
+ Set the share mode of a file. Return False on fail, True on success.
********************************************************************/
+
BOOL set_share_mode(int token, int fnum, uint16 port, uint16 op_type)
{
return share_ops->set_entry(token, fnum, port, op_type);
}
/*******************************************************************
-Remove an oplock port and mode entry from a share mode.
+ Remove an oplock port and mode entry from a share mode.
********************************************************************/
BOOL remove_share_oplock(int fnum, int token)
{
return share_ops->remove_oplock(fnum, token);
}
-
/*******************************************************************
-call the specified function on each entry under management by the
-share mode system
+ Call the specified function on each entry under management by the
+ share mode system.
********************************************************************/
+
int share_mode_forall(void (*fn)(share_mode_entry *, char *))
{
return share_ops->forall(fn);
}
/*******************************************************************
-dump the state of the system
+ Dump the state of the system.
********************************************************************/
+
void share_status(FILE *f)
{
share_ops->status(f);