linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Trond Myklebust <Trond.Myklebust@netapp.com>
To: Andi Kleen <andi@firstfloor.org>,
	Linus Torvalds <torvalds@linux-foundation.org>
Cc: linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org
Subject: [RFC PATCH 1/2] VFS: Add a mmap_file() callback to struct file_operations
Date: Fri, 08 Jan 2010 19:56:24 -0500	[thread overview]
Message-ID: <20100109005624.7473.24670.stgit@localhost.localdomain> (raw)
In-Reply-To: <20100109005624.7473.33215.stgit@localhost.localdomain>

Add a helper function to allow the NFS filesystem to hook mmap() system
calls and do the necessary page cache revalidation before passing control
to the VM layer.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
---

 include/linux/fs.h |    5 +++++
 mm/filemap.c       |   23 +++++++++++++++++++++++
 mm/mmap.c          |   11 ++++++++---
 mm/nommu.c         |   11 ++++++++---
 4 files changed, 44 insertions(+), 6 deletions(-)

diff --git a/include/linux/fs.h b/include/linux/fs.h
index 9147ca8..5d66b16 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1504,6 +1504,9 @@ struct file_operations {
 	ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
 	ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
 	int (*setlease)(struct file *, long, struct file_lock **);
+	unsigned long (*mmap_pgoff)(struct file *, unsigned long,
+			unsigned long, unsigned long,
+			unsigned long, unsigned long);
 };
 
 struct inode_operations {
@@ -2191,6 +2194,8 @@ extern int set_blocksize(struct block_device *, int);
 extern int sb_set_blocksize(struct super_block *, int);
 extern int sb_min_blocksize(struct super_block *, int);
 
+extern unsigned long generic_file_mmap_pgoff(struct file *, unsigned long,
+		unsigned long, unsigned long, unsigned long, unsigned long);
 extern int generic_file_mmap(struct file *, struct vm_area_struct *);
 extern int generic_file_readonly_mmap(struct file *, struct vm_area_struct *);
 extern int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size);
diff --git a/mm/filemap.c b/mm/filemap.c
index 96ac6b0..f7717b9 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1594,6 +1594,29 @@ const struct vm_operations_struct generic_file_vm_ops = {
 	.fault		= filemap_fault,
 };
 
+/**
+ * generic_file_mmap_pgoff - generic filesystem mmap_pgoff routine
+ * @file: file to mmap
+ * @addr: memory address to map to
+ * @len: length of the mapping
+ * @prot: memory protection flags
+ * @flags: mapping type
+ * @pgoff: starting page offset
+ */ 
+unsigned long generic_file_mmap_pgoff(struct file *file, unsigned long addr,
+			unsigned long len, unsigned long prot,
+			unsigned long flags, unsigned long pgoff)
+{
+	struct mm_struct *mm = current->mm;
+	unsigned long retval;
+
+	down_write(&mm->mmap_sem);
+	retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+	up_write(&mm->mmap_sem);
+	return retval;
+}
+EXPORT_SYMBOL(generic_file_mmap_pgoff);
+
 /* This is used for a general mmap of a disk file */
 
 int generic_file_mmap(struct file * file, struct vm_area_struct * vma)
diff --git a/mm/mmap.c b/mm/mmap.c
index ee22989..3931811 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1047,6 +1047,9 @@ SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
 		unsigned long, prot, unsigned long, flags,
 		unsigned long, fd, unsigned long, pgoff)
 {
+	unsigned long (*func)(struct file *, unsigned long,
+			unsigned long, unsigned long,
+			unsigned long, unsigned long);
 	struct file *file = NULL;
 	unsigned long retval = -EBADF;
 
@@ -1073,9 +1076,11 @@ SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
 
 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
 
-	down_write(&current->mm->mmap_sem);
-	retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
+	if (file && file->f_op && file->f_op->mmap_pgoff)
+		func = file->f_op->mmap_pgoff;
+	else
+		func = generic_file_mmap_pgoff;
+	retval = func(file, addr, len, prot, flags, pgoff);
 
 	if (file)
 		fput(file);
diff --git a/mm/nommu.c b/mm/nommu.c
index 1777386..4e31cb2 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1407,6 +1407,9 @@ SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
 		unsigned long, prot, unsigned long, flags,
 		unsigned long, fd, unsigned long, pgoff)
 {
+	unsigned long (*func)(struct file *, unsigned long,
+			unsigned long, unsigned long,
+			unsigned long, unsigned long);
 	struct file *file = NULL;
 	unsigned long retval = -EBADF;
 
@@ -1418,9 +1421,11 @@ SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
 
 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
 
-	down_write(&current->mm->mmap_sem);
-	retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
+	if (file && file->f_op && file->f_op->mmap_pgoff)
+		func = file->f_op->mmap_pgoff;
+	else
+		func = generic_file_mmap_pgoff;
+	retval = func(file, addr, len, prot, flags, pgoff);
 
 	if (file)
 		fput(file);


  parent reply	other threads:[~2010-01-09  1:07 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-01-07 20:29 [GIT PULL] Please pull NFS client bugfixes Trond Myklebust
2010-01-07 21:00 ` Andi Kleen
2010-01-07 21:23   ` Peter Staubach
2010-01-07 21:35     ` Andi Kleen
2010-01-07 21:53   ` Trond Myklebust
2010-01-07 23:51     ` Andi Kleen
2010-01-08  0:14       ` Trond Myklebust
2010-01-08  0:34         ` Linus Torvalds
2010-01-08  0:45           ` Andi Kleen
2010-01-08  1:03             ` Trond Myklebust
2010-01-08  1:03           ` Trond Myklebust
2010-01-08  1:12             ` Linus Torvalds
2010-01-08  1:22               ` Trond Myklebust
2010-01-08  1:26                 ` Trond Myklebust
2010-01-09  0:56                   ` [RFC PATCH 0/2] Fix up the NFS mmap code Trond Myklebust
2010-01-09  0:56                     ` [RFC PATCH 2/2] NFS: Fix a potential deadlock in nfs_file_mmap() Trond Myklebust
2010-01-09  1:54                       ` Al Viro
2010-01-09  0:56                     ` Trond Myklebust [this message]
2010-01-09  1:17                     ` [RFC PATCH 0/2] Fix up the NFS mmap code Linus Torvalds
2010-01-09  1:38                       ` Al Viro
2010-01-09  1:46                         ` Al Viro
2010-01-09  1:57                         ` Linus Torvalds
2010-01-09  2:11                           ` Al Viro
2010-01-09  2:22                             ` Linus Torvalds
2010-01-09  2:30                               ` Al Viro
2010-01-09  2:40                                 ` Al Viro
2010-01-09  2:43                                   ` Al Viro
2010-01-10  2:00                     ` Andi Kleen
2010-01-08  1:30                 ` [GIT PULL] Please pull NFS client bugfixes Linus Torvalds
2010-01-08  1:35                   ` Linus Torvalds
2010-01-08  2:00                     ` Linus Torvalds
2010-01-14 13:18                       ` Peter Zijlstra
2010-01-08  5:19                   ` Andi Kleen
2010-01-08  1:22               ` Linus Torvalds
2010-01-08  0:43         ` Andi Kleen

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=20100109005624.7473.24670.stgit@localhost.localdomain \
    --to=trond.myklebust@netapp.com \
    --cc=andi@firstfloor.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=torvalds@linux-foundation.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).