diff options
| author | Jeremy Allison <jra@samba.org> | 2000-04-12 17:59:09 +0000 | 
|---|---|---|
| committer | Jeremy Allison <jra@samba.org> | 2000-04-12 17:59:09 +0000 | 
| commit | 8316237e9ca83d1bd0cecdc63d7e47b44cf13181 (patch) | |
| tree | daff31da47ad88886634d083c68d4da40b5095c1 /source3/locking | |
| parent | f5da7470c3f4d1fc86dee19e85d189595344bad2 (diff) | |
| download | samba-8316237e9ca83d1bd0cecdc63d7e47b44cf13181.tar.gz samba-8316237e9ca83d1bd0cecdc63d7e47b44cf13181.tar.bz2 samba-8316237e9ca83d1bd0cecdc63d7e47b44cf13181.zip  | |
Code to map tdb locks onto POSIX. Mainly placeholder code at the moment,
but the structure is done enough so that Andrew can look it over and give
a yea/nay decision.
Jeremy.
(This used to be commit db96f83e34a139f47776fcbb5c1624fbf9d9943b)
Diffstat (limited to 'source3/locking')
| -rw-r--r-- | source3/locking/locking.c | 166 | 
1 files changed, 157 insertions, 9 deletions
diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 1bb0a3b59c..72ca91566a 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -40,27 +40,134 @@ static TDB_CONTEXT *tdb;  int global_smbpid; -  /**************************************************************************** -remove any locks on this fd + Remove any locks on this fd.  ****************************************************************************/ +  void locking_close_file(files_struct *fsp)  { -	if (!lp_locking(SNUM(fsp->conn))) return; +	if (!lp_locking(SNUM(fsp->conn))) +		return; + +	if(lp_posix_locking(SNUM(fsp->conn))) { +		/* +		 * We need to release all POSIX locks we have on this +		 * fd. +		 */ +	} + +	/* +	 * Now release all the tdb locks. +	 */ + +	brl_close(fsp->dev, fsp->inode, getpid(), fsp->conn->cnum, fsp->fnum); + +	/* +	 * We now need to search our open file list for any other +	 * fd open on this file with outstanding POSIX locks. If we +	 * don't find one, great, just return. If we do find one then +	 * we have to add this file descriptor to the 'pending close' +	 * list of that fd, to stop the POSIX problem where the locks +	 * on *that* fd will get lost when we close this one. POSIX +	 * braindamage... JRA. +	 */ + +	/* Placeholder for code here.... */ +} + +/**************************************************************************** + Debugging aid :-). +****************************************************************************/ + +static const char *lock_type_name(enum brl_type lock_type) +{ +	return (lock_type == READ_LOCK) ? "READ" : "WRITE"; +} + +/**************************************************************************** + Check to see if the given unsigned lock range is within the possible POSIX + range. Modifies the given args to be in range if possible, just returns + False if not. +****************************************************************************/ -	brl_close(fsp->dev, fsp->inode,  -		  getpid(), fsp->conn->cnum, fsp->fnum); +static BOOL posix_lock_in_range(SMB_OFF_T *p_offset, SMB_OFF_T *p_count) +{ +	/* Placeholder. */ +	return True;  } +/**************************************************************************** + POSIX function to see if a file region is locked. Returns True if the + lock could be granted, False if not. +****************************************************************************/ + +static BOOL posix_locktest(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u_count, enum brl_type lock_type) +{ +	SMB_OFF_T offset = (SMB_OFF_T)u_offset; +	SMB_OFF_T count = (SMB_OFF_T)u_count; + +	DEBUG(10,("posix_locktest: File %s, offset = %.0f, count = %.0f, type = %s\n", +			fsp->fsp_name, (double)offset, (double)count, lock_type_name(lock_type) )); + +	if(!posix_lock_in_range(&offset, &count)) +		return True; + +	/* Placeholder - for now always return that the lock could be granted. */ +	return True; +} + +/**************************************************************************** + POSIX function to acquire a lock. Returns True if the + lock could be granted, False if not. +****************************************************************************/ + +static BOOL get_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u_count, enum brl_type lock_type) +{ +	SMB_OFF_T offset = (SMB_OFF_T)u_offset; +	SMB_OFF_T count = (SMB_OFF_T)u_count; + +	DEBUG(10,("get_posix_lock: File %s, offset = %.0f, count = %.0f, type = %s\n", +			fsp->fsp_name, (double)offset, (double)count, lock_type_name(lock_type) )); + +	if(!posix_lock_in_range(&offset, &count)) +		return True; + +	/* Placeholder - for now always return that the lock could be granted. */ +	fsp->num_posix_locks++; +	return True; +} + +/**************************************************************************** + POSIX function to release a lock. Returns True if the + lock could be granted, False if not. +****************************************************************************/ + +static BOOL release_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u_count) +{ +	SMB_OFF_T offset = (SMB_OFF_T)u_offset; +	SMB_OFF_T count = (SMB_OFF_T)u_count; + +	DEBUG(10,("release_posix_lock: File %s, offset = %.0f, count = %.0f\n", +			fsp->fsp_name, (double)offset, (double)count )); + +	if(!posix_lock_in_range(&offset, &count)) +		return True; + +	/* Placeholder - for now always return that the lock could be granted. */ +	fsp->num_posix_locks--; +	return True; +}  /****************************************************************************   Utility function called to see if a file region is locked.  ****************************************************************************/ +  BOOL is_locked(files_struct *fsp,connection_struct *conn,  	       SMB_BIG_UINT count,SMB_BIG_UINT offset,   	       enum brl_type lock_type)  {  	int snum = SNUM(conn); +	BOOL ret;  	if (count == 0)  		return(False); @@ -68,15 +175,28 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn,  	if (!lp_locking(snum) || !lp_strict_locking(snum))  		return(False); -	return !brl_locktest(fsp->dev, fsp->inode,  +	ret = !brl_locktest(fsp->dev, fsp->inode,   			     global_smbpid, getpid(), conn->cnum,   			     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. +	 * Note that as an optimisation we only bother to +	 * check this if the file is not exclusively +	 * oplocked. JRA. +	 */ + +	if(!ret && !EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && lp_posix_locking(snum)) +		ret = !posix_locktest(fsp, offset, count, lock_type); + +	return ret; +}  /****************************************************************************   Utility function called by locking requests.  ****************************************************************************/ +  BOOL do_lock(files_struct *fsp,connection_struct *conn,               SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type,               int *eclass,uint32 *ecode) @@ -92,14 +212,33 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn,  		return False;  	} -	DEBUG(10,("do_lock: lock type %d start=%.0f len=%.0f requested for file %s\n", -		  lock_type, (double)offset, (double)count, fsp->fsp_name )); +	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)) {  		ok = brl_lock(fsp->dev, fsp->inode, fsp->fnum,  			      global_smbpid, getpid(), conn->cnum,   			      offset, count,   			      lock_type); + +		if(ok && lp_posix_locking(SNUM(conn))) { + +			/* +			 * Try and get a POSIX lock on this range. +			 */ + +			ok = get_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->dev, fsp->inode, fsp->fnum, +								global_smbpid, getpid(), conn->cnum,  +								offset, count); +			} +		}  	}  	if (!ok) { @@ -130,6 +269,15 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn,  		ok = brl_unlock(fsp->dev, fsp->inode, fsp->fnum,  				global_smbpid, getpid(), conn->cnum,   				offset, count); + +		if(ok && lp_posix_locking(SNUM(conn))) { + +			/* +			 * Release the POSIX lock on this range. +			 */ + +			(void)release_posix_lock(fsp, offset, count); +		}  	}  	if (!ok) {  | 
