Re: autoloading compat43 on tty ioctls

2020-10-11 Thread David Holland
On Sat, Oct 10, 2020 at 03:54:32PM -, Christos Zoulas wrote:
 > Aside for the TIOCGSID bug which I am about to fix (it is in tty_43.c
 > and is used in libc tcgetsid(), all the compat tty ioctls are defined
 > in /usr/src/sys/sys/ioctl_compat.h... We can empty that file and try
 > to build the tree :-), but I am guessing things will break. Also a lot
 > of pkgsrc will break too. It is not 4.3 applications that break it is
 > applications that still use the 4.3 terminal api's.

I _think_ I killed off the last sgtty.h user in pkgsrc a few years
ago, but that's only the really old interface. There are probably
still things using the ioctls.

rooting them out would probably be a good exercise but not exactly a
high priority...

-- 
David A. Holland
dholl...@netbsd.org


Re: [PATCH 0/2] Delete CIRCLEQ

2020-10-11 Thread David Holland
On Mon, Oct 12, 2020 at 01:23:15PM +1100, matthew green wrote:
 > > Switch the last user (ypserv) from CIRCLEQ to TAILQ.
 > > This is inspired by analogous refactoring from OpenBSD:
 > > https://github.com/openbsd/src/commit/d53c0cf4d32fdbd8b42debfba068f1b0efa423dc#diff-8d0a4fbb89658213ebf314ff188581d7
 > > 
 > > Remove the CIRCLEQ API completely from the system headers and document
 > > this fact in the QUEUE(3) man-page.
 > 
 > why?  queue.h may be used by more than src.
 > 
 > i don't see any benefit except forcing working code to
 > be changed, possibly introducing bugs.
 > 
 > please leave it alone.

It's been deprecated since -7, we can remove it for -10.

Anyway, please at least do fix ypserv.

-- 
David A. Holland
dholl...@netbsd.org


re: [PATCH 0/2] Delete CIRCLEQ

2020-10-11 Thread matthew green
Kamil Rytarowski writes:
> Switch the last user (ypserv) from CIRCLEQ to TAILQ.
> This is inspired by analogous refactoring from OpenBSD:
> https://github.com/openbsd/src/commit/d53c0cf4d32fdbd8b42debfba068f1b0efa423dc#diff-8d0a4fbb89658213ebf314ff188581d7
> 
> Remove the CIRCLEQ API completely from the system headers and document
> this fact in the QUEUE(3) man-page.

why?  queue.h may be used by more than src.

i don't see any benefit except forcing working code to
be changed, possibly introducing bugs.

please leave it alone.


.mrg.


Re: [PATCH 2/2] Remove the CIRCLEQ API

2020-10-11 Thread Paul Goyette

On Sun, 11 Oct 2020, Kamil Rytarowski wrote:


It was marked deprecated in NetBSD 7 and already removed from
FreeBSD in 2000 and OpenBSD in 2015.
---
share/man/man3/queue.3 |  10 +++
sys/sys/queue.h| 196 -
2 files changed, 10 insertions(+), 196 deletions(-)

diff --git a/share/man/man3/queue.3 b/share/man/man3/queue.3
index 4293090986d4..359c772e5439 100644
--- a/share/man/man3/queue.3
+++ b/share/man/man3/queue.3
@@ -1091,3 +1091,13 @@ and
.Nm STAILQ
functions first appeared in
.Fx 2.1.5 .
+.Pp
+The
+.Nm CIRCLEQ
+functions first appeared in
+.Bx 4.4
+and were deprecated in
+.Nx 7
+and removed in
+.Nx 10
+due to the pointer aliasing violations.


Please reword this slightly.  Instead of

 and  and 

use

, , and .



diff --git a/sys/sys/queue.h b/sys/sys/queue.h
index 5764c7a98a53..ec686364126b 100644
--- a/sys/sys/queue.h
+++ b/sys/sys/queue.h
@@ -69,14 +69,6 @@
 * after an existing element, at the head of the list, or at the end of
 * the list. A tail queue may be traversed in either direction.
 *
- * A circle queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or after
- * an existing element, at the head of the list, or at the end of the list.
- * A circle queue may be traversed in either direction, but has a more
- * complex end of list detection.
- *
 * For details on the use of these macros, see the queue(3) manual page.
 */

