From: Dave Kleikamp <shaggy@austin.ibm.com>
To: nfsv4 <nfsv4@linux-nfs.org>, fsdevel <linux-fsdevel@vger.kernel.org>
Subject: [RFC] Support for stackable file systems on top of nfs
Date: Thu, 10 Nov 2005 11:32:22 -0600 [thread overview]
Message-ID: <1131643942.9389.17.camel@kleikamp.austin.ibm.com> (raw)
The following patch allows stackable file systems, such as ClearCase's
mvfs, to run atop nfs. mvfs has it's own file and inode structures, but
points its inode->i_mapping to the lower file system's mapping. This
causes problems when nfs's address space operations try to extract the
open context from file->private_data.
The patch adds a small overhead of checking the file structure to see if
it contains an inode that is not the mapping's host.
I am curious if there are any other stackable file systems that could
benefit from this.
Signed-off-by: Dave Kleikamp <shaggy@austin.ibm.com>
diff -Nurp linux-2.6.14-git/fs/nfs/direct.c linux/fs/nfs/direct.c
--- linux-2.6.14-git/fs/nfs/direct.c 2005-11-07 07:53:49.000000000 -0600
+++ linux/fs/nfs/direct.c 2005-11-09 14:58:59.000000000 -0600
@@ -604,7 +604,19 @@ nfs_direct_IO(int rw, struct kiocb *iocb
if (!is_sync_kiocb(iocb))
return result;
- ctx = (struct nfs_open_context *)file->private_data;
+ if (nfs_is_valid_file(file))
+ ctx = get_nfs_open_context((struct nfs_open_context *)
+ file->private_data);
+ else {
+ /* file belongs to a stackable file system.
+ * Can't trust the inode either */
+ inode = inode->i_mapping->host;
+
+ ctx = nfs_find_open_context(inode, NULL,
+ (rw == READ) ? FMODE_READ : FMODE_WRITE);
+ if (ctx == NULL)
+ return -EBADF;
+ }
switch (rw) {
case READ:
dprintk("NFS: direct_IO(read) (%s) off/no(%Lu/%lu)\n",
@@ -623,6 +635,7 @@ nfs_direct_IO(int rw, struct kiocb *iocb
default:
break;
}
+ put_nfs_open_context(ctx);
return result;
}
diff -Nurp linux-2.6.14-git/fs/nfs/read.c linux/fs/nfs/read.c
--- linux-2.6.14-git/fs/nfs/read.c 2005-11-07 07:53:49.000000000 -0600
+++ linux/fs/nfs/read.c 2005-11-09 11:47:05.000000000 -0600
@@ -506,7 +506,7 @@ int nfs_readpage(struct file *file, stru
if (error)
goto out_error;
- if (file == NULL) {
+ if (!nfs_is_valid_file(file)) {
ctx = nfs_find_open_context(inode, NULL, FMODE_READ);
if (ctx == NULL)
return -EBADF;
@@ -575,7 +575,7 @@ int nfs_readpages(struct file *filp, str
(long long)NFS_FILEID(inode),
nr_pages);
- if (filp == NULL) {
+ if (!nfs_is_valid_file(filp)) {
desc.ctx = nfs_find_open_context(inode, NULL, FMODE_READ);
if (desc.ctx == NULL)
return -EBADF;
diff -Nurp linux-2.6.14-git/fs/nfs/write.c linux/fs/nfs/write.c
--- linux-2.6.14-git/fs/nfs/write.c 2005-11-07 07:53:49.000000000 -0600
+++ linux/fs/nfs/write.c 2005-11-09 14:14:33.000000000 -0600
@@ -703,10 +703,16 @@ static struct nfs_page * nfs_update_requ
int nfs_flush_incompatible(struct file *file, struct page *page)
{
- struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data;
+ struct nfs_open_context *ctx;
struct inode *inode = page->mapping->host;
struct nfs_page *req;
int status = 0;
+
+ if (nfs_is_valid_file(file))
+ ctx = (struct nfs_open_context *)file->private_data;
+ else
+ ctx = NULL;
+
/*
* Look for a request corresponding to this page. If there
* is one, and it belongs to another file, we flush it out
@@ -733,7 +739,7 @@ int nfs_flush_incompatible(struct file *
int nfs_updatepage(struct file *file, struct page *page,
unsigned int offset, unsigned int count)
{
- struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data;
+ struct nfs_open_context *ctx;
struct inode *inode = page->mapping->host;
struct nfs_page *req;
int status = 0;
@@ -743,14 +749,23 @@ int nfs_updatepage(struct file *file, st
file->f_dentry->d_name.name, count,
(long long)(page_offset(page) +offset));
+ if (nfs_is_valid_file(file))
+ ctx = get_nfs_open_context((struct nfs_open_context *)
+ file->private_data);
+ else {
+ ctx = nfs_find_open_context(inode, NULL, FMODE_WRITE);
+ if (!ctx)
+ return -EBADF;
+ }
+
if (IS_SYNC(inode)) {
status = nfs_writepage_sync(ctx, inode, page, offset, count, 0);
if (status > 0) {
if (offset == 0 && status == PAGE_CACHE_SIZE)
SetPageUptodate(page);
- return 0;
+ status = 0;
}
- return status;
+ goto out;
}
/* If we're not using byte range locks, and we know the page
@@ -803,6 +818,8 @@ done:
status, (long long)i_size_read(inode));
if (status < 0)
ClearPageUptodate(page);
+out:
+ put_nfs_open_context(ctx);
return status;
}
diff -Nurp linux-2.6.14-git/include/linux/nfs_fs.h linux/include/linux/nfs_fs.h
--- linux-2.6.14-git/include/linux/nfs_fs.h 2005-11-07 07:53:50.000000000 -0600
+++ linux/include/linux/nfs_fs.h 2005-11-09 11:44:53.000000000 -0600
@@ -350,6 +350,20 @@ static inline struct rpc_cred *nfs_file_
}
/*
+ * A stackable file system may have it's own file & inode structures, which
+ * point to the local inode's mapping. The address space operations cannot
+ * use the stackable file system's file structure to get to the open context
+ */
+static inline int nfs_is_valid_file(struct file *file)
+{
+ struct inode *inode;
+ if (!file)
+ return 0;
+ inode = file->f_dentry->d_inode;
+ return (inode == inode->i_mapping->host);
+}
+
+/*
* linux/fs/nfs/xattr.c
*/
#ifdef CONFIG_NFS_V3_ACL
--
David Kleikamp
IBM Linux Technology Center
next reply other threads:[~2005-11-10 17:32 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-11-10 17:32 Dave Kleikamp [this message]
2005-11-10 20:07 ` [RFC] Support for stackable file systems on top of nfs Christoph Hellwig
2005-11-10 21:35 ` John T. Kohl
2005-11-10 21:40 ` Shaya Potter
2005-11-10 21:57 ` John T. Kohl
2005-11-10 21:50 ` Christoph Hellwig
2005-11-11 2:31 ` Trond Myklebust
2005-11-11 4:04 ` Trond Myklebust
2005-11-11 13:45 ` John T. Kohl
2005-11-11 15:27 ` Charles P. Wright
2005-11-11 17:38 ` John T. Kohl
2005-11-14 15:56 ` David Howells
2005-11-10 21:24 ` Trond Myklebust
2005-11-10 21:36 ` Shaya Potter
2005-11-10 22:18 ` Trond Myklebust
2005-11-10 22:27 ` Shaya Potter
2005-11-10 22:40 ` Trond Myklebust
2005-11-11 0:12 ` Bryan Henderson
2005-11-11 1:30 ` Brad Boyer
2005-11-11 2:06 ` Trond Myklebust
2005-11-11 18:18 ` Bryan Henderson
2005-11-11 19:22 ` Trond Myklebust
2005-11-11 21:57 ` Bryan Henderson
2005-11-11 22:41 ` Trond Myklebust
2005-11-14 19:02 ` Bryan Henderson
2005-11-11 16:40 ` Nikita Danilov
2005-11-11 18:45 ` Bryan Henderson
2005-11-11 19:31 ` Nikita Danilov
2005-11-11 19:42 ` Trond Myklebust
2005-11-11 23:13 ` Bryan Henderson
-- strict thread matches above, loose matches on Subject: below --
2005-11-14 0:44 Nikolai Joukov
2005-11-14 16:02 ` David Howells
2005-11-14 20:48 ` Erez Zadok
2005-11-14 21:13 ` John T. Kohl
2005-11-14 21:32 ` Jamie Lokier
2005-11-14 16:11 ` John T. Kohl
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1131643942.9389.17.camel@kleikamp.austin.ibm.com \
--to=shaggy@austin.ibm.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=nfsv4@linux-nfs.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).