svn commit: samba r16886 - in trunk/source: include lib locking smbd

jra at samba.org jra at samba.org
Sun Jul 9 01:59:35 GMT 2006


Author: jra
Date: 2006-07-09 01:59:34 +0000 (Sun, 09 Jul 2006)
New Revision: 16886

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

Log:
Add the mapping from CIFS posix locks to system
POSIX locks. That's the easy part... Next will
come adding the unlock !
Jeremy.

Modified:
   trunk/source/include/locking.h
   trunk/source/lib/dummysmbd.c
   trunk/source/locking/brlock.c
   trunk/source/locking/posix.c
   trunk/source/smbd/files.c


Changeset:
Modified: trunk/source/include/locking.h
===================================================================
--- trunk/source/include/locking.h	2006-07-09 00:52:21 UTC (rev 16885)
+++ trunk/source/include/locking.h	2006-07-09 01:59:34 UTC (rev 16886)
@@ -80,7 +80,7 @@
 	struct lock_context context;
 	br_off start;
 	br_off size;
-	int fnum;
+	uint16 fnum;
 	enum brl_type lock_type;
 	enum brl_flavour lock_flav;
 };

Modified: trunk/source/lib/dummysmbd.c
===================================================================
--- trunk/source/lib/dummysmbd.c	2006-07-09 00:52:21 UTC (rev 16885)
+++ trunk/source/lib/dummysmbd.c	2006-07-09 01:59:34 UTC (rev 16886)
@@ -38,3 +38,8 @@
 {
 	return False;
 }
+
+files_struct *file_fnum(uint16 fnum)
+{
+	return NULL;
+}

Modified: trunk/source/locking/brlock.c
===================================================================
--- trunk/source/locking/brlock.c	2006-07-09 00:52:21 UTC (rev 16885)
+++ trunk/source/locking/brlock.c	2006-07-09 01:59:34 UTC (rev 16886)
@@ -650,8 +650,8 @@
 				plock->size,
 				plock->lock_type,
 				&plock->context,
+				count,
 				tp,
-				count,
 				&errno_ret)) {
 			if (errno_ret == EACCES || errno_ret == EAGAIN) {
 				SAFE_FREE(tp);

Modified: trunk/source/locking/posix.c
===================================================================
--- trunk/source/locking/posix.c	2006-07-09 00:52:21 UTC (rev 16885)
+++ trunk/source/locking/posix.c	2006-07-09 01:59:34 UTC (rev 16886)
@@ -1177,13 +1177,13 @@
 	struct lock_context lock_ctx;
 	SMB_OFF_T offset;
 	SMB_OFF_T count;
+	int posix_lock_type = map_posix_lock_type(fsp,lock_type);
 	BOOL ret = True;
 	size_t entry_num = 0;
 	size_t lock_count;
 	TALLOC_CTX *l_ctx = NULL;
 	struct lock_list *llist = NULL;
 	struct lock_list *ll = NULL;
-	int posix_lock_type = map_posix_lock_type(fsp,lock_type);
 
 	ZERO_STRUCT(lock_ctx);
 
@@ -1438,6 +1438,14 @@
 /****************************************************************************
  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 split.
 ****************************************************************************/
 
 BOOL set_posix_lock_posix_flavour(files_struct *fsp,
@@ -1445,10 +1453,85 @@
 			SMB_BIG_UINT u_count,
 			enum brl_type lock_type,
 			const struct lock_context *plock_ctx,
-			const struct lock_struct *locks,
-			int count,
+			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
+	 * pretend it was successful.
+	 */
+
+	if(!posix_lock_in_range(&offset, &count, u_offset, u_count)) {
+		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;
 }
 

Modified: trunk/source/smbd/files.c
===================================================================
--- trunk/source/smbd/files.c	2006-07-09 00:52:21 UTC (rev 16885)
+++ trunk/source/smbd/files.c	2006-07-09 01:59:34 UTC (rev 16886)
@@ -462,24 +462,16 @@
 }
 
 /****************************************************************************
- Get a fsp from a packet given the offset of a 16 bit fnum.
+ Get an fsp from a 16 bit fnum.
 ****************************************************************************/
 
-files_struct *file_fsp(char *buf, int where)
+files_struct *file_fnum(uint16 fnum)
 {
-	int fnum, count=0;
 	files_struct *fsp;
+	int count=0;
 
-	if (chain_fsp)
-		return chain_fsp;
-
-	if (!buf)
-		return NULL;
-	fnum = SVAL(buf, where);
-
 	for (fsp=Files;fsp;fsp=fsp->next, count++) {
 		if (fsp->fnum == fnum) {
-			chain_fsp = fsp;
 			if (count > 10) {
 				DLIST_PROMOTE(Files, fsp);
 			}
@@ -490,6 +482,29 @@
 }
 
 /****************************************************************************
+ Get an fsp from a packet given the offset of a 16 bit fnum.
+****************************************************************************/
+
+files_struct *file_fsp(char *buf, int where)
+{
+	files_struct *fsp;
+
+	if (chain_fsp) {
+		return chain_fsp;
+	}
+
+	if (!buf) {
+		return NULL;
+	}
+
+	fsp = file_fnum(SVAL(buf, where));
+	if (fsp) {
+		chain_fsp = fsp;
+	}
+	return fsp;
+}
+
+/****************************************************************************
  Reset the chained fsp - done at the start of a packet reply.
 ****************************************************************************/
 



More information about the samba-cvs mailing list