svn commit: samba r14705 - in trunk/source: locking smbd

jra at samba.org jra at samba.org
Sat Mar 25 02:35:42 GMT 2006


Author: jra
Date: 2006-03-25 02:35:40 +0000 (Sat, 25 Mar 2006)
New Revision: 14705

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

Log:
Fill in the lock query part of the POSIX etensions.
Final two pieces to do are :
a). Deal with SETLKW (wait locks).
b). Deal with mapping the POSIX lock requests into
POSIX locks in the underlying filesystem, currently
this doesn't work correctly. Having said that, if
posix locking = no is set on a share and the lock
calls are non-blocking this code should now be able
to be tested by Steve !
Jeremy.

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


Changeset:
Modified: trunk/source/locking/brlock.c
===================================================================
--- trunk/source/locking/brlock.c	2006-03-25 01:50:00 UTC (rev 14704)
+++ trunk/source/locking/brlock.c	2006-03-25 02:35:40 UTC (rev 14705)
@@ -1080,7 +1080,7 @@
 	 */
 
 	if(lp_posix_locking(fsp->conn->cnum) && (lock_flav == WINDOWS_LOCK)) {
-		ret = is_posix_locked(fsp, start, size, lock_type, WINDOWS_LOCK);
+		ret = is_posix_locked(fsp, &start, &size, &lock_type, WINDOWS_LOCK);
 
 		DEBUG(10,("brl_locktest: posix start=%.0f len=%.0f %s for fnum %d file %s\n",
 			(double)start, (double)size, ret ? "locked" : "unlocked",
@@ -1092,6 +1092,69 @@
 }
 
 /****************************************************************************
+ Query for existing locks.
+****************************************************************************/
+
+NTSTATUS brl_lockquery(struct byte_range_lock *br_lck,
+		uint16 *psmbpid,
+		struct process_id pid,
+		br_off *pstart,
+		br_off *psize, 
+		enum brl_type *plock_type,
+		enum brl_flavour lock_flav)
+{
+	unsigned int i;
+	struct lock_struct lock;
+	struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data;
+	files_struct *fsp = br_lck->fsp;
+
+	lock.context.smbpid = *psmbpid;
+	lock.context.pid = pid;
+	lock.context.tid = br_lck->fsp->conn->cnum;
+	lock.start = *pstart;
+	lock.size = *psize;
+	lock.fnum = fsp->fnum;
+	lock.lock_type = *plock_type;
+	lock.lock_flav = lock_flav;
+
+	/* Make sure existing locks don't conflict */
+	for (i=0; i < br_lck->num_locks; i++) {
+		/*
+		 * Our own locks don't conflict.
+		 */
+		if (brl_conflict_other(&locks[i], &lock)) {
+			*psmbpid = locks[i].context.smbpid;
+        		*pstart = locks[i].start;
+		        *psize = locks[i].size;
+        		*plock_type = locks[i].lock_type = *plock_type;
+			return NT_STATUS_LOCK_NOT_GRANTED;
+		}
+	}
+
+	/*
+	 * 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(lp_posix_locking(fsp->conn->cnum)) {
+		BOOL ret = is_posix_locked(fsp, pstart, psize, plock_type, POSIX_LOCK);
+
+		DEBUG(10,("brl_lockquery: posix start=%.0f len=%.0f %s for fnum %d file %s\n",
+			(double)*pstart, (double)*psize, ret ? "locked" : "unlocked",
+			fsp->fnum, fsp->fsp_name ));
+
+		if (ret) {
+			/* Hmmm. No clue what to set smbpid to - use -1. */
+			*psmbpid = 0xFFFF;
+			return NT_STATUS_LOCK_NOT_GRANTED;
+		}
+        }
+
+	return NT_STATUS_OK;
+}
+
+
+/****************************************************************************
  Remove a particular pending lock.
 ****************************************************************************/
 

Modified: trunk/source/locking/locking.c
===================================================================
--- trunk/source/locking/locking.c	2006-03-25 01:50:00 UTC (rev 14704)
+++ trunk/source/locking/locking.c	2006-03-25 02:35:40 UTC (rev 14705)
@@ -137,6 +137,45 @@
 }
 
 /****************************************************************************
+ 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.
 ****************************************************************************/
 
@@ -151,6 +190,10 @@
 	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;
 	}
@@ -161,10 +204,6 @@
 		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) {
-		return status;
-	}
-
 	br_lck = brl_get_locks(NULL, fsp);
 	if (!br_lck) {
 		return NT_STATUS_NO_MEMORY;
@@ -242,29 +281,7 @@
 	return ret;
 }
 
