Author: jra Date: 2006-07-12 06:56:43 +0000 (Wed, 12 Jul 2006) New Revision: 16973
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=16973 Log: Fix subtle logic error in lock ref counting found by cifsfs client code. Jeremy. Modified: branches/SAMBA_3_0/source/locking/brlock.c branches/SAMBA_3_0/source/locking/posix.c Changeset: Modified: branches/SAMBA_3_0/source/locking/brlock.c =================================================================== --- branches/SAMBA_3_0/source/locking/brlock.c 2006-07-12 04:59:41 UTC (rev 16972) +++ branches/SAMBA_3_0/source/locking/brlock.c 2006-07-12 06:56:43 UTC (rev 16973) @@ -1229,7 +1229,7 @@ struct process_id pid = procid_self(); BOOL unlock_individually = False; - if(lp_posix_locking(fsp->conn->cnum) && !lp_posix_cifsu_locktype()) { + if(lp_posix_locking(fsp->conn->cnum)) { /* Check if there are any Windows locks associated with this dev/ino pair that are not this fnum. If so we need to call unlock on each @@ -1280,9 +1280,6 @@ /* We can bulk delete - any POSIX locks will be removed when the fd closes. */ - /* Zero any lock reference count on this dev/ino pair. */ - zero_windows_lock_ref_count(fsp); - /* Remove any existing locks for this fnum (or any fnum if they're POSIX). */ for (i=0; i < br_lck->num_locks; i++) { @@ -1336,6 +1333,9 @@ dcount++; } } + + /* Reduce the lock reference count on this dev/ino pair. */ + reduce_windows_lock_ref_count(fsp, dcount); } /**************************************************************************** Modified: branches/SAMBA_3_0/source/locking/posix.c =================================================================== --- branches/SAMBA_3_0/source/locking/posix.c 2006-07-12 04:59:41 UTC (rev 16972) +++ branches/SAMBA_3_0/source/locking/posix.c 2006-07-12 06:56:43 UTC (rev 16973) @@ -492,10 +492,10 @@ } /**************************************************************************** - Ensure the lock ref count is zero. + Bulk delete - subtract as many locks as we've just deleted. ****************************************************************************/ -void zero_windows_lock_ref_count(files_struct *fsp) +void reduce_windows_lock_ref_count(files_struct *fsp, unsigned int dcount) { TDB_DATA kbuf = locking_ref_count_key_fsp(fsp); TDB_DATA dbuf; @@ -507,19 +507,19 @@ } memcpy(&lock_ref_count, dbuf.dptr, sizeof(int)); + lock_ref_count -= dcount; + if (lock_ref_count < 0) { - smb_panic("zero_windows_lock_ref_count: lock_count logic error.\n"); + smb_panic("reduce_windows_lock_ref_count: lock_count logic error.\n"); } - - lock_ref_count = 0; memcpy(dbuf.dptr, &lock_ref_count, sizeof(int)); if (tdb_store(posix_pending_close_tdb, kbuf, dbuf, TDB_REPLACE) == -1) { - smb_panic("zero_windows_lock_ref_count: tdb_store_fail.\n"); + smb_panic("reduce_windows_lock_ref_count: tdb_store_fail.\n"); } SAFE_FREE(dbuf.dptr); - DEBUG(10,("zero_windows_lock_ref_count for file now %s = %d\n", + DEBUG(10,("reduce_windows_lock_ref_count for file now %s = %d\n", fsp->fsp_name, lock_ref_count )); }