tech-kern archive

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

Re: block/dk devices and lseek()



On Tue, 30 Nov 2021, Michael van Elst wrote:

When a disk device is opened, the DIOCGPARTINFO ioctl is used to
query the size of the disk and cache it in the vnode.

The dk driver doesn't represent a disk and doesn't support DIOCGPARTINFO.
It does support DIOCGWEDGEINFO, DIOCGDISKINFO and DIOCGSECTORSIZE +
DIOCGMEDIASIZE that would reveal the information.

The same is true for the dm driver.


But that's only half of the story.

[...]


Thanks, that was very helpful and I've come up with this:

---START---
diff -urN a/sys/miscfs/specfs/spec_vnops.c b/sys/miscfs/specfs/spec_vnops.c
--- a/sys/miscfs/specfs/spec_vnops.c	2021-07-18 23:57:14.000000000 +0000
+++ b/sys/miscfs/specfs/spec_vnops.c	2021-12-04 19:33:36.530961000 +0000
@@ -508,7 +508,7 @@
 	spec_ioctl_t ioctl;
 	u_int gen;
 	const char *name;
-	struct partinfo pi;
+	voff_t msize;

 	l = curlwp;
 	vp = ap->a_vp;
@@ -667,10 +667,10 @@


 	ioctl = vp->v_type == VCHR ? cdev_ioctl : bdev_ioctl;
-	error = (*ioctl)(vp->v_rdev, DIOCGPARTINFO, &pi, FREAD, curlwp);
-	if (error == 0)
-		uvm_vnp_setsize(vp, (voff_t)pi.pi_secsize * pi.pi_size);
-
+	error = (*ioctl)(vp->v_rdev, DIOCGMEDIASIZE, &msize, FREAD, curlwp);
+ 	if (error == 0)
+		uvm_vnp_setsize(vp, (voff_t)msize);
+
 	return 0;
 }

---END---

I've used DIOCGMEDIASIZE which seems to work on all the disk-type devices
that I've got, and this also fixes the original problem I was trying to
work-around (PR# 56530).

Also now:
$ for f in /dev/rwd0 /dev/rdk{0..14}; do echo $f: $(sudo ./a.out $f); done
/dev/rwd0: 500107862016
/dev/rdk0: 314572800
/dev/rdk1: 629145600
/dev/rdk2: 134217728
/dev/rdk3: 4194304
/dev/rdk4: 4294967296
/dev/rdk5: 303279636480
/dev/rdk6: 53687091200
/dev/rdk7: 4296015872
/dev/rdk8: 8388608
/dev/rdk9: 21474836480
/dev/rdk10: 5368709120
/dev/rdk11: 10737418240
/dev/rdk12: 8388608
/dev/rdk13: 32212254720
/dev/rdk14: 53687091200
$

And also:
$ for f in /dev/wd0 /dev/dk{0..14}; do echo $f: $(stat -f '%z' $f); done
/dev/wd0: 0
/dev/dk0: 314572800
/dev/dk1: 629145600
/dev/dk2: 134217728
/dev/dk3: 4194304
/dev/dk4: 4294967296
/dev/dk5: 303279636480
/dev/dk6: 53687091200
/dev/dk7: 4296015872
/dev/dk8: 8388608
/dev/dk9: 0
/dev/dk10: 5368709120
/dev/dk11: 10737418240
/dev/dk12: 8388608
/dev/dk13: 32212254720
/dev/dk14: 53687091200
$

however, stat -f '%z' now working (for rdk*) I consider a bonus: Using
stat to get the size of non-regular files is an invalid op anyway (I've
never known this to work on Linux or FreeBSD). I was just surprised to
see it working in some instances and not in others.

Anyway, if this change is acceptable, then I can simplify the patch in
PR# 56530.

Thanks again,
-RVP



Home | Main Index | Thread Index | Old Index