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