xref: /titanic_51/usr/src/uts/common/fs/arcflush/arcflush.c (revision 96bfc24987844f362c994e18365c96d423d5759f)
1*21b926adSArne Jansen #include <sys/modctl.h>
2*21b926adSArne Jansen #include <sys/ddi.h>
3*21b926adSArne Jansen #include <sys/sunddi.h>
4*21b926adSArne Jansen #include <sys/devops.h>
5*21b926adSArne Jansen #include <sys/conf.h>
6*21b926adSArne Jansen #include <sys/cpuvar.h>
7*21b926adSArne Jansen #include <sys/kobj.h>
8*21b926adSArne Jansen #include <sys/spa.h>
9*21b926adSArne Jansen #include <sys/arc.h>
10*21b926adSArne Jansen #include <sys/vfs.h>
11*21b926adSArne Jansen #include <sys/dnlc.h>
12*21b926adSArne Jansen 
13*21b926adSArne Jansen static dev_info_t *arcflushdevi;
14*21b926adSArne Jansen 
15*21b926adSArne Jansen #define	FTAG ((char *)(uintptr_t)__func__)
16*21b926adSArne Jansen 
17*21b926adSArne Jansen static int arcflushioctl(dev_t dev, int cmd, intptr_t arg, int mode,
18*21b926adSArne Jansen     cred_t *credp, int *rvalp);
19*21b926adSArne Jansen static int arcflushclose(dev_t dev, int flag, int otyp, cred_t *crepd);
20*21b926adSArne Jansen static int arcflushopen(dev_t *devp, int flag, int otyp, cred_t *credp);
21*21b926adSArne Jansen 
22*21b926adSArne Jansen static struct cb_ops    arcflush_cb_ops = {
23*21b926adSArne Jansen 	arcflushopen,		/* open */
24*21b926adSArne Jansen 	arcflushclose,		/* close */
25*21b926adSArne Jansen 	nodev,			/* strategy */
26*21b926adSArne Jansen 	nodev,			/* print */
27*21b926adSArne Jansen 	nodev,			/* dump */
28*21b926adSArne Jansen 	nodev,			/* read */
29*21b926adSArne Jansen 	nodev,			/* write */
30*21b926adSArne Jansen 	arcflushioctl,		/* ioctl */
31*21b926adSArne Jansen 	nodev,			/* devmap */
32*21b926adSArne Jansen 	nodev,			/* mmap */
33*21b926adSArne Jansen 	nodev,			/* segmap */
34*21b926adSArne Jansen 	nochpoll,		/* poll */
35*21b926adSArne Jansen 	ddi_prop_op,		/* prop_op */
36*21b926adSArne Jansen 	(struct streamtab *)0,	/* streamtab */
37*21b926adSArne Jansen 	D_NEW | D_64BIT | D_MP,	/* flags */
38*21b926adSArne Jansen 	CB_REV,
39*21b926adSArne Jansen 	nodev,
40*21b926adSArne Jansen 	nodev
41*21b926adSArne Jansen };
42*21b926adSArne Jansen 
43*21b926adSArne Jansen static int arcflushattach(dev_info_t *, ddi_attach_cmd_t);
44*21b926adSArne Jansen static int arcflushdetach(dev_info_t *, ddi_detach_cmd_t);
45*21b926adSArne Jansen static int arcflushinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
46*21b926adSArne Jansen 
47*21b926adSArne Jansen static struct dev_ops arcflush_ops = {
48*21b926adSArne Jansen 	DEVO_REV,		/* devo_rev */
49*21b926adSArne Jansen 	0,			/* refcnt */
50*21b926adSArne Jansen 	arcflushinfo,		/* info */
51*21b926adSArne Jansen 	nulldev,		/* identify */
52*21b926adSArne Jansen 	nulldev,		/* probe */
53*21b926adSArne Jansen 	arcflushattach,		/* attach */
54*21b926adSArne Jansen 	arcflushdetach,		/* detach */
55*21b926adSArne Jansen 	nodev,			/* reset */
56*21b926adSArne Jansen 	&arcflush_cb_ops,	/* driver operations */
57*21b926adSArne Jansen 	(struct bus_ops *)NULL, /* bus operations */
58*21b926adSArne Jansen 	NULL			/* power */
59*21b926adSArne Jansen };
60*21b926adSArne Jansen 
61*21b926adSArne Jansen static struct modldrv modldrv = {
62*21b926adSArne Jansen 	&mod_driverops,		/* type of module - a driver */
63*21b926adSArne Jansen 	"arcflush driver",
64*21b926adSArne Jansen 	&arcflush_ops,
65*21b926adSArne Jansen };
66*21b926adSArne Jansen 
67*21b926adSArne Jansen static struct modlinkage modlinkage = {
68*21b926adSArne Jansen 	MODREV_1,
69*21b926adSArne Jansen 	{ (void *)&modldrv, NULL }
70*21b926adSArne Jansen };
71*21b926adSArne Jansen 
72*21b926adSArne Jansen int
73*21b926adSArne Jansen _init()
74*21b926adSArne Jansen {
75*21b926adSArne Jansen 	int error = mod_install(&modlinkage);
76*21b926adSArne Jansen 	return (error);
77*21b926adSArne Jansen }
78*21b926adSArne Jansen 
79*21b926adSArne Jansen int
80*21b926adSArne Jansen _fini()
81*21b926adSArne Jansen {
82*21b926adSArne Jansen 	int error;
83*21b926adSArne Jansen 
84*21b926adSArne Jansen 	error = mod_remove(&modlinkage);
85*21b926adSArne Jansen 	return (error);
86*21b926adSArne Jansen }
87*21b926adSArne Jansen 
88*21b926adSArne Jansen int
89*21b926adSArne Jansen _info(struct modinfo *modinfop)
90*21b926adSArne Jansen {
91*21b926adSArne Jansen 	int error;
92*21b926adSArne Jansen 
93*21b926adSArne Jansen 	error = mod_info(&modlinkage, modinfop);
94*21b926adSArne Jansen 	return error;
95*21b926adSArne Jansen }
96*21b926adSArne Jansen 
97*21b926adSArne Jansen static int
98*21b926adSArne Jansen arcflushclose(dev_t dev, int flag, int otyp, cred_t *crepd)
99*21b926adSArne Jansen {
100*21b926adSArne Jansen 	if (otyp != OTYP_CHR)
101*21b926adSArne Jansen 		return (EINVAL);
102*21b926adSArne Jansen 
103*21b926adSArne Jansen 	return (0);
104*21b926adSArne Jansen }
105*21b926adSArne Jansen 
106*21b926adSArne Jansen static int
107*21b926adSArne Jansen arcflushopen(dev_t *devp, int flag, int otyp, cred_t *credp)
108*21b926adSArne Jansen {
109*21b926adSArne Jansen 	if (otyp != OTYP_CHR)
110*21b926adSArne Jansen 		return (EINVAL);
111*21b926adSArne Jansen 	if (drv_priv(credp) != 0)
112*21b926adSArne Jansen 		return (EPERM);
113*21b926adSArne Jansen 
114*21b926adSArne Jansen 	return (0);
115*21b926adSArne Jansen }
116*21b926adSArne Jansen 
117*21b926adSArne Jansen static int
118*21b926adSArne Jansen arcflushioctl(dev_t dev, int cmd, intptr_t arg, int mode,
119*21b926adSArne Jansen     cred_t *credp, int *rvalp)
120*21b926adSArne Jansen {
121*21b926adSArne Jansen 	spa_t *spa;
122*21b926adSArne Jansen 	int ret;
123*21b926adSArne Jansen 	char name[MAXPATHLEN + 1];
124*21b926adSArne Jansen 	vfs_t *vfsp;
125*21b926adSArne Jansen 
126*21b926adSArne Jansen 	if (ddi_copyin((void *)arg, name, MAXPATHLEN, mode) != 0)
127*21b926adSArne Jansen 		return EFAULT;
128*21b926adSArne Jansen 	name[MAXPATHLEN] = 0;
129*21b926adSArne Jansen 
130*21b926adSArne Jansen 	switch (cmd) {
131*21b926adSArne Jansen 	case 0xf10053:
132*21b926adSArne Jansen 		ret = spa_open(name, &spa, FTAG);
133*21b926adSArne Jansen 		if (ret != 0)
134*21b926adSArne Jansen 			return (ret);
135*21b926adSArne Jansen 		arc_flush(spa, FALSE);
136*21b926adSArne Jansen 		spa_close(spa, FTAG);
137*21b926adSArne Jansen 		break;
138*21b926adSArne Jansen 	case 0xf10054:
139*21b926adSArne Jansen 		vfsp = vfs_mntpoint2vfsp(name);
140*21b926adSArne Jansen 		if (vfsp == NULL)
141*21b926adSArne Jansen 			return (EINVAL);
142*21b926adSArne Jansen 		dnlc_purge_vfsp(vfsp, 0);
143*21b926adSArne Jansen 		break;
144*21b926adSArne Jansen 	default:
145*21b926adSArne Jansen 		return ENOTTY;
146*21b926adSArne Jansen 	}
147*21b926adSArne Jansen 
148*21b926adSArne Jansen 	return (0);
149*21b926adSArne Jansen }
150*21b926adSArne Jansen 
151*21b926adSArne Jansen /*ARGSUSED*/
152*21b926adSArne Jansen static int
153*21b926adSArne Jansen arcflushattach(dev_info_t *devi, ddi_attach_cmd_t cmd)
154*21b926adSArne Jansen {
155*21b926adSArne Jansen 	if (cmd != DDI_ATTACH) {
156*21b926adSArne Jansen 		return (DDI_FAILURE);
157*21b926adSArne Jansen 	}
158*21b926adSArne Jansen 
159*21b926adSArne Jansen 	if (ddi_create_minor_node(devi, "arcflush", S_IFCHR, 0, DDI_PSEUDO, 0)
160*21b926adSArne Jansen 			== DDI_FAILURE) {
161*21b926adSArne Jansen 		cmn_err(CE_NOTE, "arcflushattach fail: "
162*21b926adSArne Jansen 			"ddi_create_minor_node\n");
163*21b926adSArne Jansen 		return (DDI_FAILURE);
164*21b926adSArne Jansen 	}
165*21b926adSArne Jansen 	ddi_report_dev(devi);
166*21b926adSArne Jansen 
167*21b926adSArne Jansen 	arcflushdevi = devi;
168*21b926adSArne Jansen 
169*21b926adSArne Jansen 	return (DDI_SUCCESS);
170*21b926adSArne Jansen }
171*21b926adSArne Jansen 
172*21b926adSArne Jansen static int
173*21b926adSArne Jansen arcflushdetach(dev_info_t *devi, ddi_detach_cmd_t cmd)
174*21b926adSArne Jansen {
175*21b926adSArne Jansen 	if (cmd != DDI_DETACH) {
176*21b926adSArne Jansen 		return (DDI_FAILURE);
177*21b926adSArne Jansen 	}
178*21b926adSArne Jansen 
179*21b926adSArne Jansen 	arcflushdevi = NULL;
180*21b926adSArne Jansen 
181*21b926adSArne Jansen 	ddi_prop_remove_all(devi);
182*21b926adSArne Jansen 	ddi_remove_minor_node(devi, NULL);
183*21b926adSArne Jansen 
184*21b926adSArne Jansen 	return (DDI_SUCCESS);
185*21b926adSArne Jansen }
186*21b926adSArne Jansen 
187*21b926adSArne Jansen /* ARGSUSED */
188*21b926adSArne Jansen static int
189*21b926adSArne Jansen arcflushinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
190*21b926adSArne Jansen {
191*21b926adSArne Jansen 	int error;
192*21b926adSArne Jansen 	switch (infocmd) {
193*21b926adSArne Jansen 	case DDI_INFO_DEVT2DEVINFO:
194*21b926adSArne Jansen 		*result = (void *)arcflushdevi;
195*21b926adSArne Jansen 		error = DDI_SUCCESS;
196*21b926adSArne Jansen 		break;
197*21b926adSArne Jansen 	case DDI_INFO_DEVT2INSTANCE:
198*21b926adSArne Jansen 		*result = (void *)0;
199*21b926adSArne Jansen 		error = DDI_SUCCESS;
200*21b926adSArne Jansen 		break;
201*21b926adSArne Jansen 	default:
202*21b926adSArne Jansen 		error = DDI_FAILURE;
203*21b926adSArne Jansen 	}
204*21b926adSArne Jansen 	return (error);
205*21b926adSArne Jansen }
206