From e3eec94dc91c39f2bd7939294b9cd4a65a82db44 Mon Sep 17 00:00:00 2001 From: Evgeniy Polyakov Date: Mon, 9 Feb 2009 17:02:37 +0300 Subject: Staging: pohmelfs: directory operations. This patch implementes all supported directory operations like directory reading, object lookup, creation, removal and so on. Currently object removal is not optimized at all. Signed-off-by: Evgeniy Polyakov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/pohmelfs/path_entry.c | 114 ++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 drivers/staging/pohmelfs/path_entry.c (limited to 'drivers/staging/pohmelfs/path_entry.c') diff --git a/drivers/staging/pohmelfs/path_entry.c b/drivers/staging/pohmelfs/path_entry.c new file mode 100644 index 00000000000..9270e54f157 --- /dev/null +++ b/drivers/staging/pohmelfs/path_entry.c @@ -0,0 +1,114 @@ +/* + * 2007+ Copyright (c) Evgeniy Polyakov + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "netfs.h" + +#define UNHASHED_OBSCURE_STRING_SIZE sizeof(" (deleted)") + +/* + * Create path from root for given inode. + * Path is formed as set of stuctures, containing name of the object + * and its inode data (mode, permissions and so on). + */ +int pohmelfs_construct_path_string(struct pohmelfs_inode *pi, void *data, int len) +{ + struct path path; + struct dentry *d; + char *ptr; + int err = 0, strlen, reduce = 0; + + d = d_find_alias(&pi->vfs_inode); + if (!d) { + printk("%s: no alias, list_empty: %d.\n", __func__, list_empty(&pi->vfs_inode.i_dentry)); + return -ENOENT; + } + + read_lock(¤t->fs->lock); + path.mnt = mntget(current->fs->root.mnt); + read_unlock(¤t->fs->lock); + + path.dentry = d; + + if (!IS_ROOT(d) && d_unhashed(d)) + reduce = 1; + + ptr = d_path(&path, data, len); + if (IS_ERR(ptr)) { + err = PTR_ERR(ptr); + goto out; + } + + if (reduce && len >= UNHASHED_OBSCURE_STRING_SIZE) { + char *end = data + len - UNHASHED_OBSCURE_STRING_SIZE; + *end = '\0'; + } + + strlen = len - (ptr - (char *)data); + memmove(data, ptr, strlen); + ptr = data; + + err = strlen; + + dprintk("%s: dname: '%s', len: %u, maxlen: %u, name: '%s', strlen: %d.\n", + __func__, d->d_name.name, d->d_name.len, len, ptr, strlen); + +out: + dput(d); + mntput(path.mnt); + + return err; +} + +int pohmelfs_path_length(struct pohmelfs_inode *pi) +{ + struct dentry *d, *root, *first; + int len = 1; /* Root slash */ + + first = d = d_find_alias(&pi->vfs_inode); + if (!d) { + dprintk("%s: ino: %llu, mode: %o.\n", __func__, pi->ino, pi->vfs_inode.i_mode); + return -ENOENT; + } + + read_lock(¤t->fs->lock); + root = dget(current->fs->root.dentry); + read_unlock(¤t->fs->lock); + + spin_lock(&dcache_lock); + + if (!IS_ROOT(d) && d_unhashed(d)) + len += UNHASHED_OBSCURE_STRING_SIZE; /* Obscure " (deleted)" string */ + + while (d && d != root && !IS_ROOT(d)) { + len += d->d_name.len + 1; /* Plus slash */ + d = d->d_parent; + } + spin_unlock(&dcache_lock); + + dput(root); + dput(first); + + return len + 1; /* Including zero-byte */ +} -- cgit v1.2.3