tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Issues with lseek(2) on a block device



mlelstv%serpens.de@localhost (Michael van Elst) writes:

>But it also does not work for wedges or device mapper volumes
>(zfs vol probably fail too) as these don't implement the
>used internal ioctl for disk devices. At least that part
>would be easy to fix, but of questionable value.



Like this:

Index: sys/miscfs/specfs/spec_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/miscfs/specfs/spec_vnops.c,v
retrieving revision 1.218
diff -p -u -r1.218 spec_vnops.c
--- sys/miscfs/specfs/spec_vnops.c      22 Apr 2023 15:32:49 -0000      1.218
+++ sys/miscfs/specfs/spec_vnops.c      22 Feb 2024 08:54:16 -0000
@@ -727,11 +727,11 @@ spec_open(void *v)
        enum kauth_device_req req;
        specnode_t *sn, *sn1;
        specdev_t *sd;
+       int dtype;
        spec_ioctl_t ioctl;
        u_int gen = 0;
        const char *name = NULL;
        bool needclose = false;
-       struct partinfo pi;
 
        KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE);
        KASSERTMSG(vp->v_type == VBLK || vp->v_type == VCHR, "type=%d",
@@ -1038,11 +1038,23 @@ spec_open(void *v)
         * forbidden to devsw_detach until closed).  So it is safe to
         * query cdev_type unconditionally here.
         */
-       if (cdev_type(dev) == D_DISK) {
-               ioctl = vp->v_type == VCHR ? cdev_ioctl : bdev_ioctl;
-               if ((*ioctl)(dev, DIOCGPARTINFO, &pi, FREAD, curlwp) == 0)
-                       uvm_vnp_setsize(vp,
-                           (voff_t)pi.pi_secsize * pi.pi_size);
+       switch (vp->v_type) {
+       case VCHR:
+               ioctl = bdev_ioctl;
+               dtype = cdev_type(dev);
+               break;
+       default:
+               ioctl = bdev_ioctl;
+               dtype = bdev_type(dev);
+               break;
+       }
+       if (dtype == D_DISK) {
+               off_t count;
+               u_int sz;
+
+               if ((*ioctl)(dev, DIOCGMEDIASIZE, &count, FREAD, curlwp) == 0
+                   && (*ioctl)(dev, DIOCGSECTORSIZE, &sz, FREAD, curlwp) == 0)
+                       uvm_vnp_setsize(vp, (voff_t)count * sz);
        }
 
        /* Success!  */



Home | Main Index | Thread Index | Old Index