@@ -663,192 +655,4 @@ struct {  
\
((struct type *)(void *)\
((char *)((head)->stqh_last) - offsetof(struct type, field

-
-#ifndef _KERNEL
-/*
- * Circular queue definitions. Do not use. We still keep the macros
- * for compatibility but because of pointer aliasing issues their use
- * is discouraged!
- */
-
-/*
- * __launder_type():  We use this ugly hack to work around the compiler
- * noticing that two types may not alias each other and elide tests in code.
- * We hit this in the CIRCLEQ macros when comparing 'struct name *' and
- * 'struct type *' (see CIRCLEQ_HEAD()).  Modern compilers (such as GCC
- * 4.8) declare these comparisons as always false, causing the code to
- * not run as designed.
- *
- * This hack is only to be used for comparisons and thus can be fully const.
- * Do not use for assignment.
- *
- * If we ever choose to change the ABI of the CIRCLEQ macros, we could fix
- * this by changing the head/tail sentinal values, but see the note above
- * this one.
- */
-static __inline const void * __launder_type(const void *);
-static __inline const void *
-__launder_type(const void *__x)
-{
-   __asm __volatile("" : "+r" (__x));
-   return __x;
-}
-
-#if defined(QUEUEDEBUG)
-#define QUEUEDEBUG_CIRCLEQ_HEAD(head, field)   \
-   if ((head)->cqh_first != CIRCLEQ_ENDC(head) &&   \
-   (head)->cqh_first->field.cqe_prev != CIRCLEQ_ENDC(head))  \
-   QUEUEDEBUG_ABORT("CIRCLEQ head forw %p %s:%d", (head),\
- __FILE__, __LINE__);  \
-   if ((head)->cqh_last != CIRCLEQ_ENDC(head) &&\
-   (head)->cqh_last->field.cqe_next != CIRCLEQ_ENDC(head))   \
-   QUEUEDEBUG_ABORT("CIRCLEQ head back %p %s:%d", (head),\
- __FILE__, __LINE__);
-#define QUEUEDEBUG_CIRCLEQ_ELM(head, elm, field)   \
-   if ((elm)->field.cqe_next == CIRCLEQ_ENDC(head)) {   \
-   if ((head)->cqh_last != (elm))   \
-   QUEUEDEBUG_ABORT("CIRCLEQ elm last %p %s:%d", \
-   (elm), __FILE__, __LINE__); \
-   } else {\
-   if ((elm)->field.cqe_next->field.cqe_prev != (elm))   \
-   QUEUEDEBUG_ABORT("CIRCLEQ elm forw %p %s:%d", \
-   (elm), __FILE__, __LINE__); \
-   }   \
-   if ((elm)->field.cqe_prev == CIRCLEQ_ENDC(head)) {   \
-   if ((head)->cqh_first != (elm))  \
-   QUEUEDEBUG_ABORT("CIRCLEQ elm first %p %s:%d",\
-   (elm), __FILE__, __LINE__); \
-   } else {\
-   if ((elm)->field.cqe_prev->field.cqe_next != (elm))   \
-   QUEUEDEBUG_ABORT("CIRCLEQ elm prev %p %s:%d", \
-   (elm), __FILE__, __LINE__); \
-   }

[PATCH 2/2] Remove the CIRCLEQ API

2020-10-11 Thread Kamil Rytarowski
It was marked deprecated in NetBSD 7 and already removed from
FreeBSD in 2000 and OpenBSD in 2015.
---
 share/man/man3/queue.3 |  10 +++
 sys/sys/queue.h| 196 -
 2 files changed, 10 insertions(+), 196 deletions(-)

diff --git a/share/man/man3/queue.3 b/share/man/man3/queue.3
index 4293090986d4..359c772e5439 100644
--- a/share/man/man3/queue.3
+++ b/share/man/man3/queue.3
@@ -1091,3 +1091,13 @@ and
 .Nm STAILQ
 functions first appeared in
 .Fx 2.1.5 .
+.Pp
+The
+.Nm CIRCLEQ
+functions first appeared in
+.Bx 4.4
+and were deprecated in
+.Nx 7
+and removed in
+.Nx 10
+due to the pointer aliasing violations.
diff --git a/sys/sys/queue.h b/sys/sys/queue.h
index 5764c7a98a53..ec686364126b 100644
--- a/sys/sys/queue.h
+++ b/sys/sys/queue.h
@@ -69,14 +69,6 @@
  * after an existing element, at the head of the list, or at the end of
  * the list. A tail queue may be traversed in either direction.
  *
- * A circle queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or after
- * an existing element, at the head of the list, or at the end of the list.
- * A circle queue may be traversed in either direction, but has a more
- * complex end of list detection.
- *
  * For details on the use of these macros, see the queue(3) manual page.
  */
 
@@ -663,192 +655,4 @@ struct {  
\
((struct type *)(void *)\
((char *)((head)->stqh_last) - offsetof(struct type, field
 
-
-#ifndef _KERNEL
-/*
- * Circular queue definitions. Do not use. We still keep the macros
- * for compatibility but because of pointer aliasing issues their use
- * is discouraged!
- */
-
-/*
- * __launder_type():  We use this ugly hack to work around the compiler
- * noticing that two types may not alias each other and elide tests in code.
- * We hit this in the CIRCLEQ macros when comparing 'struct name *' and
- * 'struct type *' (see CIRCLEQ_HEAD()).  Modern compilers (such as GCC
- * 4.8) declare these comparisons as always false, causing the code to
- * not run as designed.
- *
- * This hack is only to be used for comparisons and thus can be fully const.
- * Do not use for assignment.
- *
- * If we ever choose to change the ABI of the CIRCLEQ macros, we could fix
- * this by changing the head/tail sentinal values, but see the note above
- * this one.
- */
-static __inline const void * __launder_type(const void *);
-static __inline const void *
-__launder_type(const void *__x)
-{
-   __asm __volatile("" : "+r" (__x));
-   return __x;
-}
-
-#if defined(QUEUEDEBUG)
-#define QUEUEDEBUG_CIRCLEQ_HEAD(head, field)   \
-   if ((head)->cqh_first != CIRCLEQ_ENDC(head) &&  \
-   (head)->cqh_first->field.cqe_prev != CIRCLEQ_ENDC(head))\
-   QUEUEDEBUG_ABORT("CIRCLEQ head forw %p %s:%d", (head),  \
- __FILE__, __LINE__);  \
-   if ((head)->cqh_last != CIRCLEQ_ENDC(head) &&   \
-   (head)->cqh_last->field.cqe_next != CIRCLEQ_ENDC(head)) \
-   QUEUEDEBUG_ABORT("CIRCLEQ head back %p %s:%d", (head),  \
- __FILE__, __LINE__);
-#define QUEUEDEBUG_CIRCLEQ_ELM(head, elm, field)   \
-   if ((elm)->field.cqe_next == CIRCLEQ_ENDC(head)) {  \
-   if ((head)->cqh_last != (elm))  \
-   QUEUEDEBUG_ABORT("CIRCLEQ elm last %p %s:%d",   \
-   (elm), __FILE__, __LINE__); \
-   } else {\
-   if ((elm)->field.cqe_next->field.cqe_prev != (elm)) \
-   QUEUEDEBUG_ABORT("CIRCLEQ elm forw %p %s:%d",   \
-   (elm), __FILE__, __LINE__); \
-   }   \
-   if ((elm)->field.cqe_prev == CIRCLEQ_ENDC(head)) {  \
-   if ((head)->cqh_first != (elm)) \
-   QUEUEDEBUG_ABORT("CIRCLEQ elm first %p %s:%d",  \
-   (elm), __FILE__, __LINE__); \
-   } else {\
-   if ((elm)->field.cqe_prev->field.cqe_next != (elm)) \
-   QUEUEDEBUG_ABORT("CIRCLEQ elm prev %p %s:%d",   \
-   (elm), __FILE__, __LINE__); \
-   }
-#define QUEUEDEBUG_CIRCLEQ_POSTREMOVE(elm, field)  \
-   (elm)->field.cqe_next = (void *)1L; \
-   

[PATCH 1/2] Convert the CIRCLEQ (from sys/queue.h) usage to TAILQ

2020-10-11 Thread Kamil Rytarowski
The CIRCLEQ API from sys/queue.h is deprecated since NetBSD 7 and
it will be removed soon. The CIRCLEQ API implementation is prone
to a miscompilation due to the pointer aliasing and is discouraged.
---
 usr.sbin/ypserv/ypserv/ypserv_db.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/usr.sbin/ypserv/ypserv/ypserv_db.c 
b/usr.sbin/ypserv/ypserv/ypserv_db.c
index d6f9eda39eaa..9edfabc4f675 100644
--- a/usr.sbin/ypserv/ypserv/ypserv_db.c
+++ b/usr.sbin/ypserv/ypserv/ypserv_db.c
@@ -65,7 +65,7 @@ __RCSID("$NetBSD: ypserv_db.c,v 1.22 2011/02/01 21:00:25 
chuck Exp $");
 
 LIST_HEAD(domainlist, opt_domain); /* LIST of domains */
 LIST_HEAD(maplist, opt_map);   /* LIST of maps (in a domain) */
-CIRCLEQ_HEAD(mapq, opt_map);   /* CIRCLEQ of maps (LRU) */
+TAILQ_HEAD(mapq, opt_map); /* TAILQ of maps (LRU) */
 
 struct opt_map {
char*map;   /* map name (malloc'd) */
@@ -76,7 +76,7 @@ struct opt_map {
dev_t   dbdev;  /* device db is on */
ino_t   dbino;  /* inode of db */
time_t  dbmtime;/* time of last db modification */
-   CIRCLEQ_ENTRY(opt_map) mapsq;   /* map queue pointers */
+   TAILQ_ENTRY(opt_map) mapsq; /* map queue pointers */
LIST_ENTRY(opt_map) mapsl;  /* map list pointers */
 };
 
@@ -106,7 +106,7 @@ ypdb_init(void)
 {
 
LIST_INIT();
-   CIRCLEQ_INIT();
+   TAILQ_INIT();
 }
 
 /*
@@ -161,7 +161,7 @@ yp_private(datum key, int ypprivate)
 void
 ypdb_close_map(struct opt_map *map)
 {
-   CIRCLEQ_REMOVE(, map, mapsq);  /* remove from LRU circleq */
+   TAILQ_REMOVE(, map, mapsq);/* remove from LRU tailq */
LIST_REMOVE(map, mapsl);/* remove from domain list */
 
 #ifdef DEBUG
@@ -326,8 +326,8 @@ ypdb_open_db(const char *domain, const char *map, u_int 
*status,
 */
if (finfo.st_dev == m->dbdev && finfo.st_ino == m->dbino &&
finfo.st_mtime == m->dbmtime) {
-   CIRCLEQ_REMOVE(, m, mapsq); /* adjust LRU queue */
-   CIRCLEQ_INSERT_HEAD(, m, mapsq);
+   TAILQ_REMOVE(, m, mapsq); /* adjust LRU queue */
+   TAILQ_INSERT_HEAD(, m, mapsq);
if (map_info)
*map_info = m;
return (m->db);
@@ -423,7 +423,7 @@ retryopen:
m->dbdev = finfo.st_dev;
m->dbino = finfo.st_ino;
m->dbmtime = finfo.st_mtime;
-   CIRCLEQ_INSERT_HEAD(, m, mapsq);
+   TAILQ_INSERT_HEAD(, m, mapsq);
LIST_INSERT_HEAD(>dmaps, m, mapsl);
if (strcmp(map, YP_HOSTNAME) == 0 || strcmp(map, YP_HOSTADDR) == 0) {
if (!usedns) {
-- 
2.28.0



[PATCH 0/2] Delete CIRCLEQ

2020-10-11 Thread Kamil Rytarowski
Switch the last user (ypserv) from CIRCLEQ to TAILQ.
This is inspired by analogous refactoring from OpenBSD:
https://github.com/openbsd/src/commit/d53c0cf4d32fdbd8b42debfba068f1b0efa423dc#diff-8d0a4fbb89658213ebf314ff188581d7

Remove the CIRCLEQ API completely from the system headers and document
this fact in the QUEUE(3) man-page.

Kamil Rytarowski (2):
  Convert the CIRCLEQ (from sys/queue.h) usage to TAILQ
  Remove the CIRCLEQ API

 share/man/man3/queue.3 |  10 ++
 sys/sys/queue.h| 196 -
 usr.sbin/ypserv/ypserv/ypserv_db.c |  14 +--
 3 files changed, 17 insertions(+), 203 deletions(-)

-- 
2.28.0


[PATCH] Fix s87_tw reconstruction to correctly indicate register states

2020-10-11 Thread Michał Górny
Fix the code reconstructing s87_tw (full tag word) from fx_sw (abridged
tag word) to correctly represent all register states.  The previous code
only distinguished between empty/non-empty registers, and assigned
'regular value' to all non-empty registers.  The new code explicitly
distinguishes the two other tag word values: empty and special.
---
 sys/arch/x86/x86/fpu.c | 28 --
 tests/lib/libc/sys/t_ptrace_x86_wait.h |  2 --
 2 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/sys/arch/x86/x86/fpu.c b/sys/arch/x86/x86/fpu.c
index d89c78dcef47..c580f34b0615 100644
--- a/sys/arch/x86/x86/fpu.c
+++ b/sys/arch/x86/x86/fpu.c
@@ -668,7 +668,7 @@ fpu_sigreset(struct lwp *l)
 static void
 process_xmm_to_s87(const struct fxsave *sxmm, struct save87 *s87)
 {
-   unsigned int tag, ab_tag;
+   unsigned int tag, ab_tag, st;
const struct fpaccfx *fx_reg;
struct fpacc87 *s87_reg;
int i;
@@ -723,12 +723,28 @@ process_xmm_to_s87(const struct fxsave *sxmm, struct 
save87 *s87)
return;
}
 
+   /* For ST(i), i = fpu_reg - top, we start with fpu_reg=7. */
+   st = 7 - ((sxmm->fx_sw >> 11) & 7);
tag = 0;
-   /* Separate bits of abridged tag word with zeros */
-   for (i = 0x80; i != 0; tag <<= 1, i >>= 1)
-   tag |= ab_tag & i;
-   /* Replicate and invert so that 0 => 0b11 and 1 => 0b00 */
-   s87->s87_tw = (tag | tag >> 1) ^ 0x;
+   for (i = 0x80; i != 0; i >>= 1) {
+   tag <<= 2;
+   if (ab_tag & i) {
+   unsigned int exp;
+   /* Non-empty - we need to check ST(i) */
+   fx_reg = >fx_87_ac[st];
+   exp = fx_reg->r.f87_exp_sign & 0x7fff;
+   if (exp == 0) {
+   if (fx_reg->r.f87_mantissa == 0)
+   tag |= 1; /* Zero */
+   else
+   tag |= 2; /* Denormal */
+   } else if (exp == 0x7fff)
+   tag |= 2; /* Infinity or NaN */
+   } else
+   tag |= 3; /* Empty */
+   st = (st - 1) & 7;
+   }
+   s87->s87_tw = tag;
 }
 
 static void
diff --git a/tests/lib/libc/sys/t_ptrace_x86_wait.h 
b/tests/lib/libc/sys/t_ptrace_x86_wait.h
index d7e93fde55a3..6067066a36c1 100644
--- a/tests/lib/libc/sys/t_ptrace_x86_wait.h
+++ b/tests/lib/libc/sys/t_ptrace_x86_wait.h
@@ -3367,10 +3367,8 @@ x86_register_test(enum x86_test_regset regset, enum 
x86_test_registers regs,
expected_fpu.cw);
ATF_CHECK_EQ(fpr.fstate.s87_sw,
expected_fpu.sw);
-#if 0 /* TODO: translation from FXSAVE is broken */
ATF_CHECK_EQ(fpr.fstate.s87_tw,
expected_fpu.tw);
-#endif
ATF_CHECK_EQ(fpr.fstate.s87_opcode,
expected_fpu.opcode);
ATF_CHECK_EQ(fpr.fstate.s87_ip.fa_32.fa_off,
-- 
2.28.0



Re: Trying to write a kernel module for (un)mounting tmpfs

2020-10-11 Thread Bruno Melo
Hi,

When I call the namei_simple_user function it always return errno 14. It calls 
the nameiat_simple_user who calls the pathbuf_copyin function. I set a bp in 
pathbuf_copyin and i compare what happens when I use mount command vs my 
module. basically it calls the pathbuf_create_raw() who does all the magic, 
when use the mount command it sets pb->pb_path to "/tmp" and when i load my 
module it sets to the "./mount.kmod" (my module's name), that's why namei 
always returns a bad address errno.
The pathbuf_create_raw() calls the PNBUF_GET() who is a macro for
pool_cache_get(pnbuf_cache, PR_WAITOK). My question is how can I pass "/tmp" 
string to pnbuf_cache argument? Will I need to reimplement all these functions 
inside my code?

Thanks for the help.

Sent from [ProtonMail](https://protonmail.com), Swiss-based encrypted email.

‐‐‐ Original Message ‐‐‐
Em domingo, 13 de setembro de 2020 às 23:57, Maciej  
escreveu:

> Hi Bruno,
>
> The reason why it is hard to map VFS operations inside the kernel is due to 
> the way how POSIX filesystems are designed.
> Most of the operations are made to run in the context of some process where 
> we have information about things such mount point,
> some file structures or path. This information is later translated to 
> concrete kernel structures.
>
> From the other side kernel module code when executed would need to get 
> somehow such information like mount point and mount options.
> If you take a look on the man-page of mount(2) you will notice that there are 
> couple arguments like flags
> (Filesystem independent - or at least meant to be independent), and mount 
> data which is filesystem-specific.
>
> The first design question that should ask yourself is how this information 
> would be provided to the kernel module?
> Probably they can be hardcoded in the module; however, if you decide to 
> trigger this operation from userspace
> (by using any US to kernel interface), you can provide some structure that 
> contains more information about current filesystem to make things easier.
>
> A good starting point to understand how things are working would be 
> implementation in VFS layer of mount system call:
>
> `do_sys_mount()` inside: kern/vfs_syscalls.c
>
> You can notice that in order to get vnode (structure needed for mount: the 
> mount point)
> you need to translate file path to find a vnode using `namei` operation
>
> Next thing is mount operation itself, as you realized each filesystem has its 
> own `struct vfsops` that contains filesystem operations.
> Kernel contains the global list `struct vfs_list_head vfs_list ` build inside 
> `kern/vfs_init.c`
> this list contains all filesystems availavble on NetBSD with their operations.
> To get filesystem specific structure you can use `mount_get_vfsops()`.
>
> When finished with the preparation (probably you will need to prepare 
> arguments according to man page mentioned before),
> you can call your favourite FS mount operation by `mount_domount()`.
>
> Hope that quick walkthrough will help you understand how mount operation 
> works inside the kernel.
> Maciej
>
> ‐‐‐ Original Message ‐‐‐
> On Thursday, September 10, 2020 12:51 PM, Bruno Melo  
> wrote:
>
>> Hi,
>>
>> I'm trying to write a kernel module as example for mounting and unmounting 
>> tmpfs. For that, I read the mount_tmpfs code and in line 247 I found the 
>> call for mount() syscall here:
>> https://nxr.netbsd.org/xref/src/sbin/mount_tmpfs/mount_tmpfs.c#247
>>
>> Then I looked for how the kernel mounts file systems and found there are 
>> _mount() function for every file system:
>> https://nxr.netbsd.org/xref/src/sys/sys/mount.h#254
>>
>> Now, I just needed to know how to use tmpfs_mount() and find it here:
>> https://nxr.netbsd.org/xref/src/sys/fs/tmpfs/tmpfs_vfsops.c#86
>> but I still don't know how to use it. I created the struct 
>> [tmpfs_args](https://nxr.netbsd.org/source/s?defs=tmpfs_args=src) 
>> [args](https://nxr.netbsd.org/source/s?refs=args=src) and size_t 
>> args_len = sizeof args variables to pass to data and data_len arguments in 
>> tmpfs_mount(). And the directory I'm mounting is "/tmp". So, I have 3 of 4 
>> arguments needed to tmpfs_mount(), the last one is the struct mount *mp.
>>
>> I know the mount() syscall takes 
>> [MOUNT_TMPFS](https://nxr.netbsd.org/source/s?defs=MOUNT_TMPFS=src) 
>> as first argument, but I'm not understanding the magic behind struct mount 
>> mp and what I need to assign to the struct mount variable to pass it to that 
>> argument. Any hint?
>>
>> Thanks for the help,
>>
>> Bruno Melo.