]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/ntfs/namei.c
Merge branch 'core/stacktrace' of git://git.kernel.org/pub/scm/linux/kernel/git/tip...
[linux-2.6-omap-h63xx.git] / fs / ntfs / namei.c
index 351dbc3b6e404bfc36bcbd0735069acc6b4fea24..e1781c8b16504cf9c59333c3ac5b7475b9978578 100644 (file)
@@ -2,7 +2,7 @@
  * namei.c - NTFS kernel directory inode operations. Part of the Linux-NTFS
  *          project.
  *
- * Copyright (c) 2001-2004 Anton Altaparmakov
+ * Copyright (c) 2001-2006 Anton Altaparmakov
  *
  * This program/include file is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as published
@@ -21,6 +21,7 @@
  */
 
 #include <linux/dcache.h>
+#include <linux/exportfs.h>
 #include <linux/security.h>
 
 #include "attrib.h"
@@ -96,7 +97,7 @@
  *    name. We then convert the name to the current NLS code page, and proceed
  *    searching for a dentry with this name, etc, as in case 2), above.
  *
- * Locking: Caller must hold i_sem on the directory.
+ * Locking: Caller must hold i_mutex on the directory.
  */
 static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent,
                struct nameidata *nd)
@@ -115,7 +116,9 @@ static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent,
        uname_len = ntfs_nlstoucs(vol, dent->d_name.name, dent->d_name.len,
                        &uname);
        if (uname_len < 0) {
-               ntfs_error(vol->sb, "Failed to convert name to Unicode.");
+               if (uname_len != -ENAMETOOLONG)
+                       ntfs_error(vol->sb, "Failed to convert name to "
+                                       "Unicode.");
                return ERR_PTR(uname_len);
        }
        mref = ntfs_lookup_inode_by_name(NTFS_I(dir_ino), uname, uname_len,
@@ -157,7 +160,7 @@ static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent,
                /* Return the error code. */
                return (struct dentry *)dent_inode;
        }
