DEVFS - Rollup
[dragonfly.git] / sys / vfs / devfs / devfs_vnops.c
1 /*
2  * Copyright (c) 2009 The DragonFly Project.  All rights reserved.
3  *
4  * This code is derived from software contributed to The DragonFly Project
5  * by Alex Hornung <ahornung@gmail.com>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name of The DragonFly Project nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific, prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/time.h>
37 #include <sys/kernel.h>
38 #include <sys/lock.h>
39 #include <sys/fcntl.h>
40 #include <sys/proc.h>
41 #include <sys/priv.h>
42 #include <sys/signalvar.h>
43 #include <sys/vnode.h>
44 #include <sys/uio.h>
45 #include <sys/mount.h>
46 #include <sys/file.h>
47 #include <sys/fcntl.h>
48 #include <sys/namei.h>
49 #include <sys/dirent.h>
50 #include <sys/malloc.h>
51 #include <sys/stat.h>
52 #include <sys/reg.h>
53 #include <sys/buf2.h>
54 #include <vm/vm_pager.h>
55 #include <vm/vm_zone.h>
56 #include <vm/vm_object.h>
57 #include <sys/filio.h>
58 #include <sys/ttycom.h>
59 #include <sys/sysref2.h>
60 #include <sys/tty.h>
61 #include <vfs/devfs/devfs.h>
62 #include <sys/pioctl.h>
63
64 #include <machine/limits.h>
65
66 MALLOC_DECLARE(M_DEVFS);
67 #define DEVFS_BADOP     (void *)devfs_badop
68
69 static int devfs_badop(struct vop_generic_args *);
70 static int devfs_access(struct vop_access_args *);
71 static int devfs_inactive(struct vop_inactive_args *);
72 static int devfs_reclaim(struct vop_reclaim_args *);
73 static int devfs_readdir(struct vop_readdir_args *);
74 static int devfs_getattr(struct vop_getattr_args *);
75 static int devfs_setattr(struct vop_setattr_args *);
76 static int devfs_readlink(struct vop_readlink_args *);
77 static int devfs_print(struct vop_print_args *);
78
79 static int devfs_nresolve(struct vop_nresolve_args *);
80 static int devfs_nlookupdotdot(struct vop_nlookupdotdot_args *);
81 static int devfs_nsymlink(struct vop_nsymlink_args *);
82 static int devfs_nremove(struct vop_nremove_args *);
83
84 static int devfs_spec_open(struct vop_open_args *);
85 static int devfs_spec_close(struct vop_close_args *);
86 static int devfs_spec_fsync(struct vop_fsync_args *);
87
88 static int devfs_spec_read(struct vop_read_args *);
89 static int devfs_spec_write(struct vop_write_args *);
90 static int devfs_spec_ioctl(struct vop_ioctl_args *);
91 static int devfs_spec_poll(struct vop_poll_args *);
92 static int devfs_spec_kqfilter(struct vop_kqfilter_args *);
93 static int devfs_spec_strategy(struct vop_strategy_args *);
94 static void devfs_spec_strategy_done(struct bio *);
95 static int devfs_spec_freeblks(struct vop_freeblks_args *);
96 static int devfs_spec_bmap(struct vop_bmap_args *);
97 static int devfs_spec_advlock(struct vop_advlock_args *);
98 static void devfs_spec_getpages_iodone(struct bio *);
99 static int devfs_spec_getpages(struct vop_getpages_args *);
100
101
102 static int devfs_specf_close(struct file *);
103 static int devfs_specf_read(struct file *, struct uio *, struct ucred *, int);
104 static int devfs_specf_write(struct file *, struct uio *, struct ucred *, int);
105 static int devfs_specf_stat(struct file *, struct stat *, struct ucred *);
106 static int devfs_specf_kqfilter(struct file *, struct knote *);
107 static int devfs_specf_poll(struct file *, int, struct ucred *);
108 static int devfs_specf_ioctl(struct file *, u_long, caddr_t, struct ucred *);
109
110
111 static __inline int sequential_heuristic(struct uio *, struct file *);
112 extern struct lock              devfs_lock;
113
114 /*
115  * devfs vnode operations for regular files
116  */
117 struct vop_ops devfs_vnode_norm_vops = {
118         .vop_default =          vop_defaultop,
119         .vop_access =           devfs_access,
120         .vop_advlock =          DEVFS_BADOP,
121         .vop_bmap =                     DEVFS_BADOP,
122         .vop_close =            vop_stdclose,
123         .vop_getattr =          devfs_getattr,
124         .vop_inactive =         devfs_inactive,
125         .vop_ncreate =          DEVFS_BADOP,
126         .vop_nresolve =         devfs_nresolve,
127         .vop_nlookupdotdot =    devfs_nlookupdotdot,
128         .vop_nlink =            DEVFS_BADOP,
129         .vop_nmkdir =           DEVFS_BADOP,
130         .vop_nmknod =           DEVFS_BADOP,
131         .vop_nremove =          devfs_nremove,
132         .vop_nrename =          DEVFS_BADOP,
133         .vop_nrmdir =           DEVFS_BADOP,
134         .vop_nsymlink =         devfs_nsymlink,
135         .vop_open =                     vop_stdopen,
136         .vop_pathconf =         vop_stdpathconf,
137         .vop_print =            devfs_print,
138         .vop_read =                     DEVFS_BADOP,
139         .vop_readdir =          devfs_readdir,
140         .vop_readlink =         devfs_readlink,
141         .vop_reclaim =          devfs_reclaim,
142         .vop_setattr =          devfs_setattr,
143         .vop_write =            DEVFS_BADOP,
144         .vop_ioctl =            DEVFS_BADOP
145 };
146
147 /*
148  * devfs vnode operations for character devices
149  */
150 struct vop_ops devfs_vnode_dev_vops = {
151         .vop_default =          vop_defaultop,
152         .vop_access =           devfs_access,
153         .vop_advlock =          devfs_spec_advlock,
154         .vop_bmap =                     devfs_spec_bmap,
155         .vop_close =            devfs_spec_close,
156         .vop_freeblks =         devfs_spec_freeblks,
157         .vop_fsync =            devfs_spec_fsync,
158         .vop_getattr =          devfs_getattr,
159         .vop_getpages =         devfs_spec_getpages,
160         .vop_inactive =         devfs_inactive,
161         .vop_open =                     devfs_spec_open,
162         .vop_pathconf =         vop_stdpathconf,
163         .vop_print =            devfs_print,
164         .vop_poll =                     devfs_spec_poll,
165         .vop_kqfilter =         devfs_spec_kqfilter,
166         .vop_read =                     devfs_spec_read,
167         .vop_readdir =          DEVFS_BADOP,
168         .vop_readlink =         DEVFS_BADOP,
169         .vop_reclaim =          devfs_reclaim,
170         .vop_setattr =          devfs_setattr,
171         .vop_strategy =         devfs_spec_strategy,
172         .vop_write =            devfs_spec_write,
173         .vop_ioctl =            devfs_spec_ioctl
174 };
175
176 struct vop_ops *devfs_vnode_dev_vops_p = &devfs_vnode_dev_vops;
177
178 struct fileops devfs_dev_fileops = {
179         .fo_read = devfs_specf_read,
180         .fo_write = devfs_specf_write,
181         .fo_ioctl = devfs_specf_ioctl,
182         .fo_poll = devfs_specf_poll,
183         .fo_kqfilter = devfs_specf_kqfilter,
184         .fo_stat = devfs_specf_stat,
185         .fo_close = devfs_specf_close,
186         .fo_shutdown = nofo_shutdown
187 };
188
189
190 /*
191  * generic entry point for unsupported operations
192  */
193 static int
194 devfs_badop(struct vop_generic_args *ap)
195 {
196         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs: specified vnode operation is not implemented (yet)\n");
197         return (EIO);
198 }
199
200
201 static int
202 devfs_access(struct vop_access_args *ap)
203 {
204         struct devfs_node *node = DEVFS_NODE(ap->a_vp);
205         int error = 0;
206
207         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_access() called!\n");
208
209         error = vop_helper_access(ap, node->uid, node->gid,
210                                 node->mode, node->flags);
211
212         //devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_access ruled over %s: %d\n", "UNKNOWN", error);
213
214         return error;
215         //XXX: consider possible special cases? terminal, ...?
216 }
217
218
219 static int
220 devfs_inactive(struct vop_inactive_args *ap)
221 {
222         struct devfs_node *node = DEVFS_NODE(ap->a_vp);
223
224         if (node == NULL || (node->flags & DEVFS_NODE_LINKED) == 0)
225                 vrecycle(ap->a_vp);
226         return 0;
227 }
228
229
230 static int
231 devfs_reclaim(struct vop_reclaim_args *ap)
232 {
233         int locked = 0;
234         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_reclaim() called!\n");
235
236         /* Check if it is locked already. if not, we acquire the devfs lock */
237         if (!(lockstatus(&devfs_lock, curthread)) == LK_EXCLUSIVE) {
238                 lockmgr(&devfs_lock, LK_EXCLUSIVE);
239                 locked = 1;
240         }
241
242         /* Check if the devfs_node is not linked anymore into the topology.
243          * If this is the case, we get rid of the devfs_node. */
244         if (DEVFS_NODE(ap->a_vp)) {
245                 if ((DEVFS_NODE(ap->a_vp)->flags & DEVFS_NODE_LINKED) == 0) {
246                                 devfs_freep(DEVFS_NODE(ap->a_vp));
247                                 //devfs_tracer_del_orphan(DEVFS_NODE(ap->a_vp));
248                 }
249
250                 /* unlink vnode <--> devfs_node */
251                 DEVFS_NODE(ap->a_vp)->v_node = NULL;
252         }
253
254         /* If we acquired the lock, we also get rid of it */
255         if (locked)
256                 lockmgr(&devfs_lock, LK_RELEASE);
257
258         ap->a_vp->v_data = NULL;
259         /* avoid a panic on release because of not adding it with v_associate_rdev */
260         ap->a_vp->v_rdev = NULL;
261
262         return 0;
263 }
264
265
266 static int
267 devfs_readdir(struct vop_readdir_args *ap)
268 {
269         struct devfs_node *node;
270         int error2 = 0, r, error = 0;
271
272         int cookie_index;
273         int ncookies;
274         off_t *cookies;
275         off_t saveoff;
276
277         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_readdir() called!\n");
278
279         if (ap->a_uio->uio_offset < 0 || ap->a_uio->uio_offset > INT_MAX)
280                 return (EINVAL);
281         if ((error = vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY)) != 0)
282                 return (error);
283
284         if (DEVFS_NODE(ap->a_vp) == NULL)
285                 return ENOENT;
286
287         lockmgr(&devfs_lock, LK_EXCLUSIVE);
288
289         saveoff = ap->a_uio->uio_offset;
290
291         if (ap->a_ncookies) {
292                 ncookies = ap->a_uio->uio_resid / 16 + 1; /* Why / 16 ?? */
293                 if (ncookies > 256)
294                         ncookies = 256;
295                 cookies = kmalloc(256 * sizeof(off_t), M_TEMP, M_WAITOK);
296                 cookie_index = 0;
297         } else {
298                 ncookies = -1;
299                 cookies = NULL;
300                 cookie_index = 0;
301         }
302
303         nanotime(&DEVFS_NODE(ap->a_vp)->atime);
304
305         if (saveoff == 0) {
306                 r = vop_write_dirent(&error, ap->a_uio, DEVFS_NODE(ap->a_vp)->d_dir.d_ino, DT_DIR, 1, ".");
307                 if (r)
308                         goto done;
309                 if (cookies)
310                         cookies[cookie_index] = saveoff;
311                 saveoff++;
312                 cookie_index++;
313                 if (cookie_index == ncookies)
314                         goto done;
315         }
316
317         if (saveoff == 1) {
318                 if (DEVFS_NODE(ap->a_vp)->parent) {
319                         r = vop_write_dirent(&error, ap->a_uio,
320                                              DEVFS_NODE(ap->a_vp)->d_dir.d_ino,
321                                              DT_DIR, 2, "..");
322                 } else {
323                         r = vop_write_dirent(&error, ap->a_uio,
324                                              DEVFS_NODE(ap->a_vp)->d_dir.d_ino, DT_DIR, 2, "..");
325                 }
326                 if (r)
327                         goto done;
328                 if (cookies)
329                         cookies[cookie_index] = saveoff;
330                 saveoff++;
331                 cookie_index++;
332                 if (cookie_index == ncookies)
333                         goto done;
334         }
335
336         TAILQ_FOREACH(node, DEVFS_DENODE_HEAD(DEVFS_NODE(ap->a_vp)), link) {
337                 if ((node->flags & DEVFS_HIDDEN) || (node->flags & DEVFS_INVISIBLE))
338                         continue;
339
340                 if (node->cookie < saveoff)
341                         continue;
342 /*
343                 if (skip > 0) {
344                         skip--;
345                         continue;
346                 }
347 */
348                 saveoff = node->cookie;
349
350                 error2 = vop_write_dirent(&error, ap->a_uio,
351                         node->d_dir.d_ino, node->d_dir.d_type,
352                         node->d_dir.d_namlen, node->d_dir.d_name);
353
354                 if(error2)
355                         break;
356
357                 saveoff++;
358
359                 if (cookies)
360                         cookies[cookie_index] = node->cookie;
361                 ++cookie_index;
362                 if (cookie_index == ncookies)
363                         break;
364
365                 //count++;
366         }
367
368 done:
369         lockmgr(&devfs_lock, LK_RELEASE);
370         vn_unlock(ap->a_vp);
371
372         ap->a_uio->uio_offset = saveoff;
373         if (error && cookie_index == 0) {
374                 if (cookies) {
375                         kfree(cookies, M_TEMP);
376                         *ap->a_ncookies = 0;
377                         *ap->a_cookies = NULL;
378                 }
379         } else {
380                 if (cookies) {
381                         *ap->a_ncookies = cookie_index;
382                         *ap->a_cookies = cookies;
383                 }
384         }
385         return (error);
386 }
387
388
389 static int
390 devfs_nresolve(struct vop_nresolve_args *ap)
391 {
392         struct devfs_node *node, *found = NULL;
393         struct namecache *ncp;
394         struct vnode *vp = NULL;
395         //void *ident;
396         int error = 0;
397         int len;
398         int hidden = 0;
399
400         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_nresolve() called!\n");
401
402         ncp = ap->a_nch->ncp;
403         len = ncp->nc_nlen;
404
405         if (DEVFS_NODE(ap->a_dvp) == NULL)
406                 return ENOENT;
407
408         lockmgr(&devfs_lock, LK_EXCLUSIVE);
409
410         if ((DEVFS_NODE(ap->a_dvp)->node_type != Proot) &&
411                 (DEVFS_NODE(ap->a_dvp)->node_type != Pdir)) {
412                 devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_nresolve: ap->a_dvp is not a dir!!!\n");
413                 cache_setvp(ap->a_nch, NULL);
414                 goto out;
415         }
416
417 search:
418         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_nresolve -search- \n");
419         TAILQ_FOREACH(node, DEVFS_DENODE_HEAD(DEVFS_NODE(ap->a_dvp)), link) {
420                 if (len == node->d_dir.d_namlen) {
421                         if (!memcmp(ncp->nc_name, node->d_dir.d_name, len)) {
422                                 devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_nresolve: found: %s\n", ncp->nc_name);
423                                 found = node;
424                                 break;
425                         }
426                 }
427         }
428
429         if (found) {
430                 if ((found->node_type == Plink) && (found->link_target))
431                         found = found->link_target;
432
433                 if (!(found->flags & DEVFS_HIDDEN))
434                         devfs_allocv(/*ap->a_dvp->v_mount, */ &vp, found);
435                 else
436                         hidden = 1;
437                 devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_nresolve -2- \n");
438         }
439
440         //devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_nresolve -3- %c%c%c\n", ncp->nc_name[0], ncp->nc_name[1], ncp->nc_name[2]);
441         if (vp == NULL) {
442                 devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_nresolve vp==NULL \n");
443 #if 0
444                 /* XXX: len is int, devfs_clone expects size_t*, not int* */
445                 if ((!hidden) && (!devfs_clone(ncp->nc_name, &len, NULL, 0, ap->a_cred))) {
446                         goto search;
447                 }
448 #endif
449                 devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_nresolve -4- \n");
450                 error = ENOENT;
451                 cache_setvp(ap->a_nch, NULL);
452                 devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_nresolve -5- \n");
453                 goto out;
454
455         }
456         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_nresolve -6- \n");
457         KKASSERT(vp);
458         vn_unlock(vp);
459         cache_setvp(ap->a_nch, vp);
460         vrele(vp);
461
462         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_nresolve -9- \n");
463 out:
464         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_nresolve -end:10- failed? %s \n", (error)?"FAILED!":"OK!");
465         lockmgr(&devfs_lock, LK_RELEASE);
466         return error;
467 }
468
469
470 static int
471 devfs_nlookupdotdot(struct vop_nlookupdotdot_args *ap)
472 {
473         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_nlookupdotdot() called!\n");
474         *ap->a_vpp = NULL;
475
476         lockmgr(&devfs_lock, LK_EXCLUSIVE);
477         if (DEVFS_NODE(ap->a_dvp)->parent != NULL) {
478                 devfs_allocv(/*ap->a_dvp->v_mount, */ap->a_vpp, DEVFS_NODE(ap->a_dvp)->parent);
479                 vn_unlock(*ap->a_vpp);
480         }
481         lockmgr(&devfs_lock, LK_RELEASE);
482
483         return ((*ap->a_vpp == NULL) ? ENOENT : 0);
484 }
485
486
487 static int
488 devfs_getattr(struct vop_getattr_args *ap)
489 {
490         struct vattr *vap = ap->a_vap;
491         struct devfs_node *node = DEVFS_NODE(ap->a_vp);
492         int error = 0;
493
494         if (node == NULL)
495                 return ENOENT;
496
497         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_getattr() called for %s!\n", DEVFS_NODE(ap->a_vp)->d_dir.d_name);
498         lockmgr(&devfs_lock, LK_EXCLUSIVE);
499
500         /* start by zeroing out the attributes */
501         VATTR_NULL(vap);
502
503         /* next do all the common fields */
504         vap->va_type = ap->a_vp->v_type;
505         vap->va_mode = node->mode;
506         vap->va_fileid = DEVFS_NODE(ap->a_vp)->d_dir.d_ino ;
507         vap->va_flags = 0; //what should this be?
508         vap->va_blocksize = DEV_BSIZE;
509         vap->va_bytes = vap->va_size = sizeof(struct devfs_node);
510
511         //devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_getattr() check dev %s!\n", (DEVFS_NODE(ap->a_vp)->d_dev)?(DEVFS_NODE(ap->a_vp)->d_dev->si_name):"Not a device");
512
513         vap->va_fsid = ap->a_vp->v_mount->mnt_stat.f_fsid.val[0];
514
515
516         vap->va_atime = node->atime;
517         vap->va_mtime = node->mtime;
518         vap->va_ctime = node->ctime;
519
520         vap->va_nlink = 1; /* number of references to file */
521
522         vap->va_uid = node->uid;
523         vap->va_gid = node->gid;
524
525         vap->va_rmajor = 0;
526         vap->va_rminor = 0;
527
528         if ((DEVFS_NODE(ap->a_vp)->node_type == Pdev) &&
529                 (DEVFS_NODE(ap->a_vp)->d_dev))  {
530                 devfs_debug(DEVFS_DEBUG_DEBUG, "getattr: dev is: %p\n", DEVFS_NODE(ap->a_vp)->d_dev);
531                 reference_dev(DEVFS_NODE(ap->a_vp)->d_dev);
532                 vap->va_rminor = DEVFS_NODE(ap->a_vp)->d_dev->si_uminor;
533                 release_dev(DEVFS_NODE(ap->a_vp)->d_dev);
534         }
535
536         /* For a softlink the va_size is the length of the softlink */
537         if (DEVFS_NODE(ap->a_vp)->symlink_name != 0) {
538                 vap->va_size = DEVFS_NODE(ap->a_vp)->symlink_namelen;
539         }
540         nanotime(&node->atime);
541         lockmgr(&devfs_lock, LK_RELEASE);
542         return (error); //XXX: set error usefully
543 }
544
545
546 static int
547 devfs_setattr(struct vop_setattr_args *ap)
548 {
549         struct devfs_node *node;
550         struct vattr *vap;
551         int error = 0;
552
553         node = DEVFS_NODE(ap->a_vp);
554
555         if (node == NULL)
556                 return ENOENT;
557
558         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_setattr() called!\n");
559         lockmgr(&devfs_lock, LK_EXCLUSIVE);
560
561         vap = ap->a_vap;
562
563         if (vap->va_uid != (uid_t)VNOVAL) {
564                 if ((ap->a_cred->cr_uid != node->uid) &&
565                         (!groupmember(node->gid, ap->a_cred))) {
566                         error = priv_check(curthread, PRIV_VFS_CHOWN);
567                         if (error) {
568                                 devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_setattr, erroring out -1-\n");
569                                 goto out;
570                         }
571                 }
572                 node->uid = vap->va_uid;
573         }
574
575         if (vap->va_gid != (uid_t)VNOVAL) {
576                 if ((ap->a_cred->cr_uid != node->uid) &&
577                         (!groupmember(node->gid, ap->a_cred))) {
578                         error = priv_check(curthread, PRIV_VFS_CHOWN);
579                         if (error) {
580                                 devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_setattr, erroring out -2-\n");
581                                 goto out;
582                         }
583                 }
584                 node->gid = vap->va_gid;
585         }
586
587         if (vap->va_mode != (mode_t)VNOVAL) {
588                 if (ap->a_cred->cr_uid != node->uid) {
589                         error = priv_check(curthread, PRIV_VFS_ADMIN);
590                         if (error) {
591                                 devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_setattr, erroring out -3-\n");
592                                 goto out;
593                         }
594                 }
595                 node->mode = vap->va_mode;
596         }
597
598 out:
599         nanotime(&node->mtime);
600         lockmgr(&devfs_lock, LK_RELEASE);
601         return error;
602 }
603
604
605 static int
606 devfs_readlink(struct vop_readlink_args *ap)
607 {
608         struct devfs_node *node = DEVFS_NODE(ap->a_vp);
609         int ret;
610
611         if (node == NULL)
612                 return ENOENT;
613
614         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_readlink()  called!\n");
615
616         lockmgr(&devfs_lock, LK_EXCLUSIVE);
617         ret = uiomove(node->symlink_name, node->symlink_namelen, ap->a_uio);
618         lockmgr(&devfs_lock, LK_RELEASE);
619
620         return ret;
621 }
622
623
624 static int
625 devfs_print(struct vop_print_args *ap)
626 {
627         //struct devfs_node *node = DEVFS_NODE(ap->a_vp);
628
629         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_print() called!\n");
630
631         //XXX: print some useful debugging about node.
632         return (0);
633 }
634
635
636 static int
637 devfs_nsymlink(struct vop_nsymlink_args *ap)
638 {
639         size_t targetlen = strlen(ap->a_target);
640
641         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_nsymlink() called!\n");
642
643         ap->a_vap->va_type = VLNK;
644
645         if (DEVFS_NODE(ap->a_dvp) == NULL)
646                 return ENOENT;
647
648         if ((DEVFS_NODE(ap->a_dvp)->node_type != Proot) &&
649                 (DEVFS_NODE(ap->a_dvp)->node_type != Pdir)) {
650                 devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_nsymlink: ap->a_dvp is not a dir!!!\n");
651                 goto out;
652         }
653         lockmgr(&devfs_lock, LK_EXCLUSIVE);
654         devfs_allocvp(ap->a_dvp->v_mount, ap->a_vpp, Plink,
655                                 ap->a_nch->ncp->nc_name, DEVFS_NODE(ap->a_dvp), NULL);
656
657         if (*ap->a_vpp) {
658                 DEVFS_NODE(*ap->a_vpp)->flags |= DEVFS_USER_CREATED;
659
660                 DEVFS_NODE(*ap->a_vpp)->symlink_namelen = targetlen;
661                 DEVFS_NODE(*ap->a_vpp)->symlink_name = kmalloc(targetlen + 1, M_DEVFS, M_WAITOK);
662                 memcpy(DEVFS_NODE(*ap->a_vpp)->symlink_name, ap->a_target, targetlen);
663                 DEVFS_NODE(*ap->a_vpp)->symlink_name[targetlen] = '\0';
664                 cache_setunresolved(ap->a_nch);
665                 //problematic to use cache_* inside lockmgr() ? Probably not...
666                 cache_setvp(ap->a_nch, *ap->a_vpp);
667         }
668         lockmgr(&devfs_lock, LK_RELEASE);
669 out:
670         return ((*ap->a_vpp == NULL) ? ENOTDIR : 0);
671
672 }
673
674
675 static int
676 devfs_nremove(struct vop_nremove_args *ap)
677 {
678         struct devfs_node *node;
679         struct namecache *ncp;
680         //struct vnode *vp = NULL;
681         int error = ENOENT;
682
683         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_nremove() called!\n");
684
685         ncp = ap->a_nch->ncp;
686
687         if (DEVFS_NODE(ap->a_dvp) == NULL)
688                 return ENOENT;
689
690         lockmgr(&devfs_lock, LK_EXCLUSIVE);
691
692         if ((DEVFS_NODE(ap->a_dvp)->node_type != Proot) &&
693                 (DEVFS_NODE(ap->a_dvp)->node_type != Pdir)) {
694                 devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_nremove: ap->a_dvp is not a dir!!!\n");
695                 goto out;
696         }
697
698         TAILQ_FOREACH(node, DEVFS_DENODE_HEAD(DEVFS_NODE(ap->a_dvp)), link)     {
699                 if (ncp->nc_nlen == node->d_dir.d_namlen) {
700                         if (!memcmp(ncp->nc_name, node->d_dir.d_name, ncp->nc_nlen)) {
701                                 // allow only removal of user created stuff (e.g. symlinks)
702                                 if ((node->flags & DEVFS_USER_CREATED) == 0) {
703                                         error = EPERM;
704                                         goto out;
705                                 } else {
706                                         if (node->v_node)
707                                                 cache_inval_vp(node->v_node, CINV_DESTROY);
708
709                                         devfs_unlinkp(node);
710                                         error = 0;
711                                         break;
712                                 }
713                         }
714                 }
715         }
716
717         cache_setunresolved(ap->a_nch);
718         cache_setvp(ap->a_nch, NULL);
719         //cache_inval_vp(node->v_node, CINV_DESTROY);
720
721 out:
722         lockmgr(&devfs_lock, LK_RELEASE);
723         //vrele(ap->a_dvp);
724         //vput(ap->a_dvp);
725         return error;
726 }
727
728
729 static int
730 devfs_spec_open(struct vop_open_args *ap)
731 {
732         struct vnode *vp = ap->a_vp;
733         struct vnode *orig_vp = NULL;
734         cdev_t dev, ndev = NULL;
735         struct devfs_node *node = NULL;
736         int error = 0;
737         size_t len;
738
739         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_spec_open() called\n");
740
741         if (DEVFS_NODE(vp)) {
742                 if (DEVFS_NODE(vp)->d_dev == NULL)
743                         return ENXIO;
744         }
745
746         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_spec_open: -1-\n");
747
748         if ((dev = vp->v_rdev) == NULL)
749                 return ENXIO;
750
751         if (DEVFS_NODE(vp) && ap->a_fp) {
752                 devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_spec_open: -1.1-\n");
753                 lockmgr(&devfs_lock, LK_EXCLUSIVE);
754                 len = DEVFS_NODE(vp)->d_dir.d_namlen;
755                 if (!(devfs_clone(DEVFS_NODE(vp)->d_dir.d_name, &len, &ndev, 1, ap->a_cred))) {
756                         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_spec_open: -1.2- |%s|\n", ndev->si_name);
757
758                         dev = ndev;
759                         devfs_link_dev(dev);
760                         node = devfs_create_device_node(DEVFS_MNTDATA(vp->v_mount)->root_node, dev, NULL, NULL);
761
762                         devfs_debug(DEVFS_DEBUG_DEBUG, "parent here is: %s, node is: |%s|\n", (DEVFS_NODE(vp)->parent->node_type == Proot)?"ROOT!":DEVFS_NODE(vp)->parent->d_dir.d_name, node->d_dir.d_name);
763                         devfs_debug(DEVFS_DEBUG_DEBUG, "test: %s\n", ((struct devfs_node *)(TAILQ_LAST(DEVFS_DENODE_HEAD(DEVFS_NODE(vp)->parent), devfs_node_head)))->d_dir.d_name);
764
765                         /*
766                          * orig_vp is set to the original vp if we cloned.
767                          */
768                         /* node->flags |= DEVFS_CLONED; */
769                         devfs_allocv(&vp, node);
770                         orig_vp = ap->a_vp;
771                         ap->a_vp = vp;
772                 }
773                 lockmgr(&devfs_lock, LK_RELEASE);
774         }
775
776         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_spec_open() called on %s! \n", dev->si_name);
777         /*
778          * Make this field valid before any I/O in ->d_open
779          */
780         if (!dev->si_iosize_max)
781                 dev->si_iosize_max = DFLTPHYS;
782
783         if (dev_dflags(dev) & D_TTY)
784                 vp->v_flag |= VISTTY;
785
786         vn_unlock(vp);
787         error = dev_dopen(dev, ap->a_mode, S_IFCHR, ap->a_cred);
788         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
789
790         /*
791          * Clean up any cloned vp if we error out.
792          */
793         if (error) {
794                 devfs_debug(DEVFS_DEBUG_DEBUG,
795                             "devfs_spec_open() error out: %x\n", error);
796                 if (orig_vp) {
797                         vput(vp);
798                         ap->a_vp = orig_vp;
799                         /* orig_vp = NULL; */
800                 }
801                 return error;
802         }
803
804
805         if (dev_dflags(dev) & D_TTY) {
806                 if (dev->si_tty) {
807                         struct tty *tp;
808                         tp = dev->si_tty;
809                         if (!tp->t_stop) {
810                                 devfs_debug(DEVFS_DEBUG_DEBUG, "devfs: no t_stop\n");
811                                 tp->t_stop = nottystop;
812                         }
813                 }
814         }
815
816
817         if (vn_isdisk(vp, NULL)) {
818                 if (!dev->si_bsize_phys)
819                         dev->si_bsize_phys = DEV_BSIZE;
820                 vinitvmio(vp, IDX_TO_OFF(INT_MAX));
821         }
822
823         vop_stdopen(ap);
824         if (DEVFS_NODE(vp))
825                 nanotime(&DEVFS_NODE(vp)->atime);
826
827         if (orig_vp)
828                 vn_unlock(vp);
829
830         /* Ugly pty magic, to make pty devices appear once they are opened */
831         if (DEVFS_NODE(vp) && ((DEVFS_NODE(vp)->flags & DEVFS_PTY) == DEVFS_PTY))
832                 DEVFS_NODE(vp)->flags &= ~DEVFS_INVISIBLE;
833
834         if (ap->a_fp) {
835                 ap->a_fp->f_type = DTYPE_VNODE;
836                 ap->a_fp->f_flag = ap->a_mode & FMASK;
837                 ap->a_fp->f_ops = &devfs_dev_fileops;
838                 ap->a_fp->f_data = vp;
839         }
840
841         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_spec_open: -end:3-\n");
842
843         return 0;
844 }
845
846
847 static int
848 devfs_spec_close(struct vop_close_args *ap)
849 {
850         struct proc *p = curproc;
851         struct vnode *vp = ap->a_vp;
852         cdev_t dev = vp->v_rdev;
853         int error = 0;
854         int needrelock;
855
856         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_spec_close() called on %s! \n", dev->si_name);
857
858         /*
859          * A couple of hacks for devices and tty devices.  The
860          * vnode ref count cannot be used to figure out the
861          * last close, but we can use v_opencount now that
862          * revoke works properly.
863          *
864          * Detect the last close on a controlling terminal and clear
865          * the session (half-close).
866          */
867         if (dev)
868                 reference_dev(dev);
869
870         if (p && vp->v_opencount <= 1 && vp == p->p_session->s_ttyvp) {
871                 p->p_session->s_ttyvp = NULL;
872                 vrele(vp);
873         }
874
875         /*
876          * Vnodes can be opened and closed multiple times.  Do not really
877          * close the device unless (1) it is being closed forcibly,
878          * (2) the device wants to track closes, or (3) this is the last
879          * vnode doing its last close on the device.
880          *
881          * XXX the VXLOCK (force close) case can leave vnodes referencing
882          * a closed device.  This might not occur now that our revoke is
883          * fixed.
884          */
885         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_spec_close() -1- \n");
886         if (dev && ((vp->v_flag & VRECLAIMED) ||
887             (dev_dflags(dev) & D_TRACKCLOSE) ||
888             (vp->v_opencount == 1))) {
889                 needrelock = 0;
890                 if (vn_islocked(vp)) {
891                         needrelock = 1;
892                         vn_unlock(vp);
893                 }
894                 error = dev_dclose(dev, ap->a_fflag, S_IFCHR);
895 #if 0
896                 if (DEVFS_NODE(vp) && (DEVFS_NODE(vp)->flags & DEVFS_CLONED) == DEVFS_CLONED) {
897                         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_spec_close: last of the cloned ones, so delete node %s\n", dev->si_name);
898                         devfs_unlinkp(DEVFS_NODE(vp));
899                         devfs_freep(DEVFS_NODE(vp));
900                 }
901 #endif
902                 /* Ugly pty magic, to make pty devices disappear again once they are closed */
903                 if (DEVFS_NODE(vp) && ((DEVFS_NODE(vp)->flags & DEVFS_PTY) == DEVFS_PTY))
904                         DEVFS_NODE(vp)->flags |= DEVFS_INVISIBLE;
905
906                 if (needrelock)
907                         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
908         } else {
909                 error = 0;
910         }
911         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_spec_close() -2- \n");
912         /*
913          * Track the actual opens and closes on the vnode.  The last close
914          * disassociates the rdev.  If the rdev is already disassociated or the
915          * opencount is already 0, the vnode might have been revoked and no
916          * further opencount tracking occurs.
917          */
918         if (dev) {
919                 devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_spec_close() -3- \n");
920                 if (vp->v_opencount == 1) {
921                         //vp->v_rdev = 0;
922                         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_spec_close() -3.5- \n");
923                 }
924                 release_dev(dev);
925         }
926         if (vp->v_opencount > 0) {
927                 devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_spec_close() -4- \n");
928                 vop_stdclose(ap);
929                 devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_spec_close() -5- \n");
930         }
931
932         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_spec_close() -end:6- \n");
933         return(error);
934
935 }
936
937
938 static int
939 devfs_specf_close(struct file *fp)
940 {
941         int error;
942         struct vnode *vp = (struct vnode *)fp->f_data;
943
944         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_specf_close() called! \n");
945         get_mplock();
946         fp->f_ops = &badfileops;
947
948         error = vn_close(vp, fp->f_flag);
949         rel_mplock();
950
951         return (error);
952 }
953
954
955 /*
956  * Device-optimized file table vnode read routine.
957  *
958  * This bypasses the VOP table and talks directly to the device.  Most
959  * filesystems just route to specfs and can make this optimization.
960  *
961  * MPALMOSTSAFE - acquires mplock
962  */
963 static int
964 devfs_specf_read(struct file *fp, struct uio *uio, struct ucred *cred, int flags)
965 {
966         struct vnode *vp;
967         int ioflag;
968         int error;
969         cdev_t dev;
970
971         get_mplock();
972         //devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_specf_read() called! \n");
973         KASSERT(uio->uio_td == curthread,
974                 ("uio_td %p is not td %p", uio->uio_td, curthread));
975
976         vp = (struct vnode *)fp->f_data;
977         if (vp == NULL || vp->v_type == VBAD) {
978                 error = EBADF;
979                 goto done;
980         }
981
982         if ((dev = vp->v_rdev) == NULL) {
983                 error = EBADF;
984                 goto done;
985         }
986         //devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_specf_read() called! for dev %s\n", dev->si_name);
987
988         reference_dev(dev);
989
990         if (uio->uio_resid == 0) {
991                 error = 0;
992                 goto done;
993         }
994         if ((flags & O_FOFFSET) == 0)
995                 uio->uio_offset = fp->f_offset;
996
997         ioflag = 0;
998         if (flags & O_FBLOCKING) {
999                 /* ioflag &= ~IO_NDELAY; */
1000         } else if (flags & O_FNONBLOCKING) {
1001                 ioflag |= IO_NDELAY;
1002         } else if (fp->f_flag & FNONBLOCK) {
1003                 ioflag |= IO_NDELAY;
1004         }
1005         if (flags & O_FBUFFERED) {
1006                 /* ioflag &= ~IO_DIRECT; */
1007         } else if (flags & O_FUNBUFFERED) {
1008                 ioflag |= IO_DIRECT;
1009         } else if (fp->f_flag & O_DIRECT) {
1010                 ioflag |= IO_DIRECT;
1011         }
1012         ioflag |= sequential_heuristic(uio, fp);
1013
1014         error = dev_dread(dev, uio, ioflag);
1015
1016         release_dev(dev);
1017         if (DEVFS_NODE(vp))
1018                 nanotime(&DEVFS_NODE(vp)->atime);
1019         if ((flags & O_FOFFSET) == 0)
1020                 fp->f_offset = uio->uio_offset;
1021         fp->f_nextoff = uio->uio_offset;
1022 done:
1023         rel_mplock();
1024         //devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_specf_read finished\n");
1025         return (error);
1026 }
1027
1028
1029 static int
1030 devfs_specf_write(struct file *fp, struct uio *uio, struct ucred *cred, int flags)
1031 {
1032         struct vnode *vp;
1033         int ioflag;
1034         int error;
1035         cdev_t dev;
1036
1037         //devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_specf_write() called! \n");
1038         get_mplock();
1039         KASSERT(uio->uio_td == curthread,
1040                 ("uio_td %p is not p %p", uio->uio_td, curthread));
1041
1042         vp = (struct vnode *)fp->f_data;
1043         if (vp == NULL || vp->v_type == VBAD) {
1044                 error = EBADF;
1045                 goto done;
1046         }
1047         if (vp->v_type == VREG)
1048                 bwillwrite(uio->uio_resid);
1049         vp = (struct vnode *)fp->f_data;
1050
1051         if ((dev = vp->v_rdev) == NULL) {
1052                 error = EBADF;
1053                 goto done;
1054         }
1055         //devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_specf_write() called! for dev %s\n", dev->si_name);
1056         reference_dev(dev);
1057
1058         if ((flags & O_FOFFSET) == 0)
1059                 uio->uio_offset = fp->f_offset;
1060
1061         ioflag = IO_UNIT;
1062         if (vp->v_type == VREG &&
1063            ((fp->f_flag & O_APPEND) || (flags & O_FAPPEND))) {
1064                 ioflag |= IO_APPEND;
1065         }
1066
1067         if (flags & O_FBLOCKING) {
1068                 /* ioflag &= ~IO_NDELAY; */
1069         } else if (flags & O_FNONBLOCKING) {
1070                 ioflag |= IO_NDELAY;
1071         } else if (fp->f_flag & FNONBLOCK) {
1072                 ioflag |= IO_NDELAY;
1073         }
1074         if (flags & O_FBUFFERED) {
1075                 /* ioflag &= ~IO_DIRECT; */
1076         } else if (flags & O_FUNBUFFERED) {
1077                 ioflag |= IO_DIRECT;
1078         } else if (fp->f_flag & O_DIRECT) {
1079                 ioflag |= IO_DIRECT;
1080         }
1081         if (flags & O_FASYNCWRITE) {
1082                 /* ioflag &= ~IO_SYNC; */
1083         } else if (flags & O_FSYNCWRITE) {
1084                 ioflag |= IO_SYNC;
1085         } else if (fp->f_flag & O_FSYNC) {
1086                 ioflag |= IO_SYNC;
1087         }
1088
1089         if (vp->v_mount && (vp->v_mount->mnt_flag & MNT_SYNCHRONOUS))
1090                 ioflag |= IO_SYNC;
1091         ioflag |= sequential_heuristic(uio, fp);
1092
1093         error = dev_dwrite(dev, uio, ioflag);
1094
1095         release_dev(dev);
1096         if (DEVFS_NODE(vp))
1097                 nanotime(&DEVFS_NODE(vp)->mtime);
1098
1099         if ((flags & O_FOFFSET) == 0)
1100                 fp->f_offset = uio->uio_offset;
1101         fp->f_nextoff = uio->uio_offset;
1102 done:
1103         rel_mplock();
1104         //devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_specf_write done\n");
1105         return (error);
1106 }
1107
1108
1109 static int
1110 devfs_specf_stat(struct file *fp, struct stat *sb, struct ucred *cred)
1111 {
1112         struct vnode *vp;
1113         int error;
1114
1115         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_specf_stat() called\n");
1116
1117         get_mplock();
1118         vp = (struct vnode *)fp->f_data;
1119         error = vn_stat(vp, sb, cred);
1120         if (error) {
1121                 rel_mplock();
1122                 return (error);
1123         }
1124
1125         struct vattr vattr;
1126         struct vattr *vap;
1127         u_short mode;
1128         cdev_t dev;
1129
1130         vap = &vattr;
1131         error = VOP_GETATTR(vp, vap);
1132         if (error) {
1133                 rel_mplock();
1134                 return (error);
1135         }
1136
1137         /*
1138          * Zero the spare stat fields
1139          */
1140         sb->st_lspare = 0;
1141         sb->st_qspare = 0;
1142
1143         /*
1144          * Copy from vattr table ... or not in case it's a cloned device
1145          */
1146         if (vap->va_fsid != VNOVAL)
1147                 sb->st_dev = vap->va_fsid;
1148         else
1149                 sb->st_dev = vp->v_mount->mnt_stat.f_fsid.val[0];
1150
1151         sb->st_ino = vap->va_fileid;
1152
1153         mode = vap->va_mode;
1154         mode |= S_IFCHR;
1155         sb->st_mode = mode;
1156
1157         if (vap->va_nlink > (nlink_t)-1)
1158                 sb->st_nlink = (nlink_t)-1;
1159         else
1160                 sb->st_nlink = vap->va_nlink;
1161         sb->st_uid = vap->va_uid;
1162         sb->st_gid = vap->va_gid;
1163         sb->st_rdev = dev2udev(DEVFS_NODE(vp)->d_dev);
1164         sb->st_size = vap->va_size;
1165         sb->st_atimespec = vap->va_atime;
1166         sb->st_mtimespec = vap->va_mtime;
1167         sb->st_ctimespec = vap->va_ctime;
1168
1169         /*
1170          * A VCHR and VBLK device may track the last access and last modified
1171          * time independantly of the filesystem.  This is particularly true
1172          * because device read and write calls may bypass the filesystem.
1173          */
1174         if (vp->v_type == VCHR || vp->v_type == VBLK) {
1175                 dev = vp->v_rdev;
1176                 if (dev != NULL) {
1177                         if (dev->si_lastread) {
1178                                 sb->st_atimespec.tv_sec = dev->si_lastread;
1179                                 sb->st_atimespec.tv_nsec = 0;
1180                         }
1181                         if (dev->si_lastwrite) {
1182                                 sb->st_atimespec.tv_sec = dev->si_lastwrite;
1183                                 sb->st_atimespec.tv_nsec = 0;
1184                         }
1185                 }
1186         }
1187
1188         /*
1189          * According to www.opengroup.org, the meaning of st_blksize is
1190          *   "a filesystem-specific preferred I/O block size for this
1191          *    object.  In some filesystem types, this may vary from file
1192          *    to file"
1193          * Default to PAGE_SIZE after much discussion.
1194          */
1195
1196         sb->st_blksize = PAGE_SIZE;
1197
1198         sb->st_flags = vap->va_flags;
1199
1200         error = priv_check_cred(cred, PRIV_VFS_GENERATION, 0);
1201         if (error)
1202                 sb->st_gen = 0;
1203         else
1204                 sb->st_gen = (u_int32_t)vap->va_gen;
1205
1206         sb->st_blocks = vap->va_bytes / S_BLKSIZE;
1207         sb->st_fsmid = vap->va_fsmid;
1208
1209         rel_mplock();
1210         return (0);
1211 }
1212
1213
1214 static int
1215 devfs_specf_kqfilter(struct file *fp, struct knote *kn)
1216 {
1217         struct vnode *vp;
1218         //int ioflag;
1219         int error;
1220         cdev_t dev;
1221
1222         //devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_specf_kqfilter() called! \n");
1223
1224         get_mplock();
1225
1226         vp = (struct vnode *)fp->f_data;
1227         if (vp == NULL || vp->v_type == VBAD) {
1228                 error = EBADF;
1229                 goto done;
1230         }
1231
1232         if ((dev = vp->v_rdev) == NULL) {
1233                 error = EBADF;
1234                 goto done;
1235         }
1236         reference_dev(dev);
1237
1238         error = dev_dkqfilter(dev, kn);
1239
1240         release_dev(dev);
1241
1242         if (DEVFS_NODE(vp))
1243                 nanotime(&DEVFS_NODE(vp)->atime);
1244 done:
1245         rel_mplock();
1246         return (error);
1247 }
1248
1249
1250 static int
1251 devfs_specf_poll(struct file *fp, int events, struct ucred *cred)
1252 {
1253         struct vnode *vp;
1254         //int ioflag;
1255         int error;
1256         cdev_t dev;
1257
1258         //devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_specf_poll() called! \n");
1259
1260         get_mplock();
1261
1262         vp = (struct vnode *)fp->f_data;
1263         if (vp == NULL || vp->v_type == VBAD) {
1264                 error = EBADF;
1265                 goto done;
1266         }
1267
1268         if ((dev = vp->v_rdev) == NULL) {
1269                 error = EBADF;
1270                 goto done;
1271         }
1272         reference_dev(dev);
1273         error = dev_dpoll(dev, events);
1274
1275         release_dev(dev);
1276
1277         if (DEVFS_NODE(vp))
1278                 nanotime(&DEVFS_NODE(vp)->atime);
1279 done:
1280         rel_mplock();
1281         return (error);
1282 }
1283
1284
1285 /*
1286  * MPALMOSTSAFE - acquires mplock
1287  */
1288 static int
1289 devfs_specf_ioctl(struct file *fp, u_long com, caddr_t data, struct ucred *ucred)
1290 {
1291         struct vnode *vp = ((struct vnode *)fp->f_data);
1292         struct vnode *ovp;
1293         //struct vattr vattr;
1294         cdev_t  dev;
1295         int error;
1296         struct fiodname_args *name_args;
1297         size_t namlen;
1298         const char *name;
1299
1300         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_specf_ioctl() called! \n");
1301
1302         get_mplock();
1303
1304         if ((dev = vp->v_rdev) == NULL) {
1305                 error = EBADF;          /* device was revoked */
1306                 goto out;
1307         }
1308         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_specf_ioctl() called! for dev %s\n", dev->si_name);
1309
1310         if (!(dev_dflags(dev) & D_TTY))
1311                 devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_specf_ioctl() called on %s! com is: %x\n", dev->si_name, com);
1312
1313         if (com == FIODTYPE) {
1314                 *(int *)data = dev_dflags(dev) & D_TYPEMASK;
1315                 error = 0;
1316                 goto out;
1317         } else if (com == FIODNAME) {
1318                 name_args = (struct fiodname_args *)data;
1319                 name = dev->si_name;
1320                 namlen = strlen(name) + 1;
1321
1322                 devfs_debug(DEVFS_DEBUG_DEBUG, "ioctl, got: FIODNAME for %s\n", name);
1323
1324                 if (namlen <= name_args->len)
1325                         error = copyout(dev->si_name, name_args->name, namlen);
1326                 else
1327                         error = EINVAL;
1328
1329                 //name_args->len = namlen; //need _IOWR to enable this
1330                 devfs_debug(DEVFS_DEBUG_DEBUG, "ioctl stuff: error: %d\n", error);
1331                 goto out;
1332         }
1333         reference_dev(dev);
1334         error = dev_dioctl(dev, com, data, fp->f_flag, ucred);
1335         release_dev(dev);
1336         if (DEVFS_NODE(vp)) {
1337                 nanotime(&DEVFS_NODE(vp)->atime);
1338                 nanotime(&DEVFS_NODE(vp)->mtime);
1339         }
1340
1341         if (com == TIOCSCTTY)
1342                 devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_specf_ioctl: got TIOCSCTTY on %s\n", dev->si_name);
1343         if (error == 0 && com == TIOCSCTTY) {
1344                 devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_specf_ioctl: dealing with TIOCSCTTY on %s\n", dev->si_name);
1345                 struct proc *p = curthread->td_proc;
1346                 struct session *sess;
1347                         if (p == NULL) {
1348                         error = ENOTTY;
1349                         goto out;
1350                 }
1351                 sess = p->p_session;
1352                 /* Do nothing if reassigning same control tty */
1353                 if (sess->s_ttyvp == vp) {
1354                         error = 0;
1355                         goto out;
1356                 }
1357                         /* Get rid of reference to old control tty */
1358                 ovp = sess->s_ttyvp;
1359                 vref(vp);
1360                 sess->s_ttyvp = vp;
1361                 if (ovp)
1362                         vrele(ovp);
1363         }
1364
1365 out:
1366         rel_mplock();
1367         devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_specf_ioctl() finished! \n");
1368         return (error);
1369 }
1370
1371
1372 static int
1373 devfs_spec_fsync(struct vop_fsync_args *ap)
1374 {
1375         struct vnode *vp = ap->a_vp;
1376         int error;
1377
1378         if (!vn_isdisk(vp, NULL))
1379                 return (0);
1380
1381         /*
1382          * Flush all dirty buffers associated with a block device.
1383          */
1384         error = vfsync(vp, ap->a_waitfor, 10000, NULL, NULL);
1385         return (error);
1386 }
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407 static int
1408 devfs_spec_read(struct vop_read_args *ap)
1409 {
1410         struct vnode *vp;
1411         struct uio *uio;
1412         cdev_t dev;
1413         int error;
1414
1415         vp = ap->a_vp;
1416         dev = vp->v_rdev;
1417         uio = ap->a_uio;
1418
1419         if (dev == NULL)                /* device was revoked */
1420                 return (EBADF);
1421         if (uio->uio_resid == 0)
1422                 return (0);
1423
1424         vn_unlock(vp);
1425         error = dev_dread(dev, uio, ap->a_ioflag);
1426         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1427
1428         if (DEVFS_NODE(vp))
1429                 nanotime(&DEVFS_NODE(vp)->atime);
1430
1431         return (error);
1432 }
1433
1434 /*
1435  * Vnode op for write
1436  *
1437  * spec_write(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
1438  *            struct ucred *a_cred)
1439  */
1440 /* ARGSUSED */
1441 static int
1442 devfs_spec_write(struct vop_write_args *ap)
1443 {
1444         struct vnode *vp;
1445         struct uio *uio;
1446         cdev_t dev;
1447         int error;
1448
1449         vp = ap->a_vp;
1450         dev = vp->v_rdev;
1451         uio = ap->a_uio;
1452
1453         KKASSERT(uio->uio_segflg != UIO_NOCOPY);
1454
1455         if (dev == NULL)                /* device was revoked */
1456                 return (EBADF);
1457
1458         vn_unlock(vp);
1459         error = dev_dwrite(dev, uio, ap->a_ioflag);
1460         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1461
1462         if (DEVFS_NODE(vp))
1463                 nanotime(&DEVFS_NODE(vp)->mtime);
1464
1465         return (error);
1466 }
1467
1468 /*
1469  * Device ioctl operation.
1470  *
1471  * spec_ioctl(struct vnode *a_vp, int a_command, caddr_t a_data,
1472  *            int a_fflag, struct ucred *a_cred)
1473  */
1474 /* ARGSUSED */
1475 static int
1476 devfs_spec_ioctl(struct vop_ioctl_args *ap)
1477 {
1478         cdev_t dev;
1479         struct vnode *vp = ap->a_vp;
1480
1481         if ((dev = vp->v_rdev) == NULL)
1482                 return (EBADF);         /* device was revoked */
1483         if ( ap->a_command == TIOCSCTTY )
1484                 devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_*SPEC*_ioctl: got TIOCSCTTY\n");
1485
1486         if (DEVFS_NODE(vp)) {
1487                 nanotime(&DEVFS_NODE(vp)->atime);
1488                 nanotime(&DEVFS_NODE(vp)->mtime);
1489         }
1490
1491         return (dev_dioctl(dev, ap->a_command, ap->a_data,
1492                     ap->a_fflag, ap->a_cred));
1493 }
1494
1495 /*
1496  * spec_poll(struct vnode *a_vp, int a_events, struct ucred *a_cred)
1497  */
1498 /* ARGSUSED */
1499 static int
1500 devfs_spec_poll(struct vop_poll_args *ap)
1501 {
1502         cdev_t dev;
1503         struct vnode *vp = ap->a_vp;
1504
1505         if ((dev = vp->v_rdev) == NULL)
1506                 return (EBADF);         /* device was revoked */
1507
1508         if (DEVFS_NODE(vp))
1509                 nanotime(&DEVFS_NODE(vp)->atime);
1510
1511         return (dev_dpoll(dev, ap->a_events));
1512 }
1513
1514 /*
1515  * spec_kqfilter(struct vnode *a_vp, struct knote *a_kn)
1516  */
1517 /* ARGSUSED */
1518 static int
1519 devfs_spec_kqfilter(struct vop_kqfilter_args *ap)
1520 {
1521         cdev_t dev;
1522         struct vnode *vp = ap->a_vp;
1523
1524         if ((dev = vp->v_rdev) == NULL)
1525                 return (EBADF);         /* device was revoked */
1526
1527         if (DEVFS_NODE(vp))
1528                 nanotime(&DEVFS_NODE(vp)->atime);
1529
1530         return (dev_dkqfilter(dev, ap->a_kn));
1531 }
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574 /*
1575  * Convert a vnode strategy call into a device strategy call.  Vnode strategy
1576  * calls are not limited to device DMA limits so we have to deal with the
1577  * case.
1578  *
1579  * spec_strategy(struct vnode *a_vp, struct bio *a_bio)
1580  */
1581 static int
1582 devfs_spec_strategy(struct vop_strategy_args *ap)
1583 {
1584         struct bio *bio = ap->a_bio;
1585         struct buf *bp = bio->bio_buf;
1586         struct buf *nbp;
1587         struct vnode *vp;
1588         struct mount *mp;
1589         int chunksize;
1590         int maxiosize;
1591
1592         if (bp->b_cmd != BUF_CMD_READ && LIST_FIRST(&bp->b_dep) != NULL)
1593                 buf_start(bp);
1594
1595         /*
1596          * Collect statistics on synchronous and asynchronous read
1597          * and write counts for disks that have associated filesystems.
1598          */
1599         vp = ap->a_vp;
1600         KKASSERT(vp->v_rdev != NULL);   /* XXX */
1601         if (vn_isdisk(vp, NULL) && (mp = vp->v_rdev->si_mountpoint) != NULL) {
1602                 if (bp->b_cmd == BUF_CMD_READ) {
1603                         //XXX: no idea what has changed here...
1604                         if (bp->b_flags & BIO_SYNC)
1605                                 mp->mnt_stat.f_syncreads++;
1606                         else
1607                                 mp->mnt_stat.f_asyncreads++;
1608                 } else {
1609                         if (bp->b_flags & BIO_SYNC)
1610                                 mp->mnt_stat.f_syncwrites++;
1611                         else
1612                                 mp->mnt_stat.f_asyncwrites++;
1613                 }
1614         }
1615
1616         /*
1617          * Device iosize limitations only apply to read and write.  Shortcut
1618          * the I/O if it fits.
1619          */
1620         if ((maxiosize = vp->v_rdev->si_iosize_max) == 0) {
1621                 devfs_debug(DEVFS_DEBUG_DEBUG, "%s: si_iosize_max not set!\n", dev_dname(vp->v_rdev));
1622                 maxiosize = MAXPHYS;
1623         }
1624 #if SPEC_CHAIN_DEBUG & 2
1625         maxiosize = 4096;
1626 #endif
1627         if (bp->b_bcount <= maxiosize ||
1628             (bp->b_cmd != BUF_CMD_READ && bp->b_cmd != BUF_CMD_WRITE)) {
1629                 dev_dstrategy_chain(vp->v_rdev, bio);
1630                 return (0);
1631         }
1632
1633         /*
1634          * Clone the buffer and set up an I/O chain to chunk up the I/O.
1635          */
1636         nbp = kmalloc(sizeof(*bp), M_DEVBUF, M_INTWAIT|M_ZERO);
1637         initbufbio(nbp);
1638         buf_dep_init(nbp);
1639         BUF_LOCKINIT(nbp);
1640         BUF_LOCK(nbp, LK_EXCLUSIVE);
1641         BUF_KERNPROC(nbp);
1642         nbp->b_vp = vp;
1643         nbp->b_flags = B_PAGING | (bp->b_flags & B_BNOCLIP);
1644         nbp->b_data = bp->b_data;
1645         nbp->b_bio1.bio_done = devfs_spec_strategy_done;
1646         nbp->b_bio1.bio_offset = bio->bio_offset;
1647         nbp->b_bio1.bio_caller_info1.ptr = bio;
1648
1649         /*
1650          * Start the first transfer
1651          */
1652         if (vn_isdisk(vp, NULL))
1653                 chunksize = vp->v_rdev->si_bsize_phys;
1654         else
1655                 chunksize = DEV_BSIZE;
1656         chunksize = maxiosize / chunksize * chunksize;
1657 #if SPEC_CHAIN_DEBUG & 1
1658         devfs_debug(DEVFS_DEBUG_DEBUG, "spec_strategy chained I/O chunksize=%d\n", chunksize);
1659 #endif
1660         nbp->b_cmd = bp->b_cmd;
1661         nbp->b_bcount = chunksize;
1662         nbp->b_bufsize = chunksize;     /* used to detect a short I/O */
1663         nbp->b_bio1.bio_caller_info2.index = chunksize;
1664
1665 #if SPEC_CHAIN_DEBUG & 1
1666         devfs_debug(DEVFS_DEBUG_DEBUG, "spec_strategy: chain %p offset %d/%d bcount %d\n",
1667                 bp, 0, bp->b_bcount, nbp->b_bcount);
1668 #endif
1669
1670         dev_dstrategy(vp->v_rdev, &nbp->b_bio1);
1671
1672         if (DEVFS_NODE(vp)) {
1673                 nanotime(&DEVFS_NODE(vp)->atime);
1674                 nanotime(&DEVFS_NODE(vp)->mtime);
1675         }
1676
1677         return (0);
1678 }
1679
1680 /*
1681  * Chunked up transfer completion routine - chain transfers until done
1682  */
1683 static
1684 void
1685 devfs_spec_strategy_done(struct bio *nbio)
1686 {
1687         struct buf *nbp = nbio->bio_buf;
1688         struct bio *bio = nbio->bio_caller_info1.ptr;   /* original bio */
1689         struct buf *bp = bio->bio_buf;                  /* original bp */
1690         int chunksize = nbio->bio_caller_info2.index;   /* chunking */
1691         int boffset = nbp->b_data - bp->b_data;
1692
1693         if (nbp->b_flags & B_ERROR) {
1694                 /*
1695                  * An error terminates the chain, propogate the error back
1696                  * to the original bp
1697                  */
1698                 bp->b_flags |= B_ERROR;
1699                 bp->b_error = nbp->b_error;
1700                 bp->b_resid = bp->b_bcount - boffset +
1701                               (nbp->b_bcount - nbp->b_resid);
1702 #if SPEC_CHAIN_DEBUG & 1
1703                 devfs_debug(DEVFS_DEBUG_DEBUG, "spec_strategy: chain %p error %d bcount %d/%d\n",
1704                         bp, bp->b_error, bp->b_bcount,
1705                         bp->b_bcount - bp->b_resid);
1706 #endif
1707                 kfree(nbp, M_DEVBUF);
1708                 biodone(bio);
1709         } else if (nbp->b_resid) {
1710                 /*
1711                  * A short read or write terminates the chain
1712                  */
1713                 bp->b_error = nbp->b_error;
1714                 bp->b_resid = bp->b_bcount - boffset +
1715                               (nbp->b_bcount - nbp->b_resid);
1716 #if SPEC_CHAIN_DEBUG & 1
1717                 devfs_debug(DEVFS_DEBUG_DEBUG, "spec_strategy: chain %p short read(1) bcount %d/%d\n",
1718                         bp, bp->b_bcount - bp->b_resid, bp->b_bcount);
1719 #endif
1720                 kfree(nbp, M_DEVBUF);
1721                 biodone(bio);
1722         } else if (nbp->b_bcount != nbp->b_bufsize) {
1723                 /*
1724                  * A short read or write can also occur by truncating b_bcount
1725                  */
1726 #if SPEC_CHAIN_DEBUG & 1
1727                 devfs_debug(DEVFS_DEBUG_DEBUG, "spec_strategy: chain %p short read(2) bcount %d/%d\n",
1728                         bp, nbp->b_bcount + boffset, bp->b_bcount);
1729 #endif
1730                 bp->b_error = 0;
1731                 bp->b_bcount = nbp->b_bcount + boffset;
1732                 bp->b_resid = nbp->b_resid;
1733                 kfree(nbp, M_DEVBUF);
1734                 biodone(bio);
1735         } else if (nbp->b_bcount + boffset == bp->b_bcount) {
1736                 /*
1737                  * No more data terminates the chain
1738                  */
1739 #if SPEC_CHAIN_DEBUG & 1
1740                 devfs_debug(DEVFS_DEBUG_DEBUG, "spec_strategy: chain %p finished bcount %d\n",
1741                         bp, bp->b_bcount);
1742 #endif
1743                 bp->b_error = 0;
1744                 bp->b_resid = 0;
1745                 kfree(nbp, M_DEVBUF);
1746                 biodone(bio);
1747         } else {
1748                 /*
1749                  * Continue the chain
1750                  */
1751                 boffset += nbp->b_bcount;
1752                 nbp->b_data = bp->b_data + boffset;
1753                 nbp->b_bcount = bp->b_bcount - boffset;
1754                 if (nbp->b_bcount > chunksize)
1755                         nbp->b_bcount = chunksize;
1756                 nbp->b_bio1.bio_done = devfs_spec_strategy_done;
1757                 nbp->b_bio1.bio_offset = bio->bio_offset + boffset;
1758
1759 #if SPEC_CHAIN_DEBUG & 1
1760                 devfs_debug(DEVFS_DEBUG_DEBUG, "spec_strategy: chain %p offset %d/%d bcount %d\n",
1761                         bp, boffset, bp->b_bcount, nbp->b_bcount);
1762 #endif
1763
1764                 dev_dstrategy(nbp->b_vp->v_rdev, &nbp->b_bio1);
1765         }
1766 }
1767
1768 /*
1769  * spec_freeblks(struct vnode *a_vp, daddr_t a_addr, daddr_t a_length)
1770  */
1771 static int
1772 devfs_spec_freeblks(struct vop_freeblks_args *ap)
1773 {
1774         struct buf *bp;
1775
1776         /*
1777          * XXX: This assumes that strategy does the deed right away.
1778          * XXX: this may not be TRTTD.
1779          */
1780         KKASSERT(ap->a_vp->v_rdev != NULL);
1781         if ((dev_dflags(ap->a_vp->v_rdev) & D_CANFREE) == 0)
1782                 return (0);
1783         bp = geteblk(ap->a_length);
1784         bp->b_cmd = BUF_CMD_FREEBLKS;
1785         bp->b_bio1.bio_offset = ap->a_offset;
1786         bp->b_bcount = ap->a_length;
1787         dev_dstrategy(ap->a_vp->v_rdev, &bp->b_bio1);
1788         return (0);
1789 }
1790
1791 /*
1792  * Implement degenerate case where the block requested is the block
1793  * returned, and assume that the entire device is contiguous in regards
1794  * to the contiguous block range (runp and runb).
1795  *
1796  * spec_bmap(struct vnode *a_vp, off_t a_loffset,
1797  *           off_t *a_doffsetp, int *a_runp, int *a_runb)
1798  */
1799 static int
1800 devfs_spec_bmap(struct vop_bmap_args *ap)
1801 {
1802         if (ap->a_doffsetp != NULL)
1803                 *ap->a_doffsetp = ap->a_loffset;
1804         if (ap->a_runp != NULL)
1805                 *ap->a_runp = MAXBSIZE;
1806         if (ap->a_runb != NULL) {
1807                 if (ap->a_loffset < MAXBSIZE)
1808                         *ap->a_runb = (int)ap->a_loffset;
1809                 else
1810                         *ap->a_runb = MAXBSIZE;
1811         }
1812         return (0);
1813 }
1814
1815
1816 /*
1817  * Special device advisory byte-level locks.
1818  *
1819  * spec_advlock(struct vnode *a_vp, caddr_t a_id, int a_op,
1820  *              struct flock *a_fl, int a_flags)
1821  */
1822 /* ARGSUSED */
1823 static int
1824 devfs_spec_advlock(struct vop_advlock_args *ap)
1825 {
1826         return ((ap->a_flags & F_POSIX) ? EINVAL : EOPNOTSUPP);
1827 }
1828
1829 static void
1830 devfs_spec_getpages_iodone(struct bio *bio)
1831 {
1832         bio->bio_buf->b_cmd = BUF_CMD_DONE;
1833         wakeup(bio->bio_buf);
1834 }
1835
1836 /*
1837  * spec_getpages() - get pages associated with device vnode.
1838  *
1839  * Note that spec_read and spec_write do not use the buffer cache, so we
1840  * must fully implement getpages here.
1841  */
1842 static int
1843 devfs_spec_getpages(struct vop_getpages_args *ap)
1844 {
1845         vm_offset_t kva;
1846         int error;
1847         int i, pcount, size;
1848         struct buf *bp;
1849         vm_page_t m;
1850         vm_ooffset_t offset;
1851         int toff, nextoff, nread;
1852         struct vnode *vp = ap->a_vp;
1853         int blksiz;
1854         int gotreqpage;
1855
1856         error = 0;
1857         pcount = round_page(ap->a_count) / PAGE_SIZE;
1858
1859         /*
1860          * Calculate the offset of the transfer and do sanity check.
1861          */
1862         offset = IDX_TO_OFF(ap->a_m[0]->pindex) + ap->a_offset;
1863
1864         /*
1865          * Round up physical size for real devices.  We cannot round using
1866          * v_mount's block size data because v_mount has nothing to do with
1867          * the device.  i.e. it's usually '/dev'.  We need the physical block
1868          * size for the device itself.
1869          *
1870          * We can't use v_rdev->si_mountpoint because it only exists when the
1871          * block device is mounted.  However, we can use v_rdev.
1872          */
1873
1874         if (vn_isdisk(vp, NULL))
1875                 blksiz = vp->v_rdev->si_bsize_phys;
1876         else
1877                 blksiz = DEV_BSIZE;
1878
1879         size = (ap->a_count + blksiz - 1) & ~(blksiz - 1);
1880
1881         bp = getpbuf(NULL);
1882         kva = (vm_offset_t)bp->b_data;
1883
1884         /*
1885          * Map the pages to be read into the kva.
1886          */
1887         pmap_qenter(kva, ap->a_m, pcount);
1888
1889         /* Build a minimal buffer header. */
1890         bp->b_cmd = BUF_CMD_READ;
1891         bp->b_bcount = size;
1892         bp->b_resid = 0;
1893         bp->b_runningbufspace = size;
1894         if (size) {
1895                 runningbufspace += bp->b_runningbufspace;
1896                 ++runningbufcount;
1897         }
1898
1899         bp->b_bio1.bio_offset = offset;
1900         bp->b_bio1.bio_done = devfs_spec_getpages_iodone;
1901
1902         mycpu->gd_cnt.v_vnodein++;
1903         mycpu->gd_cnt.v_vnodepgsin += pcount;
1904
1905         /* Do the input. */
1906         vn_strategy(ap->a_vp, &bp->b_bio1);
1907
1908         crit_enter();
1909
1910         /* We definitely need to be at splbio here. */
1911         while (bp->b_cmd != BUF_CMD_DONE)
1912                 tsleep(bp, 0, "spread", 0);
1913
1914         crit_exit();
1915
1916         if (bp->b_flags & B_ERROR) {
1917                 if (bp->b_error)
1918                         error = bp->b_error;
1919                 else
1920                         error = EIO;
1921         }
1922
1923         /*
1924          * If EOF is encountered we must zero-extend the result in order
1925          * to ensure that the page does not contain garabge.  When no
1926          * error occurs, an early EOF is indicated if b_bcount got truncated.
1927          * b_resid is relative to b_bcount and should be 0, but some devices
1928          * might indicate an EOF with b_resid instead of truncating b_bcount.
1929          */
1930         nread = bp->b_bcount - bp->b_resid;
1931         if (nread < ap->a_count)
1932                 bzero((caddr_t)kva + nread, ap->a_count - nread);
1933         pmap_qremove(kva, pcount);
1934
1935         gotreqpage = 0;
1936         for (i = 0, toff = 0; i < pcount; i++, toff = nextoff) {
1937                 nextoff = toff + PAGE_SIZE;
1938                 m = ap->a_m[i];
1939
1940                 m->flags &= ~PG_ZERO;
1941
1942                 if (nextoff <= nread) {
1943                         m->valid = VM_PAGE_BITS_ALL;
1944                         vm_page_undirty(m);
1945                 } else if (toff < nread) {
1946                         /*
1947                          * Since this is a VM request, we have to supply the
1948                          * unaligned offset to allow vm_page_set_validclean()
1949                          * to zero sub-DEV_BSIZE'd portions of the page.
1950                          */
1951                         vm_page_set_validclean(m, 0, nread - toff);
1952                 } else {
1953                         m->valid = 0;
1954                         vm_page_undirty(m);
1955                 }
1956
1957                 if (i != ap->a_reqpage) {
1958                         /*
1959                          * Just in case someone was asking for this page we
1960                          * now tell them that it is ok to use.
1961                          */
1962                         if (!error || (m->valid == VM_PAGE_BITS_ALL)) {
1963                                 if (m->valid) {
1964                                         if (m->flags & PG_WANTED) {
1965                                                 vm_page_activate(m);
1966                                         } else {
1967                                                 vm_page_deactivate(m);
1968                                         }
1969                                         vm_page_wakeup(m);
1970                                 } else {
1971                                         vm_page_free(m);
1972                                 }
1973                         } else {
1974                                 vm_page_free(m);
1975                         }
1976                 } else if (m->valid) {
1977                         gotreqpage = 1;
1978                         /*
1979                          * Since this is a VM request, we need to make the
1980                          * entire page presentable by zeroing invalid sections.
1981                          */
1982                         if (m->valid != VM_PAGE_BITS_ALL)
1983                             vm_page_zero_invalid(m, FALSE);
1984                 }
1985         }
1986         if (!gotreqpage) {
1987                 m = ap->a_m[ap->a_reqpage];
1988                 devfs_debug(DEVFS_DEBUG_WARNING,
1989             "spec_getpages:(%s) I/O read failure: (error=%d) bp %p vp %p\n",
1990                         devtoname(vp->v_rdev), error, bp, bp->b_vp);
1991                 devfs_debug(DEVFS_DEBUG_WARNING,
1992             "               size: %d, resid: %d, a_count: %d, valid: 0x%x\n",
1993                     size, bp->b_resid, ap->a_count, m->valid);
1994                 devfs_debug(DEVFS_DEBUG_WARNING,
1995             "               nread: %d, reqpage: %d, pindex: %lu, pcount: %d\n",
1996                     nread, ap->a_reqpage, (u_long)m->pindex, pcount);
1997                 /*
1998                  * Free the buffer header back to the swap buffer pool.
1999                  */
2000                 relpbuf(bp, NULL);
2001                 return VM_PAGER_ERROR;
2002         }
2003         /*
2004          * Free the buffer header back to the swap buffer pool.
2005          */
2006         relpbuf(bp, NULL);
2007         return VM_PAGER_OK;
2008 }
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048 static __inline
2049 int
2050 sequential_heuristic(struct uio *uio, struct file *fp)
2051 {
2052         /*
2053          * Sequential heuristic - detect sequential operation
2054          */
2055         if ((uio->uio_offset == 0 && fp->f_seqcount > 0) ||
2056             uio->uio_offset == fp->f_nextoff) {
2057                 int tmpseq = fp->f_seqcount;
2058                 /*
2059                  * XXX we assume that the filesystem block size is
2060                  * the default.  Not true, but still gives us a pretty
2061                  * good indicator of how sequential the read operations
2062                  * are.
2063                  */
2064                 tmpseq += (uio->uio_resid + BKVASIZE - 1) / BKVASIZE;
2065                 if (tmpseq > IO_SEQMAX)
2066                         tmpseq = IO_SEQMAX;
2067                 fp->f_seqcount = tmpseq;
2068                 return(fp->f_seqcount << IO_SEQSHIFT);
2069         }
2070
2071         /*
2072          * Not sequential, quick draw-down of seqcount
2073          */
2074         if (fp->f_seqcount > 1)
2075                 fp->f_seqcount = 1;
2076         else
2077                 fp->f_seqcount = 0;
2078         return(0);
2079 }