patch-2.1.32 linux/fs/nfsd/nfsfh.c
Next file: linux/fs/nfsd/nfsproc.c
Previous file: linux/fs/nfsd/nfsctl.c
Back to the patch index
Back to the overall index
- Lines: 125
- Date:
Fri Apr 4 11:06:02 1997
- Orig file:
v2.1.31/linux/fs/nfsd/nfsfh.c
- Orig date:
Wed Dec 31 16:00:00 1969
diff -u --recursive --new-file v2.1.31/linux/fs/nfsd/nfsfh.c linux/fs/nfsd/nfsfh.c
@@ -0,0 +1,124 @@
+/*
+ * linux/fs/nfsd/nfsfh.c
+ *
+ * NFS server filehandle treatment.
+ *
+ * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
+ */
+
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/unistd.h>
+#include <linux/string.h>
+#include <linux/stat.h>
+
+#include <linux/sunrpc/svc.h>
+#include <linux/nfsd/nfsd.h>
+
+#define NFSDDBG_FACILITY NFSDDBG_FH
+
+/*
+ * Get the inode version number
+ */
+static inline int
+nfsd_iversion(struct inode *inode)
+{
+ if (inode->i_sb->s_magic == EXT2_SUPER_MAGIC)
+ return inode->u.ext2_i.i_version;
+ return 0;
+}
+
+/*
+ * Get the inode given a file handle.
+ */
+u32
+fh_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
+{
+ struct svc_export *exp;
+ struct inode *inode;
+ struct knfs_fh *fh = &fhp->fh_handle;
+
+ /* Already checked */
+ if (fhp->fh_inode)
+ return 0;
+
+ dprintk("nfsd: fh_lookup(exp %x/%ld fh %x/%ld)\n",
+ fh->fh_xdev, fh->fh_xino, fh->fh_dev, fh->fh_ino);
+
+ /* Make sure that clients don't cheat */
+ if (fh->fh_dev != fh->fh_xdev) {
+ printk(KERN_NOTICE "nfsd: fh with bad dev fields "
+ "(%x != %x) from %08lx:%d\n",
+ fh->fh_dev, fh->fh_xdev,
+ ntohl(rqstp->rq_addr.sin_addr.s_addr),
+ ntohs(rqstp->rq_addr.sin_port));
+ return nfserr_perm;
+ }
+
+ /* Look up the export entry */
+ exp = exp_get(rqstp->rq_client, fh->fh_xdev, fh->fh_xino);
+ if (!exp) {
+ /* nfsdstats.fhstale++; */
+ return nfserr_stale; /* export entry revoked */
+ }
+
+ /* Check if the request originated from a secure port. */
+ if (!rqstp->rq_secure && EX_SECURE(exp)) {
+ printk(KERN_WARNING
+ "nfsd: request from insecure port (%08lx:%d)!\n",
+ ntohl(rqstp->rq_addr.sin_addr.s_addr),
+ ntohs(rqstp->rq_addr.sin_port));
+ return nfserr_perm;
+ }
+
+ /* Set user creds if we haven't done so already */
+ nfsd_setuser(rqstp, exp);
+
+ /* Get the inode */
+ if (!(inode = nfsd_iget(fh->fh_dev, fh->fh_ino))
+ || !inode->i_nlink || fh->fh_version != nfsd_iversion(inode)) {
+ if (inode)
+ iput(inode);
+ /* nfsdstats.fhstale++; */
+ return nfserr_stale; /* unlinked in the meanwhile */
+ }
+
+ /* This is basically what wait_on_inode does */
+ while (inode->i_lock)
+ sleep_on(&inode->i_wait);
+ fhp->fh_inode = inode;
+ fhp->fh_export = exp;
+
+ /* Type check. The correct error return for type mismatches
+ * does not seem to be generally agreed upon. SunOS seems to
+ * use EISDIR if file isn't S_IFREG; a comment in the NFSv3
+ * spec says this is incorrect (implementation notes for the
+ * write call).
+ */
+ if (type > 0 && (inode->i_mode & S_IFMT) != type)
+ return (type == S_IFDIR)? nfserr_notdir : nfserr_isdir;
+ if (type < 0 && (inode->i_mode & S_IFMT) == -type)
+ return (type == -S_IFDIR)? nfserr_notdir : nfserr_isdir;
+
+ /* Finally, check access permissions */
+ return nfsd_permission(fhp->fh_export, inode, access);
+}
+
+/*
+ * Compose file handle for NFS reply.
+ */
+void
+fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct inode *inode)
+{
+ dprintk("nfsd: fh_compose(exp %x/%ld fh %x/%ld)\n",
+ exp->ex_dev, exp->ex_ino, inode->i_dev, inode->i_ino);
+
+ fh_init(fhp); /* initialize empty fh */
+ fhp->fh_inode = inode;
+ fhp->fh_export = exp;
+ fhp->fh_handle.fh_dev = inode->i_dev;
+ fhp->fh_handle.fh_ino = inode->i_ino;
+ fhp->fh_handle.fh_xdev = exp->ex_dev;
+ fhp->fh_handle.fh_xino = exp->ex_ino;
+ fhp->fh_handle.fh_version = nfsd_iversion(inode);
+}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov