r10909: Give better shutdown messages
[Samba/nascimento.git] / source3 / locking / locking.c
blobe3131e26a2a4da688a5aabeae9a8655fe7e767aa
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
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.
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.
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.
22 Revision History:
24 12 aug 96: Erik.Devriendt@te6.siemens.be
25 added support for shared memory implementation of share mode locking
27 May 1997. Jeremy Allison (jallison@whistle.com). Modified share mode
28 locking to deal with multiple share modes per open file.
30 September 1997. Jeremy Allison (jallison@whistle.com). Added oplock
31 support.
33 rewrtten completely to use new tdb code. Tridge, Dec '99
35 Added POSIX locking support. Jeremy Allison (jeremy@valinux.com), Apr. 2000.
38 #include "includes.h"
39 uint16 global_smbpid;
41 #undef DBGC_CLASS
42 #define DBGC_CLASS DBGC_LOCKING
44 /* the locking database handle */
45 static TDB_CONTEXT *tdb;
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[];
61 /****************************************************************************
62 Debugging aid :-).
63 ****************************************************************************/
65 static const char *lock_type_name(enum brl_type lock_type)
67 return (lock_type == READ_LOCK) ? "READ" : "WRITE";
70 /****************************************************************************
71 Utility function called to see if a file region is locked.
72 ****************************************************************************/
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)
78 int snum = SNUM(conn);
79 int strict_locking = lp_strict_locking(snum);
80 BOOL ret;
82 if (count == 0)
83 return(False);
85 if (!lp_locking(snum) || !strict_locking)
86 return(False);
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);
101 } else {
102 ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum,
103 global_smbpid, procid_self(), conn->cnum,
104 offset, count, lock_type);
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 ));
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.
116 if(!ret && lp_posix_locking(snum)) {
117 ret = is_posix_locked(fsp, offset, count, lock_type);
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 ));
124 return ret;
127 /****************************************************************************
128 Utility function called by locking requests.
129 ****************************************************************************/
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)
134 NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED;
136 if (!lp_locking(SNUM(conn)))
137 return NT_STATUS_OK;
139 /* NOTE! 0 byte long ranges ARE allowed and should be stored */
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 ));
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);
150 if (NT_STATUS_IS_OK(status) && lp_posix_locking(SNUM(conn))) {
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.
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);
165 * We failed to map - we must now remove the brl
166 * lock entry.
168 (void)brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
169 lock_pid, procid_self(), conn->cnum,
170 offset, count, False,
171 NULL, NULL);
176 return status;
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 ****************************************************************************/
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)
189 int j, maxj = lp_lock_spin_count();
190 int sleeptime = lp_lock_sleep_time();
191 NTSTATUS status, ret;
193 if (maxj <= 0)
194 maxj = 1;
196 ret = NT_STATUS_OK; /* to keep dumb compilers happy */
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;
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;
211 if (sleeptime)
212 sys_usleep(sleeptime);
214 return ret;
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;
224 /****************************************************************************
225 Function passed to brl_unlock to allow POSIX unlock to be done first.
226 ****************************************************************************/
228 static void posix_unlock(void *pre_data)
230 struct posix_unlock_data_struct *pdata = (struct posix_unlock_data_struct *)pre_data;
232 if (lp_posix_locking(SNUM(pdata->fsp->conn)))
233 release_posix_lock(pdata->fsp, pdata->offset, pdata->count);
236 /****************************************************************************
237 Utility function called by unlocking requests.
238 ****************************************************************************/
240 NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
241 SMB_BIG_UINT count,SMB_BIG_UINT offset)
243 BOOL ok = False;
244 struct posix_unlock_data_struct posix_data;
246 if (!lp_locking(SNUM(conn)))
247 return NT_STATUS_OK;
249 if (!OPEN_FSP(fsp) || !fsp->can_lock || (fsp->conn != conn)) {
250 return NT_STATUS_INVALID_HANDLE;
253 DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for file %s\n",
254 (double)offset, (double)count, fsp->fsp_name ));
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.
262 posix_data.fsp = fsp;
263 posix_data.offset = offset;
264 posix_data.count = count;
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);
270 if (!ok) {
271 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
272 return NT_STATUS_RANGE_NOT_LOCKED;
274 return NT_STATUS_OK;
277 /****************************************************************************
278 Remove any locks on this fd. Called from file_close().
279 ****************************************************************************/
281 void locking_close_file(files_struct *fsp)
283 struct process_id pid = procid_self();
285 if (!lp_locking(SNUM(fsp->conn)))
286 return;
289 * Just release all the brl locks, no need to release individually.
292 brl_close(fsp->dev, fsp->inode, pid, fsp->conn->cnum, fsp->fnum);
294 if(lp_posix_locking(SNUM(fsp->conn))) {
297 * Release all the POSIX locks.
299 posix_locking_close_file(fsp);
304 /****************************************************************************
305 Initialise the locking functions.
306 ****************************************************************************/
308 static int open_read_only;
310 BOOL locking_init(int read_only)
312 brl_init(read_only);
314 if (tdb)
315 return True;
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);
322 if (!tdb) {
323 DEBUG(0,("ERROR: Failed to initialise locking database\n"));
324 return False;
327 if (!posix_locking_init(read_only))
328 return False;
330 open_read_only = read_only;
332 return True;
335 /*******************************************************************
336 Deinitialize the share_mode management.
337 ******************************************************************/
339 BOOL locking_end(void)
341 BOOL ret = True;
343 brl_shutdown(open_read_only);
344 if (tdb) {
345 if (tdb_close(tdb) != 0)
346 ret = False;
349 return ret;
352 /*******************************************************************
353 Form a static locking key for a dev/inode pair.
354 ******************************************************************/
356 /* key and data records in the tdb locking database */
357 struct locking_key {
358 SMB_DEV_T dev;
359 SMB_INO_T ino;
362 /*******************************************************************
363 Form a static locking key for a dev/inode pair.
364 ******************************************************************/
366 static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode)
368 static struct locking_key key;
369 TDB_DATA kbuf;
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;
379 /*******************************************************************
380 Print out a share mode.
381 ********************************************************************/
383 char *share_mode_str(int num, struct share_mode_entry *e)
385 static pstring share_str;
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 );
396 return share_str;
399 /*******************************************************************
400 Print out a share mode table.
401 ********************************************************************/
403 static void print_share_mode_table(struct locking_data *data)
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;
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)));
417 /*******************************************************************
418 Get all share mode entries for a dev/inode pair.
419 ********************************************************************/
421 static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck)
423 struct locking_data *data;
424 int i;
426 if (dbuf.dsize < sizeof(struct locking_data)) {
427 DEBUG(0, ("parse_share_modes: buffer too short\n"));
428 return False;
431 data = (struct locking_data *)dbuf.dptr;
433 lck->delete_on_close = data->u.s.delete_on_close;
434 lck->num_share_modes = data->u.s.num_share_mode_entries;
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));
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;
446 lck->share_modes = NULL;
448 if (lck->num_share_modes != 0) {
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;
457 lck->share_modes = talloc_memdup(lck, dbuf.dptr+sizeof(*data),
458 lck->num_share_modes *
459 sizeof(struct share_mode_entry));
461 if (lck->share_modes == NULL) {
462 DEBUG(0, ("talloc failed\n"));
463 return False;
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));
473 * Ensure that each entry has a real process attached.
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;
488 return True;
491 static TDB_DATA unparse_share_modes(struct share_mode_lock *lck)
493 TDB_DATA result;
494 int num_valid = 0;
495 int i;
496 struct locking_data *data;
497 ssize_t offset;
499 result.dptr = NULL;
500 result.dsize = 0;
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;
508 if (num_valid == 0) {
509 return result;
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);
517 if (result.dptr == NULL) {
518 smb_panic("talloc failed\n");
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;
538 static int share_mode_lock_destructor(void *p)
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;
545 if (!lck->modified) {
546 goto done;
549 data = unparse_share_modes(lck);
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");
558 goto done;
561 if (tdb_store(tdb, key, data, TDB_REPLACE) == -1) {
562 smb_panic("Could not store share mode entry\n");
565 done:
566 tdb_chainunlock(tdb, key);
568 return 0;
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)
575 struct share_mode_lock *lck;
576 TDB_DATA key = locking_key(dev, ino);
577 TDB_DATA data;
579 lck = TALLOC_P(mem_ctx, struct share_mode_lock);
580 if (lck == NULL) {
581 DEBUG(0, ("talloc failed\n"));
582 return NULL;
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;
592 if (tdb_chainlock(tdb, key) != 0) {
593 DEBUG(3, ("Could not lock share entry\n"));
594 talloc_free(lck);
595 return NULL;
598 data = tdb_fetch(tdb, key);
599 lck->fresh = (data.dptr == NULL);
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;
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;
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;
622 talloc_set_destructor(lck, share_mode_lock_destructor);
623 SAFE_FREE(data.dptr);
625 return lck;
628 BOOL get_delete_on_close_flag(SMB_DEV_T dev, SMB_INO_T inode,
629 const char *fname)
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;
639 BOOL is_valid_share_mode_entry(const struct share_mode_entry *e)
641 int num_props = 0;
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);
647 SMB_ASSERT(num_props <= 1);
648 return (num_props != 0);
651 BOOL is_deferred_open_entry(const struct share_mode_entry *e)
653 return (e->op_type == DEFERRED_OPEN_ENTRY);
656 BOOL is_unused_share_mode_entry(const struct share_mode_entry *e)
658 return (e->op_type == UNUSED_SHARE_MODE_ENTRY);
661 /*******************************************************************
662 Fill a share mode entry.
663 ********************************************************************/
665 static void fill_share_mode_entry(struct share_mode_entry *e,
666 files_struct *fsp,
667 uint16 mid, uint16 op_type)
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;
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)
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;
697 static void add_share_mode_entry(struct share_mode_lock *lck,
698 const struct share_mode_entry *entry)
700 int i;
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;
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);
715 lck->modified = True;
718 void set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
719 uint16 mid, uint16 op_type)
721 struct share_mode_entry entry;
722 fill_share_mode_entry(&entry, fsp, mid, op_type);
723 add_share_mode_entry(lck, &entry);
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)
730 struct share_mode_entry entry;
731 fill_deferred_open_entry(&entry, request_time, dev, ino, mid);
732 add_share_mode_entry(lck, &entry);
735 /*******************************************************************
736 Check if two share mode entries are identical, ignoring oplock
737 and mid info and desired_access.
738 ********************************************************************/
740 static BOOL share_modes_identical(struct share_mode_entry *e1,
741 struct share_mode_entry *e2)
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");
755 #endif
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 );
764 static BOOL deferred_open_identical(struct share_mode_entry *e1,
765 struct share_mode_entry *e2)
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));
773 static struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck,
774 struct share_mode_entry *entry)
776 int i;
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;
785 if (is_deferred_open_entry(entry) &&
786 is_deferred_open_entry(e) &&
787 deferred_open_identical(e, entry)) {
788 return e;
791 return NULL;
794 /*******************************************************************
795 Del the share mode of a file for this process. Return the number of
796 entries left.
797 ********************************************************************/
799 BOOL del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
801 struct share_mode_entry entry, *e;
803 fill_share_mode_entry(&entry, fsp, 0, 0);
805 e = find_share_mode_entry(lck, &entry);
806 if (e == NULL) {
807 return False;
810 e->op_type = UNUSED_SHARE_MODE_ENTRY;
811 lck->modified = True;
812 return True;
815 void del_deferred_open_entry(struct share_mode_lock *lck, uint16 mid)
817 struct share_mode_entry entry, *e;
819 fill_deferred_open_entry(&entry, timeval_zero(),
820 lck->dev, lck->ino, mid);
822 e = find_share_mode_entry(lck, &entry);
823 if (e == NULL) {
824 return;
827 e->op_type = UNUSED_SHARE_MODE_ENTRY;
828 lck->modified = True;
831 /*******************************************************************
832 Remove an oplock mid and mode entry from a share mode.
833 ********************************************************************/
835 BOOL remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
837 struct share_mode_entry entry, *e;
839 fill_share_mode_entry(&entry, fsp, 0, 0);
841 e = find_share_mode_entry(lck, &entry);
842 if (e == NULL) {
843 return False;
846 e->op_mid = 0;
847 e->op_type = NO_OPLOCK;
848 lck->modified = True;
849 return True;
852 /*******************************************************************
853 Downgrade a oplock type from exclusive to level II.
854 ********************************************************************/
856 BOOL downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
858 struct share_mode_entry entry, *e;
860 fill_share_mode_entry(&entry, fsp, 0, 0);
862 e = find_share_mode_entry(lck, &entry);
863 if (e == NULL) {
864 return False;
867 e->op_type = LEVEL_II_OPLOCK;
868 lck->modified = True;
869 return True;
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)
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;
885 if (e->op_type == NO_OPLOCK) {
886 continue;
888 e->op_type = NO_OPLOCK;
889 lck->modified = True;
891 return True;
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 ****************************************************************************/
900 NTSTATUS can_set_delete_on_close(files_struct *fsp, BOOL delete_on_close,
901 uint32 dosmode)
903 if (!delete_on_close) {
904 return NT_STATUS_OK;
908 * Only allow delete on close for writable files.
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;
920 * Only allow delete on close for writable shares.
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;
931 * Only allow delete on close for files/directories opened with delete
932 * intent.
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;
942 return NT_STATUS_OK;
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 ****************************************************************************/
954 BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close)
956 struct share_mode_lock *lck;
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 ));
963 if (fsp->is_directory || fsp->is_stat)
964 return True;
966 lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL);
967 if (lck == NULL) {
968 return False;
970 if (lck->delete_on_close != delete_on_close) {
971 lck->delete_on_close = delete_on_close;
972 lck->modified = True;
975 talloc_free(lck);
976 return True;
979 static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
980 void *state)
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;
988 /* Ensure this is a locking_key record. */
989 if (kbuf.dsize != sizeof(struct locking_key))
990 return 0;
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);
997 for (i=0;i<data->u.s.num_share_mode_entries;i++) {
998 traverse_callback(&shares[i], name);
1000 return 0;
1003 /*******************************************************************
1004 Call the specified function on each entry under management by the
1005 share mode system.
1006 ********************************************************************/
1008 int share_mode_forall(void (*fn)(const struct share_mode_entry *, char *))
1010 if (tdb == NULL)
1011 return 0;
1012 return tdb_traverse(tdb, traverse_fn, fn);