summaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1995-11-14 08:00:00 +0000
committer <ralf@linux-mips.org>1995-11-14 08:00:00 +0000
commite7c2a72e2680827d6a733931273a93461c0d8d1b (patch)
treec9abeda78ef7504062bb2e816bcf3e3c9d680112 /fs/nfs
parentec6044459060a8c9ce7f64405c465d141898548c (diff)
Import of Linux/MIPS 1.3.0
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/Makefile2
-rw-r--r--fs/nfs/cache.c63
-rw-r--r--fs/nfs/dir.c41
-rw-r--r--fs/nfs/file.c6
-rw-r--r--fs/nfs/inode.c69
-rw-r--r--fs/nfs/mmap.c15
-rw-r--r--fs/nfs/proc.c6
-rw-r--r--fs/nfs/sock.c10
-rw-r--r--fs/nfs/symlink.c4
9 files changed, 175 insertions, 41 deletions
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
index 8610c95b1..eabf9f6f1 100644
--- a/fs/nfs/Makefile
+++ b/fs/nfs/Makefile
@@ -23,6 +23,8 @@ nfs.o: $(OBJS)
dep:
$(CPP) -M *.c > .depend
+modules: nfs.o
+
#
# include a dependency file if one exists
#
diff --git a/fs/nfs/cache.c b/fs/nfs/cache.c
new file mode 100644
index 000000000..57f3cc411
--- /dev/null
+++ b/fs/nfs/cache.c
@@ -0,0 +1,63 @@
+
+void nfs_bl_cache_invalidate(nfs_cache *nh)
+{
+ unsigned long flags;
+ save_flags(flags);
+ cli();
+ if(nh->inuse)
+ nh->dead=1;
+ else
+ {
+ kfree_s(nh->data);
+ nh->data=NULL;
+ nh->free=1;
+ }
+}
+
+void nfs_bl_cache_revalidate(nfs_cache *nh, struct fattr fa)
+{
+ nh->fattr=fattr;
+ nh->time=jiffies;
+}
+
+/*
+ * Find a block in the cache. We know the cache is block sized in block
+ * aligned space.
+ */
+
+nfs_cache *nfs_cache_find(struct inode *inode, off_t pos)
+{
+ nfs_cache *nh=&nfs_cache_slot[0];
+ nfs_cache *ffree=NULL;
+ struct nfs_fattr fattr;
+ int ct=0;
+ while(ct<NH_CACHE_SIZE)
+ {
+ if(nh->inode_num==inode->i_no && !nh->dead&&!nh->free&&nh->file_pos==pos)
+ {
+ if(abs(jiffies-nh->time)<EXPIRE_CACHE)
+ return nh;
+ /*
+ * Revalidate
+ */
+
+ if(nfs_proc_getattr(NFS_SERVER(inode), NFS_FH(inode), &fattr))
+ {
+ nfs_bl_cache_invalidate(nh);
+ continue; /* get attr failed */
+ }
+ if(nh->fattr.modified!=fattr.modified)
+ {
+ nfs_bl_cache_invalidate(nh);
+ continue; /* cache is out of date */
+ }
+ nfs_refresh_inode(inode, fattr);
+ nh->fattr=fattr;
+ nfs_bl_cache_revalidate(nh);
+ return nh;
+ }
+ if(nh->free)
+ ffree=nh;
+ }
+ return ffree;
+}
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 62a3e0821..bdbe92d0f 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -6,6 +6,10 @@
* nfs directory handling functions
*/
+#ifdef MODULE
+#include <linux/module.h>
+#endif
+
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/stat.h>
@@ -18,12 +22,9 @@
#include <asm/segment.h> /* for fs functions */
-#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
-#define ROUND_UP(x) (((x)+3) & ~3)
-
static int nfs_dir_read(struct inode *, struct file *filp, char *buf,
int count);
-static int nfs_readdir(struct inode *, struct file *, struct dirent *, int);
+static int nfs_readdir(struct inode *, struct file *, void *, filldir_t);
static int nfs_lookup(struct inode *dir, const char *name, int len,
struct inode **result);
static int nfs_create(struct inode *dir, const char *name, int len, int mode,
@@ -87,7 +88,7 @@ static int nfs_dir_read(struct inode *inode, struct file *filp, char *buf,
*/
static int nfs_readdir(struct inode *inode, struct file *filp,
- struct dirent *dirent, int count)
+ void *dirent, filldir_t filldir)
{
static int c_dev = 0;
static int c_ino;
@@ -95,7 +96,7 @@ static int nfs_readdir(struct inode *inode, struct file *filp,
static struct nfs_entry *c_entry = NULL;
int result;
- int i;
+ int i, index = 0;
struct nfs_entry *entry;
if (!inode || !S_ISDIR(inode->i_mode)) {
@@ -125,7 +126,7 @@ static int nfs_readdir(struct inode *inode, struct file *filp,
return 0;
}
else
- entry = c_entry + i + 1;
+ entry = c_entry + (index = i + 1);
break;
}
}
@@ -144,19 +145,27 @@ static int nfs_readdir(struct inode *inode, struct file *filp,
c_dev = inode->i_dev;
c_ino = inode->i_ino;
c_size = result;
- entry = c_entry + 0;
+ entry = c_entry + (index = 0);
}
}
/* if we found it in the cache or from an nfs call, return results */
-
- if (entry) {
- i = strlen(entry->name);
- memcpy_tofs(dirent->d_name, entry->name, i + 1);
- put_fs_long(entry->fileid, &dirent->d_ino);
- put_fs_word(i, &dirent->d_reclen);
- filp->f_pos = entry->cookie;
- return ROUND_UP(NAME_OFFSET(dirent)+i+1);
+ if (!entry)
+ return 0;
+ while (index < c_size) {
+ int nextpos = entry->cookie;
+ if (filldir(dirent, entry->name, strlen(entry->name), filp->f_pos, entry->fileid) < 0)
+ break;
+ filp->f_pos = nextpos;
+ /* revalidate the cache if we slept in filldir() */
+ if (inode->i_dev != c_dev)
+ break;
+ if (inode->i_ino != c_ino)
+ break;
+ if (nextpos != entry->cookie)
+ break;
+ index++;
+ entry++;
}
return 0;
}
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index e71d29483..cf8fe83ce 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -14,6 +14,10 @@
* nfs regular file handling functions
*/
+#ifdef MODULE
+#include <linux/module.h>
+#endif
+
#include <asm/segment.h>
#include <asm/system.h>
@@ -119,7 +123,7 @@ static int nfs_file_read(struct inode *inode, struct file *file, char *buf,
if ((cache[i].inode_num == inode->i_ino)
&& (cache[i].file_pos <= pos)
&& (cache[i].file_pos + cache[i].len >= pos + count)
- && (abs(jiffies - cache[i].time) <= EXPIRE_CACHE))
+ && (abs(jiffies - cache[i].time) < EXPIRE_CACHE))
break;
if (i < READ_CACHE_SIZE) {
++cache[i].in_use;
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 17f2cb6f0..94b4b4557 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -4,8 +4,19 @@
* Copyright (C) 1992 Rick Sladkey
*
* nfs inode and superblock handling functions
+ *
+ * Modularised by Alan Cox <Alan.Cox@linux.org>, while hacking some
+ * experimental NFS changes. Modularisation taken straight from SYS5 fs.
*/
+#ifdef MODULE
+#include <linux/module.h>
+#include <linux/version.h>
+#else
+#define MOD_INC_USE_COUNT
+#define MOD_DEC_USE_COUNT
+#endif
+
#include <asm/system.h>
#include <asm/segment.h>
@@ -18,12 +29,12 @@
#include <linux/errno.h>
#include <linux/locks.h>
-extern int close_fp(struct file *filp, unsigned int fd);
+extern int close_fp(struct file *filp);
static int nfs_notify_change(struct inode *, struct iattr *);
static void nfs_put_inode(struct inode *);
static void nfs_put_super(struct super_block *);
-static void nfs_statfs(struct super_block *, struct statfs *);
+static void nfs_statfs(struct super_block *, struct statfs *, int bufsiz);
static struct super_operations nfs_sops = {
NULL, /* read inode */
@@ -43,11 +54,11 @@ static void nfs_put_inode(struct inode * inode)
void nfs_put_super(struct super_block *sb)
{
- /* No locks should be open on this, so 0 should be safe as a fd. */
- close_fp(sb->u.nfs_sb.s_server.file, 0);
+ close_fp(sb->u.nfs_sb.s_server.file);
lock_super(sb);
sb->s_dev = 0;
unlock_super(sb);
+ MOD_DEC_USE_COUNT;
}
/*
@@ -67,9 +78,11 @@ struct super_block *nfs_read_super(struct super_block *sb, void *raw_data,
struct file *filp;
dev_t dev = sb->s_dev;
+ MOD_INC_USE_COUNT;
if (!data) {
printk("nfs_read_super: missing data argument\n");
sb->s_dev = 0;
+ MOD_DEC_USE_COUNT;
return NULL;
}
fd = data->fd;
@@ -80,11 +93,13 @@ struct super_block *nfs_read_super(struct super_block *sb, void *raw_data,
if (fd >= NR_OPEN || !(filp = current->files->fd[fd])) {
printk("nfs_read_super: invalid file descriptor\n");
sb->s_dev = 0;
+ MOD_DEC_USE_COUNT;
return NULL;
}
if (!S_ISSOCK(filp->f_inode->i_mode)) {
printk("nfs_read_super: not a socket\n");
sb->s_dev = 0;
+ MOD_DEC_USE_COUNT;
return NULL;
}
filp->f_count++;
@@ -121,32 +136,33 @@ struct super_block *nfs_read_super(struct super_block *sb, void *raw_data,
if (!(sb->s_mounted = nfs_fhget(sb, &data->root, NULL))) {
sb->s_dev = 0;
printk("nfs_read_super: get root inode failed\n");
+ MOD_DEC_USE_COUNT;
return NULL;
}
return sb;
}
-void nfs_statfs(struct super_block *sb, struct statfs *buf)
+void nfs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
{
int error;
struct nfs_fsinfo res;
+ struct statfs tmp;
- put_fs_long(NFS_SUPER_MAGIC, &buf->f_type);
error = nfs_proc_statfs(&sb->u.nfs_sb.s_server, &sb->u.nfs_sb.s_root,
&res);
if (error) {
printk("nfs_statfs: statfs error = %d\n", -error);
res.bsize = res.blocks = res.bfree = res.bavail = 0;
}
- put_fs_long(res.bsize, &buf->f_bsize);
- put_fs_long(res.blocks, &buf->f_blocks);
- put_fs_long(res.bfree, &buf->f_bfree);
- put_fs_long(res.bavail, &buf->f_bavail);
- put_fs_long(0, &buf->f_files);
- put_fs_long(0, &buf->f_ffree);
- /* We should really try to interrogate the remote server to find
- it's maximum name length here */
- put_fs_long(NAME_MAX, &buf->f_namelen);
+ tmp.f_type = NFS_SUPER_MAGIC;
+ tmp.f_bsize = res.bsize;
+ tmp.f_blocks = res.blocks;
+ tmp.f_bfree = res.bfree;
+ tmp.f_bavail = res.bavail;
+ tmp.f_files = 0;
+ tmp.f_ffree = 0;
+ tmp.f_namelen = NAME_MAX;
+ memcpy_tofs(buf, &tmp, bufsiz);
}
/*
@@ -238,3 +254,26 @@ int nfs_notify_change(struct inode *inode, struct iattr *attr)
inode->i_dirt = 0;
return error;
}
+
+#ifdef MODULE
+
+/* Every kernel module contains stuff like this. */
+
+char kernel_version[] = UTS_RELEASE;
+
+static struct file_system_type nfs_fs_type = {
+ nfs_read_super, "nfs", 0, NULL
+};
+
+int init_module(void)
+{
+ register_filesystem(&nfs_fs_type);
+ return 0;
+}
+
+void cleanup_module(void)
+{
+ unregister_filesystem(&nfs_fs_type);
+}
+
+#endif
diff --git a/fs/nfs/mmap.c b/fs/nfs/mmap.c
index 811176a69..30854469c 100644
--- a/fs/nfs/mmap.c
+++ b/fs/nfs/mmap.c
@@ -9,6 +9,10 @@
* Copyright (C) 1993
*
*/
+#ifdef MODULE
+#include <linux/module.h>
+#endif
+
#include <linux/stat.h>
#include <linux/sched.h>
#include <linux/kernel.h>
@@ -74,20 +78,25 @@ static unsigned long nfs_file_mmap_nopage(struct vm_area_struct * area,
}
return page;
}
+
struct vm_operations_struct nfs_file_mmap = {
NULL, /* open */
NULL, /* close */
+ NULL, /* unmap */
+ NULL, /* protect */
+ NULL, /* sync */
+ NULL, /* advise */
nfs_file_mmap_nopage, /* nopage */
NULL, /* wppage */
- NULL, /* share */
- NULL, /* unmap */
+ NULL, /* swapout */
+ NULL, /* swapin */
};
/* This is used for a general mmap of a nfs file */
int nfs_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma)
{
- if (vma->vm_page_prot & PAGE_RW) /* only PAGE_COW or read-only supported now */
+ if (vma->vm_flags & VM_SHARED) /* only PAGE_COW or read-only supported now */
return -EINVAL;
if (!inode->i_sb || !S_ISREG(inode->i_mode))
return -EACCES;
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index fd01dad99..9aeb66751 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -33,7 +33,10 @@
#define NFS_PROC_DEBUG
#endif
-#include <linux/config.h>
+#ifdef MODULE
+#include <linux/module.h>
+#endif
+
#include <linux/param.h>
#include <linux/sched.h>
#include <linux/mm.h>
@@ -898,6 +901,7 @@ static struct {
{ NFSERR_NOENT, ENOENT },
{ NFSERR_IO, errno_NFSERR_IO },
{ NFSERR_NXIO, ENXIO },
+ { NFSERR_EAGAIN, EAGAIN },
{ NFSERR_ACCES, EACCES },
{ NFSERR_EXIST, EEXIST },
{ NFSERR_NODEV, ENODEV },
diff --git a/fs/nfs/sock.c b/fs/nfs/sock.c
index 2455d938a..ea81f55af 100644
--- a/fs/nfs/sock.c
+++ b/fs/nfs/sock.c
@@ -18,7 +18,10 @@
*
*/
-#include <linux/config.h>
+#ifdef MODULE
+#include <linux/module.h>
+#endif
+
#include <linux/sched.h>
#include <linux/nfs_fs.h>
#include <linux/errno.h>
@@ -34,9 +37,6 @@
* ***FIXME*** should probably put this in nfs_fs.h */
#define NFS_SLACK_SPACE 1024
-
-extern struct socket *socki_lookup(struct inode *inode);
-
#define _S(nr) (1<<((nr)-1))
/*
@@ -78,7 +78,7 @@ static int do_nfs_rpc_call(struct nfs_server *server, int *start, int *end, int
file = server->file;
inode = file->f_inode;
select = file->f_op->select;
- sock = socki_lookup(inode);
+ sock = &inode->u.socket_i;
if (!sock) {
printk("nfs_rpc_call: socki_lookup failed\n");
return -EBADF;
diff --git a/fs/nfs/symlink.c b/fs/nfs/symlink.c
index 4cbe631c6..85c40b495 100644
--- a/fs/nfs/symlink.c
+++ b/fs/nfs/symlink.c
@@ -8,6 +8,10 @@
* nfs symlink handling code
*/
+#ifdef MODULE
+#include <linux/module.h>
+#endif
+
#include <asm/segment.h>
#include <linux/sched.h>