bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: error checking in libnetfs


From: Neal H Walfield
Subject: Re: error checking in libnetfs
Date: 01 Apr 2002 21:12:12 -0500
User-agent: Gnus/5.0808 (Gnus v5.8.8) Emacs/21.1

>   Here is my patch to increase the error checking within libnetfs.
> I've also included error.h in a couple of files that I noticed had compiler
> warnings.  There aren't any functions that return pointers to struct's
> left in libnetfs.

There is one in libdiskfs (diskfs_make_node).  Do you want to fix this
too?

>   Apparently the copyright wasn't updated in console-run.c during the last
> set of checkins.
> 
>   Just a reminder, there are outstanding documentation patches for hurd.texi.

Could you write these?

> nfs:
>       * nfs.h: Changed lookup_fhandle to return an error_t instead
> of void.

I think you should do:

        * nfs.h (lookup_fhandle): Now returns error_t instead of void.

> nfsd:
>       * fsys.c: Include error.h, so that the error function is explicitly
>       declared.

This should read:

        * fsys.c: Include <error.h>.

You need to <>s and there is no need for an explanation in this case.

> Index: ftpfs/fs.c
> ===================================================================
> RCS file: /cvsroot/hurd/hurd/ftpfs/fs.c,v
> retrieving revision 1.4
> diff -u -p -r1.4 fs.c
> --- ftpfs/fs.c        29 Dec 2001 00:19:39 -0000      1.4
> +++ ftpfs/fs.c        29 Mar 2002 06:12:05 -0000
> @@ -64,10 +64,8 @@ ftpfs_create (char *rmt_path, int fsid,
>  
>    if (! err)
>      {
> -      super_root = netfs_make_node (0);
> -      if (! super_root)
> -     err = ENOMEM;
> -      else
> +      err = netfs_make_node (0, &super_root);
> +      if (! err)
>       {
>         err = ftpfs_dir_create (new, super_root, rmt_path, &super_root_dir);
>         if (! err)

This seems wrong: you ignore netfs_make_node's error case!

> Index: libnetfs/fsys-getroot.c
> ===================================================================
> RCS file: /cvsroot/hurd/hurd/libnetfs/fsys-getroot.c,v
> retrieving revision 1.10
> diff -u -p -r1.10 fsys-getroot.c
> --- libnetfs/fsys-getroot.c   16 Jun 2001 20:23:29 -0000      1.10
> +++ libnetfs/fsys-getroot.c   29 Mar 2002 06:12:07 -0000
> @@ -127,20 +128,28 @@ netfs_S_fsys_getroot (mach_port_t cntl,
>    
>    flags &= ~OPENONLY_STATE_MODES;
>    
> -  newpi = netfs_make_protid (netfs_make_peropen (netfs_root_node, flags,
> -                                              &peropen_context),
> -                          cred);
> -  mach_port_deallocate (mach_task_self (), dotdot);
> -
> -  *do_retry = FS_RETRY_NORMAL;
> -  *retry_port = ports_get_right (newpi);
> -  *retry_port_type = MACH_MSG_TYPE_MAKE_SEND;
> -  retry_name[0] = '\0';
> -  ports_port_deref (newpi);
> -  
> +  err = netfs_make_peropen (netfs_root_node, flags, &peropen_context, 
> &newpo);
> +  if (! err)
> +    {
> +      err = netfs_make_protid (newpo, cred, &newpi);
> +      if (err)
> +     netfs_release_peropen (newpo);
> +    }
> +
> +  if (! err)
> +    {
> +      mach_port_deallocate (mach_task_self (), dotdot);

I think this needs to happen no matter what (i.e. error or not).

> +      
> +      *do_retry = FS_RETRY_NORMAL;
> +      *retry_port = ports_get_right (newpi);
> +      *retry_port_type = MACH_MSG_TYPE_MAKE_SEND;
> +      retry_name[0] = '\0';
> +      ports_port_deref (newpi);

So does this.

> +    }
> +  else
>   out:
> -  if (err)
>      iohelp_free_iouser (cred);
> +
>    mutex_unlock (&netfs_root_node->lock);
>    return err;
>  }
> Index: libnetfs/io-duplicate.c
> ===================================================================
> RCS file: /cvsroot/hurd/hurd/libnetfs/io-duplicate.c,v
> retrieving revision 1.3
> diff -u -p -r1.3 io-duplicate.c
> --- libnetfs/io-duplicate.c   16 Jun 2001 20:23:29 -0000      1.3
> +++ libnetfs/io-duplicate.c   29 Mar 2002 06:12:07 -0000
> @@ -35,10 +35,15 @@ netfs_S_io_duplicate (struct protid *use
>      return err;
>    
>    mutex_lock (&user->po->np->lock);
> -  newpi = netfs_make_protid (user->po, clone);
> -  *newport = ports_get_right (newpi);
> -  mutex_unlock (&user->po->np->lock);
> -  *newporttp = MACH_MSG_TYPE_MAKE_SEND;
> -  ports_port_deref (newpi);
> -  return 0;
> +  err = netfs_make_protid (user->po, clone, &newpi);
> +  if (! err)
> +    {
> +      *newport = ports_get_right (newpi);
> +      mutex_unlock (&user->po->np->lock);

You need to always unlock USER->po->np->lock.  Not just on success.

> +      *newporttp = MACH_MSG_TYPE_MAKE_SEND;
> +      ports_port_deref (newpi);

Same idea here.

> +      return 0;
> +    }
> +  else
> +    return err;
>  }
> Index: libnetfs/io-reauthenticate.c
> ===================================================================
> RCS file: /cvsroot/hurd/hurd/libnetfs/io-reauthenticate.c,v
> retrieving revision 1.10
> diff -u -p -r1.10 io-reauthenticate.c
> --- libnetfs/io-reauthenticate.c      16 Jun 2001 20:23:29 -0000      1.10
> +++ libnetfs/io-reauthenticate.c      29 Mar 2002 06:12:07 -0000
> @@ -1,5 +1,5 @@
>  /*
> -   Copyright (C) 1995,96,2000,01 Free Software Foundation, Inc.
> +   Copyright (C) 1995,96,2000,01,02 Free Software Foundation, Inc.
>     Written by Michael I. Bushnell, p/BSG.
>  
>     This file is part of the GNU Hurd.
> @@ -32,22 +32,28 @@ netfs_S_io_reauthenticate (struct protid
>      return EOPNOTSUPP;
>  
>    mutex_lock (&user->po->np->lock);
> -  newpi = netfs_make_protid (user->po, 0);
> +  err = netfs_make_protid (user->po, 0, &newpi);
>  
> -  newright = ports_get_send_right (newpi);
> -  assert (newright != MACH_PORT_NULL);
> +  if (! err)
> +    {
>  
> -  err = iohelp_reauth (&newpi->user, netfs_auth_server_port, rend_port,
> -                    newright, 1);
> -
> -  mach_port_deallocate (mach_task_self (), rend_port);
> -  mach_port_deallocate (mach_task_self (), newright);
> -
> -  mach_port_move_member (mach_task_self (), newpi->pi.port_right,
> -                      netfs_port_bucket->portset);
> -
> -  mutex_unlock (&user->po->np->lock);
> -  ports_port_deref (newpi);
> -
> -  return err;
> +      newright = ports_get_send_right (newpi);
> +      assert (newright != MACH_PORT_NULL);
> +      
> +      err = iohelp_reauth (&newpi->user, netfs_auth_server_port, rend_port,
> +                        newright, 1);
> +      
> +      mach_port_deallocate (mach_task_self (), rend_port);
> +      mach_port_deallocate (mach_task_self (), newright);
> +      
> +      mach_port_move_member (mach_task_self (), newpi->pi.port_right,
> +                          netfs_port_bucket->portset);
> +      
> +      mutex_unlock (&user->po->np->lock);

This needs to be called in both cases, i.e. error and success.

> +      ports_port_deref (newpi);

As does this.

> +
> +      return err;
> +    }
> +  else
> +    return err;
>  }
> Index: libnetfs/io-restrict-auth.c
> ===================================================================
> RCS file: /cvsroot/hurd/hurd/libnetfs/io-restrict-auth.c,v
> retrieving revision 1.4
> diff -u -p -r1.4 io-restrict-auth.c
> --- libnetfs/io-restrict-auth.c       16 Jun 2001 20:37:39 -0000      1.4
> +++ libnetfs/io-restrict-auth.c       29 Mar 2002 06:12:07 -0000
> @@ -1,5 +1,5 @@
>  /* 
> -   Copyright (C) 1995,96,2001 Free Software Foundation, Inc.
> +   Copyright (C) 1995,96,2001,2002 Free Software Foundation, Inc.
>     Written by Michael I. Bushnell, p/BSG.
>  
>     This file is part of the GNU Hurd.
> @@ -96,21 +96,17 @@ netfs_S_io_restrict_auth (struct protid 
>      }
>    
>    mutex_lock (&user->po->np->lock);
> -  newpi = netfs_make_protid (user->po, new_user);
> -  if (newpi)
> +  err = netfs_make_protid (user->po, new_user, &newpi);
> +  if (! err)
>      {
>        *newport = ports_get_right (newpi);
> -      mutex_unlock (&user->po->np->lock);
>        *newporttype = MACH_MSG_TYPE_MAKE_SEND;
> +      ports_port_deref (newpi);
>      }
> -  else
> -    {
> -      mutex_unlock (&user->po->np->lock);
> -      iohelp_free_iouser (new_user);
> -      err = ENOMEM;
> -    }
> -  
> -  ports_port_deref (newpi);
> +  mutex_unlock (&user->po->np->lock);
> +
> +  iohelp_free_iouser (new_user);

This change looks wrong.  new_user should not be freed in the success
case.  Also, ports_port_deref needs to happen after the unlock.

>    return err;
> +  
>  }
>  
> Index: libnetfs/netfs.h
> ===================================================================
> RCS file: /cvsroot/hurd/hurd/libnetfs/netfs.h,v
> retrieving revision 1.29
> diff -u -p -r1.29 netfs.h
> --- libnetfs/netfs.h  30 Jan 2001 00:50:25 -0000      1.29
> +++ libnetfs/netfs.h  29 Mar 2002 06:12:08 -0000
> @@ -263,11 +263,6 @@ error_t netfs_attempt_write (struct ious
>  error_t netfs_report_access (struct iouser *cred, struct node *np,
>                            int *types);
>  
> -/* The user must define this function.  Create a new user from the
> -   specified UID and GID arrays. */
> -struct iouser *netfs_make_user (uid_t *uids, int nuids,
> -                                    uid_t *gids, int ngids);
> -
>  /* The user must define this function.  Node NP has no more references;
>     free all its associated storage. */
>  void netfs_node_norefs (struct node *np);
> @@ -341,9 +336,9 @@ extern int netfs_maxsymlinks;
>  /* Definitions provided by netfs. */
>  
>  /* Given a netnode created by the user program, wraps it in a node
> -   structure.  The new node is not locked and has a single reference.
> -   If an error occurs, NULL is returned.  */
> -struct node *netfs_make_node (struct netnode *);
> +   structure, *nnp.  The new node is not locked and has a single
> reference.

Local variables and arguments must be in caps.  I.e. NNP.

> +   If an error occurs, the error value is returned.  */
> +error_t netfs_make_node (struct netnode *nn, struct node **nnp);
>  /* Whenever node->references is to be touched, this lock must be
>     held.  Cf. netfs_nrele, netfs_nput, netfs_nref and netfs_drop_node.  */
> @@ -363,15 +358,16 @@ mach_port_t netfs_startup (mach_port_t b
>  void netfs_server_loop (void);
>  
>  /* Creates a new credential from USER which can be NULL on the peropen
> -   PO.  Returns NULL and sets errno on error.  */
> -struct protid *netfs_make_protid (struct peropen *po, struct iouser *user);
> +   PO.  Returns the error value.  */
> +error_t netfs_make_protid (struct peropen *po, struct iouser *user, 
> +                        struct protid **pi);
>  
> -/* Create and return a new peropen structure on node NP with open
> +/* Create a new peropen structure, *ppo, on node NP with open

Likewise for PPO.

>     flags FLAGS.  The initial values for the root_parent, shadow_root,
>     and shadow_root_parent fields are copied from CONTEXT if it's
> -   non-zero, otherwise zeroed.  */
> -struct peropen *netfs_make_peropen (struct node *, int,
> -                                 struct peropen *context);
> +   non-zero, otherwise zeroed.  Returns the error value. */
> +error_t netfs_make_peropen (struct node *np, int, struct peropen *context,
> +                         struct peropen **ppo);
>  
>  /* Add a reference to node NP. Unless you already hold a reference,
>     NP must be locked.  */
> Index: trans/firmlink.c
> ===================================================================
> RCS file: /cvsroot/hurd/hurd/trans/firmlink.c,v
> retrieving revision 1.12
> diff -u -p -r1.12 firmlink.c
> --- trans/firmlink.c  26 Feb 2001 04:16:01 -0000      1.12
> +++ trans/firmlink.c  29 Mar 2002 06:12:17 -0000
> @@ -1,8 +1,9 @@
>  /* A translator for `firmlinks'
>  
> -   Copyright (C) 1997, 1998, 1999, 2001 Free Software Foundation, Inc.
> +   Copyright (C) 1997, 1998, 1999, 2001, 2002 Free Software Foundation, Inc.
>  
>     Written by Miles Bader <miles@gnu.ai.mit.edu>
> +   Extended by James A. Morrison <ja2morri@uwaterloo.ca>
>  
>     This program is free software; you can redistribute it and/or
>     modify it under the terms of the GNU General Public License as
> @@ -26,42 +27,91 @@
>  #include <fcntl.h>
>  #include <argp.h>
>  #include <error.h>
> +#include <time.h>
>  #include <sys/mman.h>
>  
>  #include <hurd/trivfs.h>
>  
>  #include <version.h>
>  
> +#define TIME_MODE 0
> +#define RANDOM_MODE 1
> +#define SEQUENCE_MODE 2
> +
>  const char *argp_program_version = STANDARD_HURD_VERSION (firmlink);
>  
>  static const struct argp_option options[] =
>  {
> +  {"randomized", 'r', NULL, 0, "Randomize selection of files, default" },
> +  {"sequencial", 's', NULL, 0, "Choose files sequencially" },
> +  {"format",'f',"DATE FORMAT", 0,
> +   "Create files named file1/file2.DATE FORMAT"},
>    { 0 }
>  };
>  
> -static const char args_doc[] = "TARGET";
> -static const char doc[] = "A translator for firmlinks."
> +static const char args_doc[] = "[file1 file2 ...]";
> +static const char doc[] = "A translator for multiple firmlinks."
>  "\vA firmlink is sort of half-way between a symbolic link and a hard link:"
>  "\n"
>  "\nLike a symbolic link, it is `by name', and contains no actual reference 
> to"
>  " the target.  However, the lookup returns a node which will redirect parent"
>  " lookups so that attempts to find the cwd that go through the link will"
>  " reflect the link name, not the target name.  The target referenced by the"
> -" firmlink is looked up in the namespace of the translator, not the client.";
> +" firmlink is looked up in the namespace of the translator, not the client."
> +" A multiple firmlink can point to more than one file, and can also create"
> +" files based on dates.";
>  
>  /* Link parameters.  */
> -static char *target = 0;     /* What we translate too.  */
> +
> +struct arg_struct 
> +{
> +  char **args;
> +  char *date_format;
> +  int type;
> +  int flags;
> +  unsigned long lastused;
> +  unsigned long size;
> +};
> +
> +struct arg_struct config; 
>  
>  /* Parse a single option/argument.  */
>  static error_t
>  parse_opt (int key, char *arg, struct argp_state *state)
>  {
> -  if (key == ARGP_KEY_ARG && state->arg_num == 0)
> -    target = arg;
> -  else if (key == ARGP_KEY_ARG || key == ARGP_KEY_NO_ARGS)
> -    argp_usage (state);
> -  else
> -    return ARGP_ERR_UNKNOWN;
> +  struct arg_struct *arguments = state->input;
> +
> +  switch (key) 
> +    {
> +    case 'r':
> +      arguments->type = RANDOM_MODE;
> +      arguments->flags = O_CREAT;
> +      break; 
> +    case 's':
> +      arguments->type = SEQUENCE_MODE;
> +      arguments->flags = O_CREAT;
> +      arguments->lastused = 0;
> +      break;
> +    case 'f':
> +      arguments->type = TIME_MODE;
> +      arguments->date_format = arg;
> +      arguments->flags = 0;
> +      break;
> +    case ARGP_KEY_ARG:
> +      arguments->args[arguments->size] = arg;
> +      arguments->size++;
> +      break;
> +    case ARGP_KEY_END:
> +      if ( arguments->type == TIME_MODE && arguments->size != 2 )
> +     argp_usage (state);
> +      break; 
> +    case ARGP_KEY_NO_ARGS:
> +      argp_usage (state);
> +      break;
> +    default:
> +      return ARGP_ERR_UNKNOWN;
> +    }
> +  

Please put this in a seperate different patch.  Not to mention, there
are no change log entries indicating these changes.

>    return 0;
>  }
>  
> @@ -74,8 +124,16 @@ main (int argc, char **argv)
>    mach_port_t bootstrap;
>    struct trivfs_control *fsys;
>  
> +  config.size = 0;
> +  config.type = RANDOM_MODE;
> +  config.args = (char**) malloc (argc);
> +  if (! config.args)
> +    error (ENOMEM, 1, "Starting up");
> +
>    /* Parse our options...  */
> -  argp_parse (&argp, argc, argv, 0, 0, 0);
> +  argp_parse (&argp, argc, argv, 0, 0, &config);
> +  if ( config.type == RANDOM_MODE ) 
> +    srand (time (NULL) );

Check these parentheseses.

>    task_get_bootstrap_port (mach_task_self (), &bootstrap);
>    if (bootstrap == MACH_PORT_NULL)
> @@ -102,7 +160,26 @@ firmlink (mach_port_t parent, const char
>  {
>    error_t err;
>    file_t authed_link;
> -  file_t target = file_name_lookup (target_name, flags & ~O_CREAT, 0);
> +  file_t target = file_name_lookup (target_name, flags & ~config.flags, 0);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]