bug-hurd
[Top][All Lists]
Advanced

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

[PATCH 04/16] libnetfs: track file name in struct peropen


From: Justus Winter
Subject: [PATCH 04/16] libnetfs: track file name in struct peropen
Date: Tue, 30 Jul 2013 11:59:12 +0200

Track the relative path used to obtain a file handle in the
struct peropen.

* libnetfs/netfs.h (struct peropen): New field path.
* libnetfs/make-peropen.c (netfs_make_peropen): Initialize path.
* libnetfs/release-peropen.c (netfs_release_peropen): Free path.
* libnetfs/fsys-getroot.c (netfs_S_fsys_getroot): Initialize path.
* libnetfs/dir-lookup.c (netfs_S_dir_lookup): Preserve the path.
* libnetfs/dir-rename.c (netfs_S_dir_rename): Update the path.
---
 libnetfs/dir-lookup.c      |   26 +++++++++++++++++++++++++-
 libnetfs/dir-rename.c      |   14 +++++++++++---
 libnetfs/fsys-getroot.c    |    6 +++++-
 libnetfs/make-peropen.c    |    8 ++++++++
 libnetfs/netfs.h           |    2 ++
 libnetfs/release-peropen.c |    1 +
 6 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/libnetfs/dir-lookup.c b/libnetfs/dir-lookup.c
index f1b6438..10ea2d0 100644
--- a/libnetfs/dir-lookup.c
+++ b/libnetfs/dir-lookup.c
@@ -1,5 +1,6 @@
 /*
-   Copyright (C) 1995,96,97,98,99,2000,01,02 Free Software Foundation, Inc.
+   Copyright (C) 1995,96,97,98,99,2000,01,02,13
+     Free Software Foundation, Inc.
    Written by Michael I. Bushnell, p/BSG.
 
    This file is part of the GNU Hurd.
@@ -46,6 +47,7 @@ netfs_S_dir_lookup (struct protid *diruser,
   int nsymlinks = 0;
   struct node *dnp, *np;
   char *nextname;
+  char *relpath;
   error_t error;
   struct protid *newpi;
   struct iouser *user;
@@ -60,6 +62,11 @@ netfs_S_dir_lookup (struct protid *diruser,
   while (*filename == '/')
     filename++;
 
+  /* Preserve the path relative to diruser->po->path.  */
+  relpath = strdup (filename);
+  if (! relpath)
+    return ENOMEM;
+
   *retry_port_type = MACH_MSG_TYPE_MAKE_SEND;
   *do_retry = FS_RETRY_NORMAL;
   *retry_name = '\0';
@@ -390,6 +397,22 @@ netfs_S_dir_lookup (struct protid *diruser,
       goto out;
     }
 
+  free (newpi->po->path);
+  if (diruser->po->path == NULL)
+    {
+      /* diruser is the root directory.  */
+      newpi->po->path = relpath;
+      relpath = NULL; /* Do not free relpath.  */
+    }
+  else
+    {
+      newpi->po->path = NULL;
+      asprintf (&newpi->po->path, "%s/%s", diruser->po->path, relpath);
+    }
+
+  if (! newpi->po->path)
+    error = errno;
+
   *retry_port = ports_get_right (newpi);
   ports_port_deref (newpi);
 
@@ -398,5 +421,6 @@ netfs_S_dir_lookup (struct protid *diruser,
     netfs_nput (np);
   if (dnp)
     netfs_nrele (dnp);
+  free (relpath);
   return error;
 }
diff --git a/libnetfs/dir-rename.c b/libnetfs/dir-rename.c
index 0215376..e826d50 100644
--- a/libnetfs/dir-rename.c
+++ b/libnetfs/dir-rename.c
@@ -1,5 +1,5 @@
 /* 
-   Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 2013 Free Software Foundation, Inc.
    Written by Michael I. Bushnell, p/BSG.
 
    This file is part of the GNU Hurd.
@@ -37,7 +37,15 @@ netfs_S_dir_rename (struct protid *fromdiruser, char 
*fromname,
   err = netfs_attempt_rename (fromdiruser->user, fromdiruser->po->np, 
                              fromname, todiruser->po->np, toname, excl);
   if (!err)
-    mach_port_deallocate (mach_task_self (), todiruser->pi.port_right);
+    {
+      mach_port_deallocate (mach_task_self (), todiruser->pi.port_right);
+
+      /* Update fromdiruser->po->path for anyone who still has a
+        reference to this node.  */
+      free (fromdiruser->po->path);
+      fromdiruser->po->path = strdup (todiruser->po->path);
+      if (! fromdiruser->po->path)
+       return ENOMEM;
+    }
   return err;
 }
-
diff --git a/libnetfs/fsys-getroot.c b/libnetfs/fsys-getroot.c
index a1dd5e5..0d80111 100644
--- a/libnetfs/fsys-getroot.c
+++ b/libnetfs/fsys-getroot.c
@@ -43,7 +43,11 @@ netfs_S_fsys_getroot (mach_port_t cntl,
   error_t err;
   struct protid *newpi;
   mode_t type;
-  struct peropen peropen_context = { root_parent: dotdot };
+  struct peropen peropen_context =
+    {
+      root_parent: dotdot,
+      path: NULL,
+    };
 
   if (!pt)
     return EOPNOTSUPP;
diff --git a/libnetfs/make-peropen.c b/libnetfs/make-peropen.c
index 92f58da..733bfdc 100644
--- a/libnetfs/make-peropen.c
+++ b/libnetfs/make-peropen.c
@@ -31,6 +31,7 @@ netfs_make_peropen (struct node *np, int flags, struct 
peropen *context)
   po->refcnt = 0;
   po->openstat = flags;
   po->np = np;
+  po->path = NULL;
 
   if (context)
     {
@@ -47,6 +48,13 @@ netfs_make_peropen (struct node *np, int flags, struct 
peropen *context)
       if (po->shadow_root_parent != MACH_PORT_NULL)
        mach_port_mod_refs (mach_task_self (), po->shadow_root_parent,
                            MACH_PORT_RIGHT_SEND, 1);
+
+      if (context->path)
+       {
+         po->path = strdup (context->path);
+         if (! po->path)
+           return ENOMEM;
+       }
     }
 
   netfs_nref (np);
diff --git a/libnetfs/netfs.h b/libnetfs/netfs.h
index d1ebed0..2b9454a 100644
--- a/libnetfs/netfs.h
+++ b/libnetfs/netfs.h
@@ -63,6 +63,8 @@ struct peropen
   mach_port_t shadow_root_parent;
   /* If in a shadow tree, its root node in this translator.  */
   struct node *shadow_root;
+
+  char *path;
 };
 
 /* A unique one of these exists for each node currently in use. */
diff --git a/libnetfs/release-peropen.c b/libnetfs/release-peropen.c
index 3e65099..d4d3574 100644
--- a/libnetfs/release-peropen.c
+++ b/libnetfs/release-peropen.c
@@ -41,6 +41,7 @@ netfs_release_peropen (struct peropen *po)
 
       netfs_nput (po->np);
 
+      free (po->path);
       free (po);
     }
 }
-- 
1.7.10.4




reply via email to

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