/*
* Copyright (c) 2000, 2002 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Further, this software is distributed without any warranty that it is
* free of the rightful claim of any third person regarding infringement
* or the like. Any license provided herein, whether implied or
* otherwise, applies only to this software file. Patent licenses, if
* any, provided herein do not apply to combinations of this program with
* other software, or any other product whatsoever.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
* Mountain View, CA 94043, or:
*
* http://www.sgi.com
*
* For further information regarding this notice, see:
*
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
*/
#ifndef __XFS_GRIO_H__
#define __XFS_GRIO_H__
/*
* This include file contains the definitions and structures
* used by the guaranteed rate IO subsystem
*/
#include <linux/limits.h>
/* Experimental ioctl interface to GRIO on /dev/grio (10,160) */
#define XFS_GRIO_MAJOR 10 /* MAJOR number - misc device */
#define XFS_GRIO_MINOR 160 /* MINOR number */
#define XFS_GRIO_CMD 113 /* IOCTL command */
typedef struct xfs_grio_ioctl { /* structure to pass to ioctl */
__u64 cmd;
__u64 arg1, arg2, arg3, arg4, arg5, arg6, arg7;
} xfs_grio_ioctl_t;
/* cast between 64 bit number and pointer */
#define I64_TO_PTR(A) ((void*)(int)(A))
#define PTR_TO_I64(A) ((__u64)(int)(void*)(A))
/* cast between sysarg_t and pointers */
#define SYSARG_TO_PTR(A) (I64_TO_PTR(A))
#define PTR_TO_SYSARG(A) (PTR_TO_I64(A))
/*
* redefine type definitions
*/
typedef __uint64_t gr_ino_t;
typedef uuid_t stream_id_t;
#ifndef _ASM_SN_TYPES_H
typedef dev_t vertex_hdl_t;
typedef signed short cnodeid_t;
#endif
typedef int toid_t;
/*
* Global defines that determine the amount of resources used
* by the GRIO subsystem.
*/
/*
* maximum number of disks used by the GRIO subsystem
*/
#define MAX_NUM_DISKS 512
/*
* maximum number of disks in a single stripped volume used by GRIO
*/
#define MAX_ROTOR_SLOTS 256
/*
* maximum number of reservations allowed in GRIO subsystem
*/
#define MAX_NUM_RESERVATIONS 3000
/*
* maximum depth of ggd/grio command queue
*/
#define MAX_GRIO_QUEUE_COUNT 200
/*
* maximum number of streams returned by a single STAT call
*/
#define MAX_STREAM_STAT_COUNT MAX_NUM_RESERVATIONS
/*
* maximum size of a GRIO device name (as recorded in the /etc/grio_config file)
*/
#define DEV_NMLEN PATH_MAX
/*
* grio_resv structure is filled in by the user process and is sent to the
* library routine grio_request() along with the file descriptor of the
* resouce for which the I/O rate guarantee is being requested.
*
* The grio_request() call will return 0 if there are no errors. If there
* is an error the routine will return -1 and the gr_error field will
* contain the error number. In addition, if the guarantee request is
* denied due to lack of device bandwidth, then gr_optime, and gr_opsize
* will contain values describing the maximum remaining bandwidth.
*
*
* Return errors are:
* The first two errors indicate an error in the library.
* EINVAL - could not communicate to daemon
* ESRCH - invalid procid
*
* These errors indicate an error in the calling process.
* EBADF - could not stat file or file already
* has a guarantee
* EIO - error in guarantee request structure
* * start or duration time is incorrect
* * invalid flags in gr_flags field
* EPERM - invalid I/O size for file system
* ENOSPC - bandwidth could not be allocated
* ENOENT - file does not contain any extents.
* EACCES - cannot provide desired level of
* guarantee (i.e HARD vs SOFT)
*/
typedef struct grio_resv {
char gr_action; /* RESV_UNRESV action */
time_t gr_start; /* when to start in secs */
time_t gr_duration; /* len of guarantee in secs*/
time_t gr_optime; /* time of one op in usecs */
int gr_opsize; /* size of each op in bytes*/
stream_id_t gr_stream_id; /* stream id */
int gr_flags; /* flags field */
union {
dev_t gr_fsdev; /* FS being reserved */
int gr_fd; /* fd being reserved */
} gr_object_u;
__uint64_t gr_memloc; /* Opaque memory handle */
int gr_error; /* returned: error code */
char gr_errordev[DEV_NMLEN]; /* device that caused error*/
} grio_resv_t;
#define gr_fsid gr_object_u.gr_fsdev
#define gr_fid gr_object_u.gr_fd
/*
* Action values for the gr_action field
*/
#define GRIO_RESV_ACTION 0x1
#define GRIO_UNRESV_ACTION 0x2
/* Define for gr_duration field. This is assumed to be the default if
* no duration is specified. (2 yrs in seconds)
*/
#define GRIO_RESV_DURATION_INFINITE (2*365*24*60*60)
/*
* This structure is used to return statistics info to the caller.
* It is used with GRIO_GET_INFO resv_type.
* subcommands are:
* GRIO_DEV_RESVS:
* return number of reservations on the device
* identified by ( device_name) in grio_blk_t
* structure.
* GRIO_FILE_RESVS:
* return number of reservations on the file
* identified by ( fs_dev, ino) pair in grio_blk_t
* structure.
* GRIO_PROC_RESVS:
* return number of reservations for the process
* identified by ( procid ) in grio_blk_t structure.
*/
typedef struct grio_stats {
/*
* value dependent on the subcommand and grio_blk_t parameters.
*/
u_long gs_count; /* current number of reservations
* active on the device/file/proc
*/
u_long gs_maxresv; /* maximum number of reservations
* allowed on the device.
* for file/proc this is the number
* of licensed streams.
*/
u_long gs_optiosize; /* size of the optimal i/o size
* in bytes for this device.
* not defined for file/proc.
*/
char devname[DEV_NMLEN];
} grio_stats_t;
/* info returned to user by libgrio when MLD stuff is done */
typedef struct grio_mem_locality_s {
cnodeid_t grio_cnode;
} grio_mem_locality_t;
/*
* Defines for the gr_flags field.
* Set the user process or by the grio_lib
*/
#define PER_FILE_GUAR 0x00000008
#define PER_FILE_SYS_GUAR 0x00000010
#define PROC_PRIVATE_GUAR 0x00000020
#define PROC_SHARE_GUAR 0x00000040
#define FIXED_ROTOR_GUAR 0x00000100
#define SLIP_ROTOR_GUAR 0x00000200
#define NON_ROTOR_GUAR 0x00000400
#define REALTIME_SCHED_GUAR 0x00002000
#define NON_SCHED_GUAR 0x00004000
#define SYSTEM_GUAR 0x00008000
#define READ_GUAR 0x00010000
#define WRITE_GUAR 0x00020000
#define GUARANTEE_MASK 0x0003FFFF
/*
* Defines for the types of reservations
* Set by the ggd daemon
*/
#define RESERVATION_STARTED 0x10000000
#define RESERVATION_TYPE_VOD 0x20000000
/*
* Defines for stream states.
* Set by the grio driver.
*/
#define STREAM_REMOVE_IN_PROGRESS 0x01000000
#define STREAM_INITIATE_IN_PROGRESS 0x02000000
#define STREAM_SLIPPED_ONCE 0x04000000
#define STREAM_ASSOCIATED 0x08000000
#define STREAM_STATE_MASK 0xFF000000
/*
* backwards compatability
*/
#define VOD_LAYOUT SLIP_ROTOR_GUAR
#define IS_VOD_GUAR( griorp ) \
( (griorp->gr_flags & FIXED_ROTOR_GUAR) || \
(griorp->gr_flags & SLIP_ROTOR_GUAR) )
#define IS_FILESYS_GUAR( griorp ) \
( griorp->gr_flags & PER_FILE_SYS_GUAR )
#define IS_FILE_GUAR( griorp ) \
( griorp->gr_flags & PER_FILE_GUAR )
/* This structure has information about the end object to which we are
* allocating bandwidth.
*/
struct end_info {
char gr_end_type;
char gr_dummy1[3];
dev_t gr_dev; /* dev_t/file system dev_t */
gr_ino_t gr_ino; /* inode number */
};
/*
* Values for the gr_end_type field
*/
#define END_TYPE_NONE 0x0 /* nothing at this end */
#define END_TYPE_REG 0x1 /* regular XFS file/fs */
#define END_TYPE_SPECIAL 0x2 /* device special file */
typedef struct grio_command {
int gr_cmd; /* grio command */
int gr_subcmd; /* grio subcommand */
pid_t gr_procid; /* process id of requestor */
__uint64_t gr_fp; /* file pointer */
struct end_info one_end; /* one end info */
struct end_info other_end; /* other end info. This is
* normally END_TYPE_NONE
* except for peer-to-peer
* cases.
*/
__uint64_t memloc; /* memory location */
union {
grio_resv_t gr_resv; /* grio request info */
grio_stats_t gr_stats; /* grio stats info */
} cmd_info;
int gr_bytes_bw; /* returned bandwidth */
int gr_usecs_bw; /* returned bandwidth */
int gr_time_to_wait; /* kernel wait time */
} grio_cmd_t;
/*
* Structure definitions with fields defined as known sizes.
* This is done to have a layer of abstraction between the kernel and the
* ggd daemon. The kernel can have 32 bit inumber, file sizes, and file
* system sizes, but the ggd will always view them as 64 bit quantities.
*/
typedef struct grio_file_id {
gr_ino_t ino;
dev_t fs_dev;
pid_t procid;
__uint64_t fp;
} grio_file_id_t;
typedef struct grio_disk_id {
int num_iops;
int opt_io_size;
time_t iops_time;
} grio_disk_id_t;
typedef struct grio_bmbt_irec {
__uint64_t br_startoff;
__uint64_t br_startblock;
__uint64_t br_blockcount;
} grio_bmbt_irec_t;
/*
* defines for the gr_cmd field.
*/
#define GRIO_UNKNOWN 0
#define GRIO_RESV 1
#define GRIO_UNRESV 2
#define GRIO_UNRESV_ASYNC 3
#define GRIO_PURGE_VDEV_ASYNC 4
#define GRIO_GET_STATS 5
#define GRIO_GET_BW 6
#define GRIO_GET_FILE_RESVD_BW 7
#define GRIO_ACTIVE_COMMANDS GRIO_GET_FILE_RESVD_BW + 1
#define GRIO_MAX_COMMANDS 20
#define GRIO_ASYNC_CMD(griocp) \
(( (griocp)->gr_cmd == GRIO_UNRESV_ASYNC ) || \
( (griocp)->gr_cmd == GRIO_PURGE_VDEV_ASYNC) )
#define GRIO_STATS_REQ(grioreq) \
( (grioreq)->gr_cmd == GRIO_GET_STATS )
#define GRIO_GET_RESV_DATA( griocp ) (&(griocp->cmd_info.gr_resv))
#define GRIO_GET_STATS_DATA( griocp ) (&(griocp->cmd_info.gr_stats))
/*
* syssgi SGI_GRIO commands
*/
#define GRIO_ADD_DISK_INFO 21
#define GRIO_UPDATE_DISK_INFO 22
#define GRIO_ADD_STREAM_INFO 23
#define GRIO_ADD_STREAM_DISK_INFO 24
#define GRIO_ASSOCIATE_FILE_WITH_STREAM 25
#define GRIO_REMOVE_STREAM_INFO 26
#define GRIO_REMOVE_ALL_STREAMS_INFO 27
#define GRIO_GET_FILE_EXTENTS 28
#define GRIO_GET_FS_BLOCK_SIZE 29
#define GRIO_GET_FILE_RT 30
#define GRIO_WRITE_GRIO_REQ 31
#define GRIO_READ_GRIO_REQ 32
#define GRIO_WRITE_GRIO_RESP 33
#define GRIO_GET_STREAM_ID 34
#define GRIO_GET_ALL_STREAMS 35
#define GRIO_GET_VOD_DISK_INFO 36
#define GRIO_MONITOR_START 37
#define GRIO_MONITOR_GET 38
#define GRIO_MONITOR_END 39
#define GRIO_READ_NUM_CMDS 40
#define GRIO_GET_HWGRAPH_PATH 41
#define GRIO_GET_MLD_CNODE 42
#define GRIO_GET_FP 43
#define GRIO_DISSOCIATE_STREAM 44
#define COPY_STREAM_ID(from, to) ( bcopy(&(from),&(to), sizeof(uuid_t)) )
#define EQUAL_STREAM_ID(one, two) ( uuid_equal( &one, &two, &status) )
#define SET_GRIO_IOPRI(bp, iopri) BUF_GRIO_PRIVATE(bp)->grio_iopri = iopri
#define GET_GRIO_IOPRI(bp, iopri) iopri = BUF_GRIO_PRIVATE(bp)->grio_iopri
typedef struct grio_add_disk_info_struct {
dev_t gdev;
int num_iops_rsv;
int num_iops_max;
int opt_io_size;
int rotation_slot;
int realtime_disk;
} grio_add_disk_info_struct_t;
typedef struct grio_stream_stat {
stream_id_t stream_id;
gr_ino_t ino;
dev_t fs_dev;
pid_t procid;
} grio_stream_stat_t;
typedef struct grio_vod_info {
int num_rotor_slots;
int rotor_position;
int num_rotor_streams;
int num_nonrotor_streams;
int rotor_slot[MAX_ROTOR_SLOTS];
} grio_vod_info_t;
#ifdef __KERNEL__
/*
* Kernel buffer scheduling structure.
*/
/*
* grio disk information
* the kernel allocates and maintains one such structure for
* each disk used by the grio subsystem
*/
typedef struct grio_disk_info {
int num_iops_max;
int num_iops_rsv;
int opt_io_size;
int active;
lock_t lock;
struct grio_stream_disk_info *diskstreams;
int ops_issued;
int ops_complete;
int subops_issued;
int subops_complete;
int rotate_position;
int realtime_disk;
time_t time_start;
int opcount;
time_t reset_time;
time_t timeout_time;
toid_t timeout_id;
dev_t diskdev;
} grio_disk_info_t;
/*
* grio disk information used by grioidbg for global op
*/
typedef struct grio_idbg_disk_info {
grio_disk_info_t *griodp_ptr;
struct grio_idbg_disk_info *next;
} grio_idbg_disk_info_t;
#define GRIO_STREAM_TABLE_SIZE 50
#define GRIO_STREAM_TABLE_INDEX( id ) ( (id / 8) % GRIO_STREAM_TABLE_SIZE )
/*
* grio stream information
* the kernel allocates and maintains one such structure for
* each active grio stream
*/
typedef struct grio_stream_info {
struct grio_stream_info *nextstream;
struct grio_stream_disk_info *diskstreams;
lock_t lock;
stream_id_t stream_id;
__uint64_t fp;
pid_t procid;
gr_ino_t ino;
dev_t fs_dev;
int flags;
int total_slots;
int max_count_per_slot;
int rotate_slot;
time_t last_stream_op;
} grio_stream_info_t;
/*
* Macros to access the per stream flags.
*/
#define MARK_STREAM_AS_BEING_REMOVED(griosp) \
(griosp->flags |= STREAM_REMOVE_IN_PROGRESS)
#define MARK_STREAM_AS_INITIATING_IO(griosp) \
(griosp->flags |= STREAM_INITIATE_IN_PROGRESS)
#define CLEAR_STREAM_AS_INITIATING_IO(griosp) \
(griosp->flags &= ~STREAM_INITIATE_IN_PROGRESS)
#define STREAM_BEING_REMOVED(griosp) \
(griosp->flags & STREAM_REMOVE_IN_PROGRESS)
#define STREAM_INITIATE_IO(griosp) \
(griosp->flags & STREAM_INITIATE_IN_PROGRESS)
#define PER_FILE_SYS_STREAM(griosp) \
(griosp->flags & PER_FILE_SYS_GUAR)
#define PER_FILE_STREAM(griosp) \
(griosp->flags & PER_FILE_GUAR)
#define FIXED_ROTOR_STREAM( griosp ) \
(griosp->flags & FIXED_ROTOR_GUAR)
#define SLIP_ROTOR_STREAM( griosp ) \
(griosp->flags & SLIP_ROTOR_GUAR)
#define ROTOR_STREAM(griosp) \
(FIXED_ROTOR_STREAM( griosp) || SLIP_ROTOR_STREAM(griosp))
#define NON_ROTOR_STREAM(griosp) \
(griosp->flags & NON_ROTOR_GUAR)
#define RT_SCHED_STREAM(griosp) \
(griosp->flags & REALTIME_SCHED_GUAR)
#define NS_SCHED_STREAM(griosp) \
(griosp->flags & NON_SCHED_GUAR)
#define SLIPPED_ONCE_STREAM(griosp) \
(griosp->flags & STREAM_SLIPPED_ONCE)
#define MARK_SLIPPED_ONCE_STREAM(griosp) \
(griosp->flags |= STREAM_SLIPPED_ONCE)
#define CLEAR_SLIPPED_ONCE_STREAM(griosp) \
(griosp->flags &= ~STREAM_SLIPPED_ONCE)
#define MARK_STREAM_AS_ASSOCIATED(griosp) \
(griosp->flags |= STREAM_ASSOCIATED)
#define MARK_STREAM_AS_DISSOCIATED(griosp) \
(griosp->flags &= ~STREAM_ASSOCIATED)
#define STREAM_IS_ASSOCIATED(griosp) \
(griosp->flags & STREAM_ASSOCIATED)
/*
* per disk stream information
* the kernel allocates and maintaines one such structure for
* each (stream id, disk used by that stream) pair.
*/
typedef struct grio_stream_disk_info {
struct grio_stream_disk_info *nextdiskinstream;
grio_stream_info_t *thisstream;
struct grio_stream_disk_info *nextstream;
grio_disk_info_t *griodp;
lock_t lock; /* lock to protect structure */
time_t period_end; /* time current period will end */
time_t iops_time; /* length of period for this stream */
xfs_buf_t *realbp; /* orignal bp from xlv for this request */
xfs_buf_t *bp_list; /* list of sub bps for this request */
xfs_buf_t *issued_bp_list; /* list of issued sub bps for this request */
xfs_buf_t *queuedbps_front; /* ptrs to queue of bps using this */
xfs_buf_t *queuedbps_back; /* stream id */
int iops_remaining_this_period; /* num grios left for this req this prd */
time_t time_priority_start;
time_t last_op_time; /* time last out of band op */
int num_iops; /* num grios for this req this period */
int opt_io_size; /* size of grio request */
} grio_stream_disk_info_t;
/* This structure defines a linked list of rate guaranteed requests which
* have been issued by clients but not yet satisfied by the daemon.
*/
typedef struct grio_cmd_queue {
sema_t sema;
int num_cmds;
grio_cmd_t *griocmd;
struct grio_cmd_queue *forw;
struct grio_cmd_queue *back;
} grio_cmd_queue_t;
#define GRIO_NONGUARANTEED_STREAM(griosp) \
( EQUAL_STREAM_ID( griosp->stream_id, non_guaranteed_id ) )
/*
* Private data attached to the buffer structures.
* This structure may NOT contain any data unique specific to a
* per disk I/O request. It is common to all the bps generated from
* a single user I/O request.
*/
typedef struct grio_buf_data {
uuid_t grio_id; /* stream id of stream associated */
short grio_iopri; /* priority of the io, b_iopri */
#ifdef GRIO_DEBUG /* with this I/O request */
time_t start_time;
time_t enter_queue_time;
#endif
} grio_buf_data_t;
#ifdef GRIO_DEBUG
#define INIT_GRIO_TIMESTAMP( bp ) { \
if ( BUF_IS_GRIO( bp ) ) { \
BUF_GRIO_PRIVATE(bp)->start_time = lbolt; \
} \
}
#define CHECK_GRIO_TIMESTAMP( bp, maxtime ) { \
if ( BUF_IS_GRIO( bp ) ) { \
if ((lbolt - BUF_GRIO_PRIVATE(bp)->start_time) > maxtime) {\
printf("GRIO TIMESTAMP %d TICKS: file %s, line %d\n", \
lbolt - BUF_GRIO_PRIVATE(bp)->start_time,\
__FILE__,__LINE__); \
} \
} \
}
#else
#define INIT_GRIO_TIMESTAMP( bp )
#define CHECK_GRIO_TIMESTAMP( bp, maxtime )
#endif
#define BUF_GRIO_PRIVATE(bp) ((grio_buf_data_t *)((bp)->b_grio_private))
/*
* Global lock and unlock macros
*/
#define GRIO_GLOB_LOCK() mutex_spinlock(&grio_global_lock)
#define GRIO_GLOB_UNLOCK(s) mutex_spinunlock(&grio_global_lock, s)
#define GRIO_STABLE_LOCK() mutex_spinlock(&grio_stream_table_lock)
#define GRIO_STABLE_UNLOCK(s) \
mutex_spinunlock(&grio_stream_table_lock, s)
#define GRIO_DISK_LOCK(griodp) mutex_spinlock(&griodp->lock)
#define GRIO_DISK_UNLOCK(griodp,s) mutex_spinunlock(&griodp->lock, s)
#define GRIO_STREAM_LOCK(griosp) mutex_spinlock(&griosp->lock)
#define GRIO_STREAM_UNLOCK(griosp,s) mutex_spinunlock(&griosp->lock, s)
#define GRIO_STREAM_DISK_LOCK(griosdp) mutex_spinlock(&griosdp->lock)
#define GRIO_STREAM_DISK_UNLOCK(griosdp,s) mutex_spinunlock(&griosdp->lock,s)
/* Function to convert the device number to an pointer to
* structure containing grio_info
*/
grio_disk_info_t *grio_disk_info(dev_t gdev);
/*
* Macros to set or clear the bits in the b_flags field of the buf structure.
*/
#define BUF_IS_GRIO( bp ) (XFS_BUF_BFLAGS(bp) & B_GR_BUF)
#define BUF_IS_GRIO_ISSUED( bp ) (XFS_BUF_BFLAGS(bp) & B_GR_ISD)
#define CLR_BUF_GRIO_ISSUED(bp) (XFS_BUF_BFLAGS(bp) &= ~B_GR_ISD)
#define MARK_BUF_GRIO_ISSUED(bp) (XFS_BUF_BFLAGS(bp) |= B_GR_ISD)
#ifdef DEBUG
#define dbg1printf(_x) if (grio_dbg_level > 1 ) { printf _x ; }
#define dbg2printf(_x) if (grio_dbg_level > 2 ) { printf _x ; }
#define dbg3printf(_x) if (grio_dbg_level > 3 ) { printf _x ; }
#else
#define dbg1printf(_x)
#define dbg2printf(_x)
#define dbg3printf(_x)
#endif
#endif /* __KERNEL__ */
#define GRIO_MONITOR_COUNT 100
typedef struct grio_monitor_times {
time_t starttime;
time_t endtime;
__int64_t size;
} grio_monitor_times_t;
typedef struct grio_monitor {
grio_monitor_times_t times[GRIO_MONITOR_COUNT];
int start_index;
int end_index;
stream_id_t stream_id;
int monitoring;
} grio_monitor_t;
/*
* syssgi GRIO_GET_HWGRAPH_PATH returns an array of these structures.
* The class and type are akin to inventory records. For hardware
* components which do not have actual inventory records associated
* with the hwgfs vertices, grio determines the class, type and state
* fields. This structure can be extended to return unit/controller etc.
*/
typedef struct grio_dev_info {
int grio_dev_class;
int grio_dev_type;
int grio_dev_state;
dev_t devnum;
} grio_dev_info_t;
typedef struct grio_ioctl_info {
vertex_hdl_t prev_vhdl;
vertex_hdl_t next_vhdl;
unsigned long long reqbw;
} grio_ioctl_info_t;
#ifdef __KERNEL__
void xfs_grio_init(void);
void xfs_grio_uninit(void);
int grio_io_is_guaranteed(struct file *fp, stream_id_t *stream_id);
int grio_monitor_start(sysarg_t );
int grio_monitor_io_start(stream_id_t *stream_id, __int64_t iosize);
int grio_monitor_io_end(stream_id_t *stream_id, int index );
int grio_strategy(xfs_buf_t *);
int grio_config(sysarg_t, sysarg_t, sysarg_t, sysarg_t, sysarg_t );
void grio_iodone(xfs_buf_t *);
/* Function to convert the device number to an pointer to
* structure containing grio_info
*/
grio_disk_info_t *grio_disk_info(dev_t gdev);
#endif /* __KERNEL__ */
#endif /* __XFS_GRIO_H__ */