svn commit: samba r16888 - in trunk/source/locking: .

jra at samba.org jra at samba.org
Sun Jul 9 04:24:50 GMT 2006


Author: jra
Date: 2006-07-09 04:24:49 +0000 (Sun, 09 Jul 2006)
New Revision: 16888

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=16888

Log:
Fix the calculation if an overlap occurred in the upper
layer when doing unlocks. Simplified the close handling
in the POSIX lock case (we know the system already does
the right thing). Get ready to add the unlock semantics
for POSIX (hard hard hard !).
Jeremy.

Modified:
   trunk/source/locking/brlock.c
   trunk/source/locking/posix.c


Changeset:
Modified: trunk/source/locking/brlock.c
===================================================================
--- trunk/source/locking/brlock.c	2006-07-09 02:38:21 UTC (rev 16887)
+++ trunk/source/locking/brlock.c	2006-07-09 04:24:49 UTC (rev 16888)
@@ -639,19 +639,14 @@
 	if ((plock->lock_type != PENDING_LOCK) && lp_posix_locking(SNUM(br_lck->fsp->conn))) {
 		int errno_ret;
 
-		/* We pass in the entire new lock array to
-		   allow the lower layer to pick out the POSIX
-		   locks with the same PID. This allows the system
-		   layer to avoid walking the lock list doing the same
-		   split/merge game we've just done. */
+		/* The lower layer just needs to attempt to
+		   get the system POSIX lock. We've weeded out
+		   any conflicts above. */
 
 		if (!set_posix_lock_posix_flavour(br_lck->fsp,
 				plock->start,
 				plock->size,
 				plock->lock_type,
-				&plock->context,
-				count,
-				tp,
 				&errno_ret)) {
 			if (errno_ret == EACCES || errno_ret == EAGAIN) {
 				SAFE_FREE(tp);
@@ -901,13 +896,18 @@
 				SMB_ASSERT(tmp_lock[0].lock_type == locks[i].lock_type);
 				SMB_ASSERT(tmp_lock[1].lock_type == UNLOCK_LOCK);
 				memcpy(&tp[count], &tmp_lock[0], sizeof(struct lock_struct));
+				if (tmp_lock[0].size != locks[i].size) {
+					overlap_found = True;
+				}
 			} else {
 				SMB_ASSERT(tmp_lock[0].lock_type == UNLOCK_LOCK);
 				SMB_ASSERT(tmp_lock[1].lock_type == locks[i].lock_type);
 				memcpy(&tp[count], &tmp_lock[1], sizeof(struct lock_struct));
+				if (tmp_lock[1].start != locks[i].start) {
+					overlap_found = True;
+				}
 			}
 			count++;
-			overlap_found = True;
 			continue;
 		} else {
 			/* tmp_count == 3 - (we split a lock range in two). */
@@ -942,7 +942,12 @@
 #if 0
 	/* Unlock any POSIX regions. */
 	if(lp_posix_locking(br_lck->fsp->conn->cnum)) {
-		release_posix_lock_posix_flavour(br_lck->fsp, plock->start, plock->size, &plock->context);
+		release_posix_lock_posix_flavour(br_lck->fsp,
+						plock->start,
+						plock->size,
+						&plock->context,
+						tp,
+						count);
 	}
 #endif
 

Modified: trunk/source/locking/posix.c
===================================================================
--- trunk/source/locking/posix.c	2006-07-09 02:38:21 UTC (rev 16887)
+++ trunk/source/locking/posix.c	2006-07-09 04:24:49 UTC (rev 16888)
@@ -578,9 +578,11 @@
 	int *fd_array = NULL;
 	BOOL locks_on_other_fds = False;
 
-	if (!lp_posix_locking(SNUM(conn))) {
+	if (!lp_posix_locking(SNUM(conn)) || lp_posix_cifsu_locktype()) {
 		/*
-		 * No POSIX to worry about, just close.
+		 * No 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.
 		 */
 		ret = SMB_VFS_CLOSE(fsp,fsp->fh->fd);
 		fsp->fh->fd = -1;
@@ -676,6 +678,16 @@
 	struct posix_lock *entries = NULL;
 	size_t count, i;
 
+	if (lp_posix_cifsu_locktype()) {
+		/* If we have CIFS POSIX locking semantics enabled
+		   we want to lose all locks on first close and we
+		   know there are no stored POSIX lock entries, just
+		   return. */
+		DEBUG(10,("posix_locking_close_file: unix semantics - ignoring locks.\n"));
+		return;
+		   
+	}
+
 	/*
 	 * Optimization for the common case where we are the only
 	 * opener of a file. If all fd entries are our own, we don't
@@ -1438,32 +1450,21 @@
 /****************************************************************************
  POSIX function to acquire a lock. Returns True if the
  lock could be granted, False if not.
- This function takes a complete lock state on this dev/ino pair from the
- upper (CIFS) lock layer and makes a copy of all the locks that are owned by
- this process. We can then apply the requested lock as given as a system
- POSIX lock. We know it doesn't conflict with any existing lock owned
- by this process as the upper layer would have caught that. We don't need
- to "stack" the locks or do any split/merge calculations like the Windows
- flavour of this function does as the upper layer has already done any
- lock manipulation neccessary and POSIX locks overwrite, not stack.
+ As POSIX locks don't stack or conflict (they just overwrite)
+ we can map the requested lock directly onto a system one. We
+ know it doesn't conflict with locks on other contexts as the
+ upper layer would have refused it.
 ****************************************************************************/
 
 BOOL set_posix_lock_posix_flavour(files_struct *fsp,
 			SMB_BIG_UINT u_offset,
 			SMB_BIG_UINT u_count,
 			enum brl_type lock_type,
-			const struct lock_context *plock_ctx,
-			int num_locks,
-			const struct lock_struct *plocks,
 			int *errno_ret)
 {
 	SMB_OFF_T offset;
 	SMB_OFF_T count;
 	int posix_lock_type = map_posix_lock_type(fsp,lock_type);
-	TDB_DATA kbuf = locking_key_fsp(fsp);
-	TDB_DATA dbuf;
-	struct posix_lock *posix_locks;
-	int i, num_posix_locks;
 
 	/*
 	 * If the requested lock won't fit in the POSIX range, we will
@@ -1474,76 +1475,29 @@
 		return True;
 	}
 
-	posix_locks = SMB_MALLOC_ARRAY(struct posix_lock, count);
-	if (!posix_locks) {
-		DEBUG(0,("set_posix_lock_posix_flavour: malloc fail !\n"));
-		return False;
-	}
-
-	dbuf.dptr = (char *)posix_locks;
-
 	if (!posix_fcntl_lock(fsp,SMB_F_SETLK,offset,count,posix_lock_type)) {
 		*errno_ret = errno;
 		DEBUG(5,("set_posix_lock_posix_flavour: Lock fail !: Type = %s: offset = %.0f, count = %.0f. Errno = %s\n",
 			posix_lock_type_name(posix_lock_type), (double)offset, (double)count, strerror(errno) ));
-		SAFE_FREE(dbuf.dptr);
 		return False;
 	}
-
-	/* Copy all the locks held by this process into the memory tdb. */
-	num_posix_locks = 0;
-	for( i = 0; i < num_locks; i++) {
-		files_struct *fsp_i;
-		struct posix_lock *pl = &posix_locks[num_posix_locks];
-		const struct lock_struct *lock = &plocks[i];
-
-		if (!procid_equal(&lock->context.pid, &plock_ctx->pid)) {
-			/* Not one of ours... */
-			continue;
-		}
-
-		SMB_ASSERT(lock->lock_flav == POSIX_LOCK);
-
-		fsp_i = file_fnum(lock->fnum);
-		if (!fsp_i) {
-			/* This *MUST* be known to us.... */
-			smb_panic("set_posix_lock_posix_flavour: logic error.\n");
-		}
-
-		SMB_ASSERT(fsp_i->fh->fd != -1);
-
-		pl->fd = fsp_i->fh->fd;
-		pl->start = lock->start;
-		pl->size = lock->size;
-		pl->lock_type = lock->lock_type;
-		pl->lock_flav = POSIX_LOCK;
-		pl->lock_ctx = lock->context;
-
-		num_posix_locks++;
-	}
-
-	/* There must be at least one - the lock we added ! */
-	SMB_ASSERT(num_posix_locks > 0);
-
-	dbuf.dsize = sizeof(struct posix_lock) * num_posix_locks;
-
-	if (tdb_store(posix_lock_tdb, kbuf, dbuf, TDB_REPLACE) == -1) {
-		DEBUG(0,("set_posix_lock_posix_flavour: Failed to add lock entry on file %s\n", fsp->fsp_name));
-		SAFE_FREE(dbuf.dptr);
-	}
-
 	return True;
 }
 
 /****************************************************************************
  POSIX function to release a lock. Returns True if the
  lock could be released, False if not.
+ We are given a complete lock state from the upper layer, so what
+ we do is punch out holes in the unlock range where locks owned by this process
+ have a different lock context.
 ****************************************************************************/
 
 BOOL release_posix_lock_posix_flavour(files_struct *fsp,
 				SMB_BIG_UINT u_offset,
 				SMB_BIG_UINT u_count,
-				const struct lock_context *plock_ctx)
+				const struct lock_context *plock_ctx,
+				const struct lock_struct *plocks,
+				int num_locks)
 {
 	return True;
 }



More information about the samba-cvs mailing list