1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-23 11:18:54 +00:00
freebsd/lkm/vinum/request.h
Greg Lehey 721fbc5ae0 config.c:
config_drive:
    Catch an instance of anonymous drives.  Doubtless many remain.

interrupt.c:
  complete_rqe:
    Call logrq to log iodone events if DEBUG_LASTREQS is set.

    Call set_sd_state with setstate_noupdate to avoid buffered I/O out
    of interrupt context.

    Use define DEBUG_RESID instead of constant.

memory.c:
  Remove dead expandrq() function

  Malloc:
    Remove directory component of file names in malloc table.

  Add function vinum_rqinfo (part of the request tracing stuff).

request.c:
  Add function logrq (part of the request tracing stuff).

  vinumstrategy:
    Check whether config needs to be written to disk, do it if so.
    This is a stopgap until the Vinum daemon (bacchusd?  oenologistd?)
    is written.

    If DEBUG_LASTREQS is set, call logrq to log user buffer headers.

  launch_requests:
    Correct format of debug output to console.

    If DEBUG_LASTREQS is set, call logrq to log request elements.

request.h:
  Add definitions for request trace.

state.c:
  set_sd_state:
    Check flags for setstate_noupdate.  If set, don't write the config
    to disk, just set global VF_DIRTYCONFIG flag.  This is part of the
    kludge to avoid writing config from an interrupt context.

vinumext.h:
    Add declaration for vinum_rqinfo, put inside #ifdef DEBUG
    Remove dead macro expandrq

vinumio.h:
  Increase maximum ioctl reply length to 4 kB if DEBUG is set.
  Define VINUM_RQINFO ioctl if DEBUG is set.

vinumioctl.c:
  vinumioctl:
    Change implementation of VINUM_DEBUG ioctl: use a debug flag
    (DEBUG_REMOTEGDB) to decide whether to go into remote debugging or
    not.

    Implement VINUM_RQINFO.

vinumkw.h:
  Define kw_info even when not debugging.

vinumvar.h:
  Define VF_DIRTYCONFIG
  Add pointers to request info to vinum_info if DEBUG is set.
  Define setstate_noupdate
  Define additional debug bits DEBUG_RESID, DEBUG_LASTREQS and
  DEBUG_REMOTEGDB.
1998-10-21 08:32:32 +00:00

192 lines
8.2 KiB
C

