Deleted Added
full compact
subr_disk.c (56767) subr_disk.c (57325)
1/*
2 * ----------------------------------------------------------------------------
3 * "THE BEER-WARE LICENSE" (Revision 42):
4 * <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you
5 * can do whatever you want with this stuff. If we meet some day, and you think
6 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
7 * ----------------------------------------------------------------------------
8 *
1/*
2 * ----------------------------------------------------------------------------
3 * "THE BEER-WARE LICENSE" (Revision 42):
4 * <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you
5 * can do whatever you want with this stuff. If we meet some day, and you think
6 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
7 * ----------------------------------------------------------------------------
8 *
9 * $FreeBSD: head/sys/kern/subr_disk.c 56767 2000-01-28 20:49:43Z phk $
9 * $FreeBSD: head/sys/kern/subr_disk.c 57325 2000-02-18 20:57:33Z sos $
10 *
11 */
12
13#include <sys/param.h>
14#include <sys/systm.h>
15#include <sys/kernel.h>
16#include <sys/sysctl.h>
17#include <sys/buf.h>
18#include <sys/conf.h>
19#include <sys/disk.h>
20#include <sys/malloc.h>
21#include <machine/md_var.h>
22
23MALLOC_DEFINE(M_DISK, "disk", "disk data");
24
25static d_strategy_t diskstrategy;
26static d_open_t diskopen;
27static d_close_t diskclose;
28static d_ioctl_t diskioctl;
29static d_psize_t diskpsize;
30
31dev_t
32disk_create(int unit, struct disk *dp, int flags, struct cdevsw *cdevsw, struct cdevsw *proto)
33{
34 dev_t dev;
35
36 bzero(dp, sizeof(*dp));
37
38 dev = makedev(cdevsw->d_maj, 0);
39 if (!devsw(dev)) {
40 *proto = *cdevsw;
41 proto->d_open = diskopen;
42 proto->d_close = diskclose;
43 proto->d_ioctl = diskioctl;
44 proto->d_strategy = diskstrategy;
45 proto->d_psize = diskpsize;
46 cdevsw_add(proto);
47 }
48
49 if (bootverbose)
50 printf("Creating DISK %s%d\n", cdevsw->d_name, unit);
51 dev = make_dev(proto, dkmakeminor(unit, WHOLE_DISK_SLICE, RAW_PART),
52 0, 0, 0, "r%s%d", cdevsw->d_name, unit);
53
54 dev->si_disk = dp;
55 dp->d_dev = dev;
56 dp->d_dsflags = flags;
57 dp->d_devsw = cdevsw;
58 return (dev);
59}
60
61int
62disk_dumpcheck(dev_t dev, u_int *count, u_int *blkno, u_int *secsize)
63{
64 struct disk *dp;
65 struct disklabel *dl;
66 u_int boff;
67
68 dp = dev->si_disk;
69 if (!dp)
70 return (ENXIO);
71 if (!dp->d_slice)
72 return (ENXIO);
73 dl = dsgetlabel(dev, dp->d_slice);
74 if (!dl)
75 return (ENXIO);
76 *count = (u_long)Maxmem * PAGE_SIZE / dl->d_secsize;
77 if (dumplo < 0 ||
78 (dumplo + *count > dl->d_partitions[dkpart(dev)].p_size))
79 return (EINVAL);
80 boff = dl->d_partitions[dkpart(dev)].p_offset +
81 dp->d_slice->dss_slices[dkslice(dev)].ds_offset;
82 *blkno = boff + dumplo;
83 *secsize = dl->d_secsize;
84 return (0);
85
86}
87
88void
89disk_invalidate (struct disk *disk)
90{
10 *
11 */
12
13#include <sys/param.h>
14#include <sys/systm.h>
15#include <sys/kernel.h>
16#include <sys/sysctl.h>
17#include <sys/buf.h>
18#include <sys/conf.h>
19#include <sys/disk.h>
20#include <sys/malloc.h>
21#include <machine/md_var.h>
22
23MALLOC_DEFINE(M_DISK, "disk", "disk data");
24
25static d_strategy_t diskstrategy;
26static d_open_t diskopen;
27static d_close_t diskclose;
28static d_ioctl_t diskioctl;
29static d_psize_t diskpsize;
30
31dev_t
32disk_create(int unit, struct disk *dp, int flags, struct cdevsw *cdevsw, struct cdevsw *proto)
33{
34 dev_t dev;
35
36 bzero(dp, sizeof(*dp));
37
38 dev = makedev(cdevsw->d_maj, 0);
39 if (!devsw(dev)) {
40 *proto = *cdevsw;
41 proto->d_open = diskopen;
42 proto->d_close = diskclose;
43 proto->d_ioctl = diskioctl;
44 proto->d_strategy = diskstrategy;
45 proto->d_psize = diskpsize;
46 cdevsw_add(proto);
47 }
48
49 if (bootverbose)
50 printf("Creating DISK %s%d\n", cdevsw->d_name, unit);
51 dev = make_dev(proto, dkmakeminor(unit, WHOLE_DISK_SLICE, RAW_PART),
52 0, 0, 0, "r%s%d", cdevsw->d_name, unit);
53
54 dev->si_disk = dp;
55 dp->d_dev = dev;
56 dp->d_dsflags = flags;
57 dp->d_devsw = cdevsw;
58 return (dev);
59}
60
61int
62disk_dumpcheck(dev_t dev, u_int *count, u_int *blkno, u_int *secsize)
63{
64 struct disk *dp;
65 struct disklabel *dl;
66 u_int boff;
67
68 dp = dev->si_disk;
69 if (!dp)
70 return (ENXIO);
71 if (!dp->d_slice)
72 return (ENXIO);
73 dl = dsgetlabel(dev, dp->d_slice);
74 if (!dl)
75 return (ENXIO);
76 *count = (u_long)Maxmem * PAGE_SIZE / dl->d_secsize;
77 if (dumplo < 0 ||
78 (dumplo + *count > dl->d_partitions[dkpart(dev)].p_size))
79 return (EINVAL);
80 boff = dl->d_partitions[dkpart(dev)].p_offset +
81 dp->d_slice->dss_slices[dkslice(dev)].ds_offset;
82 *blkno = boff + dumplo;
83 *secsize = dl->d_secsize;
84 return (0);
85
86}
87
88void
89disk_invalidate (struct disk *disk)
90{
91 dsgone(&disk->d_slice);
91 if (disk->d_slice)
92 dsgone(&disk->d_slice);
92}
93
94void
95disk_destroy(dev_t dev)
96{
93}
94
95void
96disk_destroy(dev_t dev)
97{
98 dev->si_disk = NULL;
99 destroy_dev(dev);
97 return;
98}
99
100/*
101 * The cdevsw functions
102 */
103
104static int
105diskopen(dev_t dev, int oflags, int devtype, struct proc *p)
106{
107 dev_t pdev;
108 struct disk *dp;
109 int error;
110
111 error = 0;
112 pdev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), RAW_PART);
113
114 dp = pdev->si_disk;
115 if (!dp)
116 return (ENXIO);
117
118 while (dp->d_flags & DISKFLAG_LOCK) {
119 dp->d_flags |= DISKFLAG_WANTED;
120 error = tsleep(dp, PRIBIO | PCATCH, "diskopen", hz);
121 if (error)
122 return (error);
123 }
124 dp->d_flags |= DISKFLAG_LOCK;
125
126 if (!dsisopen(dp->d_slice)) {
127 if (!pdev->si_iosize_max)
128 pdev->si_iosize_max = dev->si_iosize_max;
129 error = dp->d_devsw->d_open(pdev, oflags, devtype, p);
130 }
131
132 /* Inherit properties from the whole/raw dev_t */
133 dev->si_disk = pdev->si_disk;
134 dev->si_drv1 = pdev->si_drv1;
135 dev->si_drv2 = pdev->si_drv2;
136 dev->si_iosize_max = pdev->si_iosize_max;
137 dev->si_bsize_phys = pdev->si_bsize_phys;
138 dev->si_bsize_best = pdev->si_bsize_best;
139
140 if (error)
141 goto out;
142
143 error = dsopen(dev, devtype, dp->d_dsflags, &dp->d_slice, &dp->d_label);
144
145 if (!dsisopen(dp->d_slice))
146 dp->d_devsw->d_close(pdev, oflags, devtype, p);
147out:
148 dp->d_flags &= ~DISKFLAG_LOCK;
149 if (dp->d_flags & DISKFLAG_WANTED) {
150 dp->d_flags &= ~DISKFLAG_WANTED;
151 wakeup(dp);
152 }
153
154 return(error);
155}
156
157static int
158diskclose(dev_t dev, int fflag, int devtype, struct proc *p)
159{
160 struct disk *dp;
161 int error;
162
163 error = 0;
164 dp = dev->si_disk;
165 dsclose(dev, devtype, dp->d_slice);
166 if (!dsisopen(dp->d_slice)) {
167 error = dp->d_devsw->d_close(dp->d_dev, fflag, devtype, p);
168 }
169 return (error);
170}
171
172static void
173diskstrategy(struct buf *bp)
174{
175 dev_t pdev;
176 struct disk *dp;
177
178 dp = bp->b_dev->si_disk;
179 if (!dp) {
180 pdev = dkmodpart(dkmodslice(bp->b_dev, WHOLE_DISK_SLICE), RAW_PART);
181 dp = bp->b_dev->si_disk = pdev->si_disk;
182 bp->b_dev->si_drv1 = pdev->si_drv1;
183 bp->b_dev->si_drv2 = pdev->si_drv2;
184 bp->b_dev->si_iosize_max = pdev->si_iosize_max;
185 bp->b_dev->si_bsize_phys = pdev->si_bsize_phys;
186 bp->b_dev->si_bsize_best = pdev->si_bsize_best;
187 }
188
189 if (!dp) {
190 bp->b_error = ENXIO;
191 bp->b_flags |= B_ERROR;
192 biodone(bp);
193 return;
194 }
195
196 if (dscheck(bp, dp->d_slice) <= 0) {
197 biodone(bp);
198 return;
199 }
200
201 dp->d_devsw->d_strategy(bp);
202 return;
203
204}
205
206static int
207diskioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p)
208{
209 struct disk *dp;
210 int error;
211
212 dp = dev->si_disk;
213 error = dsioctl(dev, cmd, data, fflag, &dp->d_slice);
214 if (error == ENOIOCTL)
215 error = dp->d_devsw->d_ioctl(dev, cmd, data, fflag, p);
216 return (error);
217}
218
219static int
220diskpsize(dev_t dev)
221{
222 struct disk *dp;
223 dev_t pdev;
224
225 dp = dev->si_disk;
226 if (!dp) {
227 pdev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), RAW_PART);
228 dp = pdev->si_disk;
229 dev->si_drv1 = pdev->si_drv1;
230 dev->si_drv2 = pdev->si_drv2;
231 /* XXX: don't set bp->b_dev->si_disk (?) */
232 }
233 return (dssize(dev, &dp->d_slice));
234}
235
236SYSCTL_DECL(_debug_sizeof);
237
238SYSCTL_INT(_debug_sizeof, OID_AUTO, disklabel, CTLFLAG_RD,
239 0, sizeof(struct disklabel), "sizeof(struct disklabel)");
240
241SYSCTL_INT(_debug_sizeof, OID_AUTO, diskslices, CTLFLAG_RD,
242 0, sizeof(struct diskslices), "sizeof(struct diskslices)");
243
244SYSCTL_INT(_debug_sizeof, OID_AUTO, disk, CTLFLAG_RD,
245 0, sizeof(struct disk), "sizeof(struct disk)");
100 return;
101}
102
103/*
104 * The cdevsw functions
105 */
106
107static int
108diskopen(dev_t dev, int oflags, int devtype, struct proc *p)
109{
110 dev_t pdev;
111 struct disk *dp;
112 int error;
113
114 error = 0;
115 pdev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), RAW_PART);
116
117 dp = pdev->si_disk;
118 if (!dp)
119 return (ENXIO);
120
121 while (dp->d_flags & DISKFLAG_LOCK) {
122 dp->d_flags |= DISKFLAG_WANTED;
123 error = tsleep(dp, PRIBIO | PCATCH, "diskopen", hz);
124 if (error)
125 return (error);
126 }
127 dp->d_flags |= DISKFLAG_LOCK;
128
129 if (!dsisopen(dp->d_slice)) {
130 if (!pdev->si_iosize_max)
131 pdev->si_iosize_max = dev->si_iosize_max;
132 error = dp->d_devsw->d_open(pdev, oflags, devtype, p);
133 }
134
135 /* Inherit properties from the whole/raw dev_t */
136 dev->si_disk = pdev->si_disk;
137 dev->si_drv1 = pdev->si_drv1;
138 dev->si_drv2 = pdev->si_drv2;
139 dev->si_iosize_max = pdev->si_iosize_max;
140 dev->si_bsize_phys = pdev->si_bsize_phys;
141 dev->si_bsize_best = pdev->si_bsize_best;
142
143 if (error)
144 goto out;
145
146 error = dsopen(dev, devtype, dp->d_dsflags, &dp->d_slice, &dp->d_label);
147
148 if (!dsisopen(dp->d_slice))
149 dp->d_devsw->d_close(pdev, oflags, devtype, p);
150out:
151 dp->d_flags &= ~DISKFLAG_LOCK;
152 if (dp->d_flags & DISKFLAG_WANTED) {
153 dp->d_flags &= ~DISKFLAG_WANTED;
154 wakeup(dp);
155 }
156
157 return(error);
158}
159
160static int
161diskclose(dev_t dev, int fflag, int devtype, struct proc *p)
162{
163 struct disk *dp;
164 int error;
165
166 error = 0;
167 dp = dev->si_disk;
168 dsclose(dev, devtype, dp->d_slice);
169 if (!dsisopen(dp->d_slice)) {
170 error = dp->d_devsw->d_close(dp->d_dev, fflag, devtype, p);
171 }
172 return (error);
173}
174
175static void
176diskstrategy(struct buf *bp)
177{
178 dev_t pdev;
179 struct disk *dp;
180
181 dp = bp->b_dev->si_disk;
182 if (!dp) {
183 pdev = dkmodpart(dkmodslice(bp->b_dev, WHOLE_DISK_SLICE), RAW_PART);
184 dp = bp->b_dev->si_disk = pdev->si_disk;
185 bp->b_dev->si_drv1 = pdev->si_drv1;
186 bp->b_dev->si_drv2 = pdev->si_drv2;
187 bp->b_dev->si_iosize_max = pdev->si_iosize_max;
188 bp->b_dev->si_bsize_phys = pdev->si_bsize_phys;
189 bp->b_dev->si_bsize_best = pdev->si_bsize_best;
190 }
191
192 if (!dp) {
193 bp->b_error = ENXIO;
194 bp->b_flags |= B_ERROR;
195 biodone(bp);
196 return;
197 }
198
199 if (dscheck(bp, dp->d_slice) <= 0) {
200 biodone(bp);
201 return;
202 }
203
204 dp->d_devsw->d_strategy(bp);
205 return;
206
207}
208
209static int
210diskioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p)
211{
212 struct disk *dp;
213 int error;
214
215 dp = dev->si_disk;
216 error = dsioctl(dev, cmd, data, fflag, &dp->d_slice);
217 if (error == ENOIOCTL)
218 error = dp->d_devsw->d_ioctl(dev, cmd, data, fflag, p);
219 return (error);
220}
221
222static int
223diskpsize(dev_t dev)
224{
225 struct disk *dp;
226 dev_t pdev;
227
228 dp = dev->si_disk;
229 if (!dp) {
230 pdev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), RAW_PART);
231 dp = pdev->si_disk;
232 dev->si_drv1 = pdev->si_drv1;
233 dev->si_drv2 = pdev->si_drv2;
234 /* XXX: don't set bp->b_dev->si_disk (?) */
235 }
236 return (dssize(dev, &dp->d_slice));
237}
238
239SYSCTL_DECL(_debug_sizeof);
240
241SYSCTL_INT(_debug_sizeof, OID_AUTO, disklabel, CTLFLAG_RD,
242 0, sizeof(struct disklabel), "sizeof(struct disklabel)");
243
244SYSCTL_INT(_debug_sizeof, OID_AUTO, diskslices, CTLFLAG_RD,
245 0, sizeof(struct diskslices), "sizeof(struct diskslices)");
246
247SYSCTL_INT(_debug_sizeof, OID_AUTO, disk, CTLFLAG_RD,
248 0, sizeof(struct disk), "sizeof(struct disk)");