summaryrefslogtreecommitdiff
path: root/procfs.c
diff options
context:
space:
mode:
authorJeremie Koenig <jk@jk.fr.eu.org>2010-08-19 07:48:30 +0000
committerJeremie Koenig <jk@jk.fr.eu.org>2010-08-30 14:18:32 +0200
commitc6c770c33eb0f23e7e8e04976c711653cdf1a41d (patch)
treeff22cd9494fe9fb50f8d7b514d9a0f4102dd7db3 /procfs.c
parent4ac169deaa1eb4c8df4a49fc940700971fa5863a (diff)
Implement lookup for . and ..
* procfs.c (procfs_lookup): Keep track of the parent directory, implement the lookup of the dot-directories. (procfs_cleanup): Release the reference to the parent node, if applicable. * procfs.h: Add a comment about the parent reference. * netfs.c (netfs_attempt_lookup): Lock the looked up node after the directory has been unlocked, in case they are the same.
Diffstat (limited to 'procfs.c')
-rw-r--r--procfs.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/procfs.c b/procfs.c
index 573bb72..c5f1949 100644
--- a/procfs.c
+++ b/procfs.c
@@ -14,6 +14,9 @@ struct netnode
/* (cached) contents of the node */
void *contents;
size_t contents_len;
+
+ /* parent directory, if applicable */
+ struct node *parent;
};
void
@@ -97,8 +100,24 @@ error_t procfs_lookup (struct node *np, const char *name, struct node **npp)
{
error_t err = ENOENT;
- if (np->nn->ops->lookup)
- err = np->nn->ops->lookup (np->nn->hook, name, npp);
+ if (err && ! strcmp (name, "."))
+ {
+ netfs_nref(*npp = np);
+ err = 0;
+ }
+
+ if (err && np->nn->parent && ! strcmp (name, ".."))
+ {
+ netfs_nref(*npp = np->nn->parent);
+ err = 0;
+ }
+
+ if (err && np->nn->ops->lookup)
+ {
+ err = np->nn->ops->lookup (np->nn->hook, name, npp);
+ if (! err)
+ netfs_nref ((*npp)->nn->parent = np);
+ }
return err;
}
@@ -111,5 +130,8 @@ void procfs_cleanup (struct node *np)
if (np->nn->ops->cleanup)
np->nn->ops->cleanup (np->nn->hook);
+ if (np->nn->parent)
+ netfs_nrele (np->nn->parent);
+
free (np->nn);
}