2 Unix SMB/Netbios implementation.
4 shared memory 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)
35 #ifdef FAST_SHARE_MODES
38 extern int DEBUGLEVEL
;
39 extern connection_struct Connections
[];
40 extern files_struct Files
[];
42 static struct shmem_ops
*shmops
;
44 /* share mode record pointed to in shared memory hash bucket */
47 int next_offset
; /* offset of next record in chain from hash bucket */
51 int num_share_mode_entries
;
52 int share_mode_entries
; /* Chain of share mode entries for this file */
56 /* share mode entry pointed to by share_mode_record struct */
59 int next_share_mode_entry
;
61 } shm_share_mode_entry
;
66 /* Conversion to hash entry index from device and inode numbers. */
67 #define HASH_ENTRY(dev,ino) ((((uint32)(dev)) * ((uint32)(ino))) % shmops->hash_size())
70 /*******************************************************************
71 deinitialize the shared memory for share_mode management
72 ******************************************************************/
73 static BOOL
shm_stop_share_mode_mgmt(void)
75 return shmops
->close();
78 /*******************************************************************
79 lock a hash bucket entry in shared memory for share_mode management
80 ******************************************************************/
81 static BOOL
shm_lock_share_entry(int cnum
, uint32 dev
, uint32 inode
, int *ptok
)
83 return shmops
->lock_hash_entry(HASH_ENTRY(dev
, inode
));
86 /*******************************************************************
87 unlock a hash bucket entry in shared memory for share_mode management
88 ******************************************************************/
89 static BOOL
shm_unlock_share_entry(int cnum
, uint32 dev
, uint32 inode
, int token
)
91 return shmops
->unlock_hash_entry(HASH_ENTRY(dev
, inode
));
94 /*******************************************************************
95 get all share mode entries in shared memory for a dev/inode pair.
96 ********************************************************************/
97 static int shm_get_share_modes(int cnum
, int token
, uint32 dev
, uint32 inode
,
98 share_mode_entry
**old_shares
)
101 unsigned int hash_entry
= HASH_ENTRY(dev
, inode
);
102 share_mode_record
*file_scanner_p
;
103 share_mode_record
*file_prev_p
;
104 shm_share_mode_entry
*entry_scanner_p
;
105 shm_share_mode_entry
*entry_prev_p
;
107 int num_entries_copied
;
109 share_mode_entry
*share_array
= (share_mode_entry
*)0;
113 mode_array
= (int *)shmops
->offset2addr(shmops
->get_userdef_off());
115 if(mode_array
[hash_entry
] == NULL_OFFSET
)
117 DEBUG(5,("get_share_modes (FAST_SHARE_MODES): hash bucket %d empty\n", hash_entry
));
121 file_scanner_p
= (share_mode_record
*)shmops
->offset2addr(mode_array
[hash_entry
]);
122 file_prev_p
= file_scanner_p
;
123 while(file_scanner_p
)
125 if( (file_scanner_p
->st_dev
== dev
) && (file_scanner_p
->st_ino
== inode
) )
132 file_prev_p
= file_scanner_p
;
133 file_scanner_p
= (share_mode_record
*)shmops
->offset2addr(
134 file_scanner_p
->next_offset
);
140 DEBUG(5,("get_share_modes (FAST_SHARE_MODES): no entry for \
141 file dev = %d, ino = %d in hash_bucket %d\n", dev
, inode
, hash_entry
));
145 if(file_scanner_p
->locking_version
!= LOCKING_VERSION
)
147 DEBUG(0,("ERROR:get_share_modes (FAST_SHARE_MODES): Deleting old share mode \
148 record due to old locking version %d for file dev = %d, inode = %d in hash \
149 bucket %d\n", file_scanner_p
->locking_version
, dev
, inode
, hash_entry
));
150 if(file_prev_p
== file_scanner_p
)
151 mode_array
[hash_entry
] = file_scanner_p
->next_offset
;
153 file_prev_p
->next_offset
= file_scanner_p
->next_offset
;
154 shmops
->free(shmops
->addr2offset(file_scanner_p
));
158 /* Allocate the old_shares array */
159 num_entries
= file_scanner_p
->num_share_mode_entries
;
162 *old_shares
= share_array
= (share_mode_entry
*)
163 malloc(num_entries
* sizeof(share_mode_entry
));
166 DEBUG(0,("get_share_modes (FAST_SHARE_MODES): malloc fail !\n"));
171 num_entries_copied
= 0;
173 entry_scanner_p
= (shm_share_mode_entry
*)shmops
->offset2addr(
174 file_scanner_p
->share_mode_entries
);
175 entry_prev_p
= entry_scanner_p
;
176 while(entry_scanner_p
)
178 int pid
= entry_scanner_p
->e
.pid
;
180 if (pid
&& !process_exists(pid
))
182 /* Delete this share mode entry */
183 shm_share_mode_entry
*delete_entry_p
= entry_scanner_p
;
184 int share_mode
= entry_scanner_p
->e
.share_mode
;
186 if(entry_prev_p
== entry_scanner_p
)
188 /* We are at start of list */
189 file_scanner_p
->share_mode_entries
= entry_scanner_p
->next_share_mode_entry
;
190 entry_scanner_p
= (shm_share_mode_entry
*)shmops
->offset2addr(
191 file_scanner_p
->share_mode_entries
);
192 entry_prev_p
= entry_scanner_p
;
196 entry_prev_p
->next_share_mode_entry
= entry_scanner_p
->next_share_mode_entry
;
197 entry_scanner_p
= (shm_share_mode_entry
*)
198 shmops
->offset2addr(entry_scanner_p
->next_share_mode_entry
);
200 /* Decrement the number of share mode entries on this share mode record */
201 file_scanner_p
->num_share_mode_entries
-= 1;
204 if(file_scanner_p
->num_share_mode_entries
< 0)
206 DEBUG(0,("PANIC ERROR:get_share_mode (FAST_SHARE_MODES): num_share_mode_entries < 0 (%d) \
207 for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p
->num_share_mode_entries
,
208 dev
, inode
, hash_entry
));
212 DEBUG(0,("get_share_modes (FAST_SHARE_MODES): process %d no longer exists and \
213 it left a share mode entry with mode 0x%X for file dev = %d, ino = %d in hash \
214 bucket %d (number of entries now = %d)\n",
215 pid
, share_mode
, dev
, inode
, hash_entry
,
216 file_scanner_p
->num_share_mode_entries
));
218 shmops
->free(shmops
->addr2offset(delete_entry_p
));
222 /* This is a valid share mode entry and the process that
223 created it still exists. Copy it into the output array.
225 share_array
[num_entries_copied
].pid
= entry_scanner_p
->e
.pid
;
226 share_array
[num_entries_copied
].share_mode
= entry_scanner_p
->e
.share_mode
;
227 share_array
[num_entries_copied
].op_port
= entry_scanner_p
->e
.op_port
;
228 share_array
[num_entries_copied
].op_type
= entry_scanner_p
->e
.op_type
;
229 memcpy(&share_array
[num_entries_copied
].time
, &entry_scanner_p
->e
.time
,
230 sizeof(struct timeval
));
231 num_entries_copied
++;
232 DEBUG(5,("get_share_modes (FAST_SHARE_MODES): Read share mode \
233 record mode 0x%X pid=%d\n", entry_scanner_p
->e
.share_mode
, entry_scanner_p
->e
.pid
));
234 entry_prev_p
= entry_scanner_p
;
235 entry_scanner_p
= (shm_share_mode_entry
*)
236 shmops
->offset2addr(entry_scanner_p
->next_share_mode_entry
);
240 /* If no valid share mode entries were found then this record shouldn't exist ! */
241 if(num_entries_copied
== 0)
243 DEBUG(0,("get_share_modes (FAST_SHARE_MODES): file with dev %d, inode %d in \
244 hash bucket %d has a share mode record but no entries - deleting\n",
245 dev
, inode
, hash_entry
));
247 free((char *)*old_shares
);
250 if(file_prev_p
== file_scanner_p
)
251 mode_array
[hash_entry
] = file_scanner_p
->next_offset
;
253 file_prev_p
->next_offset
= file_scanner_p
->next_offset
;
254 shmops
->free(shmops
->addr2offset(file_scanner_p
));
257 DEBUG(5,("get_share_modes (FAST_SHARE_MODES): file with dev %d, inode %d in \
258 hash bucket %d returning %d entries\n", dev
, inode
, hash_entry
, num_entries_copied
));
260 return(num_entries_copied
);
263 /*******************************************************************
264 del the share mode of a file.
265 ********************************************************************/
266 static void shm_del_share_mode(int token
, int fnum
)
270 unsigned int hash_entry
;
271 share_mode_record
*file_scanner_p
;
272 share_mode_record
*file_prev_p
;
273 shm_share_mode_entry
*entry_scanner_p
;
274 shm_share_mode_entry
*entry_prev_p
;
278 dev
= Files
[fnum
].fd_ptr
->dev
;
279 inode
= Files
[fnum
].fd_ptr
->inode
;
281 hash_entry
= HASH_ENTRY(dev
, inode
);
283 mode_array
= (int *)shmops
->offset2addr(shmops
->get_userdef_off());
285 if(mode_array
[hash_entry
] == NULL_OFFSET
)
287 DEBUG(0,("PANIC ERROR:del_share_mode (FAST_SHARE_MODES): hash bucket %d empty\n",
292 file_scanner_p
= (share_mode_record
*)shmops
->offset2addr(mode_array
[hash_entry
]);
293 file_prev_p
= file_scanner_p
;
295 while(file_scanner_p
)
297 if( (file_scanner_p
->st_dev
== dev
) && (file_scanner_p
->st_ino
== inode
) )
304 file_prev_p
= file_scanner_p
;
305 file_scanner_p
= (share_mode_record
*)
306 shmops
->offset2addr(file_scanner_p
->next_offset
);
312 DEBUG(0,("ERROR:del_share_mode (FAST_SHARE_MODES): no entry found for dev %d, \
313 inode %d in hash bucket %d\n", dev
, inode
, hash_entry
));
317 if(file_scanner_p
->locking_version
!= LOCKING_VERSION
)
319 DEBUG(0,("ERROR: del_share_modes (FAST_SHARE_MODES): Deleting old share mode \
320 record due to old locking version %d for file dev %d, inode %d hash bucket %d\n",
321 file_scanner_p
->locking_version
, dev
, inode
, hash_entry
));
322 if(file_prev_p
== file_scanner_p
)
323 mode_array
[hash_entry
] = file_scanner_p
->next_offset
;
325 file_prev_p
->next_offset
= file_scanner_p
->next_offset
;
326 shmops
->free(shmops
->addr2offset(file_scanner_p
));
331 entry_scanner_p
= (shm_share_mode_entry
*)shmops
->offset2addr(
332 file_scanner_p
->share_mode_entries
);
333 entry_prev_p
= entry_scanner_p
;
334 while(entry_scanner_p
)
336 if( (pid
== entry_scanner_p
->e
.pid
) &&
337 (memcmp(&entry_scanner_p
->e
.time
,
338 &Files
[fnum
].open_time
,sizeof(struct timeval
)) == 0) )
345 entry_prev_p
= entry_scanner_p
;
346 entry_scanner_p
= (shm_share_mode_entry
*)
347 shmops
->offset2addr(entry_scanner_p
->next_share_mode_entry
);
353 /* Decrement the number of entries in the record. */
354 file_scanner_p
->num_share_mode_entries
-= 1;
356 DEBUG(2,("del_share_modes (FAST_SHARE_MODES): \
357 Deleting share mode entry dev = %d, inode = %d in hash bucket %d (num entries now = %d)\n",
358 dev
, inode
, hash_entry
, file_scanner_p
->num_share_mode_entries
));
359 if(entry_prev_p
== entry_scanner_p
)
360 /* We are at start of list */
361 file_scanner_p
->share_mode_entries
= entry_scanner_p
->next_share_mode_entry
;
363 entry_prev_p
->next_share_mode_entry
= entry_scanner_p
->next_share_mode_entry
;
364 shmops
->free(shmops
->addr2offset(entry_scanner_p
));
367 if(file_scanner_p
->num_share_mode_entries
< 0)
369 DEBUG(0,("PANIC ERROR:del_share_mode (FAST_SHARE_MODES): num_share_mode_entries < 0 (%d) \
370 for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p
->num_share_mode_entries
,
371 dev
, inode
, hash_entry
));
375 /* If we deleted the last share mode entry then remove the share mode record. */
376 if(file_scanner_p
->num_share_mode_entries
== 0)
378 DEBUG(2,("del_share_modes (FAST_SHARE_MODES): num entries = 0, deleting share_mode \
379 record dev = %d, inode = %d in hash bucket %d\n", dev
, inode
, hash_entry
));
380 if(file_prev_p
== file_scanner_p
)
381 mode_array
[hash_entry
] = file_scanner_p
->next_offset
;
383 file_prev_p
->next_offset
= file_scanner_p
->next_offset
;
384 shmops
->free(shmops
->addr2offset(file_scanner_p
));
389 DEBUG(0,("ERROR: del_share_modes (FAST_SHARE_MODES): No share mode record found \
390 dev = %d, inode = %d in hash bucket %d\n", dev
, inode
, hash_entry
));
394 /*******************************************************************
395 set the share mode of a file. Return False on fail, True on success.
396 ********************************************************************/
397 static BOOL
shm_set_share_mode(int token
, int fnum
, uint16 port
, uint16 op_type
)
399 files_struct
*fs_p
= &Files
[fnum
];
402 unsigned int hash_entry
;
403 share_mode_record
*file_scanner_p
;
404 share_mode_record
*file_prev_p
;
405 shm_share_mode_entry
*new_entry_p
;
406 int new_entry_offset
;
409 dev
= fs_p
->fd_ptr
->dev
;
410 inode
= fs_p
->fd_ptr
->inode
;
412 hash_entry
= HASH_ENTRY(dev
, inode
);
414 mode_array
= (int *)shmops
->offset2addr(shmops
->get_userdef_off());
416 file_scanner_p
= (share_mode_record
*)shmops
->offset2addr(mode_array
[hash_entry
]);
417 file_prev_p
= file_scanner_p
;
419 while(file_scanner_p
)
421 if( (file_scanner_p
->st_dev
== dev
) && (file_scanner_p
->st_ino
== inode
) )
428 file_prev_p
= file_scanner_p
;
429 file_scanner_p
= (share_mode_record
*)
430 shmops
->offset2addr(file_scanner_p
->next_offset
);
436 /* We must create a share_mode_record */
437 share_mode_record
*new_mode_p
= NULL
;
438 int new_offset
= shmops
->alloc( sizeof(share_mode_record
) +
439 strlen(fs_p
->name
) + 1);
440 if(new_offset
== NULL_OFFSET
)
442 DEBUG(0,("ERROR:set_share_mode (FAST_SHARE_MODES): shmops->alloc fail !\n"));
445 new_mode_p
= shmops
->offset2addr(new_offset
);
446 new_mode_p
->locking_version
= LOCKING_VERSION
;
447 new_mode_p
->st_dev
= dev
;
448 new_mode_p
->st_ino
= inode
;
449 new_mode_p
->num_share_mode_entries
= 0;
450 new_mode_p
->share_mode_entries
= NULL_OFFSET
;
451 strcpy(new_mode_p
->file_name
, fs_p
->name
);
453 /* Chain onto the start of the hash chain (in the hope we will be used first). */
454 new_mode_p
->next_offset
= mode_array
[hash_entry
];
455 mode_array
[hash_entry
] = new_offset
;
457 file_scanner_p
= new_mode_p
;
459 DEBUG(3,("set_share_mode (FAST_SHARE_MODES): Created share record for %s (dev %d \
460 inode %d in hash bucket %d\n", fs_p
->name
, dev
, inode
, hash_entry
));
463 /* Now create the share mode entry */
464 new_entry_offset
= shmops
->alloc( sizeof(shm_share_mode_entry
));
465 if(new_entry_offset
== NULL_OFFSET
)
467 int delete_offset
= mode_array
[hash_entry
];
468 DEBUG(0,("ERROR:set_share_mode (FAST_SHARE_MODES): shmops->alloc fail 1!\n"));
469 /* Unlink the damaged record */
470 mode_array
[hash_entry
] = file_scanner_p
->next_offset
;
472 shmops
->free( delete_offset
);
476 new_entry_p
= shmops
->offset2addr(new_entry_offset
);
478 new_entry_p
->e
.pid
= getpid();
479 new_entry_p
->e
.share_mode
= fs_p
->share_mode
;
480 new_entry_p
->e
.op_port
= port
;
481 new_entry_p
->e
.op_type
= op_type
;
482 memcpy( (char *)&new_entry_p
->e
.time
, (char *)&fs_p
->open_time
, sizeof(struct timeval
));
484 /* Chain onto the share_mode_record */
485 new_entry_p
->next_share_mode_entry
= file_scanner_p
->share_mode_entries
;
486 file_scanner_p
->share_mode_entries
= new_entry_offset
;
489 if(file_scanner_p
->num_share_mode_entries
< 0)
491 DEBUG(0,("PANIC ERROR:set_share_mode (FAST_SHARE_MODES): num_share_mode_entries < 0 (%d) \
492 for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p
->num_share_mode_entries
,
493 dev
, inode
, hash_entry
));
497 /* Increment the share_mode_entries counter */
498 file_scanner_p
->num_share_mode_entries
+= 1;
500 DEBUG(3,("set_share_mode (FAST_SHARE_MODES): Created share entry for %s with mode \
501 0x%X pid=%d (num_entries now = %d)\n",fs_p
->name
, fs_p
->share_mode
, new_entry_p
->e
.pid
,
502 file_scanner_p
->num_share_mode_entries
));
507 /*******************************************************************
508 Remove an oplock port and mode entry from a share mode.
509 ********************************************************************/
510 static BOOL
shm_remove_share_oplock(int fnum
, int token
)
514 unsigned int hash_entry
;
515 share_mode_record
*file_scanner_p
;
516 share_mode_record
*file_prev_p
;
517 shm_share_mode_entry
*entry_scanner_p
;
518 shm_share_mode_entry
*entry_prev_p
;
522 dev
= Files
[fnum
].fd_ptr
->dev
;
523 inode
= Files
[fnum
].fd_ptr
->inode
;
525 hash_entry
= HASH_ENTRY(dev
, inode
);
527 mode_array
= (int *)shmops
->offset2addr(shmops
->get_userdef_off());
529 if(mode_array
[hash_entry
] == NULL_OFFSET
)
531 DEBUG(0,("PANIC ERROR:remove_share_oplock (FAST_SHARE_MODES): hash bucket %d empty\n",
536 file_scanner_p
= (share_mode_record
*)shmops
->offset2addr(mode_array
[hash_entry
]);
537 file_prev_p
= file_scanner_p
;
539 while(file_scanner_p
)
541 if( (file_scanner_p
->st_dev
== dev
) && (file_scanner_p
->st_ino
== inode
) )
548 file_prev_p
= file_scanner_p
;
549 file_scanner_p
= (share_mode_record
*)
550 shmops
->offset2addr(file_scanner_p
->next_offset
);
556 DEBUG(0,("ERROR:remove_share_oplock (FAST_SHARE_MODES): no entry found for dev %d, \
557 inode %d in hash bucket %d\n", dev
, inode
, hash_entry
));
561 if(file_scanner_p
->locking_version
!= LOCKING_VERSION
)
563 DEBUG(0,("ERROR: remove_share_oplock (FAST_SHARE_MODES): Deleting old share mode \
564 record due to old locking version %d for file dev %d, inode %d hash bucket %d\n",
565 file_scanner_p
->locking_version
, dev
, inode
, hash_entry
));
566 if(file_prev_p
== file_scanner_p
)
567 mode_array
[hash_entry
] = file_scanner_p
->next_offset
;
569 file_prev_p
->next_offset
= file_scanner_p
->next_offset
;
570 shmops
->free(shmops
->addr2offset(file_scanner_p
));
575 entry_scanner_p
= (shm_share_mode_entry
*)shmops
->offset2addr(
576 file_scanner_p
->share_mode_entries
);
577 entry_prev_p
= entry_scanner_p
;
578 while(entry_scanner_p
)
580 if( (pid
== entry_scanner_p
->e
.pid
) &&
581 (entry_scanner_p
->e
.share_mode
== Files
[fnum
].share_mode
) &&
582 (memcmp(&entry_scanner_p
->e
.time
,
583 &Files
[fnum
].open_time
,sizeof(struct timeval
)) == 0) )
585 /* Delete the oplock info. */
586 entry_scanner_p
->e
.op_port
= 0;
587 entry_scanner_p
->e
.op_type
= 0;
593 entry_prev_p
= entry_scanner_p
;
594 entry_scanner_p
= (shm_share_mode_entry
*)
595 shmops
->offset2addr(entry_scanner_p
->next_share_mode_entry
);
601 DEBUG(0,("ERROR: remove_share_oplock (FAST_SHARE_MODES): No oplock granted share \
602 mode record found dev = %d, inode = %d in hash bucket %d\n", dev
, inode
, hash_entry
));
610 /*******************************************************************
611 call the specified function on each entry under management by the
613 ********************************************************************/
614 static int shm_share_forall(void (*fn
)(share_mode_entry
*, char *))
618 share_mode_record
*file_scanner_p
;
620 mode_array
= (int *)shmops
->offset2addr(shmops
->get_userdef_off());
622 for( i
= 0; i
< shmops
->hash_size(); i
++) {
623 shmops
->lock_hash_entry(i
);
624 if(mode_array
[i
] == NULL_OFFSET
) {
625 shmops
->unlock_hash_entry(i
);
629 file_scanner_p
= (share_mode_record
*)shmops
->offset2addr(mode_array
[i
]);
630 while((file_scanner_p
!= 0) &&
631 (file_scanner_p
->num_share_mode_entries
!= 0)) {
632 shm_share_mode_entry
*entry_scanner_p
=
633 (shm_share_mode_entry
*)
634 shmops
->offset2addr(file_scanner_p
->share_mode_entries
);
636 while(entry_scanner_p
!= 0) {
638 fn(&entry_scanner_p
->e
,
639 file_scanner_p
->file_name
);
642 (shm_share_mode_entry
*)
644 entry_scanner_p
->next_share_mode_entry
);
646 } /* end while entry_scanner_p */
647 file_scanner_p
= (share_mode_record
*)
648 shmops
->offset2addr(file_scanner_p
->next_offset
);
649 } /* end while file_scanner_p */
650 shmops
->unlock_hash_entry(i
);
657 /*******************************************************************
658 dump the state of the system
659 ********************************************************************/
660 static void shm_share_status(FILE *f
)
662 int bytes_free
, bytes_used
, bytes_overhead
, bytes_total
;
664 shmops
->get_usage(&bytes_free
, &bytes_used
, &bytes_overhead
);
665 bytes_total
= bytes_free
+ bytes_used
+ bytes_overhead
;
667 fprintf(f
, "Share mode memory usage (bytes):\n");
668 fprintf(f
, " %d(%d%%) free + %d(%d%%) used + %d(%d%%) overhead = %d(100%%) total\n",
669 bytes_free
, (bytes_free
* 100)/bytes_total
,
670 bytes_used
, (bytes_used
* 100)/bytes_total
,
671 bytes_overhead
, (bytes_overhead
* 100)/bytes_total
,
676 static struct share_ops share_ops
= {
677 shm_stop_share_mode_mgmt
,
678 shm_lock_share_entry
,
679 shm_unlock_share_entry
,
683 shm_remove_share_oplock
,
688 /*******************************************************************
689 initialize the shared memory for share_mode management
690 ******************************************************************/
691 struct share_ops
*locking_shm_init(int ronly
)
693 pstring shmem_file_name
;
698 shmops
= sysv_shm_open(read_only
);
699 if (shmops
) return &share_ops
;
702 shmops
= smb_shm_open(read_only
);
703 if (shmops
) return &share_ops
;
709 int locking_shm_dummy_procedure(void)