17836SJohn.Forte@Sun.COM /*
27836SJohn.Forte@Sun.COM * CDDL HEADER START
37836SJohn.Forte@Sun.COM *
47836SJohn.Forte@Sun.COM * The contents of this file are subject to the terms of the
57836SJohn.Forte@Sun.COM * Common Development and Distribution License (the "License").
67836SJohn.Forte@Sun.COM * You may not use this file except in compliance with the License.
77836SJohn.Forte@Sun.COM *
87836SJohn.Forte@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97836SJohn.Forte@Sun.COM * or http://www.opensolaris.org/os/licensing.
107836SJohn.Forte@Sun.COM * See the License for the specific language governing permissions
117836SJohn.Forte@Sun.COM * and limitations under the License.
127836SJohn.Forte@Sun.COM *
137836SJohn.Forte@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
147836SJohn.Forte@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157836SJohn.Forte@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
167836SJohn.Forte@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
177836SJohn.Forte@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
187836SJohn.Forte@Sun.COM *
197836SJohn.Forte@Sun.COM * CDDL HEADER END
207836SJohn.Forte@Sun.COM */
217836SJohn.Forte@Sun.COM /*
229093SRamana.Srikanth@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
237836SJohn.Forte@Sun.COM * Use is subject to license terms.
247836SJohn.Forte@Sun.COM */
257836SJohn.Forte@Sun.COM
267836SJohn.Forte@Sun.COM /*
277836SJohn.Forte@Sun.COM * kRPC Server for sndr
287836SJohn.Forte@Sun.COM */
297836SJohn.Forte@Sun.COM
307836SJohn.Forte@Sun.COM #include <sys/types.h>
317836SJohn.Forte@Sun.COM #include <sys/ksynch.h>
327836SJohn.Forte@Sun.COM #include <sys/cmn_err.h>
337836SJohn.Forte@Sun.COM #include <sys/kmem.h>
347836SJohn.Forte@Sun.COM #include <sys/cred.h>
357836SJohn.Forte@Sun.COM #include <sys/conf.h>
367836SJohn.Forte@Sun.COM #include <sys/stream.h>
377836SJohn.Forte@Sun.COM #include <sys/errno.h>
387836SJohn.Forte@Sun.COM
397836SJohn.Forte@Sun.COM #include <sys/unistat/spcs_s.h>
407836SJohn.Forte@Sun.COM #include <sys/unistat/spcs_s_k.h>
417836SJohn.Forte@Sun.COM #include <sys/unistat/spcs_errors.h>
427836SJohn.Forte@Sun.COM
437836SJohn.Forte@Sun.COM #ifdef _SunOS_2_6
447836SJohn.Forte@Sun.COM /*
457836SJohn.Forte@Sun.COM * on 2.6 both dki_lock.h and rpc/types.h define bool_t so we
467836SJohn.Forte@Sun.COM * define enum_t here as it is all we need from rpc/types.h
477836SJohn.Forte@Sun.COM * anyway and make it look like we included it. Yuck.
487836SJohn.Forte@Sun.COM */
497836SJohn.Forte@Sun.COM #define _RPC_TYPES_H
507836SJohn.Forte@Sun.COM typedef int enum_t;
517836SJohn.Forte@Sun.COM #else
527836SJohn.Forte@Sun.COM #ifndef DS_DDICT
537836SJohn.Forte@Sun.COM #include <rpc/types.h>
547836SJohn.Forte@Sun.COM #endif
557836SJohn.Forte@Sun.COM #endif /* _SunOS_2_6 */
567836SJohn.Forte@Sun.COM
577836SJohn.Forte@Sun.COM #ifndef DS_DDICT
587836SJohn.Forte@Sun.COM #include <rpc/auth.h>
597836SJohn.Forte@Sun.COM #include <rpc/svc.h>
607836SJohn.Forte@Sun.COM #include <rpc/xdr.h>
617836SJohn.Forte@Sun.COM #endif
627836SJohn.Forte@Sun.COM #include <sys/ddi.h>
637836SJohn.Forte@Sun.COM #include <sys/nsc_thread.h>
647836SJohn.Forte@Sun.COM #ifdef DS_DDICT
657836SJohn.Forte@Sun.COM #include <sys/nsctl/contract.h>
667836SJohn.Forte@Sun.COM #endif
677836SJohn.Forte@Sun.COM #include <sys/nsctl/nsctl.h>
687836SJohn.Forte@Sun.COM #include <sys/ncall/ncall.h>
697836SJohn.Forte@Sun.COM
707836SJohn.Forte@Sun.COM #include <sys/sdt.h> /* dtrace is S10 or later */
717836SJohn.Forte@Sun.COM
727836SJohn.Forte@Sun.COM #include "rdc_io.h"
737836SJohn.Forte@Sun.COM #include "rdc_bitmap.h"
747836SJohn.Forte@Sun.COM #include "rdcsrv.h"
757836SJohn.Forte@Sun.COM
767836SJohn.Forte@Sun.COM static rdc_sleepq_t *rdc_newsleepq();
777836SJohn.Forte@Sun.COM static void rdc_delsleepq(rdc_sleepq_t *);
787836SJohn.Forte@Sun.COM static int rdc_sleepq(rdc_group_t *, rdc_sleepq_t *);
797836SJohn.Forte@Sun.COM static int rdc_combywrite(rdc_k_info_t *, nsc_buf_t *);
807836SJohn.Forte@Sun.COM static int rdc_writemaxfba(rdc_k_info_t *, rdc_u_info_t *,
817836SJohn.Forte@Sun.COM rdc_net_dataset_t *, uint_t, int);
827836SJohn.Forte@Sun.COM static void rdc_setbitind(int *, net_pendvec_t *, rdc_net_dataset_t *, uint_t,
837836SJohn.Forte@Sun.COM int, int);
847836SJohn.Forte@Sun.COM static void rdc_dopending(rdc_group_t *, netwriteres *);
857836SJohn.Forte@Sun.COM static nsc_vec_t *rdc_dset2vec(rdc_net_dataset_t *);
867836SJohn.Forte@Sun.COM static int rdc_combyread(rdc_k_info_t *, rdc_u_info_t *, nsc_buf_t *);
877836SJohn.Forte@Sun.COM static int rdc_readmaxfba(int, nsc_off_t, nsc_size_t, int);
887836SJohn.Forte@Sun.COM static int rdc_dsetcopy(rdc_net_dataset_t *, nsc_vec_t *, nsc_off_t, nsc_size_t,
897836SJohn.Forte@Sun.COM char *, int, int);
907836SJohn.Forte@Sun.COM
917836SJohn.Forte@Sun.COM /* direction for dsetcopy() */
927836SJohn.Forte@Sun.COM #define COPY_IN 1 /* copy data into the rpc buffer */
937836SJohn.Forte@Sun.COM #define COPY_OUT 2 /* copy data out of the rpc buffer */
947836SJohn.Forte@Sun.COM
957836SJohn.Forte@Sun.COM #define MAX_EINTR_COUNT 1000
967836SJohn.Forte@Sun.COM
977836SJohn.Forte@Sun.COM static int rdc_rread_slow;
987836SJohn.Forte@Sun.COM static rdcsrv_t rdc_srvtab[];
997836SJohn.Forte@Sun.COM
1007836SJohn.Forte@Sun.COM #ifdef DEBUG
1017836SJohn.Forte@Sun.COM static int rdc_netwrite6;
1027836SJohn.Forte@Sun.COM static int rdc_stall0;
1037836SJohn.Forte@Sun.COM static int rdc_sleepcnt;
1047836SJohn.Forte@Sun.COM int rdc_datasetcnt;
1057836SJohn.Forte@Sun.COM #endif
1067836SJohn.Forte@Sun.COM
1077836SJohn.Forte@Sun.COM
1087836SJohn.Forte@Sun.COM int
_rdc_sync_event_notify(int operation,char * volume,char * group)1097836SJohn.Forte@Sun.COM _rdc_sync_event_notify(int operation, char *volume, char *group)
1107836SJohn.Forte@Sun.COM {
1117836SJohn.Forte@Sun.COM int ack = 0;
1127836SJohn.Forte@Sun.COM clock_t time;
1137836SJohn.Forte@Sun.COM
1147836SJohn.Forte@Sun.COM mutex_enter(&rdc_sync_mutex);
1157836SJohn.Forte@Sun.COM mutex_enter(&rdc_sync_event.mutex);
1167836SJohn.Forte@Sun.COM
1177836SJohn.Forte@Sun.COM if (rdc_sync_event.daemon_waiting) {
1187836SJohn.Forte@Sun.COM rdc_sync_event.daemon_waiting = 0;
1197836SJohn.Forte@Sun.COM rdc_sync_event.event = operation;
1207836SJohn.Forte@Sun.COM (void) strncpy(rdc_sync_event.master, volume, NSC_MAXPATH);
1217836SJohn.Forte@Sun.COM (void) strncpy(rdc_sync_event.group, group, NSC_MAXPATH);
1227836SJohn.Forte@Sun.COM
1237836SJohn.Forte@Sun.COM cv_signal(&rdc_sync_event.cv);
1247836SJohn.Forte@Sun.COM
1257836SJohn.Forte@Sun.COM rdc_sync_event.kernel_waiting = 1;
126*11066Srafael.vanoni@sun.com time = cv_reltimedwait_sig(&rdc_sync_event.done_cv,
127*11066Srafael.vanoni@sun.com &rdc_sync_event.mutex, rdc_sync_event_timeout,
128*11066Srafael.vanoni@sun.com TR_CLOCK_TICK);
1297836SJohn.Forte@Sun.COM if (time == (clock_t)0 || time == (clock_t)-1) {
1307836SJohn.Forte@Sun.COM /* signalled or timed out */
1317836SJohn.Forte@Sun.COM ack = 0;
1327836SJohn.Forte@Sun.COM } else {
1337836SJohn.Forte@Sun.COM if (rdc_sync_event.ack)
1347836SJohn.Forte@Sun.COM ack = 1;
1357836SJohn.Forte@Sun.COM else
1367836SJohn.Forte@Sun.COM ack = -1;
1377836SJohn.Forte@Sun.COM }
1387836SJohn.Forte@Sun.COM }
1397836SJohn.Forte@Sun.COM mutex_exit(&rdc_sync_event.mutex);
1407836SJohn.Forte@Sun.COM mutex_exit(&rdc_sync_mutex);
1417836SJohn.Forte@Sun.COM return (ack);
1427836SJohn.Forte@Sun.COM }
1437836SJohn.Forte@Sun.COM
1447836SJohn.Forte@Sun.COM
1457836SJohn.Forte@Sun.COM int
_rdc_sync_event_wait(void * arg0,void * arg1,int mode,spcs_s_info_t kstatus,int * rvp)1467836SJohn.Forte@Sun.COM _rdc_sync_event_wait(void *arg0, void *arg1, int mode, spcs_s_info_t kstatus,
1477836SJohn.Forte@Sun.COM int *rvp)
1487836SJohn.Forte@Sun.COM {
1497836SJohn.Forte@Sun.COM int rc = 0;
1507836SJohn.Forte@Sun.COM static char master[NSC_MAXPATH];
1517836SJohn.Forte@Sun.COM
1527836SJohn.Forte@Sun.COM master[0] = '\0';
1537836SJohn.Forte@Sun.COM *rvp = 0;
1547836SJohn.Forte@Sun.COM if (ddi_copyin(arg0, master, NSC_MAXPATH, mode))
1557836SJohn.Forte@Sun.COM return (EFAULT);
1567836SJohn.Forte@Sun.COM
1577836SJohn.Forte@Sun.COM mutex_enter(&rdc_sync_event.mutex);
1587836SJohn.Forte@Sun.COM
1597836SJohn.Forte@Sun.COM if (rdc_sync_event.kernel_waiting &&
1607836SJohn.Forte@Sun.COM (rdc_sync_event.lbolt - nsc_lbolt() < rdc_sync_event_timeout)) {
1617836SJohn.Forte@Sun.COM /* We haven't been away too long */
1627836SJohn.Forte@Sun.COM if (master[0])
1637836SJohn.Forte@Sun.COM rdc_sync_event.ack = 1;
1647836SJohn.Forte@Sun.COM else
1657836SJohn.Forte@Sun.COM rdc_sync_event.ack = 0;
1667836SJohn.Forte@Sun.COM rdc_sync_event.kernel_waiting = 0;
1677836SJohn.Forte@Sun.COM cv_signal(&rdc_sync_event.done_cv);
1687836SJohn.Forte@Sun.COM }
1697836SJohn.Forte@Sun.COM
1707836SJohn.Forte@Sun.COM rdc_sync_event.daemon_waiting = 1;
1717836SJohn.Forte@Sun.COM if (cv_wait_sig(&rdc_sync_event.cv, &rdc_sync_event.mutex) == 0) {
1727836SJohn.Forte@Sun.COM rdc_sync_event.daemon_waiting = 0;
1737836SJohn.Forte@Sun.COM rc = EAGAIN;
1747836SJohn.Forte@Sun.COM spcs_s_add(kstatus, rc);
1757836SJohn.Forte@Sun.COM } else {
1767836SJohn.Forte@Sun.COM (void) ddi_copyout(rdc_sync_event.master, arg0, NSC_MAXPATH,
1777836SJohn.Forte@Sun.COM mode);
1787836SJohn.Forte@Sun.COM (void) ddi_copyout(rdc_sync_event.group, arg1, NSC_MAXPATH,
1797836SJohn.Forte@Sun.COM mode);
1807836SJohn.Forte@Sun.COM *rvp = rdc_sync_event.event;
1817836SJohn.Forte@Sun.COM }
1827836SJohn.Forte@Sun.COM rdc_sync_event.lbolt = nsc_lbolt();
1837836SJohn.Forte@Sun.COM mutex_exit(&rdc_sync_event.mutex);
1847836SJohn.Forte@Sun.COM
1857836SJohn.Forte@Sun.COM return (rc);
1867836SJohn.Forte@Sun.COM }
1877836SJohn.Forte@Sun.COM
1887836SJohn.Forte@Sun.COM
1897836SJohn.Forte@Sun.COM static int
rdc_allow_sec_sync(rdc_u_info_t * urdc,int option)1907836SJohn.Forte@Sun.COM rdc_allow_sec_sync(rdc_u_info_t *urdc, int option)
1917836SJohn.Forte@Sun.COM {
1927836SJohn.Forte@Sun.COM rdc_k_info_t *krdc = &rdc_k_info[urdc->index];
1937836SJohn.Forte@Sun.COM rdc_k_info_t *ktmp;
1947836SJohn.Forte@Sun.COM rdc_u_info_t *utmp;
1957836SJohn.Forte@Sun.COM
1967836SJohn.Forte@Sun.COM if (!IS_MULTI(krdc))
1977836SJohn.Forte@Sun.COM return (0);
1987836SJohn.Forte@Sun.COM
1997836SJohn.Forte@Sun.COM rdc_many_enter(krdc);
2007836SJohn.Forte@Sun.COM
2017836SJohn.Forte@Sun.COM krdc = krdc->multi_next;
2027836SJohn.Forte@Sun.COM urdc = &rdc_u_info[krdc->index];
2037836SJohn.Forte@Sun.COM
2047836SJohn.Forte@Sun.COM if (!IS_ENABLED(urdc)) {
2057836SJohn.Forte@Sun.COM rdc_many_exit(krdc);
2067836SJohn.Forte@Sun.COM return (0);
2077836SJohn.Forte@Sun.COM }
2087836SJohn.Forte@Sun.COM
2097836SJohn.Forte@Sun.COM if (option == CCIO_RSYNC) {
2107836SJohn.Forte@Sun.COM
2117836SJohn.Forte@Sun.COM /* Reverse sync */
2127836SJohn.Forte@Sun.COM
2137836SJohn.Forte@Sun.COM if (rdc_get_mflags(urdc) & RDC_RSYNC_NEEDED) {
2147836SJohn.Forte@Sun.COM /*
2157836SJohn.Forte@Sun.COM * Reverse sync needed or in progress.
2167836SJohn.Forte@Sun.COM */
2177836SJohn.Forte@Sun.COM rdc_many_exit(krdc);
2187836SJohn.Forte@Sun.COM return (-1);
2197836SJohn.Forte@Sun.COM }
2207836SJohn.Forte@Sun.COM } else {
2217836SJohn.Forte@Sun.COM ASSERT(option == CCIO_SLAVE);
2227836SJohn.Forte@Sun.COM
2237836SJohn.Forte@Sun.COM /* Forward sync */
2247836SJohn.Forte@Sun.COM
2257836SJohn.Forte@Sun.COM if (rdc_get_mflags(urdc) & RDC_SLAVE) {
2267836SJohn.Forte@Sun.COM /*
2277836SJohn.Forte@Sun.COM * Reverse syncing is bad, as that means that data
2287836SJohn.Forte@Sun.COM * is already flowing to the target of the requested
2297836SJohn.Forte@Sun.COM * sync operation.
2307836SJohn.Forte@Sun.COM */
2317836SJohn.Forte@Sun.COM rdc_many_exit(krdc);
2327836SJohn.Forte@Sun.COM return (-1);
2337836SJohn.Forte@Sun.COM }
2347836SJohn.Forte@Sun.COM
2357836SJohn.Forte@Sun.COM /*
2367836SJohn.Forte@Sun.COM * Clear "reverse sync needed" on all 1-many volumes.
2377836SJohn.Forte@Sun.COM * The data on them will be updated from the primary of this
2387836SJohn.Forte@Sun.COM * requested sync operation, so the aborted reverse sync need
2397836SJohn.Forte@Sun.COM * not be completed.
2407836SJohn.Forte@Sun.COM */
2417836SJohn.Forte@Sun.COM
2427836SJohn.Forte@Sun.COM if ((rdc_get_mflags(urdc) & RDC_RSYNC_NEEDED) ||
2437836SJohn.Forte@Sun.COM (rdc_get_vflags(urdc) & RDC_VOL_FAILED)) {
2447836SJohn.Forte@Sun.COM rdc_clr_mflags(urdc, RDC_RSYNC_NEEDED);
2457836SJohn.Forte@Sun.COM rdc_clr_flags(urdc, RDC_VOL_FAILED);
2467836SJohn.Forte@Sun.COM rdc_write_state(urdc);
2477836SJohn.Forte@Sun.COM }
2487836SJohn.Forte@Sun.COM if (IS_MANY(krdc)) {
2497836SJohn.Forte@Sun.COM for (ktmp = krdc->many_next; ktmp != krdc;
2507836SJohn.Forte@Sun.COM ktmp = ktmp->many_next) {
2517836SJohn.Forte@Sun.COM utmp = &rdc_u_info[ktmp->index];
2527836SJohn.Forte@Sun.COM if (!IS_ENABLED(utmp))
2537836SJohn.Forte@Sun.COM continue;
2547836SJohn.Forte@Sun.COM if (rdc_get_mflags(utmp) & RDC_RSYNC_NEEDED) {
2557836SJohn.Forte@Sun.COM rdc_clr_mflags(utmp, RDC_RSYNC_NEEDED);
2567836SJohn.Forte@Sun.COM rdc_write_state(utmp);
2577836SJohn.Forte@Sun.COM }
2587836SJohn.Forte@Sun.COM }
2597836SJohn.Forte@Sun.COM }
2607836SJohn.Forte@Sun.COM }
2617836SJohn.Forte@Sun.COM
2627836SJohn.Forte@Sun.COM rdc_many_exit(krdc);
2637836SJohn.Forte@Sun.COM
2647836SJohn.Forte@Sun.COM return (0);
2657836SJohn.Forte@Sun.COM }
2667836SJohn.Forte@Sun.COM
2677836SJohn.Forte@Sun.COM
2687836SJohn.Forte@Sun.COM /*
2697836SJohn.Forte@Sun.COM * r_net_null
2707836SJohn.Forte@Sun.COM * Proc 0 Null action
2717836SJohn.Forte@Sun.COM */
2727836SJohn.Forte@Sun.COM static void
r_net_null(SVCXPRT * xprt)2737836SJohn.Forte@Sun.COM r_net_null(SVCXPRT *xprt)
2747836SJohn.Forte@Sun.COM {
2757836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_void, 0);
2767836SJohn.Forte@Sun.COM }
2777836SJohn.Forte@Sun.COM
2787836SJohn.Forte@Sun.COM /*
2797836SJohn.Forte@Sun.COM * r_net_read
2807836SJohn.Forte@Sun.COM */
2817836SJohn.Forte@Sun.COM static void
r_net_read(SVCXPRT * xprt)2827836SJohn.Forte@Sun.COM r_net_read(SVCXPRT *xprt)
2837836SJohn.Forte@Sun.COM {
2847836SJohn.Forte@Sun.COM readres resp;
2857836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
2867836SJohn.Forte@Sun.COM struct rread diskio;
2877836SJohn.Forte@Sun.COM char *buffer = NULL;
2887836SJohn.Forte@Sun.COM uchar_t *sv_addr;
2897836SJohn.Forte@Sun.COM nsc_vec_t *vec;
2907836SJohn.Forte@Sun.COM int pos, st;
2917836SJohn.Forte@Sun.COM int nocache;
2927836SJohn.Forte@Sun.COM int sv_len;
2937836SJohn.Forte@Sun.COM nsc_vec_t *vector = NULL;
2947836SJohn.Forte@Sun.COM rdc_net_dataset_t *dset = NULL;
2957836SJohn.Forte@Sun.COM int vecsz = 0;
2967836SJohn.Forte@Sun.COM
2977836SJohn.Forte@Sun.COM st = SVC_GETARGS(xprt, xdr_rread, (char *)&diskio);
2987836SJohn.Forte@Sun.COM if (!st) {
2997836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_int, (char *)&st);
3007836SJohn.Forte@Sun.COM return;
3017836SJohn.Forte@Sun.COM }
3027836SJohn.Forte@Sun.COM nocache = (diskio.flag & RDC_RREAD_FAIL) ? 0 : NSC_NOCACHE;
3037836SJohn.Forte@Sun.COM
3047836SJohn.Forte@Sun.COM if ((diskio.cd >= rdc_max_sets) || (diskio.cd < 0)) {
3057836SJohn.Forte@Sun.COM resp.rr_status = RDCERR_NOENT;
3067836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_readres, (char *)&resp);
3077836SJohn.Forte@Sun.COM #ifdef DEBUG
3087836SJohn.Forte@Sun.COM cmn_err(CE_NOTE,
3099093SRamana.Srikanth@Sun.COM "!r_net_read: EPROTO cd out or not enabled");
3107836SJohn.Forte@Sun.COM #endif
3117836SJohn.Forte@Sun.COM return;
3127836SJohn.Forte@Sun.COM }
3137836SJohn.Forte@Sun.COM
3147836SJohn.Forte@Sun.COM urdc = &rdc_u_info[diskio.cd];
3157836SJohn.Forte@Sun.COM
3167836SJohn.Forte@Sun.COM if (diskio.flag & RDC_RREAD_START) {
3177836SJohn.Forte@Sun.COM /* setup rpc */
3187836SJohn.Forte@Sun.COM if (!IS_ENABLED(urdc)) {
3197836SJohn.Forte@Sun.COM st = 0;
3207836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_int, (char *)&st);
3217836SJohn.Forte@Sun.COM return;
3227836SJohn.Forte@Sun.COM }
3237836SJohn.Forte@Sun.COM st = rdc_readmaxfba(diskio.cd, diskio.pos, diskio.len,
3247836SJohn.Forte@Sun.COM nocache);
3257836SJohn.Forte@Sun.COM
3267836SJohn.Forte@Sun.COM if (!svc_sendreply(xprt, xdr_int, (char *)&st)) {
3277836SJohn.Forte@Sun.COM if (st != 0) {
3287836SJohn.Forte@Sun.COM rdc_net_dataset_t *dset;
3297836SJohn.Forte@Sun.COM if (dset = rdc_net_get_set(diskio.cd, st)) {
3307836SJohn.Forte@Sun.COM rdc_net_del_set(diskio.cd, dset);
3317836SJohn.Forte@Sun.COM } else {
3329093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!r_net_read: get_set "
3337836SJohn.Forte@Sun.COM "has failed in cleanup");
3347836SJohn.Forte@Sun.COM }
3357836SJohn.Forte@Sun.COM }
3367836SJohn.Forte@Sun.COM }
3377836SJohn.Forte@Sun.COM return;
3387836SJohn.Forte@Sun.COM }
3397836SJohn.Forte@Sun.COM
3407836SJohn.Forte@Sun.COM /* data rpc */
3417836SJohn.Forte@Sun.COM
3427836SJohn.Forte@Sun.COM #ifdef DEBUG
3437836SJohn.Forte@Sun.COM if ((diskio.flag & RDC_RREAD_DATA) == 0) {
3449093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!r_net_read: received non-DATA rpc! flag %x",
3459093SRamana.Srikanth@Sun.COM diskio.flag);
3467836SJohn.Forte@Sun.COM }
3477836SJohn.Forte@Sun.COM #endif
3487836SJohn.Forte@Sun.COM
3497836SJohn.Forte@Sun.COM dset = rdc_net_get_set(diskio.cd, diskio.idx);
3507836SJohn.Forte@Sun.COM if (dset) {
3517836SJohn.Forte@Sun.COM vector = rdc_dset2vec(dset);
3527836SJohn.Forte@Sun.COM }
3537836SJohn.Forte@Sun.COM if (vector == NULL) {
3547836SJohn.Forte@Sun.COM resp.rr_status = RDCERR_NOMEM;
3557836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_readres, (char *)&resp);
3567836SJohn.Forte@Sun.COM goto cleanup;
3577836SJohn.Forte@Sun.COM }
3587836SJohn.Forte@Sun.COM vecsz = (dset->nitems + 1) * sizeof (nsc_vec_t);
3597836SJohn.Forte@Sun.COM
3607836SJohn.Forte@Sun.COM if (!IS_ENABLED(urdc)) {
3617836SJohn.Forte@Sun.COM resp.rr_status = RDCERR_NOENT;
3627836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_readres, (char *)&resp);
3637836SJohn.Forte@Sun.COM goto cleanup;
3647836SJohn.Forte@Sun.COM }
3657836SJohn.Forte@Sun.COM resp.rr_status = RDC_OK;
3667836SJohn.Forte@Sun.COM
3677836SJohn.Forte@Sun.COM /* find place in vector */
3687836SJohn.Forte@Sun.COM vec = vector;
3697836SJohn.Forte@Sun.COM pos = diskio.pos - dset->pos;
3707836SJohn.Forte@Sun.COM
3717836SJohn.Forte@Sun.COM for (; pos >= FBA_NUM(vec->sv_len); vec++)
3727836SJohn.Forte@Sun.COM pos -= FBA_NUM(vec->sv_len);
3737836SJohn.Forte@Sun.COM
3747836SJohn.Forte@Sun.COM sv_addr = vec->sv_addr + FBA_SIZE(pos);
3757836SJohn.Forte@Sun.COM sv_len = vec->sv_len - FBA_SIZE(pos);
3767836SJohn.Forte@Sun.COM
3777836SJohn.Forte@Sun.COM /*
3787836SJohn.Forte@Sun.COM * IF the data is in a single sb_vec entry
3797836SJohn.Forte@Sun.COM * THEN
3807836SJohn.Forte@Sun.COM * we can just point to that
3817836SJohn.Forte@Sun.COM * ELSE
3827836SJohn.Forte@Sun.COM * we have to alloc a local buffer,
3837836SJohn.Forte@Sun.COM * copy the data in and the point to
3847836SJohn.Forte@Sun.COM * the local buffer.
3857836SJohn.Forte@Sun.COM */
3867836SJohn.Forte@Sun.COM
3877836SJohn.Forte@Sun.COM if (sv_len >= FBA_SIZE(diskio.len)) {
3887836SJohn.Forte@Sun.COM /* fast */
3897836SJohn.Forte@Sun.COM resp.rr_data = (char *)sv_addr;
3907836SJohn.Forte@Sun.COM resp.rr_bufsize = FBA_SIZE(diskio.len);
3917836SJohn.Forte@Sun.COM } else {
3927836SJohn.Forte@Sun.COM /* slow */
3937836SJohn.Forte@Sun.COM rdc_rread_slow++; /* rough count */
3947836SJohn.Forte@Sun.COM resp.rr_bufsize = FBA_SIZE(diskio.len);
3957836SJohn.Forte@Sun.COM buffer = kmem_alloc(resp.rr_bufsize, KM_NOSLEEP);
3967836SJohn.Forte@Sun.COM if (!buffer) {
3977836SJohn.Forte@Sun.COM resp.rr_status = RDCERR_NOMEM;
3987836SJohn.Forte@Sun.COM } else {
3997836SJohn.Forte@Sun.COM resp.rr_data = buffer;
4007836SJohn.Forte@Sun.COM if (!rdc_dsetcopy(dset, vector, diskio.pos, diskio.len,
4017836SJohn.Forte@Sun.COM resp.rr_data, resp.rr_bufsize, COPY_IN)) {
4027836SJohn.Forte@Sun.COM resp.rr_status = RDCERR_NOMEM; /* ??? */
4037836SJohn.Forte@Sun.COM }
4047836SJohn.Forte@Sun.COM }
4057836SJohn.Forte@Sun.COM }
4067836SJohn.Forte@Sun.COM
4077836SJohn.Forte@Sun.COM st = svc_sendreply(xprt, xdr_readres, (char *)&resp); /* send data */
4087836SJohn.Forte@Sun.COM
4097836SJohn.Forte@Sun.COM cleanup:
4107836SJohn.Forte@Sun.COM
4117836SJohn.Forte@Sun.COM if (dset) {
4127836SJohn.Forte@Sun.COM if (!st ||
4137836SJohn.Forte@Sun.COM (diskio.flag & RDC_RREAD_END) ||
4147836SJohn.Forte@Sun.COM (resp.rr_status != RDC_OK)) {
4157836SJohn.Forte@Sun.COM /*
4167836SJohn.Forte@Sun.COM * RPC reply failed, OR
4177836SJohn.Forte@Sun.COM * Last RPC for this IO operation, OR
4187836SJohn.Forte@Sun.COM * We are failing this IO operation.
4197836SJohn.Forte@Sun.COM *
4207836SJohn.Forte@Sun.COM * Do cleanup.
4217836SJohn.Forte@Sun.COM */
4227836SJohn.Forte@Sun.COM rdc_net_del_set(diskio.cd, dset);
4237836SJohn.Forte@Sun.COM } else {
4247836SJohn.Forte@Sun.COM rdc_net_put_set(diskio.cd, dset);
4257836SJohn.Forte@Sun.COM }
4267836SJohn.Forte@Sun.COM }
4277836SJohn.Forte@Sun.COM
4287836SJohn.Forte@Sun.COM if (buffer)
4297836SJohn.Forte@Sun.COM kmem_free(buffer, resp.rr_bufsize);
4307836SJohn.Forte@Sun.COM if (vector) {
4317836SJohn.Forte@Sun.COM kmem_free(vector, vecsz);
4327836SJohn.Forte@Sun.COM RDC_DSMEMUSE(-vecsz);
4337836SJohn.Forte@Sun.COM }
4347836SJohn.Forte@Sun.COM }
4357836SJohn.Forte@Sun.COM
4367836SJohn.Forte@Sun.COM /*
4377836SJohn.Forte@Sun.COM * r_net_read (v6)
4387836SJohn.Forte@Sun.COM */
4397836SJohn.Forte@Sun.COM static void
r_net_read6(SVCXPRT * xprt)4407836SJohn.Forte@Sun.COM r_net_read6(SVCXPRT *xprt)
4417836SJohn.Forte@Sun.COM {
4427836SJohn.Forte@Sun.COM readres resp;
4437836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
4447836SJohn.Forte@Sun.COM struct rread6 diskio;
4457836SJohn.Forte@Sun.COM char *buffer = NULL;
4467836SJohn.Forte@Sun.COM uchar_t *sv_addr;
4477836SJohn.Forte@Sun.COM nsc_vec_t *vec;
4487836SJohn.Forte@Sun.COM int pos, st;
4497836SJohn.Forte@Sun.COM int nocache;
4507836SJohn.Forte@Sun.COM int sv_len;
4517836SJohn.Forte@Sun.COM nsc_vec_t *vector = NULL;
4527836SJohn.Forte@Sun.COM rdc_net_dataset_t *dset = NULL;
4537836SJohn.Forte@Sun.COM int vecsz = 0;
4547836SJohn.Forte@Sun.COM
4557836SJohn.Forte@Sun.COM st = SVC_GETARGS(xprt, xdr_rread6, (char *)&diskio);
4567836SJohn.Forte@Sun.COM if (!st) {
4577836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_int, (char *)&st);
4587836SJohn.Forte@Sun.COM return;
4597836SJohn.Forte@Sun.COM }
4607836SJohn.Forte@Sun.COM nocache = (diskio.flag & RDC_RREAD_FAIL) ? 0 : NSC_NOCACHE;
4617836SJohn.Forte@Sun.COM
4627836SJohn.Forte@Sun.COM if ((diskio.cd >= rdc_max_sets) || (diskio.cd < 0)) {
4637836SJohn.Forte@Sun.COM resp.rr_status = RDCERR_NOENT;
4647836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_readres, (char *)&resp);
4657836SJohn.Forte@Sun.COM #ifdef DEBUG
4669093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!r_net_read6: EPROTO cd out or not enabled");
4677836SJohn.Forte@Sun.COM #endif
4687836SJohn.Forte@Sun.COM return;
4697836SJohn.Forte@Sun.COM }
4707836SJohn.Forte@Sun.COM
4717836SJohn.Forte@Sun.COM urdc = &rdc_u_info[diskio.cd];
4727836SJohn.Forte@Sun.COM
4737836SJohn.Forte@Sun.COM if (diskio.flag & RDC_RREAD_START) {
4747836SJohn.Forte@Sun.COM /* setup rpc */
4757836SJohn.Forte@Sun.COM if (!IS_ENABLED(urdc)) {
4767836SJohn.Forte@Sun.COM st = 0;
4777836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_int, (char *)&st);
4787836SJohn.Forte@Sun.COM return;
4797836SJohn.Forte@Sun.COM }
4807836SJohn.Forte@Sun.COM st = rdc_readmaxfba(diskio.cd, diskio.pos, diskio.len,
4817836SJohn.Forte@Sun.COM nocache);
4827836SJohn.Forte@Sun.COM
4837836SJohn.Forte@Sun.COM if (!svc_sendreply(xprt, xdr_int, (char *)&st)) {
4847836SJohn.Forte@Sun.COM if (st != 0) {
4857836SJohn.Forte@Sun.COM rdc_net_dataset_t *dset;
4867836SJohn.Forte@Sun.COM if (dset = rdc_net_get_set(diskio.cd, st)) {
4877836SJohn.Forte@Sun.COM rdc_net_del_set(diskio.cd, dset);
4887836SJohn.Forte@Sun.COM } else {
4899093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!read6: get_set "
4907836SJohn.Forte@Sun.COM "has failed in cleanup");
4917836SJohn.Forte@Sun.COM }
4927836SJohn.Forte@Sun.COM }
4937836SJohn.Forte@Sun.COM }
4947836SJohn.Forte@Sun.COM return;
4957836SJohn.Forte@Sun.COM }
4967836SJohn.Forte@Sun.COM
4977836SJohn.Forte@Sun.COM /* data rpc */
4987836SJohn.Forte@Sun.COM
4997836SJohn.Forte@Sun.COM #ifdef DEBUG
5007836SJohn.Forte@Sun.COM if ((diskio.flag & RDC_RREAD_DATA) == 0) {
5019093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!read6: received non-DATA rpc! flag %x",
5029093SRamana.Srikanth@Sun.COM diskio.flag);
5037836SJohn.Forte@Sun.COM }
5047836SJohn.Forte@Sun.COM #endif
5057836SJohn.Forte@Sun.COM
5067836SJohn.Forte@Sun.COM dset = rdc_net_get_set(diskio.cd, diskio.idx);
5077836SJohn.Forte@Sun.COM if (dset) {
5087836SJohn.Forte@Sun.COM vector = rdc_dset2vec(dset);
5097836SJohn.Forte@Sun.COM }
5107836SJohn.Forte@Sun.COM if (vector == NULL) {
5117836SJohn.Forte@Sun.COM resp.rr_status = RDCERR_NOMEM;
5127836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_readres, (char *)&resp);
5137836SJohn.Forte@Sun.COM goto cleanup;
5147836SJohn.Forte@Sun.COM }
5157836SJohn.Forte@Sun.COM vecsz = (dset->nitems + 1) * sizeof (nsc_vec_t);
5167836SJohn.Forte@Sun.COM
5177836SJohn.Forte@Sun.COM if (!IS_ENABLED(urdc)) {
5187836SJohn.Forte@Sun.COM resp.rr_status = RDCERR_NOENT;
5197836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_readres, (char *)&resp);
5207836SJohn.Forte@Sun.COM goto cleanup;
5217836SJohn.Forte@Sun.COM }
5227836SJohn.Forte@Sun.COM resp.rr_status = RDC_OK;
5237836SJohn.Forte@Sun.COM
5247836SJohn.Forte@Sun.COM /* find place in vector */
5257836SJohn.Forte@Sun.COM vec = vector;
5267836SJohn.Forte@Sun.COM pos = diskio.pos - dset->pos;
5277836SJohn.Forte@Sun.COM
5287836SJohn.Forte@Sun.COM for (; pos >= FBA_NUM(vec->sv_len); vec++)
5297836SJohn.Forte@Sun.COM pos -= FBA_NUM(vec->sv_len);
5307836SJohn.Forte@Sun.COM
5317836SJohn.Forte@Sun.COM sv_addr = vec->sv_addr + FBA_SIZE(pos);
5327836SJohn.Forte@Sun.COM sv_len = vec->sv_len - FBA_SIZE(pos);
5337836SJohn.Forte@Sun.COM
5347836SJohn.Forte@Sun.COM /*
5357836SJohn.Forte@Sun.COM * IF the data is in a single sb_vec entry
5367836SJohn.Forte@Sun.COM * THEN
5377836SJohn.Forte@Sun.COM * we can just point to that
5387836SJohn.Forte@Sun.COM * ELSE
5397836SJohn.Forte@Sun.COM * we have to alloc a local buffer,
5407836SJohn.Forte@Sun.COM * copy the data in and the point to
5417836SJohn.Forte@Sun.COM * the local buffer.
5427836SJohn.Forte@Sun.COM */
5437836SJohn.Forte@Sun.COM
5447836SJohn.Forte@Sun.COM if (sv_len >= FBA_SIZE(diskio.len)) {
5457836SJohn.Forte@Sun.COM /* fast */
5467836SJohn.Forte@Sun.COM resp.rr_data = (char *)sv_addr;
5477836SJohn.Forte@Sun.COM resp.rr_bufsize = FBA_SIZE(diskio.len);
5487836SJohn.Forte@Sun.COM } else {
5497836SJohn.Forte@Sun.COM /* slow */
5507836SJohn.Forte@Sun.COM rdc_rread_slow++; /* rough count */
5517836SJohn.Forte@Sun.COM resp.rr_bufsize = FBA_SIZE(diskio.len);
5527836SJohn.Forte@Sun.COM buffer = kmem_alloc(resp.rr_bufsize, KM_NOSLEEP);
5537836SJohn.Forte@Sun.COM if (!buffer) {
5547836SJohn.Forte@Sun.COM resp.rr_status = RDCERR_NOMEM;
5557836SJohn.Forte@Sun.COM } else {
5567836SJohn.Forte@Sun.COM resp.rr_data = buffer;
5577836SJohn.Forte@Sun.COM if (!rdc_dsetcopy(dset, vector, diskio.pos, diskio.len,
5587836SJohn.Forte@Sun.COM resp.rr_data, resp.rr_bufsize, COPY_IN)) {
5597836SJohn.Forte@Sun.COM resp.rr_status = RDCERR_NOMEM; /* ??? */
5607836SJohn.Forte@Sun.COM }
5617836SJohn.Forte@Sun.COM }
5627836SJohn.Forte@Sun.COM }
5637836SJohn.Forte@Sun.COM
5647836SJohn.Forte@Sun.COM st = svc_sendreply(xprt, xdr_readres, (char *)&resp); /* send data */
5657836SJohn.Forte@Sun.COM
5667836SJohn.Forte@Sun.COM cleanup:
5677836SJohn.Forte@Sun.COM
5687836SJohn.Forte@Sun.COM if (dset) {
5697836SJohn.Forte@Sun.COM if (!st ||
5707836SJohn.Forte@Sun.COM (diskio.flag & RDC_RREAD_END) ||
5717836SJohn.Forte@Sun.COM (resp.rr_status != RDC_OK)) {
5727836SJohn.Forte@Sun.COM /*
5737836SJohn.Forte@Sun.COM * RPC reply failed, OR
5747836SJohn.Forte@Sun.COM * Last RPC for this IO operation, OR
5757836SJohn.Forte@Sun.COM * We are failing this IO operation.
5767836SJohn.Forte@Sun.COM *
5777836SJohn.Forte@Sun.COM * Do cleanup.
5787836SJohn.Forte@Sun.COM */
5797836SJohn.Forte@Sun.COM rdc_net_del_set(diskio.cd, dset);
5807836SJohn.Forte@Sun.COM } else {
5817836SJohn.Forte@Sun.COM rdc_net_put_set(diskio.cd, dset);
5827836SJohn.Forte@Sun.COM }
5837836SJohn.Forte@Sun.COM }
5847836SJohn.Forte@Sun.COM
5857836SJohn.Forte@Sun.COM if (buffer)
5867836SJohn.Forte@Sun.COM kmem_free(buffer, resp.rr_bufsize);
5877836SJohn.Forte@Sun.COM if (vector) {
5887836SJohn.Forte@Sun.COM kmem_free(vector, vecsz);
5897836SJohn.Forte@Sun.COM RDC_DSMEMUSE(-vecsz);
5907836SJohn.Forte@Sun.COM }
5917836SJohn.Forte@Sun.COM }
5927836SJohn.Forte@Sun.COM
5937836SJohn.Forte@Sun.COM /*
5947836SJohn.Forte@Sun.COM * r_net_write (Version 5)
5957836SJohn.Forte@Sun.COM * 0 reply indicates error
5967836SJohn.Forte@Sun.COM * >0 reply indicates a net handle index
5977836SJohn.Forte@Sun.COM * <0 reply indicates errno
5987836SJohn.Forte@Sun.COM * ret net handle index
5997836SJohn.Forte@Sun.COM * ret2 general error
6007836SJohn.Forte@Sun.COM * ret3 multi-hop errors (never returned)
6017836SJohn.Forte@Sun.COM */
6027836SJohn.Forte@Sun.COM static void
r_net_write5(SVCXPRT * xprt)6037836SJohn.Forte@Sun.COM r_net_write5(SVCXPRT *xprt)
6047836SJohn.Forte@Sun.COM {
6057836SJohn.Forte@Sun.COM rdc_k_info_t *krdc;
6067836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
6077836SJohn.Forte@Sun.COM struct net_data5 diskio;
6087836SJohn.Forte@Sun.COM rdc_net_dataset_t *dset;
6097836SJohn.Forte@Sun.COM rdc_net_dataitem_t *ditem;
6107836SJohn.Forte@Sun.COM int nocache;
6117836SJohn.Forte@Sun.COM int ret = 0;
6127836SJohn.Forte@Sun.COM int ret2 = 0;
6137836SJohn.Forte@Sun.COM int st;
6147836SJohn.Forte@Sun.COM
6157836SJohn.Forte@Sun.COM krdc = NULL;
6167836SJohn.Forte@Sun.COM diskio.data.data_val = kmem_alloc(RDC_MAXDATA, KM_NOSLEEP);
6177836SJohn.Forte@Sun.COM
6187836SJohn.Forte@Sun.COM if (!diskio.data.data_val) {
6197836SJohn.Forte@Sun.COM ret2 = ENOMEM;
6207836SJohn.Forte@Sun.COM goto out;
6217836SJohn.Forte@Sun.COM }
6227836SJohn.Forte@Sun.COM RDC_DSMEMUSE(RDC_MAXDATA);
6237836SJohn.Forte@Sun.COM st = SVC_GETARGS(xprt, xdr_net_data5, (char *)&diskio);
6247836SJohn.Forte@Sun.COM if (!st) {
6257836SJohn.Forte@Sun.COM ret2 = ENOMEM;
6267836SJohn.Forte@Sun.COM #ifdef DEBUG
6279093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!r_net_write5:SVC_GETARGS failed: st %d", st);
6287836SJohn.Forte@Sun.COM #endif
6297836SJohn.Forte@Sun.COM goto out;
6307836SJohn.Forte@Sun.COM }
6317836SJohn.Forte@Sun.COM if ((diskio.cd >= rdc_max_sets) || (diskio.cd < 0)) {
6327836SJohn.Forte@Sun.COM ret2 = EPROTO;
6337836SJohn.Forte@Sun.COM #ifdef DEBUG
6349093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!r_net_write6: EPROTO cd out or not enabled");
6357836SJohn.Forte@Sun.COM #endif
6367836SJohn.Forte@Sun.COM goto out;
6377836SJohn.Forte@Sun.COM }
6387836SJohn.Forte@Sun.COM
6397836SJohn.Forte@Sun.COM nocache = (diskio.flag & RDC_RWRITE_FAIL) ? 0 : NSC_NOCACHE;
6407836SJohn.Forte@Sun.COM krdc = &rdc_k_info[diskio.cd];
6417836SJohn.Forte@Sun.COM urdc = &rdc_u_info[diskio.cd];
6427836SJohn.Forte@Sun.COM
6437836SJohn.Forte@Sun.COM if (!IS_ENABLED(urdc) || IS_STATE(urdc, RDC_LOGGING)) {
6447836SJohn.Forte@Sun.COM ret2 = EPROTO;
6457836SJohn.Forte@Sun.COM #ifdef DEBUG
6469093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!r_net_write6: cd logging / not enabled (%x)",
6477836SJohn.Forte@Sun.COM rdc_get_vflags(urdc));
6487836SJohn.Forte@Sun.COM #endif
6497836SJohn.Forte@Sun.COM krdc = NULL; /* so we don't try to unqueue kstat entry */
6507836SJohn.Forte@Sun.COM goto out;
6517836SJohn.Forte@Sun.COM }
6527836SJohn.Forte@Sun.COM
6537836SJohn.Forte@Sun.COM if (krdc->io_kstats) {
6547836SJohn.Forte@Sun.COM mutex_enter(krdc->io_kstats->ks_lock);
6557836SJohn.Forte@Sun.COM kstat_runq_enter(KSTAT_IO_PTR(krdc->io_kstats));
6567836SJohn.Forte@Sun.COM mutex_exit(krdc->io_kstats->ks_lock);
6577836SJohn.Forte@Sun.COM }
6587836SJohn.Forte@Sun.COM
6597836SJohn.Forte@Sun.COM
6607836SJohn.Forte@Sun.COM /* -1 index says allocate a buffer */
6617836SJohn.Forte@Sun.COM if (diskio.idx < 0) {
6627836SJohn.Forte@Sun.COM dset = rdc_net_add_set(diskio.cd);
6637836SJohn.Forte@Sun.COM if (dset == NULL) {
6647836SJohn.Forte@Sun.COM #ifdef DEBUG
6659093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!r_net_write5: "
6669093SRamana.Srikanth@Sun.COM "failed to add dataset");
6677836SJohn.Forte@Sun.COM #endif
6687836SJohn.Forte@Sun.COM ret2 = EIO;
6697836SJohn.Forte@Sun.COM goto out;
6707836SJohn.Forte@Sun.COM } else {
6717836SJohn.Forte@Sun.COM ret = dset->id;
6727836SJohn.Forte@Sun.COM dset->pos = diskio.pos;
6737836SJohn.Forte@Sun.COM dset->fbalen = diskio.len;
6747836SJohn.Forte@Sun.COM diskio.idx = ret;
6757836SJohn.Forte@Sun.COM }
6767836SJohn.Forte@Sun.COM ditem = kmem_alloc(sizeof (rdc_net_dataitem_t), KM_NOSLEEP);
6777836SJohn.Forte@Sun.COM if (ditem == NULL) {
6787836SJohn.Forte@Sun.COM ret2 = ENOMEM;
6797836SJohn.Forte@Sun.COM goto out;
6807836SJohn.Forte@Sun.COM }
6817836SJohn.Forte@Sun.COM RDC_DSMEMUSE(sizeof (rdc_net_dataitem_t));
6827836SJohn.Forte@Sun.COM /*
6837836SJohn.Forte@Sun.COM * If this is a single transfer, then we don't
6847836SJohn.Forte@Sun.COM * need to allocate any memory for the data,
6857836SJohn.Forte@Sun.COM * just point the ditem data pointer to the
6867836SJohn.Forte@Sun.COM * existing buffer.
6877836SJohn.Forte@Sun.COM */
6887836SJohn.Forte@Sun.COM ditem->next = NULL;
6897836SJohn.Forte@Sun.COM if (diskio.endoblk) {
6907836SJohn.Forte@Sun.COM ditem->dptr = diskio.data.data_val;
6917836SJohn.Forte@Sun.COM /*
6927836SJohn.Forte@Sun.COM * So we don't free it twice.
6937836SJohn.Forte@Sun.COM */
6947836SJohn.Forte@Sun.COM diskio.data.data_val = NULL;
6957836SJohn.Forte@Sun.COM ditem->len = diskio.data.data_len;
6967836SJohn.Forte@Sun.COM ditem->mlen = RDC_MAXDATA;
6977836SJohn.Forte@Sun.COM } else {
6987836SJohn.Forte@Sun.COM /*
6997836SJohn.Forte@Sun.COM * Allocate the memory for the complete
7007836SJohn.Forte@Sun.COM * transfer.
7017836SJohn.Forte@Sun.COM */
7027836SJohn.Forte@Sun.COM ditem->dptr = kmem_alloc(FBA_SIZE(diskio.len),
7037836SJohn.Forte@Sun.COM KM_NOSLEEP);
7047836SJohn.Forte@Sun.COM if (ditem->dptr == NULL) {
7057836SJohn.Forte@Sun.COM ret2 = ENOMEM;
7067836SJohn.Forte@Sun.COM goto out;
7077836SJohn.Forte@Sun.COM }
7087836SJohn.Forte@Sun.COM RDC_DSMEMUSE(FBA_SIZE(diskio.len));
7097836SJohn.Forte@Sun.COM ditem->len = FBA_SIZE(diskio.len);
7107836SJohn.Forte@Sun.COM ditem->mlen = ditem->len;
7117836SJohn.Forte@Sun.COM
7127836SJohn.Forte@Sun.COM /*
7137836SJohn.Forte@Sun.COM * Copy the data to the new buffer.
7147836SJohn.Forte@Sun.COM */
7157836SJohn.Forte@Sun.COM ASSERT(diskio.data.data_len == FBA_SIZE(diskio.nfba));
7167836SJohn.Forte@Sun.COM bcopy(diskio.data.data_val, ditem->dptr,
7177836SJohn.Forte@Sun.COM diskio.data.data_len);
7187836SJohn.Forte@Sun.COM /*
7197836SJohn.Forte@Sun.COM * free the old data buffer.
7207836SJohn.Forte@Sun.COM */
7217836SJohn.Forte@Sun.COM kmem_free(diskio.data.data_val, RDC_MAXDATA);
7227836SJohn.Forte@Sun.COM RDC_DSMEMUSE(-RDC_MAXDATA);
7237836SJohn.Forte@Sun.COM diskio.data.data_val = NULL;
7247836SJohn.Forte@Sun.COM }
7257836SJohn.Forte@Sun.COM dset->head = ditem;
7267836SJohn.Forte@Sun.COM dset->tail = ditem;
7277836SJohn.Forte@Sun.COM dset->nitems++;
7287836SJohn.Forte@Sun.COM } else {
7297836SJohn.Forte@Sun.COM ret = diskio.idx;
7307836SJohn.Forte@Sun.COM dset = rdc_net_get_set(diskio.cd, diskio.idx);
7317836SJohn.Forte@Sun.COM if (dset == NULL) {
7327836SJohn.Forte@Sun.COM ret2 = EPROTO;
7337836SJohn.Forte@Sun.COM #ifdef DEBUG
7347836SJohn.Forte@Sun.COM cmn_err(CE_NOTE,
7359093SRamana.Srikanth@Sun.COM "!r_net_write5: net_get_set failed cd %d idx %d",
7367836SJohn.Forte@Sun.COM diskio.cd, diskio.idx);
7377836SJohn.Forte@Sun.COM #endif
7387836SJohn.Forte@Sun.COM goto out;
7397836SJohn.Forte@Sun.COM }
7407836SJohn.Forte@Sun.COM /*
7417836SJohn.Forte@Sun.COM * We have to copy the data from the rpc buffer
7427836SJohn.Forte@Sun.COM * to the data in ditem.
7437836SJohn.Forte@Sun.COM */
7447836SJohn.Forte@Sun.COM ditem = dset->head;
7457836SJohn.Forte@Sun.COM bcopy(diskio.data.data_val, (char *)ditem->dptr +
7467836SJohn.Forte@Sun.COM FBA_SIZE(diskio.sfba - diskio.pos), diskio.data.data_len);
7477836SJohn.Forte@Sun.COM
7487836SJohn.Forte@Sun.COM kmem_free(diskio.data.data_val, RDC_MAXDATA);
7497836SJohn.Forte@Sun.COM RDC_DSMEMUSE(-RDC_MAXDATA);
7507836SJohn.Forte@Sun.COM diskio.data.data_val = NULL;
7517836SJohn.Forte@Sun.COM }
7527836SJohn.Forte@Sun.COM ASSERT(dset);
7537836SJohn.Forte@Sun.COM
7547836SJohn.Forte@Sun.COM if (diskio.endoblk) {
7557836SJohn.Forte@Sun.COM ret2 = rdc_writemaxfba(krdc, urdc, dset, diskio.seq, nocache);
7567836SJohn.Forte@Sun.COM rdc_net_del_set(diskio.cd, dset);
7577836SJohn.Forte@Sun.COM dset = NULL;
7587836SJohn.Forte@Sun.COM }
7597836SJohn.Forte@Sun.COM out:
7607836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(ret2)) {
7617836SJohn.Forte@Sun.COM if (ret2 > 0)
7627836SJohn.Forte@Sun.COM ret2 = -ret2;
7637836SJohn.Forte@Sun.COM DTRACE_PROBE1(rdc_svcwrite5_err_ret2, int, ret2);
7647836SJohn.Forte@Sun.COM st = svc_sendreply(xprt, xdr_int, (char *)&ret2);
7657836SJohn.Forte@Sun.COM } else
7667836SJohn.Forte@Sun.COM st = svc_sendreply(xprt, xdr_int, (char *)&ret);
7677836SJohn.Forte@Sun.COM
7687836SJohn.Forte@Sun.COM if (krdc && krdc->io_kstats && ret2 != ENOMEM) {
7697836SJohn.Forte@Sun.COM mutex_enter(krdc->io_kstats->ks_lock);
7707836SJohn.Forte@Sun.COM kstat_runq_exit(KSTAT_IO_PTR(krdc->io_kstats));
7717836SJohn.Forte@Sun.COM mutex_exit(krdc->io_kstats->ks_lock);
7727836SJohn.Forte@Sun.COM }
7737836SJohn.Forte@Sun.COM /*
7747836SJohn.Forte@Sun.COM * On Error we must cleanup.
7757836SJohn.Forte@Sun.COM * If we have a handle, free it.
7767836SJohn.Forte@Sun.COM * If we have a network handle, free it.
7777836SJohn.Forte@Sun.COM */
7787836SJohn.Forte@Sun.COM if (!st || !RDC_SUCCESS(ret2)) {
7797836SJohn.Forte@Sun.COM #ifdef DEBUG
7809093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!r_net_write5 error case? st %x ret %d",
7819093SRamana.Srikanth@Sun.COM st, ret2);
7827836SJohn.Forte@Sun.COM #endif
7837836SJohn.Forte@Sun.COM if (dset) {
7847836SJohn.Forte@Sun.COM rdc_net_del_set(diskio.cd, dset);
7857836SJohn.Forte@Sun.COM }
7867836SJohn.Forte@Sun.COM
7877836SJohn.Forte@Sun.COM } else {
7887836SJohn.Forte@Sun.COM if (dset) {
7897836SJohn.Forte@Sun.COM rdc_net_put_set(diskio.cd, dset);
7907836SJohn.Forte@Sun.COM }
7917836SJohn.Forte@Sun.COM }
7927836SJohn.Forte@Sun.COM if (diskio.data.data_val) {
7937836SJohn.Forte@Sun.COM kmem_free(diskio.data.data_val, RDC_MAXDATA);
7947836SJohn.Forte@Sun.COM RDC_DSMEMUSE(-RDC_MAXDATA);
7957836SJohn.Forte@Sun.COM }
7967836SJohn.Forte@Sun.COM }
7977836SJohn.Forte@Sun.COM
7987836SJohn.Forte@Sun.COM /*
7997836SJohn.Forte@Sun.COM * r_net_write (Version 6)
8007836SJohn.Forte@Sun.COM * index 0 = error, or net handle index.
8017836SJohn.Forte@Sun.COM * result = 0 , ok.
8027836SJohn.Forte@Sun.COM * result = 1, pending write.
8037836SJohn.Forte@Sun.COM * result < 0 error, and is the -errno.
8047836SJohn.Forte@Sun.COM * ret net handle index.
8057836SJohn.Forte@Sun.COM * ret2 general error.
8067836SJohn.Forte@Sun.COM */
8077836SJohn.Forte@Sun.COM static void
r_net_write6(SVCXPRT * xprt)8087836SJohn.Forte@Sun.COM r_net_write6(SVCXPRT *xprt)
8097836SJohn.Forte@Sun.COM {
8107836SJohn.Forte@Sun.COM rdc_k_info_t *krdc;
8117836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
8127836SJohn.Forte@Sun.COM rdc_group_t *group;
8137836SJohn.Forte@Sun.COM struct net_data6 diskio;
8147836SJohn.Forte@Sun.COM struct netwriteres netret;
8157836SJohn.Forte@Sun.COM rdc_net_dataset_t *dset;
8167836SJohn.Forte@Sun.COM rdc_net_dataitem_t *ditem;
8177836SJohn.Forte@Sun.COM int ret = 0;
8187836SJohn.Forte@Sun.COM int ret2 = 0;
8197836SJohn.Forte@Sun.COM int st;
8207836SJohn.Forte@Sun.COM int nocache;
8217836SJohn.Forte@Sun.COM
8227836SJohn.Forte@Sun.COM netret.vecdata.vecdata_val = NULL;
8237836SJohn.Forte@Sun.COM netret.vecdata.vecdata_len = 0;
8247836SJohn.Forte@Sun.COM dset = NULL;
8257836SJohn.Forte@Sun.COM krdc = NULL;
8267836SJohn.Forte@Sun.COM diskio.data.data_val = kmem_alloc(RDC_MAXDATA, KM_NOSLEEP);
8277836SJohn.Forte@Sun.COM
8287836SJohn.Forte@Sun.COM if (!diskio.data.data_val) {
8297836SJohn.Forte@Sun.COM ret2 = ENOMEM;
8307836SJohn.Forte@Sun.COM goto out;
8317836SJohn.Forte@Sun.COM }
8327836SJohn.Forte@Sun.COM RDC_DSMEMUSE(RDC_MAXDATA);
8337836SJohn.Forte@Sun.COM st = SVC_GETARGS(xprt, xdr_net_data6, (char *)&diskio);
8347836SJohn.Forte@Sun.COM if (!st) {
8357836SJohn.Forte@Sun.COM ret2 = ENOMEM;
8367836SJohn.Forte@Sun.COM #ifdef DEBUG
8377836SJohn.Forte@Sun.COM cmn_err(CE_NOTE,
8389093SRamana.Srikanth@Sun.COM "!r_net_write6:SVC_GETARGS failed: st %d", st);
8397836SJohn.Forte@Sun.COM #endif
8407836SJohn.Forte@Sun.COM goto out;
8417836SJohn.Forte@Sun.COM }
8427836SJohn.Forte@Sun.COM
8437836SJohn.Forte@Sun.COM if ((diskio.cd >= rdc_max_sets) || (diskio.cd < 0)) {
8447836SJohn.Forte@Sun.COM ret2 = EPROTO;
8457836SJohn.Forte@Sun.COM #ifdef DEBUG
8469093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!r_net_write6: EPROTO cd out or not enabled");
8477836SJohn.Forte@Sun.COM #endif
8487836SJohn.Forte@Sun.COM goto out;
8497836SJohn.Forte@Sun.COM }
8507836SJohn.Forte@Sun.COM
8517836SJohn.Forte@Sun.COM nocache = (diskio.flag & RDC_RWRITE_FAIL) ? 0 : NSC_NOCACHE;
8527836SJohn.Forte@Sun.COM netret.seq = diskio.seq;
8537836SJohn.Forte@Sun.COM
8547836SJohn.Forte@Sun.COM krdc = &rdc_k_info[diskio.cd];
8557836SJohn.Forte@Sun.COM urdc = &rdc_u_info[diskio.cd];
8567836SJohn.Forte@Sun.COM
8577836SJohn.Forte@Sun.COM if (!IS_ENABLED(urdc) || IS_STATE(urdc, RDC_LOGGING)) {
8587836SJohn.Forte@Sun.COM ret2 = EPROTO;
8597836SJohn.Forte@Sun.COM #ifdef DEBUG
8607836SJohn.Forte@Sun.COM cmn_err(CE_NOTE,
8619093SRamana.Srikanth@Sun.COM "!r_net_write6: cd logging or not enabled (%x)",
8627836SJohn.Forte@Sun.COM rdc_get_vflags(urdc));
8637836SJohn.Forte@Sun.COM #endif
8647836SJohn.Forte@Sun.COM krdc = NULL; /* so we don't try to unqueue kstat entry */
8657836SJohn.Forte@Sun.COM goto out;
8667836SJohn.Forte@Sun.COM }
8677836SJohn.Forte@Sun.COM
8687836SJohn.Forte@Sun.COM group = krdc->group;
8697836SJohn.Forte@Sun.COM if (group == NULL) {
8707836SJohn.Forte@Sun.COM ret2 = EIO;
8717836SJohn.Forte@Sun.COM #ifdef DEBUG
8727836SJohn.Forte@Sun.COM cmn_err(CE_NOTE,
8739093SRamana.Srikanth@Sun.COM "!r_net_write6: No group structure for set %s:%s",
8747836SJohn.Forte@Sun.COM urdc->secondary.intf, urdc->secondary.file);
8757836SJohn.Forte@Sun.COM #endif
8767836SJohn.Forte@Sun.COM krdc = NULL; /* so we don't try to unqueue kstat entry */
8777836SJohn.Forte@Sun.COM goto out;
8787836SJohn.Forte@Sun.COM }
8797836SJohn.Forte@Sun.COM
8807836SJohn.Forte@Sun.COM #ifdef DEBUG
8817836SJohn.Forte@Sun.COM if (rdc_netwrite6) {
8827836SJohn.Forte@Sun.COM cmn_err(CE_NOTE,
8839093SRamana.Srikanth@Sun.COM "!r_net_write6: idx %d seq %u current seq %u pos %llu "
8847836SJohn.Forte@Sun.COM "len %d sfba %llu nfba %d endoblk %d",
8857836SJohn.Forte@Sun.COM diskio.idx, diskio.seq, group->seq,
8867836SJohn.Forte@Sun.COM (unsigned long long)diskio.pos, diskio.len,
8877836SJohn.Forte@Sun.COM (unsigned long long)diskio.sfba, diskio.nfba,
8887836SJohn.Forte@Sun.COM diskio.endoblk);
8897836SJohn.Forte@Sun.COM }
8907836SJohn.Forte@Sun.COM #endif
8917836SJohn.Forte@Sun.COM
8927836SJohn.Forte@Sun.COM if (krdc->io_kstats) {
8937836SJohn.Forte@Sun.COM mutex_enter(krdc->io_kstats->ks_lock);
8947836SJohn.Forte@Sun.COM kstat_runq_enter(KSTAT_IO_PTR(krdc->io_kstats));
8957836SJohn.Forte@Sun.COM mutex_exit(krdc->io_kstats->ks_lock);
8967836SJohn.Forte@Sun.COM }
8977836SJohn.Forte@Sun.COM
8987836SJohn.Forte@Sun.COM /* -1 index says allocate a net dataset */
8997836SJohn.Forte@Sun.COM if (diskio.idx < 0) {
9007836SJohn.Forte@Sun.COM dset = rdc_net_add_set(diskio.cd);
9017836SJohn.Forte@Sun.COM if (dset == NULL) {
9027836SJohn.Forte@Sun.COM #ifdef DEBUG
9037836SJohn.Forte@Sun.COM cmn_err(CE_NOTE,
9049093SRamana.Srikanth@Sun.COM "!r_net_write6: failed to add dataset");
9057836SJohn.Forte@Sun.COM #endif
9067836SJohn.Forte@Sun.COM ret2 = EIO;
9077836SJohn.Forte@Sun.COM goto out;
9087836SJohn.Forte@Sun.COM } else {
9097836SJohn.Forte@Sun.COM ret = dset->id;
9107836SJohn.Forte@Sun.COM dset->pos = (nsc_off_t)diskio.pos; /* 64bit! */
9117836SJohn.Forte@Sun.COM dset->fbalen = diskio.len;
9127836SJohn.Forte@Sun.COM diskio.idx = ret;
9137836SJohn.Forte@Sun.COM }
9147836SJohn.Forte@Sun.COM ditem = kmem_alloc(sizeof (rdc_net_dataitem_t), KM_NOSLEEP);
9157836SJohn.Forte@Sun.COM if (ditem == NULL) {
9167836SJohn.Forte@Sun.COM ret2 = ENOMEM;
9177836SJohn.Forte@Sun.COM goto out;
9187836SJohn.Forte@Sun.COM }
9197836SJohn.Forte@Sun.COM RDC_DSMEMUSE(sizeof (rdc_net_dataitem_t));
9207836SJohn.Forte@Sun.COM /*
9217836SJohn.Forte@Sun.COM * If this is a single transfer, then we don't
9227836SJohn.Forte@Sun.COM * need to allocate any memory for the data,
9237836SJohn.Forte@Sun.COM * just point the ditem data pointer to the
9247836SJohn.Forte@Sun.COM * existing buffer.
9257836SJohn.Forte@Sun.COM */
9267836SJohn.Forte@Sun.COM ditem->next = NULL;
9277836SJohn.Forte@Sun.COM if (diskio.endoblk) {
9287836SJohn.Forte@Sun.COM ditem->dptr = diskio.data.data_val;
9297836SJohn.Forte@Sun.COM /*
9307836SJohn.Forte@Sun.COM * So we don't free it twice.
9317836SJohn.Forte@Sun.COM */
9327836SJohn.Forte@Sun.COM diskio.data.data_val = NULL;
9337836SJohn.Forte@Sun.COM ditem->len = diskio.data.data_len;
9347836SJohn.Forte@Sun.COM ditem->mlen = RDC_MAXDATA;
9357836SJohn.Forte@Sun.COM } else {
9367836SJohn.Forte@Sun.COM /*
9377836SJohn.Forte@Sun.COM * Allocate the memory for the complete
9387836SJohn.Forte@Sun.COM * transfer.
9397836SJohn.Forte@Sun.COM */
9407836SJohn.Forte@Sun.COM ditem->dptr = kmem_alloc(FBA_SIZE(diskio.len),
9417836SJohn.Forte@Sun.COM KM_NOSLEEP);
9427836SJohn.Forte@Sun.COM if (ditem->dptr == NULL) {
9437836SJohn.Forte@Sun.COM ret2 = ENOMEM;
9447836SJohn.Forte@Sun.COM goto out;
9457836SJohn.Forte@Sun.COM }
9467836SJohn.Forte@Sun.COM RDC_DSMEMUSE(FBA_SIZE(diskio.len));
9477836SJohn.Forte@Sun.COM ditem->len = FBA_SIZE(diskio.len);
9487836SJohn.Forte@Sun.COM ditem->mlen = ditem->len;
9497836SJohn.Forte@Sun.COM
9507836SJohn.Forte@Sun.COM /*
9517836SJohn.Forte@Sun.COM * Copy the data to the new buffer.
9527836SJohn.Forte@Sun.COM */
9537836SJohn.Forte@Sun.COM ASSERT(diskio.data.data_len == FBA_SIZE(diskio.nfba));
9547836SJohn.Forte@Sun.COM bcopy(diskio.data.data_val, ditem->dptr,
9557836SJohn.Forte@Sun.COM diskio.data.data_len);
9567836SJohn.Forte@Sun.COM /*
9577836SJohn.Forte@Sun.COM * free the old data buffer.
9587836SJohn.Forte@Sun.COM */
9597836SJohn.Forte@Sun.COM kmem_free(diskio.data.data_val, RDC_MAXDATA);
9607836SJohn.Forte@Sun.COM RDC_DSMEMUSE(-RDC_MAXDATA);
9617836SJohn.Forte@Sun.COM diskio.data.data_val = NULL;
9627836SJohn.Forte@Sun.COM }
9637836SJohn.Forte@Sun.COM dset->head = ditem;
9647836SJohn.Forte@Sun.COM dset->tail = ditem;
9657836SJohn.Forte@Sun.COM dset->nitems++;
9667836SJohn.Forte@Sun.COM } else {
9677836SJohn.Forte@Sun.COM ret = diskio.idx;
9687836SJohn.Forte@Sun.COM dset = rdc_net_get_set(diskio.cd, diskio.idx);
9697836SJohn.Forte@Sun.COM if (dset == NULL) {
9707836SJohn.Forte@Sun.COM ret2 = EPROTO;
9717836SJohn.Forte@Sun.COM #ifdef DEBUG
9727836SJohn.Forte@Sun.COM cmn_err(CE_NOTE,
9739093SRamana.Srikanth@Sun.COM "!r_net_write6: net_get_set failed cd %d idx %d "
9747836SJohn.Forte@Sun.COM "packet sequence %u expected seq %u",
9757836SJohn.Forte@Sun.COM diskio.cd, diskio.idx, diskio.seq, group->seq);
9767836SJohn.Forte@Sun.COM #endif
9777836SJohn.Forte@Sun.COM goto out;
9787836SJohn.Forte@Sun.COM }
9797836SJohn.Forte@Sun.COM /*
9807836SJohn.Forte@Sun.COM * We have to copy the data from the rpc buffer
9817836SJohn.Forte@Sun.COM * to the data in ditem.
9827836SJohn.Forte@Sun.COM */
9837836SJohn.Forte@Sun.COM ditem = dset->head;
9847836SJohn.Forte@Sun.COM bcopy(diskio.data.data_val, (char *)ditem->dptr +
9857836SJohn.Forte@Sun.COM FBA_SIZE(diskio.sfba - diskio.pos), diskio.data.data_len);
9867836SJohn.Forte@Sun.COM
9877836SJohn.Forte@Sun.COM kmem_free(diskio.data.data_val, RDC_MAXDATA);
9887836SJohn.Forte@Sun.COM RDC_DSMEMUSE(-RDC_MAXDATA);
9897836SJohn.Forte@Sun.COM diskio.data.data_val = NULL;
9907836SJohn.Forte@Sun.COM }
9917836SJohn.Forte@Sun.COM ASSERT(dset);
9927836SJohn.Forte@Sun.COM
9937836SJohn.Forte@Sun.COM if (diskio.endoblk) {
9947836SJohn.Forte@Sun.COM #ifdef DEBUG
9957836SJohn.Forte@Sun.COM if (diskio.seq == (RDC_NEWSEQ + 1)) {
9967836SJohn.Forte@Sun.COM rdc_stallzero(2);
9977836SJohn.Forte@Sun.COM }
9987836SJohn.Forte@Sun.COM #endif
9997836SJohn.Forte@Sun.COM if (diskio.seq == RDC_NEWSEQ) {
10007836SJohn.Forte@Sun.COM /*
10017836SJohn.Forte@Sun.COM * magic marker, start of sequence.
10027836SJohn.Forte@Sun.COM */
10037836SJohn.Forte@Sun.COM mutex_enter(&group->ra_queue.net_qlock);
10047836SJohn.Forte@Sun.COM /*
10057836SJohn.Forte@Sun.COM * see if some threads are stuck.
10067836SJohn.Forte@Sun.COM */
10077836SJohn.Forte@Sun.COM if (group->sleepq) {
10087836SJohn.Forte@Sun.COM rdc_sleepqdiscard(group);
10097836SJohn.Forte@Sun.COM }
10107836SJohn.Forte@Sun.COM group->seqack = RDC_NEWSEQ;
10117836SJohn.Forte@Sun.COM mutex_exit(&group->ra_queue.net_qlock);
10127836SJohn.Forte@Sun.COM }
10137836SJohn.Forte@Sun.COM
10147836SJohn.Forte@Sun.COM if ((diskio.seq != RDC_NOSEQ) && (diskio.seq != RDC_NEWSEQ)) {
10157836SJohn.Forte@Sun.COM /*
10167836SJohn.Forte@Sun.COM * see if we are allowed through here to
10177836SJohn.Forte@Sun.COM * do the write, or if we have to q the
10187836SJohn.Forte@Sun.COM * request and send back a pending reply.
10197836SJohn.Forte@Sun.COM */
10207836SJohn.Forte@Sun.COM mutex_enter(&group->ra_queue.net_qlock);
10217836SJohn.Forte@Sun.COM if (diskio.seq != group->seq) {
10227836SJohn.Forte@Sun.COM rdc_sleepq_t *sq;
10237836SJohn.Forte@Sun.COM int maxseq;
10247836SJohn.Forte@Sun.COM
10257836SJohn.Forte@Sun.COM /*
10267836SJohn.Forte@Sun.COM * Check that we have room.
10277836SJohn.Forte@Sun.COM */
10287836SJohn.Forte@Sun.COM maxseq = group->seqack + RDC_MAXPENDQ + 1;
10297836SJohn.Forte@Sun.COM if (maxseq < group->seqack) {
10307836SJohn.Forte@Sun.COM /*
10317836SJohn.Forte@Sun.COM * skip magic values.
10327836SJohn.Forte@Sun.COM */
10337836SJohn.Forte@Sun.COM maxseq += RDC_NEWSEQ + 1;
10347836SJohn.Forte@Sun.COM }
10357836SJohn.Forte@Sun.COM if (!RDC_INFRONT(diskio.seq, maxseq)) {
10367836SJohn.Forte@Sun.COM #ifdef DEBUG
10379093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!net_write6: Queue "
10387836SJohn.Forte@Sun.COM "size %d exceeded seqack %u "
10397836SJohn.Forte@Sun.COM "this seq %u maxseq %u seq %u",
10407836SJohn.Forte@Sun.COM RDC_MAXPENDQ, group->seqack,
10417836SJohn.Forte@Sun.COM diskio.seq, maxseq, group->seq);
10427836SJohn.Forte@Sun.COM #endif
104310715SThomas.Atkins@Sun.COM DTRACE_PROBE2(qsize_exceeded, int, diskio.seq,
104410715SThomas.Atkins@Sun.COM int, maxseq);
10457836SJohn.Forte@Sun.COM if (!(rdc_get_vflags(urdc) &
10467836SJohn.Forte@Sun.COM RDC_VOL_FAILED)) {
10477836SJohn.Forte@Sun.COM rdc_many_enter(krdc);
10487836SJohn.Forte@Sun.COM rdc_set_flags(urdc,
10497836SJohn.Forte@Sun.COM RDC_VOL_FAILED);
10507836SJohn.Forte@Sun.COM rdc_many_exit(krdc);
10517836SJohn.Forte@Sun.COM rdc_write_state(urdc);
10527836SJohn.Forte@Sun.COM }
10537836SJohn.Forte@Sun.COM ret2 = EIO;
10547836SJohn.Forte@Sun.COM rdc_sleepqdiscard(group);
10557836SJohn.Forte@Sun.COM group->seq = RDC_NEWSEQ;
10567836SJohn.Forte@Sun.COM group->seqack = RDC_NEWSEQ;
10577836SJohn.Forte@Sun.COM mutex_exit(&group->ra_queue.net_qlock);
10587836SJohn.Forte@Sun.COM goto out;
10597836SJohn.Forte@Sun.COM }
10607836SJohn.Forte@Sun.COM
10617836SJohn.Forte@Sun.COM sq = rdc_newsleepq();
10627836SJohn.Forte@Sun.COM sq->seq = diskio.seq;
10637836SJohn.Forte@Sun.COM sq->sindex = diskio.cd;
10647836SJohn.Forte@Sun.COM sq->pindex = diskio.local_cd;
10657836SJohn.Forte@Sun.COM sq->idx = diskio.idx;
10667836SJohn.Forte@Sun.COM sq->qpos = diskio.qpos;
10677836SJohn.Forte@Sun.COM sq->nocache = nocache;
10687836SJohn.Forte@Sun.COM if (rdc_sleepq(group, sq)) {
10697836SJohn.Forte@Sun.COM ret2 = EIO;
10707836SJohn.Forte@Sun.COM group->seq = RDC_NEWSEQ;
10717836SJohn.Forte@Sun.COM group->seqack = RDC_NEWSEQ;
10727836SJohn.Forte@Sun.COM rdc_sleepqdiscard(group);
10737836SJohn.Forte@Sun.COM mutex_exit(&group->ra_queue.net_qlock);
10747836SJohn.Forte@Sun.COM goto out;
10757836SJohn.Forte@Sun.COM }
10767836SJohn.Forte@Sun.COM rdc_net_put_set(diskio.cd, dset);
10777836SJohn.Forte@Sun.COM dset = NULL;
10787836SJohn.Forte@Sun.COM if (krdc->io_kstats) {
10797836SJohn.Forte@Sun.COM mutex_enter(krdc->io_kstats->ks_lock);
10807836SJohn.Forte@Sun.COM kstat_waitq_enter(KSTAT_IO_PTR(krdc->
10817836SJohn.Forte@Sun.COM io_kstats));
10827836SJohn.Forte@Sun.COM mutex_exit(krdc->io_kstats->ks_lock);
10837836SJohn.Forte@Sun.COM }
10847836SJohn.Forte@Sun.COM mutex_exit(&group->ra_queue.net_qlock);
10857836SJohn.Forte@Sun.COM /*
10867836SJohn.Forte@Sun.COM * pending state.
10877836SJohn.Forte@Sun.COM */
10887836SJohn.Forte@Sun.COM netret.result = 1;
10897836SJohn.Forte@Sun.COM netret.index = diskio.idx;
10907836SJohn.Forte@Sun.COM st = svc_sendreply(xprt, xdr_netwriteres,
10917836SJohn.Forte@Sun.COM (char *)&netret);
10927836SJohn.Forte@Sun.COM if (krdc->io_kstats && ret2 != ENOMEM) {
10937836SJohn.Forte@Sun.COM mutex_enter(krdc->io_kstats->ks_lock);
10947836SJohn.Forte@Sun.COM kstat_runq_exit(KSTAT_IO_PTR(
10957836SJohn.Forte@Sun.COM krdc->io_kstats));
10967836SJohn.Forte@Sun.COM mutex_exit(krdc->io_kstats->ks_lock);
10977836SJohn.Forte@Sun.COM }
10987836SJohn.Forte@Sun.COM return;
10997836SJohn.Forte@Sun.COM }
11007836SJohn.Forte@Sun.COM mutex_exit(&group->ra_queue.net_qlock);
11017836SJohn.Forte@Sun.COM }
11027836SJohn.Forte@Sun.COM
11037836SJohn.Forte@Sun.COM ret2 = rdc_writemaxfba(krdc, urdc, dset, diskio.seq, nocache);
11047836SJohn.Forte@Sun.COM rdc_net_del_set(diskio.cd, dset);
11057836SJohn.Forte@Sun.COM dset = NULL;
11067836SJohn.Forte@Sun.COM #ifdef DEBUG
11077836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(ret2)) {
11089093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!r_net_write6: writemaxfba failed %d",
11097836SJohn.Forte@Sun.COM ret2);
11107836SJohn.Forte@Sun.COM }
11117836SJohn.Forte@Sun.COM #endif
11127836SJohn.Forte@Sun.COM if (diskio.seq != RDC_NOSEQ) {
11137836SJohn.Forte@Sun.COM mutex_enter(&group->ra_queue.net_qlock);
11147836SJohn.Forte@Sun.COM group->seq = diskio.seq + 1;
11157836SJohn.Forte@Sun.COM if (group->seq < diskio.seq)
11167836SJohn.Forte@Sun.COM group->seq = RDC_NEWSEQ + 1;
11177836SJohn.Forte@Sun.COM if (group->sleepq &&
11187836SJohn.Forte@Sun.COM (group->sleepq->seq == group->seq)) {
11197836SJohn.Forte@Sun.COM rdc_dopending(group, &netret);
11207836SJohn.Forte@Sun.COM }
11217836SJohn.Forte@Sun.COM group->seqack = group->seq;
11227836SJohn.Forte@Sun.COM mutex_exit(&group->ra_queue.net_qlock);
11237836SJohn.Forte@Sun.COM }
11247836SJohn.Forte@Sun.COM }
11257836SJohn.Forte@Sun.COM out:
11267836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(ret2)) {
11277836SJohn.Forte@Sun.COM DTRACE_PROBE1(rdc_svcwrite6_err_ret2, int, ret2);
11287836SJohn.Forte@Sun.COM netret.result = -ret2;
11297836SJohn.Forte@Sun.COM } else {
11307836SJohn.Forte@Sun.COM netret.result = 0;
11317836SJohn.Forte@Sun.COM netret.index = ret;
11327836SJohn.Forte@Sun.COM }
11337836SJohn.Forte@Sun.COM st = svc_sendreply(xprt, xdr_netwriteres, (char *)&netret);
11347836SJohn.Forte@Sun.COM if (netret.vecdata.vecdata_val) {
11357836SJohn.Forte@Sun.COM kmem_free(netret.vecdata.vecdata_val,
11367836SJohn.Forte@Sun.COM netret.vecdata.vecdata_len * sizeof (net_pendvec_t));
11377836SJohn.Forte@Sun.COM }
11387836SJohn.Forte@Sun.COM if (krdc && krdc->io_kstats && ret2 != ENOMEM) {
11397836SJohn.Forte@Sun.COM mutex_enter(krdc->io_kstats->ks_lock);
11407836SJohn.Forte@Sun.COM kstat_runq_exit(KSTAT_IO_PTR(krdc->io_kstats));
11417836SJohn.Forte@Sun.COM mutex_exit(krdc->io_kstats->ks_lock);
11427836SJohn.Forte@Sun.COM }
11437836SJohn.Forte@Sun.COM /*
11447836SJohn.Forte@Sun.COM * On Error we must cleanup.
11457836SJohn.Forte@Sun.COM * If we have a handle, free it.
11467836SJohn.Forte@Sun.COM * If we have a network handle, free it.
11477836SJohn.Forte@Sun.COM * If we hold the main nsc buffer, free it.
11487836SJohn.Forte@Sun.COM */
11497836SJohn.Forte@Sun.COM if (!st || !RDC_SUCCESS(ret2)) {
11507836SJohn.Forte@Sun.COM #ifdef DEBUG
11519093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!r_net_write6 error st %x ret %d seq %u",
11527836SJohn.Forte@Sun.COM st, ret2, diskio.seq);
11537836SJohn.Forte@Sun.COM #endif
11547836SJohn.Forte@Sun.COM if (dset) {
11557836SJohn.Forte@Sun.COM rdc_net_del_set(diskio.cd, dset);
11567836SJohn.Forte@Sun.COM }
11577836SJohn.Forte@Sun.COM } else {
11587836SJohn.Forte@Sun.COM if (dset) {
11597836SJohn.Forte@Sun.COM rdc_net_put_set(diskio.cd, dset);
11607836SJohn.Forte@Sun.COM }
11617836SJohn.Forte@Sun.COM }
11627836SJohn.Forte@Sun.COM if (diskio.data.data_val) {
11637836SJohn.Forte@Sun.COM kmem_free(diskio.data.data_val, RDC_MAXDATA);
11647836SJohn.Forte@Sun.COM RDC_DSMEMUSE(-RDC_MAXDATA);
11657836SJohn.Forte@Sun.COM }
11667836SJohn.Forte@Sun.COM }
11677836SJohn.Forte@Sun.COM
11687836SJohn.Forte@Sun.COM /*
11697836SJohn.Forte@Sun.COM * r_net_ping4
11707836SJohn.Forte@Sun.COM *
11717836SJohn.Forte@Sun.COM * received on the primary.
11727836SJohn.Forte@Sun.COM */
11737836SJohn.Forte@Sun.COM static void
r_net_ping4(SVCXPRT * xprt,struct svc_req * req)11747836SJohn.Forte@Sun.COM r_net_ping4(SVCXPRT *xprt, struct svc_req *req)
11757836SJohn.Forte@Sun.COM {
11767836SJohn.Forte@Sun.COM struct rdc_ping6 ping;
11777836SJohn.Forte@Sun.COM int e, ret = 0;
11787836SJohn.Forte@Sun.COM rdc_if_t *ip;
11797836SJohn.Forte@Sun.COM
11807836SJohn.Forte@Sun.COM e = SVC_GETARGS(xprt, xdr_rdc_ping6, (char *)&ping);
11817836SJohn.Forte@Sun.COM if (e) {
11827836SJohn.Forte@Sun.COM mutex_enter(&rdc_ping_lock);
11837836SJohn.Forte@Sun.COM
11847836SJohn.Forte@Sun.COM /* update specified interface */
11857836SJohn.Forte@Sun.COM
11867836SJohn.Forte@Sun.COM for (ip = rdc_if_top; ip; ip = ip->next) {
11877836SJohn.Forte@Sun.COM if ((bcmp(ping.p_ifaddr, ip->ifaddr.buf,
11889093SRamana.Srikanth@Sun.COM RDC_MAXADDR) == 0) &&
11897836SJohn.Forte@Sun.COM (bcmp(ping.s_ifaddr, ip->r_ifaddr.buf,
11909093SRamana.Srikanth@Sun.COM RDC_MAXADDR) == 0)) {
11917836SJohn.Forte@Sun.COM ip->new_pulse++;
11927836SJohn.Forte@Sun.COM ip->deadness = 1;
11937836SJohn.Forte@Sun.COM
11947836SJohn.Forte@Sun.COM /* Update the rpc protocol version to use */
11957836SJohn.Forte@Sun.COM
11967836SJohn.Forte@Sun.COM ip->rpc_version = req->rq_vers;
11977836SJohn.Forte@Sun.COM break;
11987836SJohn.Forte@Sun.COM }
11997836SJohn.Forte@Sun.COM }
12007836SJohn.Forte@Sun.COM
12017836SJohn.Forte@Sun.COM mutex_exit(&rdc_ping_lock);
12027836SJohn.Forte@Sun.COM } else {
12037836SJohn.Forte@Sun.COM svcerr_decode(xprt);
12047836SJohn.Forte@Sun.COM #ifdef DEBUG
12059093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!SNDR: couldn't get ping4 arguments");
12067836SJohn.Forte@Sun.COM #endif
12077836SJohn.Forte@Sun.COM }
12087836SJohn.Forte@Sun.COM
12097836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_int, (char *)&ret);
12107836SJohn.Forte@Sun.COM }
12117836SJohn.Forte@Sun.COM
12127836SJohn.Forte@Sun.COM /*
12137836SJohn.Forte@Sun.COM * r_net_ping7
12147836SJohn.Forte@Sun.COM *
12157836SJohn.Forte@Sun.COM * received on the primary.
12167836SJohn.Forte@Sun.COM */
12177836SJohn.Forte@Sun.COM static void
r_net_ping7(SVCXPRT * xprt,struct svc_req * req)12187836SJohn.Forte@Sun.COM r_net_ping7(SVCXPRT *xprt, struct svc_req *req)
12197836SJohn.Forte@Sun.COM {
12207836SJohn.Forte@Sun.COM struct rdc_ping ping;
12217836SJohn.Forte@Sun.COM int e, ret = 0;
12227836SJohn.Forte@Sun.COM rdc_if_t *ip;
12237836SJohn.Forte@Sun.COM unsigned short *sp;
12247836SJohn.Forte@Sun.COM
12257836SJohn.Forte@Sun.COM bzero(&ping, sizeof (struct rdc_ping));
12267836SJohn.Forte@Sun.COM e = SVC_GETARGS(xprt, xdr_rdc_ping, (char *)&ping);
12277836SJohn.Forte@Sun.COM if (e) {
12287836SJohn.Forte@Sun.COM sp = (unsigned short *)ping.p_ifaddr.buf;
12297836SJohn.Forte@Sun.COM *sp = ntohs(*sp);
12307836SJohn.Forte@Sun.COM sp = (unsigned short *)ping.s_ifaddr.buf;
12317836SJohn.Forte@Sun.COM *sp = ntohs(*sp);
12327836SJohn.Forte@Sun.COM mutex_enter(&rdc_ping_lock);
12337836SJohn.Forte@Sun.COM
12347836SJohn.Forte@Sun.COM /* update specified interface */
12357836SJohn.Forte@Sun.COM
12367836SJohn.Forte@Sun.COM for (ip = rdc_if_top; ip; ip = ip->next) {
12377836SJohn.Forte@Sun.COM if ((bcmp(ping.p_ifaddr.buf, ip->ifaddr.buf,
12389093SRamana.Srikanth@Sun.COM ping.p_ifaddr.len) == 0) &&
12397836SJohn.Forte@Sun.COM (bcmp(ping.s_ifaddr.buf, ip->r_ifaddr.buf,
12409093SRamana.Srikanth@Sun.COM ping.s_ifaddr.len) == 0)) {
12417836SJohn.Forte@Sun.COM ip->new_pulse++;
12427836SJohn.Forte@Sun.COM ip->deadness = 1;
12437836SJohn.Forte@Sun.COM
12447836SJohn.Forte@Sun.COM /* Update the rpc protocol version to use */
12457836SJohn.Forte@Sun.COM
12467836SJohn.Forte@Sun.COM ip->rpc_version = req->rq_vers;
12477836SJohn.Forte@Sun.COM break;
12487836SJohn.Forte@Sun.COM }
12497836SJohn.Forte@Sun.COM }
12507836SJohn.Forte@Sun.COM
12517836SJohn.Forte@Sun.COM mutex_exit(&rdc_ping_lock);
12527836SJohn.Forte@Sun.COM } else {
12537836SJohn.Forte@Sun.COM svcerr_decode(xprt);
12547836SJohn.Forte@Sun.COM #ifdef DEBUG
12559093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!SNDR: couldn't get ping7 arguments");
12567836SJohn.Forte@Sun.COM #endif
12577836SJohn.Forte@Sun.COM }
12587836SJohn.Forte@Sun.COM
12597836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_int, (char *)&ret);
12607836SJohn.Forte@Sun.COM }
12617836SJohn.Forte@Sun.COM
12627836SJohn.Forte@Sun.COM
12637836SJohn.Forte@Sun.COM /*
12647836SJohn.Forte@Sun.COM * r_net_bmap (v5)
12657836SJohn.Forte@Sun.COM * WARNING acts as both client and server
12667836SJohn.Forte@Sun.COM */
12677836SJohn.Forte@Sun.COM static void
r_net_bmap(SVCXPRT * xprt)12687836SJohn.Forte@Sun.COM r_net_bmap(SVCXPRT *xprt)
12697836SJohn.Forte@Sun.COM {
12707836SJohn.Forte@Sun.COM int e, ret = EINVAL;
12717836SJohn.Forte@Sun.COM struct bmap b;
12727836SJohn.Forte@Sun.COM rdc_k_info_t *krdc;
12737836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
12747836SJohn.Forte@Sun.COM struct bmap6 b6;
12757836SJohn.Forte@Sun.COM
12767836SJohn.Forte@Sun.COM
12777836SJohn.Forte@Sun.COM e = SVC_GETARGS(xprt, xdr_bmap, (char *)&b);
12787836SJohn.Forte@Sun.COM if (e == TRUE) {
12797836SJohn.Forte@Sun.COM krdc = &rdc_k_info[b.cd];
12807836SJohn.Forte@Sun.COM urdc = &rdc_u_info[b.cd];
12817836SJohn.Forte@Sun.COM if (b.cd >= 0 && b.cd < rdc_max_sets && IS_ENABLED(urdc) &&
12827836SJohn.Forte@Sun.COM ((krdc->type_flag & RDC_DISABLEPEND) == 0)) {
12837836SJohn.Forte@Sun.COM krdc->rpc_version = RDC_VERSION5;
12847836SJohn.Forte@Sun.COM b6.cd = b.cd;
12857836SJohn.Forte@Sun.COM b6.dual = b.dual;
12867836SJohn.Forte@Sun.COM b6.size = b.size;
12877836SJohn.Forte@Sun.COM ret = RDC_SEND_BITMAP(&b6);
12887836SJohn.Forte@Sun.COM }
12897836SJohn.Forte@Sun.COM }
12907836SJohn.Forte@Sun.COM
12917836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_int, (char *)&ret);
12927836SJohn.Forte@Sun.COM }
12937836SJohn.Forte@Sun.COM
12947836SJohn.Forte@Sun.COM /*
12957836SJohn.Forte@Sun.COM * r_net_bmap (v6)
12967836SJohn.Forte@Sun.COM * WARNING acts as both client and server
12977836SJohn.Forte@Sun.COM */
12987836SJohn.Forte@Sun.COM static void
r_net_bmap6(SVCXPRT * xprt)12997836SJohn.Forte@Sun.COM r_net_bmap6(SVCXPRT *xprt)
13007836SJohn.Forte@Sun.COM {
13017836SJohn.Forte@Sun.COM int e, ret = EINVAL;
13027836SJohn.Forte@Sun.COM struct bmap6 b;
13037836SJohn.Forte@Sun.COM rdc_k_info_t *krdc;
13047836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
13057836SJohn.Forte@Sun.COM
13067836SJohn.Forte@Sun.COM e = SVC_GETARGS(xprt, xdr_bmap6, (char *)&b);
13077836SJohn.Forte@Sun.COM if (e == TRUE) {
13087836SJohn.Forte@Sun.COM krdc = &rdc_k_info[b.cd];
13097836SJohn.Forte@Sun.COM urdc = &rdc_u_info[b.cd];
13107836SJohn.Forte@Sun.COM if (b.cd >= 0 && b.cd < rdc_max_sets && IS_ENABLED(urdc) &&
13117836SJohn.Forte@Sun.COM ((krdc->type_flag & RDC_DISABLEPEND) == 0)) {
13127836SJohn.Forte@Sun.COM krdc->rpc_version = RDC_VERSION6;
13137836SJohn.Forte@Sun.COM ret = RDC_SEND_BITMAP(&b);
13147836SJohn.Forte@Sun.COM }
13157836SJohn.Forte@Sun.COM }
13167836SJohn.Forte@Sun.COM /*
13177836SJohn.Forte@Sun.COM * If the bitmap send has succeeded, clear it.
13187836SJohn.Forte@Sun.COM */
13197836SJohn.Forte@Sun.COM if (ret == 0) {
13207836SJohn.Forte@Sun.COM #ifdef DEBUG
13219093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!Bitmap clear in r_net_bmap6");
13227836SJohn.Forte@Sun.COM #endif
13237836SJohn.Forte@Sun.COM RDC_ZERO_BITMAP(krdc);
13247836SJohn.Forte@Sun.COM rdc_many_enter(krdc);
13257836SJohn.Forte@Sun.COM rdc_clr_flags(urdc, RDC_CLR_AFTERSYNC);
13267836SJohn.Forte@Sun.COM rdc_many_exit(krdc);
13277836SJohn.Forte@Sun.COM }
13287836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_int, (char *)&ret);
13297836SJohn.Forte@Sun.COM }
13307836SJohn.Forte@Sun.COM
13317836SJohn.Forte@Sun.COM /*
13327836SJohn.Forte@Sun.COM * r_net_bdata
13337836SJohn.Forte@Sun.COM */
13347836SJohn.Forte@Sun.COM static void
r_net_bdata(SVCXPRT * xprt)13357836SJohn.Forte@Sun.COM r_net_bdata(SVCXPRT *xprt)
13367836SJohn.Forte@Sun.COM {
13377836SJohn.Forte@Sun.COM struct net_bdata bd;
13387836SJohn.Forte@Sun.COM struct net_bdata6 bd6;
13397836SJohn.Forte@Sun.COM int e, ret = -1;
13407836SJohn.Forte@Sun.COM rdc_k_info_t *krdc;
13417836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
13427836SJohn.Forte@Sun.COM
13437836SJohn.Forte@Sun.COM /*
13447836SJohn.Forte@Sun.COM * We have to convert it to the internal form here,
13457836SJohn.Forte@Sun.COM * net_data6, when we know that we will have to convert
13467836SJohn.Forte@Sun.COM * it back to the v5 variant for transmission.
13477836SJohn.Forte@Sun.COM */
13487836SJohn.Forte@Sun.COM
13497836SJohn.Forte@Sun.COM bd.data.data_val = kmem_alloc(BMAP_BLKSIZE, KM_NOSLEEP);
13507836SJohn.Forte@Sun.COM if (bd.data.data_val == NULL)
13517836SJohn.Forte@Sun.COM goto out;
13527836SJohn.Forte@Sun.COM
13537836SJohn.Forte@Sun.COM e = SVC_GETARGS(xprt, xdr_net_bdata, (char *)&bd);
13547836SJohn.Forte@Sun.COM if (e == TRUE) {
13557836SJohn.Forte@Sun.COM krdc = &rdc_k_info[bd.cd];
13567836SJohn.Forte@Sun.COM urdc = &rdc_u_info[bd.cd];
13577836SJohn.Forte@Sun.COM if (bd.cd >= 0 && bd.cd < rdc_max_sets && IS_ENABLED(urdc) &&
13587836SJohn.Forte@Sun.COM ((krdc->type_flag & RDC_DISABLEPEND) == 0)) {
13597836SJohn.Forte@Sun.COM bd6.cd = bd.cd;
13607836SJohn.Forte@Sun.COM bd6.offset = bd.offset;
13617836SJohn.Forte@Sun.COM bd6.size = bd.size;
13627836SJohn.Forte@Sun.COM bd6.data.data_len = bd.data.data_len;
13637836SJohn.Forte@Sun.COM bd6.data.data_val = bd.data.data_val;
13647836SJohn.Forte@Sun.COM ret = RDC_OR_BITMAP(&bd6);
13657836SJohn.Forte@Sun.COM }
13667836SJohn.Forte@Sun.COM }
13677836SJohn.Forte@Sun.COM kmem_free(bd.data.data_val, BMAP_BLKSIZE);
13687836SJohn.Forte@Sun.COM out:
13697836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_int, (char *)&ret);
13707836SJohn.Forte@Sun.COM }
13717836SJohn.Forte@Sun.COM
13727836SJohn.Forte@Sun.COM /*
13737836SJohn.Forte@Sun.COM * r_net_bdata v6
13747836SJohn.Forte@Sun.COM */
13757836SJohn.Forte@Sun.COM static void
r_net_bdata6(SVCXPRT * xprt)13767836SJohn.Forte@Sun.COM r_net_bdata6(SVCXPRT *xprt)
13777836SJohn.Forte@Sun.COM {
13787836SJohn.Forte@Sun.COM struct net_bdata6 bd;
13797836SJohn.Forte@Sun.COM int e, ret = -1;
13807836SJohn.Forte@Sun.COM rdc_k_info_t *krdc;
13817836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
13827836SJohn.Forte@Sun.COM
13837836SJohn.Forte@Sun.COM /*
13847836SJohn.Forte@Sun.COM * just allocate the bigger block, regardless of < V7
13857836SJohn.Forte@Sun.COM * bd.size will dictate how much we lor into our bitmap
13867836SJohn.Forte@Sun.COM * the other option would be write r_net_bdata7 that is identical
13877836SJohn.Forte@Sun.COM * to this function, but a V7 alloc.
13887836SJohn.Forte@Sun.COM */
13897836SJohn.Forte@Sun.COM bd.data.data_val = kmem_alloc(BMAP_BLKSIZEV7, KM_NOSLEEP);
13907836SJohn.Forte@Sun.COM if (bd.data.data_val == NULL)
13917836SJohn.Forte@Sun.COM goto out;
13927836SJohn.Forte@Sun.COM
13937836SJohn.Forte@Sun.COM e = SVC_GETARGS(xprt, xdr_net_bdata6, (char *)&bd);
13947836SJohn.Forte@Sun.COM if (e == TRUE) {
13957836SJohn.Forte@Sun.COM krdc = &rdc_k_info[bd.cd];
13967836SJohn.Forte@Sun.COM urdc = &rdc_u_info[bd.cd];
13977836SJohn.Forte@Sun.COM if (bd.cd >= 0 && bd.cd < rdc_max_sets && IS_ENABLED(urdc) &&
13987836SJohn.Forte@Sun.COM ((krdc->type_flag & RDC_DISABLEPEND) == 0))
13997836SJohn.Forte@Sun.COM ret = RDC_OR_BITMAP(&bd);
14007836SJohn.Forte@Sun.COM }
14017836SJohn.Forte@Sun.COM /*
14027836SJohn.Forte@Sun.COM * Write the merged bitmap.
14037836SJohn.Forte@Sun.COM */
14047836SJohn.Forte@Sun.COM if ((ret == 0) && bd.endoblk && (krdc->bitmap_write > 0)) {
14057836SJohn.Forte@Sun.COM #ifdef DEBUG
14069093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!r_net_bdata6: Written bitmap for %s:%s",
14077836SJohn.Forte@Sun.COM urdc->secondary.intf, urdc->secondary.file);
14087836SJohn.Forte@Sun.COM #endif
14097836SJohn.Forte@Sun.COM ret = rdc_write_bitmap(krdc);
14107836SJohn.Forte@Sun.COM }
14117836SJohn.Forte@Sun.COM kmem_free(bd.data.data_val, BMAP_BLKSIZEV7);
14127836SJohn.Forte@Sun.COM out:
14137836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_int, (char *)&ret);
14147836SJohn.Forte@Sun.COM }
14157836SJohn.Forte@Sun.COM
14167836SJohn.Forte@Sun.COM /*
14177836SJohn.Forte@Sun.COM * r_net_getsize (v5)
14187836SJohn.Forte@Sun.COM */
14197836SJohn.Forte@Sun.COM static void
r_net_getsize(SVCXPRT * xprt)14207836SJohn.Forte@Sun.COM r_net_getsize(SVCXPRT *xprt)
14217836SJohn.Forte@Sun.COM {
14227836SJohn.Forte@Sun.COM int e, ret = -1, index;
14237836SJohn.Forte@Sun.COM rdc_k_info_t *krdc;
14247836SJohn.Forte@Sun.COM
14257836SJohn.Forte@Sun.COM e = SVC_GETARGS(xprt, xdr_int, (char *)&index);
14267836SJohn.Forte@Sun.COM if (e) {
14277836SJohn.Forte@Sun.COM krdc = &rdc_k_info[index];
14287836SJohn.Forte@Sun.COM if (IS_VALID_INDEX(index) && ((krdc->type_flag &
14297836SJohn.Forte@Sun.COM RDC_DISABLEPEND) == 0))
14307836SJohn.Forte@Sun.COM ret = mirror_getsize(index);
14317836SJohn.Forte@Sun.COM }
14327836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_int, (char *)&ret);
14337836SJohn.Forte@Sun.COM }
14347836SJohn.Forte@Sun.COM
14357836SJohn.Forte@Sun.COM /*
14367836SJohn.Forte@Sun.COM * r_net_getsize (v6)
14377836SJohn.Forte@Sun.COM */
14387836SJohn.Forte@Sun.COM static void
r_net_getsize6(SVCXPRT * xprt)14397836SJohn.Forte@Sun.COM r_net_getsize6(SVCXPRT *xprt)
14407836SJohn.Forte@Sun.COM {
14417836SJohn.Forte@Sun.COM int e, index;
14427836SJohn.Forte@Sun.COM rdc_k_info_t *krdc;
14437836SJohn.Forte@Sun.COM uint64_t ret;
14447836SJohn.Forte@Sun.COM
14457836SJohn.Forte@Sun.COM /*
14467836SJohn.Forte@Sun.COM * small change in semantics here, as we can't return
14477836SJohn.Forte@Sun.COM * -1 over the wire anymore.
14487836SJohn.Forte@Sun.COM */
14497836SJohn.Forte@Sun.COM ret = 0;
14507836SJohn.Forte@Sun.COM
14517836SJohn.Forte@Sun.COM e = SVC_GETARGS(xprt, xdr_int, (char *)&index);
14527836SJohn.Forte@Sun.COM if (e) {
14537836SJohn.Forte@Sun.COM krdc = &rdc_k_info[index];
14547836SJohn.Forte@Sun.COM if (IS_VALID_INDEX(index) && ((krdc->type_flag &
14557836SJohn.Forte@Sun.COM RDC_DISABLEPEND) == 0))
14567836SJohn.Forte@Sun.COM ret = mirror_getsize(index);
14577836SJohn.Forte@Sun.COM }
14587836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_u_longlong_t, (char *)&ret);
14597836SJohn.Forte@Sun.COM }
14607836SJohn.Forte@Sun.COM
14617836SJohn.Forte@Sun.COM
14627836SJohn.Forte@Sun.COM /*
14637836SJohn.Forte@Sun.COM * r_net_state4
14647836SJohn.Forte@Sun.COM */
14657836SJohn.Forte@Sun.COM static void
r_net_state4(SVCXPRT * xprt)14667836SJohn.Forte@Sun.COM r_net_state4(SVCXPRT *xprt)
14677836SJohn.Forte@Sun.COM {
14687836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
14697836SJohn.Forte@Sun.COM rdc_k_info_t *krdc;
14707836SJohn.Forte@Sun.COM struct set_state4 state;
14717836SJohn.Forte@Sun.COM rdc_set_t rdc_set;
14727836SJohn.Forte@Sun.COM int e, index = -1;
14737836SJohn.Forte@Sun.COM int options;
14747836SJohn.Forte@Sun.COM int log = 0;
14757836SJohn.Forte@Sun.COM int done = 0;
14767836SJohn.Forte@Sun.COM int slave = 0;
14777836SJohn.Forte@Sun.COM int rev_sync = 0;
14787836SJohn.Forte@Sun.COM
14797836SJohn.Forte@Sun.COM e = SVC_GETARGS(xprt, xdr_set_state4, (char *)&state);
14807836SJohn.Forte@Sun.COM if (e) {
14817836SJohn.Forte@Sun.COM init_rdc_netbuf(&(rdc_set.primary.addr));
14827836SJohn.Forte@Sun.COM init_rdc_netbuf(&(rdc_set.secondary.addr));
14837836SJohn.Forte@Sun.COM bcopy(state.netaddr, rdc_set.primary.addr.buf,
14847836SJohn.Forte@Sun.COM state.netaddrlen);
14857836SJohn.Forte@Sun.COM bcopy(state.rnetaddr, rdc_set.secondary.addr.buf,
14867836SJohn.Forte@Sun.COM state.rnetaddrlen);
14877836SJohn.Forte@Sun.COM rdc_set.primary.addr.len = state.netaddrlen;
14887836SJohn.Forte@Sun.COM rdc_set.secondary.addr.len = state.rnetaddrlen;
14897836SJohn.Forte@Sun.COM (void) strncpy(rdc_set.primary.file, state.pfile,
14907836SJohn.Forte@Sun.COM RDC_MAXNAMLEN);
14917836SJohn.Forte@Sun.COM (void) strncpy(rdc_set.secondary.file, state.sfile,
14927836SJohn.Forte@Sun.COM RDC_MAXNAMLEN);
14937836SJohn.Forte@Sun.COM options = state.flag;
14947836SJohn.Forte@Sun.COM index = rdc_lookup_byaddr(&rdc_set);
14957836SJohn.Forte@Sun.COM
14967836SJohn.Forte@Sun.COM krdc = &rdc_k_info[index];
14977836SJohn.Forte@Sun.COM
14987836SJohn.Forte@Sun.COM if (index < 0 || (krdc->type_flag & RDC_DISABLEPEND)) {
14997836SJohn.Forte@Sun.COM #ifdef DEBUG
15007836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
15019093SRamana.Srikanth@Sun.COM "!r_net_state: no index or disable pending");
15027836SJohn.Forte@Sun.COM #endif
15037836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_int, (char *)&index);
15047836SJohn.Forte@Sun.COM return;
15057836SJohn.Forte@Sun.COM }
15067836SJohn.Forte@Sun.COM
15077836SJohn.Forte@Sun.COM urdc = &rdc_u_info[index];
15087836SJohn.Forte@Sun.COM
15097836SJohn.Forte@Sun.COM if (!IS_ENABLED(urdc)) {
15107836SJohn.Forte@Sun.COM index = -1;
15117836SJohn.Forte@Sun.COM #ifdef DEBUG
15129093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!r_net_state: set not enabled ");
15137836SJohn.Forte@Sun.COM #endif
15147836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_int, (char *)&index);
15157836SJohn.Forte@Sun.COM return;
15167836SJohn.Forte@Sun.COM }
15177836SJohn.Forte@Sun.COM
15187836SJohn.Forte@Sun.COM if (krdc->lsrv == NULL) {
15199093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!r_net_state: no valid svp\n");
15207836SJohn.Forte@Sun.COM index = -1;
15217836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_int, (char *)&index);
15227836SJohn.Forte@Sun.COM return;
15237836SJohn.Forte@Sun.COM }
15247836SJohn.Forte@Sun.COM if (!krdc || !krdc->group) {
15257836SJohn.Forte@Sun.COM #ifdef DEBUG
15267836SJohn.Forte@Sun.COM cmn_err(CE_NOTE,
15279093SRamana.Srikanth@Sun.COM "!r_net_state: no valid krdc %p\n", (void*)krdc);
15287836SJohn.Forte@Sun.COM #endif
15297836SJohn.Forte@Sun.COM index = -1;
15307836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_int, (char *)&index);
15317836SJohn.Forte@Sun.COM return;
15327836SJohn.Forte@Sun.COM }
15337836SJohn.Forte@Sun.COM
15347836SJohn.Forte@Sun.COM mutex_enter(&rdc_conf_lock);
15357836SJohn.Forte@Sun.COM if (krdc->type_flag & RDC_DISABLEPEND) {
15367836SJohn.Forte@Sun.COM mutex_exit(&rdc_conf_lock);
15377836SJohn.Forte@Sun.COM index = -1;
15387836SJohn.Forte@Sun.COM #ifdef DEBUG
15399093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!r_net_state: disable pending");
15407836SJohn.Forte@Sun.COM #endif
15417836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_int, (char *)&index);
15427836SJohn.Forte@Sun.COM return;
15437836SJohn.Forte@Sun.COM }
15447836SJohn.Forte@Sun.COM set_busy(krdc);
15457836SJohn.Forte@Sun.COM mutex_exit(&rdc_conf_lock);
15467836SJohn.Forte@Sun.COM
15477836SJohn.Forte@Sun.COM rdc_group_enter(krdc);
15487836SJohn.Forte@Sun.COM
15497836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_PRIMARY)
15507836SJohn.Forte@Sun.COM krdc->intf = rdc_add_to_if(krdc->lsrv,
15517836SJohn.Forte@Sun.COM &(urdc->primary.addr), &(urdc->secondary.addr), 1);
15527836SJohn.Forte@Sun.COM else
15537836SJohn.Forte@Sun.COM krdc->intf = rdc_add_to_if(krdc->lsrv,
15547836SJohn.Forte@Sun.COM &(urdc->secondary.addr), &(urdc->primary.addr), 0);
15557836SJohn.Forte@Sun.COM
15567836SJohn.Forte@Sun.COM if (options & CCIO_SLAVE) {
15577836SJohn.Forte@Sun.COM /*
15587836SJohn.Forte@Sun.COM * mark that the bitmap needs clearing.
15597836SJohn.Forte@Sun.COM */
15607836SJohn.Forte@Sun.COM rdc_many_enter(krdc);
15617836SJohn.Forte@Sun.COM rdc_set_flags(urdc, RDC_CLR_AFTERSYNC);
15627836SJohn.Forte@Sun.COM rdc_many_exit(krdc);
15637836SJohn.Forte@Sun.COM
15647836SJohn.Forte@Sun.COM /* Starting forward sync */
15657836SJohn.Forte@Sun.COM if (urdc->volume_size == 0)
15667836SJohn.Forte@Sun.COM rdc_get_details(krdc);
15677836SJohn.Forte@Sun.COM if (urdc->volume_size == 0) {
15687836SJohn.Forte@Sun.COM index = -1;
15697836SJohn.Forte@Sun.COM goto out;
15707836SJohn.Forte@Sun.COM }
15717836SJohn.Forte@Sun.COM if (krdc->dcio_bitmap == NULL) {
15727836SJohn.Forte@Sun.COM if (rdc_resume_bitmap(krdc) < 0) {
15737836SJohn.Forte@Sun.COM index = -1;
15747836SJohn.Forte@Sun.COM goto out;
15757836SJohn.Forte@Sun.COM }
15767836SJohn.Forte@Sun.COM }
15777836SJohn.Forte@Sun.COM if (rdc_allow_sec_sync(urdc, CCIO_SLAVE) < 0) {
15787836SJohn.Forte@Sun.COM index = -1;
15797836SJohn.Forte@Sun.COM goto out;
15807836SJohn.Forte@Sun.COM }
15817836SJohn.Forte@Sun.COM rdc_dump_dsets(index);
15827836SJohn.Forte@Sun.COM slave = 1;
15837836SJohn.Forte@Sun.COM } else if (options & CCIO_RSYNC) {
15847836SJohn.Forte@Sun.COM /*
15857836SJohn.Forte@Sun.COM * mark that the bitmap needs clearing.
15867836SJohn.Forte@Sun.COM */
15877836SJohn.Forte@Sun.COM rdc_many_enter(krdc);
15887836SJohn.Forte@Sun.COM rdc_set_flags(urdc, RDC_CLR_AFTERSYNC);
15897836SJohn.Forte@Sun.COM rdc_many_exit(krdc);
15907836SJohn.Forte@Sun.COM
15917836SJohn.Forte@Sun.COM /* Starting reverse sync */
15927836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & (RDC_SYNC_NEEDED |
15937836SJohn.Forte@Sun.COM RDC_VOL_FAILED | RDC_BMP_FAILED)) {
15947836SJohn.Forte@Sun.COM index = -1;
15957836SJohn.Forte@Sun.COM goto out;
15967836SJohn.Forte@Sun.COM }
15977836SJohn.Forte@Sun.COM if (rdc_allow_sec_sync(urdc, CCIO_RSYNC) < 0) {
15987836SJohn.Forte@Sun.COM index = -1;
15997836SJohn.Forte@Sun.COM goto out;
16007836SJohn.Forte@Sun.COM }
16017836SJohn.Forte@Sun.COM rdc_dump_dsets(index);
16027836SJohn.Forte@Sun.COM rev_sync = 1;
16037836SJohn.Forte@Sun.COM } else if (options & CCIO_DONE) {
16047836SJohn.Forte@Sun.COM /* Sync completed OK */
16057836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_SYNC_NEEDED)
16067836SJohn.Forte@Sun.COM done = 1; /* forward sync complete */
16077836SJohn.Forte@Sun.COM rdc_many_enter(krdc);
16087836SJohn.Forte@Sun.COM rdc_clr_flags(urdc, RDC_SYNCING | RDC_SYNC_NEEDED);
16097836SJohn.Forte@Sun.COM rdc_clr_mflags(urdc, RDC_SLAVE | RDC_RSYNC_NEEDED);
16107836SJohn.Forte@Sun.COM rdc_many_exit(krdc);
16117836SJohn.Forte@Sun.COM rdc_write_state(urdc);
16127836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_CLR_AFTERSYNC) {
16137836SJohn.Forte@Sun.COM RDC_ZERO_BITMAP(krdc);
16147836SJohn.Forte@Sun.COM rdc_many_enter(krdc);
16157836SJohn.Forte@Sun.COM rdc_clr_flags(urdc, RDC_CLR_AFTERSYNC);
16167836SJohn.Forte@Sun.COM rdc_many_exit(krdc);
16177836SJohn.Forte@Sun.COM }
16187836SJohn.Forte@Sun.COM } else if (options & CCIO_ENABLELOG) {
16197836SJohn.Forte@Sun.COM /* Sync aborted or logging started */
16207836SJohn.Forte@Sun.COM if (!(rdc_get_vflags(urdc) & RDC_PRIMARY)) {
16217836SJohn.Forte@Sun.COM rdc_clr_flags(urdc, RDC_SYNCING);
16227836SJohn.Forte@Sun.COM rdc_many_enter(krdc);
16237836SJohn.Forte@Sun.COM rdc_clr_mflags(urdc, RDC_SLAVE);
16247836SJohn.Forte@Sun.COM rdc_many_exit(krdc);
16257836SJohn.Forte@Sun.COM }
16267836SJohn.Forte@Sun.COM log = 1;
16277836SJohn.Forte@Sun.COM }
16287836SJohn.Forte@Sun.COM out:
16297836SJohn.Forte@Sun.COM rdc_group_exit(krdc);
16307836SJohn.Forte@Sun.COM free_rdc_netbuf(&(rdc_set.primary.addr));
16317836SJohn.Forte@Sun.COM free_rdc_netbuf(&(rdc_set.secondary.addr));
16327836SJohn.Forte@Sun.COM
16337836SJohn.Forte@Sun.COM if (slave) {
16347836SJohn.Forte@Sun.COM if (_rdc_sync_event_notify(RDC_SYNC_START,
16357836SJohn.Forte@Sun.COM urdc->secondary.file, urdc->group_name) >= 0) {
16367836SJohn.Forte@Sun.COM rdc_group_enter(krdc);
16377836SJohn.Forte@Sun.COM rdc_clr_flags(urdc, RDC_LOGGING);
16387836SJohn.Forte@Sun.COM rdc_many_enter(krdc);
16397836SJohn.Forte@Sun.COM rdc_clr_flags(urdc, RDC_VOL_FAILED);
16407836SJohn.Forte@Sun.COM rdc_set_flags(urdc,
16417836SJohn.Forte@Sun.COM RDC_SYNCING | RDC_SYNC_NEEDED);
16427836SJohn.Forte@Sun.COM rdc_set_mflags(urdc, RDC_SLAVE);
16437836SJohn.Forte@Sun.COM rdc_many_exit(krdc);
16447836SJohn.Forte@Sun.COM rdc_write_state(urdc);
16457836SJohn.Forte@Sun.COM rdc_group_exit(krdc);
16467836SJohn.Forte@Sun.COM } else {
16477836SJohn.Forte@Sun.COM index = -1;
16487836SJohn.Forte@Sun.COM }
16497836SJohn.Forte@Sun.COM } else if (rev_sync) {
16507836SJohn.Forte@Sun.COM /* Check to see if volume is mounted */
16517836SJohn.Forte@Sun.COM if (_rdc_sync_event_notify(RDC_RSYNC_START,
16527836SJohn.Forte@Sun.COM urdc->secondary.file, urdc->group_name) >= 0) {
16537836SJohn.Forte@Sun.COM rdc_group_enter(krdc);
16547836SJohn.Forte@Sun.COM rdc_clr_flags(urdc, RDC_LOGGING);
16557836SJohn.Forte@Sun.COM rdc_set_flags(urdc, RDC_SYNCING);
16567836SJohn.Forte@Sun.COM rdc_write_state(urdc);
16577836SJohn.Forte@Sun.COM rdc_group_exit(krdc);
16587836SJohn.Forte@Sun.COM } else {
16597836SJohn.Forte@Sun.COM index = -1;
16607836SJohn.Forte@Sun.COM }
16617836SJohn.Forte@Sun.COM } else if (done) {
16627836SJohn.Forte@Sun.COM
16637836SJohn.Forte@Sun.COM /*
16647836SJohn.Forte@Sun.COM * special case...
16657836SJohn.Forte@Sun.COM * if this set is in a group, then sndrsyncd will
16667836SJohn.Forte@Sun.COM * make sure that all sets in the group are REP
16677836SJohn.Forte@Sun.COM * before updating the config to "update", telling
16687836SJohn.Forte@Sun.COM * sndrsyncd that it is ok to take anther snapshot
16697836SJohn.Forte@Sun.COM * on a following sync. The important part about
16707836SJohn.Forte@Sun.COM * the whole thing is that syncd needs kernel stats.
16717836SJohn.Forte@Sun.COM * however, this thread must set the set busy to
16727836SJohn.Forte@Sun.COM * avoid disables. since this is the only
16737836SJohn.Forte@Sun.COM * sync_event_notify() that will cause a status
16747836SJohn.Forte@Sun.COM * call back into the kernel, and we will not be
16757836SJohn.Forte@Sun.COM * accessing the group structure, we have to wakeup now
16767836SJohn.Forte@Sun.COM */
16777836SJohn.Forte@Sun.COM
16787836SJohn.Forte@Sun.COM mutex_enter(&rdc_conf_lock);
16797836SJohn.Forte@Sun.COM wakeup_busy(krdc);
16807836SJohn.Forte@Sun.COM mutex_exit(&rdc_conf_lock);
16817836SJohn.Forte@Sun.COM
16827836SJohn.Forte@Sun.COM (void) _rdc_sync_event_notify(RDC_SYNC_DONE,
16837836SJohn.Forte@Sun.COM urdc->secondary.file, urdc->group_name);
16847836SJohn.Forte@Sun.COM }
16857836SJohn.Forte@Sun.COM }
16867836SJohn.Forte@Sun.COM
16877836SJohn.Forte@Sun.COM if (!done) {
16887836SJohn.Forte@Sun.COM mutex_enter(&rdc_conf_lock);
16897836SJohn.Forte@Sun.COM wakeup_busy(krdc);
16907836SJohn.Forte@Sun.COM mutex_exit(&rdc_conf_lock);
16917836SJohn.Forte@Sun.COM }
16927836SJohn.Forte@Sun.COM
16937836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_int, (char *)&index);
16947836SJohn.Forte@Sun.COM if (log) {
16957836SJohn.Forte@Sun.COM rdc_group_enter(krdc);
16967836SJohn.Forte@Sun.COM rdc_group_log(krdc, RDC_NOFLUSH | RDC_OTHERREMOTE,
16979093SRamana.Srikanth@Sun.COM "Sync aborted or logging started");
16987836SJohn.Forte@Sun.COM rdc_group_exit(krdc);
16997836SJohn.Forte@Sun.COM }
17007836SJohn.Forte@Sun.COM }
17017836SJohn.Forte@Sun.COM
17027836SJohn.Forte@Sun.COM
17037836SJohn.Forte@Sun.COM /*
17047836SJohn.Forte@Sun.COM * r_net_state
17057836SJohn.Forte@Sun.COM */
17067836SJohn.Forte@Sun.COM static void
r_net_state(SVCXPRT * xprt)17077836SJohn.Forte@Sun.COM r_net_state(SVCXPRT *xprt)
17087836SJohn.Forte@Sun.COM {
17097836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
17107836SJohn.Forte@Sun.COM rdc_k_info_t *krdc;
17117836SJohn.Forte@Sun.COM struct set_state state;
17127836SJohn.Forte@Sun.COM rdc_set_t rdc_set;
17137836SJohn.Forte@Sun.COM int e, index = -1;
17147836SJohn.Forte@Sun.COM int options;
17157836SJohn.Forte@Sun.COM int log = 0;
17167836SJohn.Forte@Sun.COM int done = 0;
17177836SJohn.Forte@Sun.COM int slave = 0;
17187836SJohn.Forte@Sun.COM int rev_sync = 0;
17197836SJohn.Forte@Sun.COM unsigned short *sp;
17207836SJohn.Forte@Sun.COM
17217836SJohn.Forte@Sun.COM bzero(&state, sizeof (struct set_state));
17227836SJohn.Forte@Sun.COM e = SVC_GETARGS(xprt, xdr_set_state, (char *)&state);
17237836SJohn.Forte@Sun.COM if (e) {
17247836SJohn.Forte@Sun.COM init_rdc_netbuf(&(rdc_set.primary.addr));
17257836SJohn.Forte@Sun.COM init_rdc_netbuf(&(rdc_set.secondary.addr));
17267836SJohn.Forte@Sun.COM sp = (unsigned short *)(state.netaddr.buf);
17277836SJohn.Forte@Sun.COM *sp = ntohs(*sp);
17287836SJohn.Forte@Sun.COM bcopy(state.netaddr.buf, rdc_set.primary.addr.buf,
17297836SJohn.Forte@Sun.COM state.netaddrlen);
17307836SJohn.Forte@Sun.COM sp = (unsigned short *)(state.rnetaddr.buf);
17317836SJohn.Forte@Sun.COM *sp = ntohs(*sp);
17327836SJohn.Forte@Sun.COM bcopy(state.rnetaddr.buf, rdc_set.secondary.addr.buf,
17337836SJohn.Forte@Sun.COM state.rnetaddrlen);
17347836SJohn.Forte@Sun.COM rdc_set.primary.addr.len = state.netaddrlen;
17357836SJohn.Forte@Sun.COM rdc_set.secondary.addr.len = state.rnetaddrlen;
17367836SJohn.Forte@Sun.COM (void) strncpy(rdc_set.primary.file, state.pfile,
17377836SJohn.Forte@Sun.COM RDC_MAXNAMLEN);
17387836SJohn.Forte@Sun.COM (void) strncpy(rdc_set.secondary.file, state.sfile,
17397836SJohn.Forte@Sun.COM RDC_MAXNAMLEN);
17407836SJohn.Forte@Sun.COM options = state.flag;
17417836SJohn.Forte@Sun.COM index = rdc_lookup_byaddr(&rdc_set);
17427836SJohn.Forte@Sun.COM
17437836SJohn.Forte@Sun.COM krdc = &rdc_k_info[index];
17447836SJohn.Forte@Sun.COM
17457836SJohn.Forte@Sun.COM if (index < 0 || (krdc->type_flag & RDC_DISABLEPEND)) {
17467836SJohn.Forte@Sun.COM #ifdef DEBUG
17477836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
17489093SRamana.Srikanth@Sun.COM "!r_net_state: no index or disable pending");
17497836SJohn.Forte@Sun.COM #endif
17507836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_int, (char *)&index);
17517836SJohn.Forte@Sun.COM return;
17527836SJohn.Forte@Sun.COM }
17537836SJohn.Forte@Sun.COM
17547836SJohn.Forte@Sun.COM urdc = &rdc_u_info[index];
17557836SJohn.Forte@Sun.COM
17567836SJohn.Forte@Sun.COM if (!IS_ENABLED(urdc)) {
17577836SJohn.Forte@Sun.COM index = -1;
17587836SJohn.Forte@Sun.COM #ifdef DEBUG
17599093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!r_net_state: set not enabled ");
17607836SJohn.Forte@Sun.COM #endif
17617836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_int, (char *)&index);
17627836SJohn.Forte@Sun.COM return;
17637836SJohn.Forte@Sun.COM }
17647836SJohn.Forte@Sun.COM
17657836SJohn.Forte@Sun.COM if (krdc->lsrv == NULL) {
17669093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!r_net_state: no valid svp\n");
17677836SJohn.Forte@Sun.COM index = -1;
17687836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_int, (char *)&index);
17697836SJohn.Forte@Sun.COM return;
17707836SJohn.Forte@Sun.COM }
17717836SJohn.Forte@Sun.COM if (!krdc || !krdc->group) {
17727836SJohn.Forte@Sun.COM #ifdef DEBUG
17737836SJohn.Forte@Sun.COM cmn_err(CE_NOTE,
17749093SRamana.Srikanth@Sun.COM "!r_net_state: no valid krdc %p\n", (void*)krdc);
17757836SJohn.Forte@Sun.COM #endif
17767836SJohn.Forte@Sun.COM index = -1;
17777836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_int, (char *)&index);
17787836SJohn.Forte@Sun.COM return;
17797836SJohn.Forte@Sun.COM }
17807836SJohn.Forte@Sun.COM
17817836SJohn.Forte@Sun.COM mutex_enter(&rdc_conf_lock);
17827836SJohn.Forte@Sun.COM if (krdc->type_flag & RDC_DISABLEPEND) {
17837836SJohn.Forte@Sun.COM mutex_exit(&rdc_conf_lock);
17847836SJohn.Forte@Sun.COM index = -1;
17857836SJohn.Forte@Sun.COM #ifdef DEBUG
17869093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!r_net_state: disable pending");
17877836SJohn.Forte@Sun.COM #endif
17887836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_int, (char *)&index);
17897836SJohn.Forte@Sun.COM return;
17907836SJohn.Forte@Sun.COM }
17917836SJohn.Forte@Sun.COM set_busy(krdc);
17927836SJohn.Forte@Sun.COM mutex_exit(&rdc_conf_lock);
17937836SJohn.Forte@Sun.COM
17947836SJohn.Forte@Sun.COM rdc_group_enter(krdc);
17957836SJohn.Forte@Sun.COM
17967836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_PRIMARY)
17977836SJohn.Forte@Sun.COM krdc->intf = rdc_add_to_if(krdc->lsrv,
17987836SJohn.Forte@Sun.COM &(urdc->primary.addr), &(urdc->secondary.addr), 1);
17997836SJohn.Forte@Sun.COM else
18007836SJohn.Forte@Sun.COM krdc->intf = rdc_add_to_if(krdc->lsrv,
18017836SJohn.Forte@Sun.COM &(urdc->secondary.addr), &(urdc->primary.addr), 0);
18027836SJohn.Forte@Sun.COM
18037836SJohn.Forte@Sun.COM if (options & CCIO_SLAVE) {
18047836SJohn.Forte@Sun.COM /*
18057836SJohn.Forte@Sun.COM * mark that the bitmap needs clearing.
18067836SJohn.Forte@Sun.COM */
18077836SJohn.Forte@Sun.COM rdc_many_enter(krdc);
18087836SJohn.Forte@Sun.COM rdc_set_flags(urdc, RDC_CLR_AFTERSYNC);
18097836SJohn.Forte@Sun.COM rdc_many_exit(krdc);
18107836SJohn.Forte@Sun.COM
18117836SJohn.Forte@Sun.COM /* Starting forward sync */
18127836SJohn.Forte@Sun.COM if (urdc->volume_size == 0)
18137836SJohn.Forte@Sun.COM rdc_get_details(krdc);
18147836SJohn.Forte@Sun.COM if (urdc->volume_size == 0) {
18157836SJohn.Forte@Sun.COM index = -1;
18167836SJohn.Forte@Sun.COM goto out;
18177836SJohn.Forte@Sun.COM }
18187836SJohn.Forte@Sun.COM if (krdc->dcio_bitmap == NULL) {
18197836SJohn.Forte@Sun.COM if (rdc_resume_bitmap(krdc) < 0) {
18207836SJohn.Forte@Sun.COM index = -1;
18217836SJohn.Forte@Sun.COM goto out;
18227836SJohn.Forte@Sun.COM }
18237836SJohn.Forte@Sun.COM }
18247836SJohn.Forte@Sun.COM if (rdc_allow_sec_sync(urdc, CCIO_SLAVE) < 0) {
18257836SJohn.Forte@Sun.COM index = -1;
18267836SJohn.Forte@Sun.COM goto out;
18277836SJohn.Forte@Sun.COM }
18287836SJohn.Forte@Sun.COM rdc_dump_dsets(index);
18297836SJohn.Forte@Sun.COM slave = 1;
18307836SJohn.Forte@Sun.COM } else if (options & CCIO_RSYNC) {
18317836SJohn.Forte@Sun.COM /*
18327836SJohn.Forte@Sun.COM * mark that the bitmap needs clearing.
18337836SJohn.Forte@Sun.COM */
18347836SJohn.Forte@Sun.COM rdc_many_enter(krdc);
18357836SJohn.Forte@Sun.COM rdc_set_flags(urdc, RDC_CLR_AFTERSYNC);
18367836SJohn.Forte@Sun.COM rdc_many_exit(krdc);
18377836SJohn.Forte@Sun.COM
18387836SJohn.Forte@Sun.COM /* Starting reverse sync */
18397836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & (RDC_SYNC_NEEDED |
18407836SJohn.Forte@Sun.COM RDC_VOL_FAILED | RDC_BMP_FAILED)) {
18417836SJohn.Forte@Sun.COM index = -1;
18427836SJohn.Forte@Sun.COM goto out;
18437836SJohn.Forte@Sun.COM }
18447836SJohn.Forte@Sun.COM if (rdc_allow_sec_sync(urdc, CCIO_RSYNC) < 0) {
18457836SJohn.Forte@Sun.COM index = -1;
18467836SJohn.Forte@Sun.COM goto out;
18477836SJohn.Forte@Sun.COM }
18487836SJohn.Forte@Sun.COM rdc_dump_dsets(index);
18497836SJohn.Forte@Sun.COM rev_sync = 1;
18507836SJohn.Forte@Sun.COM } else if (options & CCIO_DONE) {
18517836SJohn.Forte@Sun.COM /* Sync completed OK */
18527836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_SYNC_NEEDED)
18537836SJohn.Forte@Sun.COM done = 1; /* forward sync complete */
18547836SJohn.Forte@Sun.COM rdc_many_enter(krdc);
18557836SJohn.Forte@Sun.COM rdc_clr_flags(urdc, RDC_SYNCING | RDC_SYNC_NEEDED);
18567836SJohn.Forte@Sun.COM rdc_clr_mflags(urdc, RDC_SLAVE | RDC_RSYNC_NEEDED);
18577836SJohn.Forte@Sun.COM rdc_many_exit(krdc);
18587836SJohn.Forte@Sun.COM rdc_write_state(urdc);
18597836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_CLR_AFTERSYNC) {
18607836SJohn.Forte@Sun.COM RDC_ZERO_BITMAP(krdc);
18617836SJohn.Forte@Sun.COM rdc_many_enter(krdc);
18627836SJohn.Forte@Sun.COM rdc_clr_flags(urdc, RDC_CLR_AFTERSYNC);
18637836SJohn.Forte@Sun.COM rdc_many_exit(krdc);
18647836SJohn.Forte@Sun.COM }
18657836SJohn.Forte@Sun.COM } else if (options & CCIO_ENABLELOG) {
18667836SJohn.Forte@Sun.COM /* Sync aborted or logging started */
18677836SJohn.Forte@Sun.COM if (!(rdc_get_vflags(urdc) & RDC_PRIMARY)) {
18687836SJohn.Forte@Sun.COM rdc_clr_flags(urdc, RDC_SYNCING);
18697836SJohn.Forte@Sun.COM rdc_many_enter(krdc);
18707836SJohn.Forte@Sun.COM rdc_clr_mflags(urdc, RDC_SLAVE);
18717836SJohn.Forte@Sun.COM rdc_many_exit(krdc);
18727836SJohn.Forte@Sun.COM }
18737836SJohn.Forte@Sun.COM log = 1;
18747836SJohn.Forte@Sun.COM }
18757836SJohn.Forte@Sun.COM out:
18767836SJohn.Forte@Sun.COM rdc_group_exit(krdc);
18777836SJohn.Forte@Sun.COM free_rdc_netbuf(&(rdc_set.primary.addr));
18787836SJohn.Forte@Sun.COM free_rdc_netbuf(&(rdc_set.secondary.addr));
18797836SJohn.Forte@Sun.COM
18807836SJohn.Forte@Sun.COM if (slave) {
18817836SJohn.Forte@Sun.COM if (_rdc_sync_event_notify(RDC_SYNC_START,
18827836SJohn.Forte@Sun.COM urdc->secondary.file, urdc->group_name) >= 0) {
18837836SJohn.Forte@Sun.COM rdc_group_enter(krdc);
18847836SJohn.Forte@Sun.COM rdc_clr_flags(urdc, RDC_LOGGING);
18857836SJohn.Forte@Sun.COM rdc_many_enter(krdc);
18867836SJohn.Forte@Sun.COM rdc_clr_flags(urdc, RDC_VOL_FAILED);
18877836SJohn.Forte@Sun.COM rdc_set_flags(urdc,
18887836SJohn.Forte@Sun.COM RDC_SYNCING | RDC_SYNC_NEEDED);
18897836SJohn.Forte@Sun.COM rdc_set_mflags(urdc, RDC_SLAVE);
18907836SJohn.Forte@Sun.COM rdc_many_exit(krdc);
18917836SJohn.Forte@Sun.COM rdc_write_state(urdc);
18927836SJohn.Forte@Sun.COM rdc_group_exit(krdc);
18937836SJohn.Forte@Sun.COM } else {
18947836SJohn.Forte@Sun.COM index = -1;
18957836SJohn.Forte@Sun.COM }
18967836SJohn.Forte@Sun.COM } else if (rev_sync) {
18977836SJohn.Forte@Sun.COM /* Check to see if volume is mounted */
18987836SJohn.Forte@Sun.COM if (_rdc_sync_event_notify(RDC_RSYNC_START,
18997836SJohn.Forte@Sun.COM urdc->secondary.file, urdc->group_name) >= 0) {
19007836SJohn.Forte@Sun.COM rdc_group_enter(krdc);
19017836SJohn.Forte@Sun.COM rdc_clr_flags(urdc, RDC_LOGGING);
19027836SJohn.Forte@Sun.COM rdc_set_flags(urdc, RDC_SYNCING);
19037836SJohn.Forte@Sun.COM rdc_write_state(urdc);
19047836SJohn.Forte@Sun.COM rdc_group_exit(krdc);
19057836SJohn.Forte@Sun.COM } else {
19067836SJohn.Forte@Sun.COM index = -1;
19077836SJohn.Forte@Sun.COM }
19087836SJohn.Forte@Sun.COM } else if (done) {
19097836SJohn.Forte@Sun.COM
19107836SJohn.Forte@Sun.COM /*
19117836SJohn.Forte@Sun.COM * special case...
19127836SJohn.Forte@Sun.COM * if this set is in a group, then sndrsyncd will
19137836SJohn.Forte@Sun.COM * make sure that all sets in the group are REP
19147836SJohn.Forte@Sun.COM * before updating the config to "update", telling
19157836SJohn.Forte@Sun.COM * sndrsyncd that it is ok to take anther snapshot
19167836SJohn.Forte@Sun.COM * on a following sync. The important part about
19177836SJohn.Forte@Sun.COM * the whole thing is that syncd needs kernel stats.
19187836SJohn.Forte@Sun.COM * however, this thread must set the set busy to
19197836SJohn.Forte@Sun.COM * avoid disables. since this is the only
19207836SJohn.Forte@Sun.COM * sync_event_notify() that will cause a status
19217836SJohn.Forte@Sun.COM * call back into the kernel, and we will not be
19227836SJohn.Forte@Sun.COM * accessing the group structure, we have to wakeup now
19237836SJohn.Forte@Sun.COM */
19247836SJohn.Forte@Sun.COM
19257836SJohn.Forte@Sun.COM mutex_enter(&rdc_conf_lock);
19267836SJohn.Forte@Sun.COM wakeup_busy(krdc);
19277836SJohn.Forte@Sun.COM mutex_exit(&rdc_conf_lock);
19287836SJohn.Forte@Sun.COM
19297836SJohn.Forte@Sun.COM (void) _rdc_sync_event_notify(RDC_SYNC_DONE,
19307836SJohn.Forte@Sun.COM urdc->secondary.file, urdc->group_name);
19317836SJohn.Forte@Sun.COM }
19327836SJohn.Forte@Sun.COM }
19337836SJohn.Forte@Sun.COM
19347836SJohn.Forte@Sun.COM if (!done) {
19357836SJohn.Forte@Sun.COM mutex_enter(&rdc_conf_lock);
19367836SJohn.Forte@Sun.COM wakeup_busy(krdc);
19377836SJohn.Forte@Sun.COM mutex_exit(&rdc_conf_lock);
19387836SJohn.Forte@Sun.COM }
19397836SJohn.Forte@Sun.COM
19407836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_int, (char *)&index);
19417836SJohn.Forte@Sun.COM if (log) {
19427836SJohn.Forte@Sun.COM rdc_group_enter(krdc);
19437836SJohn.Forte@Sun.COM rdc_group_log(krdc, RDC_NOFLUSH | RDC_OTHERREMOTE,
19449093SRamana.Srikanth@Sun.COM "Sync aborted or logging started");
19457836SJohn.Forte@Sun.COM rdc_group_exit(krdc);
19467836SJohn.Forte@Sun.COM }
19477836SJohn.Forte@Sun.COM free_rdc_netbuf(&(state.netaddr));
19487836SJohn.Forte@Sun.COM free_rdc_netbuf(&(state.rnetaddr));
19497836SJohn.Forte@Sun.COM }
19507836SJohn.Forte@Sun.COM
19517836SJohn.Forte@Sun.COM /*
19527836SJohn.Forte@Sun.COM * r_net_getstate4
19537836SJohn.Forte@Sun.COM * Return our state to client
19547836SJohn.Forte@Sun.COM */
19557836SJohn.Forte@Sun.COM static void
r_net_getstate4(SVCXPRT * xprt,struct svc_req * req)19567836SJohn.Forte@Sun.COM r_net_getstate4(SVCXPRT *xprt, struct svc_req *req)
19577836SJohn.Forte@Sun.COM {
19587836SJohn.Forte@Sun.COM int e, ret = -1, index = -1;
19597836SJohn.Forte@Sun.COM struct set_state4 state;
19607836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
19617836SJohn.Forte@Sun.COM rdc_set_t rdc_set;
19627836SJohn.Forte@Sun.COM
19637836SJohn.Forte@Sun.COM bzero(&state, sizeof (struct set_state));
19647836SJohn.Forte@Sun.COM e = SVC_GETARGS(xprt, xdr_set_state4, (char *)&state);
19657836SJohn.Forte@Sun.COM if (e) {
19667836SJohn.Forte@Sun.COM init_rdc_netbuf(&(rdc_set.primary.addr));
19677836SJohn.Forte@Sun.COM init_rdc_netbuf(&(rdc_set.secondary.addr));
19687836SJohn.Forte@Sun.COM bcopy(state.netaddr, rdc_set.primary.addr.buf,
19697836SJohn.Forte@Sun.COM state.netaddrlen);
19707836SJohn.Forte@Sun.COM bcopy(state.rnetaddr, rdc_set.secondary.addr.buf,
19717836SJohn.Forte@Sun.COM state.rnetaddrlen);
19727836SJohn.Forte@Sun.COM rdc_set.primary.addr.len = state.netaddrlen;
19737836SJohn.Forte@Sun.COM rdc_set.secondary.addr.len = state.rnetaddrlen;
19747836SJohn.Forte@Sun.COM (void) strncpy(rdc_set.primary.file, state.pfile,
19757836SJohn.Forte@Sun.COM RDC_MAXNAMLEN);
19767836SJohn.Forte@Sun.COM (void) strncpy(rdc_set.secondary.file, state.sfile,
19777836SJohn.Forte@Sun.COM RDC_MAXNAMLEN);
19787836SJohn.Forte@Sun.COM index = rdc_lookup_byaddr(&rdc_set);
19797836SJohn.Forte@Sun.COM if (index >= 0) {
19807836SJohn.Forte@Sun.COM urdc = &rdc_u_info[index];
19817836SJohn.Forte@Sun.COM
19827836SJohn.Forte@Sun.COM ret = 0;
19837836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_SYNCING)
19847836SJohn.Forte@Sun.COM ret |= 4;
19857836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_SLAVE)
19867836SJohn.Forte@Sun.COM ret |= 2;
19877836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_LOGGING)
19887836SJohn.Forte@Sun.COM ret |= 1;
19897836SJohn.Forte@Sun.COM rdc_set_if_vers(urdc, req->rq_vers);
19907836SJohn.Forte@Sun.COM }
19917836SJohn.Forte@Sun.COM free_rdc_netbuf(&(rdc_set.primary.addr));
19927836SJohn.Forte@Sun.COM free_rdc_netbuf(&(rdc_set.secondary.addr));
19937836SJohn.Forte@Sun.COM }
19947836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_int, (char *)&ret);
19957836SJohn.Forte@Sun.COM }
19967836SJohn.Forte@Sun.COM
19977836SJohn.Forte@Sun.COM /*
19987836SJohn.Forte@Sun.COM * r_net_getstate7
19997836SJohn.Forte@Sun.COM * Return our state to client
20007836SJohn.Forte@Sun.COM */
20017836SJohn.Forte@Sun.COM static void
r_net_getstate7(SVCXPRT * xprt,struct svc_req * req)20027836SJohn.Forte@Sun.COM r_net_getstate7(SVCXPRT *xprt, struct svc_req *req)
20037836SJohn.Forte@Sun.COM {
20047836SJohn.Forte@Sun.COM int e, ret = -1, index = -1;
20057836SJohn.Forte@Sun.COM struct set_state state;
20067836SJohn.Forte@Sun.COM char pstr[RDC_MAXNAMLEN];
20077836SJohn.Forte@Sun.COM char sstr[RDC_MAXNAMLEN];
20087836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
20097836SJohn.Forte@Sun.COM rdc_set_t rdc_set;
20107836SJohn.Forte@Sun.COM unsigned short *sp;
20117836SJohn.Forte@Sun.COM
20127836SJohn.Forte@Sun.COM bzero(&state, sizeof (struct set_state));
20137836SJohn.Forte@Sun.COM state.pfile = pstr;
20147836SJohn.Forte@Sun.COM state.sfile = sstr;
20157836SJohn.Forte@Sun.COM
20167836SJohn.Forte@Sun.COM e = SVC_GETARGS(xprt, xdr_set_state, (char *)&state);
20177836SJohn.Forte@Sun.COM if (e) {
20187836SJohn.Forte@Sun.COM init_rdc_netbuf(&(rdc_set.primary.addr));
20197836SJohn.Forte@Sun.COM init_rdc_netbuf(&(rdc_set.secondary.addr));
20207836SJohn.Forte@Sun.COM sp = (unsigned short *)(state.netaddr.buf);
20217836SJohn.Forte@Sun.COM *sp = ntohs(*sp);
20227836SJohn.Forte@Sun.COM bcopy(state.netaddr.buf, rdc_set.primary.addr.buf,
20237836SJohn.Forte@Sun.COM state.netaddrlen);
20247836SJohn.Forte@Sun.COM sp = (unsigned short *)(state.rnetaddr.buf);
20257836SJohn.Forte@Sun.COM *sp = ntohs(*sp);
20267836SJohn.Forte@Sun.COM bcopy(state.rnetaddr.buf, rdc_set.secondary.addr.buf,
20277836SJohn.Forte@Sun.COM state.rnetaddrlen);
20287836SJohn.Forte@Sun.COM rdc_set.primary.addr.len = state.netaddrlen;
20297836SJohn.Forte@Sun.COM rdc_set.secondary.addr.len = state.rnetaddrlen;
20307836SJohn.Forte@Sun.COM /*
20317836SJohn.Forte@Sun.COM * strncpy(rdc_set.primary.file, state.pfile, RDC_MAXNAMLEN);
20327836SJohn.Forte@Sun.COM * strncpy(rdc_set.secondary.file, state.sfile, RDC_MAXNAMLEN);
20337836SJohn.Forte@Sun.COM */
20347836SJohn.Forte@Sun.COM bcopy(state.pfile, rdc_set.primary.file, RDC_MAXNAMLEN);
20357836SJohn.Forte@Sun.COM bcopy(state.sfile, rdc_set.secondary.file, RDC_MAXNAMLEN);
20367836SJohn.Forte@Sun.COM index = rdc_lookup_byaddr(&rdc_set);
20377836SJohn.Forte@Sun.COM if (index >= 0) {
20387836SJohn.Forte@Sun.COM urdc = &rdc_u_info[index];
20397836SJohn.Forte@Sun.COM
20407836SJohn.Forte@Sun.COM ret = 0;
20417836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_SYNCING)
20427836SJohn.Forte@Sun.COM ret |= 4;
20437836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_SLAVE)
20447836SJohn.Forte@Sun.COM ret |= 2;
20457836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_LOGGING)
20467836SJohn.Forte@Sun.COM ret |= 1;
20477836SJohn.Forte@Sun.COM rdc_set_if_vers(urdc, req->rq_vers);
20487836SJohn.Forte@Sun.COM }
20497836SJohn.Forte@Sun.COM free_rdc_netbuf(&(rdc_set.primary.addr));
20507836SJohn.Forte@Sun.COM free_rdc_netbuf(&(rdc_set.secondary.addr));
20517836SJohn.Forte@Sun.COM }
20527836SJohn.Forte@Sun.COM (void) svc_sendreply(xprt, xdr_int, (char *)&ret);
20537836SJohn.Forte@Sun.COM }
20547836SJohn.Forte@Sun.COM
20557836SJohn.Forte@Sun.COM /*
20567836SJohn.Forte@Sun.COM * copy from/to a dset/vector combination to a network xdr buffer.
20577836SJohn.Forte@Sun.COM */
20587836SJohn.Forte@Sun.COM static int
rdc_dsetcopy(rdc_net_dataset_t * dset,nsc_vec_t * invec,nsc_off_t fba_pos,nsc_size_t fba_len,char * bdata,int blen,int dir)20597836SJohn.Forte@Sun.COM rdc_dsetcopy(rdc_net_dataset_t *dset, nsc_vec_t *invec, nsc_off_t fba_pos,
20607836SJohn.Forte@Sun.COM nsc_size_t fba_len, char *bdata, int blen, int dir)
20617836SJohn.Forte@Sun.COM {
20627836SJohn.Forte@Sun.COM nsc_vec_t *vec;
20637836SJohn.Forte@Sun.COM uchar_t *sv_addr;
20647836SJohn.Forte@Sun.COM uchar_t *data;
20657836SJohn.Forte@Sun.COM int sv_len;
20667836SJohn.Forte@Sun.COM nsc_off_t fpos;
20677836SJohn.Forte@Sun.COM int len;
20687836SJohn.Forte@Sun.COM int n;
20697836SJohn.Forte@Sun.COM
20707836SJohn.Forte@Sun.COM if (!bdata || !dset || !invec) {
20717836SJohn.Forte@Sun.COM #ifdef DEBUG
20727836SJohn.Forte@Sun.COM cmn_err(CE_NOTE,
20739093SRamana.Srikanth@Sun.COM "!rdc: dsetcopy: parameters failed bdata %p, dset %p "
20749093SRamana.Srikanth@Sun.COM "invec %p", (void *)bdata, (void *)dset, (void *)invec);
20757836SJohn.Forte@Sun.COM #endif
20767836SJohn.Forte@Sun.COM return (FALSE);
20777836SJohn.Forte@Sun.COM }
20787836SJohn.Forte@Sun.COM
20797836SJohn.Forte@Sun.COM if (fba_len > MAX_RDC_FBAS ||
20807836SJohn.Forte@Sun.COM (dir != COPY_IN && dir != COPY_OUT)) {
20817836SJohn.Forte@Sun.COM #ifdef DEBUG
20827836SJohn.Forte@Sun.COM cmn_err(CE_NOTE,
20839093SRamana.Srikanth@Sun.COM "!rdc: dsetcopy: params failed fba_len %" NSC_SZFMT
20847836SJohn.Forte@Sun.COM " fba_pos %" NSC_SZFMT ", dir %d", fba_len, fba_pos, dir);
20857836SJohn.Forte@Sun.COM #endif
20867836SJohn.Forte@Sun.COM return (FALSE);
20877836SJohn.Forte@Sun.COM }
20887836SJohn.Forte@Sun.COM
20897836SJohn.Forte@Sun.COM data = (uchar_t *)bdata; /* pointer to data in rpc */
20907836SJohn.Forte@Sun.COM len = FBA_SIZE(fba_len); /* length of this transfer in bytes */
20917836SJohn.Forte@Sun.COM fpos = fba_pos; /* start fba offset within buffer */
20927836SJohn.Forte@Sun.COM
20937836SJohn.Forte@Sun.COM if (!len) {
20947836SJohn.Forte@Sun.COM #ifdef DEBUG
20959093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!rdc: dsetcopy: len = 0");
20967836SJohn.Forte@Sun.COM #endif
20977836SJohn.Forte@Sun.COM return (FALSE);
20987836SJohn.Forte@Sun.COM }
20997836SJohn.Forte@Sun.COM
21007836SJohn.Forte@Sun.COM if (len != blen) {
21017836SJohn.Forte@Sun.COM #ifdef DEBUG
21029093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!rdc:dsetcopy: len %d != blen %d", len, blen);
21037836SJohn.Forte@Sun.COM #endif
21047836SJohn.Forte@Sun.COM if (len > blen)
21057836SJohn.Forte@Sun.COM len = blen;
21067836SJohn.Forte@Sun.COM }
21077836SJohn.Forte@Sun.COM
21087836SJohn.Forte@Sun.COM if (!RDC_DSET_LIMITS(dset, fba_pos, fba_len)) {
21097836SJohn.Forte@Sun.COM /* should never happen */
21107836SJohn.Forte@Sun.COM #ifdef DEBUG
21117836SJohn.Forte@Sun.COM cmn_err(CE_NOTE,
21129093SRamana.Srikanth@Sun.COM "!rdc: dsetcopy: handle limits pos %" NSC_SZFMT " (%"
21137836SJohn.Forte@Sun.COM NSC_SZFMT ") len %" NSC_SZFMT " (%" NSC_SZFMT ")",
21149093SRamana.Srikanth@Sun.COM fba_pos, dset->pos, fba_len, dset->fbalen);
21157836SJohn.Forte@Sun.COM #endif
21167836SJohn.Forte@Sun.COM return (FALSE); /* Don't overrun handle */
21177836SJohn.Forte@Sun.COM }
21187836SJohn.Forte@Sun.COM
21197836SJohn.Forte@Sun.COM vec = invec;
21207836SJohn.Forte@Sun.COM fpos -= dset->pos;
21217836SJohn.Forte@Sun.COM
21227836SJohn.Forte@Sun.COM /* find starting position in vector */
21237836SJohn.Forte@Sun.COM
21247836SJohn.Forte@Sun.COM for (; fpos >= FBA_NUM(vec->sv_len); vec++)
21257836SJohn.Forte@Sun.COM fpos -= FBA_NUM(vec->sv_len);
21267836SJohn.Forte@Sun.COM
21277836SJohn.Forte@Sun.COM /*
21287836SJohn.Forte@Sun.COM * Copy data
21297836SJohn.Forte@Sun.COM */
21307836SJohn.Forte@Sun.COM
21317836SJohn.Forte@Sun.COM sv_addr = vec->sv_addr + FBA_SIZE(fpos);
21327836SJohn.Forte@Sun.COM sv_len = vec->sv_len - FBA_SIZE(fpos);
21337836SJohn.Forte@Sun.COM
21347836SJohn.Forte@Sun.COM while (len) {
21357836SJohn.Forte@Sun.COM if (!sv_addr) /* end of vec - how did this happen? */
21367836SJohn.Forte@Sun.COM break;
21377836SJohn.Forte@Sun.COM
21387836SJohn.Forte@Sun.COM n = min(sv_len, len);
21397836SJohn.Forte@Sun.COM
21407836SJohn.Forte@Sun.COM if (dir == COPY_OUT)
21417836SJohn.Forte@Sun.COM bcopy(data, sv_addr, (size_t)n);
21427836SJohn.Forte@Sun.COM else
21437836SJohn.Forte@Sun.COM bcopy(sv_addr, data, (size_t)n);
21447836SJohn.Forte@Sun.COM
21457836SJohn.Forte@Sun.COM sv_len -= n;
21467836SJohn.Forte@Sun.COM len -= n;
21477836SJohn.Forte@Sun.COM
21487836SJohn.Forte@Sun.COM sv_addr += n;
21497836SJohn.Forte@Sun.COM data += n;
21507836SJohn.Forte@Sun.COM
21517836SJohn.Forte@Sun.COM if (sv_len <= 0) {
21527836SJohn.Forte@Sun.COM /* goto next vector */
21537836SJohn.Forte@Sun.COM vec++;
21547836SJohn.Forte@Sun.COM sv_addr = vec->sv_addr;
21557836SJohn.Forte@Sun.COM sv_len = vec->sv_len;
21567836SJohn.Forte@Sun.COM }
21577836SJohn.Forte@Sun.COM }
21587836SJohn.Forte@Sun.COM
21597836SJohn.Forte@Sun.COM return (TRUE);
21607836SJohn.Forte@Sun.COM }
21617836SJohn.Forte@Sun.COM
21627836SJohn.Forte@Sun.COM
21637836SJohn.Forte@Sun.COM /*
21647836SJohn.Forte@Sun.COM * rdc_start_server
21657836SJohn.Forte@Sun.COM * Starts the kRPC server for rdc. Uses tli file descriptor passed down
21667836SJohn.Forte@Sun.COM * from user level rdc server.
21677836SJohn.Forte@Sun.COM *
21687836SJohn.Forte@Sun.COM * Returns: 0 or errno (NOT unistat!).
21697836SJohn.Forte@Sun.COM */
21707836SJohn.Forte@Sun.COM int
rdc_start_server(struct rdc_svc_args * args,int mode)21717836SJohn.Forte@Sun.COM rdc_start_server(struct rdc_svc_args *args, int mode)
21727836SJohn.Forte@Sun.COM {
21737836SJohn.Forte@Sun.COM file_t *fp;
21747836SJohn.Forte@Sun.COM int ret;
21757836SJohn.Forte@Sun.COM struct cred *cred;
21767836SJohn.Forte@Sun.COM STRUCT_HANDLE(rdc_svc_args, rs);
21777836SJohn.Forte@Sun.COM
21787836SJohn.Forte@Sun.COM STRUCT_SET_HANDLE(rs, mode, args);
21797836SJohn.Forte@Sun.COM cred = ddi_get_cred();
21807836SJohn.Forte@Sun.COM if (drv_priv(cred) != 0)
21817836SJohn.Forte@Sun.COM return (EPERM);
21827836SJohn.Forte@Sun.COM fp = getf(STRUCT_FGET(rs, fd));
21837836SJohn.Forte@Sun.COM if (fp == NULL) {
21847836SJohn.Forte@Sun.COM #ifdef DEBUG
21859093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc_start_server fd %d, fp %p", args->fd,
21869093SRamana.Srikanth@Sun.COM (void *) fp);
21877836SJohn.Forte@Sun.COM #endif
21887836SJohn.Forte@Sun.COM return (EBADF);
21897836SJohn.Forte@Sun.COM }
21907836SJohn.Forte@Sun.COM
21917836SJohn.Forte@Sun.COM ret = rdcsrv_load(fp, rdc_srvtab, args, mode);
21927836SJohn.Forte@Sun.COM
21937836SJohn.Forte@Sun.COM releasef(STRUCT_FGET(rs, fd));
21947836SJohn.Forte@Sun.COM return (ret);
21957836SJohn.Forte@Sun.COM }
21967836SJohn.Forte@Sun.COM
21977836SJohn.Forte@Sun.COM /*
21987836SJohn.Forte@Sun.COM * Allocate a new sleepq element.
21997836SJohn.Forte@Sun.COM */
22007836SJohn.Forte@Sun.COM
22017836SJohn.Forte@Sun.COM static rdc_sleepq_t *
rdc_newsleepq()22027836SJohn.Forte@Sun.COM rdc_newsleepq()
22037836SJohn.Forte@Sun.COM {
22047836SJohn.Forte@Sun.COM rdc_sleepq_t *sq;
22057836SJohn.Forte@Sun.COM
22067836SJohn.Forte@Sun.COM sq = kmem_alloc(sizeof (rdc_sleepq_t), KM_SLEEP);
22077836SJohn.Forte@Sun.COM sq->next = NULL;
22087836SJohn.Forte@Sun.COM #ifdef DEBUG
22097836SJohn.Forte@Sun.COM mutex_enter(&rdc_cntlock);
22107836SJohn.Forte@Sun.COM rdc_sleepcnt++;
22117836SJohn.Forte@Sun.COM mutex_exit(&rdc_cntlock);
22127836SJohn.Forte@Sun.COM #endif
22137836SJohn.Forte@Sun.COM return (sq);
22147836SJohn.Forte@Sun.COM }
22157836SJohn.Forte@Sun.COM
22167836SJohn.Forte@Sun.COM /*
22177836SJohn.Forte@Sun.COM * free memory/resources used by a sleepq element.
22187836SJohn.Forte@Sun.COM */
22197836SJohn.Forte@Sun.COM static void
rdc_delsleepq(rdc_sleepq_t * sq)22207836SJohn.Forte@Sun.COM rdc_delsleepq(rdc_sleepq_t *sq)
22217836SJohn.Forte@Sun.COM {
22227836SJohn.Forte@Sun.COM rdc_net_dataset_t *dset;
22237836SJohn.Forte@Sun.COM
22247836SJohn.Forte@Sun.COM if (sq->idx != -1) {
22257836SJohn.Forte@Sun.COM dset = rdc_net_get_set(sq->sindex, sq->idx);
22267836SJohn.Forte@Sun.COM if (dset) {
22277836SJohn.Forte@Sun.COM rdc_net_del_set(sq->sindex, dset);
22287836SJohn.Forte@Sun.COM }
22297836SJohn.Forte@Sun.COM }
22307836SJohn.Forte@Sun.COM kmem_free(sq, sizeof (rdc_sleepq_t));
22317836SJohn.Forte@Sun.COM #ifdef DEBUG
22327836SJohn.Forte@Sun.COM mutex_enter(&rdc_cntlock);
22337836SJohn.Forte@Sun.COM rdc_sleepcnt--;
22347836SJohn.Forte@Sun.COM mutex_exit(&rdc_cntlock);
22357836SJohn.Forte@Sun.COM #endif
22367836SJohn.Forte@Sun.COM }
22377836SJohn.Forte@Sun.COM
22387836SJohn.Forte@Sun.COM
22397836SJohn.Forte@Sun.COM /*
22407836SJohn.Forte@Sun.COM * skip down the sleep q and insert the sleep request
22417836SJohn.Forte@Sun.COM * in ascending order. Return 0 on success, 1 on failure.
22427836SJohn.Forte@Sun.COM */
22437836SJohn.Forte@Sun.COM static int
rdc_sleepq(rdc_group_t * group,rdc_sleepq_t * sq)22447836SJohn.Forte@Sun.COM rdc_sleepq(rdc_group_t *group, rdc_sleepq_t *sq)
22457836SJohn.Forte@Sun.COM {
22467836SJohn.Forte@Sun.COM rdc_sleepq_t *findsq;
22477836SJohn.Forte@Sun.COM
22487836SJohn.Forte@Sun.COM
22497836SJohn.Forte@Sun.COM ASSERT(MUTEX_HELD(&group->ra_queue.net_qlock));
22507836SJohn.Forte@Sun.COM if (group->sleepq == NULL) {
22517836SJohn.Forte@Sun.COM group->sleepq = sq;
22527836SJohn.Forte@Sun.COM } else {
22537836SJohn.Forte@Sun.COM if (sq->seq == group->sleepq->seq) {
22549093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc_sleepq: Attempt to "
22557836SJohn.Forte@Sun.COM "add duplicate request to queue %d", sq->seq);
22567836SJohn.Forte@Sun.COM return (1);
22577836SJohn.Forte@Sun.COM }
22587836SJohn.Forte@Sun.COM if (RDC_INFRONT(sq->seq, group->sleepq->seq)) {
22597836SJohn.Forte@Sun.COM sq->next = group->sleepq;
22607836SJohn.Forte@Sun.COM group->sleepq = sq;
22617836SJohn.Forte@Sun.COM } else {
22627836SJohn.Forte@Sun.COM findsq = group->sleepq;
22637836SJohn.Forte@Sun.COM
22647836SJohn.Forte@Sun.COM while (findsq->next) {
22657836SJohn.Forte@Sun.COM if (sq->seq == findsq->next->seq) {
22669093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc_sleepq: "
22677836SJohn.Forte@Sun.COM "Attempt to add duplicate "
22687836SJohn.Forte@Sun.COM "request to queue %d", sq->seq);
22697836SJohn.Forte@Sun.COM return (1);
22707836SJohn.Forte@Sun.COM }
22717836SJohn.Forte@Sun.COM if (RDC_INFRONT(sq->seq, findsq->next->seq)) {
22727836SJohn.Forte@Sun.COM sq->next = findsq->next;
22737836SJohn.Forte@Sun.COM findsq->next = sq;
22747836SJohn.Forte@Sun.COM break;
22757836SJohn.Forte@Sun.COM }
22767836SJohn.Forte@Sun.COM findsq = findsq->next;
22777836SJohn.Forte@Sun.COM }
22787836SJohn.Forte@Sun.COM if (findsq->next == NULL)
22797836SJohn.Forte@Sun.COM findsq->next = sq;
22807836SJohn.Forte@Sun.COM }
22817836SJohn.Forte@Sun.COM }
22827836SJohn.Forte@Sun.COM return (0);
22837836SJohn.Forte@Sun.COM }
22847836SJohn.Forte@Sun.COM
22857836SJohn.Forte@Sun.COM /*
22867836SJohn.Forte@Sun.COM * run down the sleep q and discard all the sleepq elements.
22877836SJohn.Forte@Sun.COM */
22887836SJohn.Forte@Sun.COM void
rdc_sleepqdiscard(rdc_group_t * group)22897836SJohn.Forte@Sun.COM rdc_sleepqdiscard(rdc_group_t *group)
22907836SJohn.Forte@Sun.COM {
22917836SJohn.Forte@Sun.COM rdc_sleepq_t *sq;
22927836SJohn.Forte@Sun.COM rdc_k_info_t *krdc;
22937836SJohn.Forte@Sun.COM
22947836SJohn.Forte@Sun.COM ASSERT(MUTEX_HELD(&group->ra_queue.net_qlock));
22957836SJohn.Forte@Sun.COM sq = group->sleepq;
22967836SJohn.Forte@Sun.COM
22977836SJohn.Forte@Sun.COM while (sq) {
22987836SJohn.Forte@Sun.COM rdc_sleepq_t *dsq;
22997836SJohn.Forte@Sun.COM
23007836SJohn.Forte@Sun.COM dsq = sq;
23017836SJohn.Forte@Sun.COM krdc = &rdc_k_info[dsq->sindex];
23027836SJohn.Forte@Sun.COM if (krdc->io_kstats) {
23037836SJohn.Forte@Sun.COM mutex_enter(krdc->io_kstats->ks_lock);
23047836SJohn.Forte@Sun.COM kstat_waitq_exit(KSTAT_IO_PTR(krdc->io_kstats));
23057836SJohn.Forte@Sun.COM mutex_exit(krdc->io_kstats->ks_lock);
23067836SJohn.Forte@Sun.COM }
23077836SJohn.Forte@Sun.COM sq = sq->next;
23087836SJohn.Forte@Sun.COM rdc_delsleepq(dsq);
23097836SJohn.Forte@Sun.COM }
23107836SJohn.Forte@Sun.COM group->sleepq = NULL;
23117836SJohn.Forte@Sun.COM }
23127836SJohn.Forte@Sun.COM
23137836SJohn.Forte@Sun.COM /*
23147836SJohn.Forte@Sun.COM * split any write requests down to maxfba sized chunks.
23157836SJohn.Forte@Sun.COM */
23167836SJohn.Forte@Sun.COM /*ARGSUSED*/
23177836SJohn.Forte@Sun.COM static int
rdc_writemaxfba(rdc_k_info_t * krdc,rdc_u_info_t * urdc,rdc_net_dataset_t * dset,uint_t seq,int nocache)23187836SJohn.Forte@Sun.COM rdc_writemaxfba(rdc_k_info_t *krdc, rdc_u_info_t *urdc,
23197836SJohn.Forte@Sun.COM rdc_net_dataset_t *dset, uint_t seq, int nocache)
23207836SJohn.Forte@Sun.COM {
23217836SJohn.Forte@Sun.COM int len;
23227836SJohn.Forte@Sun.COM int ret;
23237836SJohn.Forte@Sun.COM nsc_vec_t vector[2];
23247836SJohn.Forte@Sun.COM nsc_buf_t *handle;
23257836SJohn.Forte@Sun.COM int reserved;
23267836SJohn.Forte@Sun.COM int rtype;
23277836SJohn.Forte@Sun.COM nsc_size_t mfba;
23287836SJohn.Forte@Sun.COM nsc_size_t wsize;
23297836SJohn.Forte@Sun.COM nsc_off_t pos;
23307836SJohn.Forte@Sun.COM int eintr_count;
23317836SJohn.Forte@Sun.COM unsigned char *daddr;
23327836SJohn.Forte@Sun.COM int kstat_len;
23337836SJohn.Forte@Sun.COM
23347836SJohn.Forte@Sun.COM kstat_len = len = dset->fbalen;
23357836SJohn.Forte@Sun.COM ret = 0;
23367836SJohn.Forte@Sun.COM handle = NULL;
23377836SJohn.Forte@Sun.COM reserved = 0;
23387836SJohn.Forte@Sun.COM rtype = RDC_RAW;
23397836SJohn.Forte@Sun.COM
23407836SJohn.Forte@Sun.COM ASSERT(dset->nitems == 1);
23417836SJohn.Forte@Sun.COM
23427836SJohn.Forte@Sun.COM eintr_count = 0;
23437836SJohn.Forte@Sun.COM do {
23447836SJohn.Forte@Sun.COM ret = _rdc_rsrv_devs(krdc, rtype, RDC_INTERNAL);
23457836SJohn.Forte@Sun.COM if (ret == EINTR) {
23467836SJohn.Forte@Sun.COM ++eintr_count;
23477836SJohn.Forte@Sun.COM delay(2);
23487836SJohn.Forte@Sun.COM }
23497836SJohn.Forte@Sun.COM } while ((ret == EINTR) && (eintr_count < MAX_EINTR_COUNT));
23507836SJohn.Forte@Sun.COM if (ret != 0) {
23517836SJohn.Forte@Sun.COM #ifdef DEBUG
23529093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!rdc_writemaxfba: reserve devs "
23537836SJohn.Forte@Sun.COM "failed %d", ret);
23547836SJohn.Forte@Sun.COM #endif
23557836SJohn.Forte@Sun.COM goto out;
23567836SJohn.Forte@Sun.COM
23577836SJohn.Forte@Sun.COM }
23587836SJohn.Forte@Sun.COM reserved = 1;
23597836SJohn.Forte@Sun.COM /*
23607836SJohn.Forte@Sun.COM * Perhaps we should cache mfba.
23617836SJohn.Forte@Sun.COM */
23627836SJohn.Forte@Sun.COM ret = nsc_maxfbas(RDC_U_FD(krdc), 0, &mfba);
23637836SJohn.Forte@Sun.COM if (ret != 0) {
23647836SJohn.Forte@Sun.COM #ifdef DEBUG
23659093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!rdc_writemaxfba: msc_maxfbas failed %d",
23667836SJohn.Forte@Sun.COM ret);
23677836SJohn.Forte@Sun.COM #endif
23687836SJohn.Forte@Sun.COM goto out;
23697836SJohn.Forte@Sun.COM }
23707836SJohn.Forte@Sun.COM
23717836SJohn.Forte@Sun.COM ASSERT(urdc->volume_size != 0);
23727836SJohn.Forte@Sun.COM if (dset->pos + len > urdc->volume_size) {
23737836SJohn.Forte@Sun.COM /* should never happen */
23747836SJohn.Forte@Sun.COM /*
23757836SJohn.Forte@Sun.COM * also need to trim down the vector
23767836SJohn.Forte@Sun.COM * sizes.
23777836SJohn.Forte@Sun.COM */
23787836SJohn.Forte@Sun.COM kstat_len = len = urdc->volume_size - dset->pos;
23797836SJohn.Forte@Sun.COM dset->head->len -= FBA_SIZE(len);
23807836SJohn.Forte@Sun.COM ASSERT(dset->head->len > 0);
23817836SJohn.Forte@Sun.COM }
23827836SJohn.Forte@Sun.COM daddr = dset->head->dptr;
23837836SJohn.Forte@Sun.COM pos = dset->pos;
23847836SJohn.Forte@Sun.COM vector[1].sv_addr = NULL;
23857836SJohn.Forte@Sun.COM vector[1].sv_len = 0;
23867836SJohn.Forte@Sun.COM
23877836SJohn.Forte@Sun.COM while (len > 0) {
23887836SJohn.Forte@Sun.COM wsize = min((nsc_size_t)len, mfba);
23897836SJohn.Forte@Sun.COM vector[0].sv_addr = daddr;
23907836SJohn.Forte@Sun.COM vector[0].sv_len = FBA_SIZE(wsize);
23917836SJohn.Forte@Sun.COM
23927836SJohn.Forte@Sun.COM if (handle) {
23937836SJohn.Forte@Sun.COM (void) nsc_free_buf(handle);
23947836SJohn.Forte@Sun.COM handle = NULL;
23957836SJohn.Forte@Sun.COM }
23967836SJohn.Forte@Sun.COM ret = nsc_alloc_buf(RDC_U_FD(krdc), pos, wsize,
23977836SJohn.Forte@Sun.COM NSC_WRBUF|NSC_NODATA|nocache, &handle);
23987836SJohn.Forte@Sun.COM if (ret != 0) {
23997836SJohn.Forte@Sun.COM #ifdef DEBUG
24009093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!rdc_writemaxfba: "
24017836SJohn.Forte@Sun.COM "nsc_alloc (d1) buf failed %d at "
24027836SJohn.Forte@Sun.COM "pos %" NSC_SZFMT " len %" NSC_SZFMT,
24037836SJohn.Forte@Sun.COM ret, pos, wsize);
24047836SJohn.Forte@Sun.COM #endif
24057836SJohn.Forte@Sun.COM goto out;
24067836SJohn.Forte@Sun.COM }
24077836SJohn.Forte@Sun.COM handle->sb_vec = &vector[0];
24087836SJohn.Forte@Sun.COM ret = rdc_combywrite(krdc, handle);
24097836SJohn.Forte@Sun.COM if (ret != 0) {
24107836SJohn.Forte@Sun.COM #ifdef DEBUG
24119093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!rdc_writemaxfba: "
24127836SJohn.Forte@Sun.COM "write failed (d1) %d offset %" NSC_SZFMT " "
24137836SJohn.Forte@Sun.COM "length %" NSC_SZFMT, ret, pos, wsize);
24147836SJohn.Forte@Sun.COM #endif
24157836SJohn.Forte@Sun.COM goto out;
24167836SJohn.Forte@Sun.COM }
24177836SJohn.Forte@Sun.COM pos += wsize;
24187836SJohn.Forte@Sun.COM len -= wsize;
24197836SJohn.Forte@Sun.COM daddr += FBA_SIZE(wsize);
24207836SJohn.Forte@Sun.COM }
24217836SJohn.Forte@Sun.COM out:
24227836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(ret)) {
24237836SJohn.Forte@Sun.COM if (!(rdc_get_vflags(urdc) & RDC_VOL_FAILED)) {
24247836SJohn.Forte@Sun.COM ASSERT(!(rdc_get_vflags(urdc) &
24257836SJohn.Forte@Sun.COM RDC_PRIMARY));
24267836SJohn.Forte@Sun.COM rdc_many_enter(krdc);
24277836SJohn.Forte@Sun.COM rdc_set_flags(urdc, RDC_SYNC_NEEDED);
24287836SJohn.Forte@Sun.COM rdc_set_flags_log(urdc, RDC_VOL_FAILED,
24297836SJohn.Forte@Sun.COM "svc write failed");
24307836SJohn.Forte@Sun.COM rdc_many_exit(krdc);
24317836SJohn.Forte@Sun.COM rdc_write_state(urdc);
24327836SJohn.Forte@Sun.COM }
24337836SJohn.Forte@Sun.COM } else {
24347836SJohn.Forte@Sun.COM /* success */
24357836SJohn.Forte@Sun.COM #ifdef DEBUG
24367836SJohn.Forte@Sun.COM if (rdc_netwrite6) {
24377836SJohn.Forte@Sun.COM /*
24387836SJohn.Forte@Sun.COM * This string is used in the ZatoIchi MASNDR
24397836SJohn.Forte@Sun.COM * tests, if you change this, update the test.
24407836SJohn.Forte@Sun.COM */
24419093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!writemaxfba: Write "
24427836SJohn.Forte@Sun.COM "sequence %u", seq);
24437836SJohn.Forte@Sun.COM }
24447836SJohn.Forte@Sun.COM #endif
24457836SJohn.Forte@Sun.COM if (krdc->io_kstats) {
24467836SJohn.Forte@Sun.COM KSTAT_IO_PTR(krdc->io_kstats)->writes++;
24477836SJohn.Forte@Sun.COM KSTAT_IO_PTR(krdc->io_kstats)->nwritten +=
24489093SRamana.Srikanth@Sun.COM FBA_SIZE(kstat_len);
24497836SJohn.Forte@Sun.COM }
24507836SJohn.Forte@Sun.COM }
24517836SJohn.Forte@Sun.COM if (handle)
24527836SJohn.Forte@Sun.COM (void) nsc_free_buf(handle);
24537836SJohn.Forte@Sun.COM if (reserved)
24547836SJohn.Forte@Sun.COM _rdc_rlse_devs(krdc, rtype);
24557836SJohn.Forte@Sun.COM return (ret);
24567836SJohn.Forte@Sun.COM }
24577836SJohn.Forte@Sun.COM
24587836SJohn.Forte@Sun.COM static int
rdc_combywrite(rdc_k_info_t * krdc,nsc_buf_t * handle)24597836SJohn.Forte@Sun.COM rdc_combywrite(rdc_k_info_t *krdc, nsc_buf_t *handle)
24607836SJohn.Forte@Sun.COM {
24617836SJohn.Forte@Sun.COM int rsync;
24627836SJohn.Forte@Sun.COM int ret;
24637836SJohn.Forte@Sun.COM int multiret;
24647836SJohn.Forte@Sun.COM
24657836SJohn.Forte@Sun.COM rsync = -1;
24667836SJohn.Forte@Sun.COM ret = 0;
24677836SJohn.Forte@Sun.COM /* Handle multihop I/O even on error */
24687836SJohn.Forte@Sun.COM if (IS_MULTI(krdc)) {
24697836SJohn.Forte@Sun.COM rdc_k_info_t *ktmp;
24707836SJohn.Forte@Sun.COM rdc_u_info_t *utmp;
24717836SJohn.Forte@Sun.COM
24727836SJohn.Forte@Sun.COM rdc_many_enter(krdc);
24737836SJohn.Forte@Sun.COM /*
24747836SJohn.Forte@Sun.COM * Find a target primary that is enabled,
24757836SJohn.Forte@Sun.COM * taking account of the fact that this
24767836SJohn.Forte@Sun.COM * could be a multihop secondary
24777836SJohn.Forte@Sun.COM * connected to a 1-to-many primary.
24787836SJohn.Forte@Sun.COM */
24797836SJohn.Forte@Sun.COM ktmp = krdc->multi_next;
24807836SJohn.Forte@Sun.COM if (ktmp == NULL) {
24817836SJohn.Forte@Sun.COM rdc_many_exit(krdc);
24827836SJohn.Forte@Sun.COM goto multi_done;
24837836SJohn.Forte@Sun.COM }
24847836SJohn.Forte@Sun.COM utmp = &rdc_u_info[ktmp->index];
24857836SJohn.Forte@Sun.COM do {
24867836SJohn.Forte@Sun.COM if ((rdc_get_vflags(utmp) & RDC_PRIMARY)
24877836SJohn.Forte@Sun.COM /* CSTYLED */
24887836SJohn.Forte@Sun.COM && IS_ENABLED(utmp))
24897836SJohn.Forte@Sun.COM break;
24907836SJohn.Forte@Sun.COM
24917836SJohn.Forte@Sun.COM ktmp = ktmp->many_next;
24927836SJohn.Forte@Sun.COM utmp = &rdc_u_info[ktmp->index];
24937836SJohn.Forte@Sun.COM } while (ktmp != krdc->multi_next);
24947836SJohn.Forte@Sun.COM
24957836SJohn.Forte@Sun.COM if (!(rdc_get_vflags(utmp) & RDC_PRIMARY) ||
24967836SJohn.Forte@Sun.COM !IS_ENABLED(utmp)) {
24977836SJohn.Forte@Sun.COM rdc_many_exit(krdc);
24987836SJohn.Forte@Sun.COM goto multi_done;
24997836SJohn.Forte@Sun.COM }
25007836SJohn.Forte@Sun.COM
25017836SJohn.Forte@Sun.COM rdc_many_exit(krdc);
25027836SJohn.Forte@Sun.COM rsync = (rdc_get_mflags(utmp) & RDC_SLAVE);
25037836SJohn.Forte@Sun.COM if (!rsync) {
25047836SJohn.Forte@Sun.COM /* normal case - local io first */
25057836SJohn.Forte@Sun.COM ret = nsc_write(handle, handle->sb_pos, handle->sb_len,
25067836SJohn.Forte@Sun.COM 0);
25077836SJohn.Forte@Sun.COM }
25087836SJohn.Forte@Sun.COM multiret = _rdc_multi_write(handle, handle->sb_pos,
25097836SJohn.Forte@Sun.COM handle->sb_len, 0, ktmp);
25107836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(multiret)) {
25117836SJohn.Forte@Sun.COM #ifdef DEBUG
25129093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!combywrite: "
25137836SJohn.Forte@Sun.COM "rdc_multi_write failed "
25147836SJohn.Forte@Sun.COM "status %d ret %d",
25157836SJohn.Forte@Sun.COM handle->sb_error, multiret);
25167836SJohn.Forte@Sun.COM #endif
25177836SJohn.Forte@Sun.COM if (!(rdc_get_vflags(utmp) &
25187836SJohn.Forte@Sun.COM RDC_VOL_FAILED)) {
25197836SJohn.Forte@Sun.COM rdc_many_enter(ktmp);
25207836SJohn.Forte@Sun.COM if (rdc_get_vflags(utmp) &
25217836SJohn.Forte@Sun.COM RDC_PRIMARY) {
25227836SJohn.Forte@Sun.COM rdc_set_mflags(utmp,
25237836SJohn.Forte@Sun.COM RDC_RSYNC_NEEDED);
25247836SJohn.Forte@Sun.COM } else {
25257836SJohn.Forte@Sun.COM rdc_set_flags(utmp,
25267836SJohn.Forte@Sun.COM RDC_SYNC_NEEDED);
25277836SJohn.Forte@Sun.COM }
25287836SJohn.Forte@Sun.COM rdc_set_flags(utmp,
25297836SJohn.Forte@Sun.COM RDC_VOL_FAILED);
25307836SJohn.Forte@Sun.COM rdc_many_exit(ktmp);
25317836SJohn.Forte@Sun.COM rdc_write_state(utmp);
25327836SJohn.Forte@Sun.COM }
25337836SJohn.Forte@Sun.COM }
25347836SJohn.Forte@Sun.COM }
25357836SJohn.Forte@Sun.COM
25367836SJohn.Forte@Sun.COM multi_done:
25377836SJohn.Forte@Sun.COM if (rsync != 0) {
25387836SJohn.Forte@Sun.COM /*
25397836SJohn.Forte@Sun.COM * Either:
25407836SJohn.Forte@Sun.COM * reverse sync in progress and so we
25417836SJohn.Forte@Sun.COM * need to do the local io after the
25427836SJohn.Forte@Sun.COM * (multihop) secondary io.
25437836SJohn.Forte@Sun.COM * Or:
25447836SJohn.Forte@Sun.COM * no multihop and this is the only io
25457836SJohn.Forte@Sun.COM * required.
25467836SJohn.Forte@Sun.COM */
25477836SJohn.Forte@Sun.COM ret = nsc_write(handle, handle->sb_pos, handle->sb_len, 0);
25487836SJohn.Forte@Sun.COM
25497836SJohn.Forte@Sun.COM }
25507836SJohn.Forte@Sun.COM return (ret);
25517836SJohn.Forte@Sun.COM }
25527836SJohn.Forte@Sun.COM /*
25537836SJohn.Forte@Sun.COM * set the pos and len values in the piggyback reply.
25547836SJohn.Forte@Sun.COM */
25557836SJohn.Forte@Sun.COM static void
rdc_setbitind(int * pendcnt,net_pendvec_t * pvec,rdc_net_dataset_t * dset,uint_t seq,int pindex,int qpos)25567836SJohn.Forte@Sun.COM rdc_setbitind(int *pendcnt, net_pendvec_t *pvec, rdc_net_dataset_t *dset,
25577836SJohn.Forte@Sun.COM uint_t seq, int pindex, int qpos)
25587836SJohn.Forte@Sun.COM {
25597836SJohn.Forte@Sun.COM int pc;
25607836SJohn.Forte@Sun.COM ASSERT(*pendcnt < RDC_MAXPENDQ);
25617836SJohn.Forte@Sun.COM
25627836SJohn.Forte@Sun.COM pc = *pendcnt;
25637836SJohn.Forte@Sun.COM pvec[pc].seq = seq;
25647836SJohn.Forte@Sun.COM pvec[pc].apos = dset->pos;
25657836SJohn.Forte@Sun.COM pvec[pc].qpos = qpos;
25667836SJohn.Forte@Sun.COM pvec[pc].alen = dset->fbalen;
25677836SJohn.Forte@Sun.COM pvec[pc].pindex = pindex;
25687836SJohn.Forte@Sun.COM *pendcnt = pc + 1;
256910715SThomas.Atkins@Sun.COM DTRACE_PROBE1(pvec_reply, int, seq);
25707836SJohn.Forte@Sun.COM }
25717836SJohn.Forte@Sun.COM
25727836SJohn.Forte@Sun.COM /*
25737836SJohn.Forte@Sun.COM * Enters with group->ra_queue.net_qlock held.
25747836SJohn.Forte@Sun.COM * Tries to construct the return status data for
25757836SJohn.Forte@Sun.COM * all the pending requests in the sleepq that it can
25767836SJohn.Forte@Sun.COM * satisfy.
25777836SJohn.Forte@Sun.COM */
25787836SJohn.Forte@Sun.COM static void
rdc_dopending(rdc_group_t * group,netwriteres * netretp)25797836SJohn.Forte@Sun.COM rdc_dopending(rdc_group_t *group, netwriteres *netretp)
25807836SJohn.Forte@Sun.COM {
25817836SJohn.Forte@Sun.COM int pendcnt;
25827836SJohn.Forte@Sun.COM net_pendvec_t *pendvec;
25837836SJohn.Forte@Sun.COM rdc_sleepq_t *sq;
25847836SJohn.Forte@Sun.COM int ret;
25857836SJohn.Forte@Sun.COM int pendsz;
25867836SJohn.Forte@Sun.COM
25877836SJohn.Forte@Sun.COM ASSERT(MUTEX_HELD(&group->ra_queue.net_qlock));
25887836SJohn.Forte@Sun.COM
25897836SJohn.Forte@Sun.COM pendcnt = 0;
25907836SJohn.Forte@Sun.COM pendsz = RDC_MAXPENDQ * sizeof (net_pendvec_t);
25917836SJohn.Forte@Sun.COM pendvec = kmem_alloc(pendsz, KM_SLEEP);
25927836SJohn.Forte@Sun.COM
25937836SJohn.Forte@Sun.COM /*
25947836SJohn.Forte@Sun.COM * now look at the Q of pending tasks, attempt
25957836SJohn.Forte@Sun.COM * to write any that have been waiting for
25967836SJohn.Forte@Sun.COM * me to complete my write, and piggyback
25977836SJohn.Forte@Sun.COM * their results in my reply, by setiing pendcnt
25987836SJohn.Forte@Sun.COM * to the number of extra requests sucessfully
25997836SJohn.Forte@Sun.COM * processed.
26007836SJohn.Forte@Sun.COM */
26017836SJohn.Forte@Sun.COM while (group->sleepq && group->sleepq->seq == group->seq) {
26027836SJohn.Forte@Sun.COM rdc_k_info_t *krdc;
26037836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
26047836SJohn.Forte@Sun.COM struct rdc_net_dataset *dset;
26057836SJohn.Forte@Sun.COM
26067836SJohn.Forte@Sun.COM sq = group->sleepq;
26077836SJohn.Forte@Sun.COM group->sleepq = sq->next;
26087836SJohn.Forte@Sun.COM mutex_exit(&group->ra_queue.net_qlock);
26097836SJohn.Forte@Sun.COM
26107836SJohn.Forte@Sun.COM krdc = &rdc_k_info[sq->sindex];
26117836SJohn.Forte@Sun.COM urdc = &rdc_u_info[sq->sindex];
26127836SJohn.Forte@Sun.COM if (krdc->io_kstats) {
26137836SJohn.Forte@Sun.COM mutex_enter(krdc->io_kstats->ks_lock);
26147836SJohn.Forte@Sun.COM kstat_waitq_exit(KSTAT_IO_PTR(krdc->io_kstats));
26157836SJohn.Forte@Sun.COM mutex_exit(krdc->io_kstats->ks_lock);
26167836SJohn.Forte@Sun.COM }
26177836SJohn.Forte@Sun.COM
26187836SJohn.Forte@Sun.COM dset = rdc_net_get_set(sq->sindex, sq->idx);
26197836SJohn.Forte@Sun.COM if (dset == NULL) {
26207836SJohn.Forte@Sun.COM #ifdef DEBUG
26219093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!pending: %s:%s rdc_net_get_set "
26227836SJohn.Forte@Sun.COM "failed", urdc->secondary.intf,
26237836SJohn.Forte@Sun.COM urdc->secondary.file);
26247836SJohn.Forte@Sun.COM #endif
26257836SJohn.Forte@Sun.COM /*
26267836SJohn.Forte@Sun.COM * as we failed to get the pointer, there
26277836SJohn.Forte@Sun.COM * is no point expecting the cleanup
26287836SJohn.Forte@Sun.COM * code in rdc_delsleepq() to get it
26297836SJohn.Forte@Sun.COM * either.
26307836SJohn.Forte@Sun.COM */
26317836SJohn.Forte@Sun.COM sq->idx = -1;
26327836SJohn.Forte@Sun.COM goto cleansq;
26337836SJohn.Forte@Sun.COM }
26347836SJohn.Forte@Sun.COM sq->idx = -1; /* marked as cleaned up */
26357836SJohn.Forte@Sun.COM
26367836SJohn.Forte@Sun.COM ret = rdc_writemaxfba(krdc, urdc, dset, sq->seq, sq->nocache);
26377836SJohn.Forte@Sun.COM if (RDC_SUCCESS(ret)) {
26387836SJohn.Forte@Sun.COM rdc_setbitind(&pendcnt, pendvec, dset,
26397836SJohn.Forte@Sun.COM sq->seq, sq->pindex, sq->qpos);
26407836SJohn.Forte@Sun.COM } else {
26419093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!dopending: Write of pending "
26427836SJohn.Forte@Sun.COM "asynchronous task failed, with "
26437836SJohn.Forte@Sun.COM "sequence number %u for SNDR set %s:%s",
26447836SJohn.Forte@Sun.COM sq->seq, urdc->secondary.intf,
26457836SJohn.Forte@Sun.COM urdc->secondary.file);
26467836SJohn.Forte@Sun.COM }
26477836SJohn.Forte@Sun.COM rdc_net_del_set(sq->sindex, dset);
26487836SJohn.Forte@Sun.COM cleansq:
26497836SJohn.Forte@Sun.COM mutex_enter(&group->ra_queue.net_qlock);
26507836SJohn.Forte@Sun.COM group->seq = sq->seq + 1;
26517836SJohn.Forte@Sun.COM if (group->seq < sq->seq)
26527836SJohn.Forte@Sun.COM group->seq = RDC_NEWSEQ + 1;
26537836SJohn.Forte@Sun.COM rdc_delsleepq(sq);
26547836SJohn.Forte@Sun.COM }
26557836SJohn.Forte@Sun.COM mutex_exit(&group->ra_queue.net_qlock);
26567836SJohn.Forte@Sun.COM if (pendcnt) {
26577836SJohn.Forte@Sun.COM int vecsz;
26587836SJohn.Forte@Sun.COM #ifdef DEBUG
26597836SJohn.Forte@Sun.COM if (rdc_netwrite6) {
26609093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!packing pend, count %d", pendcnt);
26617836SJohn.Forte@Sun.COM }
26627836SJohn.Forte@Sun.COM #endif
26637836SJohn.Forte@Sun.COM vecsz = pendcnt * sizeof (net_pendvec_t);
26647836SJohn.Forte@Sun.COM netretp->vecdata.vecdata_val =
26657836SJohn.Forte@Sun.COM kmem_alloc(vecsz, KM_SLEEP);
26667836SJohn.Forte@Sun.COM netretp->vecdata.vecdata_len = pendcnt;
26677836SJohn.Forte@Sun.COM bcopy(pendvec, netretp->vecdata.vecdata_val, vecsz);
26687836SJohn.Forte@Sun.COM }
26697836SJohn.Forte@Sun.COM kmem_free(pendvec, pendsz);
26707836SJohn.Forte@Sun.COM mutex_enter(&group->ra_queue.net_qlock);
26717836SJohn.Forte@Sun.COM }
26727836SJohn.Forte@Sun.COM
26737836SJohn.Forte@Sun.COM /*
26747836SJohn.Forte@Sun.COM * Take the dset and allocate and fill in the vector.
26757836SJohn.Forte@Sun.COM */
26767836SJohn.Forte@Sun.COM static nsc_vec_t *
rdc_dset2vec(rdc_net_dataset_t * dset)26777836SJohn.Forte@Sun.COM rdc_dset2vec(rdc_net_dataset_t *dset)
26787836SJohn.Forte@Sun.COM {
26797836SJohn.Forte@Sun.COM nsc_vec_t *vecret;
26807836SJohn.Forte@Sun.COM int i;
26817836SJohn.Forte@Sun.COM rdc_net_dataitem_t *ditem;
26827836SJohn.Forte@Sun.COM
26837836SJohn.Forte@Sun.COM ASSERT(dset->nitems > 0);
26847836SJohn.Forte@Sun.COM ASSERT(dset->head);
26857836SJohn.Forte@Sun.COM ASSERT(dset->tail);
26867836SJohn.Forte@Sun.COM
26877836SJohn.Forte@Sun.COM vecret = kmem_alloc((dset->nitems + 1) * sizeof (nsc_vec_t),
26887836SJohn.Forte@Sun.COM KM_NOSLEEP);
26897836SJohn.Forte@Sun.COM if (vecret == NULL) {
26907836SJohn.Forte@Sun.COM return (NULL);
26917836SJohn.Forte@Sun.COM }
26927836SJohn.Forte@Sun.COM RDC_DSMEMUSE((dset->nitems + 1) * sizeof (nsc_vec_t));
26937836SJohn.Forte@Sun.COM ditem = dset->head;
26947836SJohn.Forte@Sun.COM for (i = 0; i < dset->nitems; i++) {
26957836SJohn.Forte@Sun.COM ASSERT(ditem);
26967836SJohn.Forte@Sun.COM vecret[i].sv_addr = ditem->dptr;
26977836SJohn.Forte@Sun.COM vecret[i].sv_len = ditem->len;
26987836SJohn.Forte@Sun.COM ditem = ditem->next;
26997836SJohn.Forte@Sun.COM }
27007836SJohn.Forte@Sun.COM /*
27017836SJohn.Forte@Sun.COM * Null terminate.
27027836SJohn.Forte@Sun.COM */
27037836SJohn.Forte@Sun.COM vecret[i].sv_addr = NULL;
27047836SJohn.Forte@Sun.COM vecret[i].sv_len = 0;
27057836SJohn.Forte@Sun.COM /*
27067836SJohn.Forte@Sun.COM * Check the list and count matches.
27077836SJohn.Forte@Sun.COM */
27087836SJohn.Forte@Sun.COM ASSERT(ditem == NULL);
27097836SJohn.Forte@Sun.COM return (vecret);
27107836SJohn.Forte@Sun.COM }
27117836SJohn.Forte@Sun.COM
27127836SJohn.Forte@Sun.COM /*
27137836SJohn.Forte@Sun.COM * Split the local read into maxfba sized chunks.
27147836SJohn.Forte@Sun.COM * Returns 0 on an error, or a valid idx on success.
27157836SJohn.Forte@Sun.COM */
27167836SJohn.Forte@Sun.COM static int
rdc_readmaxfba(int cd,nsc_off_t pos,nsc_size_t fbalen,int nocache)27177836SJohn.Forte@Sun.COM rdc_readmaxfba(int cd, nsc_off_t pos, nsc_size_t fbalen, int nocache)
27187836SJohn.Forte@Sun.COM {
27197836SJohn.Forte@Sun.COM int idx;
27207836SJohn.Forte@Sun.COM rdc_k_info_t *krdc;
27217836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
27227836SJohn.Forte@Sun.COM rdc_net_dataset_t *dset;
27237836SJohn.Forte@Sun.COM rdc_net_dataitem_t *ditem;
27247836SJohn.Forte@Sun.COM int rtype;
27257836SJohn.Forte@Sun.COM nsc_buf_t *handle;
27267836SJohn.Forte@Sun.COM nsc_vec_t veclist[2];
27277836SJohn.Forte@Sun.COM int ret;
27287836SJohn.Forte@Sun.COM int reserved;
27297836SJohn.Forte@Sun.COM nsc_size_t fbaleft;
27307836SJohn.Forte@Sun.COM nsc_size_t mfba;
27317836SJohn.Forte@Sun.COM nsc_off_t fba;
27327836SJohn.Forte@Sun.COM nsc_off_t spos;
27337836SJohn.Forte@Sun.COM int eintr_count;
27347836SJohn.Forte@Sun.COM
27357836SJohn.Forte@Sun.COM handle = NULL;
27367836SJohn.Forte@Sun.COM idx = 0; /* error status */
27377836SJohn.Forte@Sun.COM dset = NULL;
27387836SJohn.Forte@Sun.COM ditem = NULL;
27397836SJohn.Forte@Sun.COM reserved = 0;
27407836SJohn.Forte@Sun.COM ret = 0;
27417836SJohn.Forte@Sun.COM mfba = 0;
27427836SJohn.Forte@Sun.COM
27437836SJohn.Forte@Sun.COM rtype = RDC_RAW;
27447836SJohn.Forte@Sun.COM krdc = &rdc_k_info[cd];
27457836SJohn.Forte@Sun.COM urdc = &rdc_u_info[cd];
27467836SJohn.Forte@Sun.COM
27477836SJohn.Forte@Sun.COM eintr_count = 0;
27487836SJohn.Forte@Sun.COM do {
27497836SJohn.Forte@Sun.COM ret = _rdc_rsrv_devs(krdc, rtype, RDC_INTERNAL);
27507836SJohn.Forte@Sun.COM if (ret == EINTR) {
27517836SJohn.Forte@Sun.COM ++eintr_count;
27527836SJohn.Forte@Sun.COM delay(2);
27537836SJohn.Forte@Sun.COM }
27547836SJohn.Forte@Sun.COM } while ((ret == EINTR) && (eintr_count < MAX_EINTR_COUNT));
27557836SJohn.Forte@Sun.COM if (ret != 0) {
27567836SJohn.Forte@Sun.COM #ifdef DEBUG
27579093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!readmaxfba: reserve failed on set %s:%s %d",
27587836SJohn.Forte@Sun.COM urdc->secondary.intf, urdc->secondary.file,
27597836SJohn.Forte@Sun.COM ret);
27607836SJohn.Forte@Sun.COM #endif
27617836SJohn.Forte@Sun.COM goto out;
27627836SJohn.Forte@Sun.COM }
27637836SJohn.Forte@Sun.COM reserved = 1;
27647836SJohn.Forte@Sun.COM /*
27657836SJohn.Forte@Sun.COM * create a dataset that we can hang all the buffers from.
27667836SJohn.Forte@Sun.COM */
27677836SJohn.Forte@Sun.COM dset = rdc_net_add_set(cd);
27687836SJohn.Forte@Sun.COM if (dset == NULL) {
27697836SJohn.Forte@Sun.COM #ifdef DEBUG
27709093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!readmaxfba: Unable to allocate dset on set "
27717836SJohn.Forte@Sun.COM "%s:%s", urdc->secondary.intf, urdc->secondary.file);
27727836SJohn.Forte@Sun.COM #endif
27737836SJohn.Forte@Sun.COM goto out;
27747836SJohn.Forte@Sun.COM }
27757836SJohn.Forte@Sun.COM dset->pos = pos;
27767836SJohn.Forte@Sun.COM dset->fbalen = fbalen;
27777836SJohn.Forte@Sun.COM ret = nsc_maxfbas(RDC_U_FD(krdc), 0, &mfba);
27787836SJohn.Forte@Sun.COM if (ret != 0) {
27797836SJohn.Forte@Sun.COM #ifdef DEBUG
27809093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!readmaxfba: msc_maxfbas failed on set %s:%s "
27817836SJohn.Forte@Sun.COM "%d", urdc->secondary.intf, urdc->secondary.file, ret);
27827836SJohn.Forte@Sun.COM #endif
27837836SJohn.Forte@Sun.COM goto out;
27847836SJohn.Forte@Sun.COM }
27857836SJohn.Forte@Sun.COM spos = pos;
27867836SJohn.Forte@Sun.COM fbaleft = fbalen;
27877836SJohn.Forte@Sun.COM veclist[1].sv_addr = NULL;
27887836SJohn.Forte@Sun.COM veclist[1].sv_len = 0;
27897836SJohn.Forte@Sun.COM
27907836SJohn.Forte@Sun.COM while (fbaleft > 0) {
27917836SJohn.Forte@Sun.COM fba = min(mfba, fbaleft);
27927836SJohn.Forte@Sun.COM if (handle) {
27937836SJohn.Forte@Sun.COM (void) nsc_free_buf(handle);
27947836SJohn.Forte@Sun.COM handle = NULL;
27957836SJohn.Forte@Sun.COM }
27967836SJohn.Forte@Sun.COM ret = nsc_alloc_buf(RDC_U_FD(krdc), spos, fba,
27977836SJohn.Forte@Sun.COM nocache|NSC_NODATA, &handle);
27987836SJohn.Forte@Sun.COM if (ret != 0) {
27997836SJohn.Forte@Sun.COM #ifdef DEBUG
28009093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!readmaxfba: alloc failed on set"
28017836SJohn.Forte@Sun.COM "%s:%s %d", urdc->secondary.intf,
28027836SJohn.Forte@Sun.COM urdc->secondary.file, ret);
28037836SJohn.Forte@Sun.COM #endif
28047836SJohn.Forte@Sun.COM goto out;
28057836SJohn.Forte@Sun.COM }
28067836SJohn.Forte@Sun.COM ditem = kmem_alloc(sizeof (rdc_net_dataitem_t), KM_NOSLEEP);
28077836SJohn.Forte@Sun.COM if (ditem == NULL) {
28087836SJohn.Forte@Sun.COM goto out;
28097836SJohn.Forte@Sun.COM }
28107836SJohn.Forte@Sun.COM RDC_DSMEMUSE(sizeof (rdc_net_dataitem_t));
28117836SJohn.Forte@Sun.COM ditem->len = FBA_SIZE(fba);
28127836SJohn.Forte@Sun.COM ditem->mlen = ditem->len;
28137836SJohn.Forte@Sun.COM ditem->dptr = kmem_alloc(ditem->len, KM_SLEEP);
28147836SJohn.Forte@Sun.COM RDC_DSMEMUSE(ditem->len);
28157836SJohn.Forte@Sun.COM ditem->next = NULL;
28167836SJohn.Forte@Sun.COM /*
28177836SJohn.Forte@Sun.COM * construct a vector list
28187836SJohn.Forte@Sun.COM */
28197836SJohn.Forte@Sun.COM veclist[0].sv_addr = ditem->dptr;
28207836SJohn.Forte@Sun.COM veclist[0].sv_len = ditem->len;
28217836SJohn.Forte@Sun.COM handle->sb_vec = veclist;
28227836SJohn.Forte@Sun.COM ret = rdc_combyread(krdc, urdc, handle);
28237836SJohn.Forte@Sun.COM if (ret != 0) {
28247836SJohn.Forte@Sun.COM goto out;
28257836SJohn.Forte@Sun.COM }
28267836SJohn.Forte@Sun.COM /*
28277836SJohn.Forte@Sun.COM * place on linked list.
28287836SJohn.Forte@Sun.COM */
28297836SJohn.Forte@Sun.COM dset->nitems++;
28307836SJohn.Forte@Sun.COM if (dset->head == NULL) {
28317836SJohn.Forte@Sun.COM dset->head = ditem;
28327836SJohn.Forte@Sun.COM dset->tail = ditem;
28337836SJohn.Forte@Sun.COM } else {
28347836SJohn.Forte@Sun.COM dset->tail->next = ditem;
28357836SJohn.Forte@Sun.COM dset->tail = ditem;
28367836SJohn.Forte@Sun.COM }
28377836SJohn.Forte@Sun.COM /*
28387836SJohn.Forte@Sun.COM * now its linked, clear this so its not freed twice.
28397836SJohn.Forte@Sun.COM */
28407836SJohn.Forte@Sun.COM ditem = NULL;
28417836SJohn.Forte@Sun.COM fbaleft -= fba;
28427836SJohn.Forte@Sun.COM spos += fba;
28437836SJohn.Forte@Sun.COM }
28447836SJohn.Forte@Sun.COM /*
28457836SJohn.Forte@Sun.COM * all the reads have worked, store the results.
28467836SJohn.Forte@Sun.COM */
28477836SJohn.Forte@Sun.COM idx = dset->id;
28487836SJohn.Forte@Sun.COM rdc_net_put_set(cd, dset);
28497836SJohn.Forte@Sun.COM dset = NULL;
28507836SJohn.Forte@Sun.COM out:
28517836SJohn.Forte@Sun.COM if (handle)
28527836SJohn.Forte@Sun.COM (void) nsc_free_buf(handle);
28537836SJohn.Forte@Sun.COM if (reserved)
28547836SJohn.Forte@Sun.COM _rdc_rlse_devs(krdc, rtype);
28557836SJohn.Forte@Sun.COM if (dset)
28567836SJohn.Forte@Sun.COM rdc_net_del_set(cd, dset);
28577836SJohn.Forte@Sun.COM if (ditem) {
28587836SJohn.Forte@Sun.COM kmem_free(ditem->dptr, ditem->mlen);
28597836SJohn.Forte@Sun.COM RDC_DSMEMUSE(-ditem->mlen);
28607836SJohn.Forte@Sun.COM kmem_free(ditem, sizeof (*ditem));
28617836SJohn.Forte@Sun.COM RDC_DSMEMUSE(-sizeof (*ditem));
28627836SJohn.Forte@Sun.COM }
28637836SJohn.Forte@Sun.COM return (idx);
28647836SJohn.Forte@Sun.COM }
28657836SJohn.Forte@Sun.COM
28667836SJohn.Forte@Sun.COM
28677836SJohn.Forte@Sun.COM /*
28687836SJohn.Forte@Sun.COM * perform both a local read, and if multihop, a remote read.
28697836SJohn.Forte@Sun.COM * return 0 on success, or errno on failure.
28707836SJohn.Forte@Sun.COM */
28717836SJohn.Forte@Sun.COM static int
rdc_combyread(rdc_k_info_t * krdc,rdc_u_info_t * urdc,nsc_buf_t * handle)28727836SJohn.Forte@Sun.COM rdc_combyread(rdc_k_info_t *krdc, rdc_u_info_t *urdc, nsc_buf_t *handle)
28737836SJohn.Forte@Sun.COM {
28747836SJohn.Forte@Sun.COM int ret;
28757836SJohn.Forte@Sun.COM rdc_k_info_t *ktmp;
28767836SJohn.Forte@Sun.COM rdc_u_info_t *utmp;
28777836SJohn.Forte@Sun.COM
28787836SJohn.Forte@Sun.COM /*
28797836SJohn.Forte@Sun.COM * read it.
28807836SJohn.Forte@Sun.COM */
28817836SJohn.Forte@Sun.COM if (krdc->io_kstats) {
28827836SJohn.Forte@Sun.COM mutex_enter(krdc->io_kstats->ks_lock);
28837836SJohn.Forte@Sun.COM kstat_runq_enter(KSTAT_IO_PTR(krdc->io_kstats));
28847836SJohn.Forte@Sun.COM mutex_exit(krdc->io_kstats->ks_lock);
28857836SJohn.Forte@Sun.COM }
28867836SJohn.Forte@Sun.COM
28877836SJohn.Forte@Sun.COM ret = nsc_read(handle, handle->sb_pos, handle->sb_len, NSC_READ);
28887836SJohn.Forte@Sun.COM
28897836SJohn.Forte@Sun.COM if (krdc->io_kstats) {
28907836SJohn.Forte@Sun.COM mutex_enter(krdc->io_kstats->ks_lock);
28917836SJohn.Forte@Sun.COM kstat_runq_exit(KSTAT_IO_PTR(krdc->io_kstats));
28927836SJohn.Forte@Sun.COM mutex_exit(krdc->io_kstats->ks_lock);
28937836SJohn.Forte@Sun.COM }
28947836SJohn.Forte@Sun.COM
28957836SJohn.Forte@Sun.COM if (ret != 0) {
28967836SJohn.Forte@Sun.COM #ifdef DEBUG
28979093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!combyread: read failed on set %s:%s %d",
28987836SJohn.Forte@Sun.COM urdc->secondary.intf, urdc->secondary.file, ret);
28997836SJohn.Forte@Sun.COM #endif
29007836SJohn.Forte@Sun.COM if (!(rdc_get_vflags(urdc) & RDC_VOL_FAILED)) {
29017836SJohn.Forte@Sun.COM rdc_many_enter(krdc);
29027836SJohn.Forte@Sun.COM rdc_set_mflags(urdc, RDC_RSYNC_NEEDED);
29037836SJohn.Forte@Sun.COM rdc_set_flags_log(urdc, RDC_VOL_FAILED,
29047836SJohn.Forte@Sun.COM "comby read failed");
29057836SJohn.Forte@Sun.COM rdc_many_exit(krdc);
29067836SJohn.Forte@Sun.COM rdc_write_state(urdc);
29077836SJohn.Forte@Sun.COM }
29087836SJohn.Forte@Sun.COM goto out;
29097836SJohn.Forte@Sun.COM }
29107836SJohn.Forte@Sun.COM if (IS_MULTI(krdc) && (ktmp = krdc->multi_next) &&
29117836SJohn.Forte@Sun.COM (utmp = &rdc_u_info[ktmp->index]) &&
29127836SJohn.Forte@Sun.COM IS_ENABLED(utmp) &&
29137836SJohn.Forte@Sun.COM (rdc_get_mflags(utmp) & RDC_RSYNC_NEEDED)) {
29147836SJohn.Forte@Sun.COM ret = _rdc_remote_read(ktmp, handle, handle->sb_pos,
29157836SJohn.Forte@Sun.COM handle->sb_len, NSC_READ);
29167836SJohn.Forte@Sun.COM /*
29177836SJohn.Forte@Sun.COM * Set NSC_MIXED so
29187836SJohn.Forte@Sun.COM * that the cache will throw away this
29197836SJohn.Forte@Sun.COM * buffer when we free it since we have
29207836SJohn.Forte@Sun.COM * combined data from multiple sources
29217836SJohn.Forte@Sun.COM * into a single buffer.
29227836SJohn.Forte@Sun.COM * Currently we don't use the cache for
29237836SJohn.Forte@Sun.COM * data volumes, so comment this out.
29247836SJohn.Forte@Sun.COM * handle->sb_flag |= NSC_MIXED;
29257836SJohn.Forte@Sun.COM */
29267836SJohn.Forte@Sun.COM if (ret != 0) {
29277836SJohn.Forte@Sun.COM #ifdef DEBUG
29289093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!combyread: remote read failed on "
29297836SJohn.Forte@Sun.COM "set %s:%s %d", utmp->secondary.intf,
29307836SJohn.Forte@Sun.COM utmp->secondary.file, ret);
29317836SJohn.Forte@Sun.COM #endif
29327836SJohn.Forte@Sun.COM goto out;
29337836SJohn.Forte@Sun.COM }
29347836SJohn.Forte@Sun.COM }
29357836SJohn.Forte@Sun.COM if (krdc->io_kstats) {
29367836SJohn.Forte@Sun.COM KSTAT_IO_PTR(krdc->io_kstats)->reads++;
29377836SJohn.Forte@Sun.COM KSTAT_IO_PTR(krdc->io_kstats)->nread +=
29387836SJohn.Forte@Sun.COM FBA_SIZE(handle->sb_len);
29397836SJohn.Forte@Sun.COM }
29407836SJohn.Forte@Sun.COM out:
29417836SJohn.Forte@Sun.COM return (ret);
29427836SJohn.Forte@Sun.COM }
29437836SJohn.Forte@Sun.COM
29447836SJohn.Forte@Sun.COM
29457836SJohn.Forte@Sun.COM /*
29467836SJohn.Forte@Sun.COM * remove and free all the collected dsets for this set.
29477836SJohn.Forte@Sun.COM */
29487836SJohn.Forte@Sun.COM void
rdc_dump_dsets(int index)29497836SJohn.Forte@Sun.COM rdc_dump_dsets(int index)
29507836SJohn.Forte@Sun.COM {
29517836SJohn.Forte@Sun.COM rdc_k_info_t *krdc;
29527836SJohn.Forte@Sun.COM rdc_net_dataset_t *dset;
29537836SJohn.Forte@Sun.COM
29547836SJohn.Forte@Sun.COM krdc = &rdc_k_info[index];
29557836SJohn.Forte@Sun.COM tloop:
29567836SJohn.Forte@Sun.COM mutex_enter(&krdc->dc_sleep);
29577836SJohn.Forte@Sun.COM while ((dset = krdc->net_dataset) != NULL) {
29587836SJohn.Forte@Sun.COM if (dset->inuse) {
29597836SJohn.Forte@Sun.COM /*
29607836SJohn.Forte@Sun.COM * for the dset to be in use, the
29617836SJohn.Forte@Sun.COM * service routine r_net_write6() must
29627836SJohn.Forte@Sun.COM * be active with it. It will free
29637836SJohn.Forte@Sun.COM * it eventually.
29647836SJohn.Forte@Sun.COM */
29657836SJohn.Forte@Sun.COM mutex_exit(&krdc->dc_sleep);
29667836SJohn.Forte@Sun.COM delay(5);
29677836SJohn.Forte@Sun.COM goto tloop;
29687836SJohn.Forte@Sun.COM }
29697836SJohn.Forte@Sun.COM /*
29707836SJohn.Forte@Sun.COM * free it.
29717836SJohn.Forte@Sun.COM */
29727836SJohn.Forte@Sun.COM rdc_net_free_set(krdc, dset);
29737836SJohn.Forte@Sun.COM }
29747836SJohn.Forte@Sun.COM mutex_exit(&krdc->dc_sleep);
29757836SJohn.Forte@Sun.COM }
29767836SJohn.Forte@Sun.COM
29777836SJohn.Forte@Sun.COM #ifdef DEBUG
29787836SJohn.Forte@Sun.COM void
rdc_stallzero(int flag)29797836SJohn.Forte@Sun.COM rdc_stallzero(int flag)
29807836SJohn.Forte@Sun.COM {
29817836SJohn.Forte@Sun.COM static int init = 0;
29827836SJohn.Forte@Sun.COM static kcondvar_t cv;
29837836SJohn.Forte@Sun.COM static kmutex_t mu;
29847836SJohn.Forte@Sun.COM
29857836SJohn.Forte@Sun.COM if (init == 0) {
29867836SJohn.Forte@Sun.COM cv_init(&cv, NULL, CV_DRIVER, NULL);
29877836SJohn.Forte@Sun.COM mutex_init(&mu, NULL, MUTEX_DRIVER, NULL);
29887836SJohn.Forte@Sun.COM init = 1;
29897836SJohn.Forte@Sun.COM }
29907836SJohn.Forte@Sun.COM
29917836SJohn.Forte@Sun.COM mutex_enter(&mu);
29927836SJohn.Forte@Sun.COM switch (flag) {
29937836SJohn.Forte@Sun.COM case 0:
29947836SJohn.Forte@Sun.COM rdc_stall0 = 0;
29957836SJohn.Forte@Sun.COM cv_signal(&cv);
29967836SJohn.Forte@Sun.COM break;
29977836SJohn.Forte@Sun.COM case 1:
29987836SJohn.Forte@Sun.COM rdc_stall0 = 1;
29997836SJohn.Forte@Sun.COM break;
30007836SJohn.Forte@Sun.COM case 2:
30017836SJohn.Forte@Sun.COM while (rdc_stall0 == 1)
30027836SJohn.Forte@Sun.COM cv_wait(&cv, &mu);
30037836SJohn.Forte@Sun.COM break;
30047836SJohn.Forte@Sun.COM default:
30057836SJohn.Forte@Sun.COM cmn_err(CE_PANIC, "Bad flag value passed to rdc_stallzero");
30067836SJohn.Forte@Sun.COM break;
30077836SJohn.Forte@Sun.COM }
30087836SJohn.Forte@Sun.COM mutex_exit(&mu);
30097836SJohn.Forte@Sun.COM }
30107836SJohn.Forte@Sun.COM #endif
30117836SJohn.Forte@Sun.COM
30127836SJohn.Forte@Sun.COM /*
30137836SJohn.Forte@Sun.COM * RDC protocol version 5
30147836SJohn.Forte@Sun.COM */
30157836SJohn.Forte@Sun.COM static rdc_disptab_t rdc_disptab5[] =
30167836SJohn.Forte@Sun.COM {
30177836SJohn.Forte@Sun.COM /* PROC Idempotent */
30187836SJohn.Forte@Sun.COM { r_net_null, FALSE },
30197836SJohn.Forte@Sun.COM { rdcsrv_noproc, FALSE },
30207836SJohn.Forte@Sun.COM { r_net_getsize, FALSE },
30217836SJohn.Forte@Sun.COM { rdcsrv_noproc, FALSE },
30227836SJohn.Forte@Sun.COM { r_net_write5, TRUE },
30237836SJohn.Forte@Sun.COM { r_net_read, FALSE },
30247836SJohn.Forte@Sun.COM { rdcsrv_noproc, FALSE },
30257836SJohn.Forte@Sun.COM { r_net_state4, FALSE },
30267836SJohn.Forte@Sun.COM { r_net_ping4, FALSE },
30277836SJohn.Forte@Sun.COM { r_net_bmap, FALSE },
30287836SJohn.Forte@Sun.COM { r_net_bdata, FALSE },
30297836SJohn.Forte@Sun.COM { rdcsrv_noproc, FALSE },
30307836SJohn.Forte@Sun.COM { r_net_getstate4, FALSE }
30317836SJohn.Forte@Sun.COM };
30327836SJohn.Forte@Sun.COM
30337836SJohn.Forte@Sun.COM /*
30347836SJohn.Forte@Sun.COM * RDC protocol version 6
30357836SJohn.Forte@Sun.COM */
30367836SJohn.Forte@Sun.COM static rdc_disptab_t rdc_disptab6[] =
30377836SJohn.Forte@Sun.COM {
30387836SJohn.Forte@Sun.COM /* PROC Idempotent */
30397836SJohn.Forte@Sun.COM { r_net_null, FALSE },
30407836SJohn.Forte@Sun.COM { rdcsrv_noproc, FALSE },
30417836SJohn.Forte@Sun.COM { r_net_getsize6, FALSE },
30427836SJohn.Forte@Sun.COM { rdcsrv_noproc, FALSE },
30437836SJohn.Forte@Sun.COM { r_net_write6, TRUE },
30447836SJohn.Forte@Sun.COM { r_net_read6, FALSE },
30457836SJohn.Forte@Sun.COM { rdcsrv_noproc, FALSE },
30467836SJohn.Forte@Sun.COM { r_net_state4, FALSE },
30477836SJohn.Forte@Sun.COM { r_net_ping4, FALSE },
30487836SJohn.Forte@Sun.COM { r_net_bmap6, FALSE },
30497836SJohn.Forte@Sun.COM { r_net_bdata6, FALSE },
30507836SJohn.Forte@Sun.COM { rdcsrv_noproc, FALSE },
30517836SJohn.Forte@Sun.COM { r_net_getstate4, FALSE }
30527836SJohn.Forte@Sun.COM };
30537836SJohn.Forte@Sun.COM
30547836SJohn.Forte@Sun.COM /*
30557836SJohn.Forte@Sun.COM * RDC protocol version 7
30567836SJohn.Forte@Sun.COM */
30577836SJohn.Forte@Sun.COM static rdc_disptab_t rdc_disptab7[] =
30587836SJohn.Forte@Sun.COM {
30597836SJohn.Forte@Sun.COM /* PROC Idempotent */
30607836SJohn.Forte@Sun.COM { r_net_null, FALSE },
30617836SJohn.Forte@Sun.COM { rdcsrv_noproc, FALSE },
30627836SJohn.Forte@Sun.COM { r_net_getsize6, FALSE },
30637836SJohn.Forte@Sun.COM { rdcsrv_noproc, FALSE },
30647836SJohn.Forte@Sun.COM { r_net_write6, TRUE },
30657836SJohn.Forte@Sun.COM { r_net_read6, FALSE },
30667836SJohn.Forte@Sun.COM { rdcsrv_noproc, FALSE },
30677836SJohn.Forte@Sun.COM { r_net_state, FALSE },
30687836SJohn.Forte@Sun.COM { r_net_ping7, FALSE },
30697836SJohn.Forte@Sun.COM { r_net_bmap6, FALSE },
30707836SJohn.Forte@Sun.COM { r_net_bdata6, FALSE },
30717836SJohn.Forte@Sun.COM { rdcsrv_noproc, FALSE },
30727836SJohn.Forte@Sun.COM { r_net_getstate7, FALSE }
30737836SJohn.Forte@Sun.COM };
30747836SJohn.Forte@Sun.COM
30757836SJohn.Forte@Sun.COM static rdcsrv_t rdc_srvtab[] = {
30767836SJohn.Forte@Sun.COM { rdc_disptab5, sizeof (rdc_disptab5) / sizeof (*rdc_disptab5) },
30777836SJohn.Forte@Sun.COM { rdc_disptab6, sizeof (rdc_disptab6) / sizeof (*rdc_disptab6) },
30787836SJohn.Forte@Sun.COM { rdc_disptab7, sizeof (rdc_disptab7) / sizeof (*rdc_disptab7) }
30797836SJohn.Forte@Sun.COM };
30807836SJohn.Forte@Sun.COM
30817836SJohn.Forte@Sun.COM bool_t
rdc_xdr_netbuf(XDR * xdrs,struct netbuf * objp)30827836SJohn.Forte@Sun.COM rdc_xdr_netbuf(XDR *xdrs, struct netbuf *objp)
30837836SJohn.Forte@Sun.COM {
30847836SJohn.Forte@Sun.COM /*
30857836SJohn.Forte@Sun.COM * If we're decoding and the caller has already allocated a buffer,
30867836SJohn.Forte@Sun.COM * throw away maxlen, since it doesn't apply to the caller's
30877836SJohn.Forte@Sun.COM * buffer. xdr_bytes will return an error if the buffer isn't big
30887836SJohn.Forte@Sun.COM * enough.
30897836SJohn.Forte@Sun.COM */
30907836SJohn.Forte@Sun.COM if (xdrs->x_op == XDR_DECODE && objp->buf != NULL) {
30917836SJohn.Forte@Sun.COM uint_t maxlen;
30927836SJohn.Forte@Sun.COM
30937836SJohn.Forte@Sun.COM if (!xdr_u_int(xdrs, &maxlen))
30947836SJohn.Forte@Sun.COM return (FALSE);
30957836SJohn.Forte@Sun.COM } else {
30967836SJohn.Forte@Sun.COM if (!xdr_u_int(xdrs, (uint_t *)&objp->maxlen))
30977836SJohn.Forte@Sun.COM return (FALSE);
30987836SJohn.Forte@Sun.COM }
30997836SJohn.Forte@Sun.COM return (xdr_bytes(xdrs, (char **)&(objp->buf),
31007836SJohn.Forte@Sun.COM (uint_t *)&(objp->len), objp->maxlen));
31017836SJohn.Forte@Sun.COM }
3102