patch 38/38: SERVER: giant patch importing NFSv4 server functionality

patch 38/38: SERVER: giant patch importing NFSv4 server functionality

Post by Kendrick M. Smit » Thu, 15 Aug 2002 08:30:12



Now that all the hooks are in place, this large patch imports all
of the new code for the NFSv4 server.

This patch makes almost no changes to the existing nfsd codebase
(these have been taken care of by the preceding patches).

One aspect of the NFSv4 code deserves comment.  The most natural scheme
for processing a COMPOUND request would seem to be:
  1a. XDR decode phase, decode args of all operations
  2a. processing phase, process all operations
  3a. XDR encode phase, encode results of all operations

However, we use a scheme which works as follows:
  1b. XDR decode phase, decode args of all operations
  2b. For each operation,
        process the operation
        encode the result

To see what is wrong with the first scheme, consider a COMPOUND
of the form READ REMOVE.  Since the last bit of processing for
the READ request occurs in XDR encode, we might discover in step
3a that the READ request should return an error.  Therefore, the
REMOVE request should not be processed at all.  This is a fatal
problem, since the REMOVE was already been done in step 2a!

Another type of problem would occur in a COMPOUND of the form
READ WRITE.  Assume that both operations succeed.  Under scheme
(a), the WRITE is actually performed _before_ the READ (since
the "real" READ is really done during XDR encode).  This is
certainly incorrect if the READ and WRITE ranges overlap.

These examples might seem a little artificial, but nevertheless
it does seem that in order to process a COMPOUND correctly in
all cases, we need to use scheme (b) instead of scheme (a).

(To construct less artificial examples, just substitute GETATTR
 for READ in the examples above.  This works because the "real"
 GETATTR is done during XDR encode: one would really have to
 bend over backwards in order to arrange things otherwise.)

--- old/fs/nfsd/Makefile        Wed Jul 24 16:03:25 2002
+++ new/fs/nfsd/Makefile        Wed Aug  7 12:59:23 2002
@@ -7,6 +7,7 @@ obj-$(CONFIG_NFSD)      += nfsd.o
 nfsd-y                         := nfssvc.o nfsctl.o nfsproc.o nfsfh.o vfs.o \
                           export.o auth.o lockd.o nfscache.o nfsxdr.o stats.o
 nfsd-$(CONFIG_NFSD_V3) += nfs3proc.o nfs3xdr.o
+nfsd-$(CONFIG_NFSD_V4) += nfs4proc.o nfs4xdr.o
 nfsd-objs              := $(nfsd-y)

 include $(TOPDIR)/Rules.make
--- old/fs/nfsd/nfssvc.c        Fri Aug  9 11:16:02 2002
+++ new/fs/nfsd/nfssvc.c        Thu Aug  8 09:53:23 2002
@@ -77,6 +77,18 @@ nfsd_svc(unsigned short port, int nrserv
        int     none_left;
        struct list_head *victim;

+#ifdef CONFIG_NFSD_V4
+       printk(KERN_INFO "Starting experimental NFSv4 server.\n");
+       printk(KERN_INFO "Note 1: The NFSv4 pseudo filesystem is not yet implemented!\n");
+       printk(KERN_INFO "   The first export in your /etc/exports has been arbitrarily\n");
+       printk(KERN_INFO "   selected as the root of the pseudofs.  In order to see this\n");
+       printk(KERN_INFO "   export, you will have to mount '/' instead of the export pathname.\n");
+       printk(KERN_INFO "   Exports other than this one will not be available.\n");
+       printk(KERN_INFO "Note 2: Most of the NFSv4 state model is not yet implemented;\n");
+       printk(KERN_INFO "   this server patch should still provide basic functionality.\n");
+       printk(KERN_INFO "   However, byte-range file locking is not available.\n");
+#endif
+
        lock_kernel();
        dprintk("nfsd: creating service\n");
        error = -EINVAL;
@@ -338,10 +350,23 @@ static struct svc_version nfsd_version3
                .vs_dispatch    = nfsd_dispatch
 };
 #endif
+#ifdef CONFIG_NFSD_V4
+static struct svc_version      nfsd_version4 = {
+               .vs_vers        = 4,
+               .vs_nproc       = 2,
+               .vs_proc        = nfsd_procedures4,
+               .vs_dispatch    = nfsd_dispatch
+};
+#endif
 static struct svc_version *    nfsd_version[] = {
        [2] = &nfsd_version2,
-#ifdef CONFIG_NFSD_V3
+#if defined(CONFIG_NFSD_V3)
        [3] = &nfsd_version3,
+#elif defined(CONFIG_NFSD_V4)
+       [3] = NULL,
+#endif
+#if defined(CONFIG_NFSD_V4)
+       [4] = &nfsd_version4,
 #endif
 };

