From: Cong Wang <amwang@redhat.com>
To: linux-kernel@vger.kernel.org
Cc: akpm@linux-foundation.org, Hugh Dickins <hughd@google.com>,
Al Viro <viro@zeniv.linux.org.uk>, Christoph Hellwig <hch@lst.de>,
WANG Cong <amwang@redhat.com>, Matthew Wilcox <matthew@wil.cx>,
Andrea Arcangeli <aarcange@redhat.com>,
Rik van Riel <riel@redhat.com>, Mel Gorman <mel@csn.ul.ie>,
Minchan Kim <minchan.kim@gmail.com>,
Johannes Weiner <hannes@cmpxchg.org>,
linux-fsdevel@vger.kernel.org, linux-mm@kvack.org
Subject: [PATCH 2/2] fs: wire up .truncate_range and .fallocate
Date: Wed, 23 Nov 2011 16:53:31 +0800 [thread overview]
Message-ID: <1322038412-29013-2-git-send-email-amwang@redhat.com> (raw)
In-Reply-To: <1322038412-29013-1-git-send-email-amwang@redhat.com>
As Hugh suggested, with FALLOC_FL_PUNCH_HOLE, we can use do_fallocate()
to implement madvise_remove and finally remove .truncate_range call back.
Cc: Hugh Dickins <hughd@google.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: WANG Cong <amwang@redhat.com>
---
include/linux/fs.h | 1 -
include/linux/mm.h | 3 ++-
mm/madvise.c | 8 +++++---
mm/shmem.c | 1 -
mm/truncate.c | 21 +++++++++++++--------
5 files changed, 20 insertions(+), 14 deletions(-)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index e313022..266df73 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1635,7 +1635,6 @@ struct inode_operations {
ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
ssize_t (*listxattr) (struct dentry *, char *, size_t);
int (*removexattr) (struct dentry *, const char *);
- void (*truncate_range)(struct inode *, loff_t, loff_t);
int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
u64 len);
} ____cacheline_aligned;
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 3dc3a8c..a47f744 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -951,7 +951,8 @@ static inline void unmap_shared_mapping_range(struct address_space *mapping,
extern void truncate_pagecache(struct inode *inode, loff_t old, loff_t new);
extern void truncate_setsize(struct inode *inode, loff_t newsize);
extern int vmtruncate(struct inode *inode, loff_t offset);
-extern int vmtruncate_range(struct inode *inode, loff_t offset, loff_t end);
+extern int vmtruncate_file_range(struct file *file, struct inode *inode,
+ loff_t offset, loff_t end);
int truncate_inode_page(struct address_space *mapping, struct page *page);
int generic_error_remove_page(struct address_space *mapping, struct page *page);
diff --git a/mm/madvise.c b/mm/madvise.c
index 74bf193..05610d3 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -194,7 +194,8 @@ static long madvise_remove(struct vm_area_struct *vma,
struct vm_area_struct **prev,
unsigned long start, unsigned long end)
{
- struct address_space *mapping;
+ struct file *file;
+ struct inode *inode;
loff_t offset, endoff;
int error;
@@ -211,7 +212,8 @@ static long madvise_remove(struct vm_area_struct *vma,
if ((vma->vm_flags & (VM_SHARED|VM_WRITE)) != (VM_SHARED|VM_WRITE))
return -EACCES;
- mapping = vma->vm_file->f_mapping;
+ file = vma->vm_file;
+ inode = file->f_mapping->host;
offset = (loff_t)(start - vma->vm_start)
+ ((loff_t)vma->vm_pgoff << PAGE_SHIFT);
@@ -220,7 +222,7 @@ static long madvise_remove(struct vm_area_struct *vma,
/* vmtruncate_range needs to take i_mutex */
up_read(¤t->mm->mmap_sem);
- error = vmtruncate_range(mapping->host, offset, endoff);
+ error = vmtruncate_file_range(file, inode, offset, endoff);
down_read(¤t->mm->mmap_sem);
return error;
}
diff --git a/mm/shmem.c b/mm/shmem.c
index 65f7a27..fce5667 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -2356,7 +2356,6 @@ static const struct file_operations shmem_file_operations = {
static const struct inode_operations shmem_inode_operations = {
.setattr = shmem_setattr,
- .truncate_range = shmem_truncate_range,
#ifdef CONFIG_TMPFS_XATTR
.setxattr = shmem_setxattr,
.getxattr = shmem_getxattr,
diff --git a/mm/truncate.c b/mm/truncate.c
index 632b15e..7c46539 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -20,6 +20,7 @@
#include <linux/buffer_head.h> /* grr. try_to_release_page,
do_invalidatepage */
#include <linux/cleancache.h>
+#include <linux/falloc.h>
#include "internal.h"
@@ -602,24 +603,28 @@ int vmtruncate(struct inode *inode, loff_t newsize)
}
EXPORT_SYMBOL(vmtruncate);
-int vmtruncate_range(struct inode *inode, loff_t lstart, loff_t lend)
+int vmtruncate_file_range(struct file *file, struct inode *inode,
+ loff_t lstart, loff_t lend)
{
struct address_space *mapping = inode->i_mapping;
loff_t holebegin = round_up(lstart, PAGE_SIZE);
loff_t holelen = 1 + lend - holebegin;
+ int err;
- /*
- * If the underlying filesystem is not going to provide
- * a way to truncate a range of blocks (punch a hole) -
- * we should return failure right now.
- */
- if (!inode->i_op->truncate_range)
+ if (!file->f_op->fallocate)
return -ENOSYS;
mutex_lock(&inode->i_mutex);
inode_dio_wait(inode);
unmap_mapping_range(mapping, holebegin, holelen, 1);
- inode->i_op->truncate_range(inode, lstart, lend);
+ mutex_unlock(&inode->i_mutex);
+
+ err = do_fallocate(file, FALLOC_FL_KEEP_SIZE|FALLOC_FL_PUNCH_HOLE,
+ holebegin, holelen);
+ if (err)
+ return err;
+
+ mutex_lock(&inode->i_mutex);
/* unmap again to remove racily COWed private pages */
unmap_mapping_range(mapping, holebegin, holelen, 1);
mutex_unlock(&inode->i_mutex);
--
1.7.4.4
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
WARNING: multiple messages have this Message-ID (diff)
From: Cong Wang <amwang@redhat.com>
To: linux-kernel@vger.kernel.org
Cc: akpm@linux-foundation.org, Hugh Dickins <hughd@google.com>,
Al Viro <viro@zeniv.linux.org.uk>, Christoph Hellwig <hch@lst.de>,
WANG Cong <amwang@redhat.com>, Matthew Wilcox <matthew@wil.cx>,
Andrea Arcangeli <aarcange@redhat.com>,
Rik van Riel <riel@redhat.com>, Mel Gorman <mel@csn.ul.ie>,
Minchan Kim <minchan.kim@gmail.com>,
Johannes Weiner <hannes@cmpxchg.org>,
linux-fsdevel@vger.kernel.org, linux-mm@kvack.org
Subject: [PATCH 2/2] fs: wire up .truncate_range and .fallocate
Date: Wed, 23 Nov 2011 16:53:31 +0800 [thread overview]
Message-ID: <1322038412-29013-2-git-send-email-amwang@redhat.com> (raw)
In-Reply-To: <1322038412-29013-1-git-send-email-amwang@redhat.com>
As Hugh suggested, with FALLOC_FL_PUNCH_HOLE, we can use do_fallocate()
to implement madvise_remove and finally remove .truncate_range call back.
Cc: Hugh Dickins <hughd@google.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: WANG Cong <amwang@redhat.com>
---
include/linux/fs.h | 1 -
include/linux/mm.h | 3 ++-
mm/madvise.c | 8 +++++---
mm/shmem.c | 1 -
mm/truncate.c | 21 +++++++++++++--------
5 files changed, 20 insertions(+), 14 deletions(-)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index e313022..266df73 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1635,7 +1635,6 @@ struct inode_operations {
ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
ssize_t (*listxattr) (struct dentry *, char *, size_t);
int (*removexattr) (struct dentry *, const char *);
- void (*truncate_range)(struct inode *, loff_t, loff_t);
int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
u64 len);
} ____cacheline_aligned;
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 3dc3a8c..a47f744 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -951,7 +951,8 @@ static inline void unmap_shared_mapping_range(struct address_space *mapping,
extern void truncate_pagecache(struct inode *inode, loff_t old, loff_t new);
extern void truncate_setsize(struct inode *inode, loff_t newsize);
extern int vmtruncate(struct inode *inode, loff_t offset);
-extern int vmtruncate_range(struct inode *inode, loff_t offset, loff_t end);
+extern int vmtruncate_file_range(struct file *file, struct inode *inode,
+ loff_t offset, loff_t end);
int truncate_inode_page(struct address_space *mapping, struct page *page);
int generic_error_remove_page(struct address_space *mapping, struct page *page);
diff --git a/mm/madvise.c b/mm/madvise.c
index 74bf193..05610d3 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -194,7 +194,8 @@ static long madvise_remove(struct vm_area_struct *vma,
struct vm_area_struct **prev,
unsigned long start, unsigned long end)
{
- struct address_space *mapping;
+ struct file *file;
+ struct inode *inode;
loff_t offset, endoff;
int error;
@@ -211,7 +212,8 @@ static long madvise_remove(struct vm_area_struct *vma,
if ((vma->vm_flags & (VM_SHARED|VM_WRITE)) != (VM_SHARED|VM_WRITE))
return -EACCES;
- mapping = vma->vm_file->f_mapping;
+ file = vma->vm_file;
+ inode = file->f_mapping->host;
offset = (loff_t)(start - vma->vm_start)
+ ((loff_t)vma->vm_pgoff << PAGE_SHIFT);
@@ -220,7 +222,7 @@ static long madvise_remove(struct vm_area_struct *vma,
/* vmtruncate_range needs to take i_mutex */
up_read(¤t->mm->mmap_sem);
- error = vmtruncate_range(mapping->host, offset, endoff);
+ error = vmtruncate_file_range(file, inode, offset, endoff);
down_read(¤t->mm->mmap_sem);
return error;
}
diff --git a/mm/shmem.c b/mm/shmem.c
index 65f7a27..fce5667 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -2356,7 +2356,6 @@ static const struct file_operations shmem_file_operations = {
static const struct inode_operations shmem_inode_operations = {
.setattr = shmem_setattr,
- .truncate_range = shmem_truncate_range,
#ifdef CONFIG_TMPFS_XATTR
.setxattr = shmem_setxattr,
.getxattr = shmem_getxattr,
diff --git a/mm/truncate.c b/mm/truncate.c
index 632b15e..7c46539 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -20,6 +20,7 @@
#include <linux/buffer_head.h> /* grr. try_to_release_page,
do_invalidatepage */
#include <linux/cleancache.h>
+#include <linux/falloc.h>
#include "internal.h"
@@ -602,24 +603,28 @@ int vmtruncate(struct inode *inode, loff_t newsize)
}
EXPORT_SYMBOL(vmtruncate);
-int vmtruncate_range(struct inode *inode, loff_t lstart, loff_t lend)
+int vmtruncate_file_range(struct file *file, struct inode *inode,
+ loff_t lstart, loff_t lend)
{
struct address_space *mapping = inode->i_mapping;
loff_t holebegin = round_up(lstart, PAGE_SIZE);
loff_t holelen = 1 + lend - holebegin;
+ int err;
- /*
- * If the underlying filesystem is not going to provide
- * a way to truncate a range of blocks (punch a hole) -
- * we should return failure right now.
- */
- if (!inode->i_op->truncate_range)
+ if (!file->f_op->fallocate)
return -ENOSYS;
mutex_lock(&inode->i_mutex);
inode_dio_wait(inode);
unmap_mapping_range(mapping, holebegin, holelen, 1);
- inode->i_op->truncate_range(inode, lstart, lend);
+ mutex_unlock(&inode->i_mutex);
+
+ err = do_fallocate(file, FALLOC_FL_KEEP_SIZE|FALLOC_FL_PUNCH_HOLE,
+ holebegin, holelen);
+ if (err)
+ return err;
+
+ mutex_lock(&inode->i_mutex);
/* unmap again to remove racily COWed private pages */
unmap_mapping_range(mapping, holebegin, holelen, 1);
mutex_unlock(&inode->i_mutex);
--
1.7.4.4
next prev parent reply other threads:[~2011-11-23 8:53 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-11-23 8:53 [V3 PATCH 1/2] tmpfs: add fallocate support Cong Wang
2011-11-23 8:53 ` Cong Wang
2011-11-23 8:53 ` Cong Wang [this message]
2011-11-23 8:53 ` [PATCH 2/2] fs: wire up .truncate_range and .fallocate Cong Wang
2011-11-23 10:38 ` Christoph Hellwig
2011-11-23 10:38 ` Christoph Hellwig
2011-11-23 19:16 ` Hugh Dickins
2011-11-23 19:16 ` Hugh Dickins
2011-11-23 9:06 ` [V3 PATCH 1/2] tmpfs: add fallocate support Pekka Enberg
2011-11-23 9:06 ` Pekka Enberg
2011-11-23 19:07 ` Hugh Dickins
2011-11-23 19:07 ` Hugh Dickins
2011-11-24 3:18 ` Cong Wang
2011-11-24 3:18 ` Cong Wang
2011-11-23 19:59 ` KOSAKI Motohiro
2011-11-23 19:59 ` KOSAKI Motohiro
2011-11-23 21:11 ` Pekka Enberg
2011-11-23 21:11 ` Pekka Enberg
2011-11-23 22:20 ` Hugh Dickins
2011-11-24 3:15 ` Cong Wang
2011-11-24 3:15 ` Cong Wang
2011-11-24 1:52 ` KAMEZAWA Hiroyuki
2011-11-24 1:52 ` KAMEZAWA Hiroyuki
2011-11-24 2:46 ` KOSAKI Motohiro
2011-11-24 2:46 ` KOSAKI Motohiro
2011-11-24 3:01 ` KAMEZAWA Hiroyuki
2011-11-24 3:01 ` KAMEZAWA Hiroyuki
2011-11-24 3:22 ` Cong Wang
2011-11-24 3:22 ` Cong Wang
2011-11-24 4:23 ` KAMEZAWA Hiroyuki
2011-11-24 4:23 ` KAMEZAWA Hiroyuki
2011-11-24 5:52 ` Cong Wang
2011-11-24 5:52 ` Cong Wang
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=1322038412-29013-2-git-send-email-amwang@redhat.com \
--to=amwang@redhat.com \
--cc=aarcange@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=hannes@cmpxchg.org \
--cc=hch@lst.de \
--cc=hughd@google.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=matthew@wil.cx \
--cc=mel@csn.ul.ie \
--cc=minchan.kim@gmail.com \
--cc=riel@redhat.com \
--cc=viro@zeniv.linux.org.uk \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.