Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=16f1820028d660d9da9c03b2ae7e98253c11795b
Commit:     16f1820028d660d9da9c03b2ae7e98253c11795b
Parent:     b6a2fea39318e43fee84fa7b0b90d68bed92d2ba
Author:     Josef 'Jeff' Sipek <[EMAIL PROTECTED]>
AuthorDate: Thu Jul 19 01:48:18 2007 -0700
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Thu Jul 19 10:04:45 2007 -0700

    fs: introduce vfs_path_lookup
    
    Stackable file systems, among others, frequently need to lookup paths or
    path components starting from an arbitrary point in the namespace
    (identified by a dentry and a vfsmount).  Currently, such file systems use
    lookup_one_len, which is frowned upon [1] as it does not pass the lookup
    intent along; not passing a lookup intent, for example, can trigger BUG_ON's
    when stacking on top of NFSv4.
    
    The first patch introduces a new lookup function to allow lookup starting
    from an arbitrary point in the namespace.  This approach has been suggested
    by Christoph Hellwig [2].
    
    The second patch changes sunrpc to use vfs_path_lookup.
    
    The third patch changes nfsctl.c to use vfs_path_lookup.
    
    The fourth patch marks link_path_walk static.
    
    The fifth, and last patch, unexports path_walk because it is no longer
    unnecessary to call it directly, and using the new vfs_path_lookup is
    cleaner.
    
    For example, the following snippet of code, looks up "some/path/component"
    in a directory pointed to by parent_{dentry,vfsmnt}:
    
    err = vfs_path_lookup(parent_dentry, parent_vfsmnt,
                      "some/path/component", 0, &nd);
    if (!err) {
        /* exits */
    
        ...
    
        /* once done, release the references */
        path_release(&nd);
    } else if (err == -ENOENT) {
        /* doesn't exist */
    } else {
        /* other error */
    }
    
    VFS functions such as lookup_create can be used on the nameidata structure
    to pass the create intent to the file system.
    
    Signed-off-by: Josef 'Jeff' Sipek <[EMAIL PROTECTED]>
    Cc: Al Viro <[EMAIL PROTECTED]>
    Acked-by: Christoph Hellwig <[EMAIL PROTECTED]>
    Cc: Trond Myklebust <[EMAIL PROTECTED]>
    Cc: Neil Brown <[EMAIL PROTECTED]>
    Cc: Michael Halcrow <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 fs/namei.c            |   32 ++++++++++++++++++++++++++++++++
 include/linux/namei.h |    2 ++
 2 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index defaa47..3bdb296 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1172,6 +1172,37 @@ int fastcall path_lookup(const char *name, unsigned int 
flags,
        return do_path_lookup(AT_FDCWD, name, flags, nd);
 }
 
+/**
+ * vfs_path_lookup - lookup a file path relative to a dentry-vfsmount pair
+ * @dentry:  pointer to dentry of the base directory
+ * @mnt: pointer to vfs mount of the base directory
+ * @name: pointer to file name
+ * @flags: lookup flags
+ * @nd: pointer to nameidata
+ */
+int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
+                   const char *name, unsigned int flags,
+                   struct nameidata *nd)
+{
+       int retval;
+
+       /* same as do_path_lookup */
+       nd->last_type = LAST_ROOT;
+       nd->flags = flags;
+       nd->depth = 0;
+
+       nd->mnt = mntget(mnt);
+       nd->dentry = dget(dentry);
+
+       retval = path_walk(name, nd);
+       if (unlikely(!retval && !audit_dummy_context() && nd->dentry &&
+                               nd->dentry->d_inode))
+               audit_inode(name, nd->dentry->d_inode);
+
+       return retval;
+
+}
+
 static int __path_lookup_intent_open(int dfd, const char *name,
                unsigned int lookup_flags, struct nameidata *nd,
                int open_flags, int create_mode)
@@ -2774,6 +2805,7 @@ EXPORT_SYMBOL(__page_symlink);
 EXPORT_SYMBOL(page_symlink);
 EXPORT_SYMBOL(page_symlink_inode_operations);
 EXPORT_SYMBOL(path_lookup);
+EXPORT_SYMBOL(vfs_path_lookup);
 EXPORT_SYMBOL(path_release);
 EXPORT_SYMBOL(path_walk);
 EXPORT_SYMBOL(permission);
diff --git a/include/linux/namei.h b/include/linux/namei.h
index b7dd249..2e21af0 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -69,6 +69,8 @@ extern int FASTCALL(__user_walk_fd(int dfd, const char __user 
*, unsigned, struc
 #define user_path_walk_link(name,nd) \
        __user_walk_fd(AT_FDCWD, name, 0, nd)
 extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *));
+extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
+                          const char *, unsigned int, struct nameidata *);
 extern int FASTCALL(path_walk(const char *, struct nameidata *));
 extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
 extern void path_release(struct nameidata *);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to