r10656: BIG merge from trunk. Features not copied over
[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    Copyright (C) Volker Lendecke 2005
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
22    Revision History:
23
24    12 aug 96: Erik.Devriendt@te6.siemens.be
25    added support for shared memory implementation of share mode locking
26
27    May 1997. Jeremy Allison (jallison@whistle.com). Modified share mode
28    locking to deal with multiple share modes per open file.
29
30    September 1997. Jeremy Allison (jallison@whistle.com). Added oplock
31    support.
32
33    rewrtten completely to use new tdb code. Tridge, Dec '99
34
35    Added POSIX locking support. Jeremy Allison (jeremy@valinux.com), Apr. 2000.
36 */
37
38 #include "includes.h"
39 uint16 global_smbpid;
40
41 #undef DBGC_CLASS
42 #define DBGC_CLASS DBGC_LOCKING
43
44 /* the locking database handle */
45 static TDB_CONTEXT *tdb;
46
47 struct locking_data {
48         union {
49                 struct {
50                         int num_share_mode_entries;
51                         BOOL delete_on_close;
52                 } s;
53                 struct share_mode_entry dummy; /* Needed for alignment. */
54         } u;
55         /* the following two entries are implicit
56            struct share_mode_entry modes[num_share_mode_entries];
57            char file_name[];
58         */
59 };
60
61 /****************************************************************************
62  Debugging aid :-).
63 ****************************************************************************/
64
65 static const char *lock_type_name(enum brl_type lock_type)
66 {
67         return (lock_type == READ_LOCK) ? "READ" : "WRITE";
68 }
69
70 /****************************************************************************
71  Utility function called to see if a file region is locked.
72 ****************************************************************************/
73
74 BOOL is_locked(files_struct *fsp,connection_struct *conn,
75                SMB_BIG_UINT count,SMB_BIG_UINT offset, 
76                enum brl_type lock_type)
77 {
78         int snum = SNUM(conn);
79         int strict_locking = lp_strict_locking(snum);
80         BOOL ret;
81         
82         if (count == 0)
83                 return(False);
84
85         if (!lp_locking(snum) || !strict_locking)
86                 return(False);
87
88         if (strict_locking == Auto) {
89                 if  (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (lock_type == READ_LOCK || lock_type == WRITE_LOCK)) {
90                         DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp->fsp_name ));
91                         ret = 0;
92                 } else if ((fsp->oplock_type == LEVEL_II_OPLOCK) &&
93                            (lock_type == READ_LOCK)) {
94                         DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name ));
95                         ret = 0;
96                 } else {
97                         ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum,
98                                      global_smbpid, procid_self(), conn->cnum, 
99                                      offset, count, lock_type);
100                 }
101         } else {
102                 ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum,
103                                 global_smbpid, procid_self(), conn->cnum,
104                                 offset, count, lock_type);
105         }
106
107         DEBUG(10,("is_locked: brl start=%.0f len=%.0f %s for file %s\n",
108                         (double)offset, (double)count, ret ? "locked" : "unlocked",
109                         fsp->fsp_name ));
110
111         /*
112          * There is no lock held by an SMB daemon, check to
113          * see if there is a POSIX lock from a UNIX or NFS process.
114          */
115
116         if(!ret && lp_posix_locking(snum)) {
117                 ret = is_posix_locked(fsp, offset, count, lock_type);
118
119                 DEBUG(10,("is_locked: posix start=%.0f len=%.0f %s for file %s\n",
120                                 (double)offset, (double)count, ret ? "locked" : "unlocked",
121                                 fsp->fsp_name ));
122         }
123
124         return ret;
125 }
126
127 /****************************************************************************
128  Utility function called by locking requests.
129 ****************************************************************************/
130
131 static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
132                  SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type, BOOL *my_lock_ctx)
133 {
134         NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED;
135
136         if (!lp_locking(SNUM(conn)))
137                 return NT_STATUS_OK;
138
139         /* NOTE! 0 byte long ranges ARE allowed and should be stored  */
140
141         DEBUG(10,("do_lock: lock type %s start=%.0f len=%.0f requested for file %s\n",
142                   lock_type_name(lock_type), (double)offset, (double)count, fsp->fsp_name ));
143
144         if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) {
145                 status = brl_lock(fsp->dev, fsp->inode, fsp->fnum,
146                                   lock_pid, procid_self(), conn->cnum, 
147                                   offset, count, 
148                                   lock_type, my_lock_ctx);
149
150                 if (NT_STATUS_IS_OK(status) && lp_posix_locking(SNUM(conn))) {
151
152                         /*
153                          * Try and get a POSIX lock on this range.
154                          * Note that this is ok if it is a read lock
155                          * overlapping on a different fd. JRA.
156                          */
157
158                         if (!set_posix_lock(fsp, offset, count, lock_type)) {
159                                 if (errno == EACCES || errno == EAGAIN)
160                                         status = NT_STATUS_FILE_LOCK_CONFLICT;
161                                 else
162                                         status = map_nt_error_from_unix(errno);
163
164                                 /*
165                                  * We failed to map - we must now remove the brl
166                                  * lock entry.
167                                  */
168                                 (void)brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
169                                                                 lock_pid, procid_self(), conn->cnum, 
170                                                                 offset, count, False,
171                                                                 NULL, NULL);
172                         }
173                 }
174         }
175
176         return status;
177 }
178
179 /****************************************************************************
180  Utility function called by locking requests. This is *DISGUSTING*. It also
181  appears to be "What Windows Does" (tm). Andrew, ever wonder why Windows 2000
182  is so slow on the locking tests...... ? This is the reason. Much though I hate
183  it, we need this. JRA.
184 ****************************************************************************/
185
186 NTSTATUS do_lock_spin(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
187                  SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type, BOOL *my_lock_ctx)
188 {
189         int j, maxj = lp_lock_spin_count();
190         int sleeptime = lp_lock_sleep_time();
191         NTSTATUS status, ret;
192
193         if (maxj <= 0)
194                 maxj = 1;
195
196         ret = NT_STATUS_OK; /* to keep dumb compilers happy */
197
198         for (j = 0; j < maxj; j++) {
199                 status = do_lock(fsp, conn, lock_pid, count, offset, lock_type, my_lock_ctx);
200                 if (!NT_STATUS_EQUAL(status, NT_STATUS_LOCK_NOT_GRANTED) &&
201                     !NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
202                         return status;
203                 }
204                 /* if we do fail then return the first error code we got */
205                 if (j == 0) {
206                         ret = status;
207                         /* Don't spin if we blocked ourselves. */
208                         if (*my_lock_ctx)
209                                 return ret;
210                 }
211                 if (sleeptime)
212                         sys_usleep(sleeptime);
213         }
214         return ret;
215 }
216
217 /* Struct passed to brl_unlock. */
218 struct posix_unlock_data_struct {
219         files_struct *fsp;
220         SMB_BIG_UINT offset;
221         SMB_BIG_UINT count;
222 };
223
224 /****************************************************************************
225  Function passed to brl_unlock to allow POSIX unlock to be done first.
226 ****************************************************************************/
227
228 static void posix_unlock(void *pre_data)
229 {
230         struct posix_unlock_data_struct *pdata = (struct posix_unlock_data_struct *)pre_data;
231
232         if (lp_posix_locking(SNUM(pdata->fsp->conn)))
233                 release_posix_lock(pdata->fsp, pdata->offset, pdata->count);
234 }
235
236 /****************************************************************************
237  Utility function called by unlocking requests.
238 ****************************************************************************/
239
240 NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
241                    SMB_BIG_UINT count,SMB_BIG_UINT offset)
242 {
243         BOOL ok = False;
244         struct posix_unlock_data_struct posix_data;
245         
246         if (!lp_locking(SNUM(conn)))
247                 return NT_STATUS_OK;
248         
249         if (!OPEN_FSP(fsp) || !fsp->can_lock || (fsp->conn != conn)) {
250                 return NT_STATUS_INVALID_HANDLE;
251         }
252         
253         DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for file %s\n",
254                   (double)offset, (double)count, fsp->fsp_name ));
255
256         /*
257          * Remove the existing lock record from the tdb lockdb
258          * before looking at POSIX locks. If this record doesn't
259          * match then don't bother looking to remove POSIX locks.
260          */
261
262         posix_data.fsp = fsp;
263         posix_data.offset = offset;
264         posix_data.count = count;
265
266         ok = brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
267                         lock_pid, procid_self(), conn->cnum, offset, count,
268                         False, posix_unlock, (void *)&posix_data);
269    
270         if (!ok) {
271                 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
272                 return NT_STATUS_RANGE_NOT_LOCKED;
273         }
274         return NT_STATUS_OK;
275 }
276
277 /****************************************************************************
278  Remove any locks on this fd. Called from file_close().
279 ****************************************************************************/
280
281 void locking_close_file(files_struct *fsp)
282 {
283         struct process_id pid = procid_self();
284
285         if (!lp_locking(SNUM(fsp->conn)))
286                 return;
287
288         /*
289          * Just release all the brl locks, no need to release individually.
290          */
291
292         brl_close(fsp->dev, fsp->inode, pid, fsp->conn->cnum, fsp->fnum);
293
294         if(lp_posix_locking(SNUM(fsp->conn))) {
295
296                 /* 
297                  * Release all the POSIX locks.
298                  */
299                 posix_locking_close_file(fsp);
300
301         }
302 }
303
304 /****************************************************************************
305  Initialise the locking functions.
306 ****************************************************************************/
307
308 static int open_read_only;
309
310 BOOL locking_init(int read_only)
311 {
312         brl_init(read_only);
313
314         if (tdb)
315                 return True;
316
317         tdb = tdb_open_log(lock_path("locking.tdb"), 
318                        0, TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST), 
319                        read_only?O_RDONLY:O_RDWR|O_CREAT,
320                        0644);
321
322         if (!tdb) {
323                 DEBUG(0,("ERROR: Failed to initialise locking database\n"));
324                 return False;
325         }
326
327         if (!posix_locking_init(read_only))
328                 return False;
329
330         open_read_only = read_only;
331
332         return True;
333 }
334
335 /*******************************************************************
336  Deinitialize the share_mode management.
337 ******************************************************************/
338
339 BOOL locking_end(void)
340 {
341         BOOL ret = True;
342
343         brl_shutdown(open_read_only);
344         if (tdb) {
345                 if (tdb_close(tdb) != 0)
346                         ret = False;
347         }
348
349         return ret;
350 }
351
352 /*******************************************************************
353  Form a static locking key for a dev/inode pair.
354 ******************************************************************/
355
356 /* key and data records in the tdb locking database */
357 struct locking_key {
358         SMB_DEV_T dev;
359         SMB_INO_T ino;
360 };
361
362 /*******************************************************************
363  Form a static locking key for a dev/inode pair.
364 ******************************************************************/
365
366 static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode)
367 {
368         static struct locking_key key;
369         TDB_DATA kbuf;
370
371         memset(&key, '\0', sizeof(key));
372         key.dev = dev;
373         key.ino = inode;
374         kbuf.dptr = (char *)&key;
375         kbuf.dsize = sizeof(key);
376         return kbuf;
377 }
378
379 /*******************************************************************
380  Print out a share mode.
381 ********************************************************************/
382
383 char *share_mode_str(int num, struct share_mode_entry *e)
384 {
385         static pstring share_str;
386
387         slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: "
388                  "pid = %s, share_access = 0x%x, private_options = 0x%x, "
389                  "access_mask = 0x%x, mid = 0x%x, type= 0x%x, file_id = %lu, "
390                  "dev = 0x%x, inode = %.0f",
391                  num, procid_str_static(&e->pid),
392                  e->share_access, e->private_options,
393                  e->access_mask, e->op_mid, e->op_type, e->share_file_id,
394                  (unsigned int)e->dev, (double)e->inode );
395
396         return share_str;
397 }
398
399 /*******************************************************************
400  Print out a share mode table.
401 ********************************************************************/
402
403 static void print_share_mode_table(struct locking_data *data)
404 {
405         int num_share_modes = data->u.s.num_share_mode_entries;
406         struct share_mode_entry *shares =
407                 (struct share_mode_entry *)(data + 1);
408         int i;
409
410         for (i = 0; i < num_share_modes; i++) {
411                 struct share_mode_entry *entry_p = &shares[i];
412                 DEBUG(10,("print_share_mode_table: %s\n",
413                           share_mode_str(i, entry_p)));
414         }
415 }
416
417 /*******************************************************************
418  Get all share mode entries for a dev/inode pair.
419 ********************************************************************/
420
421 static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck)
422 {
423         struct locking_data *data;
424         int i;
425
426         if (dbuf.dsize < sizeof(struct locking_data)) {
427                 DEBUG(0, ("parse_share_modes: buffer too short\n"));
428                 return False;
429         }
430
431         data = (struct locking_data *)dbuf.dptr;
432
433         lck->delete_on_close = data->u.s.delete_on_close;
434         lck->num_share_modes = data->u.s.num_share_mode_entries;
435
436         DEBUG(10, ("parse_share_modes: delete_on_close: %d, "
437                    "num_share_modes: %d\n", lck->delete_on_close,
438                    lck->num_share_modes));
439
440         if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) {
441                 DEBUG(0, ("invalid number of share modes: %d\n",
442                           lck->num_share_modes));
443                 return False;
444         }
445
446         lck->share_modes = NULL;
447
448         if (lck->num_share_modes != 0) {
449
450                 if (dbuf.dsize < (sizeof(struct locking_data) +
451                                   (lck->num_share_modes *
452                                    sizeof(struct share_mode_entry)))) {
453                         DEBUG(0, ("parse_share_modes: buffer too short\n"));
454                         return False;
455                 }
456                                   
457                 lck->share_modes = talloc_memdup(lck, dbuf.dptr+sizeof(*data),
458                                                  lck->num_share_modes *
459                                                  sizeof(struct share_mode_entry));
460
461                 if (lck->share_modes == NULL) {
462                         DEBUG(0, ("talloc failed\n"));
463                         return False;
464                 }
465         }
466
467         /* Save off the associated filename. */
468         lck->filename = talloc_strdup(lck, dbuf.dptr + sizeof(*data) +
469                                       lck->num_share_modes *
470                                       sizeof(struct share_mode_entry));
471
472         /*
473          * Ensure that each entry has a real process attached.
474          */
475
476         for (i = 0; i < lck->num_share_modes; i++) {
477                 struct share_mode_entry *entry_p = &lck->share_modes[i];
478                 DEBUG(10,("parse_share_modes: %s\n",
479                           share_mode_str(i, entry_p) ));
480                 if (!process_exists(entry_p->pid)) {
481                         DEBUG(10,("parse_share_modes: deleted %s\n",
482                                   share_mode_str(i, entry_p) ));
483                         entry_p->op_type = UNUSED_SHARE_MODE_ENTRY;
484                         lck->modified = True;
485                 }
486         }
487
488         return True;
489 }
490
491 static TDB_DATA unparse_share_modes(struct share_mode_lock *lck)
492 {
493         TDB_DATA result;
494         int num_valid = 0;
495         int i;
496         struct locking_data *data;
497         ssize_t offset;
498
499         result.dptr = NULL;
500         result.dsize = 0;
501
502         for (i=0; i<lck->num_share_modes; i++) {
503                 if (!is_unused_share_mode_entry(&lck->share_modes[i])) {
504                         num_valid += 1;
505                 }
506         }
507
508         if (num_valid == 0) {
509                 return result;
510         }
511
512         result.dsize = sizeof(*data) +
513                 lck->num_share_modes * sizeof(struct share_mode_entry) +
514                 strlen(lck->filename) + 1;
515         result.dptr = talloc_size(lck, result.dsize);
516
517         if (result.dptr == NULL) {
518                 smb_panic("talloc failed\n");
519         }
520
521         data = (struct locking_data *)result.dptr;
522         ZERO_STRUCTP(data);
523         data->u.s.num_share_mode_entries = lck->num_share_modes;
524         data->u.s.delete_on_close = lck->delete_on_close;
525         DEBUG(10, ("unparse_share_modes: del: %d, num: %d\n",
526                    data->u.s.delete_on_close,
527                    data->u.s.num_share_mode_entries));
528         memcpy(result.dptr + sizeof(*data), lck->share_modes,
529                sizeof(struct share_mode_entry)*lck->num_share_modes);
530         offset = sizeof(*data) +
531                 sizeof(struct share_mode_entry)*lck->num_share_modes;
532         safe_strcpy(result.dptr + offset, lck->filename,
533                     result.dsize - offset - 1);
534         print_share_mode_table(data);
535         return result;
536 }
537
538 static int share_mode_lock_destructor(void *p)
539 {
540         struct share_mode_lock *lck =
541                 talloc_get_type_abort(p, struct share_mode_lock);
542         TDB_DATA key = locking_key(lck->dev, lck->ino);
543         TDB_DATA data;
544
545         if (!lck->modified) {
546                 goto done;
547         }
548
549         data = unparse_share_modes(lck);
550
551         if (data.dptr == NULL) {
552                 if (!lck->fresh) {
553                         /* There has been an entry before, delete it */
554                         if (tdb_delete(tdb, key) == -1) {
555                                 smb_panic("Could not delete share entry\n");
556                         }
557                 }
558                 goto done;
559         }
560
561         if (tdb_store(tdb, key, data, TDB_REPLACE) == -1) {
562                 smb_panic("Could not store share mode entry\n");
563         }
564
565  done:
566         tdb_chainunlock(tdb, key);
567
568         return 0;
569 }
570
571 struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
572                                             SMB_DEV_T dev, SMB_INO_T ino,
573                                             const char *fname)
574 {
575         struct share_mode_lock *lck;
576         TDB_DATA key = locking_key(dev, ino);
577         TDB_DATA data;
578
579         lck = TALLOC_P(mem_ctx, struct share_mode_lock);
580         if (lck == NULL) {
581                 DEBUG(0, ("talloc failed\n"));
582                 return NULL;
583         }
584
585         lck->dev = dev;
586         lck->ino = ino;
587         lck->delete_on_close = False;
588         lck->num_share_modes = 0;
589         lck->share_modes = NULL;
590         lck->modified = False;
591
592         if (tdb_chainlock(tdb, key) != 0) {
593                 DEBUG(3, ("Could not lock share entry\n"));
594                 talloc_free(lck);
595                 return NULL;
596         }
597
598         data = tdb_fetch(tdb, key);
599         lck->fresh = (data.dptr == NULL);
600
601         if (lck->fresh) {
602                 if (fname == NULL) {
603                         DEBUG(0, ("New file, but no filename supplied\n"));
604                         talloc_free(lck);
605                         return NULL;
606                 }
607                 lck->filename = talloc_strdup(lck, fname);
608                 if (lck->filename == NULL) {
609                         DEBUG(0, ("talloc failed\n"));
610                         talloc_free(lck);
611                         return NULL;
612                 }
613         } else {
614                 if (!parse_share_modes(data, lck)) {
615                         DEBUG(0, ("Could not parse share modes\n"));
616                         talloc_free(lck);
617                         SAFE_FREE(data.dptr);
618                         return NULL;
619                 }
620         }
621
622         talloc_set_destructor(lck, share_mode_lock_destructor);
623         SAFE_FREE(data.dptr);
624
625         return lck;
626 }
627
628 BOOL get_delete_on_close_flag(SMB_DEV_T dev, SMB_INO_T inode,
629                               const char *fname)
630 {
631         BOOL result;
632         struct share_mode_lock *lck = get_share_mode_lock(NULL, dev, inode,
633                                                           fname);
634         result = lck->delete_on_close;
635         talloc_free(lck);
636         return result;
637 }
638
639 BOOL is_valid_share_mode_entry(const struct share_mode_entry *e)
640 {
641         int num_props = 0;
642
643         num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
644         num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
645         num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
646
647         SMB_ASSERT(num_props <= 1);
648         return (num_props != 0);
649 }
650
651 BOOL is_deferred_open_entry(const struct share_mode_entry *e)
652 {
653         return (e->op_type == DEFERRED_OPEN_ENTRY);
654 }
655
656 BOOL is_unused_share_mode_entry(const struct share_mode_entry *e)
657 {
658         return (e->op_type == UNUSED_SHARE_MODE_ENTRY);
659 }
660
661 /*******************************************************************
662  Fill a share mode entry.
663 ********************************************************************/
664
665 static void fill_share_mode_entry(struct share_mode_entry *e,
666                                   files_struct *fsp,
667                                   uint16 mid, uint16 op_type)
668 {
669         ZERO_STRUCTP(e);
670         e->pid = procid_self();
671         e->share_access = fsp->share_access;
672         e->private_options = fsp->fh->private_options;
673         e->access_mask = fsp->access_mask;
674         e->op_mid = mid;
675         e->op_type = op_type;
676         e->time.tv_sec = fsp->open_time.tv_sec;
677         e->time.tv_usec = fsp->open_time.tv_usec;
678         e->share_file_id = fsp->file_id;
679         e->dev = fsp->dev;
680         e->inode = fsp->inode;
681 }
682
683 static void fill_deferred_open_entry(struct share_mode_entry *e,
684                                      const struct timeval request_time,
685                                      SMB_DEV_T dev, SMB_INO_T ino, uint16 mid)
686 {
687         ZERO_STRUCTP(e);
688         e->pid = procid_self();
689         e->op_mid = mid;
690         e->op_type = DEFERRED_OPEN_ENTRY;
691         e->time.tv_sec = request_time.tv_sec;
692         e->time.tv_usec = request_time.tv_usec;
693         e->dev = dev;
694         e->inode = ino;
695 }
696
697 static void add_share_mode_entry(struct share_mode_lock *lck,
698                                  const struct share_mode_entry *entry)
699 {
700         int i;
701
702         for (i=0; i<lck->num_share_modes; i++) {
703                 struct share_mode_entry *e = &lck->share_modes[i];
704                 if (is_unused_share_mode_entry(e)) {
705                         *e = *entry;
706                         break;
707                 }
708         }
709
710         if (i == lck->num_share_modes) {
711                 /* No unused entry found */
712                 ADD_TO_ARRAY(lck, struct share_mode_entry, *entry,
713                              &lck->share_modes, &lck->num_share_modes);
714         }
715         lck->modified = True;
716 }
717
718 void set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
719                     uint16 mid, uint16 op_type)
720 {
721         struct share_mode_entry entry;
722         fill_share_mode_entry(&entry, fsp, mid, op_type);
723         add_share_mode_entry(lck, &entry);
724 }
725
726 void add_deferred_open(struct share_mode_lock *lck, uint16 mid,
727                        struct timeval request_time,
728                        SMB_DEV_T dev, SMB_INO_T ino)
729 {
730         struct share_mode_entry entry;
731         fill_deferred_open_entry(&entry, request_time, dev, ino, mid);
732         add_share_mode_entry(lck, &entry);
733 }
734
735 /*******************************************************************
736  Check if two share mode entries are identical, ignoring oplock 
737  and mid info and desired_access.
738 ********************************************************************/
739
740 static BOOL share_modes_identical(struct share_mode_entry *e1,
741                                   struct share_mode_entry *e2)
742 {
743 #if 1 /* JRA PARANOIA TEST - REMOVE LATER */
744         if (procid_equal(&e1->pid, &e2->pid) &&
745             e1->share_file_id == e2->share_file_id &&
746             e1->dev == e2->dev &&
747             e1->inode == e2->inode &&
748             (e1->share_access) != (e2->share_access)) {
749                 DEBUG(0,("PANIC: share_modes_identical: share_mode "
750                          "mismatch (e1 = 0x%x, e2 = 0x%x). Logic error.\n",
751                          (unsigned int)e1->share_access,
752                          (unsigned int)e2->share_access ));
753                 smb_panic("PANIC: share_modes_identical logic error.\n");
754         }
755 #endif
756
757         return (procid_equal(&e1->pid, &e2->pid) &&
758                 (e1->share_access) == (e2->share_access) &&
759                 e1->dev == e2->dev &&
760                 e1->inode == e2->inode &&
761                 e1->share_file_id == e2->share_file_id );
762 }
763
764 static BOOL deferred_open_identical(struct share_mode_entry *e1,
765                                     struct share_mode_entry *e2)
766 {
767         return (procid_equal(&e1->pid, &e2->pid) &&
768                 (e1->op_mid == e2->op_mid) &&
769                 (e1->dev == e2->dev) &&
770                 (e1->inode == e2->inode));
771 }
772
773 static struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck,
774                                                       struct share_mode_entry *entry)
775 {
776         int i;
777
778         for (i=0; i<lck->num_share_modes; i++) {
779                 struct share_mode_entry *e = &lck->share_modes[i];
780                 if (is_valid_share_mode_entry(entry) &&
781                     is_valid_share_mode_entry(e) &&
782                     share_modes_identical(e, entry)) {
783                         return e;
784                 }
785                 if (is_deferred_open_entry(entry) &&
786                     is_deferred_open_entry(e) &&
787                     deferred_open_identical(e, entry)) {
788                         return e;
789                 }
790         }
791         return NULL;
792 }
793
794 /*******************************************************************
795  Del the share mode of a file for this process. Return the number of
796  entries left.
797 ********************************************************************/
798
799 BOOL del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
800 {
801         struct share_mode_entry entry, *e;
802
803         fill_share_mode_entry(&entry, fsp, 0, 0);
804
805         e = find_share_mode_entry(lck, &entry);
806         if (e == NULL) {
807                 return False;
808         }
809
810         e->op_type = UNUSED_SHARE_MODE_ENTRY;
811         lck->modified = True;
812         return True;
813 }
814
815 void del_deferred_open_entry(struct share_mode_lock *lck, uint16 mid)
816 {
817         struct share_mode_entry entry, *e;
818
819         fill_deferred_open_entry(&entry, timeval_zero(),
820                                  lck->dev, lck->ino, mid);
821
822         e = find_share_mode_entry(lck, &entry);
823         if (e == NULL) {
824                 return;
825         }
826
827         e->op_type = UNUSED_SHARE_MODE_ENTRY;
828         lck->modified = True;
829 }
830
831 /*******************************************************************
832  Remove an oplock mid and mode entry from a share mode.
833 ********************************************************************/
834
835 BOOL remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
836 {
837         struct share_mode_entry entry, *e;
838
839         fill_share_mode_entry(&entry, fsp, 0, 0);
840
841         e = find_share_mode_entry(lck, &entry);
842         if (e == NULL) {
843                 return False;
844         }
845
846         e->op_mid = 0;
847         e->op_type = NO_OPLOCK;
848         lck->modified = True;
849         return True;
850 }
851
852 /*******************************************************************
853  Downgrade a oplock type from exclusive to level II.
854 ********************************************************************/
855
856 BOOL downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
857 {
858         struct share_mode_entry entry, *e;
859
860         fill_share_mode_entry(&entry, fsp, 0, 0);
861
862         e = find_share_mode_entry(lck, &entry);
863         if (e == NULL) {
864                 return False;
865         }
866
867         e->op_type = LEVEL_II_OPLOCK;
868         lck->modified = True;
869         return True;
870 }
871
872
873 /*******************************************************************
874  We've just told all the smbd's that our level2 or fake level2 has been
875  written to.
876 ********************************************************************/
877 BOOL remove_all_share_oplocks(struct share_mode_lock *lck, files_struct *fsp)
878 {
879         int i;
880         for (i=0; i<lck->num_share_modes; i++) {
881                 struct share_mode_entry *e = &lck->share_modes[i];
882                 if (!is_valid_share_mode_entry(e)) {
883                         continue;
884                 }
885                 if (e->op_type == NO_OPLOCK) {
886                         continue;
887                 }
888                 e->op_type = NO_OPLOCK;
889                 lck->modified = True;
890         }
891         return True;
892 }
893
894 /****************************************************************************
895  Deal with the internal needs of setting the delete on close flag. Note that
896  as the tdb locking is recursive, it is safe to call this from within 
897  open_file_shared. JRA.
898 ****************************************************************************/
899
900 NTSTATUS can_set_delete_on_close(files_struct *fsp, BOOL delete_on_close,
901                                  uint32 dosmode)
902 {
903         if (!delete_on_close) {
904                 return NT_STATUS_OK;
905         }
906
907         /*
908          * Only allow delete on close for writable files.
909          */
910
911         if ((dosmode & aRONLY) &&
912             !lp_delete_readonly(SNUM(fsp->conn))) {
913                 DEBUG(10,("can_set_delete_on_close: file %s delete on close "
914                           "flag set but file attribute is readonly.\n",
915                           fsp->fsp_name ));
916                 return NT_STATUS_CANNOT_DELETE;
917         }
918
919         /*
920          * Only allow delete on close for writable shares.
921          */
922
923         if (!CAN_WRITE(fsp->conn)) {
924                 DEBUG(10,("can_set_delete_on_close: file %s delete on "
925                           "close flag set but write access denied on share.\n",
926                           fsp->fsp_name ));
927                 return NT_STATUS_ACCESS_DENIED;
928         }
929
930         /*
931          * Only allow delete on close for files/directories opened with delete
932          * intent.
933          */
934
935         if (!(fsp->access_mask & DELETE_ACCESS)) {
936                 DEBUG(10,("can_set_delete_on_close: file %s delete on "
937                           "close flag set but delete access denied.\n",
938                           fsp->fsp_name ));
939                 return NT_STATUS_ACCESS_DENIED;
940         }
941
942         return NT_STATUS_OK;
943 }
944
945 /****************************************************************************
946  Sets the delete on close flag over all share modes on this file.
947  Modify the share mode entry for all files open
948  on this device and inode to tell other smbds we have
949  changed the delete on close flag. This will be noticed
950  in the close code, the last closer will delete the file
951  if flag is set.
952 ****************************************************************************/
953
954 BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close)
955 {
956         struct share_mode_lock *lck;
957         
958         DEBUG(10,("set_delete_on_close: %s delete on close flag for "
959                   "fnum = %d, file %s\n",
960                   delete_on_close ? "Adding" : "Removing", fsp->fnum,
961                   fsp->fsp_name ));
962
963         if (fsp->is_directory || fsp->is_stat)
964                 return True;
965
966         lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL);
967         if (lck == NULL) {
968                 return False;
969         }
970         if (lck->delete_on_close != delete_on_close) {
971                 lck->delete_on_close = delete_on_close;
972                 lck->modified = True;
973         }
974
975         talloc_free(lck);
976         return True;
977 }
978
979 static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, 
980                        void *state)
981 {
982         struct locking_data *data;
983         struct share_mode_entry *shares;
984         char *name;
985         int i;
986         void (*traverse_callback)(struct share_mode_entry *, char *) = state;
987
988         /* Ensure this is a locking_key record. */
989         if (kbuf.dsize != sizeof(struct locking_key))
990                 return 0;
991
992         data = (struct locking_data *)dbuf.dptr;
993         shares = (struct share_mode_entry *)(dbuf.dptr + sizeof(*data));
994         name = dbuf.dptr + sizeof(*data) +
995                 data->u.s.num_share_mode_entries*sizeof(*shares);
996
997         for (i=0;i<data->u.s.num_share_mode_entries;i++) {
998                 traverse_callback(&shares[i], name);
999         }
1000         return 0;
1001 }
1002
1003 /*******************************************************************
1004  Call the specified function on each entry under management by the
1005  share mode system.
1006 ********************************************************************/
1007
1008 int share_mode_forall(void (*fn)(const struct share_mode_entry *, char *))
1009 {
1010         if (tdb == NULL)
1011                 return 0;
1012         return tdb_traverse(tdb, traverse_fn, fn);
1013 }