lkml.org 
[lkml]   [2000]   [Jul]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subjectzapping nfs file cache
I would like to see functionality in the kernel nfs client which permits
userspace to request that any cached data (from previous reads) be dropped
from memory. This is exactly what 'nfs_zap_caches(inode)' does in the
kernel.

I'm in the process of porting a Unix application to Linux. We use a custom
locking protocol on top of NFS. I'd originally been told that the only
special thing we required from the NFS implementation was a way to turn off
attribute caching, which is already available. However, after our locking
test suite failed on Linux, someone remembered "the other" NFS hack we've
had to make on our other ports, which involves the ability to request that
any cached data from an NFS file (present due to previous reads) be
dropped, so that a subsequent read will result in an NFS read request to
the server.

Formerly we've overloaded fsync(), but after some discussion it was
suggested to implement it as an ioctl(), rather than perverting the
meaning of fsync(). Unfortunately, there doesn't seem to be any way to
access this functionality from userspace without adding an ioctl or the
like.

The attached patch adds this functionality. I'd like to hear any
responses, including any problems with the patch, suggestions for alternate
ways I could achieve the same thing, suggestions for how to make these
changes available to our end-users in an easy-to-use and license-compliant
fashion, and most wonderful of all being told that this kind of
functionality would be included in a standard kernel somewhere down
the road.

Jeff
PS I don't understand the locking situation, but I'm the most linux-savvy
of the people working on this project so I get to write this message.
Apparently this problem crops up when a sequence like this occurs,
due to the limited resolution of mtime:
Client 1 Client 2
Write to file
Read file -> NFS request
Write to file again within 1 second
Read file -> Timestamp matches,
use cached (invalid) data
--
Jeff Epler jepler@inetnebr.com
--- fs/nfs.orig/file.c Thu Jul 13 18:51:06 2000
+++ fs/nfs/file.c Thu Jul 13 19:15:58 2000
@@ -37,6 +37,8 @@
static ssize_t nfs_file_write(struct file *, const char *, size_t, loff_t *);
static int nfs_file_flush(struct file *);
static int nfs_fsync(struct file *, struct dentry *dentry);
+static int nfs_file_ioctl(struct inode * inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);

static struct file_operations nfs_file_operations = {
NULL, /* lseek - default */
@@ -44,7 +46,7 @@
nfs_file_write, /* write */
NULL, /* readdir - bad */
NULL, /* select - default */
- NULL, /* ioctl - default */
+ nfs_file_ioctl, /* ioctl */
nfs_file_mmap, /* mmap */
nfs_open, /* open */
nfs_file_flush, /* flush */
@@ -118,6 +120,20 @@
if (!result)
result = generic_file_read(file, buf, count, ppos);
return result;
+}
+
+static int
+nfs_file_ioctl(struct inode * inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ switch (cmd) {
+ case NFS_IOC_ZAP_CACHES:
+ nfs_zap_caches(inode);
+ return 0;
+ break;
+ default:
+ return -EINVAL;
+ }
}

static int
--- fs/nfs.orig/inode.c Thu Jul 13 18:51:06 2000
+++ fs/nfs/inode.c Thu Jul 13 19:08:03 2000
@@ -37,7 +37,6 @@
#define NFS_PARANOIA 1

static struct inode * __nfs_fhget(struct super_block *, struct nfs_fattr *);
-static void nfs_zap_caches(struct inode *);
static void nfs_invalidate_inode(struct inode *);

static void nfs_read_inode(struct inode *);
@@ -432,7 +431,7 @@
/*
* Invalidate the local caches
*/
-static void
+void
nfs_zap_caches(struct inode *inode)
{
NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode);
--- include/linux/nfs_fs.h.orig Thu Jul 13 19:03:21 2000
+++ include/linux/nfs_fs.h Thu Jul 13 19:09:47 2000
@@ -17,6 +17,8 @@
#include <linux/nfs.h>
#include <linux/nfs_mount.h>

+#include <linux/ioctl.h>
+
/*
* Enable debugging support for nfs client.
* Requires RPC_DEBUG.
@@ -25,6 +27,8 @@
# define NFS_DEBUG
#endif

+#define NFS_IOC_ZAP_CACHES _IO('d', 0)
+
/*
* NFS_MAX_DIRCACHE controls the number of simultaneously cached
* directory chunks. Each chunk holds the list of nfs_entry's returned
@@ -184,6 +188,7 @@
extern int nfs_open(struct inode *, struct file *);
extern int nfs_release(struct inode *, struct file *);
extern int _nfs_revalidate_inode(struct nfs_server *, struct dentry *);
+extern void nfs_zap_caches(struct inode *inode);

/*
* linux/fs/nfs/file.c
\
 
 \ /
  Last update: 2005-03-22 13:57    [from the cache]
©2003-2011 Jasper Spaans