--- old/include/linux/nfsd/nfsd.h       Fri Aug  9 10:17:14 2002
+++ new/include/linux/nfsd/nfsd.h       Fri Aug  9 09:57:45 2002
@@ -26,6 +26,7 @@
  * nfsd version
  */
 #define NFSD_VERSION           "0.5"
+#define NFSD_SUPPORTED_MINOR_VERSION   0

 #ifdef __KERNEL__
 /*
@@ -69,6 +70,9 @@ extern struct svc_procedure   nfsd_procedu
 #ifdef CONFIG_NFSD_V3
 extern struct svc_procedure    nfsd_procedures3[];
 #endif /* CONFIG_NFSD_V3 */
+#ifdef CONFIG_NFSD_V4
+extern struct svc_procedure    nfsd_procedures4[];
+#endif /* CONFIG_NFSD_V4 */
 extern struct svc_program      nfsd_program;

 /*
@@ -197,6 +201,73 @@ void               nfsd_lockd_unexport(struct svc_cli
  */
 extern struct timeval  nfssvc_boot;

+
+#ifdef CONFIG_NFSD_V4
+
+/* before processing a COMPOUND operation, we have to check that there
+ * is enough space in the buffer for XDR encode to succeed.  otherwise,
+ * we might process an operation with side effects, and be unable to
+ * tell the client that the operation succeeded.
+ *
+ * COMPOUND_SLACK_SPACE - this is the minimum amount of buffer space
+ * needed to encode an "ordinary" _successful_ operation.  (GETATTR,
+ * READ, READDIR, and READLINK have their own buffer checks.)  if we
+ * fall below this level, we fail the next operation with NFS4ERR_RESOURCE.
+ *
+ * COMPOUND_ERR_SLACK_SPACE - this is the minimum amount of buffer space
+ * needed to encode an operation which has failed with NFS4ERR_RESOURCE.
+ * care is taken to ensure that we never fall below this level for any
+ * reason.
+ */
+#define        COMPOUND_SLACK_SPACE            140    /* OP_GETFH */
+#define COMPOUND_ERR_SLACK_SPACE       12     /* OP_SETATTR */
+
+#define NFSD_LEASE_TIME                        60  /* seconds */
+
+/*
+ * The following attributes are currently not supported by the NFSv4 server:
+ *    ACL           (will be supported in a forthcoming patch)
+ *    ARCHIVE       (deprecated anyway)
+ *    FS_LOCATIONS  (will be supported eventually)
+ *    HIDDEN        (unlikely to be supported any time soon)
+ *    MIMETYPE      (unlikely to be supported any time soon)
+ *    QUOTA_*       (will be supported in a forthcoming patch)
+ *    SYSTEM        (unlikely to be supported any time soon)
+ *    TIME_BACKUP   (unlikely to be supported any time soon)
+ *    TIME_CREATE   (unlikely to be supported any time soon)
+ */
+#define NFSD_SUPPORTED_ATTRS_WORD0                                                          \
+(FATTR4_WORD0_SUPPORTED_ATTRS   | FATTR4_WORD0_TYPE         | FATTR4_WORD0_FH_EXPIRE_TYPE   \
+ | FATTR4_WORD0_CHANGE          | FATTR4_WORD0_SIZE         | FATTR4_WORD0_LINK_SUPPORT     \
+ | FATTR4_WORD0_SYMLINK_SUPPORT | FATTR4_WORD0_NAMED_ATTR   | FATTR4_WORD0_FSID             \
+ | FATTR4_WORD0_UNIQUE_HANDLES  | FATTR4_WORD0_LEASE_TIME   | FATTR4_WORD0_RDATTR_ERROR     \
+ | FATTR4_WORD0_ACLSUPPORT      | FATTR4_WORD0_CANSETTIME   | FATTR4_WORD0_CASE_INSENSITIVE \
+ | FATTR4_WORD0_CASE_PRESERVING | FATTR4_WORD0_CHOWN_RESTRICTED                             \
+ | FATTR4_WORD0_FILEHANDLE      | FATTR4_WORD0_FILEID       | FATTR4_WORD0_FILES_AVAIL      \
+ | FATTR4_WORD0_FILES_FREE      | FATTR4_WORD0_FILES_TOTAL  | FATTR4_WORD0_HOMOGENEOUS      \
+ | FATTR4_WORD0_MAXFILESIZE     | FATTR4_WORD0_MAXLINK      | FATTR4_WORD0_MAXNAME          \
+ | FATTR4_WORD0_MAXREAD         | FATTR4_WORD0_MAXWRITE)
+
+#define NFSD_SUPPORTED_ATTRS_WORD1                                                          \
+(FATTR4_WORD1_MODE              | FATTR4_WORD1_NO_TRUNC     | FATTR4_WORD1_NUMLINKS         \
+ | FATTR4_WORD1_OWNER          | FATTR4_WORD1_OWNER_GROUP  | FATTR4_WORD1_RAWDEV           \
+ | FATTR4_WORD1_SPACE_AVAIL     | FATTR4_WORD1_SPACE_FREE   | FATTR4_WORD1_SPACE_TOTAL      \
+ | FATTR4_WORD1_SPACE_USED      | FATTR4_WORD1_TIME_ACCESS  | FATTR4_WORD1_TIME_ACCESS_SET  \
+ | FATTR4_WORD1_TIME_CREATE     | FATTR4_WORD1_TIME_DELTA   | FATTR4_WORD1_TIME_METADATA    \
+ | FATTR4_WORD1_TIME_MODIFY     | FATTR4_WORD1_TIME_MODIFY_SET)
+
+/* These will return ERR_INVAL if specified in GETATTR or READDIR. */
+#define NFSD_WRITEONLY_ATTRS_WORD1                                                         \
+(FATTR4_WORD1_TIME_ACCESS_SET   | FATTR4_WORD1_TIME_MODIFY_SET)
+
+/* These are the only attrs allowed in CREATE/OPEN/SETATTR. */
+#define NFSD_WRITEABLE_ATTRS_WORD0                            FATTR4_WORD0_SIZE
+#define NFSD_WRITEABLE_ATTRS_WORD1                                                          \
+(FATTR4_WORD1_MODE              | FATTR4_WORD1_OWNER         | FATTR4_WORD1_OWNER_GROUP     \
+ | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_METADATA | FATTR4_WORD1_TIME_MODIFY_SET)
+
+#endif /* CONFIG_NFSD_V4 */
+
 #endif /* __KERNEL__ */

 #endif /* LINUX_NFSD_NFSD_H */
