2 Unix SMB/CIFS implementation.
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.
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
33 rewrtten completely to use new tdb code. Tridge, Dec '99
35 Added POSIX locking support. Jeremy Allison (jeremy@valinux.com), Apr. 2000.
42 #define DBGC_CLASS DBGC_LOCKING
44 /* the locking database handle */
45 static TDB_CONTEXT *tdb;
50 int num_share_mode_entries;
53 struct share_mode_entry dummy; /* Needed for alignment. */
55 /* the following two entries are implicit
56 struct share_mode_entry modes[num_share_mode_entries];
61 /****************************************************************************
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);
85 if (!lp_locking(snum) || !strict_locking)
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 ));
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 ));
97 ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum,
98 global_smbpid, procid_self(), conn->cnum,
99 offset, count, lock_type);
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",
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",
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)))
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,
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;
162 status = map_nt_error_from_unix(errno);
165 * We failed to map - we must now remove the brl
168 (void)brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
169 lock_pid, procid_self(), conn->cnum,
170 offset, count, False,
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;
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)) {
204 /* if we do fail then return the first error code we got */
207 /* Don't spin if we blocked ourselves. */
212 sys_usleep(sleeptime);
217 /* Struct passed to brl_unlock. */
218 struct posix_unlock_data_struct {
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)
244 struct posix_unlock_data_struct posix_data;
246 if (!lp_locking(SNUM(conn)))
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);
271 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
272 return NT_STATUS_RANGE_NOT_LOCKED;
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)))
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)
317 tdb = tdb_open_log(lock_path("locking.tdb"),
318 SMB_OPEN_DATABASE_TDB_HASH_SIZE, TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST),
319 read_only?O_RDONLY:O_RDWR|O_CREAT,
323 DEBUG(0,("ERROR: Failed to initialise locking database\n"));
327 if (!posix_locking_init(read_only))
330 open_read_only = read_only;
335 /*******************************************************************
336 Deinitialize the share_mode management.
337 ******************************************************************/
339 BOOL locking_end(void)
343 brl_shutdown(open_read_only);
345 if (tdb_close(tdb) != 0)
352 /*******************************************************************
353 Form a static locking key for a dev/inode pair.
354 ******************************************************************/
356 /* key and data records in the tdb locking database */
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;
371 memset(&key, '\0', sizeof(key));
374 kbuf.dptr = (char *)&key;
375 kbuf.dsize = sizeof(key);
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]: %s "
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",
392 e->op_type == UNUSED_SHARE_MODE_ENTRY ? "UNUSED" : "",
393 procid_str_static(&e->pid),
394 e->share_access, e->private_options,
395 e->access_mask, e->op_mid, e->op_type, e->share_file_id,
396 (unsigned int)e->dev, (double)e->inode );
401 /*******************************************************************
402 Print out a share mode table.
403 ********************************************************************/
405 static void print_share_mode_table(struct locking_data *data)
407 int num_share_modes = data->u.s.num_share_mode_entries;
408 struct share_mode_entry *shares =
409 (struct share_mode_entry *)(data + 1);
412 for (i = 0; i < num_share_modes; i++) {
413 struct share_mode_entry entry;
415 memcpy(&entry, &shares[i], sizeof(struct share_mode_entry));
416 DEBUG(10,("print_share_mode_table: %s\n",
417 share_mode_str(i, &entry)));
421 /*******************************************************************
422 Get all share mode entries for a dev/inode pair.
423 ********************************************************************/
425 static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck)
427 struct locking_data *data;
430 if (dbuf.dsize < sizeof(struct locking_data)) {
431 DEBUG(0, ("parse_share_modes: buffer too short\n"));
435 data = (struct locking_data *)dbuf.dptr;
437 lck->delete_on_close = data->u.s.delete_on_close;
438 lck->num_share_modes = data->u.s.num_share_mode_entries;
440 DEBUG(10, ("parse_share_modes: delete_on_close: %d, "
441 "num_share_modes: %d\n", lck->delete_on_close,
442 lck->num_share_modes));
444 if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) {
445 DEBUG(0, ("invalid number of share modes: %d\n",
446 lck->num_share_modes));
450 lck->share_modes = NULL;
452 if (lck->num_share_modes != 0) {
454 if (dbuf.dsize < (sizeof(struct locking_data) +
455 (lck->num_share_modes *
456 sizeof(struct share_mode_entry)))) {
457 DEBUG(0, ("parse_share_modes: buffer too short\n"));
461 lck->share_modes = talloc_memdup(lck, dbuf.dptr+sizeof(*data),
462 lck->num_share_modes *
463 sizeof(struct share_mode_entry));
465 if (lck->share_modes == NULL) {
466 DEBUG(0, ("talloc failed\n"));
471 /* Save off the associated service path and filename. */
472 lck->servicepath = talloc_strdup(lck, dbuf.dptr + sizeof(*data) +
473 (lck->num_share_modes *
474 sizeof(struct share_mode_entry)));
476 lck->filename = talloc_strdup(lck, dbuf.dptr + sizeof(*data) +
477 (lck->num_share_modes *
478 sizeof(struct share_mode_entry)) +
479 strlen(lck->servicepath) + 1 );
482 * Ensure that each entry has a real process attached.
485 for (i = 0; i < lck->num_share_modes; i++) {
486 struct share_mode_entry *entry_p = &lck->share_modes[i];
487 DEBUG(10,("parse_share_modes: %s\n",
488 share_mode_str(i, entry_p) ));
489 if (!process_exists(entry_p->pid)) {
490 DEBUG(10,("parse_share_modes: deleted %s\n",
491 share_mode_str(i, entry_p) ));
492 entry_p->op_type = UNUSED_SHARE_MODE_ENTRY;
493 lck->modified = True;
500 static TDB_DATA unparse_share_modes(struct share_mode_lock *lck)
505 struct locking_data *data;
512 for (i=0; i<lck->num_share_modes; i++) {
513 if (!is_unused_share_mode_entry(&lck->share_modes[i])) {
518 if (num_valid == 0) {
522 sp_len = strlen(lck->servicepath);
524 result.dsize = sizeof(*data) +
525 lck->num_share_modes * sizeof(struct share_mode_entry) +
527 strlen(lck->filename) + 1;
528 result.dptr = talloc_size(lck, result.dsize);
530 if (result.dptr == NULL) {
531 smb_panic("talloc failed\n");
534 data = (struct locking_data *)result.dptr;
536 data->u.s.num_share_mode_entries = lck->num_share_modes;
537 data->u.s.delete_on_close = lck->delete_on_close;
538 DEBUG(10, ("unparse_share_modes: del: %d, num: %d\n",
539 data->u.s.delete_on_close,
540 data->u.s.num_share_mode_entries));
541 memcpy(result.dptr + sizeof(*data), lck->share_modes,
542 sizeof(struct share_mode_entry)*lck->num_share_modes);
543 offset = sizeof(*data) +
544 sizeof(struct share_mode_entry)*lck->num_share_modes;
545 safe_strcpy(result.dptr + offset, lck->servicepath,
546 result.dsize - offset - 1);
547 offset += sp_len + 1;
548 safe_strcpy(result.dptr + offset, lck->filename,
549 result.dsize - offset - 1);
551 if (DEBUGLEVEL >= 10) {
552 print_share_mode_table(data);
558 static int share_mode_lock_destructor(void *p)
560 struct share_mode_lock *lck =
561 talloc_get_type_abort(p, struct share_mode_lock);
562 TDB_DATA key = locking_key(lck->dev, lck->ino);
565 if (!lck->modified) {
569 data = unparse_share_modes(lck);
571 if (data.dptr == NULL) {
573 /* There has been an entry before, delete it */
574 if (tdb_delete(tdb, key) == -1) {
575 smb_panic("Could not delete share entry\n");
581 if (tdb_store(tdb, key, data, TDB_REPLACE) == -1) {
582 smb_panic("Could not store share mode entry\n");
586 tdb_chainunlock(tdb, key);
591 struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
592 SMB_DEV_T dev, SMB_INO_T ino,
593 const char *servicepath,
596 struct share_mode_lock *lck;
597 TDB_DATA key = locking_key(dev, ino);
600 lck = TALLOC_P(mem_ctx, struct share_mode_lock);
602 DEBUG(0, ("talloc failed\n"));
606 /* Ensure we set every field here as the destructor must be
607 valid even if parse_share_modes fails. */
609 lck->servicepath = NULL;
610 lck->filename = NULL;
613 lck->num_share_modes = 0;
614 lck->share_modes = NULL;
615 lck->delete_on_close = False;
617 lck->modified = False;
619 if (tdb_chainlock(tdb, key) != 0) {
620 DEBUG(3, ("Could not lock share entry\n"));
625 /* We must set the destructor immediately after the chainlock
626 ensure the lock is cleaned up on any of the error return
629 talloc_set_destructor(lck, share_mode_lock_destructor);
631 data = tdb_fetch(tdb, key);
632 lck->fresh = (data.dptr == NULL);
636 if (fname == NULL || servicepath == NULL) {
640 lck->filename = talloc_strdup(lck, fname);
641 lck->servicepath = talloc_strdup(lck, servicepath);
642 if (lck->filename == NULL || lck->servicepath == NULL) {
643 DEBUG(0, ("talloc failed\n"));
648 if (!parse_share_modes(data, lck)) {
649 DEBUG(0, ("Could not parse share modes\n"));
651 SAFE_FREE(data.dptr);
656 SAFE_FREE(data.dptr);
661 BOOL get_delete_on_close_flag(SMB_DEV_T dev, SMB_INO_T inode,
665 struct share_mode_lock *lck = get_share_mode_lock(NULL, dev, inode, NULL, NULL);
669 result = lck->delete_on_close;
674 BOOL is_valid_share_mode_entry(const struct share_mode_entry *e)
678 num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
679 num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
680 num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
682 SMB_ASSERT(num_props <= 1);
683 return (num_props != 0);
686 BOOL is_deferred_open_entry(const struct share_mode_entry *e)
688 return (e->op_type == DEFERRED_OPEN_ENTRY);
691 BOOL is_unused_share_mode_entry(const struct share_mode_entry *e)
693 return (e->op_type == UNUSED_SHARE_MODE_ENTRY);
696 /*******************************************************************
697 Fill a share mode entry.
698 ********************************************************************/
700 static void fill_share_mode_entry(struct share_mode_entry *e,
702 uint16 mid, uint16 op_type)
705 e->pid = procid_self();
706 e->share_access = fsp->share_access;
707 e->private_options = fsp->fh->private_options;
708 e->access_mask = fsp->access_mask;
710 e->op_type = op_type;
711 e->time.tv_sec = fsp->open_time.tv_sec;
712 e->time.tv_usec = fsp->open_time.tv_usec;
713 e->share_file_id = fsp->file_id;
715 e->inode = fsp->inode;
718 static void fill_deferred_open_entry(struct share_mode_entry *e,
719 const struct timeval request_time,
720 SMB_DEV_T dev, SMB_INO_T ino, uint16 mid)
723 e->pid = procid_self();
725 e->op_type = DEFERRED_OPEN_ENTRY;
726 e->time.tv_sec = request_time.tv_sec;
727 e->time.tv_usec = request_time.tv_usec;
732 static void add_share_mode_entry(struct share_mode_lock *lck,
733 const struct share_mode_entry *entry)
737 for (i=0; i<lck->num_share_modes; i++) {
738 struct share_mode_entry *e = &lck->share_modes[i];
739 if (is_unused_share_mode_entry(e)) {
745 if (i == lck->num_share_modes) {
746 /* No unused entry found */
747 ADD_TO_ARRAY(lck, struct share_mode_entry, *entry,
748 &lck->share_modes, &lck->num_share_modes);
750 lck->modified = True;
753 void set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
754 uint16 mid, uint16 op_type)
756 struct share_mode_entry entry;
757 fill_share_mode_entry(&entry, fsp, mid, op_type);
758 add_share_mode_entry(lck, &entry);
761 void add_deferred_open(struct share_mode_lock *lck, uint16 mid,
762 struct timeval request_time,
763 SMB_DEV_T dev, SMB_INO_T ino)
765 struct share_mode_entry entry;
766 fill_deferred_open_entry(&entry, request_time, dev, ino, mid);
767 add_share_mode_entry(lck, &entry);
770 /*******************************************************************
771 Check if two share mode entries are identical, ignoring oplock
772 and mid info and desired_access.
773 ********************************************************************/
775 static BOOL share_modes_identical(struct share_mode_entry *e1,
776 struct share_mode_entry *e2)
778 #if 1 /* JRA PARANOIA TEST - REMOVE LATER */
779 if (procid_equal(&e1->pid, &e2->pid) &&
780 e1->share_file_id == e2->share_file_id &&
781 e1->dev == e2->dev &&
782 e1->inode == e2->inode &&
783 (e1->share_access) != (e2->share_access)) {
784 DEBUG(0,("PANIC: share_modes_identical: share_mode "
785 "mismatch (e1 = 0x%x, e2 = 0x%x). Logic error.\n",
786 (unsigned int)e1->share_access,
787 (unsigned int)e2->share_access ));
788 smb_panic("PANIC: share_modes_identical logic error.\n");
792 return (procid_equal(&e1->pid, &e2->pid) &&
793 (e1->share_access) == (e2->share_access) &&
794 e1->dev == e2->dev &&
795 e1->inode == e2->inode &&
796 e1->share_file_id == e2->share_file_id );
799 static BOOL deferred_open_identical(struct share_mode_entry *e1,
800 struct share_mode_entry *e2)
802 return (procid_equal(&e1->pid, &e2->pid) &&
803 (e1->op_mid == e2->op_mid) &&
804 (e1->dev == e2->dev) &&
805 (e1->inode == e2->inode));
808 static struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck,
809 struct share_mode_entry *entry)
813 for (i=0; i<lck->num_share_modes; i++) {
814 struct share_mode_entry *e = &lck->share_modes[i];
815 if (is_valid_share_mode_entry(entry) &&
816 is_valid_share_mode_entry(e) &&
817 share_modes_identical(e, entry)) {
820 if (is_deferred_open_entry(entry) &&
821 is_deferred_open_entry(e) &&
822 deferred_open_identical(e, entry)) {
829 /*******************************************************************
830 Del the share mode of a file for this process. Return the number of
832 ********************************************************************/
834 BOOL del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
836 struct share_mode_entry entry, *e;
838 fill_share_mode_entry(&entry, fsp, 0, 0);
840 e = find_share_mode_entry(lck, &entry);
845 e->op_type = UNUSED_SHARE_MODE_ENTRY;
846 lck->modified = True;
850 void del_deferred_open_entry(struct share_mode_lock *lck, uint16 mid)
852 struct share_mode_entry entry, *e;
854 fill_deferred_open_entry(&entry, timeval_zero(),
855 lck->dev, lck->ino, mid);
857 e = find_share_mode_entry(lck, &entry);
862 e->op_type = UNUSED_SHARE_MODE_ENTRY;
863 lck->modified = True;
866 /*******************************************************************
867 Remove an oplock mid and mode entry from a share mode.
868 ********************************************************************/
870 BOOL remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
872 struct share_mode_entry entry, *e;
874 fill_share_mode_entry(&entry, fsp, 0, 0);
876 e = find_share_mode_entry(lck, &entry);
882 e->op_type = NO_OPLOCK;
883 lck->modified = True;
887 /*******************************************************************
888 Downgrade a oplock type from exclusive to level II.
889 ********************************************************************/
891 BOOL downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
893 struct share_mode_entry entry, *e;
895 fill_share_mode_entry(&entry, fsp, 0, 0);
897 e = find_share_mode_entry(lck, &entry);
902 e->op_type = LEVEL_II_OPLOCK;
903 lck->modified = True;
907 /****************************************************************************
908 Deal with the internal needs of setting the delete on close flag. Note that
909 as the tdb locking is recursive, it is safe to call this from within
910 open_file_shared. JRA.
911 ****************************************************************************/
913 NTSTATUS can_set_delete_on_close(files_struct *fsp, BOOL delete_on_close,
916 if (!delete_on_close) {
921 * Only allow delete on close for writable files.
924 if ((dosmode & aRONLY) &&
925 !lp_delete_readonly(SNUM(fsp->conn))) {
926 DEBUG(10,("can_set_delete_on_close: file %s delete on close "
927 "flag set but file attribute is readonly.\n",
929 return NT_STATUS_CANNOT_DELETE;
933 * Only allow delete on close for writable shares.
936 if (!CAN_WRITE(fsp->conn)) {
937 DEBUG(10,("can_set_delete_on_close: file %s delete on "
938 "close flag set but write access denied on share.\n",
940 return NT_STATUS_ACCESS_DENIED;
944 * Only allow delete on close for files/directories opened with delete
948 if (!(fsp->access_mask & DELETE_ACCESS)) {
949 DEBUG(10,("can_set_delete_on_close: file %s delete on "
950 "close flag set but delete access denied.\n",
952 return NT_STATUS_ACCESS_DENIED;
958 /****************************************************************************
959 Sets the delete on close flag over all share modes on this file.
960 Modify the share mode entry for all files open
961 on this device and inode to tell other smbds we have
962 changed the delete on close flag. This will be noticed
963 in the close code, the last closer will delete the file
965 ****************************************************************************/
967 BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close)
969 struct share_mode_lock *lck;
971 DEBUG(10,("set_delete_on_close: %s delete on close flag for "
972 "fnum = %d, file %s\n",
973 delete_on_close ? "Adding" : "Removing", fsp->fnum,
980 lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
984 if (lck->delete_on_close != delete_on_close) {
985 lck->delete_on_close = delete_on_close;
986 lck->modified = True;
993 static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
996 struct locking_data *data;
997 struct share_mode_entry *shares;
998 const char *sharepath;
1001 void (*traverse_callback)(struct share_mode_entry *, const char *, const char *) = state;
1003 /* Ensure this is a locking_key record. */
1004 if (kbuf.dsize != sizeof(struct locking_key))
1007 data = (struct locking_data *)dbuf.dptr;
1008 shares = (struct share_mode_entry *)(dbuf.dptr + sizeof(*data));
1009 sharepath = dbuf.dptr + sizeof(*data) +
1010 data->u.s.num_share_mode_entries*sizeof(*shares);
1011 fname = dbuf.dptr + sizeof(*data) +
1012 data->u.s.num_share_mode_entries*sizeof(*shares) +
1013 strlen(sharepath) + 1;
1015 for (i=0;i<data->u.s.num_share_mode_entries;i++) {
1016 traverse_callback(&shares[i], sharepath, fname);
1021 /*******************************************************************
1022 Call the specified function on each entry under management by the
1024 ********************************************************************/
1026 int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *, const char *))
1030 return tdb_traverse(tdb, traverse_fn, fn);