io.d revision 236628
1236628Sgnn/*
2236628Sgnn * CDDL HEADER START
3236628Sgnn *
4236628Sgnn * The contents of this file are subject to the terms of the
5236628Sgnn * Common Development and Distribution License (the "License").
6236628Sgnn * You may not use this file except in compliance with the License.
7236628Sgnn *
8236628Sgnn * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9236628Sgnn * or http://www.opensolaris.org/os/licensing.
10236628Sgnn * See the License for the specific language governing permissions
11236628Sgnn * and limitations under the License.
12236628Sgnn *
13236628Sgnn * When distributing Covered Code, include this CDDL HEADER in each
14236628Sgnn * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15236628Sgnn * If applicable, add the following below this CDDL HEADER, with the
16236628Sgnn * fields enclosed by brackets "[]" replaced with your own identifying
17236628Sgnn * information: Portions Copyright [yyyy] [name of copyright owner]
18236628Sgnn *
19236628Sgnn * CDDL HEADER END
20236628Sgnn *
21236628Sgnn * $FreeBSD: head/cddl/lib/libdtrace/io.d 236628 2012-06-05 18:58:05Z gnn $
22236628Sgnn */
23236628Sgnn/*
24236628Sgnn * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
25236628Sgnn * Use is subject to license terms.
26236628Sgnn */
27236628Sgnn
28236628Sgnn#pragma ident	"%Z%%M%	%I%	%E% SMI"
29236628Sgnn
30236628Sgnn#pragma D depends_on module unix
31236628Sgnn#pragma D depends_on provider io
32236628Sgnn
33236628Sgnninline int B_BUSY = B_BUSY;
34236628Sgnn#pragma D binding "1.0" B_BUSY
35236628Sgnninline int B_DONE = 0x00000200;
36236628Sgnn#pragma D binding "1.0" B_DONE
37236628Sgnninline int B_ERROR = B_ERROR;
38236628Sgnn#pragma D binding "1.0" B_ERROR
39236628Sgnninline int B_PAGEIO = B_PAGEIO;
40236628Sgnn#pragma D binding "1.0" B_PAGEIO
41236628Sgnninline int B_PHYS = B_PHYS;
42236628Sgnn#pragma D binding "1.0" B_PHYS
43236628Sgnninline int B_READ = B_READ;
44236628Sgnn#pragma D binding "1.0" B_READ
45236628Sgnninline int B_WRITE = B_WRITE;
46236628Sgnn#pragma D binding "1.0" B_WRITE
47236628Sgnninline int B_ASYNC = 0x00000004;
48236628Sgnn#pragma D binding "1.0" B_ASYNC
49236628Sgnn
50236628Sgnntypedef struct bufinfo {
51236628Sgnn	int b_flags;			/* buffer status */
52236628Sgnn	size_t b_bcount;		/* number of bytes */
53236628Sgnn	caddr_t b_addr;			/* buffer address */
54236628Sgnn	uint64_t b_lblkno;		/* block # on device */
55236628Sgnn	uint64_t b_blkno;		/* expanded block # on device */
56236628Sgnn	size_t b_resid;			/* # of bytes not transferred */
57236628Sgnn	size_t b_bufsize;		/* size of allocated buffer */
58236628Sgnn	caddr_t b_iodone;		/* I/O completion routine */
59236628Sgnn	int b_error;			/* expanded error field */
60236628Sgnn	dev_t b_edev;			/* extended device */
61236628Sgnn} bufinfo_t;
62236628Sgnn
63236628Sgnn#pragma D binding "1.0" translator
64236628Sgnntranslator bufinfo_t < struct buf *B > {
65236628Sgnn	b_flags = B->b_flags;
66236628Sgnn	b_addr = B->b_un.b_addr;
67236628Sgnn	b_bcount = B->b_bcount;
68236628Sgnn	b_lblkno = B->_b_blkno._f;
69236628Sgnn	b_blkno = sizeof (long) == 8 ? B->_b_blkno._f : B->_b_blkno._p._l;
70236628Sgnn	b_resid = B->b_resid;
71236628Sgnn	b_bufsize = B->b_bufsize;
72236628Sgnn	b_iodone = (caddr_t)B->b_iodone;
73236628Sgnn	b_error = B->b_error;
74236628Sgnn	b_edev = B->b_edev;
75236628Sgnn};
76236628Sgnn
77236628Sgnntypedef struct devinfo {
78236628Sgnn	int dev_major;			/* major number */
79236628Sgnn	int dev_minor;			/* minor number */
80236628Sgnn	int dev_instance;		/* instance number */
81236628Sgnn	string dev_name;		/* name of device */
82236628Sgnn	string dev_statname;		/* name of device + instance/minor */
83236628Sgnn	string dev_pathname;		/* pathname of device */
84236628Sgnn} devinfo_t;
85236628Sgnn
86236628Sgnn#pragma D binding "1.0" translator
87236628Sgnntranslator devinfo_t < struct buf *B > {
88236628Sgnn	dev_major = B->b_dip != NULL ? getmajor(B->b_edev) :
89236628Sgnn	    getmajor(B->b_file->v_vfsp->vfs_dev);
90236628Sgnn	dev_minor = B->b_dip != NULL ? getminor(B->b_edev) :
91236628Sgnn	    getminor(B->b_file->v_vfsp->vfs_dev);
92236628Sgnn	dev_instance = B->b_dip == NULL ?
93236628Sgnn	    getminor(B->b_file->v_vfsp->vfs_dev) :
94236628Sgnn	    ((struct dev_info *)B->b_dip)->devi_instance;
95236628Sgnn	dev_name = B->b_dip == NULL ? "nfs" :
96236628Sgnn	    stringof(`devnamesp[getmajor(B->b_edev)].dn_name);
97236628Sgnn	dev_statname = strjoin(B->b_dip == NULL ? "nfs" :
98236628Sgnn	    stringof(`devnamesp[getmajor(B->b_edev)].dn_name),
99236628Sgnn	    lltostr(B->b_dip == NULL ? getminor(B->b_file->v_vfsp->vfs_dev) :
100236628Sgnn	    ((struct dev_info *)B->b_dip)->devi_instance == 0 &&
101236628Sgnn	    ((struct dev_info *)B->b_dip)->devi_parent != NULL &&
102236628Sgnn	    ((struct dev_info *)B->b_dip)->devi_parent->devi_node_name ==
103236628Sgnn	    "pseudo" ? getminor(B->b_edev) :
104236628Sgnn	    ((struct dev_info *)B->b_dip)->devi_instance));
105236628Sgnn	dev_pathname = B->b_dip == NULL ? "<nfs>" :
106236628Sgnn	    ddi_pathname(B->b_dip, getminor(B->b_edev));
107236628Sgnn};
108236628Sgnn
109236628Sgnntypedef struct fileinfo {
110236628Sgnn	string fi_name;			/* name (basename of fi_pathname) */
111236628Sgnn	string fi_dirname;		/* directory (dirname of fi_pathname) */
112236628Sgnn	string fi_pathname;		/* full pathname */
113236628Sgnn	offset_t fi_offset;		/* offset within file */
114236628Sgnn	string fi_fs;			/* filesystem */
115236628Sgnn	string fi_mount;		/* mount point of file system */
116236628Sgnn	int fi_oflags;			/* open(2) flags for file descriptor */
117236628Sgnn} fileinfo_t;
118236628Sgnn
119236628Sgnn#pragma D binding "1.0" translator
120236628Sgnntranslator fileinfo_t < struct buf *B > {
121236628Sgnn	fi_name = B->b_file == NULL ? "<none>" :
122236628Sgnn	    B->b_file->v_path == NULL ? "<unknown>" :
123236628Sgnn	    basename(cleanpath(B->b_file->v_path));
124236628Sgnn	fi_dirname = B->b_file == NULL ? "<none>" :
125236628Sgnn	    B->b_file->v_path == NULL ? "<unknown>" :
126236628Sgnn	    dirname(cleanpath(B->b_file->v_path));
127236628Sgnn	fi_pathname = B->b_file == NULL ? "<none>" :
128236628Sgnn	    B->b_file->v_path == NULL ? "<unknown>" :
129236628Sgnn	    cleanpath(B->b_file->v_path);
130236628Sgnn	fi_offset = B->b_offset;
131236628Sgnn	fi_fs = B->b_file == NULL ? "<none>" :
132236628Sgnn	    stringof(B->b_file->v_op->vnop_name);
133236628Sgnn	fi_mount = B->b_file == NULL ? "<none>" :
134236628Sgnn	    B->b_file->v_vfsp->vfs_vnodecovered == NULL ? "/" :
135236628Sgnn	    B->b_file->v_vfsp->vfs_vnodecovered->v_path == NULL ? "<unknown>" :
136236628Sgnn	    cleanpath(B->b_file->v_vfsp->vfs_vnodecovered->v_path);
137236628Sgnn	fi_oflags = 0;
138236628Sgnn};
139236628Sgnn
140236628Sgnn/*
141236628Sgnn * The following inline constants can be used to examine fi_oflags when using
142236628Sgnn * the fds[] array or a translated fileinfo_t.  Note that the various open
143236628Sgnn * flags behave as a bit-field *except* for O_RDONLY, O_WRONLY, and O_RDWR.
144236628Sgnn * To test the open mode, you write code similar to that used with the fcntl(2)
145236628Sgnn * F_GET[X]FL command, such as: if ((fi_oflags & O_ACCMODE) == O_WRONLY).
146236628Sgnn */
147236628Sgnninline int O_ACCMODE = 0x0003;
148236628Sgnn#pragma D binding "1.1" O_ACCMODE
149236628Sgnn
150236628Sgnninline int O_RDONLY = 0x0000;
151236628Sgnn#pragma D binding "1.1" O_RDONLY
152236628Sgnninline int O_WRONLY = 0x0001;
153236628Sgnn#pragma D binding "1.1" O_WRONLY
154236628Sgnninline int O_RDWR = 0x0002;
155236628Sgnn#pragma D binding "1.1" O_RDWR
156236628Sgnn
157236628Sgnninline int O_APPEND = 0x0008;
158236628Sgnn#pragma D binding "1.1" O_APPEND
159236628Sgnninline int O_CREAT = 0x0200;
160236628Sgnn#pragma D binding "1.1" O_CREAT
161236628Sgnninline int O_DSYNC = O_DSYNC;
162236628Sgnn#pragma D binding "1.1" O_DSYNC
163236628Sgnninline int O_EXCL = 0x0800;
164236628Sgnn#pragma D binding "1.1" O_EXCL
165236628Sgnninline int O_LARGEFILE = O_LARGEFILE;
166236628Sgnn#pragma D binding "1.1" O_LARGEFILE
167236628Sgnninline int O_NOCTTY = 0x8000;
168236628Sgnn#pragma D binding "1.1" O_NOCTTY
169236628Sgnninline int O_NONBLOCK = 0x0004;
170236628Sgnn#pragma D binding "1.1" O_NONBLOCK
171236628Sgnninline int O_NDELAY = 0x0004;
172236628Sgnn#pragma D binding "1.1" O_NDELAY
173236628Sgnninline int O_RSYNC = O_RSYNC;
174236628Sgnn#pragma D binding "1.1" O_RSYNC
175236628Sgnninline int O_SYNC = 0x0080;
176236628Sgnn#pragma D binding "1.1" O_SYNC
177236628Sgnninline int O_TRUNC = 0x0400;
178236628Sgnn#pragma D binding "1.1" O_TRUNC
179236628Sgnninline int O_XATTR = O_XATTR;
180236628Sgnn#pragma D binding "1.1" O_XATTR
181236628Sgnn
182236628Sgnn#pragma D binding "1.1" translator
183236628Sgnntranslator fileinfo_t < struct file *F > {
184236628Sgnn	fi_name = F == NULL ? "<none>" :
185236628Sgnn	    F->f_vnode->v_path == NULL ? "<unknown>" :
186236628Sgnn	    basename(cleanpath(F->f_vnode->v_path));
187236628Sgnn	fi_dirname = F == NULL ? "<none>" :
188236628Sgnn	    F->f_vnode->v_path == NULL ? "<unknown>" :
189236628Sgnn	    dirname(cleanpath(F->f_vnode->v_path));
190236628Sgnn	fi_pathname = F == NULL ? "<none>" :
191236628Sgnn	    F->f_vnode->v_path == NULL ? "<unknown>" :
192236628Sgnn	    cleanpath(F->f_vnode->v_path);
193236628Sgnn	fi_offset = F == NULL ? 0 : F->f_offset;
194236628Sgnn	fi_fs = F == NULL ? "<none>" : stringof(F->f_vnode->v_op->vnop_name);
195236628Sgnn	fi_mount = F == NULL ? "<none>" :
196236628Sgnn	    F->f_vnode->v_vfsp->vfs_vnodecovered == NULL ? "/" :
197236628Sgnn	    F->f_vnode->v_vfsp->vfs_vnodecovered->v_path == NULL ? "<unknown>" :
198236628Sgnn	    cleanpath(F->f_vnode->v_vfsp->vfs_vnodecovered->v_path);
199236628Sgnn	fi_oflags = F == NULL ? 0 : F->f_flag + (int)FOPEN;
200236628Sgnn};
201236628Sgnn
202236628Sgnninline fileinfo_t fds[int fd] = xlate <fileinfo_t> (
203236628Sgnn    fd >= 0 && fd < curthread->t_procp->p_user.u_finfo.fi_nfiles ?
204236628Sgnn    curthread->t_procp->p_user.u_finfo.fi_list[fd].uf_file : NULL);
205236628Sgnn
206236628Sgnn#pragma D attributes Stable/Stable/Common fds
207236628Sgnn#pragma D binding "1.1" fds
208236628Sgnn
209236628Sgnn#pragma D binding "1.2" translator
210236628Sgnntranslator fileinfo_t < struct vnode *V > {
211236628Sgnn	fi_name = V->v_path == NULL ? "<unknown>" :
212236628Sgnn	    basename(cleanpath(V->v_path));
213236628Sgnn	fi_dirname = V->v_path == NULL ? "<unknown>" :
214236628Sgnn	    dirname(cleanpath(V->v_path));
215236628Sgnn	fi_pathname = V->v_path == NULL ? "<unknown>" : cleanpath(V->v_path);
216236628Sgnn	fi_fs = stringof(V->v_op->vnop_name);
217236628Sgnn	fi_mount = V->v_vfsp->vfs_vnodecovered == NULL ? "/" :
218236628Sgnn	    V->v_vfsp->vfs_vnodecovered->v_path == NULL ? "<unknown>" :
219236628Sgnn	    cleanpath(V->v_vfsp->vfs_vnodecovered->v_path);
220236628Sgnn};
221