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)
85 pstrcpy(name,lp_lockdir());
86 trim_string(name,"","/");
87 if (!*name) return(False);
91 slprintf(name, sizeof(pstring) - len - 1, "/share.%u.%u",dev,inode);
95 /*******************************************************************
96 Force a share file to be deleted.
97 ********************************************************************/
98 static int delete_share_file( int cnum, char *fname )
100 if (read_only) return -1;
102 /* the share file could be owned by anyone, so do this as root */
105 if(unlink(fname) != 0)
107 DEBUG(0,("delete_share_file: Can't delete share file %s (%s)\n",
108 fname, strerror(errno)));
112 DEBUG(5,("delete_share_file: Deleted share file %s\n", fname));
115 /* return to our previous privilage level */
116 unbecome_root(False);
121 /*******************************************************************
122 lock a share mode file.
123 ******************************************************************/
124 static BOOL slow_lock_share_entry(int cnum, uint32 dev, uint32 inode, int *ptok)
132 if(!share_name(cnum, dev, inode, fname))
135 if (read_only) return True;
137 /* we need to do this as root */
141 BOOL gotlock = False;
143 * There was a race condition in the original slow share mode code.
144 * A smbd could open a share mode file, and before getting
145 * the lock, another smbd could delete the last entry for
146 * the share mode file and delete the file entry from the
147 * directory. Thus this smbd would be left with a locked
148 * share mode fd attached to a file that no longer had a
149 * directory entry. Thus another smbd would think that
150 * there were no outstanding opens on the file. To fix
151 * this we now check we can do a stat() call on the filename
152 * before allowing the lock to proceed, and back out completely
153 * and try the open again if we cannot.
154 * Jeremy Allison (jallison@whistle.com).
159 struct stat dummy_stat;
161 fd = (int)open(fname,read_only?O_RDONLY:(O_RDWR|O_CREAT),
166 DEBUG(0,("ERROR lock_share_entry: failed to open share file %s. Error was %s\n",
167 fname, strerror(errno)));
172 /* At this point we have an open fd to the share mode file.
173 Lock the first byte exclusively to signify a lock. */
174 if(fcntl_lock(fd, F_SETLKW, 0, 1, F_WRLCK) == False)
176 DEBUG(0,("ERROR lock_share_entry: fcntl_lock on file %s failed with %s\n",
177 fname, strerror(errno)));
184 * If we cannot stat the filename, the file was deleted between
185 * the open and the lock call. Back out and try again.
188 if(stat(fname, &dummy_stat)!=0)
190 DEBUG(2,("lock_share_entry: Re-issuing open on %s to fix race. Error was %s\n",
191 fname, strerror(errno)));
199 * We have to come here if any of the above calls fail
200 * as we don't want to return and leave ourselves running
207 /* return to our previous privilage level */
208 unbecome_root(False);
213 /*******************************************************************
214 unlock a share mode file.
215 ******************************************************************/
216 static BOOL slow_unlock_share_entry(int cnum, uint32 dev, uint32 inode, int token)
223 if (read_only) return True;
225 /* Fix for zero length share files from
226 Gerald Werner <wernerg@mfldclin.edu> */
228 share_name(cnum, dev, inode, fname);
230 /* get the share mode file size */
231 if(fstat((int)token, &sb) != 0)
233 DEBUG(0,("ERROR: unlock_share_entry: Failed to do stat on share file %s (%s)\n",
234 fname, strerror(errno)));
239 /* If the file was zero length, we must delete before
240 doing the unlock to avoid a race condition (see
241 the code in lock_share_mode_entry for details.
244 /* remove the share file if zero length */
246 delete_share_file(cnum, fname);
248 /* token is the fd of the open share mode file. */
249 /* Unlock the first byte. */
250 if(fcntl_lock(fd, F_SETLKW, 0, 1, F_UNLCK) == False)
252 DEBUG(0,("ERROR unlock_share_entry: fcntl_lock failed with %s\n",
261 /*******************************************************************
262 Read a share file into a buffer.
263 ********************************************************************/
264 static int read_share_file(int cnum, int fd, char *fname, char **out, BOOL *p_new_file)
273 if(fstat(fd, &sb) != 0)
275 DEBUG(0,("ERROR: read_share_file: Failed to do stat on share file %s (%s)\n",
276 fname, strerror(errno)));
286 /* Allocate space for the file */
287 if((buf = (char *)malloc(sb.st_size)) == NULL)
289 DEBUG(0,("read_share_file: malloc for file size %d fail !\n", sb.st_size));
293 if(lseek(fd, 0, SEEK_SET) != 0)
295 DEBUG(0,("ERROR: read_share_file: Failed to reset position to 0 \
296 for share file %s (%s)\n", fname, strerror(errno)));
302 if (read(fd,buf,sb.st_size) != sb.st_size)
304 DEBUG(0,("ERROR: read_share_file: Failed to read share file %s (%s)\n",
305 fname, strerror(errno)));
311 if (IVAL(buf,SMF_VERSION_OFFSET) != LOCKING_VERSION) {
312 DEBUG(0,("ERROR: read_share_file: share file %s has incorrect \
313 locking version (was %d, should be %d).\n",fname,
314 IVAL(buf,SMF_VERSION_OFFSET), LOCKING_VERSION));
317 delete_share_file(cnum, fname);
321 /* Sanity check for file contents */
323 size -= SMF_HEADER_LENGTH; /* Remove the header */
325 /* Remove the filename component. */
326 size -= SVAL(buf, SMF_FILENAME_LEN_OFFSET);
328 /* The remaining size must be a multiple of SMF_ENTRY_LENGTH - error if not. */
329 if((size % SMF_ENTRY_LENGTH) != 0)
331 DEBUG(0,("ERROR: read_share_file: share file %s is an incorrect length - \
332 deleting it.\n", fname));
335 delete_share_file(cnum, fname);
343 /*******************************************************************
344 get all share mode entries in a share file for a dev/inode pair.
345 ********************************************************************/
346 static int slow_get_share_modes(int cnum, int token, uint32 dev, uint32 inode,
347 share_mode_entry **old_shares)
353 int num_entries_copied;
355 share_mode_entry *share_array;
362 /* Read the share file header - this is of the form:
364 4 - number of share mode entries.
365 8 - 2 byte name length
366 [n bytes] file name (zero terminated).
368 Followed by <n> share mode entries of the form :
374 16 - oplock port (if oplocks in use) - 2 bytes.
377 share_name(cnum, dev, inode, fname);
379 if(read_share_file( cnum, fd, fname, &buf, &new_file) != 0)
381 DEBUG(0,("ERROR: get_share_modes: Failed to read share file %s\n",
389 num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
391 DEBUG(5,("get_share_modes: share file %s has %d share mode entries.\n",
392 fname, num_entries));
397 DEBUG(0,("PANIC ERROR:get_share_mode: num_share_mode_entries < 0 (%d) \
398 for share file %d\n", num_entries, fname));
404 *old_shares = share_array = (share_mode_entry *)
405 malloc(num_entries * sizeof(share_mode_entry));
408 DEBUG(0,("get_share_modes: malloc fail !\n"));
414 /* No entries - just delete the file. */
415 DEBUG(0,("get_share_modes: share file %s has no share mode entries - deleting.\n",
419 delete_share_file(cnum, fname);
423 num_entries_copied = 0;
424 base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
426 for( i = 0; i < num_entries; i++)
429 char *p = base + (i*SMF_ENTRY_LENGTH);
431 pid = IVAL(p,SME_PID_OFFSET);
433 if(!process_exists(pid))
435 DEBUG(0,("get_share_modes: process %d no longer exists and \
436 it left a share mode entry with mode 0x%X in share file %s\n",
437 pid, IVAL(p,SME_SHAREMODE_OFFSET), fname));
440 share_array[num_entries_copied].time.tv_sec = IVAL(p,SME_SEC_OFFSET);
441 share_array[num_entries_copied].time.tv_usec = IVAL(p,SME_USEC_OFFSET);
442 share_array[num_entries_copied].share_mode = IVAL(p,SME_SHAREMODE_OFFSET);
443 share_array[num_entries_copied].pid = pid;
444 share_array[num_entries_copied].op_port = SVAL(p,SME_PORT_OFFSET);
445 share_array[num_entries_copied].op_type = SVAL(p,SME_OPLOCK_TYPE_OFFSET);
447 num_entries_copied++;
450 if(num_entries_copied == 0)
452 /* Delete the whole file. */
453 DEBUG(0,("get_share_modes: share file %s had no valid entries - deleting it !\n",
456 free((char *)*old_shares);
460 delete_share_file(cnum, fname);
464 /* If we deleted some entries we need to re-write the whole number of
465 share mode entries back into the file. */
467 if(num_entries_copied != num_entries)
469 if(lseek(fd, 0, SEEK_SET) != 0)
471 DEBUG(0,("ERROR: get_share_modes: lseek failed to reset to \
472 position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
474 free((char *)*old_shares);
481 SIVAL(buf, SMF_NUM_ENTRIES_OFFSET, num_entries_copied);
482 for( i = 0; i < num_entries_copied; i++)
484 char *p = base + (i*SMF_ENTRY_LENGTH);
486 SIVAL(p,SME_PID_OFFSET,share_array[i].pid);
487 SIVAL(p,SME_SHAREMODE_OFFSET,share_array[i].share_mode);
488 SIVAL(p,SME_SEC_OFFSET,share_array[i].time.tv_sec);
489 SIVAL(p,SME_USEC_OFFSET,share_array[i].time.tv_usec);
490 SSVAL(p,SME_PORT_OFFSET,share_array[i].op_port);
491 SSVAL(p,SME_OPLOCK_TYPE_OFFSET,share_array[i].op_type);
494 newsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries_copied);
495 if(write(fd, buf, newsize) != newsize)
497 DEBUG(0,("ERROR: get_share_modes: failed to re-write share \
498 mode file %s (%s)\n", fname, strerror(errno)));
500 free((char *)*old_shares);
506 /* Now truncate the file at this point. */
507 #ifdef FTRUNCATE_NEEDS_ROOT
509 #endif /* FTRUNCATE_NEEDS_ROOT */
511 if(ftruncate(fd, newsize)!= 0)
514 #ifdef FTRUNCATE_NEEDS_ROOT
515 unbecome_root(False);
516 #endif /* FTRUNCATE_NEEDS_ROOT */
518 DEBUG(0,("ERROR: get_share_modes: failed to ftruncate share \
519 mode file %s to size %d (%s)\n", fname, newsize, strerror(errno)));
521 free((char *)*old_shares);
529 #ifdef FTRUNCATE_NEEDS_ROOT
530 unbecome_root(False);
531 #endif /* FTRUNCATE_NEEDS_ROOT */
536 DEBUG(5,("get_share_modes: Read share file %s returning %d entries\n",fname,
537 num_entries_copied));
539 return num_entries_copied;
542 /*******************************************************************
543 del a share mode from a share mode file.
544 ********************************************************************/
545 static void slow_del_share_mode(int token, int fnum)
554 files_struct *fs_p = &Files[fnum];
556 BOOL deleted = False;
559 share_name(fs_p->cnum, fs_p->fd_ptr->dev,
560 fs_p->fd_ptr->inode, fname);
562 if(read_share_file( fs_p->cnum, fd, fname, &buf, &new_file) != 0)
564 DEBUG(0,("ERROR: del_share_mode: Failed to read share file %s\n",
571 DEBUG(0,("ERROR:del_share_mode: share file %s is new (size zero), deleting it.\n",
573 delete_share_file(fs_p->cnum, fname);
577 num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
579 DEBUG(5,("del_share_mode: share file %s has %d share mode entries.\n",
580 fname, num_entries));
585 DEBUG(0,("PANIC ERROR:del_share_mode: num_share_mode_entries < 0 (%d) \
586 for share file %d\n", num_entries, fname));
592 /* No entries - just delete the file. */
593 DEBUG(0,("del_share_mode: share file %s has no share mode entries - deleting.\n",
597 delete_share_file(fs_p->cnum, fname);
603 /* Go through the entries looking for the particular one
604 we have set - delete it.
607 base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
609 for(i = 0; i < num_entries; i++)
611 char *p = base + (i*SMF_ENTRY_LENGTH);
613 if((IVAL(p,SME_SEC_OFFSET) != fs_p->open_time.tv_sec) ||
614 (IVAL(p,SME_USEC_OFFSET) != fs_p->open_time.tv_usec) ||
615 (IVAL(p,SME_SHAREMODE_OFFSET) != fs_p->share_mode) ||
616 (IVAL(p,SME_PID_OFFSET) != pid))
619 DEBUG(5,("del_share_mode: deleting entry number %d (of %d) from the share file %s\n",
620 i, num_entries, fname));
622 /* Remove this entry. */
623 if(i != num_entries - 1)
624 memcpy(p, p + SMF_ENTRY_LENGTH, (num_entries - i - 1)*SMF_ENTRY_LENGTH);
632 DEBUG(0,("del_share_mode: entry not found in share file %s\n", fname));
639 SIVAL(buf,SMF_NUM_ENTRIES_OFFSET, num_entries);
643 /* Deleted the last entry - remove the file. */
644 DEBUG(5,("del_share_mode: removed last entry in share file - deleting share file %s\n",
648 delete_share_file(fs_p->cnum,fname);
652 /* Re-write the file - and truncate it at the correct point. */
653 if(lseek(fd, 0, SEEK_SET) != 0)
655 DEBUG(0,("ERROR: del_share_mode: lseek failed to reset to \
656 position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
662 newsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries);
663 if(write(fd, buf, newsize) != newsize)
665 DEBUG(0,("ERROR: del_share_mode: failed to re-write share \
666 mode file %s (%s)\n", fname, strerror(errno)));
672 /* Now truncate the file at this point. */
673 #ifdef FTRUNCATE_NEEDS_ROOT
675 #endif /* FTRUNCATE_NEEDS_ROOT */
677 if(ftruncate(fd, newsize) != 0)
680 #ifdef FTRUNCATE_NEEDS_ROOT
681 unbecome_root(False);
682 #endif /* FTRUNCATE_NEEDS_ROOT */
684 DEBUG(0,("ERROR: del_share_mode: failed to ftruncate share \
685 mode file %s to size %d (%s)\n", fname, newsize, strerror(errno)));
691 #ifdef FTRUNCATE_NEEDS_ROOT
692 unbecome_root(False);
693 #endif /* FTRUNCATE_NEEDS_ROOT */
696 /*******************************************************************
697 set the share mode of a file
698 ********************************************************************/
699 static BOOL slow_set_share_mode(int token,int fnum, uint16 port, uint16 op_type)
701 files_struct *fs_p = &Files[fnum];
704 int pid = (int)getpid();
711 share_name(fs_p->cnum, fs_p->fd_ptr->dev,
712 fs_p->fd_ptr->inode, fname);
714 if(fstat(fd, &sb) != 0)
716 DEBUG(0,("ERROR: set_share_mode: Failed to do stat on share file %s\n",
721 /* Sanity check for file contents (if it's not a new share file). */
724 int size = sb.st_size;
726 /* Allocate space for the file plus one extra entry */
727 if((buf = (char *)malloc(sb.st_size + SMF_ENTRY_LENGTH)) == NULL)
729 DEBUG(0,("set_share_mode: malloc for file size %d fail !\n",
730 sb.st_size + SMF_ENTRY_LENGTH));
734 if(lseek(fd, 0, SEEK_SET) != 0)
736 DEBUG(0,("ERROR: set_share_mode: Failed to reset position \
737 to 0 for share file %s (%s)\n", fname, strerror(errno)));
743 if (read(fd,buf,sb.st_size) != sb.st_size)
745 DEBUG(0,("ERROR: set_share_mode: Failed to read share file %s (%s)\n",
746 fname, strerror(errno)));
752 if (IVAL(buf,SMF_VERSION_OFFSET) != LOCKING_VERSION)
754 DEBUG(0,("ERROR: set_share_mode: share file %s has incorrect \
755 locking version (was %d, should be %d).\n",fname, IVAL(buf,SMF_VERSION_OFFSET),
759 delete_share_file(fs_p->cnum, fname);
763 size -= (SMF_HEADER_LENGTH + SVAL(buf, SMF_FILENAME_LEN_OFFSET)); /* Remove the header */
765 /* The remaining size must be a multiple of SMF_ENTRY_LENGTH - error if not. */
766 if((size % SMF_ENTRY_LENGTH) != 0)
768 DEBUG(0,("ERROR: set_share_mode: share file %s is an incorrect length - \
769 deleting it.\n", fname));
772 delete_share_file(fs_p->cnum, fname);
779 /* New file - just use a single_entry. */
780 if((buf = (char *)malloc(SMF_HEADER_LENGTH +
781 strlen(fs_p->name) + 1 + SMF_ENTRY_LENGTH)) == NULL)
783 DEBUG(0,("ERROR: set_share_mode: malloc failed for single entry.\n"));
786 SIVAL(buf,SMF_VERSION_OFFSET,LOCKING_VERSION);
787 SIVAL(buf,SMF_NUM_ENTRIES_OFFSET,0);
788 SSVAL(buf,SMF_FILENAME_LEN_OFFSET,strlen(fs_p->name) + 1);
789 pstrcpy(buf + SMF_HEADER_LENGTH, fs_p->name);
792 num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
793 header_size = SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
794 p = buf + header_size + (num_entries * SMF_ENTRY_LENGTH);
795 SIVAL(p,SME_SEC_OFFSET,fs_p->open_time.tv_sec);
796 SIVAL(p,SME_USEC_OFFSET,fs_p->open_time.tv_usec);
797 SIVAL(p,SME_SHAREMODE_OFFSET,fs_p->share_mode);
798 SIVAL(p,SME_PID_OFFSET,pid);
799 SSVAL(p,SME_PORT_OFFSET,port);
800 SSVAL(p,SME_OPLOCK_TYPE_OFFSET,op_type);
804 SIVAL(buf,SMF_NUM_ENTRIES_OFFSET,num_entries);
806 if(lseek(fd, 0, SEEK_SET) != 0)
808 DEBUG(0,("ERROR: set_share_mode: (1) Failed to reset position to \
809 0 for share file %s (%s)\n", fname, strerror(errno)));
815 if (write(fd,buf,header_size + (num_entries*SMF_ENTRY_LENGTH)) !=
816 (header_size + (num_entries*SMF_ENTRY_LENGTH)))
818 DEBUG(2,("ERROR: set_share_mode: Failed to write share file %s - \
819 deleting it (%s).\n",fname, strerror(errno)));
820 delete_share_file(fs_p->cnum, fname);
826 /* Now truncate the file at this point - just for safety. */
828 #ifdef FTRUNCATE_NEEDS_ROOT
830 #endif /* FTRUNCATE_NEEDS_ROOT */
832 if(ftruncate(fd, header_size + (SMF_ENTRY_LENGTH*num_entries))!= 0)
835 #ifdef FTRUNCATE_NEEDS_ROOT
836 unbecome_root(False);
837 #endif /* FTRUNCATE_NEEDS_ROOT */
839 DEBUG(0,("ERROR: set_share_mode: failed to ftruncate share \
840 mode file %s to size %d (%s)\n", fname, header_size + (SMF_ENTRY_LENGTH*num_entries),
847 #ifdef FTRUNCATE_NEEDS_ROOT
848 unbecome_root(False);
849 #endif /* FTRUNCATE_NEEDS_ROOT */
854 DEBUG(3,("set_share_mode: Created share file %s with \
855 mode 0x%X pid=%d\n",fname,fs_p->share_mode,pid));
860 /*******************************************************************
861 Remove an oplock port and mode entry from a share mode.
862 ********************************************************************/
863 static BOOL slow_remove_share_oplock(int fnum, int token)
872 files_struct *fs_p = &Files[fnum];
877 share_name(fs_p->cnum, fs_p->fd_ptr->dev,
878 fs_p->fd_ptr->inode, fname);
880 if(read_share_file( fs_p->cnum, fd, fname, &buf, &new_file) != 0)
882 DEBUG(0,("ERROR: remove_share_oplock: Failed to read share file %s\n",
889 DEBUG(0,("ERROR: remove_share_oplock: share file %s is new (size zero), \
890 deleting it.\n", fname));
891 delete_share_file(fs_p->cnum, fname);
895 num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
897 DEBUG(5,("remove_share_oplock: share file %s has %d share mode entries.\n",
898 fname, num_entries));
903 DEBUG(0,("PANIC ERROR:remove_share_oplock: num_share_mode_entries < 0 (%d) \
904 for share file %d\n", num_entries, fname));
910 /* No entries - just delete the file. */
911 DEBUG(0,("remove_share_oplock: share file %s has no share mode entries - deleting.\n",
915 delete_share_file(fs_p->cnum, fname);
921 /* Go through the entries looking for the particular one
922 we have set - remove the oplock settings on it.
925 base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
927 for(i = 0; i < num_entries; i++)
929 char *p = base + (i*SMF_ENTRY_LENGTH);
931 if((IVAL(p,SME_SEC_OFFSET) != fs_p->open_time.tv_sec) ||
932 (IVAL(p,SME_USEC_OFFSET) != fs_p->open_time.tv_usec) ||
933 (IVAL(p,SME_SHAREMODE_OFFSET) != fs_p->share_mode) ||
934 (IVAL(p,SME_PID_OFFSET) != pid))
937 DEBUG(5,("remove_share_oplock: clearing oplock on entry number %d (of %d) \
938 from the share file %s\n", i, num_entries, fname));
940 SSVAL(p,SME_PORT_OFFSET,0);
941 SSVAL(p,SME_OPLOCK_TYPE_OFFSET,0);
948 DEBUG(0,("remove_share_oplock: entry not found in share file %s\n", fname));
954 /* Re-write the file - and truncate it at the correct point. */
955 if(lseek(fd, 0, SEEK_SET) != 0)
957 DEBUG(0,("ERROR: remove_share_oplock: lseek failed to reset to \
958 position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
964 fsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries);
965 if(write(fd, buf, fsize) != fsize)
967 DEBUG(0,("ERROR: remove_share_oplock: failed to re-write share \
968 mode file %s (%s)\n", fname, strerror(errno)));
979 /*******************************************************************
980 call the specified function on each entry under management by the
982 ********************************************************************/
983 static int slow_share_forall(void (*fn)(share_mode_entry *, char *))
990 dir = opendir(lp_lockdir());
995 while ((s=readdirname(dir))) {
1004 if (sscanf(s,"share.%u.%u",&dev,&inode)!=2) continue;
1006 pstrcpy(lname,lp_lockdir());
1007 trim_string(lname,NULL,"/");
1011 fd = open(lname,read_only?O_RDONLY:O_RDWR,0);
1016 /* Lock the share mode file while we read it. */
1018 fcntl_lock(fd, F_SETLKW, 0, 1, F_WRLCK) == False) {
1023 if(read_share_file( 0, fd, lname, &buf, &new_file)) {
1027 pstrcpy( fname, &buf[10]);
1030 base = buf + SMF_HEADER_LENGTH +
1031 SVAL(buf,SMF_FILENAME_LEN_OFFSET);
1032 for( i = 0; i < IVAL(buf, SMF_NUM_ENTRIES_OFFSET); i++) {
1033 char *p = base + (i*SMF_ENTRY_LENGTH);
1034 e.pid = IVAL(p,SME_PID_OFFSET);
1035 e.share_mode = IVAL(p,SME_SHAREMODE_OFFSET);
1036 e.time.tv_sec = IVAL(p,SME_SEC_OFFSET);
1037 e.time.tv_usec = IVAL(p,SME_USEC_OFFSET);
1038 e.op_port = SVAL(p,SME_PORT_OFFSET);
1039 e.pid = SVAL(p,SME_PID_OFFSET);
1040 e.op_type = SVAL(p,SME_OPLOCK_TYPE_OFFSET);
1042 if (process_exists(e.pid)) {
1058 /*******************************************************************
1059 dump the state of the system
1060 ********************************************************************/
1061 static void slow_share_status(FILE *f)
1067 static struct share_ops share_ops = {
1068 slow_stop_share_mode_mgmt,
1069 slow_lock_share_entry,
1070 slow_unlock_share_entry,
1071 slow_get_share_modes,
1072 slow_del_share_mode,
1073 slow_set_share_mode,
1074 slow_remove_share_oplock,
1079 /*******************************************************************
1080 initialize the slow share_mode management
1081 ******************************************************************/
1082 struct share_ops *locking_slow_init(int ronly)
1087 if (!directory_exist(lp_lockdir(),NULL)) {
1089 mkdir(lp_lockdir(),0755);
1090 if (!directory_exist(lp_lockdir(),NULL))