2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1992-2000
5 Copyright (C) Jeremy Allison 1992-2000
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 12 aug 96: Erik.Devriendt@te6.siemens.be
24 added support for shared memory implementation of share mode locking
26 May 1997. Jeremy Allison (jallison@whistle.com). Modified share mode
27 locking to deal with multiple share modes per open file.
29 September 1997. Jeremy Allison (jallison@whistle.com). Added oplock
32 rewrtten completely to use new tdb code. Tridge, Dec '99
34 Added POSIX locking support. Jeremy Allison (jeremy@valinux.com), Apr. 2000.
40 /* the locking database handle */
41 static TDB_CONTEXT
*tdb
;
43 /****************************************************************************
45 ****************************************************************************/
47 static const char *lock_type_name(enum brl_type lock_type
)
49 return (lock_type
== READ_LOCK
) ? "READ" : "WRITE";
52 /****************************************************************************
53 Utility function called to see if a file region is locked.
54 If check_self is True, then checks on our own fd with the same locking context
55 are still made. If check_self is False, then checks are not made on our own fd
56 with the same locking context are not made.
57 ****************************************************************************/
59 BOOL
is_locked(files_struct
*fsp
,connection_struct
*conn
,
60 SMB_BIG_UINT count
,SMB_BIG_UINT offset
,
61 enum brl_type lock_type
, BOOL check_self
)
63 int snum
= SNUM(conn
);
69 if (!lp_locking(snum
) || !lp_strict_locking(snum
))
72 ret
= !brl_locktest(fsp
->dev
, fsp
->inode
, fsp
->fnum
,
73 global_smbpid
, sys_getpid(), conn
->cnum
,
74 offset
, count
, lock_type
, check_self
);
76 DEBUG(10,("is_locked: brl start=%.0f len=%.0f %s for file %s\n",
77 (double)offset
, (double)count
, ret
? "locked" : "unlocked",
81 * There is no lock held by an SMB daemon, check to
82 * see if there is a POSIX lock from a UNIX or NFS process.
85 if(!ret
&& lp_posix_locking(snum
)) {
86 ret
= is_posix_locked(fsp
, offset
, count
, lock_type
);
88 DEBUG(10,("is_locked: posix start=%.0f len=%.0f %s for file %s\n",
89 (double)offset
, (double)count
, ret
? "locked" : "unlocked",
96 /****************************************************************************
97 Utility function called by locking requests.
98 ****************************************************************************/
100 static NTSTATUS
do_lock(files_struct
*fsp
,connection_struct
*conn
, uint16 lock_pid
,
101 SMB_BIG_UINT count
,SMB_BIG_UINT offset
,enum brl_type lock_type
)
103 NTSTATUS status
= NT_STATUS_LOCK_NOT_GRANTED
;
105 if (!lp_locking(SNUM(conn
)))
108 /* NOTE! 0 byte long ranges ARE allowed and should be stored */
110 DEBUG(10,("do_lock: lock type %s start=%.0f len=%.0f requested for file %s\n",
111 lock_type_name(lock_type
), (double)offset
, (double)count
, fsp
->fsp_name
));
113 if (OPEN_FSP(fsp
) && fsp
->can_lock
&& (fsp
->conn
== conn
)) {
114 status
= brl_lock(fsp
->dev
, fsp
->inode
, fsp
->fnum
,
115 lock_pid
, sys_getpid(), conn
->cnum
,
119 if (NT_STATUS_IS_OK(status
) && lp_posix_locking(SNUM(conn
))) {
122 * Try and get a POSIX lock on this range.
123 * Note that this is ok if it is a read lock
124 * overlapping on a different fd. JRA.
127 if (!set_posix_lock(fsp
, offset
, count
, lock_type
)) {
128 status
= NT_STATUS_LOCK_NOT_GRANTED
;
130 * We failed to map - we must now remove the brl
133 (void)brl_unlock(fsp
->dev
, fsp
->inode
, fsp
->fnum
,
134 lock_pid
, sys_getpid(), conn
->cnum
,
135 offset
, count
, False
);
143 /****************************************************************************
144 Utility function called by locking requests. This is *DISGUSTING*. It also
145 appears to be "What Windows Does" (tm). Andrew, ever wonder why Windows 2000
146 is so slow on the locking tests...... ? This is the reason. Much though I hate
147 it, we need this. JRA.
148 ****************************************************************************/
150 NTSTATUS
do_lock_spin(files_struct
*fsp
,connection_struct
*conn
, uint16 lock_pid
,
151 SMB_BIG_UINT count
,SMB_BIG_UINT offset
,enum brl_type lock_type
)
153 int j
, maxj
= lp_lock_spin_count();
154 int sleeptime
= lp_lock_sleep_time();
155 NTSTATUS status
, ret
;
160 ret
= NT_STATUS_OK
; /* to keep dumb compilers happy */
162 for (j
= 0; j
< maxj
; j
++) {
163 status
= do_lock(fsp
, conn
, lock_pid
, count
, offset
, lock_type
);
164 if (!NT_STATUS_EQUAL(status
, NT_STATUS_LOCK_NOT_GRANTED
) &&
165 !NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
168 /* if we do fail then return the first error code we got */
173 sys_usleep(sleeptime
);
178 /****************************************************************************
179 Utility function called by unlocking requests.
180 ****************************************************************************/
182 NTSTATUS
do_unlock(files_struct
*fsp
,connection_struct
*conn
, uint16 lock_pid
,
183 SMB_BIG_UINT count
,SMB_BIG_UINT offset
)
187 if (!lp_locking(SNUM(conn
)))
190 if (!OPEN_FSP(fsp
) || !fsp
->can_lock
|| (fsp
->conn
!= conn
)) {
191 return NT_STATUS_INVALID_HANDLE
;
194 DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for file %s\n",
195 (double)offset
, (double)count
, fsp
->fsp_name
));
198 * Remove the existing lock record from the tdb lockdb
199 * before looking at POSIX locks. If this record doesn't
200 * match then don't bother looking to remove POSIX locks.
203 ok
= brl_unlock(fsp
->dev
, fsp
->inode
, fsp
->fnum
,
204 lock_pid
, sys_getpid(), conn
->cnum
, offset
, count
, False
);
207 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
208 return NT_STATUS_RANGE_NOT_LOCKED
;
211 if (!lp_posix_locking(SNUM(conn
)))
214 (void)release_posix_lock(fsp
, offset
, count
);
219 /****************************************************************************
220 Remove any locks on this fd. Called from file_close().
221 ****************************************************************************/
223 void locking_close_file(files_struct
*fsp
)
225 pid_t pid
= sys_getpid();
227 if (!lp_locking(SNUM(fsp
->conn
)))
231 * Just release all the brl locks, no need to release individually.
234 brl_close(fsp
->dev
, fsp
->inode
, pid
, fsp
->conn
->cnum
, fsp
->fnum
);
236 if(lp_posix_locking(SNUM(fsp
->conn
))) {
239 * Release all the POSIX locks.
241 posix_locking_close_file(fsp
);
246 /****************************************************************************
247 Initialise the locking functions.
248 ****************************************************************************/
250 static int open_read_only
;
252 BOOL
locking_init(int read_only
)
259 tdb
= tdb_open_log(lock_path("locking.tdb"),
260 0, TDB_DEFAULT
|(read_only
?0x0:TDB_CLEAR_IF_FIRST
),
261 read_only
?O_RDONLY
:O_RDWR
|O_CREAT
,
265 DEBUG(0,("ERROR: Failed to initialise locking database\n"));
269 if (!posix_locking_init(read_only
))
272 open_read_only
= read_only
;
277 /*******************************************************************
278 Deinitialize the share_mode management.
279 ******************************************************************/
281 BOOL
locking_end(void)
284 brl_shutdown(open_read_only
);
287 if (tdb_close(tdb
) != 0)
294 /*******************************************************************
295 Form a static locking key for a dev/inode pair.
296 ******************************************************************/
298 static TDB_DATA
locking_key(SMB_DEV_T dev
, SMB_INO_T inode
)
300 static struct locking_key key
;
303 memset(&key
, '\0', sizeof(key
));
306 kbuf
.dptr
= (char *)&key
;
307 kbuf
.dsize
= sizeof(key
);
311 static TDB_DATA
locking_key_fsp(files_struct
*fsp
)
313 return locking_key(fsp
->dev
, fsp
->inode
);
316 /*******************************************************************
317 Lock a hash bucket entry.
318 ******************************************************************/
320 BOOL
lock_share_entry(connection_struct
*conn
,
321 SMB_DEV_T dev
, SMB_INO_T inode
)
323 return tdb_chainlock(tdb
, locking_key(dev
, inode
)) == 0;
326 /*******************************************************************
327 Unlock a hash bucket entry.
328 ******************************************************************/
330 void unlock_share_entry(connection_struct
*conn
,
331 SMB_DEV_T dev
, SMB_INO_T inode
)
333 tdb_chainunlock(tdb
, locking_key(dev
, inode
));
336 /*******************************************************************
337 Lock a hash bucket entry. use a fsp for convenience
338 ******************************************************************/
340 BOOL
lock_share_entry_fsp(files_struct
*fsp
)
342 return tdb_chainlock(tdb
, locking_key(fsp
->dev
, fsp
->inode
)) == 0;
345 /*******************************************************************
346 Unlock a hash bucket entry.
347 ******************************************************************/
349 void unlock_share_entry_fsp(files_struct
*fsp
)
351 tdb_chainunlock(tdb
, locking_key(fsp
->dev
, fsp
->inode
));
354 /*******************************************************************
355 Print out a share mode.
356 ********************************************************************/
358 static char *share_mode_str(int num
, share_mode_entry
*e
)
360 static pstring share_str
;
362 slprintf(share_str
, sizeof(share_str
)-1, "share_mode_entry[%d]: \
363 pid = %u, share_mode = 0x%x, desired_access = 0x%x, port = 0x%x, type= 0x%x, file_id = %lu, dev = 0x%x, inode = %.0f",
364 num
, e
->pid
, e
->share_mode
, (unsigned int)e
->desired_access
, e
->op_port
, e
->op_type
, e
->share_file_id
,
365 (unsigned int)e
->dev
, (double)e
->inode
);
370 /*******************************************************************
371 Print out a share mode table.
372 ********************************************************************/
374 static void print_share_mode_table(struct locking_data
*data
)
376 int num_share_modes
= data
->u
.num_share_mode_entries
;
377 share_mode_entry
*shares
= (share_mode_entry
*)(data
+ 1);
380 for (i
= 0; i
< num_share_modes
; i
++) {
381 share_mode_entry
*entry_p
= &shares
[i
];
382 DEBUG(10,("print_share_mode_table: %s\n", share_mode_str(i
, entry_p
) ));
386 /*******************************************************************
387 Get all share mode entries for a dev/inode pair.
388 ********************************************************************/
390 int get_share_modes(connection_struct
*conn
,
391 SMB_DEV_T dev
, SMB_INO_T inode
,
392 share_mode_entry
**pp_shares
)
395 struct locking_data
*data
;
397 share_mode_entry
*shares
= NULL
;
401 dbuf
= tdb_fetch(tdb
, locking_key(dev
, inode
));
405 data
= (struct locking_data
*)dbuf
.dptr
;
406 num_share_modes
= data
->u
.num_share_mode_entries
;
407 if(num_share_modes
) {
411 shares
= (share_mode_entry
*)memdup(dbuf
.dptr
+ sizeof(*data
),
412 num_share_modes
* sizeof(share_mode_entry
));
415 SAFE_FREE(dbuf
.dptr
);
420 * Ensure that each entry has a real process attached.
423 for (i
= 0; i
< num_share_modes
; ) {
424 share_mode_entry
*entry_p
= &shares
[i
];
425 if (process_exists(entry_p
->pid
)) {
426 DEBUG(10,("get_share_modes: %s\n", share_mode_str(i
, entry_p
) ));
429 DEBUG(10,("get_share_modes: deleted %s\n", share_mode_str(i
, entry_p
) ));
430 memcpy( &shares
[i
], &shares
[i
+1],
431 sizeof(share_mode_entry
) * (num_share_modes
- i
- 1));
437 /* Did we delete any ? If so, re-store in tdb. */
439 data
->u
.num_share_mode_entries
= num_share_modes
;
442 memcpy(dbuf
.dptr
+ sizeof(*data
), shares
,
443 num_share_modes
* sizeof(share_mode_entry
));
445 /* The record has shrunk a bit */
446 dbuf
.dsize
-= del_count
* sizeof(share_mode_entry
);
448 if (tdb_store(tdb
, locking_key(dev
, inode
), dbuf
, TDB_REPLACE
) == -1) {
450 SAFE_FREE(dbuf
.dptr
);
456 SAFE_FREE(dbuf
.dptr
);
458 return num_share_modes
;
461 /*******************************************************************
462 Fill a share mode entry.
463 ********************************************************************/
465 static void fill_share_mode(char *p
, files_struct
*fsp
, uint16 port
, uint16 op_type
)
467 share_mode_entry
*e
= (share_mode_entry
*)p
;
468 void *x
= &e
->time
; /* Needed to force alignment. p may not be aligned.... */
470 memset(e
, '\0', sizeof(share_mode_entry
));
471 e
->pid
= sys_getpid();
472 e
->share_mode
= fsp
->share_mode
;
473 e
->desired_access
= fsp
->desired_access
;
475 e
->op_type
= op_type
;
476 memcpy(x
, &fsp
->open_time
, sizeof(struct timeval
));
477 e
->share_file_id
= fsp
->file_id
;
479 e
->inode
= fsp
->inode
;
482 /*******************************************************************
483 Check if two share mode entries are identical, ignoring oplock
484 and port info and desired_access.
485 ********************************************************************/
487 BOOL
share_modes_identical( share_mode_entry
*e1
, share_mode_entry
*e2
)
489 #if 1 /* JRA PARANOIA TEST - REMOVE LATER */
490 if (e1
->pid
== e2
->pid
&&
491 e1
->share_file_id
== e2
->share_file_id
&&
492 e1
->dev
== e2
->dev
&&
493 e1
->inode
== e2
->inode
&&
494 (e1
->share_mode
& ~DELETE_ON_CLOSE_FLAG
) != (e2
->share_mode
& ~DELETE_ON_CLOSE_FLAG
)) {
495 DEBUG(0,("PANIC: share_modes_identical: share_mode missmatch (e1 = %u, e2 = %u). Logic error.\n",
496 (unsigned int)(e1
->share_mode
& ~DELETE_ON_CLOSE_FLAG
),
497 (unsigned int)(e2
->share_mode
& ~DELETE_ON_CLOSE_FLAG
) ));
498 smb_panic("PANIC: share_modes_identical logic error.\n");
502 return (e1
->pid
== e2
->pid
&&
503 (e1
->share_mode
& ~DELETE_ON_CLOSE_FLAG
) == (e2
->share_mode
& ~DELETE_ON_CLOSE_FLAG
) &&
504 e1
->dev
== e2
->dev
&&
505 e1
->inode
== e2
->inode
&&
506 e1
->share_file_id
== e2
->share_file_id
);
509 /*******************************************************************
510 Delete a specific share mode. Return the number
511 of entries left, and a memdup'ed copy of the entry deleted (if required).
512 Ignore if no entry deleted.
513 ********************************************************************/
515 ssize_t
del_share_entry( SMB_DEV_T dev
, SMB_INO_T inode
,
516 share_mode_entry
*entry
, share_mode_entry
**ppse
)
519 struct locking_data
*data
;
521 share_mode_entry
*shares
;
527 /* read in the existing share modes */
528 dbuf
= tdb_fetch(tdb
, locking_key(dev
, inode
));
532 data
= (struct locking_data
*)dbuf
.dptr
;
533 shares
= (share_mode_entry
*)(dbuf
.dptr
+ sizeof(*data
));
536 * Find any with this pid and delete it
537 * by overwriting with the rest of the data
541 DEBUG(10,("del_share_entry: num_share_modes = %d\n", data
->u
.num_share_mode_entries
));
543 for (i
=0;i
<data
->u
.num_share_mode_entries
;) {
544 if (share_modes_identical(&shares
[i
], entry
)) {
545 DEBUG(10,("del_share_entry: deleted %s\n",
546 share_mode_str(i
, &shares
[i
]) ));
548 *ppse
= memdup(&shares
[i
], sizeof(*shares
));
549 data
->u
.num_share_mode_entries
--;
550 memmove(&shares
[i
], &shares
[i
+1],
551 dbuf
.dsize
- (sizeof(*data
) + (i
+1)*sizeof(*shares
)));
554 DEBUG(10,("del_share_entry: deleting entry %d\n", i
));
562 /* the record may have shrunk a bit */
563 dbuf
.dsize
-= del_count
* sizeof(*shares
);
565 count
= (ssize_t
)data
->u
.num_share_mode_entries
;
567 /* store it back in the database */
568 if (data
->u
.num_share_mode_entries
== 0) {
569 if (tdb_delete(tdb
, locking_key(dev
, inode
)) == -1)
572 if (tdb_store(tdb
, locking_key(dev
, inode
), dbuf
, TDB_REPLACE
) == -1)
576 DEBUG(10,("del_share_entry: Remaining table.\n"));
577 print_share_mode_table((struct locking_data
*)dbuf
.dptr
);
578 SAFE_FREE(dbuf
.dptr
);
582 /*******************************************************************
583 Del the share mode of a file for this process. Return the number
584 of entries left, and a memdup'ed copy of the entry deleted.
585 ********************************************************************/
587 ssize_t
del_share_mode(files_struct
*fsp
, share_mode_entry
**ppse
)
589 share_mode_entry entry
;
592 * Fake up a share_mode_entry for comparisons.
595 fill_share_mode((char *)&entry
, fsp
, 0, 0);
596 return del_share_entry(fsp
->dev
, fsp
->inode
, &entry
, ppse
);
599 /*******************************************************************
600 Set the share mode of a file. Return False on fail, True on success.
601 ********************************************************************/
603 BOOL
set_share_mode(files_struct
*fsp
, uint16 port
, uint16 op_type
)
606 struct locking_data
*data
;
611 /* read in the existing share modes if any */
612 dbuf
= tdb_fetch(tdb
, locking_key_fsp(fsp
));
615 /* we'll need to create a new record */
618 pstrcpy(fname
, fsp
->conn
->connectpath
);
620 pstrcat(fname
, fsp
->fsp_name
);
622 size
= sizeof(*data
) + sizeof(share_mode_entry
) + strlen(fname
) + 1;
623 p
= (char *)malloc(size
);
626 data
= (struct locking_data
*)p
;
627 data
->u
.num_share_mode_entries
= 1;
629 DEBUG(10,("set_share_mode: creating entry for file %s. num_share_modes = 1\n",
632 offset
= sizeof(*data
) + sizeof(share_mode_entry
);
633 safe_strcpy(p
+ offset
, fname
, size
- offset
- 1);
634 fill_share_mode(p
+ sizeof(*data
), fsp
, port
, op_type
);
637 if (tdb_store(tdb
, locking_key_fsp(fsp
), dbuf
, TDB_REPLACE
) == -1)
640 print_share_mode_table((struct locking_data
*)p
);
646 /* we're adding to an existing entry - this is a bit fiddly */
647 data
= (struct locking_data
*)dbuf
.dptr
;
649 data
->u
.num_share_mode_entries
++;
651 DEBUG(10,("set_share_mode: adding entry for file %s. new num_share_modes = %d\n",
652 fsp
->fsp_name
, data
->u
.num_share_mode_entries
));
654 size
= dbuf
.dsize
+ sizeof(share_mode_entry
);
657 SAFE_FREE(dbuf
.dptr
);
660 memcpy(p
, dbuf
.dptr
, sizeof(*data
));
661 fill_share_mode(p
+ sizeof(*data
), fsp
, port
, op_type
);
662 memcpy(p
+ sizeof(*data
) + sizeof(share_mode_entry
), dbuf
.dptr
+ sizeof(*data
),
663 dbuf
.dsize
- sizeof(*data
));
664 SAFE_FREE(dbuf
.dptr
);
667 if (tdb_store(tdb
, locking_key_fsp(fsp
), dbuf
, TDB_REPLACE
) == -1)
669 print_share_mode_table((struct locking_data
*)p
);
674 /*******************************************************************
675 A generic in-place modification call for share mode entries.
676 ********************************************************************/
678 static BOOL
mod_share_mode( SMB_DEV_T dev
, SMB_INO_T inode
, share_mode_entry
*entry
,
679 void (*mod_fn
)(share_mode_entry
*, SMB_DEV_T
, SMB_INO_T
, void *),
683 struct locking_data
*data
;
685 share_mode_entry
*shares
;
686 BOOL need_store
=False
;
689 /* read in the existing share modes */
690 dbuf
= tdb_fetch(tdb
, locking_key(dev
, inode
));
694 data
= (struct locking_data
*)dbuf
.dptr
;
695 shares
= (share_mode_entry
*)(dbuf
.dptr
+ sizeof(*data
));
697 /* find any with our pid and call the supplied function */
698 for (i
=0;i
<data
->u
.num_share_mode_entries
;i
++) {
699 if (share_modes_identical(entry
, &shares
[i
])) {
700 mod_fn(&shares
[i
], dev
, inode
, param
);
705 /* if the mod fn was called then store it back */
707 if (data
->u
.num_share_mode_entries
== 0) {
708 if (tdb_delete(tdb
, locking_key(dev
, inode
)) == -1)
711 if (tdb_store(tdb
, locking_key(dev
, inode
), dbuf
, TDB_REPLACE
) == -1)
716 SAFE_FREE(dbuf
.dptr
);
720 /*******************************************************************
721 Static function that actually does the work for the generic function
723 ********************************************************************/
725 static void remove_share_oplock_fn(share_mode_entry
*entry
, SMB_DEV_T dev
, SMB_INO_T inode
,
728 DEBUG(10,("remove_share_oplock_fn: removing oplock info for entry dev=%x ino=%.0f\n",
729 (unsigned int)dev
, (double)inode
));
730 /* Delete the oplock info. */
732 entry
->op_type
= NO_OPLOCK
;
735 /*******************************************************************
736 Remove an oplock port and mode entry from a share mode.
737 ********************************************************************/
739 BOOL
remove_share_oplock(files_struct
*fsp
)
741 share_mode_entry entry
;
743 * Fake up an entry for comparisons...
745 fill_share_mode((char *)&entry
, fsp
, 0, 0);
746 return mod_share_mode(fsp
->dev
, fsp
->inode
, &entry
, remove_share_oplock_fn
, NULL
);
749 /*******************************************************************
750 Static function that actually does the work for the generic function
752 ********************************************************************/
754 static void downgrade_share_oplock_fn(share_mode_entry
*entry
, SMB_DEV_T dev
, SMB_INO_T inode
,
757 DEBUG(10,("downgrade_share_oplock_fn: downgrading oplock info for entry dev=%x ino=%.0f\n",
758 (unsigned int)dev
, (double)inode
));
759 entry
->op_type
= LEVEL_II_OPLOCK
;
762 /*******************************************************************
763 Downgrade a oplock type from exclusive to level II.
764 ********************************************************************/
766 BOOL
downgrade_share_oplock(files_struct
*fsp
)
768 share_mode_entry entry
;
770 * Fake up an entry for comparisons...
772 fill_share_mode((char *)&entry
, fsp
, 0, 0);
773 return mod_share_mode(fsp
->dev
, fsp
->inode
, &entry
, downgrade_share_oplock_fn
, NULL
);
776 /*******************************************************************
777 Get/Set the delete on close flag in a set of share modes.
778 Return False on fail, True on success.
779 ********************************************************************/
781 BOOL
modify_delete_flag( SMB_DEV_T dev
, SMB_INO_T inode
, BOOL delete_on_close
)
784 struct locking_data
*data
;
786 share_mode_entry
*shares
;
788 /* read in the existing share modes */
789 dbuf
= tdb_fetch(tdb
, locking_key(dev
, inode
));
793 data
= (struct locking_data
*)dbuf
.dptr
;
794 shares
= (share_mode_entry
*)(dbuf
.dptr
+ sizeof(*data
));
796 /* Set/Unset the delete on close element. */
797 for (i
=0;i
<data
->u
.num_share_mode_entries
;i
++,shares
++) {
798 shares
->share_mode
= (delete_on_close
?
799 (shares
->share_mode
| DELETE_ON_CLOSE_FLAG
) :
800 (shares
->share_mode
& ~DELETE_ON_CLOSE_FLAG
) );
804 if (data
->u
.num_share_mode_entries
) {
805 if (tdb_store(tdb
, locking_key(dev
,inode
), dbuf
, TDB_REPLACE
)==-1) {
806 SAFE_FREE(dbuf
.dptr
);
811 SAFE_FREE(dbuf
.dptr
);
815 /****************************************************************************
816 Traverse the whole database with this function, calling traverse_callback
818 ****************************************************************************/
820 static int traverse_fn(TDB_CONTEXT
*the_tdb
, TDB_DATA kbuf
, TDB_DATA dbuf
,
823 struct locking_data
*data
;
824 share_mode_entry
*shares
;
828 SHAREMODE_FN(traverse_callback
) = (SHAREMODE_FN_CAST())state
;
830 data
= (struct locking_data
*)dbuf
.dptr
;
831 shares
= (share_mode_entry
*)(dbuf
.dptr
+ sizeof(*data
));
832 name
= dbuf
.dptr
+ sizeof(*data
) + data
->u
.num_share_mode_entries
*sizeof(*shares
);
834 for (i
=0;i
<data
->u
.num_share_mode_entries
;i
++) {
835 traverse_callback(&shares
[i
], name
);
840 /*******************************************************************
841 Call the specified function on each entry under management by the
843 ********************************************************************/
845 int share_mode_forall(SHAREMODE_FN(fn
))
849 return tdb_traverse(tdb
, traverse_fn
, (void*)fn
);