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

jra at samba.org jra at samba.org
Sat Mar 25 01:50:01 GMT 2006


Author: jra
Date: 2006-03-25 01:50:00 +0000 (Sat, 25 Mar 2006)
New Revision: 14704

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

Log:
Fix lock queries with the new VFS semantics.
Jeremy.

Modified:
   trunk/source/locking/posix.c


Changeset:
Modified: trunk/source/locking/posix.c
===================================================================
--- trunk/source/locking/posix.c	2006-03-25 01:35:43 UTC (rev 14703)
+++ trunk/source/locking/posix.c	2006-03-25 01:50:00 UTC (rev 14704)
@@ -649,16 +649,11 @@
 
 static BOOL posix_fcntl_lock(files_struct *fsp, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
 {
-	int ret;
+	BOOL ret;
 
 	DEBUG(8,("posix_fcntl_lock %d %d %.0f %.0f %d\n",fsp->fh->fd,op,(double)offset,(double)count,type));
 
-	if (op != SMB_F_GETLK) {
-		ret = SMB_VFS_LOCK(fsp,fsp->fh->fd,op,offset,count,type);
-	} else {
-		pid_t pid;
-		ret = SMB_VFS_GETLOCK(fsp,fsp->fh->fd,&offset,&count,&type,&pid);
-	}
+	ret = SMB_VFS_LOCK(fsp,fsp->fh->fd,op,offset,count,type);
 
 	if (!ret && ((errno == EFBIG) || (errno == ENOLCK) || (errno ==  EINVAL))) {
 
@@ -682,12 +677,7 @@
 			DEBUG(0,("Count greater than 31 bits - retrying with 31 bit truncated length.\n"));
 			errno = 0;
 			count &= 0x7fffffff;
-			if (op != SMB_F_GETLK) {
-				ret = SMB_VFS_LOCK(fsp,fsp->fh->fd,op,offset,count,type);
-			} else {
-				pid_t pid;
-				ret = SMB_VFS_GETLOCK(fsp,fsp->fh->fd,&offset,&count,&type,&pid);
-			}
+			ret = SMB_VFS_LOCK(fsp,fsp->fh->fd,op,offset,count,type);
 		}
 	}
 
@@ -696,6 +686,52 @@
 }
 
 /****************************************************************************
+ Actual function that gets POSIX locks. Copes with 64 -> 32 bit cruft and
+ broken NFS implementations.
+****************************************************************************/
+
+static BOOL posix_fcntl_getlock(files_struct *fsp, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype)
+{
+	pid_t pid;
+	BOOL ret;
+
+	DEBUG(8,("posix_fcntl_getlock %d %.0f %.0f %d\n",
+		fsp->fh->fd,(double)*poffset,(double)*pcount,*ptype));
+
+	ret = SMB_VFS_GETLOCK(fsp,fsp->fh->fd,poffset,pcount,ptype,&pid);
+
+	if (!ret && ((errno == EFBIG) || (errno == ENOLCK) || (errno ==  EINVAL))) {
+
+		DEBUG(0,("posix_fcntl_getlock: WARNING: lock request at offset %.0f, length %.0f returned\n",
+					(double)*poffset,(double)*pcount));
+		DEBUG(0,("an %s error. This can happen when using 64 bit lock offsets\n", strerror(errno)));
+		DEBUG(0,("on 32 bit NFS mounted file systems.\n"));
+
+		/*
+		 * If the offset is > 0x7FFFFFFF then this will cause problems on
+		 * 32 bit NFS mounted filesystems. Just ignore it.
+		 */
+
+		if (*poffset & ~((SMB_OFF_T)0x7fffffff)) {
+			DEBUG(0,("Offset greater than 31 bits. Returning success.\n"));
+			return True;
+		}
+
+		if (*pcount & ~((SMB_OFF_T)0x7fffffff)) {
+			/* 32 bit NFS file system, retry with smaller offset */
+			DEBUG(0,("Count greater than 31 bits - retrying with 31 bit truncated length.\n"));
+			errno = 0;
+			*pcount &= 0x7fffffff;
+			ret = SMB_VFS_GETLOCK(fsp,fsp->fh->fd,poffset,pcount,ptype,&pid);
+		}
+	}
+
+	DEBUG(8,("posix_fcntl_getlock: Lock query call %s\n", ret ? "successful" : "failed"));
+	return ret;
+}
+
+
+/****************************************************************************
  POSIX function to see if a file region is locked. Returns True if the
  region is locked, False otherwise.
 ****************************************************************************/
@@ -718,20 +754,15 @@
 	 * 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, u_offset, u_count)) {
 		return False;
+	}
 
-	/*
-	 * Note that most UNIX's can *test* for a write lock on
-	 * a read-only fd, just not *set* a write lock on a read-only
-	 * fd. So we don't need to use map_lock_type here.
-	 */ 
-
-	if (!posix_fcntl_lock(fsp,SMB_F_GETLK,offset,count,posix_lock_type)) {
+	if (!posix_fcntl_getlock(fsp,&offset,&count,&posix_lock_type)) {
 		return False;
 	}
 
-	return (posix_lock_type != F_UNLCK ? True : False);
+	return (posix_lock_type == F_UNLCK ? False : True);
 }
 
 /*



More information about the samba-cvs mailing list