* [PATCH 000 of 8] knfsd: cleanups for exportfs code.
@ 2007-05-15 7:15 NeilBrown
2007-05-15 7:16 ` [PATCH 001 of 8] knfsd: exportfs: add exportfs.h header NeilBrown
` (7 more replies)
0 siblings, 8 replies; 10+ messages in thread
From: NeilBrown @ 2007-05-15 7:15 UTC (permalink / raw)
To: Andrew Morton
Cc: nfs, linux-kernel, Christoph Hellwig, Christoph Hellwig,
Neil Brown, shaggy
Following are 8 patches from Christoph Hellwig which tidy up the
"exportfs" code used by nfsd for communicating with filesystems about
the handling of filehandles.
One change of note is that the old "iget" approach to filehandle
lookup is moved out of generic code and into the two filesystems that
still use it (including jfs: hence the Cc to shaggy@austin.ibm.com).
These are for -mm until 2.6.23 opens.
NeilBrown
[PATCH 001 of 8] knfsd: exportfs: add exportfs.h header
[PATCH 002 of 8] knfsd: exportfs: remove iget abuse
[PATCH 003 of 8] knfsd: exportfs: add procedural interface for NFSD
[PATCH 004 of 8] knfsd: exportfs: remove CALL macro
[PATCH 005 of 8] knfsd: exportfs: untangle ISDIR logic in find_exported_dentry
[PATCH 006 of 8] knfsd: exportfs: move acceptable check into find_acceptable_alias
[PATCH 007 of 8] knfsd: exportfs: add find_disconnected_root helper
[PATCH 008 of 8] knfsd: exportfs: split out reconnecting a dentry from find_exported_dentry.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 001 of 8] knfsd: exportfs: add exportfs.h header
2007-05-15 7:15 [PATCH 000 of 8] knfsd: cleanups for exportfs code NeilBrown
@ 2007-05-15 7:16 ` NeilBrown
2007-05-15 7:16 ` [PATCH 002 of 8] knfsd: exportfs: remove iget abuse NeilBrown
` (6 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: NeilBrown @ 2007-05-15 7:16 UTC (permalink / raw)
To: Andrew Morton
Cc: nfs, linux-kernel, Christoph Hellwig, Christoph Hellwig,
Neil Brown
From: Christoph Hellwig <hch@infradead.org>
currently the export_operation structure and helpers related to it
are in fs.h. fs.h is already far too large and there are very few
places needing the export bits, so split them off into a separate
header.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Neil Brown <neilb@suse.de>
### Diffstat output
./fs/efs/super.c | 1
./fs/exportfs/expfs.c | 1
./fs/ext2/super.c | 1
./fs/ext3/super.c | 1
./fs/ext4/super.c | 1
./fs/fat/inode.c | 1
./fs/gfs2/ops_export.c | 1
./fs/gfs2/ops_export.h | 2
./fs/isofs/isofs.h | 1
./fs/jfs/super.c | 1
./fs/nfsd/export.c | 1
./fs/nfsd/nfsfh.c | 1
./fs/ntfs/namei.c | 1
./fs/ocfs2/export.h | 2
./fs/reiserfs/inode.c | 1
./fs/reiserfs/super.c | 1
./fs/xfs/linux-2.6/xfs_super.h | 2
./include/linux/exportfs.h | 119 +++++++++++++++++++++++++++++++++++++++++
./include/linux/fs.h | 114 ---------------------------------------
./mm/shmem.c | 1
20 files changed, 141 insertions(+), 113 deletions(-)
diff .prev/fs/efs/super.c ./fs/efs/super.c
--- .prev/fs/efs/super.c 2007-05-14 11:14:52.000000000 +1000
+++ ./fs/efs/super.c 2007-05-14 11:15:23.000000000 +1000
@@ -11,6 +11,7 @@
#include <linux/efs_fs.h>
#include <linux/efs_vh.h>
#include <linux/efs_fs_sb.h>
+#include <linux/exportfs.h>
#include <linux/slab.h>
#include <linux/buffer_head.h>
#include <linux/vfs.h>
diff .prev/fs/exportfs/expfs.c ./fs/exportfs/expfs.c
--- .prev/fs/exportfs/expfs.c 2007-05-14 11:14:52.000000000 +1000
+++ ./fs/exportfs/expfs.c 2007-05-14 11:15:23.000000000 +1000
@@ -1,4 +1,5 @@
+#include <linux/exportfs.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/module.h>
diff .prev/fs/ext2/super.c ./fs/ext2/super.c
--- .prev/fs/ext2/super.c 2007-05-14 11:14:52.000000000 +1000
+++ ./fs/ext2/super.c 2007-05-14 11:15:23.000000000 +1000
@@ -25,6 +25,7 @@
#include <linux/parser.h>
#include <linux/random.h>
#include <linux/buffer_head.h>
+#include <linux/exportfs.h>
#include <linux/smp_lock.h>
#include <linux/vfs.h>
#include <linux/seq_file.h>
diff .prev/fs/ext3/super.c ./fs/ext3/super.c
--- .prev/fs/ext3/super.c 2007-05-14 11:14:52.000000000 +1000
+++ ./fs/ext3/super.c 2007-05-14 11:15:23.000000000 +1000
@@ -29,6 +29,7 @@
#include <linux/parser.h>
#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
+#include <linux/exportfs.h>
#include <linux/vfs.h>
#include <linux/random.h>
#include <linux/mount.h>
diff .prev/fs/ext4/super.c ./fs/ext4/super.c
--- .prev/fs/ext4/super.c 2007-05-14 11:14:52.000000000 +1000
+++ ./fs/ext4/super.c 2007-05-14 11:15:23.000000000 +1000
@@ -29,6 +29,7 @@
#include <linux/parser.h>
#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
+#include <linux/exportfs.h>
#include <linux/vfs.h>
#include <linux/random.h>
#include <linux/mount.h>
diff .prev/fs/fat/inode.c ./fs/fat/inode.c
--- .prev/fs/fat/inode.c 2007-05-14 11:14:52.000000000 +1000
+++ ./fs/fat/inode.c 2007-05-14 11:15:23.000000000 +1000
@@ -20,6 +20,7 @@
#include <linux/pagemap.h>
#include <linux/mpage.h>
#include <linux/buffer_head.h>
+#include <linux/exportfs.h>
#include <linux/mount.h>
#include <linux/vfs.h>
#include <linux/parser.h>
diff .prev/fs/gfs2/ops_export.c ./fs/gfs2/ops_export.c
--- .prev/fs/gfs2/ops_export.c 2007-05-14 11:14:52.000000000 +1000
+++ ./fs/gfs2/ops_export.c 2007-05-14 11:15:23.000000000 +1000
@@ -11,6 +11,7 @@
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/buffer_head.h>
+#include <linux/exportfs.h>
#include <linux/gfs2_ondisk.h>
#include <linux/crc32.h>
#include <linux/lm_interface.h>
diff .prev/fs/gfs2/ops_export.h ./fs/gfs2/ops_export.h
--- .prev/fs/gfs2/ops_export.h 2007-05-14 11:14:52.000000000 +1000
+++ ./fs/gfs2/ops_export.h 2007-05-14 11:15:23.000000000 +1000
@@ -10,6 +10,8 @@
#ifndef __OPS_EXPORT_DOT_H__
#define __OPS_EXPORT_DOT_H__
+#include <linux/exportfs.h>
+
#define GFS2_SMALL_FH_SIZE 4
#define GFS2_LARGE_FH_SIZE 10
diff .prev/fs/isofs/isofs.h ./fs/isofs/isofs.h
--- .prev/fs/isofs/isofs.h 2007-05-14 11:14:52.000000000 +1000
+++ ./fs/isofs/isofs.h 2007-05-14 11:15:23.000000000 +1000
@@ -1,5 +1,6 @@
#include <linux/fs.h>
#include <linux/buffer_head.h>
+#include <linux/exportfs.h>
#include <linux/iso_fs.h>
#include <asm/unaligned.h>
diff .prev/fs/jfs/super.c ./fs/jfs/super.c
--- .prev/fs/jfs/super.c 2007-05-14 11:14:52.000000000 +1000
+++ ./fs/jfs/super.c 2007-05-14 11:15:23.000000000 +1000
@@ -27,6 +27,7 @@
#include <linux/kthread.h>
#include <linux/posix_acl.h>
#include <linux/buffer_head.h>
+#include <linux/exportfs.h>
#include <asm/uaccess.h>
#include <linux/seq_file.h>
diff .prev/fs/nfsd/export.c ./fs/nfsd/export.c
--- .prev/fs/nfsd/export.c 2007-05-14 11:14:52.000000000 +1000
+++ ./fs/nfsd/export.c 2007-05-14 11:15:23.000000000 +1000
@@ -26,6 +26,7 @@
#include <linux/mount.h>
#include <linux/hash.h>
#include <linux/module.h>
+#include <linux/exportfs.h>
#include <linux/sunrpc/svc.h>
#include <linux/nfsd/nfsd.h>
diff .prev/fs/nfsd/nfsfh.c ./fs/nfsd/nfsfh.c
--- .prev/fs/nfsd/nfsfh.c 2007-05-14 11:14:52.000000000 +1000
+++ ./fs/nfsd/nfsfh.c 2007-05-14 11:15:23.000000000 +1000
@@ -15,6 +15,7 @@
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/dcache.h>
+#include <linux/exportfs.h>
#include <linux/mount.h>
#include <linux/sunrpc/clnt.h>
diff .prev/fs/ntfs/namei.c ./fs/ntfs/namei.c
--- .prev/fs/ntfs/namei.c 2007-05-14 11:14:52.000000000 +1000
+++ ./fs/ntfs/namei.c 2007-05-14 11:15:23.000000000 +1000
@@ -21,6 +21,7 @@
*/
#include <linux/dcache.h>
+#include <linux/exportfs.h>
#include <linux/security.h>
#include "attrib.h"
diff .prev/fs/ocfs2/export.h ./fs/ocfs2/export.h
--- .prev/fs/ocfs2/export.h 2007-05-14 11:14:52.000000000 +1000
+++ ./fs/ocfs2/export.h 2007-05-14 11:15:23.000000000 +1000
@@ -26,6 +26,8 @@
#ifndef OCFS2_EXPORT_H
#define OCFS2_EXPORT_H
+#include <linux/exportfs.h>
+
extern struct export_operations ocfs2_export_ops;
#endif /* OCFS2_EXPORT_H */
diff .prev/fs/reiserfs/inode.c ./fs/reiserfs/inode.c
--- .prev/fs/reiserfs/inode.c 2007-05-14 11:14:52.000000000 +1000
+++ ./fs/reiserfs/inode.c 2007-05-14 11:15:23.000000000 +1000
@@ -7,6 +7,7 @@
#include <linux/reiserfs_fs.h>
#include <linux/reiserfs_acl.h>
#include <linux/reiserfs_xattr.h>
+#include <linux/exportfs.h>
#include <linux/smp_lock.h>
#include <linux/pagemap.h>
#include <linux/highmem.h>
diff .prev/fs/reiserfs/super.c ./fs/reiserfs/super.c
--- .prev/fs/reiserfs/super.c 2007-05-14 11:14:52.000000000 +1000
+++ ./fs/reiserfs/super.c 2007-05-14 11:15:23.000000000 +1000
@@ -21,6 +21,7 @@
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/buffer_head.h>
+#include <linux/exportfs.h>
#include <linux/vfs.h>
#include <linux/mnt_namespace.h>
#include <linux/mount.h>
diff .prev/fs/xfs/linux-2.6/xfs_super.h ./fs/xfs/linux-2.6/xfs_super.h
--- .prev/fs/xfs/linux-2.6/xfs_super.h 2007-05-14 11:14:52.000000000 +1000
+++ ./fs/xfs/linux-2.6/xfs_super.h 2007-05-14 11:15:23.000000000 +1000
@@ -18,6 +18,8 @@
#ifndef __XFS_SUPER_H__
#define __XFS_SUPER_H__
+#include <linux/exportfs.h>
+
#ifdef CONFIG_XFS_DMAPI
# define vfs_insertdmapi(vfs) vfs_insertops(vfsp, &xfs_dmops)
# define vfs_initdmapi() dmapi_init()
diff .prev/include/linux/exportfs.h ./include/linux/exportfs.h
--- .prev/include/linux/exportfs.h 2007-05-14 11:14:52.000000000 +1000
+++ ./include/linux/exportfs.h 2007-05-14 11:15:23.000000000 +1000
@@ -0,0 +1,119 @@
+#ifndef LINUX_EXPORTFS_H
+#define LINUX_EXPORTFS_H 1
+
+#include <linux/types.h>
+
+struct dentry;
+struct super_block;
+
+
+/**
+ * struct export_operations - for nfsd to communicate with file systems
+ * @decode_fh: decode a file handle fragment and return a &struct dentry
+ * @encode_fh: encode a file handle fragment from a dentry
+ * @get_name: find the name for a given inode in a given directory
+ * @get_parent: find the parent of a given directory
+ * @get_dentry: find a dentry for the inode given a file handle sub-fragment
+ * @find_exported_dentry:
+ * set by the exporting module to a standard helper function.
+ *
+ * Description:
+ * The export_operations structure provides a means for nfsd to communicate
+ * with a particular exported file system - particularly enabling nfsd and
+ * the filesystem to co-operate when dealing with file handles.
+ *
+ * export_operations contains two basic operation for dealing with file
+ * handles, decode_fh() and encode_fh(), and allows for some other
+ * operations to be defined which standard helper routines use to get
+ * specific information from the filesystem.
+ *
+ * nfsd encodes information use to determine which filesystem a filehandle
+ * applies to in the initial part of the file handle. The remainder, termed
+ * a file handle fragment, is controlled completely by the filesystem. The
+ * standard helper routines assume that this fragment will contain one or
+ * two sub-fragments, one which identifies the file, and one which may be
+ * used to identify the (a) directory containing the file.
+ *
+ * In some situations, nfsd needs to get a dentry which is connected into a
+ * specific part of the file tree. To allow for this, it passes the
+ * function acceptable() together with a @context which can be used to see
+ * if the dentry is acceptable. As there can be multiple dentrys for a
+ * given file, the filesystem should check each one for acceptability before
+ * looking for the next. As soon as an acceptable one is found, it should
+ * be returned.
+ *
+ * decode_fh:
+ * @decode_fh is given a &struct super_block (@sb), a file handle fragment
+ * (@fh, @fh_len) and an acceptability testing function (@acceptable,
+ * @context). It should return a &struct dentry which refers to the same
+ * file that the file handle fragment refers to, and which passes the
+ * acceptability test. If it cannot, it should return a %NULL pointer if
+ * the file was found but no acceptable &dentries were available, or a
+ * %ERR_PTR error code indicating why it couldn't be found (e.g. %ENOENT or
+ * %ENOMEM).
+ *
+ * encode_fh:
+ * @encode_fh should store in the file handle fragment @fh (using at most
+ * @max_len bytes) information that can be used by @decode_fh to recover the
+ * file refered to by the &struct dentry @de. If the @connectable flag is
+ * set, the encode_fh() should store sufficient information so that a good
+ * attempt can be made to find not only the file but also it's place in the
+ * filesystem. This typically means storing a reference to de->d_parent in
+ * the filehandle fragment. encode_fh() should return the number of bytes
+ * stored or a negative error code such as %-ENOSPC
+ *
+ * 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
+ * understanding that it is already pointing to a a %NAME_MAX+1 sized
+ * buffer. get_name() should return %0 on success, a negative error code
+ * or error. @get_name will be called without @parent->i_mutex held.
+ *
+ * get_parent:
+ * @get_parent should find the parent directory for the given @child which
+ * is also a directory. In the event that it cannot be found, or storage
+ * space cannot be allocated, a %ERR_PTR should be returned.
+ *
+ * get_dentry:
+ * Given a &super_block (@sb) and a pointer to a file-system specific inode
+ * identifier, possibly an inode number, (@inump) get_dentry() should find
+ * the identified inode and return a dentry for that inode. 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 dentrys by
+ * following the d_alias links. If a new dentry was created using
+ * d_alloc_root, DCACHE_NFSD_DISCONNECTED should be set, and the dentry
+ * should be d_rehash()ed.
+ *
+ * If the inode cannot be found, either a %NULL pointer or an %ERR_PTR code
+ * can be returned. The @inump will be whatever was passed to
+ * nfsd_find_fh_dentry() in either the @obj or @parent parameters.
+ *
+ * Locking rules:
+ * get_parent is called with child->d_inode->i_mutex down
+ * get_name is not (which is possibly inconsistent)
+ */
+
+struct export_operations {
+ struct dentry *(*decode_fh)(struct super_block *sb, __u32 *fh,
+ int fh_len, int fh_type,
+ int (*acceptable)(void *context, struct dentry *de),
+ void *context);
+ int (*encode_fh)(struct dentry *de, __u32 *fh, int *max_len,
+ int connectable);
+ int (*get_name)(struct dentry *parent, char *name,
+ struct dentry *child);
+ struct dentry * (*get_parent)(struct dentry *child);
+ struct dentry * (*get_dentry)(struct super_block *sb, void *inump);
+
+ /* This is set by the exporting module to a standard helper */
+ struct dentry * (*find_exported_dentry)(
+ struct super_block *sb, void *obj, void *parent,
+ int (*acceptable)(void *context, struct dentry *de),
+ void *context);
+};
+
+extern struct dentry *find_exported_dentry(struct super_block *sb, void *obj,
+ void *parent, int (*acceptable)(void *context, struct dentry *de),
+ void *context);
+
+#endif /* LINUX_EXPORTFS_H */
diff .prev/include/linux/fs.h ./include/linux/fs.h
--- .prev/include/linux/fs.h 2007-05-14 11:14:52.000000000 +1000
+++ ./include/linux/fs.h 2007-05-14 11:15:23.000000000 +1000
@@ -294,6 +294,7 @@ extern int dir_notify_enable;
#include <asm/semaphore.h>
#include <asm/byteorder.h>
+struct export_operations;
struct hd_geometry;
struct iovec;
struct nameidata;
@@ -1259,119 +1260,6 @@ static inline void file_accessed(struct
int sync_inode(struct inode *inode, struct writeback_control *wbc);
-/**
- * struct export_operations - for nfsd to communicate with file systems
- * @decode_fh: decode a file handle fragment and return a &struct dentry
- * @encode_fh: encode a file handle fragment from a dentry
- * @get_name: find the name for a given inode in a given directory
- * @get_parent: find the parent of a given directory
- * @get_dentry: find a dentry for the inode given a file handle sub-fragment
- * @find_exported_dentry:
- * set by the exporting module to a standard helper function.
- *
- * Description:
- * The export_operations structure provides a means for nfsd to communicate
- * with a particular exported file system - particularly enabling nfsd and
- * the filesystem to co-operate when dealing with file handles.
- *
- * export_operations contains two basic operation for dealing with file
- * handles, decode_fh() and encode_fh(), and allows for some other
- * operations to be defined which standard helper routines use to get
- * specific information from the filesystem.
- *
- * nfsd encodes information use to determine which filesystem a filehandle
- * applies to in the initial part of the file handle. The remainder, termed
- * a file handle fragment, is controlled completely by the filesystem. The
- * standard helper routines assume that this fragment will contain one or
- * two sub-fragments, one which identifies the file, and one which may be
- * used to identify the (a) directory containing the file.
- *
- * In some situations, nfsd needs to get a dentry which is connected into a
- * specific part of the file tree. To allow for this, it passes the
- * function acceptable() together with a @context which can be used to see
- * if the dentry is acceptable. As there can be multiple dentrys for a
- * given file, the filesystem should check each one for acceptability before
- * looking for the next. As soon as an acceptable one is found, it should
- * be returned.
- *
- * decode_fh:
- * @decode_fh is given a &struct super_block (@sb), a file handle fragment
- * (@fh, @fh_len) and an acceptability testing function (@acceptable,
- * @context). It should return a &struct dentry which refers to the same
- * file that the file handle fragment refers to, and which passes the
- * acceptability test. If it cannot, it should return a %NULL pointer if
- * the file was found but no acceptable &dentries were available, or a
- * %ERR_PTR error code indicating why it couldn't be found (e.g. %ENOENT or
- * %ENOMEM).
- *
- * encode_fh:
- * @encode_fh should store in the file handle fragment @fh (using at most
- * @max_len bytes) information that can be used by @decode_fh to recover the
- * file refered to by the &struct dentry @de. If the @connectable flag is
- * set, the encode_fh() should store sufficient information so that a good
- * attempt can be made to find not only the file but also it's place in the
- * filesystem. This typically means storing a reference to de->d_parent in
- * the filehandle fragment. encode_fh() should return the number of bytes
- * stored or a negative error code such as %-ENOSPC
- *
- * 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
- * understanding that it is already pointing to a a %NAME_MAX+1 sized
- * buffer. get_name() should return %0 on success, a negative error code
- * or error. @get_name will be called without @parent->i_mutex held.
- *
- * get_parent:
- * @get_parent should find the parent directory for the given @child which
- * is also a directory. In the event that it cannot be found, or storage
- * space cannot be allocated, a %ERR_PTR should be returned.
- *
- * get_dentry:
- * Given a &super_block (@sb) and a pointer to a file-system specific inode
- * identifier, possibly an inode number, (@inump) get_dentry() should find
- * the identified inode and return a dentry for that inode. 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 dentrys by
- * following the d_alias links. If a new dentry was created using
- * d_alloc_root, DCACHE_NFSD_DISCONNECTED should be set, and the dentry
- * should be d_rehash()ed.
- *
- * If the inode cannot be found, either a %NULL pointer or an %ERR_PTR code
- * can be returned. The @inump will be whatever was passed to
- * nfsd_find_fh_dentry() in either the @obj or @parent parameters.
- *
- * Locking rules:
- * get_parent is called with child->d_inode->i_mutex down
- * get_name is not (which is possibly inconsistent)
- */
-
-struct export_operations {
- struct dentry *(*decode_fh)(struct super_block *sb, __u32 *fh, int fh_len, int fh_type,
- int (*acceptable)(void *context, struct dentry *de),
- void *context);
- int (*encode_fh)(struct dentry *de, __u32 *fh, int *max_len,
- int connectable);
-
- /* the following are only called from the filesystem itself */
- int (*get_name)(struct dentry *parent, char *name,
- struct dentry *child);
- struct dentry * (*get_parent)(struct dentry *child);
- struct dentry * (*get_dentry)(struct super_block *sb, void *inump);
-
- /* This is set by the exporting module to a standard helper */
- struct dentry * (*find_exported_dentry)(
- struct super_block *sb, void *obj, void *parent,
- int (*acceptable)(void *context, struct dentry *de),
- void *context);
-
-
-};
-
-extern struct dentry *
-find_exported_dentry(struct super_block *sb, void *obj, void *parent,
- int (*acceptable)(void *context, struct dentry *de),
- void *context);
-
struct file_system_type {
const char *name;
int fs_flags;
diff .prev/mm/shmem.c ./mm/shmem.c
--- .prev/mm/shmem.c 2007-05-14 11:14:52.000000000 +1000
+++ ./mm/shmem.c 2007-05-14 11:15:23.000000000 +1000
@@ -27,6 +27,7 @@
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/xattr.h>
+#include <linux/exportfs.h>
#include <linux/generic_acl.h>
#include <linux/mm.h>
#include <linux/mman.h>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 002 of 8] knfsd: exportfs: remove iget abuse
2007-05-15 7:15 [PATCH 000 of 8] knfsd: cleanups for exportfs code NeilBrown
2007-05-15 7:16 ` [PATCH 001 of 8] knfsd: exportfs: add exportfs.h header NeilBrown
@ 2007-05-15 7:16 ` NeilBrown
2007-05-15 12:30 ` Dave Kleikamp
2007-05-15 7:16 ` [PATCH 003 of 8] knfsd: exportfs: add procedural interface for NFSD NeilBrown
` (5 subsequent siblings)
7 siblings, 1 reply; 10+ messages in thread
From: NeilBrown @ 2007-05-15 7:16 UTC (permalink / raw)
To: Andrew Morton
Cc: nfs, linux-kernel, Christoph Hellwig, Christoph Hellwig,
Neil Brown, shaggy
From: Christoph Hellwig <hch@infradead.org>
When the exportfs interface was added the expectation was that
filesystems provide an operation to convert from a file handle
to an inode/dentry, but it kept a backwards compat option that
still calls into iget.
Calling into iget from non-filesystem code is very bad, because
it gives too little information to filesystem, and simply crashes
if the filesystem doesn't implement the ->read_inode routine.
Fortunately there are only two filesystems left using this fallback:
efs and jfs. This patch moves a copy of export_iget to each
of those to implement the get_dentry method.
While this is a temporary increase of lines of code in the kernel
it allows for a much cleaner interface and important code restructuring
in later patches.
Cc: shaggy@austin.ibm.com
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Neil Brown <neilb@suse.de>
### Diffstat output
./fs/efs/namei.c | 32 ++++++++++++++++++++++++++
./fs/efs/super.c | 1
./fs/exportfs/expfs.c | 56 ++---------------------------------------------
./fs/jfs/jfs_inode.h | 2 -
./fs/jfs/namei.c | 32 ++++++++++++++++++++++++++
./fs/jfs/super.c | 1
./include/linux/efs_fs.h | 1
7 files changed, 71 insertions(+), 54 deletions(-)
diff .prev/fs/efs/namei.c ./fs/efs/namei.c
--- .prev/fs/efs/namei.c 2007-05-14 11:14:52.000000000 +1000
+++ ./fs/efs/namei.c 2007-05-14 11:15:29.000000000 +1000
@@ -75,6 +75,38 @@ struct dentry *efs_lookup(struct inode *
return NULL;
}
+struct dentry *efs_get_dentry(struct super_block *sb, void *vobjp)
+{
+ __u32 *objp = vobjp;
+ unsigned long ino = objp[0];
+ __u32 generation = objp[1];
+ struct inode *inode;
+ struct dentry *result;
+
+ if (ino == 0)
+ return ERR_PTR(-ESTALE);
+ inode = iget(sb, ino);
+ if (inode == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ if (is_bad_inode(inode) ||
+ (generation && inode->i_generation != generation)) {
+ result = ERR_PTR(-ESTALE);
+ goto out_iput;
+ }
+
+ result = d_alloc_anon(inode);
+ if (!result) {
+ result = ERR_PTR(-ENOMEM);
+ goto out_iput;
+ }
+ return result;
+
+ out_iput:
+ iput(inode);
+ return result;
+}
+
struct dentry *efs_get_parent(struct dentry *child)
{
struct dentry *parent;
diff .prev/fs/efs/super.c ./fs/efs/super.c
--- .prev/fs/efs/super.c 2007-05-14 11:15:23.000000000 +1000
+++ ./fs/efs/super.c 2007-05-14 11:15:29.000000000 +1000
@@ -115,6 +115,7 @@ static const struct super_operations efs
};
static struct export_operations efs_export_ops = {
+ .get_dentry = efs_get_dentry,
.get_parent = efs_get_parent,
};
diff .prev/fs/exportfs/expfs.c ./fs/exportfs/expfs.c
--- .prev/fs/exportfs/expfs.c 2007-05-14 11:15:23.000000000 +1000
+++ ./fs/exportfs/expfs.c 2007-05-14 11:15:29.000000000 +1000
@@ -391,61 +391,11 @@ out:
return error;
}
-
-static struct dentry *export_iget(struct super_block *sb, unsigned long ino, __u32 generation)
+static struct dentry *get_dentry(struct super_block *sb, void *vobjp)
{
-
- /* iget isn't really right if the inode is currently unallocated!!
- * This should really all be done inside each filesystem
- *
- * ext2fs' read_inode has been strengthed to return a bad_inode if
- * the inode had been deleted.
- *
- * Currently we don't know the generation for parent directory, so
- * a generation of 0 means "accept any"
- */
- struct inode *inode;
- struct dentry *result;
- if (ino == 0)
- return ERR_PTR(-ESTALE);
- inode = iget(sb, ino);
- if (inode == NULL)
- return ERR_PTR(-ENOMEM);
- if (is_bad_inode(inode)
- || (generation && inode->i_generation != generation)
- ) {
- /* we didn't find the right inode.. */
- dprintk("fh_verify: Inode %lu, Bad count: %d %d or version %u %u\n",
- inode->i_ino,
- inode->i_nlink, atomic_read(&inode->i_count),
- inode->i_generation,
- generation);
-
- iput(inode);
- return ERR_PTR(-ESTALE);
- }
- /* now to find a dentry.
- * If possible, get a well-connected one
- */
- result = d_alloc_anon(inode);
- if (!result) {
- iput(inode);
- return ERR_PTR(-ENOMEM);
- }
- return result;
+ return ERR_PTR(-ESTALE);
}
-
-static struct dentry *get_object(struct super_block *sb, void *vobjp)
-{
- __u32 *objp = vobjp;
- unsigned long ino = objp[0];
- __u32 generation = objp[1];
-
- return export_iget(sb, ino, generation);
-}
-
-
/**
* export_encode_fh - default export_operations->encode_fh function
* @dentry: the dentry to encode
@@ -524,7 +474,7 @@ struct export_operations export_op_defau
.get_name = get_name,
.get_parent = get_parent,
- .get_dentry = get_object,
+ .get_dentry = get_dentry,
};
EXPORT_SYMBOL(export_op_default);
diff .prev/fs/jfs/jfs_inode.h ./fs/jfs/jfs_inode.h
--- .prev/fs/jfs/jfs_inode.h 2007-05-14 11:14:52.000000000 +1000
+++ ./fs/jfs/jfs_inode.h 2007-05-14 11:15:29.000000000 +1000
@@ -31,7 +31,7 @@ extern void jfs_truncate(struct inode *)
extern void jfs_truncate_nolock(struct inode *, loff_t);
extern void jfs_free_zero_link(struct inode *);
extern struct dentry *jfs_get_parent(struct dentry *dentry);
-extern void jfs_get_inode_flags(struct jfs_inode_info *);
+extern struct dentry *jfs_get_dentry(struct super_block *sb, void *vobjp);
extern void jfs_set_inode_flags(struct inode *);
extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
diff .prev/fs/jfs/namei.c ./fs/jfs/namei.c
--- .prev/fs/jfs/namei.c 2007-05-14 11:14:52.000000000 +1000
+++ ./fs/jfs/namei.c 2007-05-14 11:15:29.000000000 +1000
@@ -1477,6 +1477,38 @@ static struct dentry *jfs_lookup(struct
return dentry;
}
+struct dentry *jfs_get_dentry(struct super_block *sb, void *vobjp)
+{
+ __u32 *objp = vobjp;
+ unsigned long ino = objp[0];
+ __u32 generation = objp[1];
+ struct inode *inode;
+ struct dentry *result;
+
+ if (ino == 0)
+ return ERR_PTR(-ESTALE);
+ inode = iget(sb, ino);
+ if (inode == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ if (is_bad_inode(inode) ||
+ (generation && inode->i_generation != generation)) {
+ result = ERR_PTR(-ESTALE);
+ goto out_iput;
+ }
+
+ result = d_alloc_anon(inode);
+ if (!result) {
+ result = ERR_PTR(-ENOMEM);
+ goto out_iput;
+ }
+ return result;
+
+ out_iput:
+ iput(inode);
+ return result;
+}
+
struct dentry *jfs_get_parent(struct dentry *dentry)
{
struct super_block *sb = dentry->d_inode->i_sb;
diff .prev/fs/jfs/super.c ./fs/jfs/super.c
--- .prev/fs/jfs/super.c 2007-05-14 11:15:23.000000000 +1000
+++ ./fs/jfs/super.c 2007-05-14 11:15:29.000000000 +1000
@@ -738,6 +738,7 @@ static const struct super_operations jfs
};
static struct export_operations jfs_export_operations = {
+ .get_dentry = jfs_get_dentry,
.get_parent = jfs_get_parent,
};
diff .prev/include/linux/efs_fs.h ./include/linux/efs_fs.h
--- .prev/include/linux/efs_fs.h 2007-05-14 11:14:52.000000000 +1000
+++ ./include/linux/efs_fs.h 2007-05-14 11:15:29.000000000 +1000
@@ -45,6 +45,7 @@ extern efs_block_t efs_map_block(struct
extern int efs_get_block(struct inode *, sector_t, struct buffer_head *, int);
extern struct dentry *efs_lookup(struct inode *, struct dentry *, struct nameidata *);
+extern struct dentry *efs_get_dentry(struct super_block *sb, void *vobjp);
extern struct dentry *efs_get_parent(struct dentry *);
extern int efs_bmap(struct inode *, int);
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 003 of 8] knfsd: exportfs: add procedural interface for NFSD
2007-05-15 7:15 [PATCH 000 of 8] knfsd: cleanups for exportfs code NeilBrown
2007-05-15 7:16 ` [PATCH 001 of 8] knfsd: exportfs: add exportfs.h header NeilBrown
2007-05-15 7:16 ` [PATCH 002 of 8] knfsd: exportfs: remove iget abuse NeilBrown
@ 2007-05-15 7:16 ` NeilBrown
2007-05-15 7:16 ` [PATCH 004 of 8] knfsd: exportfs: remove CALL macro NeilBrown
` (4 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: NeilBrown @ 2007-05-15 7:16 UTC (permalink / raw)
To: Andrew Morton
Cc: nfs, linux-kernel, Christoph Hellwig, Christoph Hellwig,
Neil Brown
From: Christoph Hellwig <hch@infradead.org>
Currently NFSD calls directly into filesystems through the
export_operations structure. I plan to change this interface
in various ways in later patches, and want to avoid the export
of the default operations to NFSD, so this patch adds two
simple exportfs_encode_fh/exportfs_decode_fh helpers for NFSD
to call instead of poking into exportfs guts.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Neil Brown <neilb@suse.de>
### Diffstat output
./fs/exportfs/expfs.c | 22 +++++++++++++++++++++-
./fs/nfsd/nfsfh.c | 18 +++++-------------
./include/linux/exportfs.h | 7 +++++++
3 files changed, 33 insertions(+), 14 deletions(-)
diff .prev/fs/exportfs/expfs.c ./fs/exportfs/expfs.c
--- .prev/fs/exportfs/expfs.c 2007-05-14 11:15:29.000000000 +1000
+++ ./fs/exportfs/expfs.c 2007-05-14 11:15:31.000000000 +1000
@@ -3,6 +3,7 @@
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/module.h>
+#include <linux/mount.h>
#include <linux/namei.h>
struct export_operations export_op_default;
@@ -468,6 +469,26 @@ static struct dentry *export_decode_fh(s
acceptable, context);
}
+int exportfs_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len,
+ int connectable)
+{
+ struct export_operations *nop = dentry->d_sb->s_export_op;
+
+ return CALL(nop, encode_fh)(dentry, fh, max_len, connectable);
+}
+EXPORT_SYMBOL_GPL(exportfs_encode_fh);
+
+struct dentry *exportfs_decode_fh(struct vfsmount *mnt, __u32 *fh, int fh_len,
+ int fileid_type, int (*acceptable)(void *, struct dentry *),
+ void *context)
+{
+ struct export_operations *nop = mnt->mnt_sb->s_export_op;
+
+ return CALL(nop, decode_fh)(mnt->mnt_sb, fh, fh_len, fileid_type,
+ acceptable, context);
+}
+EXPORT_SYMBOL_GPL(exportfs_decode_fh);
+
struct export_operations export_op_default = {
.decode_fh = export_decode_fh,
.encode_fh = export_encode_fh,
@@ -477,7 +498,6 @@ struct export_operations export_op_defau
.get_dentry = get_dentry,
};
-EXPORT_SYMBOL(export_op_default);
EXPORT_SYMBOL(find_exported_dentry);
MODULE_LICENSE("GPL");
diff .prev/fs/nfsd/nfsfh.c ./fs/nfsd/nfsfh.c
--- .prev/fs/nfsd/nfsfh.c 2007-05-14 11:15:23.000000000 +1000
+++ ./fs/nfsd/nfsfh.c 2007-05-14 11:15:31.000000000 +1000
@@ -28,10 +28,6 @@
static int nfsd_nr_verified;
static int nfsd_nr_put;
-extern struct export_operations export_op_default;
-
-#define CALL(ops,fun) ((ops->fun)?(ops->fun):export_op_default.fun)
-
/*
* our acceptability function.
* if NOSUBTREECHECK, accept anything
@@ -212,11 +208,9 @@ fh_verify(struct svc_rqst *rqstp, struct
if (fileid_type == 0)
dentry = dget(exp->ex_dentry);
else {
- struct export_operations *nop = exp->ex_mnt->mnt_sb->s_export_op;
- dentry = CALL(nop,decode_fh)(exp->ex_mnt->mnt_sb,
- datap, data_left,
- fileid_type,
- nfsd_acceptable, exp);
+ dentry = exportfs_decode_fh(exp->ex_mnt, datap,
+ data_left, fileid_type,
+ nfsd_acceptable, exp);
}
if (dentry == NULL)
goto out;
@@ -287,15 +281,13 @@ out:
static inline int _fh_update(struct dentry *dentry, struct svc_export *exp,
__u32 *datap, int *maxsize)
{
- struct export_operations *nop = exp->ex_mnt->mnt_sb->s_export_op;
-
if (dentry == exp->ex_dentry) {
*maxsize = 0;
return 0;
}
- return CALL(nop,encode_fh)(dentry, datap, maxsize,
- !(exp->ex_flags&NFSEXP_NOSUBTREECHECK));
+ return exportfs_encode_fh(dentry, datap, maxsize,
+ !(exp->ex_flags & NFSEXP_NOSUBTREECHECK));
}
/*
diff .prev/include/linux/exportfs.h ./include/linux/exportfs.h
--- .prev/include/linux/exportfs.h 2007-05-14 11:15:23.000000000 +1000
+++ ./include/linux/exportfs.h 2007-05-14 11:15:31.000000000 +1000
@@ -5,6 +5,7 @@
struct dentry;
struct super_block;
+struct vfsmount;
/**
@@ -116,4 +117,10 @@ extern struct dentry *find_exported_dent
void *parent, int (*acceptable)(void *context, struct dentry *de),
void *context);
+extern int exportfs_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len,
+ int connectable);
+extern struct dentry *exportfs_decode_fh(struct vfsmount *mnt, __u32 *fh,
+ int fh_len, int fileid_type, int (*acceptable)(void *, struct dentry *),
+ void *context);
+
#endif /* LINUX_EXPORTFS_H */
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 004 of 8] knfsd: exportfs: remove CALL macro
2007-05-15 7:15 [PATCH 000 of 8] knfsd: cleanups for exportfs code NeilBrown
` (2 preceding siblings ...)
2007-05-15 7:16 ` [PATCH 003 of 8] knfsd: exportfs: add procedural interface for NFSD NeilBrown
@ 2007-05-15 7:16 ` NeilBrown
2007-05-15 7:16 ` [PATCH 005 of 8] knfsd: exportfs: untangle ISDIR logic in find_exported_dentry NeilBrown
` (3 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: NeilBrown @ 2007-05-15 7:16 UTC (permalink / raw)
To: Andrew Morton
Cc: nfs, linux-kernel, Christoph Hellwig, Christoph Hellwig,
Neil Brown
From: Christoph Hellwig <hch@infradead.org>
Currently exportfs uses a way to call methods very differently from
the rest of the kernel. This patch changes it to the standard conventions
for method calls.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Neil Brown <neilb@suse.de>
### Diffstat output
./fs/exportfs/expfs.c | 128 ++++++++++++++++++++++++++++----------------------
1 file changed, 72 insertions(+), 56 deletions(-)
diff .prev/fs/exportfs/expfs.c ./fs/exportfs/expfs.c
--- .prev/fs/exportfs/expfs.c 2007-05-14 11:15:31.000000000 +1000
+++ ./fs/exportfs/expfs.c 2007-05-14 11:15:34.000000000 +1000
@@ -6,11 +6,36 @@
#include <linux/mount.h>
#include <linux/namei.h>
-struct export_operations export_op_default;
+#define dprintk(fmt, args...) do{}while(0)
-#define CALL(ops,fun) ((ops->fun)?(ops->fun):export_op_default.fun)
-#define dprintk(fmt, args...) do{}while(0)
+static int get_name(struct dentry *dentry, char *name,
+ struct dentry *child);
+
+
+static struct dentry *exportfs_get_dentry(struct super_block *sb, void *obj)
+{
+ struct dentry *result = ERR_PTR(-ESTALE);
+
+ if (sb->s_export_op->get_dentry) {
+ result = sb->s_export_op->get_dentry(sb, obj);
+ if (!result)
+ result = ERR_PTR(-ESTALE);
+ }
+
+ return result;
+}
+
+static int exportfs_get_name(struct dentry *dir, char *name,
+ struct dentry *child)
+{
+ struct export_operations *nop = dir->d_sb->s_export_op;
+
+ if (nop->get_name)
+ return nop->get_name(dir, name, child);
+ else
+ return get_name(dir, name, child);
+}
static struct dentry *
find_acceptable_alias(struct dentry *result,
@@ -78,7 +103,7 @@ find_exported_dentry(struct super_block
{
struct dentry *result = NULL;
struct dentry *target_dir;
- int err;
+ int err = -ESTALE;
struct export_operations *nops = sb->s_export_op;
struct dentry *alias;
int noprogress;
@@ -87,14 +112,10 @@ find_exported_dentry(struct super_block
/*
* Attempt to find the inode.
*/
- result = CALL(sb->s_export_op,get_dentry)(sb,obj);
- err = -ESTALE;
- if (result == NULL)
- goto err_out;
- if (IS_ERR(result)) {
- err = PTR_ERR(result);
- goto err_out;
- }
+ result = exportfs_get_dentry(sb, obj);
+ if (IS_ERR(result))
+ return result;
+
if (S_ISDIR(result->d_inode->i_mode) &&
(result->d_flags & DCACHE_DISCONNECTED)) {
/* it is an unconnected directory, we must connect it */
@@ -122,11 +143,11 @@ find_exported_dentry(struct super_block
if (parent == NULL)
goto err_result;
- target_dir = CALL(sb->s_export_op,get_dentry)(sb,parent);
- if (IS_ERR(target_dir))
+ target_dir = exportfs_get_dentry(sb,parent);
+ if (IS_ERR(target_dir)) {
err = PTR_ERR(target_dir);
- if (target_dir == NULL || IS_ERR(target_dir))
goto err_result;
+ }
}
/*
* Now we need to make sure that target_dir is properly connected.
@@ -177,18 +198,27 @@ find_exported_dentry(struct super_block
spin_unlock(&pd->d_lock);
noprogress = 0;
} else {
- /* we have hit the top of a disconnected path. Try
- * to find parent and connect
- * note: racing with some other process renaming a
- * directory isn't much of a problem here. If someone
- * renames the directory, it will end up properly
- * connected, which is what we want
+ /*
+ * We have hit the top of a disconnected path, try to
+ * find parent and connect.
+ *
+ * Racing with some other process renaming a directory
+ * isn't much of a problem here. If someone renames
+ * the directory, it will end up properly connected,
+ * which is what we want
+ *
+ * Getting the parent can't be supported generically,
+ * the locking is too icky.
+ *
+ * Instead we just return EACCES. If server reboots
+ * or inodes get flushed, you lose
*/
- struct dentry *ppd;
+ struct dentry *ppd = ERR_PTR(-EACCES);
struct dentry *npd;
mutex_lock(&pd->d_inode->i_mutex);
- ppd = CALL(nops,get_parent)(pd);
+ if (nops->get_parent)
+ ppd = nops->get_parent(pd);
mutex_unlock(&pd->d_inode->i_mutex);
if (IS_ERR(ppd)) {
@@ -199,7 +229,7 @@ find_exported_dentry(struct super_block
break;
}
dprintk("find_exported_dentry: find name of %lu in %lu\n", pd->d_inode->i_ino, ppd->d_inode->i_ino);
- err = CALL(nops,get_name)(ppd, nbuf, pd);
+ err = exportfs_get_name(ppd, nbuf, pd);
if (err) {
dput(ppd);
dput(pd);
@@ -250,7 +280,7 @@ find_exported_dentry(struct super_block
/* if we weren't after a directory, have one more step to go */
if (result != target_dir) {
struct dentry *nresult;
- err = CALL(nops,get_name)(target_dir, nbuf, result);
+ err = exportfs_get_name(target_dir, nbuf, result);
if (!err) {
mutex_lock(&target_dir->d_inode->i_mutex);
nresult = lookup_one_len(nbuf, target_dir, strlen(nbuf));
@@ -286,23 +316,9 @@ find_exported_dentry(struct super_block
dput(target_dir);
err_result:
dput(result);
- err_out:
return ERR_PTR(err);
}
-
-
-static struct dentry *get_parent(struct dentry *child)
-{
- /* get_parent cannot be supported generically, the locking
- * is too icky.
- * instead, we just return EACCES. If server reboots or inodes
- * get flushed, you lose
- */
- return ERR_PTR(-EACCES);
-}
-
-
struct getdents_callback {
char *name; /* name that was found. It already points to a
buffer NAME_MAX+1 is size */
@@ -392,11 +408,6 @@ out:
return error;
}
-static struct dentry *get_dentry(struct super_block *sb, void *vobjp)
-{
- return ERR_PTR(-ESTALE);
-}
-
/**
* export_encode_fh - default export_operations->encode_fh function
* @dentry: the dentry to encode
@@ -472,9 +483,15 @@ static struct dentry *export_decode_fh(s
int exportfs_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len,
int connectable)
{
- struct export_operations *nop = dentry->d_sb->s_export_op;
+ struct export_operations *nop = dentry->d_sb->s_export_op;
+ int error;
+
+ if (nop->encode_fh)
+ error = nop->encode_fh(dentry, fh, max_len, connectable);
+ else
+ error = export_encode_fh(dentry, fh, max_len, connectable);
- return CALL(nop, encode_fh)(dentry, fh, max_len, connectable);
+ return error;
}
EXPORT_SYMBOL_GPL(exportfs_encode_fh);
@@ -483,21 +500,20 @@ struct dentry *exportfs_decode_fh(struct
void *context)
{
struct export_operations *nop = mnt->mnt_sb->s_export_op;
+ struct dentry *result;
- return CALL(nop, decode_fh)(mnt->mnt_sb, fh, fh_len, fileid_type,
+ if (nop->decode_fh) {
+ result = nop->decode_fh(mnt->mnt_sb, fh, fh_len, fileid_type,
+ acceptable, context);
+ } else {
+ result = export_decode_fh(mnt->mnt_sb, fh, fh_len, fileid_type,
acceptable, context);
+ }
+
+ return result;
}
EXPORT_SYMBOL_GPL(exportfs_decode_fh);
-struct export_operations export_op_default = {
- .decode_fh = export_decode_fh,
- .encode_fh = export_encode_fh,
-
- .get_name = get_name,
- .get_parent = get_parent,
- .get_dentry = get_dentry,
-};
-
EXPORT_SYMBOL(find_exported_dentry);
MODULE_LICENSE("GPL");
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 005 of 8] knfsd: exportfs: untangle ISDIR logic in find_exported_dentry
2007-05-15 7:15 [PATCH 000 of 8] knfsd: cleanups for exportfs code NeilBrown
` (3 preceding siblings ...)
2007-05-15 7:16 ` [PATCH 004 of 8] knfsd: exportfs: remove CALL macro NeilBrown
@ 2007-05-15 7:16 ` NeilBrown
2007-05-15 7:16 ` [PATCH 006 of 8] knfsd: exportfs: move acceptable check into find_acceptable_alias NeilBrown
` (2 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: NeilBrown @ 2007-05-15 7:16 UTC (permalink / raw)
To: Andrew Morton
Cc: nfs, linux-kernel, Christoph Hellwig, Christoph Hellwig,
Neil Brown
From: Christoph Hellwig <hch@infradead.org>
Rework some logic in find_exported_dentry so that we only have a single
S_ISDIR check and logic that makes clear to the reader what we're really
doing here.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Neil Brown <neilb@suse.de>
### Diffstat output
./fs/exportfs/expfs.c | 26 ++++++++++----------------
1 file changed, 10 insertions(+), 16 deletions(-)
diff .prev/fs/exportfs/expfs.c ./fs/exportfs/expfs.c
--- .prev/fs/exportfs/expfs.c 2007-05-14 11:15:34.000000000 +1000
+++ ./fs/exportfs/expfs.c 2007-05-14 11:15:37.000000000 +1000
@@ -116,30 +116,23 @@ find_exported_dentry(struct super_block
if (IS_ERR(result))
return result;
- if (S_ISDIR(result->d_inode->i_mode) &&
- (result->d_flags & DCACHE_DISCONNECTED)) {
- /* it is an unconnected directory, we must connect it */
- ;
- } else {
- if (acceptable(context, result))
- return result;
- if (S_ISDIR(result->d_inode->i_mode)) {
+ if (S_ISDIR(result->d_inode->i_mode)) {
+ if (!(result->d_flags & DCACHE_DISCONNECTED)) {
+ if (acceptable(context, result))
+ return result;
err = -EACCES;
goto err_result;
}
+ target_dir = dget(result);
+ } else {
+ if (acceptable(context, result))
+ return result;
+
alias = find_acceptable_alias(result, acceptable, context);
if (alias)
return alias;
- }
- /* It's a directory, or we are required to confirm the file's
- * location in the tree based on the parent information
- */
- dprintk("find_exported_dentry: need to look harder for %s/%d\n",sb->s_id,*(int*)obj);
- if (S_ISDIR(result->d_inode->i_mode))
- target_dir = dget(result);
- else {
if (parent == NULL)
goto err_result;
@@ -149,6 +142,7 @@ find_exported_dentry(struct super_block
goto err_result;
}
}
+
/*
* Now we need to make sure that target_dir is properly connected.
* It may already be, as the flag isn't always updated when connection
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 006 of 8] knfsd: exportfs: move acceptable check into find_acceptable_alias
2007-05-15 7:15 [PATCH 000 of 8] knfsd: cleanups for exportfs code NeilBrown
` (4 preceding siblings ...)
2007-05-15 7:16 ` [PATCH 005 of 8] knfsd: exportfs: untangle ISDIR logic in find_exported_dentry NeilBrown
@ 2007-05-15 7:16 ` NeilBrown
2007-05-15 7:16 ` [PATCH 007 of 8] knfsd: exportfs: add find_disconnected_root helper NeilBrown
2007-05-15 7:16 ` [PATCH 008 of 8] knfsd: exportfs: split out reconnecting a dentry from find_exported_dentry NeilBrown
7 siblings, 0 replies; 10+ messages in thread
From: NeilBrown @ 2007-05-15 7:16 UTC (permalink / raw)
To: Andrew Morton
Cc: nfs, linux-kernel, Christoph Hellwig, Christoph Hellwig,
Neil Brown
From: Christoph Hellwig <hch@infradead.org>
All callers of find_acceptable_alias check if the current dentry
is acceptable before looking for other acceptable aliases using
find_acceptable_alias. Move the check into find_acceptable_alias
to make the code a little more dense and add a comment to
find_acceptable_alias that documents its intent.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Neil Brown <neilb@suse.de>
### Diffstat output
./fs/exportfs/expfs.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff .prev/fs/exportfs/expfs.c ./fs/exportfs/expfs.c
--- .prev/fs/exportfs/expfs.c 2007-05-14 11:15:37.000000000 +1000
+++ ./fs/exportfs/expfs.c 2007-05-14 11:15:46.000000000 +1000
@@ -37,6 +37,9 @@ static int exportfs_get_name(struct dent
return get_name(dir, name, child);
}
+/*
+ * Check if the dentry or any of it's aliases is acceptable.
+ */
static struct dentry *
find_acceptable_alias(struct dentry *result,
int (*acceptable)(void *context, struct dentry *dentry),
@@ -44,6 +47,9 @@ find_acceptable_alias(struct dentry *res
{
struct dentry *dentry, *toput = NULL;
+ if (acceptable(context, result))
+ return result;
+
spin_lock(&dcache_lock);
list_for_each_entry(dentry, &result->d_inode->i_dentry, d_alias) {
dget_locked(dentry);
@@ -126,9 +132,6 @@ find_exported_dentry(struct super_block
target_dir = dget(result);
} else {
- if (acceptable(context, result))
- return result;
-
alias = find_acceptable_alias(result, acceptable, context);
if (alias)
return alias;
@@ -289,9 +292,6 @@ find_exported_dentry(struct super_block
}
}
dput(target_dir);
- /* now result is properly connected, it is our best bet */
- if (acceptable(context, result))
- return result;
alias = find_acceptable_alias(result, acceptable, context);
if (alias)
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 007 of 8] knfsd: exportfs: add find_disconnected_root helper
2007-05-15 7:15 [PATCH 000 of 8] knfsd: cleanups for exportfs code NeilBrown
` (5 preceding siblings ...)
2007-05-15 7:16 ` [PATCH 006 of 8] knfsd: exportfs: move acceptable check into find_acceptable_alias NeilBrown
@ 2007-05-15 7:16 ` NeilBrown
2007-05-15 7:16 ` [PATCH 008 of 8] knfsd: exportfs: split out reconnecting a dentry from find_exported_dentry NeilBrown
7 siblings, 0 replies; 10+ messages in thread
From: NeilBrown @ 2007-05-15 7:16 UTC (permalink / raw)
To: Andrew Morton
Cc: nfs, linux-kernel, Christoph Hellwig, Christoph Hellwig,
Neil Brown
From: Christoph Hellwig <hch@infradead.org>
Break the loop that finds the root of a disconnected subtree
into a helper of its own to make reading easier and
document the intent.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Neil Brown <neilb@suse.de>
### Diffstat output
./fs/exportfs/expfs.c | 39 +++++++++++++++++++++++----------------
1 file changed, 23 insertions(+), 16 deletions(-)
diff .prev/fs/exportfs/expfs.c ./fs/exportfs/expfs.c
--- .prev/fs/exportfs/expfs.c 2007-05-14 11:15:46.000000000 +1000
+++ ./fs/exportfs/expfs.c 2007-05-14 11:15:51.000000000 +1000
@@ -70,6 +70,27 @@ find_acceptable_alias(struct dentry *res
return NULL;
}
+/*
+ * Find root of a disconnected subtree and return a reference to it.
+ */
+static struct dentry *
+find_disconnected_root(struct dentry *dentry)
+{
+ dget(dentry);
+ spin_lock(&dentry->d_lock);
+ while (!IS_ROOT(dentry) &&
+ (dentry->d_parent->d_flags & DCACHE_DISCONNECTED)) {
+ struct dentry *parent = dentry->d_parent;
+ dget(parent);
+ spin_unlock(&dentry->d_lock);
+ dput(dentry);
+ dentry = parent;
+ spin_lock(&dentry->d_lock);
+ }
+ spin_unlock(&dentry->d_lock);
+ return dentry;
+}
+
/**
* find_exported_dentry - helper routine to implement export_operations->decode_fh
* @sb: The &super_block identifying the filesystem
@@ -164,23 +185,9 @@ find_exported_dentry(struct super_block
* the noprogress counter. If we go through the loop 10 times (2 is
* probably enough) without getting anywhere, we just give up
*/
- noprogress= 0;
+ noprogress = 0;
while (target_dir->d_flags & DCACHE_DISCONNECTED && noprogress++ < 10) {
- struct dentry *pd = target_dir;
-
- dget(pd);
- spin_lock(&pd->d_lock);
- while (!IS_ROOT(pd) &&
- (pd->d_parent->d_flags&DCACHE_DISCONNECTED)) {
- struct dentry *parent = pd->d_parent;
-
- dget(parent);
- spin_unlock(&pd->d_lock);
- dput(pd);
- pd = parent;
- spin_lock(&pd->d_lock);
- }
- spin_unlock(&pd->d_lock);
+ struct dentry *pd = find_disconnected_root(target_dir);
if (!IS_ROOT(pd)) {
/* must have found a connected parent - great */
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 008 of 8] knfsd: exportfs: split out reconnecting a dentry from find_exported_dentry.
2007-05-15 7:15 [PATCH 000 of 8] knfsd: cleanups for exportfs code NeilBrown
` (6 preceding siblings ...)
2007-05-15 7:16 ` [PATCH 007 of 8] knfsd: exportfs: add find_disconnected_root helper NeilBrown
@ 2007-05-15 7:16 ` NeilBrown
7 siblings, 0 replies; 10+ messages in thread
From: NeilBrown @ 2007-05-15 7:16 UTC (permalink / raw)
To: Andrew Morton
Cc: nfs, linux-kernel, Christoph Hellwig, Christoph Hellwig,
Neil Brown
From: Christoph Hellwig <hch@infradead.org>
There's a clear subfunctionality of reconnecting a given dentry to
the main dentry tree in find_exported_dentry, that can be called
both for the dentry we're looking for or it's parent directory.
This patch splits the subfunctionality out into a separate helper to
make the code more readable and document it's intent. As a nice
side-optimization we can avoid getting a superfluous dentry reference
count in the case we need to reconnect a directory on it's own.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Neil Brown <neilb@suse.de>
### Diffstat output
./fs/exportfs/expfs.c | 213 ++++++++++++++++++++++++++------------------------
1 file changed, 113 insertions(+), 100 deletions(-)
diff .prev/fs/exportfs/expfs.c ./fs/exportfs/expfs.c
--- .prev/fs/exportfs/expfs.c 2007-05-14 11:15:51.000000000 +1000
+++ ./fs/exportfs/expfs.c 2007-05-14 11:15:54.000000000 +1000
@@ -91,101 +91,27 @@ find_disconnected_root(struct dentry *de
return dentry;
}
-/**
- * find_exported_dentry - helper routine to implement export_operations->decode_fh
- * @sb: The &super_block identifying the filesystem
- * @obj: An opaque identifier of the object to be found - passed to
- * get_inode
- * @parent: An optional opqaue identifier of the parent of the object.
- * @acceptable: A function used to test possible &dentries to see if they are
- * acceptable
- * @context: A parameter to @acceptable so that it knows on what basis to
- * judge.
- *
- * find_exported_dentry is the central helper routine to enable file systems
- * to provide the decode_fh() export_operation. It's main task is to take
- * an &inode, find or create an appropriate &dentry structure, and possibly
- * splice this into the dcache in the correct place.
- *
- * The decode_fh() operation provided by the filesystem should call
- * find_exported_dentry() with the same parameters that it received except
- * that instead of the file handle fragment, pointers to opaque identifiers
- * for the object and optionally its parent are passed. The default decode_fh
- * routine passes one pointer to the start of the filehandle fragment, and
- * one 8 bytes into the fragment. It is expected that most filesystems will
- * take this approach, though the offset to the parent identifier may well be
- * different.
+
+/*
+ * Make sure target_dir is fully connected to the dentry tree.
*
- * find_exported_dentry() will call get_dentry to get an dentry pointer from
- * the file system. If any &dentry in the d_alias list is acceptable, it will
- * be returned. Otherwise find_exported_dentry() will attempt to splice a new
- * &dentry into the dcache using get_name() and get_parent() to find the
- * appropriate place.
+ * It may already be, as the flag isn't always updated when connection happens.
*/
-
-struct dentry *
-find_exported_dentry(struct super_block *sb, void *obj, void *parent,
- int (*acceptable)(void *context, struct dentry *de),
- void *context)
+static int
+reconnect_path(struct super_block *sb, struct dentry *target_dir)
{
- struct dentry *result = NULL;
- struct dentry *target_dir;
- int err = -ESTALE;
- struct export_operations *nops = sb->s_export_op;
- struct dentry *alias;
- int noprogress;
char nbuf[NAME_MAX+1];
+ int noprogress = 0;
+ int err = -ESTALE;
/*
- * Attempt to find the inode.
- */
- result = exportfs_get_dentry(sb, obj);
- if (IS_ERR(result))
- return result;
-
- if (S_ISDIR(result->d_inode->i_mode)) {
- if (!(result->d_flags & DCACHE_DISCONNECTED)) {
- if (acceptable(context, result))
- return result;
- err = -EACCES;
- goto err_result;
- }
-
- target_dir = dget(result);
- } else {
- alias = find_acceptable_alias(result, acceptable, context);
- if (alias)
- return alias;
-
- if (parent == NULL)
- goto err_result;
-
- target_dir = exportfs_get_dentry(sb,parent);
- if (IS_ERR(target_dir)) {
- err = PTR_ERR(target_dir);
- goto err_result;
- }
- }
-
- /*
- * Now we need to make sure that target_dir is properly connected.
- * It may already be, as the flag isn't always updated when connection
- * happens.
- * So, we walk up parent links until we find a connected directory,
- * or we run out of directories. Then we find the parent, find
- * the name of the child in that parent, and do a lookup.
- * This should connect the child into the parent
- * We then repeat.
- */
-
- /* it is possible that a confused file system might not let us complete
+ * It is possible that a confused file system might not let us complete
* the path to the root. For example, if get_parent returns a directory
* in which we cannot find a name for the child. While this implies a
* very sick filesystem we don't want it to cause knfsd to spin. Hence
* the noprogress counter. If we go through the loop 10 times (2 is
* probably enough) without getting anywhere, we just give up
*/
- noprogress = 0;
while (target_dir->d_flags & DCACHE_DISCONNECTED && noprogress++ < 10) {
struct dentry *pd = find_disconnected_root(target_dir);
@@ -221,18 +147,20 @@ find_exported_dentry(struct super_block
struct dentry *npd;
mutex_lock(&pd->d_inode->i_mutex);
- if (nops->get_parent)
- ppd = nops->get_parent(pd);
+ if (sb->s_export_op->get_parent)
+ ppd = sb->s_export_op->get_parent(pd);
mutex_unlock(&pd->d_inode->i_mutex);
if (IS_ERR(ppd)) {
err = PTR_ERR(ppd);
- dprintk("find_exported_dentry: get_parent of %ld failed, err %d\n",
- pd->d_inode->i_ino, err);
+ dprintk("%s: get_parent of %ld failed, err %d\n",
+ __FUNCTION__, pd->d_inode->i_ino, err);
dput(pd);
break;
}
- dprintk("find_exported_dentry: find name of %lu in %lu\n", pd->d_inode->i_ino, ppd->d_inode->i_ino);
+
+ dprintk("%s: find name of %lu in %lu\n", __FUNCTION__,
+ pd->d_inode->i_ino, ppd->d_inode->i_ino);
err = exportfs_get_name(ppd, nbuf, pd);
if (err) {
dput(ppd);
@@ -244,13 +172,14 @@ find_exported_dentry(struct super_block
continue;
break;
}
- dprintk("find_exported_dentry: found name: %s\n", nbuf);
+ dprintk("%s: found name: %s\n", __FUNCTION__, nbuf);
mutex_lock(&ppd->d_inode->i_mutex);
npd = lookup_one_len(nbuf, ppd, strlen(nbuf));
mutex_unlock(&ppd->d_inode->i_mutex);
if (IS_ERR(npd)) {
err = PTR_ERR(npd);
- dprintk("find_exported_dentry: lookup failed: %d\n", err);
+ dprintk("%s: lookup failed: %d\n",
+ __FUNCTION__, err);
dput(ppd);
dput(pd);
break;
@@ -263,7 +192,7 @@ find_exported_dentry(struct super_block
if (npd == pd)
noprogress = 0;
else
- printk("find_exported_dentry: npd != pd\n");
+ printk("%s: npd != pd\n", __FUNCTION__);
dput(npd);
dput(ppd);
if (IS_ROOT(pd)) {
@@ -279,15 +208,101 @@ find_exported_dentry(struct super_block
/* something went wrong - oh-well */
if (!err)
err = -ESTALE;
- goto err_target;
+ return err;
}
- /* if we weren't after a directory, have one more step to go */
- if (result != target_dir) {
- struct dentry *nresult;
+
+ return 0;
+}
+
+/**
+ * find_exported_dentry - helper routine to implement export_operations->decode_fh
+ * @sb: The &super_block identifying the filesystem
+ * @obj: An opaque identifier of the object to be found - passed to
+ * get_inode
+ * @parent: An optional opqaue identifier of the parent of the object.
+ * @acceptable: A function used to test possible &dentries to see if they are
+ * acceptable
+ * @context: A parameter to @acceptable so that it knows on what basis to
+ * judge.
+ *
+ * find_exported_dentry is the central helper routine to enable file systems
+ * to provide the decode_fh() export_operation. It's main task is to take
+ * an &inode, find or create an appropriate &dentry structure, and possibly
+ * splice this into the dcache in the correct place.
+ *
+ * The decode_fh() operation provided by the filesystem should call
+ * find_exported_dentry() with the same parameters that it received except
+ * that instead of the file handle fragment, pointers to opaque identifiers
+ * for the object and optionally its parent are passed. The default decode_fh
+ * routine passes one pointer to the start of the filehandle fragment, and
+ * one 8 bytes into the fragment. It is expected that most filesystems will
+ * take this approach, though the offset to the parent identifier may well be
+ * different.
+ *
+ * find_exported_dentry() will call get_dentry to get an dentry pointer from
+ * the file system. If any &dentry in the d_alias list is acceptable, it will
+ * be returned. Otherwise find_exported_dentry() will attempt to splice a new
+ * &dentry into the dcache using get_name() and get_parent() to find the
+ * appropriate place.
+ */
+
+struct dentry *
+find_exported_dentry(struct super_block *sb, void *obj, void *parent,
+ int (*acceptable)(void *context, struct dentry *de),
+ void *context)
+{
+ struct dentry *result, *alias;
+ int err = -ESTALE;
+
+ /*
+ * Attempt to find the inode.
+ */
+ result = exportfs_get_dentry(sb, obj);
+ if (IS_ERR(result))
+ return result;
+
+ if (S_ISDIR(result->d_inode->i_mode)) {
+ if (!(result->d_flags & DCACHE_DISCONNECTED)) {
+ if (acceptable(context, result))
+ return result;
+ err = -EACCES;
+ goto err_result;
+ }
+
+ err = reconnect_path(sb, result);
+ if (err)
+ goto err_result;
+ } else {
+ struct dentry *target_dir, *nresult;
+ char nbuf[NAME_MAX+1];
+
+ alias = find_acceptable_alias(result, acceptable, context);
+ if (alias)
+ return alias;
+
+ if (parent == NULL)
+ goto err_result;
+
+ target_dir = exportfs_get_dentry(sb,parent);
+ if (IS_ERR(target_dir)) {
+ err = PTR_ERR(target_dir);
+ goto err_result;
+ }
+
+ err = reconnect_path(sb, target_dir);
+ if (err) {
+ dput(target_dir);
+ goto err_result;
+ }
+
+ /*
+ * As we weren't after a directory, have one more step to go.
+ */
err = exportfs_get_name(target_dir, nbuf, result);
if (!err) {
mutex_lock(&target_dir->d_inode->i_mutex);
- nresult = lookup_one_len(nbuf, target_dir, strlen(nbuf));
+ nresult = lookup_one_len(nbuf, target_dir,
+ strlen(nbuf));
mutex_unlock(&target_dir->d_inode->i_mutex);
if (!IS_ERR(nresult)) {
if (nresult->d_inode) {
@@ -297,8 +312,8 @@ find_exported_dentry(struct super_block
dput(nresult);
}
}
+ dput(target_dir);
}
- dput(target_dir);
alias = find_acceptable_alias(result, acceptable, context);
if (alias)
@@ -308,13 +323,11 @@ find_exported_dentry(struct super_block
dput(result);
/* It might be justifiable to return ESTALE here,
* but the filehandle at-least looks reasonable good
- * and it just be a permission problem, so returning
+ * and it may just be a permission problem, so returning
* -EACCESS is safer
*/
return ERR_PTR(-EACCES);
- err_target:
- dput(target_dir);
err_result:
dput(result);
return ERR_PTR(err);
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 002 of 8] knfsd: exportfs: remove iget abuse
2007-05-15 7:16 ` [PATCH 002 of 8] knfsd: exportfs: remove iget abuse NeilBrown
@ 2007-05-15 12:30 ` Dave Kleikamp
0 siblings, 0 replies; 10+ messages in thread
From: Dave Kleikamp @ 2007-05-15 12:30 UTC (permalink / raw)
To: NeilBrown
Cc: Andrew Morton, nfs, linux-kernel, Christoph Hellwig,
Christoph Hellwig
On Tue, 2007-05-15 at 17:16 +1000, NeilBrown wrote:
> diff .prev/fs/jfs/jfs_inode.h ./fs/jfs/jfs_inode.h
> --- .prev/fs/jfs/jfs_inode.h 2007-05-14 11:14:52.000000000 +1000
> +++ ./fs/jfs/jfs_inode.h 2007-05-14 11:15:29.000000000 +1000
> @@ -31,7 +31,7 @@ extern void jfs_truncate(struct inode *)
> extern void jfs_truncate_nolock(struct inode *, loff_t);
> extern void jfs_free_zero_link(struct inode *);
> extern struct dentry *jfs_get_parent(struct dentry *dentry);
> -extern void jfs_get_inode_flags(struct jfs_inode_info *);
You don't want to remove the declaration of jfs_get_inode_flags().
> +extern struct dentry *jfs_get_dentry(struct super_block *sb, void *vobjp);
> extern void jfs_set_inode_flags(struct inode *);
> extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
>
>
> diff .prev/fs/jfs/namei.c ./fs/jfs/namei.c
> --- .prev/fs/jfs/namei.c 2007-05-14 11:14:52.000000000 +1000
> +++ ./fs/jfs/namei.c 2007-05-14 11:15:29.000000000 +1000
> @@ -1477,6 +1477,38 @@ static struct dentry *jfs_lookup(struct
> return dentry;
> }
>
> +struct dentry *jfs_get_dentry(struct super_block *sb, void *vobjp)
> +{
> + __u32 *objp = vobjp;
> + unsigned long ino = objp[0];
> + __u32 generation = objp[1];
> + struct inode *inode;
> + struct dentry *result;
> +
> + if (ino == 0)
> + return ERR_PTR(-ESTALE);
> + inode = iget(sb, ino);
> + if (inode == NULL)
> + return ERR_PTR(-ENOMEM);
> +
> + if (is_bad_inode(inode) ||
> + (generation && inode->i_generation != generation)) {
> + result = ERR_PTR(-ESTALE);
> + goto out_iput;
> + }
> +
> + result = d_alloc_anon(inode);
> + if (!result) {
> + result = ERR_PTR(-ENOMEM);
> + goto out_iput;
> + }
> + return result;
> +
> + out_iput:
> + iput(inode);
> + return result;
> +}
> +
> struct dentry *jfs_get_parent(struct dentry *dentry)
> {
> struct super_block *sb = dentry->d_inode->i_sb;
>
> diff .prev/fs/jfs/super.c ./fs/jfs/super.c
> --- .prev/fs/jfs/super.c 2007-05-14 11:15:23.000000000 +1000
> +++ ./fs/jfs/super.c 2007-05-14 11:15:29.000000000 +1000
> @@ -738,6 +738,7 @@ static const struct super_operations jfs
> };
>
> static struct export_operations jfs_export_operations = {
> + .get_dentry = jfs_get_dentry,
> .get_parent = jfs_get_parent,
> };
Looks sane. You can add:
Signed-off-by: Dave Kleikamp <shaggy@linux.vnet.ibm.com>
--
David Kleikamp
IBM Linux Technology Center
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2007-05-15 12:30 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-05-15 7:15 [PATCH 000 of 8] knfsd: cleanups for exportfs code NeilBrown
2007-05-15 7:16 ` [PATCH 001 of 8] knfsd: exportfs: add exportfs.h header NeilBrown
2007-05-15 7:16 ` [PATCH 002 of 8] knfsd: exportfs: remove iget abuse NeilBrown
2007-05-15 12:30 ` Dave Kleikamp
2007-05-15 7:16 ` [PATCH 003 of 8] knfsd: exportfs: add procedural interface for NFSD NeilBrown
2007-05-15 7:16 ` [PATCH 004 of 8] knfsd: exportfs: remove CALL macro NeilBrown
2007-05-15 7:16 ` [PATCH 005 of 8] knfsd: exportfs: untangle ISDIR logic in find_exported_dentry NeilBrown
2007-05-15 7:16 ` [PATCH 006 of 8] knfsd: exportfs: move acceptable check into find_acceptable_alias NeilBrown
2007-05-15 7:16 ` [PATCH 007 of 8] knfsd: exportfs: add find_disconnected_root helper NeilBrown
2007-05-15 7:16 ` [PATCH 008 of 8] knfsd: exportfs: split out reconnecting a dentry from find_exported_dentry NeilBrown
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox