Adding own fcntl
Adding own fcntl
- Subject: Adding own fcntl
- From: Jorgen Lundman <email@hidden>
- Date: Mon, 09 May 2016 12:59:08 +0900
Dear list,
So, IllumOS OpenZFS has fcntl(F_FREESP), and even though XNU does not have
it, the testing environment uses it for some of its tests. So I do not need
it, but thought it would be "amusing" to support it anyway.
I define the standard:
#define F_FREESP_IOC _IOW('Z', 11, struct flock)
#define F_FREESP IOCBASECMD(F_FREESP)
Where I made up 'Z' and 11 (although, 11 is the value in IllumOS). I use
_IOW as it should copyin() a struct flock.
The userland program simply calls:
struct flock fl;
if (fcntl(fd, F_FREESP_IOC, &fl) != 0) {
and in kernel I have the handler for:
case F_FREESP:
The end of the giant switch in fcntl_nocancel() bsd/kern/kern_descrip.c
appears to check for IOC_IN and calls copyin() before passing it to me with
VNOP_IOCTL().
Except that it doesn't.
I simply get EFAULT from fcntl(), and clearly I am doing something wrong.
dtrace tells me this:
* userland:
24580/0x149320: write_nocancel(0x1, "Address 0x7fff506cfbf0\n\0", 0x17)
= 23 0
24580/0x149320: fcntl(0x3, 0x80185A0B, 0x506CFBF0) = -1 Err#14
(Already truncated here?)
* kernel.
fcntl_nocancel(proc_t p, struct fcntl_nocancel_args *uap, int32_t *retval)
# dtrace -n 'fcntl_nocancel:entry { printf("%s %p %p %p", execname, arg0,
arg1, arg2); tracemem(arg1, 100, 100);}'
0 191560 fcntl_nocancel:entry randfree_file ffffff8022fcca78
ffffff801c3d6000 ffffff801c3d6040
0 1 2 3 4 5 6 7 8 9 a b c d e f
0: 03 00 00 00 00 00 00 00 61 00 00 00 00 00 00 00
10: 00 c3 6c 50 ff 7f 00 00 00 70 00 00 00 00 00 00
0 191560 fcntl_nocancel:entry randfree_file ffffff8022fcca78
ffffff801c3d6000 ffffff801c3d6040
0 1 2 3 4 5 6 7 8 9 a b c d e f
0: 03 00 00 00 00 00 00 00 0b 5a 18 80 00 00 00 00
10: f0 fb 6c 50 00 00 00 00 01 00 00 00 00 00 00 00
So the userland call ends up calling fcntl_nocancel() twice, the first time
the uap->arg is 0x7fff506cc300 and the second time it has been truncated to
32bit, but the correct 32bits, 0x506cfbf0.
The first call is off by 0x38f0 (14576).
So maybe something goes wrong with the 32/64 syscall layer, but I am unsure
how I can fix it. If I use _IO() definition (ie, IOC_VOID) it does call my
ioctl handler, but the ptr is wrong, and if I call copyin() I get the same
EFAULT error. It looks like maybe I could do 0x38f0 math on the ptr, but
that can't be right.. surely..
Any insight?
Lund
--
Jorgen Lundman | <email@hidden>
Unix Administrator | +81 (0)90-5578-8500 (work)
Shibuya-ku, Tokyo | +81 (0)80-2090-5800 (cell)
Japan | +81 (0)3 -3375-1767 (home)
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Filesystem-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden