Re: which way to update export_args structure?

2018-10-23 Thread John-Mark Gurney
Brooks Davis wrote this message on Mon, Oct 22, 2018 at 16:05 +:
> > +   switch (len) {
> > +   case (sizeof(struct oexport_args)):
> > +   case (sizeof(struct o2export_args)):
> > +   memset(, 0, sizeof(export));
> 
> I think this is now redundant.
> 
> > +   memset(, 0, sizeof(o2export));
> 
> This is certainly redundant given that you immediately copy over it.

This is not redundant if sizeof oexport_args < sizeof o2export, and
len == sizeof oexport_args...  It zeros out the remaining of the buffer..

> > +   memcpy(, bufp, len);

-- 
  John-Mark Gurney  Voice: +1 415 225 5579

 "All that I will do, has been done, All that I have, has not."


signature.asc
Description: PGP signature


Re: which way to update export_args structure?

2018-10-23 Thread Enji Cooper

> On Oct 22, 2018, at 09:49, Josh Paetzel  wrote:
> 
> 
> 
>> On Mon, Oct 22, 2018, at 11:05 AM, Brooks Davis wrote:
>> 
>> 
>> This is the direction I'd been thinking.  FWIW, the usecase is more that
>> once you've moved away from the struct it's easy to make incremental
>> changes then to use a 32-bit mountd on a 64-bit kernel.  Moving toward
>> size-independent interfaces helps both causes though.
>> 
>> -- Brooks
>> Email had 1 attachment:
>> + signature.asc
>>  1k (application/pgp-signature)
> 
> 
> Brooks,
> 
> What is the benefit or usecase for running a 32 bit mountd on a 64 bit kernel?

There generally isn’t a case for doing this, but running a 32-bit mountd in a 
32-bit chroot can allow someone with a working 32-bit environment at a company 
(for instance) to rebuild environments which rely on NFS mounts and the like.

This is an esoteric usecase, but I’ve seen it used before (and I’ve used it 
myself ;)..).

I don’t think this niche usecase should hinder forward progress in terms of 
modernizing the base OS though. Biarch usecases are diminishing over time.

-Enji
___
freebsd-current@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: which way to update export_args structure?

2018-10-22 Thread Brooks Davis
On Mon, Oct 22, 2018 at 09:59:52PM +, Rick Macklem wrote:
> 
> 
> From: owner-freebsd-curr...@freebsd.org  
> on behalf of Rick Macklem 
> Sent: Monday, October 22, 2018 5:24 PM
> To: Brooks Davis
> Cc: FreeBSD Current; Josh Paetzel
> Subject: Re: which way to update export_args structure?
> 
> Brooks Davis wrote:
> On Sat, Oct 20, 2018 at 01:17:37AM +, Rick Macklem wrote:
> [lots of stuff snipped]
> >> + if (vfs_getopt(mp->mnt_optnew, "export", , ) == 0) {
> >> + /* Assume that there is only 1 ABI for each length. 
> >> */
> >> + switch (len) {
> >> + case (sizeof(struct oexport_args)):
> >> + case (sizeof(struct o2export_args)):
> ...
> >> + memset(, 0, sizeof(o2export));
> >
> >This is certainly redundant given that you immediately copy over it.
> Actually, I just looked and this code is correct. The trick is that "len" 
> might
> equal sizeof(struct oexport_args) which is < sizeof(struct o2export_args).
> As such, the memcpy() may only replace the first fields of "struct 
> o2export_args".
> I've added a comment to the patch to clarify this.

Ah, that makes sense.

-- Brooks


signature.asc
Description: PGP signature


Re: which way to update export_args structure?

2018-10-22 Thread Rick Macklem



From: owner-freebsd-curr...@freebsd.org  on 
behalf of Rick Macklem 
Sent: Monday, October 22, 2018 5:24 PM
To: Brooks Davis
Cc: FreeBSD Current; Josh Paetzel
Subject: Re: which way to update export_args structure?

Brooks Davis wrote:
On Sat, Oct 20, 2018 at 01:17:37AM +, Rick Macklem wrote:
[lots of stuff snipped]
>> + if (vfs_getopt(mp->mnt_optnew, "export", , ) == 0) {
>> + /* Assume that there is only 1 ABI for each length. */
>> + switch (len) {
>> + case (sizeof(struct oexport_args)):
>> + case (sizeof(struct o2export_args)):
...
>> + memset(, 0, sizeof(o2export));
>
>This is certainly redundant given that you immediately copy over it.
Actually, I just looked and this code is correct. The trick is that "len" might
equal sizeof(struct oexport_args) which is < sizeof(struct o2export_args).
As such, the memcpy() may only replace the first fields of "struct 
o2export_args".
I've added a comment to the patch to clarify this.

rick

___
freebsd-current@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: which way to update export_args structure?

2018-10-22 Thread Rick Macklem
Brooks Davis wrote:
On Sat, Oct 20, 2018 at 01:17:37AM +, Rick Macklem wrote:
[lots of stuff snipped]
>> + if (error == 0) {
>> + gotexp = 0;
>> + memset(, 0, sizeof(export));
>> + if (vfs_getopt(mp->mnt_optnew, "export.exflags", ,
>> + ) == 0) {
>> + gotexp = 1;
>> + export.ex_flags = strtouq(bufp, , 0);
>> + if (endptr == bufp)
>> + export_error = EINVAL;
>> + }
>
>This pattern involving strtouq seems wrong to me.  We should probably
>pass a pointer to the integer type (which should always be an explicitly
>sized type).
Thanks for noticing this. I was "on the fence" w.r.t. whether the arguments 
should
all be architecture neutral (ascii representation or ???).
(I didn't bother doing the code for the net addresses in ascii notation.)

It looks like you don't see that as needed, so I will just pass the binary 
numbers in.
(We could put them in Big Endian order, if someone thinks that is necessary?)

>If it didn't contradict the first sentence of the description in
>vfs_getopt.9, I'd say we should pass int and long values in the length
>with a NULL buffer.
Heh, heh. That would be a sneaky hack. I like it, but will resist and use the 
bufp.

[more stuff snipped]
>> + if (vfs_getopt(mp->mnt_optnew, "export", , ) == 0) {
>> + /* Assume that there is only 1 ABI for each length. */
>> + switch (len) {
>> + case (sizeof(struct oexport_args)):
>> + case (sizeof(struct o2export_args)):
>> + memset(, 0, sizeof(export));
>
>I think this is now redundant.
I'll be looking at the code to-day, but I think there is at least one field
(ex_suppgroups) that needs to be set NULL so that the free() won't blow up.
(I tend to bzero()/memset(0) so that any future additional fields don't have to 
be
explicitly set 0/NULL in the compatibility code, but it there aren't currently 
any,
I may take this out. This code doesn't get executed frequently, so efficiency at
the "save a few instructions" level doesn't matter, imho.)

>> + memset(, 0, sizeof(o2export));
>
>This is certainly redundant given that you immediately copy over it.
Yep. This was just cruft left over from a previous version of the patch.

>This is the direction I'd been thinking.  FWIW, the usecase is more that
>once you've moved away from the struct it's easy to make incremental
>changes then to use a 32-bit mountd on a 64-bit kernel.  Moving toward
>size-independent interfaces helps both causes though.

Cool. I'll finish the patch to-day and then let Josh work on mountd.c.

Thanks for your comments, rick

___
freebsd-current@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: which way to update export_args structure?

2018-10-22 Thread Brooks Davis
On Mon, Oct 22, 2018 at 11:49:23AM -0500, Josh Paetzel wrote:
> 
> 
> On Mon, Oct 22, 2018, at 11:05 AM, Brooks Davis wrote:
> 
> > 
> > This is the direction I'd been thinking.  FWIW, the usecase is more that
> > once you've moved away from the struct it's easy to make incremental
> > changes then to use a 32-bit mountd on a 64-bit kernel.  Moving toward
> > size-independent interfaces helps both causes though.

> What is the benefit or usecase for running a 32 bit mountd on a 64 bit kernel?

In practice there isn't much of one.  If the support had been there, I'd
have tried to use it in CheriBSD to run with our 128-bit pointers.  The
bigger benefit is that now when you want to add something you just add
it and handle the case when it's missing rather than having to add
another compat shim for old structs.

FWIW, I don't feel all that strongly about this case.  If you two don't
find it worthwhile to make this change, that's entierly reasonable.  It
just felt like the use of the export struct within the nmount interface
was a conversion bandaid vs an intentional decision.

-- Brooks


signature.asc
Description: PGP signature


Re: which way to update export_args structure?

2018-10-22 Thread Josh Paetzel



On Mon, Oct 22, 2018, at 11:05 AM, Brooks Davis wrote:

> 
> This is the direction I'd been thinking.  FWIW, the usecase is more that
> once you've moved away from the struct it's easy to make incremental
> changes then to use a 32-bit mountd on a 64-bit kernel.  Moving toward
> size-independent interfaces helps both causes though.
> 
> -- Brooks
> Email had 1 attachment:
> + signature.asc
>   1k (application/pgp-signature)


Brooks,

What is the benefit or usecase for running a 32 bit mountd on a 64 bit kernel?

-- 

Thanks,

Josh Paetzel
___
freebsd-current@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: which way to update export_args structure?

2018-10-22 Thread Brooks Davis
On Sat, Oct 20, 2018 at 01:17:37AM +, Rick Macklem wrote:
> Brooks Davis wrote:
> > Yes, I think that's the right way foward.  Thanks for following up.
> >Rick Macklem wrote:
> >> Just in case you missed it in the email thread, in your general question 
> >> below...
> >> Did you mean/suggest that the fields of "struct export_args" be passed in 
> >> as
> >> separate options to nmount(2)?
> >>
> >> This sounds like a reasonable idea to me and I can ping Josh Paetzel 
> >> w.r.t. the
> >> changes to mountd.c to do it. (We are still in the testing stage for the 
> >> updated
> >> struct, so we might as well get that working first.)
> >>
> Well, Josh and I now have the code working via. passing the export_args
> structure into the kernel using the "export"  nmount(2) option.
> 
> I have coded a partial patch (not complete nor tested) to pass the fields in 
> as
> separate nmount(2) arguments. Since the patch has gotten fairly large
> already, I wanted to see if people do think this is the correct approach.
> (I'll admit I don't understand why having the arguments would matter, given
>  that only mountd does it. Would anyone run a 32bit mountd on a 64bit kernel?)
> 
> Anyhow, here's the partial patch showing the main changes when going from
> passing in "struct export_args" to passing in separate fields:
> 
> --- kern/vfs_mount.c.nofsid2  2018-10-16 23:45:33.540348000 -0400
> +++ kern/vfs_mount.c  2018-10-19 20:01:14.92737 -0400
> @@ -277,6 +277,7 @@ vfs_buildopts(struct uio *auio, struct v
>   size_t memused, namelen, optlen;
>   unsigned int i, iovcnt;
>   int error;
> + char *cp;
>  
>   opts = malloc(sizeof(struct vfsoptlist), M_MOUNT, M_WAITOK);
>   TAILQ_INIT(opts);
> @@ -325,7 +326,7 @@ vfs_buildopts(struct uio *auio, struct v
>   }
>   if (optlen != 0) {
>   opt->len = optlen;
> - opt->value = malloc(optlen, M_MOUNT, M_WAITOK);
> + opt->value = malloc(optlen + 1, M_MOUNT, M_WAITOK);
>   if (auio->uio_segflg == UIO_SYSSPACE) {
>   bcopy(auio->uio_iov[i + 1].iov_base, opt->value,
>   optlen);
> @@ -335,6 +336,8 @@ vfs_buildopts(struct uio *auio, struct v
>   if (error)
>   goto bad;
>   }
> + cp = (char *)opt->value;
> + cp[optlen] = '\0';
>   }
>   }
>   vfs_sanitizeopts(opts);
> @@ -961,6 +964,8 @@ vfs_domount_update(
>   int error, export_error, i, len;
>   uint64_t flag;
>   struct o2export_args o2export;
> + char *endptr;
> + int gotexp;
>  
>   ASSERT_VOP_ELOCKED(vp, __func__);
>   KASSERT((fsflags & MNT_UPDATE) != 0, ("MNT_UPDATE should be here"));
> @@ -1033,36 +1038,117 @@ vfs_domount_update(
>  
>   export_error = 0;
>   /* Process the export option. */
> - if (error == 0 && vfs_getopt(mp->mnt_optnew, "export", ,
> - ) == 0) {
> - /* Assume that there is only 1 ABI for each length. */
> - switch (len) {
> - case (sizeof(struct oexport_args)):
> - case (sizeof(struct o2export_args)):
> - memset(, 0, sizeof(export));
> - memset(, 0, sizeof(o2export));
> - memcpy(, bufp, len);
> - export.ex_flags = (u_int)o2export.ex_flags;
> - export.ex_root = o2export.ex_root;
> - export.ex_anon = o2export.ex_anon;
> - export.ex_addr = o2export.ex_addr;
> - export.ex_addrlen = o2export.ex_addrlen;
> - export.ex_mask = o2export.ex_mask;
> - export.ex_masklen = o2export.ex_masklen;
> - export.ex_indexfile = o2export.ex_indexfile;
> - export.ex_numsecflavors = o2export.ex_numsecflavors;
> - for (i = 0; i < MAXSECFLAVORS; i++)
> - export.ex_secflavors[i] =
> - o2export.ex_secflavors[i];
> - export_error = vfs_export(mp, );
> - break;
> - case (sizeof(export)):
> - bcopy(bufp, , len);
> - export_error = vfs_export(mp, );
> - break;
> - default:
> - export_error = EINVAL;
> - break;
> + if (error == 0) {
> + gotexp = 0;
> + memset(, 0, sizeof(export));
> + if (vfs_getopt(mp->mnt_optnew, "export.exflags", ,
> + ) == 0) {
> + gotexp = 1;
> + export.ex_flags = strtouq(bufp, , 0);
> + if (endptr == bufp)
> + export_error = EINVAL;
> + }

This pattern involving 

Re: which way to update export_args structure?

2018-10-19 Thread Rick Macklem
Brooks Davis wrote:
> Yes, I think that's the right way foward.  Thanks for following up.
>Rick Macklem wrote:
>> Just in case you missed it in the email thread, in your general question 
>> below...
>> Did you mean/suggest that the fields of "struct export_args" be passed in as
>> separate options to nmount(2)?
>>
>> This sounds like a reasonable idea to me and I can ping Josh Paetzel w.r.t. 
>> the
>> changes to mountd.c to do it. (We are still in the testing stage for the 
>> updated
>> struct, so we might as well get that working first.)
>>
Well, Josh and I now have the code working via. passing the export_args
structure into the kernel using the "export"  nmount(2) option.

I have coded a partial patch (not complete nor tested) to pass the fields in as
separate nmount(2) arguments. Since the patch has gotten fairly large
already, I wanted to see if people do think this is the correct approach.
(I'll admit I don't understand why having the arguments would matter, given
 that only mountd does it. Would anyone run a 32bit mountd on a 64bit kernel?)

Anyhow, here's the partial patch showing the main changes when going from
passing in "struct export_args" to passing in separate fields:

--- kern/vfs_mount.c.nofsid22018-10-16 23:45:33.540348000 -0400
+++ kern/vfs_mount.c2018-10-19 20:01:14.92737 -0400
@@ -277,6 +277,7 @@ vfs_buildopts(struct uio *auio, struct v
size_t memused, namelen, optlen;
unsigned int i, iovcnt;
int error;
+   char *cp;
 
opts = malloc(sizeof(struct vfsoptlist), M_MOUNT, M_WAITOK);
TAILQ_INIT(opts);
@@ -325,7 +326,7 @@ vfs_buildopts(struct uio *auio, struct v
}
if (optlen != 0) {
opt->len = optlen;
-   opt->value = malloc(optlen, M_MOUNT, M_WAITOK);
+   opt->value = malloc(optlen + 1, M_MOUNT, M_WAITOK);
if (auio->uio_segflg == UIO_SYSSPACE) {
bcopy(auio->uio_iov[i + 1].iov_base, opt->value,
optlen);
@@ -335,6 +336,8 @@ vfs_buildopts(struct uio *auio, struct v
if (error)
goto bad;
}
+   cp = (char *)opt->value;
+   cp[optlen] = '\0';
}
}
vfs_sanitizeopts(opts);
@@ -961,6 +964,8 @@ vfs_domount_update(
int error, export_error, i, len;
uint64_t flag;
struct o2export_args o2export;
+   char *endptr;
+   int gotexp;
 
ASSERT_VOP_ELOCKED(vp, __func__);
KASSERT((fsflags & MNT_UPDATE) != 0, ("MNT_UPDATE should be here"));
@@ -1033,36 +1038,117 @@ vfs_domount_update(
 
export_error = 0;
/* Process the export option. */
-   if (error == 0 && vfs_getopt(mp->mnt_optnew, "export", ,
-   ) == 0) {
-   /* Assume that there is only 1 ABI for each length. */
-   switch (len) {
-   case (sizeof(struct oexport_args)):
-   case (sizeof(struct o2export_args)):
-   memset(, 0, sizeof(export));
-   memset(, 0, sizeof(o2export));
-   memcpy(, bufp, len);
-   export.ex_flags = (u_int)o2export.ex_flags;
-   export.ex_root = o2export.ex_root;
-   export.ex_anon = o2export.ex_anon;
-   export.ex_addr = o2export.ex_addr;
-   export.ex_addrlen = o2export.ex_addrlen;
-   export.ex_mask = o2export.ex_mask;
-   export.ex_masklen = o2export.ex_masklen;
-   export.ex_indexfile = o2export.ex_indexfile;
-   export.ex_numsecflavors = o2export.ex_numsecflavors;
-   for (i = 0; i < MAXSECFLAVORS; i++)
-   export.ex_secflavors[i] =
-   o2export.ex_secflavors[i];
-   export_error = vfs_export(mp, );
-   break;
-   case (sizeof(export)):
-   bcopy(bufp, , len);
-   export_error = vfs_export(mp, );
-   break;
-   default:
-   export_error = EINVAL;
-   break;
+   if (error == 0) {
+   gotexp = 0;
+   memset(, 0, sizeof(export));
+   if (vfs_getopt(mp->mnt_optnew, "export.exflags", ,
+   ) == 0) {
+   gotexp = 1;
+   export.ex_flags = strtouq(bufp, , 0);
+   if (endptr == bufp)
+   export_error = EINVAL;
+   }
+   if (vfs_getopt(mp->mnt_optnew, "export.root", ,
+   ) == 0) {
+   gotexp = 1;
+   export.ex_root 

Re: which way to update export_args structure?

2018-10-03 Thread Rick Macklem
Brooks Davis wrote:
>On Wed, Oct 03, 2018 at 12:40:27AM +, Rick Macklem wrote:
>> Hi,
>>
>> I am working on updating "struct export_args" to fix/add a few things.
>> One of these is that "ex_flags" is an int, but the flags are defined in 
>> mount.h
>> as MNT_xx bits that now exceed 32bits (mnt_flag is now uint64_t).
>> For now, this doesn't break anything, since the flags used by ex_flags are
>> all defined in the low order 32bits but...it seems like this should be 
>> addressed
>> by a new version of "struct export_args".
>>
>> I have two versions of the updated structure:
>> A)
>> struct export_args {
>>   uint64_t ex_flags;  /* export related flags */
>>   uid_t   ex_root;/* mapping for root uid */
>>   struct  xucred ex_anon; /* mapping for anonymous user */
>>   struct  sockaddr *ex_addr;  /* net address to which exported */
>>   u_char  ex_addrlen; /* and the net address length */
>>   struct  sockaddr *ex_mask;  /* mask of valid bits in saddr */
>>   u_char  ex_masklen; /* and the smask length */
>>   char*ex_indexfile;  /* index file for WebNFS URLs */
>>   int ex_numsecflavors;   /* security flavor count */
>>   int ex_secflavors[MAXSECFLAVORS]; /* list of security flavors */
>>   int32_t ex_fsid;/* mnt_stat.f_fsid.val[0] if */
>>   /* MNT_EXPORTFSID set in ex_flags64 */
>>   gid_t   *ex_suppgroups; /* Supplemental groups if */
>>   /* ex_anon.cr_ngroups > XU_NGROUPS */
>> };
>> B)
>> struct export_args {
>>   int ex_flags;   /* export related flags */
>>   uid_t   ex_root;/* mapping for root uid */
>>   struct  xucred ex_anon; /* mapping for anonymous user */
>>   struct  sockaddr *ex_addr;  /* net address to which exported */
>>   u_char  ex_addrlen; /* and the net address length */
>>   struct  sockaddr *ex_mask;  /* mask of valid bits in saddr */
>>   u_char  ex_masklen; /* and the smask length */
>>   char*ex_indexfile;  /* index file for WebNFS URLs */
>>   int ex_numsecflavors;   /* security flavor count */
>>   int ex_secflavors[MAXSECFLAVORS]; /* list of security flavors */
>>   uint64_t ex_flagshighbits;  /* High order bits of mnt_flag */
>>   int32_t ex_fsid;/* mnt_stat.f_fsid.val[0] if */
>>   /* MNT_EXPORTFSID set in ex_flags64 */
>>   gid_t   *ex_suppgroups; /* Supplemental groups if */
>>   /* ex_anon.cr_ngroups > XU_NGROUPS */
>> };
>>
>> A) does the obvious thing. Unfortunately, this changes the vfs KABI
>> (specifically the function vfs_oexport_conv()) such that a file system
>> module compiled with an unpatched mount.h could crash a patched system.
>> As such, I think it couldn't be MFC'd and would be stuck in head/current
>> until FreeBSD13 (or FreeBSD14 if 13 gets skipped over;-).
>>
>> B) doesn't change any fields, but adds a second ex_flagshighbits for the high
>> order bit. Since it only adds fields where none of those bits are used after
>> the exports are processed by vfs_export() and, as such, will not break
>> the VFS KABI, since vfs_domount_update() differentiates which version
>> of export_args is being used.
>> As such, I believe this version can be MFC'd. However, it does seem confusing
>> to have the two ex_flags fields for the low and high 32bits.
>
>I see you've found a way to do compatibility for a new ABI.  If you
>wanted to avoid changing the struct size, there is 3 bytes of usable
>padding after each ex_addrlen and ex_masklen.
Actually, you want the size to change, since that is how the code detects
a different version of the struct. (Take a look around line# 1037 of 
vfs_mount.c).
The additions are a lot more than 6bytes. The reason I was a little hesitant to
change ex_flags to 64bits is that it makes the compatibility code a little 
messier,
but it isn't that bad.
The tricky one is vfs_oexport_conv(), because it doesn't know the size of the
struct being passed in via a pointer. My current solution is to have this 
function
remain in place for old file system binaries only and add a new function with
a different name (and takes a struct length argument as well as the pointer)
for the new code. This function is only used by three file systems to handle the
old pre-nmount(2) syscall.

>One general question: why does export_args still exist as an interface
>between userspace and the kernel?  It's passed via nmount so it seems
>like the individual entries should be elements in the vector instead.
>This would be much friendlier if one wanted to do 32-bit compat support
>for mountd.
Not sure what you are thinking of here. Right now "struct export_args" is the 
data
for a mount option 

Re: which way to update export_args structure?

2018-10-03 Thread Brooks Davis
On Wed, Oct 03, 2018 at 12:40:27AM +, Rick Macklem wrote:
> Hi,
> 
> I am working on updating "struct export_args" to fix/add a few things.
> One of these is that "ex_flags" is an int, but the flags are defined in 
> mount.h
> as MNT_xx bits that now exceed 32bits (mnt_flag is now uint64_t).
> For now, this doesn't break anything, since the flags used by ex_flags are
> all defined in the low order 32bits but...it seems like this should be 
> addressed
> by a new version of "struct export_args".
> 
> I have two versions of the updated structure:
> A)
> struct export_args {
>   uint64_t ex_flags;  /* export related flags */
>   uid_t   ex_root;/* mapping for root uid */
>   struct  xucred ex_anon; /* mapping for anonymous user */
>   struct  sockaddr *ex_addr;  /* net address to which exported */
>   u_char  ex_addrlen; /* and the net address length */
>   struct  sockaddr *ex_mask;  /* mask of valid bits in saddr */
>   u_char  ex_masklen; /* and the smask length */
>   char*ex_indexfile;  /* index file for WebNFS URLs */
>   int ex_numsecflavors;   /* security flavor count */
>   int ex_secflavors[MAXSECFLAVORS]; /* list of security flavors */
>   int32_t ex_fsid;/* mnt_stat.f_fsid.val[0] if */
>   /* MNT_EXPORTFSID set in ex_flags64 */
>   gid_t   *ex_suppgroups; /* Supplemental groups if */
>   /* ex_anon.cr_ngroups > XU_NGROUPS */
> };
> B)
> struct export_args {
>   int ex_flags;   /* export related flags */
>   uid_t   ex_root;/* mapping for root uid */
>   struct  xucred ex_anon; /* mapping for anonymous user */
>   struct  sockaddr *ex_addr;  /* net address to which exported */
>   u_char  ex_addrlen; /* and the net address length */
>   struct  sockaddr *ex_mask;  /* mask of valid bits in saddr */
>   u_char  ex_masklen; /* and the smask length */
>   char*ex_indexfile;  /* index file for WebNFS URLs */
>   int ex_numsecflavors;   /* security flavor count */
>   int ex_secflavors[MAXSECFLAVORS]; /* list of security flavors */
>   uint64_t ex_flagshighbits;  /* High order bits of mnt_flag */
>   int32_t ex_fsid;/* mnt_stat.f_fsid.val[0] if */
>   /* MNT_EXPORTFSID set in ex_flags64 */
>   gid_t   *ex_suppgroups; /* Supplemental groups if */
>   /* ex_anon.cr_ngroups > XU_NGROUPS */
> };
> 
> A) does the obvious thing. Unfortunately, this changes the vfs KABI
> (specifically the function vfs_oexport_conv()) such that a file system
> module compiled with an unpatched mount.h could crash a patched system.
> As such, I think it couldn't be MFC'd and would be stuck in head/current
> until FreeBSD13 (or FreeBSD14 if 13 gets skipped over;-).
> 
> B) doesn't change any fields, but adds a second ex_flagshighbits for the high
> order bit. Since it only adds fields where none of those bits are used after
> the exports are processed by vfs_export() and, as such, will not break
> the VFS KABI, since vfs_domount_update() differentiates which version
> of export_args is being used.
> As such, I believe this version can be MFC'd. However, it does seem confusing
> to have the two ex_flags fields for the low and high 32bits.

I see you've found a way to do compatibility for a new ABI.  If you
wanted to avoid changing the struct size, there is 3 bytes of usable
padding after each ex_addrlen and ex_masklen.

One general question: why does export_args still exist as an interface
between userspace and the kernel?  It's passed via nmount so it seems
like the individual entries should be elements in the vector instead.
This would be much friendlier if one wanted to do 32-bit compat support
for mountd.

-- Brooks


signature.asc
Description: PGP signature


Re: which way to update export_args structure?

2018-10-03 Thread Rick Macklem
Gary Jennejohn wrote:
[stuff snipped]
>In B, shouldn't ex_flags become uint32_t if all 32 bits can contain
>flag bits?
You could. For B) my intent was to leave the structure exactly the same as the
old versions and only add new fields at the end.  The current compatibility 
code in head does bcopy() of the structure, which means a change to uint32_t 
would require that to be re-written. (For A) it gets re-written anyhow.)

> And why make ex_flagshighbits a uint64_t?  You could
>make it uint32_t and simply shift the high bits around.
Again, you could. I didn't do that, since the code then does require bit shifts
every time you test a flag and I thought that would look messy.
I also get worried that compilers will do weird things like truncate the 
constant
to 32bits before the shift and drop the flag. (I do test cases for these in a 
little
program, but can only test i386.)
(The flags are constants defined in mount.h as MNT_xx for 64bits.)

Since I figured out a way that I think allows A) to be MFC'd, I'm leaning 
towards
A) anyhow.


rick

___
freebsd-current@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: which way to update export_args structure?

2018-10-03 Thread Gary Jennejohn
On Wed, 3 Oct 2018 00:40:27 +
Rick Macklem  wrote:

> Hi,
> 
> I am working on updating "struct export_args" to fix/add a few things.
> One of these is that "ex_flags" is an int, but the flags are defined in 
> mount.h
> as MNT_xx bits that now exceed 32bits (mnt_flag is now uint64_t).
> For now, this doesn't break anything, since the flags used by ex_flags are
> all defined in the low order 32bits but...it seems like this should be 
> addressed
> by a new version of "struct export_args".
> 
> I have two versions of the updated structure:
> A)
> struct export_args {
>   uint64_t ex_flags;  /* export related flags */
>   uid_t   ex_root;/* mapping for root uid */
>   struct  xucred ex_anon; /* mapping for anonymous user */
>   struct  sockaddr *ex_addr;  /* net address to which exported */
>   u_char  ex_addrlen; /* and the net address length */
>   struct  sockaddr *ex_mask;  /* mask of valid bits in saddr */
>   u_char  ex_masklen; /* and the smask length */
>   char*ex_indexfile;  /* index file for WebNFS URLs */
>   int ex_numsecflavors;   /* security flavor count */
>   int ex_secflavors[MAXSECFLAVORS]; /* list of security flavors */
>   int32_t ex_fsid;/* mnt_stat.f_fsid.val[0] if */
>   /* MNT_EXPORTFSID set in ex_flags64 */
>   gid_t   *ex_suppgroups; /* Supplemental groups if */
>   /* ex_anon.cr_ngroups > XU_NGROUPS */
> };
> B)
> struct export_args {
>   int ex_flags;   /* export related flags */
>   uid_t   ex_root;/* mapping for root uid */
>   struct  xucred ex_anon; /* mapping for anonymous user */
>   struct  sockaddr *ex_addr;  /* net address to which exported */
>   u_char  ex_addrlen; /* and the net address length */
>   struct  sockaddr *ex_mask;  /* mask of valid bits in saddr */
>   u_char  ex_masklen; /* and the smask length */
>   char*ex_indexfile;  /* index file for WebNFS URLs */
>   int ex_numsecflavors;   /* security flavor count */
>   int ex_secflavors[MAXSECFLAVORS]; /* list of security flavors */
>   uint64_t ex_flagshighbits;  /* High order bits of mnt_flag */
>   int32_t ex_fsid;/* mnt_stat.f_fsid.val[0] if */
>   /* MNT_EXPORTFSID set in ex_flags64 */
>   gid_t   *ex_suppgroups; /* Supplemental groups if */
>   /* ex_anon.cr_ngroups > XU_NGROUPS */
> };
> 
> A) does the obvious thing. Unfortunately, this changes the vfs KABI
> (specifically the function vfs_oexport_conv()) such that a file system
> module compiled with an unpatched mount.h could crash a patched system.
> As such, I think it couldn't be MFC'd and would be stuck in head/current
> until FreeBSD13 (or FreeBSD14 if 13 gets skipped over;-).
> 
> B) doesn't change any fields, but adds a second ex_flagshighbits for the high
> order bit. Since it only adds fields where none of those bits are used after
> the exports are processed by vfs_export() and, as such, will not break
> the VFS KABI, since vfs_domount_update() differentiates which version
> of export_args is being used.
> As such, I believe this version can be MFC'd. However, it does seem confusing
> to have the two ex_flags fields for the low and high 32bits.
> 
> So, which do you think it preferable? rick
> ps: Josh Paetzel has volunteered to do the mountd.c changes and I have a kerne
>   patch that I'll put up on phabricator once Josh has been able to test 
> it.
> 

In B, shouldn't ex_flags become uint32_t if all 32 bits can contain
flag bits?  And why make ex_flagshighbits a uint64_t?  You could
make it uint32_t and simply shift the high bits around.

-- 
Gary Jennejohn
___
freebsd-current@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: which way to update export_args structure?

2018-10-02 Thread Rick Macklem
I wrote:
>Hi,
>
>I am working on updating "struct export_args" to fix/add a few things.
>One of these is that "ex_flags" is an int, but the flags are defined in mount.h
>as MNT_xx bits that now exceed 32bits (mnt_flag is now uint64_t).
>For now, this doesn't break anything, since the flags used by ex_flags are
>all defined in the low order 32bits but...it seems like this should be 
>addressed
>by a new version of "struct export_args".
>
>I have two versions of the updated structure:
>A)
>struct export_args {
>uint64_t ex_flags;  /* export related flags */
>uid_t   ex_root;/* mapping for root uid */
>struct  xucred ex_anon; /* mapping for anonymous user */
>struct  sockaddr *ex_addr;  /* net address to which exported */
>u_char  ex_addrlen; /* and the net address length */
>struct  sockaddr *ex_mask;  /* mask of valid bits in saddr */
>u_char  ex_masklen; /* and the smask length */
>char*ex_indexfile;  /* index file for WebNFS URLs */
>int ex_numsecflavors;   /* security flavor count */
>int ex_secflavors[MAXSECFLAVORS]; /* list of security flavors */
>int32_t ex_fsid;/* mnt_stat.f_fsid.val[0] if */
>/* MNT_EXPORTFSID set in ex_flags64 */
>gid_t   *ex_suppgroups; /* Supplemental groups if */
>/* ex_anon.cr_ngroups > XU_NGROUPS */
>};
>B)
>struct export_args {
>int ex_flags;   /* export related flags */
>uid_t   ex_root;/* mapping for root uid */
>struct  xucred ex_anon; /* mapping for anonymous user */
>struct  sockaddr *ex_addr;  /* net address to which exported */
>u_char  ex_addrlen; /* and the net address length */
>struct  sockaddr *ex_mask;  /* mask of valid bits in saddr */
>u_char  ex_masklen; /* and the smask length */
>char*ex_indexfile;  /* index file for WebNFS URLs */
>int ex_numsecflavors;   /* security flavor count */
>int ex_secflavors[MAXSECFLAVORS]; /* list of security flavors */
>uint64_t ex_flagshighbits;  /* High order bits of mnt_flag */
>int32_t ex_fsid;/* mnt_stat.f_fsid.val[0] if */
>/* MNT_EXPORTFSID set in ex_flags64 */
>gid_t   *ex_suppgroups; /* Supplemental groups if */
>/* ex_anon.cr_ngroups > XU_NGROUPS */
>};
>
>A) does the obvious thing. Unfortunately, this changes the vfs KABI
>(specifically the function vfs_oexport_conv()) such that a file system
>module compiled with an unpatched mount.h could crash a patched system.
>As such, I think it couldn't be MFC'd and would be stuck in head/current
>until FreeBSD13 (or FreeBSD14 if 13 gets skipped over;-).
I think I have now figured out a way to fix vfs_oexport_conv() so that it can 
be MFC'd.

>B) doesn't change any fields, but adds a second ex_flagshighbits for the high
>order bit. Since it only adds fields where none of those bits are used after
>the exports are processed by vfs_export() and, as such, will not break
>the VFS KABI, since vfs_domount_update() differentiates which version
>of export_args is being used.
>As such, I believe this version can be MFC'd. However, it does seem confusing
>to have the two ex_flags fields for the low and high 32bits.
No longer an advantage, since I have figured out how to handle A) so that it
can be MFC'd too.

>So, which do you think it preferable? rick
>ps: Josh Paetzel has volunteered to do the mountd.c changes and I have a kerne
>  patch that I'll put up on phabricator once Josh has been able to test it.
I'd still like to hear any opinions w.r.t. which is better? rick

___
freebsd-current@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"
___
freebsd-current@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


which way to update export_args structure?

2018-10-02 Thread Rick Macklem
Hi,

I am working on updating "struct export_args" to fix/add a few things.
One of these is that "ex_flags" is an int, but the flags are defined in mount.h
as MNT_xx bits that now exceed 32bits (mnt_flag is now uint64_t).
For now, this doesn't break anything, since the flags used by ex_flags are
all defined in the low order 32bits but...it seems like this should be addressed
by a new version of "struct export_args".

I have two versions of the updated structure:
A)
struct export_args {
uint64_t ex_flags;  /* export related flags */
uid_t   ex_root;/* mapping for root uid */
struct  xucred ex_anon; /* mapping for anonymous user */
struct  sockaddr *ex_addr;  /* net address to which exported */
u_char  ex_addrlen; /* and the net address length */
struct  sockaddr *ex_mask;  /* mask of valid bits in saddr */
u_char  ex_masklen; /* and the smask length */
char*ex_indexfile;  /* index file for WebNFS URLs */
int ex_numsecflavors;   /* security flavor count */
int ex_secflavors[MAXSECFLAVORS]; /* list of security flavors */
int32_t ex_fsid;/* mnt_stat.f_fsid.val[0] if */
/* MNT_EXPORTFSID set in ex_flags64 */
gid_t   *ex_suppgroups; /* Supplemental groups if */
/* ex_anon.cr_ngroups > XU_NGROUPS */
};
B)
struct export_args {
int ex_flags;   /* export related flags */
uid_t   ex_root;/* mapping for root uid */
struct  xucred ex_anon; /* mapping for anonymous user */
struct  sockaddr *ex_addr;  /* net address to which exported */
u_char  ex_addrlen; /* and the net address length */
struct  sockaddr *ex_mask;  /* mask of valid bits in saddr */
u_char  ex_masklen; /* and the smask length */
char*ex_indexfile;  /* index file for WebNFS URLs */
int ex_numsecflavors;   /* security flavor count */
int ex_secflavors[MAXSECFLAVORS]; /* list of security flavors */
uint64_t ex_flagshighbits;  /* High order bits of mnt_flag */
int32_t ex_fsid;/* mnt_stat.f_fsid.val[0] if */
/* MNT_EXPORTFSID set in ex_flags64 */
gid_t   *ex_suppgroups; /* Supplemental groups if */
/* ex_anon.cr_ngroups > XU_NGROUPS */
};

A) does the obvious thing. Unfortunately, this changes the vfs KABI
(specifically the function vfs_oexport_conv()) such that a file system
module compiled with an unpatched mount.h could crash a patched system.
As such, I think it couldn't be MFC'd and would be stuck in head/current
until FreeBSD13 (or FreeBSD14 if 13 gets skipped over;-).

B) doesn't change any fields, but adds a second ex_flagshighbits for the high
order bit. Since it only adds fields where none of those bits are used after
the exports are processed by vfs_export() and, as such, will not break
the VFS KABI, since vfs_domount_update() differentiates which version
of export_args is being used.
As such, I believe this version can be MFC'd. However, it does seem confusing
to have the two ex_flags fields for the low and high 32bits.

So, which do you think it preferable? rick
ps: Josh Paetzel has volunteered to do the mountd.c changes and I have a kerne
  patch that I'll put up on phabricator once Josh has been able to test it.

___
freebsd-current@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"