From ca7a9a467f8470af9a359b27ca88ee2f51054000 Mon Sep 17 00:00:00 2001 From: Justus Winter Date: Mon, 18 Apr 2016 21:53:28 +0200 Subject: [PATCH hurd 5/5] YYY Unify the short-circuit translator logic * libdiskfs/dir-lookup.c (short_circuited_callback1): Drop function. * libdiskfs/trans-callback.c * libfshelp/fetch-root.c * libfshelp/fshelp.h * libnetfs/dir-lookup.c * libnetfs/trans-callback.c --- libdiskfs/dir-lookup.c | 61 ++++++++++++---------------------------------- libdiskfs/trans-callback.c | 4 ++- libfshelp/fetch-root.c | 39 +++++++++++++++++++++++++++++ libfshelp/fshelp.h | 16 ++++++++++++ libnetfs/dir-lookup.c | 53 +++++++--------------------------------- libnetfs/trans-callback.c | 4 ++- 6 files changed, 86 insertions(+), 91 deletions(-) diff --git a/libdiskfs/dir-lookup.c b/libdiskfs/dir-lookup.c index 72ada0f..8b43e27 100644 --- a/libdiskfs/dir-lookup.c +++ b/libdiskfs/dir-lookup.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -225,43 +226,6 @@ diskfs_S_dir_lookup (struct protid *dircred, mach_port_t dirport; struct iouser *user; - /* A callback function for short-circuited translators. - S_ISLNK and S_IFSOCK are handled elsewhere. */ - error_t short_circuited_callback1 (void *cookie1, void *cookie2, - uid_t *uid, gid_t *gid, - char **argz, size_t *argz_len) - { - struct node *node = cookie1; - - switch (node->dn_stat.st_mode & S_IFMT) - { - case S_IFCHR: - case S_IFBLK: - if (asprintf (argz, "%s%c%d%c%d", - (S_ISCHR (node->dn_stat.st_mode) - ? _HURD_CHRDEV : _HURD_BLKDEV), - 0, major (node->dn_stat.st_rdev), - 0, minor (node->dn_stat.st_rdev)) < 0) - return ENOMEM; - *argz_len = strlen (*argz) + 1; - *argz_len += strlen (*argz + *argz_len) + 1; - *argz_len += strlen (*argz + *argz_len) + 1; - break; - case S_IFIFO: - if (asprintf (argz, "%s", _HURD_FIFO) < 0) - return ENOMEM; - *argz_len = strlen (*argz) + 1; - break; - default: - return ENOENT; - } - - *uid = node->dn_stat.st_uid; - *gid = node->dn_stat.st_gid; - - return 0; - } - /* Create an unauthenticated port for DNP, and then unlock it. */ err = iohelp_create_empty_iouser (&user); @@ -292,14 +256,21 @@ diskfs_S_dir_lookup (struct protid *dircred, boolean_t register_translator = np->transbox.active == MACH_PORT_NULL; - err = fshelp_fetch_root (&np->transbox, dircred->po, - dirport, dircred->user, - lastcomp ? flags : 0, - ((np->dn_stat.st_mode & S_IPTRANS) - ? _diskfs_translator_callback1 - : short_circuited_callback1), - _diskfs_translator_callback2, - do_retry, retry_name, retry_port); + struct fshelp_stat_cookie2 cookie = { + .statp = &np->dn_stat, + .modep = &np->dn_stat.st_mode, + .next = dircred->po, + }; + err = fshelp_fetch_root (&np->transbox, + &cookie, + dirport, + dircred->user, + lastcomp ? flags : 0, + ((np->dn_stat.st_mode & S_IPTRANS) + ? _diskfs_translator_callback1 + : fshelp_short_circuited_callback1), + _diskfs_translator_callback2, + do_retry, retry_name, retry_port); /* fetch_root copies DIRPORT for success, so we always should deallocate our send right. */ diff --git a/libdiskfs/trans-callback.c b/libdiskfs/trans-callback.c index 283b184..15e8f9a 100644 --- a/libdiskfs/trans-callback.c +++ b/libdiskfs/trans-callback.c @@ -20,6 +20,7 @@ #include "priv.h" #include +#include /* Callback function needed for calls to fshelp_fetch_root. See for the interface description. */ @@ -56,6 +57,7 @@ _diskfs_translator_callback2_fn (void *cookie1, void *cookie2, mach_msg_type_name_t *underlying_type) { struct node *np = cookie1; + struct fshelp_stat_cookie2 *statc = cookie2; struct protid *cred; struct peropen *po; error_t err; @@ -66,7 +68,7 @@ _diskfs_translator_callback2_fn (void *cookie1, void *cookie2, if (err) return err; - err = diskfs_make_peropen (np, flags, cookie2, &po); + err = diskfs_make_peropen (np, flags, statc->next, &po); if (! err) { err = diskfs_create_protid (po, user, &cred); diff --git a/libfshelp/fetch-root.c b/libfshelp/fetch-root.c index cc9fa50..eb43993 100644 --- a/libfshelp/fetch-root.c +++ b/libfshelp/fetch-root.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -197,3 +198,41 @@ fshelp_fetch_root (struct transbox *box, void *cookie, return err; } + +/* A callback function for short-circuited translators. S_ISLNK and + S_IFSOCK must be handled elsewhere. */ +error_t +fshelp_short_circuited_callback1 (void *cookie1, void *cookie2, + uid_t *uid, gid_t *gid, + char **argz, size_t *argz_len) +{ + struct fshelp_stat_cookie2 *statc = cookie2; + + switch (*statc->modep & S_IFMT) + { + case S_IFCHR: + case S_IFBLK: + if (asprintf (argz, "%s%c%d%c%d", + (S_ISCHR (*statc->modep) + ? _HURD_CHRDEV : _HURD_BLKDEV), + 0, major (statc->statp->st_rdev), + 0, minor (statc->statp->st_rdev)) < 0) + return ENOMEM; + *argz_len = strlen (*argz) + 1; + *argz_len += strlen (*argz + *argz_len) + 1; + *argz_len += strlen (*argz + *argz_len) + 1; + break; + case S_IFIFO: + if (asprintf (argz, "%s", _HURD_FIFO) < 0) + return ENOMEM; + *argz_len = strlen (*argz) + 1; + break; + default: + return ENOENT; + } + + *uid = statc->statp->st_uid; + *gid = statc->statp->st_gid; + + return 0; +} diff --git a/libfshelp/fshelp.h b/libfshelp/fshelp.h index d04c056..ecd9335 100644 --- a/libfshelp/fshelp.h +++ b/libfshelp/fshelp.h @@ -148,6 +148,22 @@ typedef error_t (*fshelp_fetch_root_callback1_t) (void *cookie1, void *cookie2, uid_t *uid, gid_t *gid, char **argz, size_t *argz_len); +/* A cookie for fshelp_short_circuited_callback1. Such a structure + must be passed to the call to fshelp_fetch_root. */ +struct fshelp_stat_cookie2 +{ + io_statbuf_t *statp; + mode_t *modep; + void *next; +}; + +/* A callback function for short-circuited translators. S_ISLNK and + S_IFSOCK must be handled elsewhere. */ +error_t fshelp_short_circuited_callback1 (void *cookie1, void *cookie2, + uid_t *uid, gid_t *gid, + char **argz, size_t *argz_len); + + /* This routine is called by fshelp_fetch_root to fetch more information. Return an unauthenticated node for the file itself in *UNDERLYING and *UNDERLYING_TYPE (opened with FLAGS). COOKIE1 is the cookie passed in diff --git a/libnetfs/dir-lookup.c b/libnetfs/dir-lookup.c index caeb151..3bcc745 100644 --- a/libnetfs/dir-lookup.c +++ b/libnetfs/dir-lookup.c @@ -207,48 +207,6 @@ netfs_S_dir_lookup (struct protid *dircred, { mach_port_t dirport; - /* A callback function for short-circuited translators. - S_ISLNK and S_IFSOCK are handled elsewhere. */ - error_t short_circuited_callback1 (void *cookie1, void *cookie2, - uid_t *uid, gid_t *gid, - char **argz, size_t *argz_len) - { - struct node *np = cookie1; - error_t err; - - err = netfs_validate_stat (np, dircred->user); - if (err) - return err; - - switch (np->nn_translated & S_IFMT) - { - case S_IFCHR: - case S_IFBLK: - if (asprintf (argz, "%s%c%d%c%d", - (S_ISCHR (np->nn_translated) - ? _HURD_CHRDEV : _HURD_BLKDEV), - 0, major (np->nn_stat.st_rdev), - 0, minor (np->nn_stat.st_rdev)) < 0) - return ENOMEM; - *argz_len = strlen (*argz) + 1; - *argz_len += strlen (*argz + *argz_len) + 1; - *argz_len += strlen (*argz + *argz_len) + 1; - break; - case S_IFIFO: - if (asprintf (argz, "%s", _HURD_FIFO) < 0) - return ENOMEM; - *argz_len = strlen (*argz) + 1; - break; - default: - return ENOENT; - } - - *uid = np->nn_stat.st_uid; - *gid = np->nn_stat.st_gid; - - return 0; - } - /* Create an unauthenticated port for DNP, and then unlock it. */ err = iohelp_create_empty_iouser (&user); @@ -267,6 +225,12 @@ netfs_S_dir_lookup (struct protid *dircred, boolean_t register_translator = 0; if (! err) { + struct fshelp_stat_cookie2 cookie = { + .statp = &np->nn_stat, + .modep = &np->nn_translated, + .next = dircred->po, + }; + dirport = ports_get_send_right (newpi); /* Check if an active translator is currently running. If @@ -275,13 +239,14 @@ netfs_S_dir_lookup (struct protid *dircred, translators. */ register_translator = np->transbox.active == MACH_PORT_NULL; - err = fshelp_fetch_root (&np->transbox, dircred->po, + err = fshelp_fetch_root (&np->transbox, + &cookie, dirport, dircred->user, lastcomp ? flags : 0, ((np->nn_translated & S_IPTRANS) ? _netfs_translator_callback1 - : short_circuited_callback1), + : fshelp_short_circuited_callback1), _netfs_translator_callback2, do_retry, retry_name, retry_port); /* fetch_root copies DIRPORT for success, so we always should diff --git a/libnetfs/trans-callback.c b/libnetfs/trans-callback.c index ed21aa2..99f4dc0 100644 --- a/libnetfs/trans-callback.c +++ b/libnetfs/trans-callback.c @@ -20,6 +20,7 @@ #include "priv.h" #include +#include /* Callback function needed for calls to fshelp_fetch_root. See for the interface description. */ @@ -57,6 +58,7 @@ _netfs_translator_callback2_fn (void *cookie1, void *cookie2, int flags, error_t err; struct protid *cred; struct node *node = cookie1; + struct fshelp_stat_cookie2 *statc = cookie2; struct iouser *user; struct peropen *po; @@ -65,7 +67,7 @@ _netfs_translator_callback2_fn (void *cookie1, void *cookie2, int flags, if (err) return err; - po = netfs_make_peropen (node, flags, cookie2); + po = netfs_make_peropen (node, flags, statc->next); if (! po) { err = errno; -- 2.1.4