1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #ifndef _SD_SAFESTORE_H
27 #define _SD_SAFESTORE_H
28
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32
33 #include <sys/nsc_thread.h>
34 #ifdef DS_DDICT
35 #include <sys/nsctl/contract.h>
36 #endif
37 #include <sys/nsctl/nsctl.h>
38 #if defined(_KERNEL) || defined(_KMEMUSER)
39
40 /* CSTYLED */
41 /**$
42 * token for a volume directory stream
43 */
44 typedef struct ss_vdir_s {
45 intptr_t opaque[6];
46 } ss_vdir_t;
47
48 /* CSTYLED */
49 /**$
50 * token for a cache entry directory stream
51 */
52 typedef struct ss_cdir_s {
53 intptr_t opaque[6];
54 }ss_cdir_t;
55
56 /* CSTYLED */
57 /**$
58 * token for a volume
59 */
60 typedef struct ss_vol_s {
61 intptr_t opaque;
62 }ss_vol_t;
63
64 /* CSTYLED */
65 /**$
66 * token for cache entry block and dirty bits
67 */
68 typedef struct s_resource_s {
69 intptr_t opaque;
70 } ss_resource_t;
71
72 /* CSTYLED */
73 /**$
74 * token for a list of cache safestore resources
75 */
76 typedef struct ss_resourcelist_s {
77 intptr_t opaque;
78 }ss_resourcelist_t;
79
80
81 /* CSTYLED */
82 /**$
83 * cache entry directory stream type specifier
84 *
85 * @field ck_type specifies all cache entries, cache entries for volume, node
86 * @field ck_vol volume token if ck_type is CDIR_VOL
87 * @field ck_node node id if ck_type is node CDIR_NODE
88 */
89 typedef struct ss_cdirkey_s {
90 uint_t ck_type; /* discriminator: see type defines below */
91 union {
92 ss_vol_t *ck_vol;
93 uint_t ck_node;
94 } cdk_u;
95 } ss_cdirkey_t;
96
97 /* centry directory stream types */
98 #define CDIR_ALL 0
99 #define CDIR_VOL 1
100 #define CDIR_NODE 2
101
102 /* BEGIN CSTYLED */
103 /**$
104 * exported cache entry info
105 *
106 * @field sc_cd the cache descriptor, associates this entry with a volume
107 * @field sc_fpos file position in cache blocks
108 * @field sc_dirty dirty bits, one for each fba in the cache block
109 * @field sc_flag flags
110 * @field sc_res safestore resource token for this cache entry
111 * @see ss_voldata_t{}
112 */
113 typedef struct ss_centry_info_s {
114 int sc_cd; /* Cache descriptor */
115 nsc_off_t sc_fpos; /* File position */
116 int sc_dirty; /* Dirty mask */
117 int sc_flag; /* CC_PINNABLE | CC_PINNED */
118 ss_resource_t *sc_res; /* token for this centry */
119 } ss_centry_info_t;
120 /* END CSTYLED */
121
122
123 /* CSTYLED */
124 /**$
125 * volume directory stream type specifier
126 *
127 * @field vk_type specifies all volume entries, entries for volume, node
128 * @field vk_vol volume token if vk_type is VDIR_VOL
129 * @field vk_node node id if vk_type is node VDIR_NODE
130 */
131 typedef struct ss_vdirkey_s {
132 uint_t vk_type; /* discriminator: see type defines below */
133 union {
134 ss_vol_t *vk_vol;
135 uint_t vk_node;
136 } cdk_u;
137 } ss_vdirkey_t;
138
139 /* volume directory stream types */
140 #define VDIR_ALL 0
141 #define VDIR_VOL 1
142 #define VDIR_NODE 2
143
144 /* CSTYLED */
145 /**$
146 * exported volume entry info
147 *
148 * @field sv_cd the cache descriptor
149 * @field sv_vol the safestore volume token for this volume
150 * @field sv_pinned volume has pinned blocks, holds node id
151 * @field sv_attached node which has attached this volume
152 * @field sv_volname path name
153 * @field sv_devidsz length of device id, the sv_devid
154 * @field sv_devid unique id for physical, i.e. non-volume-managed volumes
155 */
156 typedef struct ss_voldata_s {
157 int sv_cd; /* NOTE may need dual node map info */
158 ss_vol_t *sv_vol; /* volume token for this vol entry */
159 int sv_pinned; /* Device has failed/pinned blocks */
160 int sv_attached; /* Node which has device attached */
161 char sv_volname[NSC_MAXPATH]; /* Filename */
162 int sv_devidsz; /* unique dev id length */
163 uchar_t sv_devid[NSC_MAXPATH]; /* wwn id - physical devs only */
164 } ss_voldata_t;
165
166 /* safestore media types */
167
168 /* CSTYLED */
169 /**%
170 * safestore in RAM, useful but not very safe
171 */
172 #define SS_M_RAM 0x00000001
173
174 /* CSTYLED */
175 /**%
176 * safestore in NVRAM on a single node
177 */
178 #define SS_M_NV_SINGLENODE 0x00000002
179
180 /* CSTYLED */
181 /**%
182 * safestore in NVRAM on a dual node system. all data is store remotely.
183 */
184 #define SS_M_NV_DUALNODE_NOMIRROR 0x00000004
185
186 /* CSTYLED */
187 /**%
188 * safestore in NVRAM on a dual node system. data is mirrored on both nodes.
189 */
190 #define SS_M_NV_DUALNODE_MIRROR 0x00000008
191
192
193 /* safestore data and metadata transport types */
194
195 /* CSTYLED */
196 /**%
197 * data is transferred using STE connection
198 */
199 #define SS_T_STE 0x00010000
200
201 /* CSTYLED */
202 /**%
203 * data is transferred using RPC
204 */
205 #define SS_T_RPC 0x00020000
206
207 /* CSTYLED */
208 /**%
209 * no transport -- (single node)
210 */
211 #define SS_T_NONE 0x08000000
212
213 #define SS_MEDIA_MASK 0x0000ffff
214 #define SS_TRANSPORT_MASK 0xffff0000
215
216 #define _SD_NO_NET 0
217 #define _SD_NO_NETADDR 0
218 #define _SD_NO_HOST -1
219 #define _SD_NO_CD -1
220
221 /* config settings */
222 #define SS_UNCONFIGURED 0
223 #define SS_INITTED 1
224 #define SS_CONFIGURED 2
225
226 /* error return for safestore ops */
227 #define SS_ERR -1
228 #define SS_OK 0
229 #define SS_EOF 1
230
231 /* config flag */
232 #define SS_GENPATTERN 1
233
234 /*
235 * convenience macros. should they be implemented in ss_ctl()?
236 */
237
238 /* is safestore on a single node? */
239 #define SAFESTORE_LOCAL(ssp) ((ssp) && (ssp->ssop_type & SS_T_NONE))
240
241 /* is safestore really safe or is it just RAM? */
242 #define SAFESTORE_SAFE(ssp) ((ssp) && !(ssp->ssop_type & SS_M_RAM))
243
244 /* is recovery needed with this safestore module? */
245 #define SAFESTORE_RECOVERY(ssp) ((ssp) && \
246 (ssp->ssop_flags & SS_RECOVERY_NEEDED))
247
248 /* CSTYLED */
249 /**$
250 * configuration structure provided by safestore client
251 *
252 * @field ssc_configured set by safestore module to indicate config completed
253 * @field ssc_ss_psize safestore internal page size, set by ss module
254 * @field ssc_client_psize callers page size
255 * @field ssc_wsize cache size in bytes: amount of data that can be safestored
256 * @field ssc_maxfiles maximum number of volumes
257 * @field ssc_pattern initialization pattern if any
258 * @field ssc_flag use ssc_pattern if this is SS_GENPATTERN
259 */
260 typedef struct ss_common_config_s {
261 uint_t ssc_configured;
262 uint_t ssc_ss_psize; /* safestore internal page size */
263 uint_t ssc_client_psize; /* client page size */
264 uint_t ssc_wsize; /* Write cache size in bytes */
265 int ssc_maxfiles; /* max files */
266 uint_t ssc_pattern; /* initialization pattern */
267 uint_t ssc_flag;
268 } ss_common_config_t;
269
270 /* BEGIN CSTYLED */
271 /**$
272 * safestore operations structure
273 *
274 * @field ssop_name description of this module.
275 * @field ssop_type media type OR'd with transport type
276 * @field ssop_flags SS_RECOVERY_NEEDED
277 * @field ssop_configure configure the module
278 * @field ssop_deconfigure deconfigure the module
279 * @field ssop_getvdir get a volume directory stream according to type
280 * @field ssop_getvdirent get next entry in a volume directory stream
281 * @field ssop_getvol get the data for a volume
282 * @field ssop_setvol set the data for a volume
283 * @field ssop_getcdir get cache entry directory stream according to type
284 * @field ssop_getcdirent get next cache entry in stream
285 * @field ssop_allocresource allocate safestore resources from free list
286 * @field ssop_deallocresource deallocate, i.e. free, a safestore resource
287 * @field ssop_getresource get next resource in resource list
288 * @field ssop_getcentry get metadata for a cache entry
289 * @field ssop_setcentry set the metadata for a cache entry
290 * @field ssop_read_cblock read the actual data for a cache entry
291 * @field ssop_write_cblock write the data for a cache entry
292 * @field ssop_ctl module entry point for everything else, e.g. stats
293 *
294 * @see ss_vdirkey_t{}
295 * @see ss_voldata_t{}
296 * @see ss_cdirkey_t{}
297 * @see ss_resourcelist_t{}
298 * @see ss_resource_t{}
299 * @see ss_centry_info_t{}
300 */
301 typedef struct safestore_ops_s {
302 char *ssop_name;
303 uint_t ssop_type; /* media type OR'd with transport type */
304 uint_t ssop_flags; /* recovery needed, etc */
305 int (* ssop_configure)(ss_common_config_t *, spcs_s_info_t);
306 int (* ssop_deconfigure)(int);
307 int (* ssop_getvdir)(const ss_vdirkey_t *, ss_vdir_t *);
308 int (* ssop_getvdirent)(const ss_vdir_t *, ss_voldata_t *);
309 int (* ssop_getvol)(ss_voldata_t *);
310 int (* ssop_setvol)(const ss_voldata_t *);
311 int (* ssop_getcdir)(const ss_cdirkey_t *, ss_cdir_t *);
312 int (* ssop_getcdirent)(ss_cdir_t *, ss_centry_info_t *);
313 int (* ssop_allocresource)(int, int *, ss_resourcelist_t **);
314 void (* ssop_deallocresource)(ss_resource_t *);
315 int (* ssop_getresource)(ss_resourcelist_t **, ss_resource_t **);
316 int (* ssop_getcentry)(ss_centry_info_t *);
317 int (* ssop_setcentry)(const ss_centry_info_t *);
318 int (* ssop_read_cblock)(const ss_resource_t *, void *, int, int);
319 int (* ssop_write_cblock)(const ss_resource_t *,
320 const void *, int, int);
321 int (* ssop_ctl)(uint_t, uintptr_t);
322 } safestore_ops_t;
323 /* END CSTYLED */
324
325 /* ssop_flags */
326 /*
327 * no writes permitted when this bit is set in ssop flags field
328 * (single node nvram mostly)
329 */
330 #define SS_RECOVERY_NEEDED 1
331
332 /* safestore operations */
333
334 /* BEGIN CSTYLED */
335 /**#
336 * SSOP_CONFIGURE() configure a safestore module
337 * @param ssp a safestore_ops_t pointer obtained from sst_open()
338 * @param cfg a pointer to ss_common_config_t, initialized by caller
339 * @param kstatus unistat spcs_s_info_t
340 * @return SS_OK successful, errno otherwise
341 *
342 * @see safestore_ops_t{}
343 * @see sst_open()
344 * @see ss_common_config_t{}
345 */
346 #define SSOP_CONFIGURE(ssp, cfg, kstatus) \
347 ((ssp)->ssop_configure(cfg, kstatus))
348
349 /**#
350 * SSOP_DECONFIGURE deconfigure a safestore module
351 * @param ssp a safestore_ops_t pointer obtained from sst_open()
352 * @param dirty integer flag, if set it signifies there is pinned data
353 * @return SS_OK success, SS_ERR otherwise
354 *
355 * @see safestore_ops_t{}
356 */
357 #define SSOP_DECONFIGURE(ssp, dirty) ((ssp)->ssop_deconfigure(dirty))
358
359
360 /* volume directory functions */
361
362 /**#
363 * SSOP_GETVDIR get a volume directory stream according to type
364 * @param ssp a safestore_ops_t pointer obtained from sst_open()
365 * @param key pointer to ss_vdirkey_t initialized by caller
366 * @param vdir pointer to ss_vdir_t owned by caller
367 * @return SS_OK success, SS_ERR otherwise
368 *
369 * @see safestore_ops_t{}
370 * @see ss_vdirkey_t{}
371 * @see ss_vdir_t{}
372 */
373 #define SSOP_GETVDIR(ssp, key, vdir) ((ssp)->ssop_getvdir(key, vdir))
374
375 /**#
376 * SSOP_GETVDIRENT get next volume in a volume directory stream
377 * @param ssp a safestore_ops_t pointer obtained from sst_open()
378 * @param vdir pointer to a properly initialized ss_vdir_t obtained
379 * from a successsful SSOP_GETVDIR() call
380 * @param voldata pointer to ss_voldata_t owned by caller, filled
381 * in with valid data on successful return
382 * @return SS_OK success
383 * SS_EOF if no more elements in stream,
384 * SS_ERR otherwise
385 *
386 * @see safestore_ops_t{}
387 * @see sst_open()
388 * @see ss_vdir_t{}
389 * @see ss_voldata_t{}
390 * @see SSOP_GETVDIR()
391 */
392 #define SSOP_GETVDIRENT(ssp, vdir, voldata) \
393 ((ssp)->ssop_getvdirent(vdir, voldata))
394
395 /* volume accessor functions */
396
397 /**#
398 * SSOP_GETVOL get the volume data for a particular volume
399 * @param ssp a safestore_ops_t pointer obtained from sst_open()
400 * @param voldata pointer to ss_voldata_t owned by caller, field sv_vol
401 * must be initialized with a valid ss_vol_t, normally
402 * obtained from a successful SSOP_GETVDIRENT() call.
403 * the rest of the structure is filled with valid volume data
404 * on successful return
405 * @return SS_OK if data read successfully
406 * SS_ERR otherwise
407 * @see safestore_ops_t{}
408 * @see sst_open()
409 * @see ss_voldata_t{}
410 * @see ss_vol_t{}
411 * @see SSOP_GETVDIRENT()
412 */
413 #define SSOP_GETVOL(ssp, voldata) ((ssp)->ssop_getvol(voldata))
414
415
416 /**#
417 * SSOP_SETVOL set the volume data for a particular volume
418 * @param ssp a safestore_ops_t pointer obtained from sst_open()
419 * @param voldata pointer to ss_voldata_t owned by caller, field sv_vol
420 * must be initialized with a valid ss_vol_t, obtained from
421 * a successful SSOP_GETVDIRENT() call. the remaining
422 * fields of the structure are written to safestore
423 * @return SS_OK if data saved successfully
424 * SS_ERR otherwise
425 * @see safestore_ops_t{}
426 * @see sst_open()
427 * @see ss_voldata_t{}
428 * @see ss_vol_t{}
429 * @see SSOP_GETVDIRENT()
430 */
431 #define SSOP_SETVOL(ssp, voldata) ((ssp)->ssop_setvol(voldata))
432
433 /* centry directory functions */
434
435 /**#
436 * SSOP_GETCDIR get a cache entry stream accroding to type
437 * @param ssp a safestore_ops_t pointer obtained from sst_open()
438 * @param key pointer to a ss_cdirkey_t initialized by caller
439 * @param cdir pointer to ss_cdir_t owned by caller
440 * @return SS_OK success, SS_ERR otherwise
441 *
442 * @see safestore_ops_t{}
443 * @see sst_open()
444 * @see ss_cdirkey_t{}
445 * @ see ss_cdir_t{}
446 */
447 #define SSOP_GETCDIR(ssp, key, cdir) \
448 ((ssp)->ssop_getcdir(key, cdir))
449
450 /**#
451 * SSOP_GETCDIRENT get next cache entry in a cache entry stream
452 * @param ssp a safestore_ops_t pointer obtained from sst_open()
453 * @param cdir pointer to valid ss_cdirkey_t obtained from a
454 * successsful SSOP_GETCDIR call
455 * @param voldata pointer to ss_voldata_t owned by caller, filled
456 * in with valid data on successful return
457 * @return SS_OK success
458 * SS_EOF if no more elements in stream,
459 * SS_ERR otherwise
460 *
461 * @see safestore_ops_t{}
462 * @see sst_open()
463 * @see ss_vdirkey_t{}
464 * @see ss_voldata_t{}
465 * @see SSOP_GETVDIR()
466 */
467 #define SSOP_GETCDIRENT(ssp, cdir, centry) \
468 ((ssp)->ssop_getcdirent(cdir, centry))
469
470 /* cache entry alloc functions */
471
472 /**#
473 * SSOP_ALLOCRESOURCE allocate safestore resources from the free list
474 * @param ssp a safestore_ops_t pointer obtained from sst_open()
475 * @param count number of resources, that is data blocks, needed
476 * @param stall integer pointer to stall count, no blocks available. used only
477 * when _sd_wblk_sync === 0
478 * @param reslist pointer to pointer to ss_resourcelist_t. points to valid
479 * resource list on successful return
480 * @return SS_OK success
481 * SS_ERR otherwise
482 *
483 * @see safestore_ops_t{}
484 * @see ss_resourcelist_t{}
485 * @see SSOP_DEALLOCRESOURCE()
486 * @see SSOP_GETRESOURCE()
487 */
488 #define SSOP_ALLOCRESOURCE(ssp, count, stall, reslist) \
489 ((ssp)->ssop_allocresource(count, stall, reslist))
490
491 /**#
492 * SSOP_DEALLOCRESOURCE deallocate, i.e. release, a single safestore resource
493 * @param ssp a safestore_ops_t pointer obtained from sst_open()
494 * @param res pointer to ss_resource_t to be released
495 * @return void
496 *
497 * @see safestore_ops_t{}
498 * @see ss_resource_t{}
499 * @see SSOP_ALLOCRESOURCE()
500 * @see SSOP_GETRESOURCE()
501 */
502 #define SSOP_DEALLOCRESOURCE(ssp, res) \
503 ((ssp)->ssop_deallocresource(res))
504
505 /**#
506 * SSOP_GETRESOURCE get the next safestore resource in a list
507 * @param ssp a safestore_ops_t pointer obtained from sst_open()
508 * @param reslist pointer to pointer to ss_resourcelist_t obtained from
509 * a successful call to SSOP_ALLOCRESOURCE()
510 * @param res pointer to pointer to ss_resource_t. points to a valid
511 * on successful resource
512 * @return SS_OK success
513 * SS_EOF if no more resources in list
514 * SS_ERR otherwise
515 *
516 * @see safestore_ops_t{}
517 * @see ss_resourcelist_t{}
518 * @see ss_resource_t{}
519 * @see SSOP_ALLOCRESOURCE()
520 * @see SSOP_DEALLOCRESOURCE()
521 */
522 #define SSOP_GETRESOURCE(ssp, reslist, res) \
523 ((ssp)->ssop_getresource(reslist, res))
524
525 /* centry accessor functions */
526
527
528 /**#
529 * SSOP_GETCENTRY read cache entry metadata for a particular cache entry
530 * @param ssp a safestore_ops_t pointer obtained from sst_open()
531 * @param centry_info pointer to ss_centry_info_t owned by caller.
532 * field sc_res must point to a valid ss_resource_t
533 * obtained from a successful call to SSOP_GETRESOURCE().
534 * the rest of the structure is filled with valid
535 * metadata on successful return
536 * @return SS_OK if data was read successfully
537 * SS_ERR otherwise
538 *
539 * @see safestore_ops_t{}
540 * @see sst_open()
541 * @see ss_centry_info_t
542 * @see ss_resource_t{}
543 * @see SSOP_GETRESOURCE()
544 */
545 #define SSOP_GETCENTRY(ssp, centry_info) \
546 ((ssp)->ssop_getcentry(centry_info))
547
548 /**#
549 * SSOP_SETCENTRY write cache entry metadata for a particular cache entry
550 * @param ssp a safestore_ops_t pointer obtained from sst_open()
551 * @param centry_info pointer to ss_centry_info_t owned by caller.
552 * field sc_res must point to a valid ss_resource_t
553 * obtained from a successful call to SSOP_GETRESOURCE().
554 * the remaining fields of the structured are written
555 * to safestore.
556 * @return SS_OK if data was written successfully
557 * SS_ERR otherwise
558 *
559 * @see safestore_ops_t{}
560 * @see sst_open()
561 * @see ss_centry_info_t{}
562 * @see ss_resource_t{}
563 * @see SSOP_GETRESOURCE()
564 */
565 #define SSOP_SETCENTRY(ssp, centry_info) \
566 ((ssp)->ssop_setcentry(centry_info))
567
568 /* cache data block read/write and ctl */
569
570
571 /**#
572 * SSOP_READ_CBLOCK read cache data for a particular cache entry
573 * @param ssp a safestore_ops_t pointer obtained from sst_open()
574 * @param resource pointer to ss_resource_t obtained from a successful
575 * call to SSOP_GETRESOURCE().
576 * @param buf buffer to hold the data
577 * @param nbyte number of bytes to read
578 * @param srcoffset byte location from beginning of the cache block
579 * represented by resource to read the data from
580 *
581 * @return SS_OK if data was read successfully
582 * SS_ERR otherwise
583 *
584 * @see safestore_ops_t{}
585 * @see sst_open()
586 * @see ss_resource_t{}
587 * @see SSOP_GETRESOURCE()
588 */
589 #define SSOP_READ_CBLOCK(ssp, resource, buf, nbyte, srcoffset) \
590 ((ssp)->ssop_read_cblock(resource, buf, nbyte, srcoffset))
591 /**#
592 * SSOP_WRITE_CBLOCK write cache data for a particular cache entry
593 * @param ssp a safestore_ops_t pointer obtained from sst_open()
594 * @param resource pointer to ss_resource_t obtained from a successful
595 * call to SSOP_GETRESOURCE().
596 * @param buf buffer to hold the data
597 * @param nbyte number of bytes to write
598 * @param destoffset byte location from beginning the cache block
599 * represented by resource to write the data to
600 *
601 * @return SS_OK if data was read successfully
602 * SS_ERR otherwise
603 *
604 * @see safestore_ops_t{}
605 * @see sst_open()
606 * @see ss_resource_t{}
607 * @see SSOP_GETRESOURCE()
608 */
609 #define SSOP_WRITE_CBLOCK(ssp, resource, buf, nbyte, destoffset) \
610 ((ssp)->ssop_write_cblock(resource, buf, nbyte, destoffset))
611
612 /**#
613 * SSOP_CTL perform a safestore control function
614 * @param cmd integer specifying the command to execute, e.g. SSIOC_STATS.
615 * some commands may be specific to a safestore module type
616 * @param arg a uintptr_t that has additional information that is
617 * needed by the safestore module to perform the command. it
618 * may be an int or a pionter to a module specifc structure.
619 * @return SS_OK success
620 * errno otherwise
621 */
622 #define SSOP_CTL(ssp, cmd, arg) ((ssp)->ssop_ctl(cmd, arg))
623
624 /* END CSTYLED */
625
626 /* general control definitions supported by safestore modules */
627
628 #define SSCTL(x) (('S'<< 16)|('S'<< 8)|(x))
629
630 #define SSIOC_STATS SSCTL(1)
631 #define SSIOC_SETFLAG SSCTL(2)
632
633 /* structure definitions */
634
635 typedef struct ssioc_stats_s {
636 int wq_inq; /* write queue count */
637 } ssioc_stats_t;
638
639 extern void sst_init();
640 extern void sst_register_mod(safestore_ops_t *);
641 extern void sst_unregister_mod(safestore_ops_t *);
642 extern safestore_ops_t *sst_open(uint_t, ...);
643 extern int sst_close(safestore_ops_t *);
644
645 extern safestore_ops_t *sdbc_safestore;
646
647 extern int _sd_centry_shift;
648
649 #endif /* _KERNEL */
650
651 #ifdef __cplusplus
652 }
653 #endif
654
655 #endif /* _SD_SAFESTORE_H */