--- old/fs/nfsd/nfs4proc.c      Wed Dec 31 18:00:00 1969
+++ new/fs/nfsd/nfs4proc.c      Thu Aug  8 09:48:00 2002
@@ -0,0 +1,719 @@
+/*
+ *  fs/nfsd/nfs4proc.c
+ *
+ *  Server-side procedures for NFSv4.
+ *
+ *  Copyright (c) 2002 The Regents of the University of Michigan.
+ *  All rights reserved.
+ *
+ *  Kendrick Smith <kmsm...@umich.edu>
+ *  Andy Adamson   <and...@umich.edu>
+ *
+ * Note: some routines in this file are just trivial wrappers
+ * (e.g. nfsd4_lookup()) defined solely for the sake of consistent
+ * naming.  Since all such routines have been declared "inline",
+ * there shouldn't be any associated overhead.  At some point in
+ * the future, I might inline these "by hand" to clean up a
+ * little.
+ */
+
+#include <linux/param.h>
+#include <linux/major.h>
+#include <linux/slab.h>
+
+#include <linux/sunrpc/svc.h>
+#include <linux/nfsd/nfsd.h>
+#include <linux/nfsd/cache.h>
+#include <linux/nfs4.h>
+#include <linux/nfsd/xdr4.h>
+
+#define NFSDDBG_FACILITY               NFSDDBG_PROC
+
+static inline int
+nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_close *close)
+{
+       return nfs_ok;
+}
+
+/* Note: The organization of the OPEN code seems a little strange; it
+ * has been superfluously split into three routines, one of which is named
+ * nfsd4_process_open2() even though there is no nfsd4_process_open1()!
+ * This is because the code has been organized in anticipation of a
+ * subsequent patch which will implement more of the NFSv4 state model.
+ */
+static int
+do_open_lookup(struct ...

read more »

 
 
 

patch 38/38: SERVER: giant patch importing NFSv4 server functionality

Post by Christoph Hellwi » Thu, 15 Aug 2002 21:50:09



> --- old/fs/nfsd/nfssvc.c   Fri Aug  9 11:16:02 2002
> +++ new/fs/nfsd/nfssvc.c   Thu Aug  8 09:53:23 2002

>    int     none_left;
>    struct list_head *victim;

> +#ifdef CONFIG_NFSD_V4
> +  printk(KERN_INFO "Starting experimental NFSv4 server.\n");
> +  printk(KERN_INFO "Note 1: The NFSv4 pseudo filesystem is not yet implemented!\n");
> +  printk(KERN_INFO "   The first export in your /etc/exports has been arbitrarily\n");
> +  printk(KERN_INFO "   selected as the root of the pseudofs.  In order to see this\n");
> +  printk(KERN_INFO "   export, you will have to mount '/' instead of the export pathname.\n");
> +  printk(KERN_INFO "   Exports other than this one will not be available.\n");
> +  printk(KERN_INFO "Note 2: Most of the NFSv4 state model is not yet implemented;\n");
> +  printk(KERN_INFO "   this server patch should still provide basic functionality.\n");
> +  printk(KERN_INFO "   However, byte-range file locking is not available.\n");
> +#endif

This belongs into a readme, not into kernel messages..

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/