r6502: add LOCKING debug class - pull PRINTINGDB class definition from trunk
[samba.git] / source3 / locking / locking.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Locking functions
4    Copyright (C) Andrew Tridgell 1992-2000
5    Copyright (C) Jeremy Allison 1992-2000
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21    Revision History:
22
23    12 aug 96: Erik.Devriendt@te6.siemens.be
24    added support for shared memory implementation of share mode locking
25
26    May 1997. Jeremy Allison (jallison@whistle.com). Modified share mode
27    locking to deal with multiple share modes per open file.
28
29    September 1997. Jeremy Allison (jallison@whistle.com). Added oplock
30    support.
31
32    rewrtten completely to use new tdb code. Tridge, Dec '99
33
34    Added POSIX locking support. Jeremy Allison (jeremy@valinux.com), Apr. 2000.
35 */
36
37 #include "includes.h"
38 uint16 global_smbpid;
39
40 #undef DBGC_CLASS
41 #define DBGC_CLASS DBGC_LOCKING
42
43 /* the locking database handle */
44 static TDB_CONTEXT *tdb;
45
46 struct locking_data {
47         union {
48                 int num_share_mode_entries;
49                 share_mode_entry dummy; /* Needed for alignment. */
50         } u;
51         /* the following two entries are implicit
52            share_mode_entry modes[num_share_mode_entries];
53            char file_name[];
54         */
55 };
56
57 /****************************************************************************
58  Debugging aid :-).
59 ****************************************************************************/
60
61 static const char *lock_type_name(enum brl_type lock_type)
62 {
63         return (lock_type == READ_LOCK) ? "READ" : "WRITE";
64 }
65
66 /****************************************************************************
67  Utility function called to see if a file region is locked.
68 ****************************************************************************/
69
70 BOOL is_locked(files_struct *fsp,connection_struct *conn,
71                SMB_BIG_UINT count,SMB_BIG_UINT offset, 
72                enum brl_type lock_type)
73 {
74         int snum = SNUM(conn);
75         int strict_locking = lp_strict_locking(snum);
76         BOOL ret;
77         
78         if (count == 0)
79                 return(False);
80
81         if (!lp_locking(snum) || !strict_locking)
82                 return(False);
83
84         if (strict_locking == Auto) {
85                 if  (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (lock_type == READ_LOCK || lock_type == WRITE_LOCK)) {
86                         DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp->fsp_name ));
87                         ret = 0;
88                 } else if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type) && (lock_type == READ_LOCK)) {
89                         DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name ));
90                         ret = 0;
91                 } else {
92                         ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum,
93                                      global_smbpid, sys_getpid(), conn->cnum, 
94                                      offset, count, lock_type);
95                 }
96         } else {
97                 ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum,
98                                 global_smbpid, sys_getpid(), conn->cnum,
99                                 offset, count, lock_type);
100         }
101
102         DEBUG(10,("is_locked: brl start=%.0f len=%.0f %s for file %s\n",
103                         (double)offset, (double)count, ret ? "locked" : "unlocked",
104                         fsp->fsp_name ));
105
106         /*
107          * There is no lock held by an SMB daemon, check to
108          * see if there is a POSIX lock from a UNIX or NFS process.
109          */
110
111         if(!ret && lp_posix_locking(snum)) {
112                 ret = is_posix_locked(fsp, offset, count, lock_type);
113
114                 DEBUG(10,("is_locked: posix start=%.0f len=%.0f %s for file %s\n",
115                                 (double)offset, (double)count, ret ? "locked" : "unlocked",
116                                 fsp->fsp_name ));
117         }
118
119         return ret;
120 }
121
122 /****************************************************************************
123  Utility function called by locking requests.
124 ****************************************************************************/
125
126 static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
127                  SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type, BOOL *my_lock_ctx)
128 {
129         NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED;
130
131         if (!lp_locking(SNUM(conn)))
132                 return NT_STATUS_OK;
133
134         /* NOTE! 0 byte long ranges ARE allowed and should be stored  */
135
136         DEBUG(10,("do_lock: lock type %s start=%.0f len=%.0f requested for file %s\n",
137                   lock_type_name(lock_type), (double)offset, (double)count, fsp->fsp_name ));
138
139         if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) {
140                 status = brl_lock(fsp->dev, fsp->inode, fsp->fnum,
141                                   lock_pid, sys_getpid(), conn->cnum, 
142                                   offset, count, 
143                                   lock_type, my_lock_ctx);
144
145                 if (NT_STATUS_IS_OK(status) && lp_posix_locking(SNUM(conn))) {
146
147                         /*
148                          * Try and get a POSIX lock on this range.
149                          * Note that this is ok if it is a read lock
150                          * overlapping on a different fd. JRA.
151                          */
152
153                         if (!set_posix_lock(fsp, offset, count, lock_type)) {
154                                 if (errno == EACCES || errno == EAGAIN)
155                                         status = NT_STATUS_FILE_LOCK_CONFLICT;
156                                 else
157                                         status = map_nt_error_from_unix(errno);
158
159                                 /*
160                                  * We failed to map - we must now remove the brl
161                                  * lock entry.
162                                  */
163                                 (void)brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
164                                                                 lock_pid, sys_getpid(), conn->cnum, 
165                                                                 offset, count, False,
166                                                                 NULL, NULL);
167                         }
168                 }
169         }
170
171         return status;
172 }
173
174 /****************************************************************************
175  Utility function called by locking requests. This is *DISGUSTING*. It also
176  appears to be "What Windows Does" (tm). Andrew, ever wonder why Windows 2000
177  is so slow on the locking tests...... ? This is the reason. Much though I hate
178  it, we need this. JRA.
179 ****************************************************************************/
180
181 NTSTATUS do_lock_spin(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
182                  SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type, BOOL *my_lock_ctx)
183 {
184         int j, maxj = lp_lock_spin_count();
185         int sleeptime = lp_lock_sleep_time();
186         NTSTATUS status, ret;
187
188         if (maxj <= 0)
189                 maxj = 1;
190
191         ret = NT_STATUS_OK; /* to keep dumb compilers happy */
192
193         for (j = 0; j < maxj; j++) {
194                 status = do_lock(fsp, conn, lock_pid, count, offset, lock_type, my_lock_ctx);
195                 if (!NT_STATUS_EQUAL(status, NT_STATUS_LOCK_NOT_GRANTED) &&
196                     !NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
197                         return status;
198                 }
199                 /* if we do fail then return the first error code we got */
200                 if (j == 0) {
201                         ret = status;
202                         /* Don't spin if we blocked ourselves. */
203                         if (*my_lock_ctx)
204                                 return ret;
205                 }
206                 if (sleeptime)
207                         sys_usleep(sleeptime);
208         }
209         return ret;
210 }
211
212 /* Struct passed to brl_unlock. */
213 struct posix_unlock_data_struct {
214         files_struct *fsp;
215         SMB_BIG_UINT offset;
216         SMB_BIG_UINT count;
217 };
218
219 /****************************************************************************
220  Function passed to brl_unlock to allow POSIX unlock to be done first.
221 ****************************************************************************/
222
223 static void posix_unlock(void *pre_data)
224 {
225         struct posix_unlock_data_struct *pdata = (struct posix_unlock_data_struct *)pre_data;
226
227         if (lp_posix_locking(SNUM(pdata->fsp->conn)))
228                 release_posix_lock(pdata->fsp, pdata->offset, pdata->count);
229 }
230
231 /****************************************************************************
232  Utility function called by unlocking requests.
233 ****************************************************************************/
234
235 NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
236                    SMB_BIG_UINT count,SMB_BIG_UINT offset)
237 {
238         BOOL ok = False;
239         struct posix_unlock_data_struct posix_data;
240         
241         if (!lp_locking(SNUM(conn)))
242                 return NT_STATUS_OK;
243         
244         if (!OPEN_FSP(fsp) || !fsp->can_lock || (fsp->conn != conn)) {
245                 return NT_STATUS_INVALID_HANDLE;
246         }
247         
248         DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for file %s\n",
249                   (double)offset, (double)count, fsp->fsp_name ));
250
251         /*
252          * Remove the existing lock record from the tdb lockdb
253          * before looking at POSIX locks. If this record doesn't
254          * match then don't bother looking to remove POSIX locks.
255          */
256
257         posix_data.fsp = fsp;
258         posix_data.offset = offset;
259         posix_data.count = count;
260
261         ok = brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
262                         lock_pid, sys_getpid(), conn->cnum, offset, count,
263                         False, posix_unlock, (void *)&posix_data);
264    
265         if (!ok) {
266                 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
267                 return NT_STATUS_RANGE_NOT_LOCKED;
268         }
269         return NT_STATUS_OK;
270 }
271
272 /****************************************************************************
273  Remove any locks on this fd. Called from file_close().
274 ****************************************************************************/
275
276 void locking_close_file(files_struct *fsp)
277 {
278         pid_t pid = sys_getpid();
279
280         if (!lp_locking(SNUM(fsp->conn)))
281                 return;
282
283         /*
284          * Just release all the brl locks, no need to release individually.
285          */
286
287         brl_close(fsp->dev, fsp->inode, pid, fsp->conn->cnum, fsp->fnum);
288
289         if(lp_posix_locking(SNUM(fsp->conn))) {
290
291                 /* 
292                  * Release all the POSIX locks.
293                  */
294                 posix_locking_close_file(fsp);
295
296         }
297 }
298
299 /****************************************************************************
300  Initialise the locking functions.
301 ****************************************************************************/
302
303 static int open_read_only;
304
305 BOOL locking_init(int read_only)
306 {
307         brl_init(read_only);
308
309         if (tdb)
310                 return True;
311
312         tdb = tdb_open_log(lock_path("locking.tdb"), 
313                        0, TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST), 
314                        read_only?O_RDONLY:O_RDWR|O_CREAT,
315                        0644);
316
317         if (!tdb) {
318                 DEBUG(0,("ERROR: Failed to initialise locking database\n"));
319                 return False;
320         }
321         
322         if (!posix_locking_init(read_only))
323                 return False;
324
325         open_read_only = read_only;
326
327         return True;
328 }
329
330 /*******************************************************************
331  Deinitialize the share_mode management.
332 ******************************************************************/
333
334 BOOL locking_end(void)
335 {
336
337         brl_shutdown(open_read_only);
338         if (tdb) {
339
340                 if (tdb_close(tdb) != 0)
341                         return False;
342         }
343
344         return True;
345 }
346
347 /*******************************************************************
348  Form a static locking key for a dev/inode pair.
349 ******************************************************************/
350
351 static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode)
352 {
353         static struct locking_key key;
354         TDB_DATA kbuf;
355
356         memset(&key, '\0', sizeof(key));
357         key.dev = dev;
358         key.inode = inode;
359         kbuf.dptr = (char *)&key;
360         kbuf.dsize = sizeof(key);
361         return kbuf;
362 }
363
364 static TDB_DATA locking_key_fsp(files_struct *fsp)
365 {
366         return locking_key(fsp->dev, fsp->inode);
367 }
368
369 /*******************************************************************
370  Lock a hash bucket entry.
371 ******************************************************************/
372
373 BOOL lock_share_entry(connection_struct *conn,
374                       SMB_DEV_T dev, SMB_INO_T inode)
375 {
376         return tdb_chainlock(tdb, locking_key(dev, inode)) == 0;
377 }
378
379 /*******************************************************************
380  Unlock a hash bucket entry.
381 ******************************************************************/
382
383 void unlock_share_entry(connection_struct *conn,
384                         SMB_DEV_T dev, SMB_INO_T inode)
385 {
386         tdb_chainunlock(tdb, locking_key(dev, inode));
387 }
388
389 /*******************************************************************
390  Lock a hash bucket entry. use a fsp for convenience
391 ******************************************************************/
392
393 BOOL lock_share_entry_fsp(files_struct *fsp)
394 {
395         return tdb_chainlock(tdb, locking_key(fsp->dev, fsp->inode)) == 0;
396 }
397
398 /*******************************************************************
399  Unlock a hash bucket entry.
400 ******************************************************************/
401
402 void unlock_share_entry_fsp(files_struct *fsp)
403 {
404         tdb_chainunlock(tdb, locking_key(fsp->dev, fsp->inode));
405 }
406
407 /*******************************************************************
408  Print out a share mode.
409 ********************************************************************/
410
411 char *share_mode_str(int num, share_mode_entry *e)
412 {
413         static pstring share_str;
414
415         slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: \
416 pid = %lu, share_mode = 0x%x, desired_access = 0x%x, port = 0x%x, type= 0x%x, file_id = %lu, dev = 0x%x, inode = %.0f",
417         num, (unsigned long)e->pid, e->share_mode, (unsigned int)e->desired_access, e->op_port, e->op_type, e->share_file_id,
418         (unsigned int)e->dev, (double)e->inode );
419
420         return share_str;
421 }
422
423 /*******************************************************************
424  Print out a share mode table.
425 ********************************************************************/
426
427 static void print_share_mode_table(struct locking_data *data)
428 {
429         int num_share_modes = data->u.num_share_mode_entries;
430         share_mode_entry *shares = (share_mode_entry *)(data + 1);
431         int i;
432
433         for (i = 0; i < num_share_modes; i++) {
434                 share_mode_entry *entry_p = &shares[i];
435                 DEBUG(10,("print_share_mode_table: %s\n", share_mode_str(i, entry_p) ));
436         }
437 }
438
439 /*******************************************************************
440  Get all share mode entries for a dev/inode pair.
441 ********************************************************************/
442
443 int get_share_modes(connection_struct *conn, 
444                     SMB_DEV_T dev, SMB_INO_T inode, 
445                     share_mode_entry **pp_shares)
446 {
447         TDB_DATA dbuf;
448         struct locking_data *data;
449         int num_share_modes;
450         share_mode_entry *shares = NULL;
451         TDB_DATA key = locking_key(dev, inode);
452         *pp_shares = NULL;
453
454         dbuf = tdb_fetch(tdb, key);
455         if (!dbuf.dptr)
456                 return 0;
457
458         data = (struct locking_data *)dbuf.dptr;
459         num_share_modes = data->u.num_share_mode_entries;
460         if(num_share_modes) {
461                 pstring fname;
462                 int i;
463                 int del_count = 0;
464
465                 shares = (share_mode_entry *)memdup(dbuf.dptr + sizeof(*data),  
466                                                 num_share_modes * sizeof(share_mode_entry));
467
468                 if (!shares) {
469                         SAFE_FREE(dbuf.dptr);
470                         return 0;
471                 }
472
473                 /* Save off the associated filename. */
474                 pstrcpy(fname, dbuf.dptr + sizeof(*data) + num_share_modes * sizeof(share_mode_entry));
475
476                 /*
477                  * Ensure that each entry has a real process attached.
478                  */
479
480                 for (i = 0; i < num_share_modes; ) {
481                         share_mode_entry *entry_p = &shares[i];
482                         if (process_exists(entry_p->pid)) {
483                                 DEBUG(10,("get_share_modes: %s\n", share_mode_str(i, entry_p) ));
484                                 i++;
485                         } else {
486                                 DEBUG(10,("get_share_modes: deleted %s\n", share_mode_str(i, entry_p) ));
487                                 if (num_share_modes - i - 1 > 0) {
488                                         memcpy( &shares[i], &shares[i+1],
489                                                 sizeof(share_mode_entry) * (num_share_modes - i - 1));
490                                 }
491                                 num_share_modes--;
492                                 del_count++;
493                         }
494                 }
495
496                 /* Did we delete any ? If so, re-store in tdb. */
497                 if (del_count) {
498                         data->u.num_share_mode_entries = num_share_modes;
499                         
500                         if (num_share_modes) {
501                                 memcpy(dbuf.dptr + sizeof(*data), shares,
502                                                 num_share_modes * sizeof(share_mode_entry));
503                                 /* Append the filename. */
504                                 pstrcpy(dbuf.dptr + sizeof(*data) + num_share_modes * sizeof(share_mode_entry), fname);
505                         }
506
507                         /* The record has shrunk a bit */
508                         dbuf.dsize -= del_count * sizeof(share_mode_entry);
509
510                         if (data->u.num_share_mode_entries == 0) {
511                                 if (tdb_delete(tdb, key) == -1) {
512                                         SAFE_FREE(shares);
513                                         SAFE_FREE(dbuf.dptr);
514                                         return 0;
515                                 }
516                         } else {
517                                 if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) {
518                                         SAFE_FREE(shares);
519                                         SAFE_FREE(dbuf.dptr);
520                                         return 0;
521                                 }
522                         }
523                 }
524         }
525
526         SAFE_FREE(dbuf.dptr);
527         *pp_shares = shares;
528         return num_share_modes;
529 }
530
531 /*******************************************************************
532  Fill a share mode entry.
533 ********************************************************************/
534
535 static void fill_share_mode(char *p, files_struct *fsp, uint16 port, uint16 op_type)
536 {
537         share_mode_entry *e = (share_mode_entry *)p;
538         void *x = &e->time; /* Needed to force alignment. p may not be aligned.... */
539
540         memset(e, '\0', sizeof(share_mode_entry));
541         e->pid = sys_getpid();
542         e->share_mode = fsp->share_mode;
543         e->desired_access = fsp->desired_access;
544         e->op_port = port;
545         e->op_type = op_type;
546         memcpy(x, &fsp->open_time, sizeof(struct timeval));
547         e->share_file_id = fsp->file_id;
548         e->dev = fsp->dev;
549         e->inode = fsp->inode;
550 }
551
552 /*******************************************************************
553  Check if two share mode entries are identical, ignoring oplock 
554  and port info and desired_access.
555 ********************************************************************/
556
557 BOOL share_modes_identical( share_mode_entry *e1, share_mode_entry *e2)
558 {
559 #if 1 /* JRA PARANOIA TEST - REMOVE LATER */
560         if (e1->pid == e2->pid &&
561                 e1->share_file_id == e2->share_file_id &&
562                 e1->dev == e2->dev &&
563                 e1->inode == e2->inode &&
564                 (e1->share_mode & ~DELETE_ON_CLOSE_FLAG) != (e2->share_mode & ~DELETE_ON_CLOSE_FLAG)) {
565                         DEBUG(0,("PANIC: share_modes_identical: share_mode missmatch (e1 = %u, e2 = %u). Logic error.\n",
566                                 (unsigned int)(e1->share_mode & ~DELETE_ON_CLOSE_FLAG),
567                                 (unsigned int)(e2->share_mode & ~DELETE_ON_CLOSE_FLAG) ));
568                 smb_panic("PANIC: share_modes_identical logic error.\n");
569         }
570 #endif
571
572         return (e1->pid == e2->pid &&
573                 (e1->share_mode & ~DELETE_ON_CLOSE_FLAG) == (e2->share_mode & ~DELETE_ON_CLOSE_FLAG) &&
574                 e1->dev == e2->dev &&
575                 e1->inode == e2->inode &&
576                 e1->share_file_id == e2->share_file_id );
577 }
578
579 /*******************************************************************
580  Delete a specific share mode. Return the number
581  of entries left, and a memdup'ed copy of the entry deleted (if required).
582  Ignore if no entry deleted.
583 ********************************************************************/
584
585 ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode,
586                         share_mode_entry *entry, share_mode_entry **ppse)
587 {
588         TDB_DATA dbuf;
589         struct locking_data *data;
590         int i, del_count=0;
591         share_mode_entry *shares;
592         ssize_t count = 0;
593         TDB_DATA key = locking_key(dev, inode);
594
595         if (ppse)
596                 *ppse = NULL;
597
598         /* read in the existing share modes */
599         dbuf = tdb_fetch(tdb, key);
600         if (!dbuf.dptr)
601                 return -1;
602
603         data = (struct locking_data *)dbuf.dptr;
604         shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
605
606         /*
607          * Find any with this pid and delete it
608          * by overwriting with the rest of the data 
609          * from the record.
610          */
611
612         DEBUG(10,("del_share_entry: num_share_modes = %d\n", data->u.num_share_mode_entries ));
613
614         for (i=0;i<data->u.num_share_mode_entries;) {
615                 if (share_modes_identical(&shares[i], entry)) {
616                         DEBUG(10,("del_share_entry: deleted %s\n",
617                                 share_mode_str(i, &shares[i]) ));
618                         if (ppse)
619                                 *ppse = memdup(&shares[i], sizeof(*shares));
620                         data->u.num_share_mode_entries--;
621                         if ((dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares))) > 0) {
622                                 memmove(&shares[i], &shares[i+1], 
623                                         dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares)));
624                         }
625                         del_count++;
626
627                         DEBUG(10,("del_share_entry: deleting entry %d\n", i ));
628
629                 } else {
630                         i++;
631                 }
632         }
633
634         if (del_count) {
635                 /* the record may have shrunk a bit */
636                 dbuf.dsize -= del_count * sizeof(*shares);
637
638                 count = (ssize_t)data->u.num_share_mode_entries;
639
640                 /* store it back in the database */
641                 if (data->u.num_share_mode_entries == 0) {
642                         if (tdb_delete(tdb, key) == -1)
643                                 count = -1;
644                 } else {
645                         if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1)
646                                 count = -1;
647                 }
648         }
649         DEBUG(10,("del_share_entry: Remaining table.\n"));
650         print_share_mode_table((struct locking_data *)dbuf.dptr);
651         SAFE_FREE(dbuf.dptr);
652         return count;
653 }
654
655 /*******************************************************************
656  Del the share mode of a file for this process. Return the number
657  of entries left, and a memdup'ed copy of the entry deleted.
658 ********************************************************************/
659
660 ssize_t del_share_mode(files_struct *fsp, share_mode_entry **ppse)
661 {
662         share_mode_entry entry;
663
664         /*
665          * Fake up a share_mode_entry for comparisons.
666          */
667
668         fill_share_mode((char *)&entry, fsp, 0, 0);
669         return del_share_entry(fsp->dev, fsp->inode, &entry, ppse);
670 }
671
672 /*******************************************************************
673  Set the share mode of a file. Return False on fail, True on success.
674 ********************************************************************/
675
676 BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type)
677 {
678         TDB_DATA dbuf;
679         struct locking_data *data;
680         char *p=NULL;
681         int size;
682         TDB_DATA key = locking_key_fsp(fsp);
683         BOOL ret = True;
684                 
685         /* read in the existing share modes if any */
686         dbuf = tdb_fetch(tdb, key);
687         if (!dbuf.dptr) {
688                 size_t offset;
689                 /* we'll need to create a new record */
690                 pstring fname;
691
692                 pstrcpy(fname, fsp->conn->connectpath);
693                 pstrcat(fname, "/");
694                 pstrcat(fname, fsp->fsp_name);
695
696                 size = sizeof(*data) + sizeof(share_mode_entry) + strlen(fname) + 1;
697                 p = (char *)SMB_MALLOC(size);
698                 if (!p)
699                         return False;
700                 data = (struct locking_data *)p;
701                 data->u.num_share_mode_entries = 1;
702         
703                 DEBUG(10,("set_share_mode: creating entry for file %s. num_share_modes = 1\n",
704                         fsp->fsp_name ));
705
706                 offset = sizeof(*data) + sizeof(share_mode_entry);
707                 safe_strcpy(p + offset, fname, size - offset - 1);
708                 fill_share_mode(p + sizeof(*data), fsp, port, op_type);
709                 dbuf.dptr = p;
710                 dbuf.dsize = size;
711                 if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1)
712                         ret = False;
713
714                 print_share_mode_table((struct locking_data *)p);
715
716                 SAFE_FREE(p);
717                 return ret;
718         }
719
720         /* we're adding to an existing entry - this is a bit fiddly */
721         data = (struct locking_data *)dbuf.dptr;
722
723         data->u.num_share_mode_entries++;
724         
725         DEBUG(10,("set_share_mode: adding entry for file %s. new num_share_modes = %d\n",
726                 fsp->fsp_name, data->u.num_share_mode_entries ));
727
728         size = dbuf.dsize + sizeof(share_mode_entry);
729         p = SMB_MALLOC(size);
730         if (!p) {
731                 SAFE_FREE(dbuf.dptr);
732                 return False;
733         }
734         memcpy(p, dbuf.dptr, sizeof(*data));
735         fill_share_mode(p + sizeof(*data), fsp, port, op_type);
736         memcpy(p + sizeof(*data) + sizeof(share_mode_entry), dbuf.dptr + sizeof(*data),
737                dbuf.dsize - sizeof(*data));
738         SAFE_FREE(dbuf.dptr);
739         dbuf.dptr = p;
740         dbuf.dsize = size;
741         if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1)
742                 ret = False;
743         print_share_mode_table((struct locking_data *)p);
744         SAFE_FREE(p);
745         return ret;
746 }
747
748 /*******************************************************************
749  A generic in-place modification call for share mode entries.
750 ********************************************************************/
751
752 static BOOL mod_share_mode( SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *entry,
753                            void (*mod_fn)(share_mode_entry *, SMB_DEV_T, SMB_INO_T, void *),
754                            void *param)
755 {
756         TDB_DATA dbuf;
757         struct locking_data *data;
758         int i;
759         share_mode_entry *shares;
760         BOOL need_store=False;
761         BOOL ret = True;
762         TDB_DATA key = locking_key(dev, inode);
763
764         /* read in the existing share modes */
765         dbuf = tdb_fetch(tdb, key);
766         if (!dbuf.dptr)
767                 return False;
768
769         data = (struct locking_data *)dbuf.dptr;
770         shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
771
772         /* find any with our pid and call the supplied function */
773         for (i=0;i<data->u.num_share_mode_entries;i++) {
774                 if (share_modes_identical(entry, &shares[i])) {
775                         mod_fn(&shares[i], dev, inode, param);
776                         need_store=True;
777                 }
778         }
779
780         /* if the mod fn was called then store it back */
781         if (need_store) {
782                 if (data->u.num_share_mode_entries == 0) {
783                         if (tdb_delete(tdb, key) == -1)
784                                 ret = False;
785                 } else {
786                         if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1)
787                                 ret = False;
788                 }
789         }
790
791         SAFE_FREE(dbuf.dptr);
792         return ret;
793 }
794
795 /*******************************************************************
796  Static function that actually does the work for the generic function
797  below.
798 ********************************************************************/
799
800 static void remove_share_oplock_fn(share_mode_entry *entry, SMB_DEV_T dev, SMB_INO_T inode, 
801                                    void *param)
802 {
803         DEBUG(10,("remove_share_oplock_fn: removing oplock info for entry dev=%x ino=%.0f\n",
804                   (unsigned int)dev, (double)inode ));
805         /* Delete the oplock info. */
806         entry->op_port = 0;
807         entry->op_type = NO_OPLOCK;
808 }
809
810 /*******************************************************************
811  Remove an oplock port and mode entry from a share mode.
812 ********************************************************************/
813
814 BOOL remove_share_oplock(files_struct *fsp)
815 {
816         share_mode_entry entry;
817         /*
818          * Fake up an entry for comparisons...
819          */
820         fill_share_mode((char *)&entry, fsp, 0, 0);
821         return mod_share_mode(fsp->dev, fsp->inode, &entry, remove_share_oplock_fn, NULL);
822 }
823
824 /*******************************************************************
825  Static function that actually does the work for the generic function
826  below.
827 ********************************************************************/
828
829 static void downgrade_share_oplock_fn(share_mode_entry *entry, SMB_DEV_T dev, SMB_INO_T inode, 
830                                    void *param)
831 {
832         DEBUG(10,("downgrade_share_oplock_fn: downgrading oplock info for entry dev=%x ino=%.0f\n",
833                   (unsigned int)dev, (double)inode ));
834         entry->op_type = LEVEL_II_OPLOCK;
835 }
836
837 /*******************************************************************
838  Downgrade a oplock type from exclusive to level II.
839 ********************************************************************/
840
841 BOOL downgrade_share_oplock(files_struct *fsp)
842 {
843         share_mode_entry entry;
844         /*
845          * Fake up an entry for comparisons...
846          */
847         fill_share_mode((char *)&entry, fsp, 0, 0);
848         return mod_share_mode(fsp->dev, fsp->inode, &entry, downgrade_share_oplock_fn, NULL);
849 }
850
851 /*******************************************************************
852  Get/Set the delete on close flag in a set of share modes.
853  Return False on fail, True on success.
854 ********************************************************************/
855
856 BOOL modify_delete_flag( SMB_DEV_T dev, SMB_INO_T inode, BOOL delete_on_close)
857 {
858         TDB_DATA dbuf;
859         struct locking_data *data;
860         int i;
861         share_mode_entry *shares;
862         TDB_DATA key = locking_key(dev, inode);
863
864         /* read in the existing share modes */
865         dbuf = tdb_fetch(tdb, key);
866         if (!dbuf.dptr)
867                 return False;
868
869         data = (struct locking_data *)dbuf.dptr;
870         shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
871
872         /* Set/Unset the delete on close element. */
873         for (i=0;i<data->u.num_share_mode_entries;i++,shares++) {
874                 shares->share_mode = (delete_on_close ?
875                             (shares->share_mode | DELETE_ON_CLOSE_FLAG) :
876                             (shares->share_mode & ~DELETE_ON_CLOSE_FLAG) );
877         }
878
879         /* store it back */
880         if (data->u.num_share_mode_entries) {
881                 if (tdb_store(tdb, key, dbuf, TDB_REPLACE)==-1) {
882                         SAFE_FREE(dbuf.dptr);
883                         return False;
884                 }
885         }
886
887         SAFE_FREE(dbuf.dptr);
888         return True;
889 }
890
891 /*******************************************************************
892  Print out a deferred open entry.
893 ********************************************************************/
894
895 char *deferred_open_str(int num, deferred_open_entry *e)
896 {
897         static pstring de_str;
898
899         slprintf(de_str, sizeof(de_str)-1, "deferred_open_entry[%d]: \
900 pid = %lu, mid = %u, dev = 0x%x, inode = %.0f, port = %u, time = [%u.%06u]",
901                 num, (unsigned long)e->pid, (unsigned int)e->mid, (unsigned int)e->dev, (double)e->inode,
902                 (unsigned int)e->port,
903                 (unsigned int)e->time.tv_sec, (unsigned int)e->time.tv_usec );
904
905         return de_str;
906 }
907
908 /* Internal data structures for deferred opens... */
909
910 struct de_locking_key {
911         char name[4];
912         SMB_DEV_T dev;
913         SMB_INO_T inode;
914 };
915
916 struct deferred_open_data {
917         union {
918                 int num_deferred_open_entries;
919                 deferred_open_entry dummy; /* Needed for alignment. */
920         } u;
921         /* the following two entries are implicit
922            deferred_open_entry de_entries[num_deferred_open_entries];
923            char file_name[];
924         */
925 };
926
927 /*******************************************************************
928  Print out a deferred open table.
929 ********************************************************************/
930
931 static void print_deferred_open_table(struct deferred_open_data *data)
932 {
933         int num_de_entries = data->u.num_deferred_open_entries;
934         deferred_open_entry *de_entries = (deferred_open_entry *)(data + 1);
935         int i;
936
937         for (i = 0; i < num_de_entries; i++) {
938                 deferred_open_entry *entry_p = &de_entries[i];
939                 DEBUG(10,("print_deferred_open_table: %s\n", deferred_open_str(i, entry_p) ));
940         }
941 }
942
943
944 /*******************************************************************
945  Form a static deferred open locking key for a dev/inode pair.
946 ******************************************************************/
947
948 static TDB_DATA deferred_open_locking_key(SMB_DEV_T dev, SMB_INO_T inode)
949 {
950         static struct de_locking_key key;
951         TDB_DATA kbuf;
952
953         memset(&key, '\0', sizeof(key));
954         memcpy(&key.name[0], "DOE", 4);
955         key.dev = dev;
956         key.inode = inode;
957         kbuf.dptr = (char *)&key;
958         kbuf.dsize = sizeof(key);
959         return kbuf;
960 }
961
962 /*******************************************************************
963  Get all deferred open entries for a dev/inode pair.
964 ********************************************************************/
965
966 int get_deferred_opens(connection_struct *conn, 
967                     SMB_DEV_T dev, SMB_INO_T inode, 
968                     deferred_open_entry **pp_de_entries)
969 {
970         TDB_DATA dbuf;
971         struct deferred_open_data *data;
972         int num_de_entries;
973         deferred_open_entry *de_entries = NULL;
974         TDB_DATA key = deferred_open_locking_key(dev, inode);
975
976         *pp_de_entries = NULL;
977
978         dbuf = tdb_fetch(tdb, key);
979         if (!dbuf.dptr)
980                 return 0;
981
982         data = (struct deferred_open_data *)dbuf.dptr;
983         num_de_entries = data->u.num_deferred_open_entries;
984         if(num_de_entries) {
985                 pstring fname;
986                 int i;
987                 int del_count = 0;
988
989                 de_entries = (deferred_open_entry *)memdup(dbuf.dptr + sizeof(*data),   
990                                                 num_de_entries * sizeof(deferred_open_entry));
991
992                 if (!de_entries) {
993                         SAFE_FREE(dbuf.dptr);
994                         return 0;
995                 }
996
997                 /* Save off the associated filename. */
998                 pstrcpy(fname, dbuf.dptr + sizeof(*data) + num_de_entries * sizeof(deferred_open_entry));
999
1000                 /*
1001                  * Ensure that each entry has a real process attached.
1002                  */
1003
1004                 for (i = 0; i < num_de_entries; ) {
1005                         deferred_open_entry *entry_p = &de_entries[i];
1006                         if (process_exists(entry_p->pid)) {
1007                                 DEBUG(10,("get_deferred_opens: %s\n", deferred_open_str(i, entry_p) ));
1008                                 i++;
1009                         } else {
1010                                 DEBUG(10,("get_deferred_opens: deleted %s\n", deferred_open_str(i, entry_p) ));
1011                                 if (num_de_entries - i - 1 > 0) {
1012                                         memcpy( &de_entries[i], &de_entries[i+1],
1013                                                 sizeof(deferred_open_entry) * (num_de_entries - i - 1));
1014                                 }
1015                                 num_de_entries--;
1016                                 del_count++;
1017                         }
1018                 }
1019
1020                 /* Did we delete any ? If so, re-store in tdb. */
1021                 if (del_count) {
1022                         data->u.num_deferred_open_entries = num_de_entries;
1023                         
1024                         if (num_de_entries) {
1025                                 memcpy(dbuf.dptr + sizeof(*data), de_entries,
1026                                                 num_de_entries * sizeof(deferred_open_entry));
1027                                 /* Append the filename. */
1028                                 pstrcpy(dbuf.dptr + sizeof(*data) + num_de_entries * sizeof(deferred_open_entry), fname);
1029                         }
1030
1031                         /* The record has shrunk a bit */
1032                         dbuf.dsize -= del_count * sizeof(deferred_open_entry);
1033
1034                         if (data->u.num_deferred_open_entries == 0) {
1035                                 if (tdb_delete(tdb, key) == -1) {
1036                                         SAFE_FREE(de_entries);
1037                                         SAFE_FREE(dbuf.dptr);
1038                                         return 0;
1039                                 }
1040                         } else {
1041                                 if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) {
1042                                         SAFE_FREE(de_entries);
1043                                         SAFE_FREE(dbuf.dptr);
1044                                         return 0;
1045                                 }
1046                         }
1047                 }
1048         }
1049
1050         SAFE_FREE(dbuf.dptr);
1051         *pp_de_entries = de_entries;
1052         return num_de_entries;
1053 }
1054
1055 /*******************************************************************
1056  Check if two deferred open entries are identical.
1057 ********************************************************************/
1058
1059 static BOOL deferred_open_entries_identical( deferred_open_entry *e1, deferred_open_entry *e2)
1060 {
1061         return (e1->pid == e2->pid &&
1062                 e1->mid == e2->mid &&
1063                 e1->port == e2->port &&
1064                 e1->dev == e2->dev &&
1065                 e1->inode == e2->inode &&
1066                 e1->time.tv_sec == e2->time.tv_sec &&
1067                 e1->time.tv_usec == e2->time.tv_usec);
1068 }
1069
1070 /*******************************************************************
1071  Delete a specific deferred open entry.
1072  Ignore if no entry deleted.
1073 ********************************************************************/
1074
1075 BOOL delete_deferred_open_entry(deferred_open_entry *entry)
1076 {
1077         TDB_DATA dbuf;
1078         struct deferred_open_data *data;
1079         int i, del_count=0;
1080         deferred_open_entry *de_entries;
1081         BOOL ret = True;
1082         TDB_DATA key = deferred_open_locking_key(entry->dev, entry->inode);
1083
1084         /* read in the existing share modes */
1085         dbuf = tdb_fetch(tdb, key);
1086         if (!dbuf.dptr)
1087                 return -1;
1088
1089         data = (struct deferred_open_data *)dbuf.dptr;
1090         de_entries = (deferred_open_entry *)(dbuf.dptr + sizeof(*data));
1091
1092         /*
1093          * Find any with this pid and delete it
1094          * by overwriting with the rest of the data 
1095          * from the record.
1096          */
1097
1098         DEBUG(10,("delete_deferred_open_entry: num_deferred_open_entries = %d\n",
1099                 data->u.num_deferred_open_entries ));
1100
1101         for (i=0;i<data->u.num_deferred_open_entries;) {
1102                 if (deferred_open_entries_identical(&de_entries[i], entry)) {
1103                         DEBUG(10,("delete_deferred_open_entry: deleted %s\n",
1104                                 deferred_open_str(i, &de_entries[i]) ));
1105
1106                         data->u.num_deferred_open_entries--;
1107                         if ((dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*de_entries))) > 0) {
1108                                 memmove(&de_entries[i], &de_entries[i+1], 
1109                                         dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*de_entries)));
1110                         }
1111                         del_count++;
1112
1113                         DEBUG(10,("delete_deferred_open_entry: deleting entry %d\n", i ));
1114
1115                 } else {
1116                         i++;
1117                 }
1118         }
1119
1120         SMB_ASSERT(del_count == 0 || del_count == 1);
1121
1122         if (del_count) {
1123                 /* the record may have shrunk a bit */
1124                 dbuf.dsize -= del_count * sizeof(*de_entries);
1125
1126                 /* store it back in the database */
1127                 if (data->u.num_deferred_open_entries == 0) {
1128                         if (tdb_delete(tdb, key) == -1)
1129                                 ret = False;
1130                 } else {
1131                         if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1)
1132                                 ret = False;
1133                 }
1134         }
1135         DEBUG(10,("delete_deferred_open_entry: Remaining table.\n"));
1136         print_deferred_open_table((struct deferred_open_data*)dbuf.dptr);
1137         SAFE_FREE(dbuf.dptr);
1138         return ret;
1139 }
1140
1141 /*******************************************************************
1142  Fill a deferred open entry.
1143 ********************************************************************/
1144
1145 static void fill_deferred_open(char *p, uint16 mid, struct timeval *ptv, SMB_DEV_T dev, SMB_INO_T inode, uint16 port)
1146 {
1147         deferred_open_entry *e = (deferred_open_entry *)p;
1148         void *x = &e->time; /* Needed to force alignment. p may not be aligned.... */
1149
1150         memset(e, '\0', sizeof(deferred_open_entry));
1151         e->mid = mid;
1152         e->pid = sys_getpid();
1153         memcpy(x, ptv, sizeof(struct timeval));
1154         e->dev = dev;
1155         e->inode = inode;
1156         e->port = port;
1157 }
1158
1159 /*******************************************************************
1160  Add a deferred open record. Return False on fail, True on success.
1161 ********************************************************************/
1162
1163 BOOL add_deferred_open(uint16 mid, struct timeval *ptv, SMB_DEV_T dev, SMB_INO_T inode, uint16 port, const char *fname)
1164 {
1165         TDB_DATA dbuf;
1166         struct deferred_open_data *data;
1167         char *p=NULL;
1168         int size;
1169         TDB_DATA key = deferred_open_locking_key(dev, inode);
1170         BOOL ret = True;
1171                 
1172         /* read in the existing deferred open records if any */
1173         dbuf = tdb_fetch(tdb, key);
1174         if (!dbuf.dptr) {
1175                 size_t offset;
1176                 /* we'll need to create a new record */
1177
1178                 size = sizeof(*data) + sizeof(deferred_open_entry) + strlen(fname) + 1;
1179                 p = (char *)SMB_MALLOC(size);
1180                 if (!p)
1181                         return False;
1182                 data = (struct deferred_open_data *)p;
1183                 data->u.num_deferred_open_entries = 1;
1184         
1185                 DEBUG(10,("add_deferred_open: creating entry for file %s. num_deferred_open_entries = 1\n",
1186                         fname ));
1187
1188                 offset = sizeof(*data) + sizeof(deferred_open_entry);
1189                 safe_strcpy(p + offset, fname, size - offset - 1);
1190                 fill_deferred_open(p + sizeof(*data), mid, ptv, dev, inode, port);
1191                 dbuf.dptr = p;
1192                 dbuf.dsize = size;
1193                 if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1)
1194                         ret = False;
1195
1196                 print_deferred_open_table((struct deferred_open_data *)p);
1197
1198                 SAFE_FREE(p);
1199                 return ret;
1200         }
1201
1202         /* we're adding to an existing entry - this is a bit fiddly */
1203         data = (struct deferred_open_data *)dbuf.dptr;
1204
1205         data->u.num_deferred_open_entries++;
1206         
1207         DEBUG(10,("add_deferred_open: adding entry for file %s. new num_deferred_open_entries = %d\n",
1208                 fname, data->u.num_deferred_open_entries ));
1209
1210         size = dbuf.dsize + sizeof(deferred_open_entry);
1211         p = SMB_MALLOC(size);
1212         if (!p) {
1213                 SAFE_FREE(dbuf.dptr);
1214                 return False;
1215         }
1216         memcpy(p, dbuf.dptr, sizeof(*data));
1217         fill_deferred_open(p + sizeof(*data), mid, ptv, dev, inode, port);
1218         memcpy(p + sizeof(*data) + sizeof(deferred_open_entry), dbuf.dptr + sizeof(*data),
1219                dbuf.dsize - sizeof(*data));
1220         SAFE_FREE(dbuf.dptr);
1221         dbuf.dptr = p;
1222         dbuf.dsize = size;
1223         if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1)
1224                 ret = False;
1225         print_deferred_open_table((struct deferred_open_data *)p);
1226         SAFE_FREE(p);
1227         return ret;
1228 }
1229
1230 /****************************************************************************
1231  Traverse the whole database with this function, calling traverse_callback
1232  on each share mode
1233 ****************************************************************************/
1234
1235 static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, 
1236                        void* state)
1237 {
1238         struct locking_data *data;
1239         share_mode_entry *shares;
1240         char *name;
1241         int i;
1242
1243         SHAREMODE_FN(traverse_callback) = (SHAREMODE_FN_CAST())state;
1244
1245         /* Ensure this is a locking_key record. */
1246         if (kbuf.dsize != sizeof(struct locking_key))
1247                 return 0;
1248
1249         data = (struct locking_data *)dbuf.dptr;
1250         shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
1251         name = dbuf.dptr + sizeof(*data) + data->u.num_share_mode_entries*sizeof(*shares);
1252
1253         for (i=0;i<data->u.num_share_mode_entries;i++) {
1254                 traverse_callback(&shares[i], name);
1255         }
1256         return 0;
1257 }
1258
1259 /*******************************************************************
1260  Call the specified function on each entry under management by the
1261  share mode system.
1262 ********************************************************************/
1263
1264 int share_mode_forall(SHAREMODE_FN(fn))
1265 {
1266         if (!tdb)
1267                 return 0;
1268         return tdb_traverse(tdb, traverse_fn, (void*)fn);
1269 }