2 Unix SMB/Netbios implementation.
4 slow (lockfile) locking implementation
5 Copyright (C) Andrew Tridgell 1992-1998
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 #ifdef FTRUNCATE_NEEDS_ROOT
507 #endif /* FTRUNCATE_NEEDS_ROOT */
509 if(ftruncate(fd, newsize)!= 0)
512 #ifdef FTRUNCATE_NEEDS_ROOT
513 unbecome_root(False);
514 #endif /* FTRUNCATE_NEEDS_ROOT */
516 DEBUG(0,("ERROR: get_share_modes: failed to ftruncate share \
517 mode file %s to size %d (%s)\n", fname, newsize, strerror(errno)));
519 free((char *)*old_shares);
527 #ifdef FTRUNCATE_NEEDS_ROOT
528 unbecome_root(False);
529 #endif /* FTRUNCATE_NEEDS_ROOT */
534 DEBUG(5,("get_share_modes: Read share file %s returning %d entries\n",fname,
535 num_entries_copied));
537 return num_entries_copied;
540 /*******************************************************************
541 del a share mode from a share mode file.
542 ********************************************************************/
543 static void slow_del_share_mode(int token, int fnum)
552 files_struct *fs_p = &Files[fnum];
554 BOOL deleted = False;
557 share_name(fs_p->cnum, fs_p->fd_ptr->dev,
558 fs_p->fd_ptr->inode, fname);
560 if(read_share_file( fs_p->cnum, fd, fname, &buf, &new_file) != 0)
562 DEBUG(0,("ERROR: del_share_mode: Failed to read share file %s\n",
569 DEBUG(0,("ERROR:del_share_mode: share file %s is new (size zero), deleting it.\n",
571 delete_share_file(fs_p->cnum, fname);
575 num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
577 DEBUG(5,("del_share_mode: share file %s has %d share mode entries.\n",
578 fname, num_entries));
583 DEBUG(0,("PANIC ERROR:del_share_mode: num_share_mode_entries < 0 (%d) \
584 for share file %d\n", num_entries, fname));
590 /* No entries - just delete the file. */
591 DEBUG(0,("del_share_mode: share file %s has no share mode entries - deleting.\n",
595 delete_share_file(fs_p->cnum, fname);
601 /* Go through the entries looking for the particular one
602 we have set - delete it.
605 base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
607 for(i = 0; i < num_entries; i++)
609 char *p = base + (i*SMF_ENTRY_LENGTH);
611 if((IVAL(p,SME_SEC_OFFSET) != fs_p->open_time.tv_sec) ||
612 (IVAL(p,SME_USEC_OFFSET) != fs_p->open_time.tv_usec) ||
613 (IVAL(p,SME_SHAREMODE_OFFSET) != fs_p->share_mode) ||
614 (IVAL(p,SME_PID_OFFSET) != pid))
617 DEBUG(5,("del_share_mode: deleting entry number %d (of %d) from the share file %s\n",
618 i, num_entries, fname));
620 /* Remove this entry. */
621 if(i != num_entries - 1)
622 memcpy(p, p + SMF_ENTRY_LENGTH, (num_entries - i - 1)*SMF_ENTRY_LENGTH);
630 DEBUG(0,("del_share_mode: entry not found in share file %s\n", fname));
637 SIVAL(buf,SMF_NUM_ENTRIES_OFFSET, num_entries);
641 /* Deleted the last entry - remove the file. */
642 DEBUG(5,("del_share_mode: removed last entry in share file - deleting share file %s\n",
646 delete_share_file(fs_p->cnum,fname);
650 /* Re-write the file - and truncate it at the correct point. */
651 if(lseek(fd, 0, SEEK_SET) != 0)
653 DEBUG(0,("ERROR: del_share_mode: lseek failed to reset to \
654 position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
660 newsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries);
661 if(write(fd, buf, newsize) != newsize)
663 DEBUG(0,("ERROR: del_share_mode: failed to re-write share \
664 mode file %s (%s)\n", fname, strerror(errno)));
670 /* Now truncate the file at this point. */
671 #ifdef FTRUNCATE_NEEDS_ROOT
673 #endif /* FTRUNCATE_NEEDS_ROOT */
675 if(ftruncate(fd, newsize) != 0)
678 #ifdef FTRUNCATE_NEEDS_ROOT
679 unbecome_root(False);
680 #endif /* FTRUNCATE_NEEDS_ROOT */
682 DEBUG(0,("ERROR: del_share_mode: failed to ftruncate share \
683 mode file %s to size %d (%s)\n", fname, newsize, strerror(errno)));
689 #ifdef FTRUNCATE_NEEDS_ROOT
690 unbecome_root(False);
691 #endif /* FTRUNCATE_NEEDS_ROOT */
694 /*******************************************************************
695 set the share mode of a file
696 ********************************************************************/
697 static BOOL slow_set_share_mode(int token,int fnum, uint16 port, uint16 op_type)
699 files_struct *fs_p = &Files[fnum];
702 int pid = (int)getpid();
709 share_name(fs_p->cnum, fs_p->fd_ptr->dev,
710 fs_p->fd_ptr->inode, fname);
712 if(fstat(fd, &sb) != 0)
714 DEBUG(0,("ERROR: set_share_mode: Failed to do stat on share file %s\n",
719 /* Sanity check for file contents (if it's not a new share file). */
722 int size = sb.st_size;
724 /* Allocate space for the file plus one extra entry */
725 if((buf = (char *)malloc(sb.st_size + SMF_ENTRY_LENGTH)) == NULL)
727 DEBUG(0,("set_share_mode: malloc for file size %d fail !\n",
728 sb.st_size + SMF_ENTRY_LENGTH));
732 if(lseek(fd, 0, SEEK_SET) != 0)
734 DEBUG(0,("ERROR: set_share_mode: Failed to reset position \
735 to 0 for share file %s (%s)\n", fname, strerror(errno)));
741 if (read(fd,buf,sb.st_size) != sb.st_size)
743 DEBUG(0,("ERROR: set_share_mode: Failed to read share file %s (%s)\n",
744 fname, strerror(errno)));
750 if (IVAL(buf,SMF_VERSION_OFFSET) != LOCKING_VERSION)
752 DEBUG(0,("ERROR: set_share_mode: share file %s has incorrect \
753 locking version (was %d, should be %d).\n",fname, IVAL(buf,SMF_VERSION_OFFSET),
757 delete_share_file(fs_p->cnum, fname);
761 size -= (SMF_HEADER_LENGTH + SVAL(buf, SMF_FILENAME_LEN_OFFSET)); /* Remove the header */
763 /* The remaining size must be a multiple of SMF_ENTRY_LENGTH - error if not. */
764 if((size % SMF_ENTRY_LENGTH) != 0)
766 DEBUG(0,("ERROR: set_share_mode: share file %s is an incorrect length - \
767 deleting it.\n", fname));
770 delete_share_file(fs_p->cnum, fname);
777 /* New file - just use a single_entry. */
778 if((buf = (char *)malloc(SMF_HEADER_LENGTH +
779 strlen(fs_p->name) + 1 + SMF_ENTRY_LENGTH)) == NULL)
781 DEBUG(0,("ERROR: set_share_mode: malloc failed for single entry.\n"));
784 SIVAL(buf,SMF_VERSION_OFFSET,LOCKING_VERSION);
785 SIVAL(buf,SMF_NUM_ENTRIES_OFFSET,0);
786 SSVAL(buf,SMF_FILENAME_LEN_OFFSET,strlen(fs_p->name) + 1);
787 strcpy(buf + SMF_HEADER_LENGTH, fs_p->name);
790 num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
791 header_size = SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
792 p = buf + header_size + (num_entries * SMF_ENTRY_LENGTH);
793 SIVAL(p,SME_SEC_OFFSET,fs_p->open_time.tv_sec);
794 SIVAL(p,SME_USEC_OFFSET,fs_p->open_time.tv_usec);
795 SIVAL(p,SME_SHAREMODE_OFFSET,fs_p->share_mode);
796 SIVAL(p,SME_PID_OFFSET,pid);
797 SSVAL(p,SME_PORT_OFFSET,port);
798 SSVAL(p,SME_OPLOCK_TYPE_OFFSET,op_type);
802 SIVAL(buf,SMF_NUM_ENTRIES_OFFSET,num_entries);
804 if(lseek(fd, 0, SEEK_SET) != 0)
806 DEBUG(0,("ERROR: set_share_mode: (1) Failed to reset position to \
807 0 for share file %s (%s)\n", fname, strerror(errno)));
813 if (write(fd,buf,header_size + (num_entries*SMF_ENTRY_LENGTH)) !=
814 (header_size + (num_entries*SMF_ENTRY_LENGTH)))
816 DEBUG(2,("ERROR: set_share_mode: Failed to write share file %s - \
817 deleting it (%s).\n",fname, strerror(errno)));
818 delete_share_file(fs_p->cnum, fname);
824 /* Now truncate the file at this point - just for safety. */
826 #ifdef FTRUNCATE_NEEDS_ROOT
828 #endif /* FTRUNCATE_NEEDS_ROOT */
830 if(ftruncate(fd, header_size + (SMF_ENTRY_LENGTH*num_entries))!= 0)
833 #ifdef FTRUNCATE_NEEDS_ROOT
834 unbecome_root(False);
835 #endif /* FTRUNCATE_NEEDS_ROOT */
837 DEBUG(0,("ERROR: set_share_mode: failed to ftruncate share \
838 mode file %s to size %d (%s)\n", fname, header_size + (SMF_ENTRY_LENGTH*num_entries),
845 #ifdef FTRUNCATE_NEEDS_ROOT
846 unbecome_root(False);
847 #endif /* FTRUNCATE_NEEDS_ROOT */
852 DEBUG(3,("set_share_mode: Created share file %s with \
853 mode 0x%X pid=%d\n",fname,fs_p->share_mode,pid));
858 /*******************************************************************
859 Remove an oplock port and mode entry from a share mode.
860 ********************************************************************/
861 static BOOL slow_remove_share_oplock(int fnum, int token)
870 files_struct *fs_p = &Files[fnum];
875 share_name(fs_p->cnum, fs_p->fd_ptr->dev,
876 fs_p->fd_ptr->inode, fname);
878 if(read_share_file( fs_p->cnum, fd, fname, &buf, &new_file) != 0)
880 DEBUG(0,("ERROR: remove_share_oplock: Failed to read share file %s\n",
887 DEBUG(0,("ERROR: remove_share_oplock: share file %s is new (size zero), \
888 deleting it.\n", fname));
889 delete_share_file(fs_p->cnum, fname);
893 num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
895 DEBUG(5,("remove_share_oplock: share file %s has %d share mode entries.\n",
896 fname, num_entries));
901 DEBUG(0,("PANIC ERROR:remove_share_oplock: num_share_mode_entries < 0 (%d) \
902 for share file %d\n", num_entries, fname));
908 /* No entries - just delete the file. */
909 DEBUG(0,("remove_share_oplock: share file %s has no share mode entries - deleting.\n",
913 delete_share_file(fs_p->cnum, fname);
919 /* Go through the entries looking for the particular one
920 we have set - remove the oplock settings on it.
923 base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
925 for(i = 0; i < num_entries; i++)
927 char *p = base + (i*SMF_ENTRY_LENGTH);
929 if((IVAL(p,SME_SEC_OFFSET) != fs_p->open_time.tv_sec) ||
930 (IVAL(p,SME_USEC_OFFSET) != fs_p->open_time.tv_usec) ||
931 (IVAL(p,SME_SHAREMODE_OFFSET) != fs_p->share_mode) ||
932 (IVAL(p,SME_PID_OFFSET) != pid))
935 DEBUG(5,("remove_share_oplock: clearing oplock on entry number %d (of %d) \
936 from the share file %s\n", i, num_entries, fname));
938 SSVAL(p,SME_PORT_OFFSET,0);
939 SSVAL(p,SME_OPLOCK_TYPE_OFFSET,0);
946 DEBUG(0,("remove_share_oplock: entry not found in share file %s\n", fname));
952 /* Re-write the file - and truncate it at the correct point. */
953 if(lseek(fd, 0, SEEK_SET) != 0)
955 DEBUG(0,("ERROR: remove_share_oplock: lseek failed to reset to \
956 position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
962 fsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries);
963 if(write(fd, buf, fsize) != fsize)
965 DEBUG(0,("ERROR: remove_share_oplock: failed to re-write share \
966 mode file %s (%s)\n", fname, strerror(errno)));
977 /*******************************************************************
978 call the specified function on each entry under management by the
980 ********************************************************************/
981 static int slow_share_forall(void (*fn)(share_mode_entry *, char *))
988 dir = opendir(lp_lockdir());
993 while ((s=readdirname(dir))) {
1002 if (sscanf(s,"share.%u.%u",&dev,&inode)!=2) continue;
1004 strcpy(lname,lp_lockdir());
1005 trim_string(lname,NULL,"/");
1009 fd = open(lname,read_only?O_RDONLY:O_RDWR,0);
1014 /* Lock the share mode file while we read it. */
1016 fcntl_lock(fd, F_SETLKW, 0, 1, F_WRLCK) == False) {
1021 if(read_share_file( 0, fd, lname, &buf, &new_file)) {
1025 strcpy( fname, &buf[10]);
1028 base = buf + SMF_HEADER_LENGTH +
1029 SVAL(buf,SMF_FILENAME_LEN_OFFSET);
1030 for( i = 0; i < IVAL(buf, SMF_NUM_ENTRIES_OFFSET); i++) {
1031 char *p = base + (i*SMF_ENTRY_LENGTH);
1032 e.pid = IVAL(p,SME_PID_OFFSET);
1033 e.share_mode = IVAL(p,SME_SHAREMODE_OFFSET);
1034 e.time.tv_sec = IVAL(p,SME_SEC_OFFSET);
1035 e.time.tv_usec = IVAL(p,SME_USEC_OFFSET);
1036 e.op_port = SVAL(p,SME_PORT_OFFSET);
1037 e.pid = SVAL(p,SME_PID_OFFSET);
1038 e.op_type = SVAL(p,SME_OPLOCK_TYPE_OFFSET);
1040 if (process_exists(e.pid)) {
1056 /*******************************************************************
1057 dump the state of the system
1058 ********************************************************************/
1059 static void slow_share_status(FILE *f)
1065 static struct share_ops share_ops = {
1066 slow_stop_share_mode_mgmt,
1067 slow_lock_share_entry,
1068 slow_unlock_share_entry,
1069 slow_get_share_modes,
1070 slow_del_share_mode,
1071 slow_set_share_mode,
1072 slow_remove_share_oplock,
1077 /*******************************************************************
1078 initialize the slow share_mode management
1079 ******************************************************************/
1080 struct share_ops *locking_slow_init(int ronly)
1085 if (!directory_exist(lp_lockdir(),NULL)) {
1087 mkdir(lp_lockdir(),0755);
1088 if (!directory_exist(lp_lockdir(),NULL))