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
)
105 if (!lp_locking(SNUM(conn
)))
108 /* NOTE! 0 byte long ranges ARE allowed and should be stored */
111 DEBUG(10,("do_lock: lock type %s start=%.0f len=%.0f requested for file %s\n",
112 lock_type_name(lock_type
), (double)offset
, (double)count
, fsp
->fsp_name
));
114 if (OPEN_FSP(fsp
) && fsp
->can_lock
&& (fsp
->conn
== conn
)) {
115 status
= brl_lock(fsp
->dev
, fsp
->inode
, fsp
->fnum
,
116 lock_pid
, sys_getpid(), conn
->cnum
,
120 if (NT_STATUS_IS_OK(status
) && lp_posix_locking(SNUM(conn
))) {
123 * Try and get a POSIX lock on this range.
124 * Note that this is ok if it is a read lock
125 * overlapping on a different fd. JRA.
128 if (!set_posix_lock(fsp
, offset
, count
, lock_type
)) {
129 status
= NT_STATUS_LOCK_NOT_GRANTED
;
131 * We failed to map - we must now remove the brl
134 (void)brl_unlock(fsp
->dev
, fsp
->inode
, fsp
->fnum
,
135 lock_pid
, sys_getpid(), conn
->cnum
,
144 /****************************************************************************
145 Utility function called by locking requests. This is *DISGUSTING*. It also
146 appears to be "What Windows Does" (tm). Andrew, ever wonder why Windows 2000
147 is so slow on the locking tests...... ? This is the reason. Much though I hate
148 it, we need this. JRA.
149 ****************************************************************************/
151 NTSTATUS
do_lock_spin(files_struct
*fsp
,connection_struct
*conn
, uint16 lock_pid
,
152 SMB_BIG_UINT count
,SMB_BIG_UINT offset
,enum brl_type lock_type
)
154 int j
, maxj
= lp_lock_spin_count();
155 int sleeptime
= lp_lock_sleep_time();
156 NTSTATUS status
, ret
;
161 ret
= NT_STATUS_OK
; /* to keep dumb compilers happy */
163 for (j
= 0; j
< maxj
; j
++) {
164 status
= do_lock(fsp
, conn
, lock_pid
, count
, offset
, lock_type
);
165 if (!NT_STATUS_EQUAL(status
, NT_STATUS_LOCK_NOT_GRANTED
) &&
166 !NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
169 /* if we do fail then return the first error code we got */
174 sys_usleep(sleeptime
);
179 /****************************************************************************
180 Utility function called by unlocking requests.
181 ****************************************************************************/
183 NTSTATUS
do_unlock(files_struct
*fsp
,connection_struct
*conn
, uint16 lock_pid
,
184 SMB_BIG_UINT count
,SMB_BIG_UINT offset
)
188 if (!lp_locking(SNUM(conn
)))
191 if (!OPEN_FSP(fsp
) || !fsp
->can_lock
|| (fsp
->conn
!= conn
)) {
192 return NT_STATUS_INVALID_HANDLE
;
195 DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for file %s\n",
196 (double)offset
, (double)count
, fsp
->fsp_name
));
199 * Remove the existing lock record from the tdb lockdb
200 * before looking at POSIX locks. If this record doesn't
201 * match then don't bother looking to remove POSIX locks.
204 ok
= brl_unlock(fsp
->dev
, fsp
->inode
, fsp
->fnum
,
205 lock_pid
, sys_getpid(), conn
->cnum
, offset
, count
);
208 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
209 return NT_STATUS_RANGE_NOT_LOCKED
;
212 if (!lp_posix_locking(SNUM(conn
)))
215 (void)release_posix_lock(fsp
, offset
, count
);
220 /****************************************************************************
221 Remove any locks on this fd. Called from file_close().
222 ****************************************************************************/
224 void locking_close_file(files_struct
*fsp
)
226 pid_t pid
= sys_getpid();
228 if (!lp_locking(SNUM(fsp
->conn
)))
232 * Just release all the brl locks, no need to release individually.
235 brl_close(fsp
->dev
, fsp
->inode
, pid
, fsp
->conn
->cnum
, fsp
->fnum
);
237 if(lp_posix_locking(SNUM(fsp
->conn
))) {
240 * Release all the POSIX locks.
242 posix_locking_close_file(fsp
);
247 /****************************************************************************
248 Initialise the locking functions.
249 ****************************************************************************/
251 static int open_read_only
;
253 BOOL
locking_init(int read_only
)
260 tdb
= tdb_open_log(lock_path("locking.tdb"),
261 0, TDB_DEFAULT
|(read_only
?0x0:TDB_CLEAR_IF_FIRST
),
262 read_only
?O_RDONLY
:O_RDWR
|O_CREAT
,
266 DEBUG(0,("ERROR: Failed to initialise locking database\n"));
270 if (!posix_locking_init(read_only
))
273 open_read_only
= read_only
;
278 /*******************************************************************
279 Deinitialize the share_mode management.
280 ******************************************************************/
282 BOOL
locking_end(void)
285 brl_shutdown(open_read_only
);
288 if (tdb_close(tdb
) != 0)
295 /*******************************************************************
296 Form a static locking key for a dev/inode pair.
297 ******************************************************************/
299 static TDB_DATA
locking_key(SMB_DEV_T dev
, SMB_INO_T inode
)
301 static struct locking_key key
;
304 memset(&key
, '\0', sizeof(key
));
307 kbuf
.dptr
= (char *)&key
;
308 kbuf
.dsize
= sizeof(key
);
312 static TDB_DATA
locking_key_fsp(files_struct
*fsp
)
314 return locking_key(fsp
->dev
, fsp
->inode
);
317 /*******************************************************************
318 Lock a hash bucket entry.
319 ******************************************************************/
321 BOOL
lock_share_entry(connection_struct
*conn
,
322 SMB_DEV_T dev
, SMB_INO_T inode
)
324 return tdb_chainlock(tdb
, locking_key(dev
, inode
)) == 0;
327 /*******************************************************************
328 Unlock a hash bucket entry.
329 ******************************************************************/
331 void unlock_share_entry(connection_struct
*conn
,
332 SMB_DEV_T dev
, SMB_INO_T inode
)
334 tdb_chainunlock(tdb
, locking_key(dev
, inode
));
337 /*******************************************************************
338 Lock a hash bucket entry. use a fsp for convenience
339 ******************************************************************/
341 BOOL
lock_share_entry_fsp(files_struct
*fsp
)
343 return tdb_chainlock(tdb
, locking_key(fsp
->dev
, fsp
->inode
)) == 0;
346 /*******************************************************************
347 Unlock a hash bucket entry.
348 ******************************************************************/
350 void unlock_share_entry_fsp(files_struct
*fsp
)
352 tdb_chainunlock(tdb
, locking_key(fsp
->dev
, fsp
->inode
));
355 /*******************************************************************
356 Print out a share mode.
357 ********************************************************************/
359 static char *share_mode_str(int num
, share_mode_entry
*e
)
361 static pstring share_str
;
363 slprintf(share_str
, sizeof(share_str
)-1, "share_mode_entry[%d]: \
364 pid = %u, share_mode = 0x%x, desired_access = 0x%x, port = 0x%x, type= 0x%x, file_id = %lu, dev = 0x%x, inode = %.0f",
365 num
, e
->pid
, e
->share_mode
, (unsigned int)e
->desired_access
, e
->op_port
, e
->op_type
, e
->share_file_id
,
366 (unsigned int)e
->dev
, (double)e
->inode
);
371 /*******************************************************************
372 Print out a share mode table.
373 ********************************************************************/
375 static void print_share_mode_table(struct locking_data
*data
)
377 int num_share_modes
= data
->u
.num_share_mode_entries
;
378 share_mode_entry
*shares
= (share_mode_entry
*)(data
+ 1);
381 for (i
= 0; i
< num_share_modes
; i
++) {
382 share_mode_entry
*entry_p
= &shares
[i
];
383 DEBUG(10,("print_share_mode_table: %s\n", share_mode_str(i
, entry_p
) ));
387 /*******************************************************************
388 Get all share mode entries for a dev/inode pair.
389 ********************************************************************/
391 int get_share_modes(connection_struct
*conn
,
392 SMB_DEV_T dev
, SMB_INO_T inode
,
393 share_mode_entry
**pp_shares
)
396 struct locking_data
*data
;
398 share_mode_entry
*shares
= NULL
;
402 dbuf
= tdb_fetch(tdb
, locking_key(dev
, inode
));
406 data
= (struct locking_data
*)dbuf
.dptr
;
407 num_share_modes
= data
->u
.num_share_mode_entries
;
408 if(num_share_modes
) {
412 shares
= (share_mode_entry
*)memdup(dbuf
.dptr
+ sizeof(*data
),
413 num_share_modes
* sizeof(share_mode_entry
));
416 SAFE_FREE(dbuf
.dptr
);
421 * Ensure that each entry has a real process attached.
424 for (i
= 0; i
< num_share_modes
; ) {
425 share_mode_entry
*entry_p
= &shares
[i
];
426 if (process_exists(entry_p
->pid
)) {
427 DEBUG(10,("get_share_modes: %s\n", share_mode_str(i
, entry_p
) ));
430 DEBUG(10,("get_share_modes: deleted %s\n", share_mode_str(i
, entry_p
) ));
431 memcpy( &shares
[i
], &shares
[i
+1],
432 sizeof(share_mode_entry
) * (num_share_modes
- i
- 1));
438 /* Did we delete any ? If so, re-store in tdb. */
440 data
->u
.num_share_mode_entries
= num_share_modes
;
443 memcpy(dbuf
.dptr
+ sizeof(*data
), shares
,
444 num_share_modes
* sizeof(share_mode_entry
));
446 /* The record has shrunk a bit */
447 dbuf
.dsize
-= del_count
* sizeof(share_mode_entry
);
449 if (tdb_store(tdb
, locking_key(dev
, inode
), dbuf
, TDB_REPLACE
) == -1) {
451 SAFE_FREE(dbuf
.dptr
);
457 SAFE_FREE(dbuf
.dptr
);
459 return num_share_modes
;
462 /*******************************************************************
463 Fill a share mode entry.
464 ********************************************************************/
466 static void fill_share_mode(char *p
, files_struct
*fsp
, uint16 port
, uint16 op_type
)
468 share_mode_entry
*e
= (share_mode_entry
*)p
;
469 void *x
= &e
->time
; /* Needed to force alignment. p may not be aligned.... */
471 memset(e
, '\0', sizeof(share_mode_entry
));
472 e
->pid
= sys_getpid();
473 e
->share_mode
= fsp
->share_mode
;
474 e
->desired_access
= fsp
->desired_access
;
476 e
->op_type
= op_type
;
477 memcpy(x
, &fsp
->open_time
, sizeof(struct timeval
));
478 e
->share_file_id
= fsp
->file_id
;
480 e
->inode
= fsp
->inode
;
483 /*******************************************************************
484 Check if two share mode entries are identical, ignoring oplock
485 and port info and desired_access.
486 ********************************************************************/
488 BOOL
share_modes_identical( share_mode_entry
*e1
, share_mode_entry
*e2
)
490 #if 1 /* JRA PARANOIA TEST - REMOVE LATER */
491 if (e1
->pid
== e2
->pid
&&
492 e1
->share_file_id
== e2
->share_file_id
&&
493 e1
->dev
== e2
->dev
&&
494 e1
->inode
== e2
->inode
&&
495 (e1
->share_mode
& ~DELETE_ON_CLOSE_FLAG
) != (e2
->share_mode
& ~DELETE_ON_CLOSE_FLAG
)) {
496 DEBUG(0,("PANIC: share_modes_identical: share_mode missmatch (e1 = %u, e2 = %u). Logic error.\n",
497 (unsigned int)(e1
->share_mode
& ~DELETE_ON_CLOSE_FLAG
),
498 (unsigned int)(e2
->share_mode
& ~DELETE_ON_CLOSE_FLAG
) ));
499 smb_panic("PANIC: share_modes_identical logic error.\n");
503 return (e1
->pid
== e2
->pid
&&
504 (e1
->share_mode
& ~DELETE_ON_CLOSE_FLAG
) == (e2
->share_mode
& ~DELETE_ON_CLOSE_FLAG
) &&
505 e1
->dev
== e2
->dev
&&
506 e1
->inode
== e2
->inode
&&
507 e1
->share_file_id
== e2
->share_file_id
);
510 /*******************************************************************
511 Delete a specific share mode. Return the number
512 of entries left, and a memdup'ed copy of the entry deleted (if required).
513 Ignore if no entry deleted.
514 ********************************************************************/
516 ssize_t
del_share_entry( SMB_DEV_T dev
, SMB_INO_T inode
,
517 share_mode_entry
*entry
, share_mode_entry
**ppse
)
520 struct locking_data
*data
;
522 share_mode_entry
*shares
;
528 /* read in the existing share modes */
529 dbuf
= tdb_fetch(tdb
, locking_key(dev
, inode
));
533 data
= (struct locking_data
*)dbuf
.dptr
;
534 shares
= (share_mode_entry
*)(dbuf
.dptr
+ sizeof(*data
));
537 * Find any with this pid and delete it
538 * by overwriting with the rest of the data
542 DEBUG(10,("del_share_entry: num_share_modes = %d\n", data
->u
.num_share_mode_entries
));
544 for (i
=0;i
<data
->u
.num_share_mode_entries
;) {
545 if (share_modes_identical(&shares
[i
], entry
)) {
546 DEBUG(10,("del_share_entry: deleted %s\n",
547 share_mode_str(i
, &shares
[i
]) ));
549 *ppse
= memdup(&shares
[i
], sizeof(*shares
));
550 data
->u
.num_share_mode_entries
--;
551 memmove(&shares
[i
], &shares
[i
+1],
552 dbuf
.dsize
- (sizeof(*data
) + (i
+1)*sizeof(*shares
)));
555 DEBUG(10,("del_share_entry: deleting entry %d\n", i
));
563 /* the record may have shrunk a bit */
564 dbuf
.dsize
-= del_count
* sizeof(*shares
);
566 count
= (ssize_t
)data
->u
.num_share_mode_entries
;
568 /* store it back in the database */
569 if (data
->u
.num_share_mode_entries
== 0) {
570 if (tdb_delete(tdb
, locking_key(dev
, inode
)) == -1)
573 if (tdb_store(tdb
, locking_key(dev
, inode
), dbuf
, TDB_REPLACE
) == -1)
577 DEBUG(10,("del_share_entry: Remaining table.\n"));
578 print_share_mode_table((struct locking_data
*)dbuf
.dptr
);
579 SAFE_FREE(dbuf
.dptr
);
583 /*******************************************************************
584 Del the share mode of a file for this process. Return the number
585 of entries left, and a memdup'ed copy of the entry deleted.
586 ********************************************************************/
588 ssize_t
del_share_mode(files_struct
*fsp
, share_mode_entry
**ppse
)
590 share_mode_entry entry
;
593 * Fake up a share_mode_entry for comparisons.
596 fill_share_mode((char *)&entry
, fsp
, 0, 0);
597 return del_share_entry(fsp
->dev
, fsp
->inode
, &entry
, ppse
);
600 /*******************************************************************
601 Set the share mode of a file. Return False on fail, True on success.
602 ********************************************************************/
604 BOOL
set_share_mode(files_struct
*fsp
, uint16 port
, uint16 op_type
)
607 struct locking_data
*data
;
612 /* read in the existing share modes if any */
613 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 pstrcpy(p
+ sizeof(*data
) + sizeof(share_mode_entry
), fname
);
633 fill_share_mode(p
+ sizeof(*data
), fsp
, port
, op_type
);
636 if (tdb_store(tdb
, locking_key_fsp(fsp
), dbuf
, TDB_REPLACE
) == -1)
639 print_share_mode_table((struct locking_data
*)p
);
645 /* we're adding to an existing entry - this is a bit fiddly */
646 data
= (struct locking_data
*)dbuf
.dptr
;
648 data
->u
.num_share_mode_entries
++;
650 DEBUG(10,("set_share_mode: adding entry for file %s. new num_share_modes = %d\n",
651 fsp
->fsp_name
, data
->u
.num_share_mode_entries
));
653 size
= dbuf
.dsize
+ sizeof(share_mode_entry
);
657 memcpy(p
, dbuf
.dptr
, sizeof(*data
));
658 fill_share_mode(p
+ sizeof(*data
), fsp
, port
, op_type
);
659 memcpy(p
+ sizeof(*data
) + sizeof(share_mode_entry
), dbuf
.dptr
+ sizeof(*data
),
660 dbuf
.dsize
- sizeof(*data
));
661 SAFE_FREE(dbuf
.dptr
);
664 if (tdb_store(tdb
, locking_key_fsp(fsp
), dbuf
, TDB_REPLACE
) == -1)
666 print_share_mode_table((struct locking_data
*)p
);
671 /*******************************************************************
672 A generic in-place modification call for share mode entries.
673 ********************************************************************/
675 static BOOL
mod_share_mode( SMB_DEV_T dev
, SMB_INO_T inode
, share_mode_entry
*entry
,
676 void (*mod_fn
)(share_mode_entry
*, SMB_DEV_T
, SMB_INO_T
, void *),
680 struct locking_data
*data
;
682 share_mode_entry
*shares
;
683 BOOL need_store
=False
;
686 /* read in the existing share modes */
687 dbuf
= tdb_fetch(tdb
, locking_key(dev
, inode
));
691 data
= (struct locking_data
*)dbuf
.dptr
;
692 shares
= (share_mode_entry
*)(dbuf
.dptr
+ sizeof(*data
));
694 /* find any with our pid and call the supplied function */
695 for (i
=0;i
<data
->u
.num_share_mode_entries
;i
++) {
696 if (share_modes_identical(entry
, &shares
[i
])) {
697 mod_fn(&shares
[i
], dev
, inode
, param
);
702 /* if the mod fn was called then store it back */
704 if (data
->u
.num_share_mode_entries
== 0) {
705 if (tdb_delete(tdb
, locking_key(dev
, inode
)) == -1)
708 if (tdb_store(tdb
, locking_key(dev
, inode
), dbuf
, TDB_REPLACE
) == -1)
713 SAFE_FREE(dbuf
.dptr
);
717 /*******************************************************************
718 Static function that actually does the work for the generic function
720 ********************************************************************/
722 static void remove_share_oplock_fn(share_mode_entry
*entry
, SMB_DEV_T dev
, SMB_INO_T inode
,
725 DEBUG(10,("remove_share_oplock_fn: removing oplock info for entry dev=%x ino=%.0f\n",
726 (unsigned int)dev
, (double)inode
));
727 /* Delete the oplock info. */
729 entry
->op_type
= NO_OPLOCK
;
732 /*******************************************************************
733 Remove an oplock port and mode entry from a share mode.
734 ********************************************************************/
736 BOOL
remove_share_oplock(files_struct
*fsp
)
738 share_mode_entry entry
;
740 * Fake up an entry for comparisons...
742 fill_share_mode((char *)&entry
, fsp
, 0, 0);
743 return mod_share_mode(fsp
->dev
, fsp
->inode
, &entry
, remove_share_oplock_fn
, NULL
);
746 /*******************************************************************
747 Static function that actually does the work for the generic function
749 ********************************************************************/
751 static void downgrade_share_oplock_fn(share_mode_entry
*entry
, SMB_DEV_T dev
, SMB_INO_T inode
,
754 DEBUG(10,("downgrade_share_oplock_fn: downgrading oplock info for entry dev=%x ino=%.0f\n",
755 (unsigned int)dev
, (double)inode
));
756 entry
->op_type
= LEVEL_II_OPLOCK
;
759 /*******************************************************************
760 Downgrade a oplock type from exclusive to level II.
761 ********************************************************************/
763 BOOL
downgrade_share_oplock(files_struct
*fsp
)
765 share_mode_entry entry
;
767 * Fake up an entry for comparisons...
769 fill_share_mode((char *)&entry
, fsp
, 0, 0);
770 return mod_share_mode(fsp
->dev
, fsp
->inode
, &entry
, downgrade_share_oplock_fn
, NULL
);
773 /*******************************************************************
774 Get/Set the delete on close flag in a set of share modes.
775 Return False on fail, True on success.
776 ********************************************************************/
778 BOOL
modify_delete_flag( SMB_DEV_T dev
, SMB_INO_T inode
, BOOL delete_on_close
)
781 struct locking_data
*data
;
783 share_mode_entry
*shares
;
785 /* read in the existing share modes */
786 dbuf
= tdb_fetch(tdb
, locking_key(dev
, inode
));
790 data
= (struct locking_data
*)dbuf
.dptr
;
791 shares
= (share_mode_entry
*)(dbuf
.dptr
+ sizeof(*data
));
793 /* Set/Unset the delete on close element. */
794 for (i
=0;i
<data
->u
.num_share_mode_entries
;i
++,shares
++) {
795 shares
->share_mode
= (delete_on_close
?
796 (shares
->share_mode
| DELETE_ON_CLOSE_FLAG
) :
797 (shares
->share_mode
& ~DELETE_ON_CLOSE_FLAG
) );
801 if (data
->u
.num_share_mode_entries
) {
802 if (tdb_store(tdb
, locking_key(dev
,inode
), dbuf
, TDB_REPLACE
)==-1) {
803 SAFE_FREE(dbuf
.dptr
);
808 SAFE_FREE(dbuf
.dptr
);
812 /****************************************************************************
813 Traverse the whole database with this function, calling traverse_callback
815 ****************************************************************************/
817 static int traverse_fn(TDB_CONTEXT
*the_tdb
, TDB_DATA kbuf
, TDB_DATA dbuf
,
820 struct locking_data
*data
;
821 share_mode_entry
*shares
;
825 SHAREMODE_FN(traverse_callback
) = (SHAREMODE_FN_CAST())state
;
827 data
= (struct locking_data
*)dbuf
.dptr
;
828 shares
= (share_mode_entry
*)(dbuf
.dptr
+ sizeof(*data
));
829 name
= dbuf
.dptr
+ sizeof(*data
) + data
->u
.num_share_mode_entries
*sizeof(*shares
);
831 for (i
=0;i
<data
->u
.num_share_mode_entries
;i
++) {
832 traverse_callback(&shares
[i
], name
);
837 /*******************************************************************
838 Call the specified function on each entry under management by the
840 ********************************************************************/
842 int share_mode_forall(SHAREMODE_FN(fn
))
846 return tdb_traverse(tdb
, traverse_fn
, (void*)fn
);