summaryrefslogtreecommitdiffstats
path: root/fs/dcache.c
diff options
context:
space:
mode:
authorMiguel de Icaza <miguel@nuclecu.unam.mx>1997-08-06 19:14:48 +0000
committerMiguel de Icaza <miguel@nuclecu.unam.mx>1997-08-06 19:14:48 +0000
commite2819e52a162873ff5061de81bb749831bdb5de9 (patch)
tree6067ea700202750ba335a423696f2972700e5f76 /fs/dcache.c
parent17a005074429bbf143e40401f405ae4363e56828 (diff)
Merge to 2.1.38.
IMPORTANT NOTE: I could not figure out what information is the one that should be used for the following files (ie, those that were in our tree, or those that came from Linus' patch), please, check these: include/asm-mips/jazz.h include/asm-mips/jazzdma.h include/asm-mips/ioctls.h
Diffstat (limited to 'fs/dcache.c')
-rw-r--r--fs/dcache.c50
1 files changed, 33 insertions, 17 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index 97937822f..6e742ca7f 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -353,27 +353,43 @@ void d_move(struct dentry * dentry, struct dentry * newdir, struct qstr * newnam
dentry->d_parent = newdir;
d_insert_to_parent(dentry, newdir);
}
-
/*
- * This is broken in more ways than one. Unchecked recursion,
- * unchecked buffer size. Get rid of it.
+ * "buflen" should be PAGE_SIZE or more.
*/
-int d_path(struct dentry * entry, struct dentry * chroot, char * buf)
+char * d_path(struct dentry *dentry, char *buffer, int buflen)
{
- if (IS_ROOT(entry) || (chroot && entry == chroot)) {
- *buf = '/';
- return 1;
- } else {
- int len = d_path(entry->d_covers->d_parent, chroot, buf);
-
- buf += len;
- if (len > 1) {
- *buf++ = '/';
- len++;
- }
- memcpy(buf, entry->d_name.name, entry->d_name.len);
- return len + entry->d_name.len;
+ char * end = buffer+buflen;
+ char * retval;
+ struct dentry * root = current->fs->root;
+
+ *--end = '\0';
+ buflen--;
+
+ /* Get '/' right */
+ retval = end-1;
+ *retval = '/';
+
+ for (;;) {
+ struct dentry * parent;
+ int namelen;
+
+ if (dentry == root)
+ break;
+ dentry = dentry->d_covers;
+ parent = dentry->d_parent;
+ if (dentry == parent)
+ break;
+ namelen = dentry->d_name.len;
+ buflen -= namelen + 1;
+ if (buflen < 0)
+ break;
+ end -= namelen;
+ memcpy(end, dentry->d_name.name, namelen);
+ *--end = '/';
+ retval = end;
+ dentry = parent;
}
+ return retval;
}
__initfunc(void dcache_init(void))