Ah ok, so the code in

libsyscall/wrappers/cancelable/fcntl-base.c

has a switch() with a large list of fcntls that are to be handled as "void
*" and everything else is int *.

All the void * entries listed there, is handled in bsd/kern/kern_descrip.c,
and will not reach the default case. So I can't "borrow" an legacy fcntl
for my own purposes.

So it would seem it is not supported to add your own fcntl (non-int) calls.

Lund


Jorgen Lundman wrote:
> 
> 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 protected]>
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 protected])
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/filesystem-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to