diff options
Diffstat (limited to 'source/locking')
-rw-r--r-- | source/locking/locking.c | 74 |
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); |