Re: [PATCH 02/18] exportfs: add new methods

2007-09-21 Thread Christoph Hellwig
On Thu, Sep 20, 2007 at 05:18:40PM -0700, Andrew Morton wrote:
> On Wed, 19 Sep 2007 18:30:25 +0200
> Christoph Hellwig <[EMAIL PROTECTED]> wrote:
> 
> > +   /*
> > +* It's not a directory.  Life is a little more complicated.
> > +*/
> > +   struct dentry *target_dir, *nresult;
> > +   char nbuf[NAME_MAX+1];
> 
> Lots of stack usage there.

True.  But this is just copying the old code around to make use of the
new methods, so I didn't want to mess with underlying details.
-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 02/18] exportfs: add new methods

2007-09-20 Thread Andrew Morton
On Wed, 19 Sep 2007 18:30:25 +0200
Christoph Hellwig <[EMAIL PROTECTED]> wrote:

> + /*
> +  * It's not a directory.  Life is a little more complicated.
> +  */
> + struct dentry *target_dir, *nresult;
> + char nbuf[NAME_MAX+1];

Lots of stack usage there.
-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 02/18] exportfs: add new methods

2007-09-19 Thread Christoph Hellwig
Add the guts for the new filesystem API to exportfs.

There's now a fh_to_dentry method that returns a dentry for the 
object looked for given a filehandle fragment, and a fh_to_parent
operation that returns the dentry for the encoded parent directory
in case the file handle contains it.

There are default implementations for these methods that only take
a callback for an nfs-enhanced iget variant and implement the
rest of the semantics.


Signed-off-by: Christoph Hellwig <[EMAIL PROTECTED]>

Index: linux-2.6/include/linux/exportfs.h
===
--- linux-2.6.orig/include/linux/exportfs.h 2007-09-13 15:11:11.0 
+0200
+++ linux-2.6/include/linux/exportfs.h  2007-09-13 15:13:57.0 +0200
@@ -4,6 +4,7 @@
 #include 
 
 struct dentry;
+struct inode;
 struct super_block;
 struct vfsmount;
 
@@ -101,6 +102,21 @@ struct fid {
  *the filehandle fragment.  encode_fh() should return the number of bytes
  *stored or a negative error code such as %-ENOSPC
  *
+ * fh_to_dentry:
+ *@fh_to_dentry is given a &struct super_block (@sb) and a file handle
+ *fragment (@fh, @fh_len). It should return a &struct dentry which refers
+ *to the same file that the file handle fragment refers to.  If it cannot,
+ *it should return a %NULL pointer if the file was found but no acceptable
+ *&dentries were available, or an %ERR_PTR error code indicating why it
+ *couldn't be found (e.g. %ENOENT or %ENOMEM).  Any suitable dentry can be
+ *returned including, if necessary, a new dentry created with d_alloc_root.
+ *The caller can then find any other extant dentries by following the
+ *d_alias links.
+ *
+ * fh_to_parent:
+ *Same as @fh_to_dentry, except that it returns a pointer to the parent
+ *dentry if it was encoded into the filehandle fragment by @encode_fh.
+ *
  * get_name:
  *@get_name should find a name for the given @child in the given @parent
  *directory.  The name should be stored in the @name (with the
@@ -139,6 +155,10 @@ struct export_operations {
void *context);
int (*encode_fh)(struct dentry *de, __u32 *fh, int *max_len,
int connectable);
+   struct dentry * (*fh_to_dentry)(struct super_block *sb, struct fid *fid,
+   int fh_len, int fh_type);
+   struct dentry * (*fh_to_parent)(struct super_block *sb, struct fid *fid,
+   int fh_len, int fh_type);
int (*get_name)(struct dentry *parent, char *name,
struct dentry *child);
struct dentry * (*get_parent)(struct dentry *child);
@@ -161,4 +181,14 @@ extern struct dentry *exportfs_decode_fh
int fh_len, int fileid_type, int (*acceptable)(void *, struct dentry *),
void *context);
 
+/*
+ * Generic helpers for filesystems.
+ */
+extern struct dentry *generic_fh_to_dentry(struct super_block *sb,
+   struct fid *fid, int fh_len, int fh_type,
+   struct inode *(*get_inode) (struct super_block *sb, u64 ino, u32 gen));
+extern struct dentry *generic_fh_to_parent(struct super_block *sb,
+   struct fid *fid, int fh_len, int fh_type,
+   struct inode *(*get_inode) (struct super_block *sb, u64 ino, u32 gen));
+
 #endif /* LINUX_EXPORTFS_H */
Index: linux-2.6/fs/exportfs/expfs.c
===
--- linux-2.6.orig/fs/exportfs/expfs.c  2007-09-13 15:13:02.0 +0200
+++ linux-2.6/fs/exportfs/expfs.c   2007-09-13 15:14:42.0 +0200
@@ -514,17 +514,141 @@ struct dentry *exportfs_decode_fh(struct
int (*acceptable)(void *, struct dentry *), void *context)
 {
struct export_operations *nop = mnt->mnt_sb->s_export_op;
-   struct dentry *result;
+   struct dentry *result, *alias;
+   int err;
 
-   if (nop->decode_fh) {
-   result = nop->decode_fh(mnt->mnt_sb, fid->raw, fh_len,
+   /*
+* Old way of doing things.  Will go away soon.
+*/
+   if (!nop->fh_to_dentry) {
+   if (nop->decode_fh) {
+   return nop->decode_fh(mnt->mnt_sb, fid->raw, fh_len,
fileid_type, acceptable, context);
+   } else {
+   return export_decode_fh(mnt->mnt_sb, fid->raw, fh_len,
+   fileid_type, acceptable, context);
+   }
+   }
+
+   /*
+* Try to get any dentry for the given file handle from the filesystem.
+*/
+   result = nop->fh_to_dentry(mnt->mnt_sb, fid, fh_len, fileid_type);
+   if (!result)
+   result = ERR_PTR(-ESTALE);
+   if (IS_ERR(result))
+   return result;
+
+   if (S_ISDIR(result->d_inode->i_mode)) {
+   /*
+* This request is for a directory.
+*
+* On the positive side there is only one dentry for