2 Unix SMB/Netbios implementation.
4 slow (lockfile) locking implementation
5 Copyright (C) Andrew Tridgell 1992-1997
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 October 1997 - split into separate file (tridge)
36 extern int DEBUGLEVEL;
37 extern connection_struct Connections[];
38 extern files_struct Files[];
41 * Locking file header lengths & offsets.
43 #define SMF_VERSION_OFFSET 0
44 #define SMF_NUM_ENTRIES_OFFSET 4
45 #define SMF_FILENAME_LEN_OFFSET 8
46 #define SMF_HEADER_LENGTH 10
48 #define SMF_ENTRY_LENGTH 20
51 * Share mode record offsets.
54 #define SME_SEC_OFFSET 0
55 #define SME_USEC_OFFSET 4
56 #define SME_SHAREMODE_OFFSET 8
57 #define SME_PID_OFFSET 12
58 #define SME_PORT_OFFSET 16
59 #define SME_OPLOCK_TYPE_OFFSET 18
61 /* we need world read for smbstatus to function correctly */
62 #ifdef SECURE_SHARE_MODES
63 #define SHARE_FILE_MODE 0600
65 #define SHARE_FILE_MODE 0644
70 /*******************************************************************
71 deinitialize share_mode management
72 ******************************************************************/
73 static BOOL slow_stop_share_mode_mgmt(void)
79 /*******************************************************************
81 ******************************************************************/
82 static BOOL share_name(int cnum, uint32 dev, uint32 inode, char *name)
84 strcpy(name,lp_lockdir());
85 trim_string(name,"","/");
86 if (!*name) return(False);
89 sprintf(name,"/share.%u.%u",dev,inode);
93 /*******************************************************************
94 Force a share file to be deleted.
95 ********************************************************************/
96 static int delete_share_file( int cnum, char *fname )
98 if (read_only) return -1;
100 /* the share file could be owned by anyone, so do this as root */
103 if(unlink(fname) != 0)
105 DEBUG(0,("delete_share_file: Can't delete share file %s (%s)\n",
106 fname, strerror(errno)));
110 DEBUG(5,("delete_share_file: Deleted share file %s\n", fname));
113 /* return to our previous privilage level */
114 unbecome_root(False);
119 /*******************************************************************
120 lock a share mode file.
121 ******************************************************************/
122 static BOOL slow_lock_share_entry(int cnum, uint32 dev, uint32 inode, int *ptok)
130 if(!share_name(cnum, dev, inode, fname))
133 if (read_only) return True;
135 /* we need to do this as root */
139 BOOL gotlock = False;
141 * There was a race condition in the original slow share mode code.
142 * A smbd could open a share mode file, and before getting
143 * the lock, another smbd could delete the last entry for
144 * the share mode file and delete the file entry from the
145 * directory. Thus this smbd would be left with a locked
146 * share mode fd attached to a file that no longer had a
147 * directory entry. Thus another smbd would think that
148 * there were no outstanding opens on the file. To fix
149 * this we now check we can do a stat() call on the filename
150 * before allowing the lock to proceed, and back out completely
151 * and try the open again if we cannot.
152 * Jeremy Allison (jallison@whistle.com).
157 struct stat dummy_stat;
159 fd = (int)open(fname,read_only?O_RDONLY:(O_RDWR|O_CREAT),
164 DEBUG(0,("ERROR lock_share_entry: failed to open share file %s. Error was %s\n",
165 fname, strerror(errno)));
170 /* At this point we have an open fd to the share mode file.
171 Lock the first byte exclusively to signify a lock. */
172 if(fcntl_lock(fd, F_SETLKW, 0, 1, F_WRLCK) == False)
174 DEBUG(0,("ERROR lock_share_entry: fcntl_lock on file %s failed with %s\n",
175 fname, strerror(errno)));
182 * If we cannot stat the filename, the file was deleted between
183 * the open and the lock call. Back out and try again.
186 if(stat(fname, &dummy_stat)!=0)
188 DEBUG(2,("lock_share_entry: Re-issuing open on %s to fix race. Error was %s\n",
189 fname, strerror(errno)));
197 * We have to come here if any of the above calls fail
198 * as we don't want to return and leave ourselves running
205 /* return to our previous privilage level */
206 unbecome_root(False);
211 /*******************************************************************
212 unlock a share mode file.
213 ******************************************************************/
214 static BOOL slow_unlock_share_entry(int cnum, uint32 dev, uint32 inode, int token)
221 if (read_only) return True;
223 /* Fix for zero length share files from
224 Gerald Werner <wernerg@mfldclin.edu> */
226 share_name(cnum, dev, inode, fname);
228 /* get the share mode file size */
229 if(fstat((int)token, &sb) != 0)
231 DEBUG(0,("ERROR: unlock_share_entry: Failed to do stat on share file %s (%s)\n",
232 fname, strerror(errno)));
237 /* If the file was zero length, we must delete before
238 doing the unlock to avoid a race condition (see
239 the code in lock_share_mode_entry for details.
242 /* remove the share file if zero length */
244 delete_share_file(cnum, fname);
246 /* token is the fd of the open share mode file. */
247 /* Unlock the first byte. */
248 if(fcntl_lock(fd, F_SETLKW, 0, 1, F_UNLCK) == False)
250 DEBUG(0,("ERROR unlock_share_entry: fcntl_lock failed with %s\n",
259 /*******************************************************************
260 Read a share file into a buffer.
261 ********************************************************************/
262 static int read_share_file(int cnum, int fd, char *fname, char **out, BOOL *p_new_file)
271 if(fstat(fd, &sb) != 0)
273 DEBUG(0,("ERROR: read_share_file: Failed to do stat on share file %s (%s)\n",
274 fname, strerror(errno)));
284 /* Allocate space for the file */
285 if((buf = (char *)malloc(sb.st_size)) == NULL)
287 DEBUG(0,("read_share_file: malloc for file size %d fail !\n", sb.st_size));
291 if(lseek(fd, 0, SEEK_SET) != 0)
293 DEBUG(0,("ERROR: read_share_file: Failed to reset position to 0 \
294 for share file %s (%s)\n", fname, strerror(errno)));
300 if (read(fd,buf,sb.st_size) != sb.st_size)
302 DEBUG(0,("ERROR: read_share_file: Failed to read share file %s (%s)\n",
303 fname, strerror(errno)));
309 if (IVAL(buf,SMF_VERSION_OFFSET) != LOCKING_VERSION) {
310 DEBUG(0,("ERROR: read_share_file: share file %s has incorrect \
311 locking version (was %d, should be %d).\n",fname,
312 IVAL(buf,SMF_VERSION_OFFSET), LOCKING_VERSION));
315 delete_share_file(cnum, fname);
319 /* Sanity check for file contents */
321 size -= SMF_HEADER_LENGTH; /* Remove the header */
323 /* Remove the filename component. */
324 size -= SVAL(buf, SMF_FILENAME_LEN_OFFSET);
326 /* The remaining size must be a multiple of SMF_ENTRY_LENGTH - error if not. */
327 if((size % SMF_ENTRY_LENGTH) != 0)
329 DEBUG(0,("ERROR: read_share_file: share file %s is an incorrect length - \
330 deleting it.\n", fname));
333 delete_share_file(cnum, fname);
341 /*******************************************************************
342 get all share mode entries in a share file for a dev/inode pair.
343 ********************************************************************/
344 static int slow_get_share_modes(int cnum, int token, uint32 dev, uint32 inode,
345 share_mode_entry **old_shares)
351 int num_entries_copied;
353 share_mode_entry *share_array;
360 /* Read the share file header - this is of the form:
362 4 - number of share mode entries.
363 8 - 2 byte name length
364 [n bytes] file name (zero terminated).
366 Followed by <n> share mode entries of the form :
372 16 - oplock port (if oplocks in use) - 2 bytes.
375 share_name(cnum, dev, inode, fname);
377 if(read_share_file( cnum, fd, fname, &buf, &new_file) != 0)
379 DEBUG(0,("ERROR: get_share_modes: Failed to read share file %s\n",
387 num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
389 DEBUG(5,("get_share_modes: share file %s has %d share mode entries.\n",
390 fname, num_entries));
395 DEBUG(0,("PANIC ERROR:get_share_mode: num_share_mode_entries < 0 (%d) \
396 for share file %d\n", num_entries, fname));
402 *old_shares = share_array = (share_mode_entry *)
403 malloc(num_entries * sizeof(share_mode_entry));
406 DEBUG(0,("get_share_modes: malloc fail !\n"));
412 /* No entries - just delete the file. */
413 DEBUG(0,("get_share_modes: share file %s has no share mode entries - deleting.\n",
417 delete_share_file(cnum, fname);
421 num_entries_copied = 0;
422 base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
424 for( i = 0; i < num_entries; i++)
427 char *p = base + (i*SMF_ENTRY_LENGTH);
429 pid = IVAL(p,SME_PID_OFFSET);
431 if(!process_exists(pid))
433 DEBUG(0,("get_share_modes: process %d no longer exists and \
434 it left a share mode entry with mode 0x%X in share file %s\n",
435 pid, IVAL(p,SME_SHAREMODE_OFFSET), fname));
438 share_array[num_entries_copied].time.tv_sec = IVAL(p,SME_SEC_OFFSET);
439 share_array[num_entries_copied].time.tv_usec = IVAL(p,SME_USEC_OFFSET);
440 share_array[num_entries_copied].share_mode = IVAL(p,SME_SHAREMODE_OFFSET);
441 share_array[num_entries_copied].pid = pid;
442 share_array[num_entries_copied].op_port = SVAL(p,SME_PORT_OFFSET);
443 share_array[num_entries_copied].op_type = SVAL(p,SME_OPLOCK_TYPE_OFFSET);
445 num_entries_copied++;
448 if(num_entries_copied == 0)
450 /* Delete the whole file. */
451 DEBUG(0,("get_share_modes: share file %s had no valid entries - deleting it !\n",
454 free((char *)*old_shares);
458 delete_share_file(cnum, fname);
462 /* If we deleted some entries we need to re-write the whole number of
463 share mode entries back into the file. */
465 if(num_entries_copied != num_entries)
467 if(lseek(fd, 0, SEEK_SET) != 0)
469 DEBUG(0,("ERROR: get_share_modes: lseek failed to reset to \
470 position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
472 free((char *)*old_shares);
479 SIVAL(buf, SMF_NUM_ENTRIES_OFFSET, num_entries_copied);
480 for( i = 0; i < num_entries_copied; i++)
482 char *p = base + (i*SMF_ENTRY_LENGTH);
484 SIVAL(p,SME_PID_OFFSET,share_array[i].pid);
485 SIVAL(p,SME_SHAREMODE_OFFSET,share_array[i].share_mode);
486 SIVAL(p,SME_SEC_OFFSET,share_array[i].time.tv_sec);
487 SIVAL(p,SME_USEC_OFFSET,share_array[i].time.tv_usec);
488 SSVAL(p,SME_PORT_OFFSET,share_array[i].op_port);
489 SSVAL(p,SME_OPLOCK_TYPE_OFFSET,share_array[i].op_type);
492 newsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries_copied);
493 if(write(fd, buf, newsize) != newsize)
495 DEBUG(0,("ERROR: get_share_modes: failed to re-write share \
496 mode file %s (%s)\n", fname, strerror(errno)));
498 free((char *)*old_shares);
504 /* Now truncate the file at this point. */
505 if(ftruncate(fd, newsize)!= 0)
507 DEBUG(0,("ERROR: get_share_modes: failed to ftruncate share \
508 mode file %s to size %d (%s)\n", fname, newsize, strerror(errno)));
510 free((char *)*old_shares);
521 DEBUG(5,("get_share_modes: Read share file %s returning %d entries\n",fname,
522 num_entries_copied));
524 return num_entries_copied;
527 /*******************************************************************
528 del a share mode from a share mode file.
529 ********************************************************************/
530 static void slow_del_share_mode(int token, int fnum)
539 files_struct *fs_p = &Files[fnum];
541 BOOL deleted = False;
544 share_name(fs_p->cnum, fs_p->fd_ptr->dev,
545 fs_p->fd_ptr->inode, fname);
547 if(read_share_file( fs_p->cnum, fd, fname, &buf, &new_file) != 0)
549 DEBUG(0,("ERROR: del_share_mode: Failed to read share file %s\n",
556 DEBUG(0,("ERROR:del_share_mode: share file %s is new (size zero), deleting it.\n",
558 delete_share_file(fs_p->cnum, fname);
562 num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
564 DEBUG(5,("del_share_mode: share file %s has %d share mode entries.\n",
565 fname, num_entries));
570 DEBUG(0,("PANIC ERROR:del_share_mode: num_share_mode_entries < 0 (%d) \
571 for share file %d\n", num_entries, fname));
577 /* No entries - just delete the file. */
578 DEBUG(0,("del_share_mode: share file %s has no share mode entries - deleting.\n",
582 delete_share_file(fs_p->cnum, fname);
588 /* Go through the entries looking for the particular one
589 we have set - delete it.
592 base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
594 for(i = 0; i < num_entries; i++)
596 char *p = base + (i*SMF_ENTRY_LENGTH);
598 if((IVAL(p,SME_SEC_OFFSET) != fs_p->open_time.tv_sec) ||
599 (IVAL(p,SME_USEC_OFFSET) != fs_p->open_time.tv_usec) ||
600 (IVAL(p,SME_SHAREMODE_OFFSET) != fs_p->share_mode) ||
601 (IVAL(p,SME_PID_OFFSET) != pid))
604 DEBUG(5,("del_share_mode: deleting entry number %d (of %d) from the share file %s\n",
605 i, num_entries, fname));
607 /* Remove this entry. */
608 if(i != num_entries - 1)
609 memcpy(p, p + SMF_ENTRY_LENGTH, (num_entries - i - 1)*SMF_ENTRY_LENGTH);
617 DEBUG(0,("del_share_mode: entry not found in share file %s\n", fname));
624 SIVAL(buf,SMF_NUM_ENTRIES_OFFSET, num_entries);
628 /* Deleted the last entry - remove the file. */
629 DEBUG(5,("del_share_mode: removed last entry in share file - deleting share file %s\n",
633 delete_share_file(fs_p->cnum,fname);
637 /* Re-write the file - and truncate it at the correct point. */
638 if(lseek(fd, 0, SEEK_SET) != 0)
640 DEBUG(0,("ERROR: del_share_mode: lseek failed to reset to \
641 position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
647 newsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries);
648 if(write(fd, buf, newsize) != newsize)
650 DEBUG(0,("ERROR: del_share_mode: failed to re-write share \
651 mode file %s (%s)\n", fname, strerror(errno)));
656 /* Now truncate the file at this point. */
657 if(ftruncate(fd, newsize) != 0)
659 DEBUG(0,("ERROR: del_share_mode: failed to ftruncate share \
660 mode file %s to size %d (%s)\n", fname, newsize, strerror(errno)));
667 /*******************************************************************
668 set the share mode of a file
669 ********************************************************************/
670 static BOOL slow_set_share_mode(int token,int fnum, uint16 port, uint16 op_type)
672 files_struct *fs_p = &Files[fnum];
675 int pid = (int)getpid();
682 share_name(fs_p->cnum, fs_p->fd_ptr->dev,
683 fs_p->fd_ptr->inode, fname);
685 if(fstat(fd, &sb) != 0)
687 DEBUG(0,("ERROR: set_share_mode: Failed to do stat on share file %s\n",
692 /* Sanity check for file contents (if it's not a new share file). */
695 int size = sb.st_size;
697 /* Allocate space for the file plus one extra entry */
698 if((buf = (char *)malloc(sb.st_size + SMF_ENTRY_LENGTH)) == NULL)
700 DEBUG(0,("set_share_mode: malloc for file size %d fail !\n",
701 sb.st_size + SMF_ENTRY_LENGTH));
705 if(lseek(fd, 0, SEEK_SET) != 0)
707 DEBUG(0,("ERROR: set_share_mode: Failed to reset position \
708 to 0 for share file %s (%s)\n", fname, strerror(errno)));
714 if (read(fd,buf,sb.st_size) != sb.st_size)
716 DEBUG(0,("ERROR: set_share_mode: Failed to read share file %s (%s)\n",
717 fname, strerror(errno)));
723 if (IVAL(buf,SMF_VERSION_OFFSET) != LOCKING_VERSION)
725 DEBUG(0,("ERROR: set_share_mode: share file %s has incorrect \
726 locking version (was %d, should be %d).\n",fname, IVAL(buf,SMF_VERSION_OFFSET),
730 delete_share_file(fs_p->cnum, fname);
734 size -= (SMF_HEADER_LENGTH + SVAL(buf, SMF_FILENAME_LEN_OFFSET)); /* Remove the header */
736 /* The remaining size must be a multiple of SMF_ENTRY_LENGTH - error if not. */
737 if((size % SMF_ENTRY_LENGTH) != 0)
739 DEBUG(0,("ERROR: set_share_mode: share file %s is an incorrect length - \
740 deleting it.\n", fname));
743 delete_share_file(fs_p->cnum, fname);
750 /* New file - just use a single_entry. */
751 if((buf = (char *)malloc(SMF_HEADER_LENGTH +
752 strlen(fs_p->name) + 1 + SMF_ENTRY_LENGTH)) == NULL)
754 DEBUG(0,("ERROR: set_share_mode: malloc failed for single entry.\n"));
757 SIVAL(buf,SMF_VERSION_OFFSET,LOCKING_VERSION);
758 SIVAL(buf,SMF_NUM_ENTRIES_OFFSET,0);
759 SSVAL(buf,SMF_FILENAME_LEN_OFFSET,strlen(fs_p->name) + 1);
760 strcpy(buf + SMF_HEADER_LENGTH, fs_p->name);
763 num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
764 header_size = SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
765 p = buf + header_size + (num_entries * SMF_ENTRY_LENGTH);
766 SIVAL(p,SME_SEC_OFFSET,fs_p->open_time.tv_sec);
767 SIVAL(p,SME_USEC_OFFSET,fs_p->open_time.tv_usec);
768 SIVAL(p,SME_SHAREMODE_OFFSET,fs_p->share_mode);
769 SIVAL(p,SME_PID_OFFSET,pid);
770 SSVAL(p,SME_PORT_OFFSET,port);
771 SSVAL(p,SME_OPLOCK_TYPE_OFFSET,op_type);
775 SIVAL(buf,SMF_NUM_ENTRIES_OFFSET,num_entries);
777 if(lseek(fd, 0, SEEK_SET) != 0)
779 DEBUG(0,("ERROR: set_share_mode: (1) Failed to reset position to \
780 0 for share file %s (%s)\n", fname, strerror(errno)));
786 if (write(fd,buf,header_size + (num_entries*SMF_ENTRY_LENGTH)) !=
787 (header_size + (num_entries*SMF_ENTRY_LENGTH)))
789 DEBUG(2,("ERROR: set_share_mode: Failed to write share file %s - \
790 deleting it (%s).\n",fname, strerror(errno)));
791 delete_share_file(fs_p->cnum, fname);
797 /* Now truncate the file at this point - just for safety. */
798 if(ftruncate(fd, header_size + (SMF_ENTRY_LENGTH*num_entries))!= 0)
800 DEBUG(0,("ERROR: set_share_mode: failed to ftruncate share \
801 mode file %s to size %d (%s)\n", fname, header_size + (SMF_ENTRY_LENGTH*num_entries),
811 DEBUG(3,("set_share_mode: Created share file %s with \
812 mode 0x%X pid=%d\n",fname,fs_p->share_mode,pid));
817 /*******************************************************************
818 Remove an oplock port and mode entry from a share mode.
819 ********************************************************************/
820 static BOOL slow_remove_share_oplock(int fnum, int token)
829 files_struct *fs_p = &Files[fnum];
834 share_name(fs_p->cnum, fs_p->fd_ptr->dev,
835 fs_p->fd_ptr->inode, fname);
837 if(read_share_file( fs_p->cnum, fd, fname, &buf, &new_file) != 0)
839 DEBUG(0,("ERROR: remove_share_oplock: Failed to read share file %s\n",
846 DEBUG(0,("ERROR: remove_share_oplock: share file %s is new (size zero), \
847 deleting it.\n", fname));
848 delete_share_file(fs_p->cnum, fname);
852 num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
854 DEBUG(5,("remove_share_oplock: share file %s has %d share mode entries.\n",
855 fname, num_entries));
860 DEBUG(0,("PANIC ERROR:remove_share_oplock: num_share_mode_entries < 0 (%d) \
861 for share file %d\n", num_entries, fname));
867 /* No entries - just delete the file. */
868 DEBUG(0,("remove_share_oplock: share file %s has no share mode entries - deleting.\n",
872 delete_share_file(fs_p->cnum, fname);
878 /* Go through the entries looking for the particular one
879 we have set - remove the oplock settings on it.
882 base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
884 for(i = 0; i < num_entries; i++)
886 char *p = base + (i*SMF_ENTRY_LENGTH);
888 if((IVAL(p,SME_SEC_OFFSET) != fs_p->open_time.tv_sec) ||
889 (IVAL(p,SME_USEC_OFFSET) != fs_p->open_time.tv_usec) ||
890 (IVAL(p,SME_SHAREMODE_OFFSET) != fs_p->share_mode) ||
891 (IVAL(p,SME_PID_OFFSET) != pid))
894 DEBUG(5,("remove_share_oplock: clearing oplock on entry number %d (of %d) \
895 from the share file %s\n", i, num_entries, fname));
897 SSVAL(p,SME_PORT_OFFSET,0);
898 SSVAL(p,SME_OPLOCK_TYPE_OFFSET,0);
905 DEBUG(0,("remove_share_oplock: entry not found in share file %s\n", fname));
911 /* Re-write the file - and truncate it at the correct point. */
912 if(lseek(fd, 0, SEEK_SET) != 0)
914 DEBUG(0,("ERROR: remove_share_oplock: lseek failed to reset to \
915 position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
921 fsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries);
922 if(write(fd, buf, fsize) != fsize)
924 DEBUG(0,("ERROR: remove_share_oplock: failed to re-write share \
925 mode file %s (%s)\n", fname, strerror(errno)));
936 /*******************************************************************
937 call the specified function on each entry under management by the
939 ********************************************************************/
940 static int slow_share_forall(void (*fn)(share_mode_entry *, char *))
947 dir = opendir(lp_lockdir());
952 while ((s=readdirname(dir))) {
961 if (sscanf(s,"share.%u.%u",&dev,&inode)!=2) continue;
963 strcpy(lname,lp_lockdir());
964 trim_string(lname,NULL,"/");
968 fd = open(lname,read_only?O_RDONLY:O_RDWR,0);
973 /* Lock the share mode file while we read it. */
975 fcntl_lock(fd, F_SETLKW, 0, 1, F_WRLCK) == False) {
980 if(read_share_file( 0, fd, lname, &buf, &new_file)) {
984 strcpy( fname, &buf[10]);
987 base = buf + SMF_HEADER_LENGTH +
988 SVAL(buf,SMF_FILENAME_LEN_OFFSET);
989 for( i = 0; i < IVAL(buf, SMF_NUM_ENTRIES_OFFSET); i++) {
990 char *p = base + (i*SMF_ENTRY_LENGTH);
991 e.pid = IVAL(p,SME_PID_OFFSET);
992 e.share_mode = IVAL(p,SME_SHAREMODE_OFFSET);
993 e.time.tv_sec = IVAL(p,SME_SEC_OFFSET);
994 e.time.tv_usec = IVAL(p,SME_USEC_OFFSET);
995 e.op_port = SVAL(p,SME_PORT_OFFSET);
996 e.pid = SVAL(p,SME_PID_OFFSET);
997 e.op_type = SVAL(p,SME_OPLOCK_TYPE_OFFSET);
1013 /*******************************************************************
1014 dump the state of the system
1015 ********************************************************************/
1016 static void slow_share_status(FILE *f)
1022 static struct share_ops share_ops = {
1023 slow_stop_share_mode_mgmt,
1024 slow_lock_share_entry,
1025 slow_unlock_share_entry,
1026 slow_get_share_modes,
1027 slow_del_share_mode,
1028 slow_set_share_mode,
1029 slow_remove_share_oplock,
1034 /*******************************************************************
1035 initialize the slow share_mode management
1036 ******************************************************************/
1037 struct share_ops *locking_slow_init(int ronly)
1042 if (!directory_exist(lp_lockdir(),NULL)) {
1044 mkdir(lp_lockdir(),0755);
1045 if (!directory_exist(lp_lockdir(),NULL))