[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 03/16] libdiskfs: track file name in struct peropen
From: |
Justus Winter |
Subject: |
[PATCH 03/16] libdiskfs: track file name in struct peropen |
Date: |
Tue, 30 Jul 2013 11:59:11 +0200 |
Track the relative path used to obtain a file handle in the
struct peropen.
* libdiskfs/diskfs.h (struct peropen): New field path.
* libdiskfs/peropen-make.c (diskfs_make_peropen): Initialize path.
* libdiskfs/peropen-rele.c (diskfs_release_peropen): Free path.
* libdiskfs/fsys-getroot.c (diskfs_S_fsys_getroot): Initialize path.
* libdiskfs/dir-lookup.c (diskfs_S_dir_lookup): Preserve the path.
* libdiskfs/dir-rename.c (diskfs_S_dir_rename): Update the path.
---
libdiskfs/dir-lookup.c | 26 +++++++++++++++++++++++++-
libdiskfs/dir-rename.c | 22 +++++++++++++++++++---
libdiskfs/diskfs.h | 3 +++
libdiskfs/fsys-getroot.c | 3 ++-
libdiskfs/peropen-make.c | 8 ++++++++
libdiskfs/peropen-rele.c | 1 +
6 files changed, 58 insertions(+), 5 deletions(-)
diff --git a/libdiskfs/dir-lookup.c b/libdiskfs/dir-lookup.c
index 923be03..15a9b0c 100644
--- a/libdiskfs/dir-lookup.c
+++ b/libdiskfs/dir-lookup.c
@@ -1,6 +1,6 @@
/* libdiskfs implementation of fs.defs:dir_lookup
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- 2002, 2008 Free Software Foundation, Inc.
+ 2002, 2008, 2013 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -41,6 +41,7 @@ diskfs_S_dir_lookup (struct protid *dircred,
struct node *np;
int nsymlink = 0;
char *nextname;
+ char *relpath;
int nextnamelen;
error_t error = 0;
char *pathbuf = 0;
@@ -68,6 +69,11 @@ diskfs_S_dir_lookup (struct protid *dircred,
while (path[0] == '/')
path++;
+ /* Preserve the path relative to diruser->po->path. */
+ relpath = strdup (path);
+ if (! relpath)
+ return ENOMEM;
+
*returned_port_poly = MACH_MSG_TYPE_MAKE_SEND;
*retry = FS_RETRY_NORMAL;
retryname[0] = '\0';
@@ -479,6 +485,22 @@ diskfs_S_dir_lookup (struct protid *dircred,
if (! error)
{
+ free (newpi->po->path);
+ if (dircred->po->path == NULL)
+ {
+ /* dircred 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", dircred->po->path, relpath);
+ }
+
+ if (! newpi->po->path)
+ error = errno;
+
*returned_port = ports_get_right (newpi);
ports_port_deref (newpi);
newpi = 0;
@@ -500,5 +522,7 @@ diskfs_S_dir_lookup (struct protid *dircred,
if (newpo)
diskfs_release_peropen (newpo);
+ free (relpath);
+
return error;
}
diff --git a/libdiskfs/dir-rename.c b/libdiskfs/dir-rename.c
index ff9dead..4e8627a 100644
--- a/libdiskfs/dir-rename.c
+++ b/libdiskfs/dir-rename.c
@@ -1,6 +1,6 @@
/* libdiskfs implementation of fs.defs: dir_rename
- Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 2007
+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 2007, 2013
Free Software Foundation
This program is free software; you can redistribute it and/or
@@ -100,8 +100,17 @@ diskfs_S_dir_rename (struct protid *fromcred,
diskfs_nrele (fnp);
pthread_mutex_unlock (&renamedirlock);
if (!err)
- /* MiG won't do this for us, which it ought to. */
- mach_port_deallocate (mach_task_self (), tocred->pi.port_right);
+ {
+ /* MiG won't do this for us, which it ought to. */
+ mach_port_deallocate (mach_task_self (), tocred->pi.port_right);
+
+ /* Update fromcred->po->path for anyone who still has a
+ reference to this node. */
+ free (fromcred->po->path);
+ fromcred->po->path = strdup (tocred->po->path);
+ if (! fromcred->po->path)
+ return ENOMEM;
+ }
return err;
}
@@ -194,6 +203,13 @@ diskfs_S_dir_rename (struct protid *fromcred,
/* We now hold no locks */
+ /* Update fromcred->po->path for anyone who still has a reference to
+ this node. */
+ free (fromcred->po->path);
+ fromcred->po->path = strdup (tocred->po->path);
+ if (! fromcred->po->path)
+ return ENOMEM;
+
/* Now we remove the source. Unfortunately, we haven't held
fdp locked (nor could we), so someone else might have already
removed it. */
diff --git a/libdiskfs/diskfs.h b/libdiskfs/diskfs.h
index 0f9c1d3..2489517 100644
--- a/libdiskfs/diskfs.h
+++ b/libdiskfs/diskfs.h
@@ -69,6 +69,9 @@ struct peropen
mach_port_t shadow_root_parent;
/* If in a shadow tree, its root node in this translator. */
struct node *shadow_root;
+
+ /* Path relative to the root of the translator. */
+ char *path;
};
/* A unique one of these exists for each node currently in use (and
diff --git a/libdiskfs/fsys-getroot.c b/libdiskfs/fsys-getroot.c
index 2e11da4..39973a8 100644
--- a/libdiskfs/fsys-getroot.c
+++ b/libdiskfs/fsys-getroot.c
@@ -51,7 +51,8 @@ diskfs_S_fsys_getroot (fsys_t controlport,
{
root_parent: dotdot,
shadow_root_parent: MACH_PORT_NULL,
- shadow_root: _diskfs_chroot_directory ? diskfs_root_node : NULL /* XXX */
+ shadow_root: _diskfs_chroot_directory ? diskfs_root_node : NULL, /* XXX */
+ path: NULL,
};
if (!pt)
diff --git a/libdiskfs/peropen-make.c b/libdiskfs/peropen-make.c
index d37516c..b11b2ad 100644
--- a/libdiskfs/peropen-make.c
+++ b/libdiskfs/peropen-make.c
@@ -34,6 +34,7 @@ diskfs_make_peropen (struct node *np, int flags, struct
peropen *context,
po->refcnt = 0;
po->openstat = flags;
po->np = np;
+ po->path = NULL;
if (context)
{
@@ -50,6 +51,13 @@ diskfs_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;
+ }
}
else
{
diff --git a/libdiskfs/peropen-rele.c b/libdiskfs/peropen-rele.c
index 08276ec..d3f7492 100644
--- a/libdiskfs/peropen-rele.c
+++ b/libdiskfs/peropen-rele.c
@@ -45,5 +45,6 @@ diskfs_release_peropen (struct peropen *po)
diskfs_nput (po->np);
+ free (po->path);
free (po);
}
--
1.7.10.4
- mtab translator (v4), Justus Winter, 2013/07/30
- [PATCH 02/16] libnetfs: handle dead-name notifications, Justus Winter, 2013/07/30
- [PATCH 01/16] libnetfs: implement file_get_translator_cntl, Justus Winter, 2013/07/30
- [PATCH 03/16] libdiskfs: track file name in struct peropen,
Justus Winter <=
- [PATCH 04/16] libnetfs: track file name in struct peropen, Justus Winter, 2013/07/30
- [PATCH 05/16] libfshelp: add translator-list.c, Justus Winter, 2013/07/30
- [PATCH 06/16] libdiskfs: add fsys_get_children, Justus Winter, 2013/07/30
- [PATCH 08/16] libtrivfs: add fsys_get_children, Justus Winter, 2013/07/30
- [PATCH 07/16] libnetfs: add fsys_get_children, Justus Winter, 2013/07/30
- [PATCH 09/16] trans/symlink.c: add fsys_get_children, Justus Winter, 2013/07/30
- [PATCH 10/16] hurd: add fsys_get_children, Justus Winter, 2013/07/30