/*-
* Copyright (c) 1997, 1998
* Nan Yang Computer Services Limited. All rights reserved.
*
* This software is distributed under the so-called ``Berkeley
* License'':
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Nan Yang Computer
* Services Limited.
* 4. Neither the name of the Company nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* This software is provided ``as is'', and any express or implied
* warranties, including, but not limited to, the implied warranties of
* merchantability and fitness for a particular purpose are disclaimed.
* In no event shall the company or contributors be liable for any
* direct, indirect, incidental, special, exemplary, or consequential
* damages (including, but not limited to, procurement of substitute
* goods or services; loss of use, data, or profits; or business
* interruption) however caused and on any theory of liability, whether
* in contract, strict liability, or tort (including negligence or
* otherwise) arising in any way out of the use of this software, even if
* advised of the possibility of such damage.
*
* $Id: request.h,v 1.10 1998/08/03 07:15:26 grog Exp grog $
*/
/* Information needed to set up a transfer */
/* struct buf is surprisingly big (about 300
* bytes), and it's part of the request, so this
* value is really important. Most requests
* don't need more than 2 subrequests per
* plex. The table is automatically extended if
* this value is too small. */
#define RQELTS 2 /* default of 2 requests per transfer */
enum xferinfo {
XFR_NORMAL_READ = 1,
XFR_NORMAL_WRITE = 2, /* write request in normal mode */
XFR_RECOVERY_READ = 4,
XFR_DEGRADED_WRITE = 8,
XFR_PARITYLESS_WRITE = 0x10,
XFR_NO_PARITY_STRIPE = 0x20, /* parity stripe is not available */
XFR_DATA_BLOCK = 0x40, /* data block in request */
XFR_PARITY_BLOCK = 0x80, /* parity block in request */
XFR_BAD_SUBDISK = 0x100, /* this subdisk is dead */
XFR_MALLOCED = 0x200, /* this buffer is malloced */
#if DEBUG
XFR_PHASE2 = 0x800, /* documentation only: 2nd phase write */
#endif
XFR_REVIVECONFLICT = 0x1000, /* possible conflict with a revive operation */
/* operations that need a parity block */
XFR_PARITYOP = (XFR_NORMAL_WRITE | XFR_RECOVERY_READ | XFR_DEGRADED_WRITE),
/* operations that use the group parameters */
XFR_GROUPOP = (XFR_DEGRADED_WRITE | XFR_RECOVERY_READ),
/* operations that that use the data parameters */
XFR_DATAOP = (XFR_NORMAL_READ | XFR_NORMAL_WRITE | XFR_PARITYLESS_WRITE),
/* operations requiring read before write */
XFR_RBW = (XFR_NORMAL_WRITE | XFR_DEGRADED_WRITE),
/* operations that need a malloced buffer */
XFR_NEEDS_MALLOC = (XFR_NORMAL_WRITE | XFR_RECOVERY_READ | XFR_DEGRADED_WRITE)
};
/* Describe one low-level request, part
* of a high-level request. This is an
* extended struct buf buffer, and the first
* element *must* be a struct buf. We pass this structure
* to the I/O routines instead of a struct buf in oder
* to be able to locate the high-level request when it
* completes.
*
* All offsets and lengths are in "blocks", i.e. sectors */
struct rqelement {
struct buf b; /* buf structure */
struct rqgroup *rqg; /* pointer to our group */
/* Information about the transfer */
daddr_t sdoffset; /* offset in subdisk */
int useroffset; /* offset in user buffer of normal data */
/* dataoffset and datalen refer to "individual"
* data transfers (normal read, parityless write)
* and also degraded write.
*
* groupoffset and grouplen refer to the other
* "group" operations (normal write, recovery read)
* Both the offsets are relative to the start of the
* local buffer */
int dataoffset; /* offset in buffer of the normal data */
int groupoffset; /* offset in buffer of group data */
short datalen; /* length of normal data (sectors) */
short grouplen; /* length of group data (sectors) */
short buflen; /* total buffer length to allocate */
short flags; /* really enum xferinfo (see above) */
/* Ways to find other components */
short sdno; /* subdisk number */
short driveno; /* drive number */
};
/* A group of requests built to satisfy a certain
* component of a user request */
struct rqgroup {
struct rqgroup *next; /* pointer to next group */
struct request *rq; /* pointer to the request */
short count; /* number of requests in this group */
short active; /* and number active */
short plexno; /* index of plex */
int badsdno; /* index of bad subdisk or -1 */
enum xferinfo flags; /* description of transfer */
struct rqelement rqe[0]; /* and the elements of this request */
};
/* Describe one high-level request and the
* work we have to do to satisfy it */
struct request {
struct buf *bp; /* pointer to the high-level request */
int flags;
union {
int volno; /* volume index */
int plexno; /* or plex index */
} volplex;
int error; /* current error indication */
short isplex; /* set if this is a plex request */
short active; /* number of subrequests still active */
struct rqgroup *rqg; /* pointer to the first group of requests */
struct rqgroup *lrqg; /* and to the first group of requests */
struct request *next; /* link of waiting requests */
};
/* Extended buffer header for subdisk I/O. Includes
* a pointer to the user I/O request. */
struct sdbuf {
struct buf b; /* our buffer */
struct buf *bp; /* and pointer to parent */
short driveno; /* drive index */
short sdno; /* and subdisk index */
};
/* Values returned by rqe and friends.
* Be careful with these: they are in order of increasing
* seriousness. Some routines check for > REQUEST_RECOVERED
* to indicate a completely failed request. */
enum requeststatus {
REQUEST_OK, /* request built OK */
REQUEST_RECOVERED, /* request OK, but involves RAID5 recovery */
REQUEST_EOF, /* request failed: outside plex */
REQUEST_DOWN, /* request failed: subdisk down */
REQUEST_ENOMEM /* ran out of memory */
};
#ifdef DEBUG
/* Trace entry for request info (DEBUG_LASTREQS) */
enum rqinfo_type {
loginfo_unused, /* never been used */
loginfo_user_bp, /* this is the bp when strategy is called */
loginfo_user_bpl, /* and this is the bp at launch time */
loginfo_rqe, /* user RQE */
loginfo_iodone, /* iodone */
loginfo_raid5_data, /* write RAID-5 data block */
loginfo_raid5_parity /* write RAID-5 parity block */
};
union rqinfou { /* info to pass to logrq */
struct buf *bp;
struct rqelement *rqe; /* address of request, for correlation */
};
struct rqinfo {
enum rqinfo_type type; /* kind of event */
struct timeval timestamp; /* time it happened */
struct buf *bp; /* point to user buffer */
union {
struct buf b; /* yup, the *whole* buffer header */
struct rqelement rqe; /* and the whole rqe */
} info;
};
#define RQINFO_SIZE 64 /* number of info slots in buffer */
void logrq(enum rqinfo_type type, union rqinfou info, struct buf *ubp);
#endif