-/* Struct passed to brl_unlock. */
-struct posix_unlock_data_struct {
-	files_struct *fsp;
-	SMB_BIG_UINT offset;
-	SMB_BIG_UINT count;
-};
-
-#if 0
 /****************************************************************************
- 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);
-	}
-}
-#endif
-
-/****************************************************************************
  Utility function called by unlocking requests.
 ****************************************************************************/
 
@@ -275,9 +292,6 @@
 			enum brl_flavour lock_flav)
 {
 	BOOL ok = False;
-#if 0
-	struct posix_unlock_data_struct posix_data;
-#endif
 	struct byte_range_lock *br_lck = NULL;
 	
 	if (!lp_locking(SNUM(fsp->conn))) {
@@ -291,12 +305,6 @@
 	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 ));
 
-#if 0
-	posix_data.fsp = fsp;
-	posix_data.offset = offset;
-	posix_data.count = count;
-#endif
-
 	br_lck = brl_get_locks(NULL, fsp);
 	if (!br_lck) {
 		return NT_STATUS_NO_MEMORY;

Modified: trunk/source/locking/posix.c
===================================================================
--- trunk/source/locking/posix.c	2006-03-25 01:50:00 UTC (rev 14704)
+++ trunk/source/locking/posix.c	2006-03-25 02:35:40 UTC (rev 14705)
@@ -737,24 +737,24 @@
 ****************************************************************************/
 
 BOOL is_posix_locked(files_struct *fsp,
-			SMB_BIG_UINT u_offset,
-			SMB_BIG_UINT u_count,
-			enum brl_type lock_type,
+			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;
 	}
 
@@ -762,7 +762,17 @@
 		return False;
 	}
 
-	return (posix_lock_type == F_UNLCK ? False : True);
+	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;
 }
 
 /*

Modified: trunk/source/smbd/trans2.c
===================================================================
--- trunk/source/smbd/trans2.c	2006-03-25 01:50:00 UTC (rev 14704)
+++ trunk/source/smbd/trans2.c	2006-03-25 02:35:40 UTC (rev 14705)
@@ -3546,28 +3546,36 @@
 			count = (SMB_BIG_UINT)IVAL(pdata,POSIX_LOCK_LEN_OFFSET);
 #endif /* HAVE_LONGLONG */
 
-#if 0
-			/* We need a vfs change to get data on already locked regions... */
-			status = do_lock(fsp,
-					lock_pid,
-					count,
-					offset,
-					lock_type,
-					POSIX_LOCK,
-					&my_lock_ctx);
-#endif
+			status = query_lock(fsp,
+					&lock_pid,
+					&count,
+					&offset,
+					&lock_type,
+					POSIX_LOCK);
 
 			if (ERROR_WAS_LOCK_DENIED(status)) {
 				/* Here we need to report who has it locked... */
 				data_size = POSIX_LOCK_DATA_SIZE;
-				/* FIXME - Coverity tmp fix. */
-				memset(pdata, '\0', POSIX_LOCK_DATA_SIZE);
+
+				SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, lock_type);
+				SSVAL(pdata, POSIX_LOCK_FLAGS_OFFSET, 0);
+				SIVAL(pdata, POSIX_LOCK_PID_OFFSET, lock_pid);
+#if defined(HAVE_LONGLONG)
+				SIVAL(pdata, POSIX_LOCK_START_OFFSET, (uint32)(offset & 0xFFFFFFFF));
+				SIVAL(pdata, POSIX_LOCK_START_OFFSET + 4, (uint32)((offset >> 32) & 0xFFFFFFFF));
+				SIVAL(pdata, POSIX_LOCK_LEN_OFFSET, (uint32)(count & 0xFFFFFFFF));
+				SIVAL(pdata, POSIX_LOCK_LEN_OFFSET + 4, (uint32)((count >> 32) & 0xFFFFFFFF));
+#else /* HAVE_LONGLONG */
+				SIVAL(pdata, POSIX_LOCK_START_OFFSET, offset);
+				SIVAL(pdata, POSIX_LOCK_LEN_OFFSET, count);
+#endif /* HAVE_LONGLONG */
+
 			} else if (NT_STATUS_IS_OK(status)) {
 				/* For success we just return a copy of what we sent
 				   with the lock type set to POSIX_LOCK_TYPE_UNLOCK. */
 				data_size = POSIX_LOCK_DATA_SIZE;
 				memcpy(pdata, lock_data, POSIX_LOCK_DATA_SIZE);
-				SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET,POSIX_LOCK_TYPE_UNLOCK);
+				SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK);
 			} else {
 				return ERROR_NT(status);
 			}



More information about the samba-cvs mailing list