Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Marek <mmarek@suse.cz>2009-11-20 17:29:58 +0100
committerMichal Marek <mmarek@suse.cz>2009-11-20 17:47:00 +0100
commit0ef4e637a25dd8e6c8e25425dac6837f3e5e8faf (patch)
tree2e5b03ea8dce852a91c2ffaa2ff122ea8812bb17
parent83d72fcfe987f68790a99e160fc8079e4cc6d244 (diff)
- patches.suse/export-sync_page_range: Revert "vfs: Remove
generic_osync_inode() and sync_page_range{_nolock}()" (bnc#557231).
-rw-r--r--kernel-source.changes7
-rw-r--r--patches.suse/export-sync_page_range189
-rw-r--r--series.conf1
3 files changed, 197 insertions, 0 deletions
diff --git a/kernel-source.changes b/kernel-source.changes
index 2d295db4a4..c83a9bd488 100644
--- a/kernel-source.changes
+++ b/kernel-source.changes
@@ -1,4 +1,11 @@
-------------------------------------------------------------------
+Fri Nov 20 17:29:45 CET 2009 - mmarek@suse.cz
+
+- patches.suse/export-sync_page_range: Revert "vfs: Remove
+ generic_osync_inode() and sync_page_range{_nolock}()"
+ (bnc#557231).
+
+-------------------------------------------------------------------
Fri Nov 20 17:26:01 CET 2009 - jbeulich@novell.com
- patches.suse/init-move-populate_rootfs-back-to-start_kernel:
diff --git a/patches.suse/export-sync_page_range b/patches.suse/export-sync_page_range
new file mode 100644
index 0000000000..8a506d333e
--- /dev/null
+++ b/patches.suse/export-sync_page_range
@@ -0,0 +1,189 @@
+From 48b8926b6b02382bc774efee2ed2cd6be8770ac0 Mon Sep 17 00:00:00 2001
+From: Michal Marek <mmarek@suse.cz>
+Date: Fri, 20 Nov 2009 17:25:21 +0100
+Subject: [PATCH] Revert "vfs: Remove generic_osync_inode() and sync_page_range{_nolock}()"
+References: bnc#557231
+
+Commit 18f2ee705d98034b0f229a3202d827468d4bffd9 broke iscsitarget, revert
+it temporarily. The exports are marged _GPL though.
+
+Signed-off-by: Michal Marek <mmarek@suse.cz>
+
+---
+ fs/fs-writeback.c | 54 ++++++++++++++++++++++++++++++++++++++
+ include/linux/fs.h | 5 +++
+ include/linux/writeback.h | 4 +++
+ mm/filemap.c | 64 +++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 127 insertions(+), 0 deletions(-)
+
+diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
+index 9d5360c..f68c542 100644
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -1280,3 +1280,57 @@ int sync_inode(struct inode *inode, struct writeback_control *wbc)
+ return ret;
+ }
+ EXPORT_SYMBOL(sync_inode);
++
++/**
++ * generic_osync_inode - flush all dirty data for a given inode to disk
++ * @inode: inode to write
++ * @mapping: the address_space that should be flushed
++ * @what: what to write and wait upon
++ *
++ * This can be called by file_write functions for files which have the
++ * O_SYNC flag set, to flush dirty writes to disk.
++ *
++ * @what is a bitmask, specifying which part of the inode's data should be
++ * written and waited upon.
++ *
++ * OSYNC_DATA: i_mapping's dirty data
++ * OSYNC_METADATA: the buffers at i_mapping->private_list
++ * OSYNC_INODE: the inode itself
++ */
++
++int generic_osync_inode(struct inode *inode, struct address_space *mapping, int what)
++{
++ int err = 0;
++ int need_write_inode_now = 0;
++ int err2;
++
++ if (what & OSYNC_DATA)
++ err = filemap_fdatawrite(mapping);
++ if (what & (OSYNC_METADATA|OSYNC_DATA)) {
++ err2 = sync_mapping_buffers(mapping);
++ if (!err)
++ err = err2;
++ }
++ if (what & OSYNC_DATA) {
++ err2 = filemap_fdatawait(mapping);
++ if (!err)
++ err = err2;
++ }
++
++ spin_lock(&inode_lock);
++ if ((inode->i_state & I_DIRTY) &&
++ ((what & OSYNC_INODE) || (inode->i_state & I_DIRTY_DATASYNC)))
++ need_write_inode_now = 1;
++ spin_unlock(&inode_lock);
++
++ if (need_write_inode_now) {
++ err2 = write_inode_now(inode, 1);
++ if (!err)
++ err = err2;
++ }
++ else
++ inode_sync_wait(inode);
++
++ return err;
++}
++EXPORT_SYMBOL_GPL(generic_osync_inode);
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index 2620a8c..d2a9ffa 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -1459,6 +1459,11 @@ int fiemap_check_flags(struct fiemap_extent_info *fieinfo, u32 fs_flags);
+ #define DT_SOCK 12
+ #define DT_WHT 14
+
++#define OSYNC_METADATA (1<<0)
++#define OSYNC_DATA (1<<1)
++#define OSYNC_INODE (1<<2)
++int generic_osync_inode(struct inode *, struct address_space *, int);
++
+ /*
+ * This is the "filldir" function type, used by readdir() to let
+ * the kernel specify what kind of dirent layout it wants to have.
+diff --git a/include/linux/writeback.h b/include/linux/writeback.h
+index 66ebddc..3676321 100644
+--- a/include/linux/writeback.h
++++ b/include/linux/writeback.h
+@@ -148,6 +148,10 @@ int write_cache_pages(struct address_space *mapping,
+ struct writeback_control *wbc, writepage_t writepage,
+ void *data);
+ int do_writepages(struct address_space *mapping, struct writeback_control *wbc);
++int sync_page_range(struct inode *inode, struct address_space *mapping,
++ loff_t pos, loff_t count);
++int sync_page_range_nolock(struct inode *inode, struct address_space *mapping,
++ loff_t pos, loff_t count);
+ void set_page_dirty_balance(struct page *page, int page_mkwrite);
+ void writeback_set_ratelimit(void);
+
+diff --git a/mm/filemap.c b/mm/filemap.c
+index ef169f3..c7283a9 100644
+--- a/mm/filemap.c
++++ b/mm/filemap.c
+@@ -332,6 +332,70 @@ int filemap_fdatawait_range(struct address_space *mapping, loff_t start,
+ EXPORT_SYMBOL(filemap_fdatawait_range);
+
+ /**
++ * sync_page_range - write and wait on all pages in the passed range
++ * @inode: target inode
++ * @mapping: target address_space
++ * @pos: beginning offset in pages to write
++ * @count: number of bytes to write
++ *
++ * Write and wait upon all the pages in the passed range. This is a "data
++ * integrity" operation. It waits upon in-flight writeout before starting and
++ * waiting upon new writeout. If there was an IO error, return it.
++ *
++ * We need to re-take i_mutex during the generic_osync_inode list walk because
++ * it is otherwise livelockable.
++ */
++int sync_page_range(struct inode *inode, struct address_space *mapping,
++ loff_t pos, loff_t count)
++{
++ pgoff_t start = pos >> PAGE_CACHE_SHIFT;
++ pgoff_t end = (pos + count - 1) >> PAGE_CACHE_SHIFT;
++ int ret;
++
++ if (!mapping_cap_writeback_dirty(mapping) || !count)
++ return 0;
++ ret = filemap_fdatawrite_range(mapping, pos, pos + count - 1);
++ if (ret == 0) {
++ mutex_lock(&inode->i_mutex);
++ ret = generic_osync_inode(inode, mapping, OSYNC_METADATA);
++ mutex_unlock(&inode->i_mutex);
++ }
++ if (ret == 0)
++ ret = wait_on_page_writeback_range(mapping, start, end);
++ return ret;
++}
++EXPORT_SYMBOL_GPL(sync_page_range);
++
++/**
++ * sync_page_range_nolock - write & wait on all pages in the passed range without locking
++ * @inode: target inode
++ * @mapping: target address_space
++ * @pos: beginning offset in pages to write
++ * @count: number of bytes to write
++ *
++ * Note: Holding i_mutex across sync_page_range_nolock() is not a good idea
++ * as it forces O_SYNC writers to different parts of the same file
++ * to be serialised right until io completion.
++ */
++int sync_page_range_nolock(struct inode *inode, struct address_space *mapping,
++ loff_t pos, loff_t count)
++{
++ pgoff_t start = pos >> PAGE_CACHE_SHIFT;
++ pgoff_t end = (pos + count - 1) >> PAGE_CACHE_SHIFT;
++ int ret;
++
++ if (!mapping_cap_writeback_dirty(mapping) || !count)
++ return 0;
++ ret = filemap_fdatawrite_range(mapping, pos, pos + count - 1);
++ if (ret == 0)
++ ret = generic_osync_inode(inode, mapping, OSYNC_METADATA);
++ if (ret == 0)
++ ret = wait_on_page_writeback_range(mapping, start, end);
++ return ret;
++}
++EXPORT_SYMBOL_GPL(sync_page_range_nolock);
++
++/**
+ * filemap_fdatawait - wait for all under-writeback pages to complete
+ * @mapping: address space structure to wait for
+ *
+--
+1.6.4.2
+
diff --git a/series.conf b/series.conf
index 524356e3b1..d0d6cc12c6 100644
--- a/series.conf
+++ b/series.conf
@@ -91,6 +91,7 @@
patches.suse/kvm-as-kmp
patches.suse/export-release_open_intent
patches.suse/export-security_inode_permission
+ patches.suse/export-sync_page_range
########################################################
# Bug workarounds for binutils