-       /* It is guaranteed that name is no longer allocated at this point. */
+       /* It is guaranteed that @name is no longer allocated at this point. */
        if (MREF_ERR(mref) == -ENOENT) {
                ntfs_debug("Entry was not found, adding negative dentry.");
                /* The dcache will handle negative entries. */
@@ -168,7 +171,6 @@ static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent,
        ntfs_error(vol->sb, "ntfs_lookup_ino_by_name() failed with error "
                        "code %i.", -MREF_ERR(mref));
        return ERR_PTR(MREF_ERR(mref));
-
        // TODO: Consider moving this lot to a separate function! (AIA)
 handle_name:
    {
@@ -254,7 +256,7 @@ handle_name:
        nls_name.hash = full_name_hash(nls_name.name, nls_name.len);
 
        /*
-        * Note: No need for dent->d_lock lock as i_sem is held on the
+        * Note: No need for dent->d_lock lock as i_mutex is held on the
         * parent inode.
         */
 
@@ -358,7 +360,7 @@ err_out:
 /**
  * Inode operations for directories.
  */
-struct inode_operations ntfs_dir_inode_ops = {
+const struct inode_operations ntfs_dir_inode_ops = {
        .lookup = ntfs_lookup,  /* VFS: Lookup directory. */
 };
 
@@ -374,7 +376,7 @@ struct inode_operations ntfs_dir_inode_ops = {
  * The code is based on the ext3 ->get_parent() implementation found in
  * fs/ext3/namei.c::ext3_get_parent().
  *
- * Note: ntfs_get_parent() is called with @child_dent->d_inode->i_sem down.
+ * Note: ntfs_get_parent() is called with @child_dent->d_inode->i_mutex down.
  *
  * Return the dentry of the parent directory on success or the error code on
  * error (IS_ERR() is true).
@@ -448,58 +450,40 @@ try_next:
        return parent_dent;
 }
 
-/**
- * ntfs_get_dentry - find a dentry for the inode from a file handle sub-fragment
- * @sb:                super block identifying the mounted ntfs volume
- * @fh:                the file handle sub-fragment
- *
- * Find a dentry for the inode given a file handle sub-fragment.  This function
- * is called from fs/exportfs/expfs.c::find_exported_dentry() which in turn is
- * called from the default ->decode_fh() which is export_decode_fh() in the
- * same file.  The code is closely based on the default ->get_dentry() helper
- * fs/exportfs/expfs.c::get_object().
- *
- * The @fh contains two 32-bit unsigned values, the first one is the inode
- * number and the second one is the inode generation.
- *
- * Return the dentry on success or the error code on error (IS_ERR() is true).
- */
-static struct dentry *ntfs_get_dentry(struct super_block *sb, void *fh)
+static struct inode *ntfs_nfs_get_inode(struct super_block *sb,
+               u64 ino, u32 generation)
 {
-       struct inode *vi;
-       struct dentry *dent;
-       unsigned long ino = ((u32 *)fh)[0];
-       u32 gen = ((u32 *)fh)[1];
+       struct inode *inode;
 
-       ntfs_debug("Entering for inode 0x%lx, generation 0x%x.", ino, gen);
-       vi = ntfs_iget(sb, ino);
-       if (IS_ERR(vi)) {
-               ntfs_error(sb, "Failed to get inode 0x%lx.", ino);
-               return (struct dentry *)vi;
-       }
-       if (unlikely(is_bad_inode(vi) || vi->i_generation != gen)) {
-               /* We didn't find the right inode. */
-               ntfs_error(sb, "Inode 0x%lx, bad count: %d %d or version 0x%x "
-                               "0x%x.", vi->i_ino, vi->i_nlink,
-                               atomic_read(&vi->i_count), vi->i_generation,
-                               gen);
-               iput(vi);
-               return ERR_PTR(-ESTALE);
-       }
-       /* Now find a dentry.  If possible, get a well-connected one. */
-       dent = d_alloc_anon(vi);
-       if (unlikely(!dent)) {
-               iput(vi);
-               return ERR_PTR(-ENOMEM);
+       inode = ntfs_iget(sb, ino);
+       if (!IS_ERR(inode)) {
+               if (is_bad_inode(inode) || inode->i_generation != generation) {
+                       iput(inode);
+                       inode = ERR_PTR(-ESTALE);
+               }
        }
-       ntfs_debug("Done for inode 0x%lx, generation 0x%x.", ino, gen);
-       return dent;
+
+       return inode;
+}
+
+static struct dentry *ntfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
+               int fh_len, int fh_type)
+{
+       return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
+                                   ntfs_nfs_get_inode);
+}
+
+static struct dentry *ntfs_fh_to_parent(struct super_block *sb, struct fid *fid,
+               int fh_len, int fh_type)
+{
+       return generic_fh_to_parent(sb, fid, fh_len, fh_type,
+                                   ntfs_nfs_get_inode);
 }
 
 /**
  * Export operations allowing NFS exporting of mounted NTFS partitions.
  *
- * We use the default ->decode_fh() and ->encode_fh() for now.  Note that they
+ * We use the default ->encode_fh() for now.  Note that they
  * use 32 bits to store the inode number which is an unsigned long so on 64-bit
  * architectures is usually 64 bits so it would all fail horribly on huge
  * volumes.  I guess we need to define our own encode and decode fh functions
@@ -515,10 +499,9 @@ static struct dentry *ntfs_get_dentry(struct super_block *sb, void *fh)
  * allowing the inode number 0 which is used in NTFS for the system file $MFT
  * and due to using iget() whereas NTFS needs ntfs_iget().
  */
-struct export_operations ntfs_export_ops = {
+const struct export_operations ntfs_export_ops = {
        .get_parent     = ntfs_get_parent,      /* Find the parent of a given
                                                   directory. */
-       .get_dentry     = ntfs_get_dentry,      /* Find a dentry for the inode
-                                                  given a file handle
-                                                  sub-fragment. */
+       .fh_to_dentry   = ntfs_fh_to_dentry,
+       .fh_to_parent   = ntfs_fh_to_parent,
 };