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

Reply via email to