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. ****************************************************************************/
