2005-04-17 05:20:36 +07:00
|
|
|
/*
|
2005-11-02 10:58:39 +07:00
|
|
|
* Copyright (c) 2000-2005 Silicon Graphics, Inc.
|
|
|
|
* All Rights Reserved.
|
2005-04-17 05:20:36 +07:00
|
|
|
*
|
2005-11-02 10:58:39 +07:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License as
|
2005-04-17 05:20:36 +07:00
|
|
|
* published by the Free Software Foundation.
|
|
|
|
*
|
2005-11-02 10:58:39 +07:00
|
|
|
* This program is distributed in the hope that it would be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
2005-04-17 05:20:36 +07:00
|
|
|
*
|
2005-11-02 10:58:39 +07:00
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write the Free Software Foundation,
|
|
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
2005-04-17 05:20:36 +07:00
|
|
|
*/
|
|
|
|
#include "xfs.h"
|
2013-10-23 06:36:05 +07:00
|
|
|
#include "xfs_shared.h"
|
2013-10-23 06:50:10 +07:00
|
|
|
#include "xfs_format.h"
|
|
|
|
#include "xfs_log_format.h"
|
|
|
|
#include "xfs_trans_resv.h"
|
2005-04-17 05:20:36 +07:00
|
|
|
#include "xfs_mount.h"
|
|
|
|
#include "xfs_inode.h"
|
2013-10-23 06:50:10 +07:00
|
|
|
#include "xfs_trans.h"
|
2012-03-13 15:41:05 +07:00
|
|
|
#include "xfs_inode_item.h"
|
2005-11-02 10:38:42 +07:00
|
|
|
#include "xfs_alloc.h"
|
2005-04-17 05:20:36 +07:00
|
|
|
#include "xfs_error.h"
|
|
|
|
#include "xfs_iomap.h"
|
2009-12-15 06:14:59 +07:00
|
|
|
#include "xfs_trace.h"
|
2010-03-05 09:00:42 +07:00
|
|
|
#include "xfs_bmap.h"
|
2013-08-12 17:49:42 +07:00
|
|
|
#include "xfs_bmap_util.h"
|
2013-10-23 06:51:50 +07:00
|
|
|
#include "xfs_bmap_btree.h"
|
include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h
percpu.h is included by sched.h and module.h and thus ends up being
included when building most .c files. percpu.h includes slab.h which
in turn includes gfp.h making everything defined by the two files
universally available and complicating inclusion dependencies.
percpu.h -> slab.h dependency is about to be removed. Prepare for
this change by updating users of gfp and slab facilities include those
headers directly instead of assuming availability. As this conversion
needs to touch large number of source files, the following script is
used as the basis of conversion.
http://userweb.kernel.org/~tj/misc/slabh-sweep.py
The script does the followings.
* Scan files for gfp and slab usages and update includes such that
only the necessary includes are there. ie. if only gfp is used,
gfp.h, if slab is used, slab.h.
* When the script inserts a new include, it looks at the include
blocks and try to put the new include such that its order conforms
to its surrounding. It's put in the include block which contains
core kernel includes, in the same order that the rest are ordered -
alphabetical, Christmas tree, rev-Xmas-tree or at the end if there
doesn't seem to be any matching order.
* If the script can't find a place to put a new include (mostly
because the file doesn't have fitting include block), it prints out
an error message indicating which .h file needs to be added to the
file.
The conversion was done in the following steps.
1. The initial automatic conversion of all .c files updated slightly
over 4000 files, deleting around 700 includes and adding ~480 gfp.h
and ~3000 slab.h inclusions. The script emitted errors for ~400
files.
2. Each error was manually checked. Some didn't need the inclusion,
some needed manual addition while adding it to implementation .h or
embedding .c file was more appropriate for others. This step added
inclusions to around 150 files.
3. The script was run again and the output was compared to the edits
from #2 to make sure no file was left behind.
4. Several build tests were done and a couple of problems were fixed.
e.g. lib/decompress_*.c used malloc/free() wrappers around slab
APIs requiring slab.h to be added manually.
5. The script was run on all .h files but without automatically
editing them as sprinkling gfp.h and slab.h inclusions around .h
files could easily lead to inclusion dependency hell. Most gfp.h
inclusion directives were ignored as stuff from gfp.h was usually
wildly available and often used in preprocessor macros. Each
slab.h inclusion directive was examined and added manually as
necessary.
6. percpu.h was updated not to include slab.h.
7. Build test were done on the following configurations and failures
were fixed. CONFIG_GCOV_KERNEL was turned off for all tests (as my
distributed build env didn't work with gcov compiles) and a few
more options had to be turned off depending on archs to make things
build (like ipr on powerpc/64 which failed due to missing writeq).
* x86 and x86_64 UP and SMP allmodconfig and a custom test config.
* powerpc and powerpc64 SMP allmodconfig
* sparc and sparc64 SMP allmodconfig
* ia64 SMP allmodconfig
* s390 SMP allmodconfig
* alpha SMP allmodconfig
* um on x86_64 SMP allmodconfig
8. percpu.h modifications were reverted so that it could be applied as
a separate patch and serve as bisection point.
Given the fact that I had only a couple of failures from tests on step
6, I'm fairly confident about the coverage of this conversion patch.
If there is a breakage, it's likely to be something in one of the arch
headers which should be easily discoverable easily on most builds of
the specific arch.
Signed-off-by: Tejun Heo <tj@kernel.org>
Guess-its-ok-by: Christoph Lameter <cl@linux-foundation.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Lee Schermerhorn <Lee.Schermerhorn@hp.com>
2010-03-24 15:04:11 +07:00
|
|
|
#include <linux/gfp.h>
|
2005-04-17 05:20:36 +07:00
|
|
|
#include <linux/mpage.h>
|
2006-01-11 16:48:14 +07:00
|
|
|
#include <linux/pagevec.h>
|
2005-04-17 05:20:36 +07:00
|
|
|
#include <linux/writeback.h>
|
|
|
|
|
2009-12-15 06:14:59 +07:00
|
|
|
void
|
2006-03-14 09:26:27 +07:00
|
|
|
xfs_count_page_state(
|
|
|
|
struct page *page,
|
|
|
|
int *delalloc,
|
|
|
|
int *unwritten)
|
|
|
|
{
|
|
|
|
struct buffer_head *bh, *head;
|
|
|
|
|
2010-06-24 06:46:01 +07:00
|
|
|
*delalloc = *unwritten = 0;
|
2006-03-14 09:26:27 +07:00
|
|
|
|
|
|
|
bh = head = page_buffers(page);
|
|
|
|
do {
|
2010-06-24 06:46:01 +07:00
|
|
|
if (buffer_unwritten(bh))
|
2006-03-14 09:26:27 +07:00
|
|
|
(*unwritten) = 1;
|
|
|
|
else if (buffer_delay(bh))
|
|
|
|
(*delalloc) = 1;
|
|
|
|
} while ((bh = bh->b_this_page) != head);
|
|
|
|
}
|
|
|
|
|
2007-09-14 12:23:17 +07:00
|
|
|
STATIC struct block_device *
|
|
|
|
xfs_find_bdev_for_inode(
|
2010-04-28 19:28:52 +07:00
|
|
|
struct inode *inode)
|
2007-09-14 12:23:17 +07:00
|
|
|
{
|
2010-04-28 19:28:52 +07:00
|
|
|
struct xfs_inode *ip = XFS_I(inode);
|
2007-09-14 12:23:17 +07:00
|
|
|
struct xfs_mount *mp = ip->i_mount;
|
|
|
|
|
2007-11-23 12:29:42 +07:00
|
|
|
if (XFS_IS_REALTIME_INODE(ip))
|
2007-09-14 12:23:17 +07:00
|
|
|
return mp->m_rtdev_targp->bt_bdev;
|
|
|
|
else
|
|
|
|
return mp->m_ddev_targp->bt_bdev;
|
|
|
|
}
|
|
|
|
|
2006-01-11 11:40:13 +07:00
|
|
|
/*
|
|
|
|
* We're now finished for good with this ioend structure.
|
|
|
|
* Update the page state via the associated buffer_heads,
|
|
|
|
* release holds on the inode and bio, and finally free
|
|
|
|
* up memory. Do not use the ioend after this.
|
|
|
|
*/
|
2005-09-02 13:58:49 +07:00
|
|
|
STATIC void
|
|
|
|
xfs_destroy_ioend(
|
|
|
|
xfs_ioend_t *ioend)
|
|
|
|
{
|
2006-01-11 11:40:13 +07:00
|
|
|
struct buffer_head *bh, *next;
|
|
|
|
|
|
|
|
for (bh = ioend->io_buffer_head; bh; bh = next) {
|
|
|
|
next = bh->b_private;
|
2006-06-09 11:58:38 +07:00
|
|
|
bh->b_end_io(bh, !ioend->io_error);
|
2006-01-11 11:40:13 +07:00
|
|
|
}
|
2008-12-03 18:20:38 +07:00
|
|
|
|
2005-09-02 13:58:49 +07:00
|
|
|
mempool_free(ioend, xfs_ioend_pool);
|
|
|
|
}
|
|
|
|
|
2011-08-23 15:28:11 +07:00
|
|
|
/*
|
|
|
|
* Fast and loose check if this write could update the on-disk inode size.
|
|
|
|
*/
|
|
|
|
static inline bool xfs_ioend_is_append(struct xfs_ioend *ioend)
|
|
|
|
{
|
|
|
|
return ioend->io_offset + ioend->io_size >
|
|
|
|
XFS_I(ioend->io_inode)->i_d.di_size;
|
|
|
|
}
|
|
|
|
|
2012-03-13 15:41:05 +07:00
|
|
|
STATIC int
|
|
|
|
xfs_setfilesize_trans_alloc(
|
|
|
|
struct xfs_ioend *ioend)
|
|
|
|
{
|
|
|
|
struct xfs_mount *mp = XFS_I(ioend->io_inode)->i_mount;
|
|
|
|
struct xfs_trans *tp;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS);
|
|
|
|
|
2013-08-12 17:49:59 +07:00
|
|
|
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_fsyncts, 0, 0);
|
2012-03-13 15:41:05 +07:00
|
|
|
if (error) {
|
2015-06-04 10:47:56 +07:00
|
|
|
xfs_trans_cancel(tp);
|
2012-03-13 15:41:05 +07:00
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
ioend->io_append_trans = tp;
|
|
|
|
|
2012-06-12 21:20:39 +07:00
|
|
|
/*
|
2012-11-28 09:01:00 +07:00
|
|
|
* We may pass freeze protection with a transaction. So tell lockdep
|
2012-06-12 21:20:39 +07:00
|
|
|
* we released it.
|
|
|
|
*/
|
2015-07-20 04:48:20 +07:00
|
|
|
__sb_writers_release(ioend->io_inode->i_sb, SB_FREEZE_FS);
|
2012-03-13 15:41:05 +07:00
|
|
|
/*
|
|
|
|
* We hand off the transaction to the completion thread now, so
|
|
|
|
* clear the flag here.
|
|
|
|
*/
|
|
|
|
current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
[XFS] Fix to prevent the notorious 'NULL files' problem after a crash.
The problem that has been addressed is that of synchronising updates of
the file size with writes that extend a file. Without the fix the update
of a file's size, as a result of a write beyond eof, is independent of
when the cached data is flushed to disk. Often the file size update would
be written to the filesystem log before the data is flushed to disk. When
a system crashes between these two events and the filesystem log is
replayed on mount the file's size will be set but since the contents never
made it to disk the file is full of holes. If some of the cached data was
flushed to disk then it may just be a section of the file at the end that
has holes.
There are existing fixes to help alleviate this problem, particularly in
the case where a file has been truncated, that force cached data to be
flushed to disk when the file is closed. If the system crashes while the
file(s) are still open then this flushing will never occur.
The fix that we have implemented is to introduce a second file size,
called the in-memory file size, that represents the current file size as
viewed by the user. The existing file size, called the on-disk file size,
is the one that get's written to the filesystem log and we only update it
when it is safe to do so. When we write to a file beyond eof we only
update the in- memory file size in the write operation. Later when the I/O
operation, that flushes the cached data to disk completes, an I/O
completion routine will update the on-disk file size. The on-disk file
size will be updated to the maximum offset of the I/O or to the value of
the in-memory file size if the I/O includes eof.
SGI-PV: 958522
SGI-Modid: xfs-linux-melb:xfs-kern:28322a
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Signed-off-by: David Chinner <dgc@sgi.com>
Signed-off-by: Tim Shimmin <tes@sgi.com>
2007-05-08 10:49:46 +07:00
|
|
|
/*
|
2011-12-19 03:00:12 +07:00
|
|
|
* Update on-disk file size now that data has been written to disk.
|
[XFS] Fix to prevent the notorious 'NULL files' problem after a crash.
The problem that has been addressed is that of synchronising updates of
the file size with writes that extend a file. Without the fix the update
of a file's size, as a result of a write beyond eof, is independent of
when the cached data is flushed to disk. Often the file size update would
be written to the filesystem log before the data is flushed to disk. When
a system crashes between these two events and the filesystem log is
replayed on mount the file's size will be set but since the contents never
made it to disk the file is full of holes. If some of the cached data was
flushed to disk then it may just be a section of the file at the end that
has holes.
There are existing fixes to help alleviate this problem, particularly in
the case where a file has been truncated, that force cached data to be
flushed to disk when the file is closed. If the system crashes while the
file(s) are still open then this flushing will never occur.
The fix that we have implemented is to introduce a second file size,
called the in-memory file size, that represents the current file size as
viewed by the user. The existing file size, called the on-disk file size,
is the one that get's written to the filesystem log and we only update it
when it is safe to do so. When we write to a file beyond eof we only
update the in- memory file size in the write operation. Later when the I/O
operation, that flushes the cached data to disk completes, an I/O
completion routine will update the on-disk file size. The on-disk file
size will be updated to the maximum offset of the I/O or to the value of
the in-memory file size if the I/O includes eof.
SGI-PV: 958522
SGI-Modid: xfs-linux-melb:xfs-kern:28322a
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Signed-off-by: David Chinner <dgc@sgi.com>
Signed-off-by: Tim Shimmin <tes@sgi.com>
2007-05-08 10:49:46 +07:00
|
|
|
*/
|
2012-03-13 15:41:05 +07:00
|
|
|
STATIC int
|
[XFS] Fix to prevent the notorious 'NULL files' problem after a crash.
The problem that has been addressed is that of synchronising updates of
the file size with writes that extend a file. Without the fix the update
of a file's size, as a result of a write beyond eof, is independent of
when the cached data is flushed to disk. Often the file size update would
be written to the filesystem log before the data is flushed to disk. When
a system crashes between these two events and the filesystem log is
replayed on mount the file's size will be set but since the contents never
made it to disk the file is full of holes. If some of the cached data was
flushed to disk then it may just be a section of the file at the end that
has holes.
There are existing fixes to help alleviate this problem, particularly in
the case where a file has been truncated, that force cached data to be
flushed to disk when the file is closed. If the system crashes while the
file(s) are still open then this flushing will never occur.
The fix that we have implemented is to introduce a second file size,
called the in-memory file size, that represents the current file size as
viewed by the user. The existing file size, called the on-disk file size,
is the one that get's written to the filesystem log and we only update it
when it is safe to do so. When we write to a file beyond eof we only
update the in- memory file size in the write operation. Later when the I/O
operation, that flushes the cached data to disk completes, an I/O
completion routine will update the on-disk file size. The on-disk file
size will be updated to the maximum offset of the I/O or to the value of
the in-memory file size if the I/O includes eof.
SGI-PV: 958522
SGI-Modid: xfs-linux-melb:xfs-kern:28322a
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Signed-off-by: David Chinner <dgc@sgi.com>
Signed-off-by: Tim Shimmin <tes@sgi.com>
2007-05-08 10:49:46 +07:00
|
|
|
xfs_setfilesize(
|
2015-02-02 06:02:09 +07:00
|
|
|
struct xfs_inode *ip,
|
|
|
|
struct xfs_trans *tp,
|
|
|
|
xfs_off_t offset,
|
|
|
|
size_t size)
|
[XFS] Fix to prevent the notorious 'NULL files' problem after a crash.
The problem that has been addressed is that of synchronising updates of
the file size with writes that extend a file. Without the fix the update
of a file's size, as a result of a write beyond eof, is independent of
when the cached data is flushed to disk. Often the file size update would
be written to the filesystem log before the data is flushed to disk. When
a system crashes between these two events and the filesystem log is
replayed on mount the file's size will be set but since the contents never
made it to disk the file is full of holes. If some of the cached data was
flushed to disk then it may just be a section of the file at the end that
has holes.
There are existing fixes to help alleviate this problem, particularly in
the case where a file has been truncated, that force cached data to be
flushed to disk when the file is closed. If the system crashes while the
file(s) are still open then this flushing will never occur.
The fix that we have implemented is to introduce a second file size,
called the in-memory file size, that represents the current file size as
viewed by the user. The existing file size, called the on-disk file size,
is the one that get's written to the filesystem log and we only update it
when it is safe to do so. When we write to a file beyond eof we only
update the in- memory file size in the write operation. Later when the I/O
operation, that flushes the cached data to disk completes, an I/O
completion routine will update the on-disk file size. The on-disk file
size will be updated to the maximum offset of the I/O or to the value of
the in-memory file size if the I/O includes eof.
SGI-PV: 958522
SGI-Modid: xfs-linux-melb:xfs-kern:28322a
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Signed-off-by: David Chinner <dgc@sgi.com>
Signed-off-by: Tim Shimmin <tes@sgi.com>
2007-05-08 10:49:46 +07:00
|
|
|
{
|
|
|
|
xfs_fsize_t isize;
|
|
|
|
|
2012-02-29 16:53:48 +07:00
|
|
|
xfs_ilock(ip, XFS_ILOCK_EXCL);
|
2015-02-02 06:02:09 +07:00
|
|
|
isize = xfs_new_eof(ip, offset + size);
|
2012-03-13 15:41:05 +07:00
|
|
|
if (!isize) {
|
|
|
|
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
2015-06-04 10:47:56 +07:00
|
|
|
xfs_trans_cancel(tp);
|
2012-03-13 15:41:05 +07:00
|
|
|
return 0;
|
[XFS] Fix to prevent the notorious 'NULL files' problem after a crash.
The problem that has been addressed is that of synchronising updates of
the file size with writes that extend a file. Without the fix the update
of a file's size, as a result of a write beyond eof, is independent of
when the cached data is flushed to disk. Often the file size update would
be written to the filesystem log before the data is flushed to disk. When
a system crashes between these two events and the filesystem log is
replayed on mount the file's size will be set but since the contents never
made it to disk the file is full of holes. If some of the cached data was
flushed to disk then it may just be a section of the file at the end that
has holes.
There are existing fixes to help alleviate this problem, particularly in
the case where a file has been truncated, that force cached data to be
flushed to disk when the file is closed. If the system crashes while the
file(s) are still open then this flushing will never occur.
The fix that we have implemented is to introduce a second file size,
called the in-memory file size, that represents the current file size as
viewed by the user. The existing file size, called the on-disk file size,
is the one that get's written to the filesystem log and we only update it
when it is safe to do so. When we write to a file beyond eof we only
update the in- memory file size in the write operation. Later when the I/O
operation, that flushes the cached data to disk completes, an I/O
completion routine will update the on-disk file size. The on-disk file
size will be updated to the maximum offset of the I/O or to the value of
the in-memory file size if the I/O includes eof.
SGI-PV: 958522
SGI-Modid: xfs-linux-melb:xfs-kern:28322a
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Signed-off-by: David Chinner <dgc@sgi.com>
Signed-off-by: Tim Shimmin <tes@sgi.com>
2007-05-08 10:49:46 +07:00
|
|
|
}
|
|
|
|
|
2015-02-02 06:02:09 +07:00
|
|
|
trace_xfs_setfilesize(ip, offset, size);
|
2012-03-13 15:41:05 +07:00
|
|
|
|
|
|
|
ip->i_d.di_size = isize;
|
|
|
|
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
|
|
|
|
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
|
|
|
|
|
2015-06-04 10:48:08 +07:00
|
|
|
return xfs_trans_commit(tp);
|
2010-02-17 12:36:29 +07:00
|
|
|
}
|
|
|
|
|
2015-02-02 06:02:09 +07:00
|
|
|
STATIC int
|
|
|
|
xfs_setfilesize_ioend(
|
|
|
|
struct xfs_ioend *ioend)
|
|
|
|
{
|
|
|
|
struct xfs_inode *ip = XFS_I(ioend->io_inode);
|
|
|
|
struct xfs_trans *tp = ioend->io_append_trans;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The transaction may have been allocated in the I/O submission thread,
|
|
|
|
* thus we need to mark ourselves as being in a transaction manually.
|
|
|
|
* Similarly for freeze protection.
|
|
|
|
*/
|
|
|
|
current_set_flags_nested(&tp->t_pflags, PF_FSTRANS);
|
2015-07-20 04:48:20 +07:00
|
|
|
__sb_writers_acquired(VFS_I(ip)->i_sb, SB_FREEZE_FS);
|
2015-02-02 06:02:09 +07:00
|
|
|
|
2015-10-12 11:28:39 +07:00
|
|
|
/* we abort the update if there was an IO error */
|
|
|
|
if (ioend->io_error) {
|
|
|
|
xfs_trans_cancel(tp);
|
|
|
|
return ioend->io_error;
|
|
|
|
}
|
|
|
|
|
2015-02-02 06:02:09 +07:00
|
|
|
return xfs_setfilesize(ip, tp, ioend->io_offset, ioend->io_size);
|
|
|
|
}
|
|
|
|
|
2010-02-17 12:36:29 +07:00
|
|
|
/*
|
2010-07-19 04:17:11 +07:00
|
|
|
* Schedule IO completion handling on the final put of an ioend.
|
2011-08-23 15:28:11 +07:00
|
|
|
*
|
|
|
|
* If there is no work to do we might as well call it a day and free the
|
|
|
|
* ioend right now.
|
2010-02-17 12:36:29 +07:00
|
|
|
*/
|
|
|
|
STATIC void
|
|
|
|
xfs_finish_ioend(
|
2010-07-19 04:17:11 +07:00
|
|
|
struct xfs_ioend *ioend)
|
2010-02-17 12:36:29 +07:00
|
|
|
{
|
|
|
|
if (atomic_dec_and_test(&ioend->io_remaining)) {
|
2012-02-29 16:53:48 +07:00
|
|
|
struct xfs_mount *mp = XFS_I(ioend->io_inode)->i_mount;
|
|
|
|
|
2012-05-23 03:56:21 +07:00
|
|
|
if (ioend->io_type == XFS_IO_UNWRITTEN)
|
2012-02-29 16:53:48 +07:00
|
|
|
queue_work(mp->m_unwritten_workqueue, &ioend->io_work);
|
2015-02-02 06:02:09 +07:00
|
|
|
else if (ioend->io_append_trans)
|
2012-02-29 16:53:48 +07:00
|
|
|
queue_work(mp->m_data_workqueue, &ioend->io_work);
|
2011-08-23 15:28:11 +07:00
|
|
|
else
|
|
|
|
xfs_destroy_ioend(ioend);
|
2010-02-17 12:36:29 +07:00
|
|
|
}
|
[XFS] Fix to prevent the notorious 'NULL files' problem after a crash.
The problem that has been addressed is that of synchronising updates of
the file size with writes that extend a file. Without the fix the update
of a file's size, as a result of a write beyond eof, is independent of
when the cached data is flushed to disk. Often the file size update would
be written to the filesystem log before the data is flushed to disk. When
a system crashes between these two events and the filesystem log is
replayed on mount the file's size will be set but since the contents never
made it to disk the file is full of holes. If some of the cached data was
flushed to disk then it may just be a section of the file at the end that
has holes.
There are existing fixes to help alleviate this problem, particularly in
the case where a file has been truncated, that force cached data to be
flushed to disk when the file is closed. If the system crashes while the
file(s) are still open then this flushing will never occur.
The fix that we have implemented is to introduce a second file size,
called the in-memory file size, that represents the current file size as
viewed by the user. The existing file size, called the on-disk file size,
is the one that get's written to the filesystem log and we only update it
when it is safe to do so. When we write to a file beyond eof we only
update the in- memory file size in the write operation. Later when the I/O
operation, that flushes the cached data to disk completes, an I/O
completion routine will update the on-disk file size. The on-disk file
size will be updated to the maximum offset of the I/O or to the value of
the in-memory file size if the I/O includes eof.
SGI-PV: 958522
SGI-Modid: xfs-linux-melb:xfs-kern:28322a
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Signed-off-by: David Chinner <dgc@sgi.com>
Signed-off-by: Tim Shimmin <tes@sgi.com>
2007-05-08 10:49:46 +07:00
|
|
|
}
|
|
|
|
|
2005-09-02 13:58:49 +07:00
|
|
|
/*
|
2009-10-30 16:11:47 +07:00
|
|
|
* IO write completion.
|
2006-01-11 11:40:13 +07:00
|
|
|
*/
|
|
|
|
STATIC void
|
2009-10-30 16:11:47 +07:00
|
|
|
xfs_end_io(
|
2010-02-17 12:36:29 +07:00
|
|
|
struct work_struct *work)
|
2005-09-02 13:58:49 +07:00
|
|
|
{
|
2010-02-17 12:36:29 +07:00
|
|
|
xfs_ioend_t *ioend = container_of(work, xfs_ioend_t, io_work);
|
|
|
|
struct xfs_inode *ip = XFS_I(ioend->io_inode);
|
2010-03-04 07:57:09 +07:00
|
|
|
int error = 0;
|
[XFS] Fix to prevent the notorious 'NULL files' problem after a crash.
The problem that has been addressed is that of synchronising updates of
the file size with writes that extend a file. Without the fix the update
of a file's size, as a result of a write beyond eof, is independent of
when the cached data is flushed to disk. Often the file size update would
be written to the filesystem log before the data is flushed to disk. When
a system crashes between these two events and the filesystem log is
replayed on mount the file's size will be set but since the contents never
made it to disk the file is full of holes. If some of the cached data was
flushed to disk then it may just be a section of the file at the end that
has holes.
There are existing fixes to help alleviate this problem, particularly in
the case where a file has been truncated, that force cached data to be
flushed to disk when the file is closed. If the system crashes while the
file(s) are still open then this flushing will never occur.
The fix that we have implemented is to introduce a second file size,
called the in-memory file size, that represents the current file size as
viewed by the user. The existing file size, called the on-disk file size,
is the one that get's written to the filesystem log and we only update it
when it is safe to do so. When we write to a file beyond eof we only
update the in- memory file size in the write operation. Later when the I/O
operation, that flushes the cached data to disk completes, an I/O
completion routine will update the on-disk file size. The on-disk file
size will be updated to the maximum offset of the I/O or to the value of
the in-memory file size if the I/O includes eof.
SGI-PV: 958522
SGI-Modid: xfs-linux-melb:xfs-kern:28322a
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Signed-off-by: David Chinner <dgc@sgi.com>
Signed-off-by: Tim Shimmin <tes@sgi.com>
2007-05-08 10:49:46 +07:00
|
|
|
|
2011-08-24 12:59:25 +07:00
|
|
|
if (XFS_FORCED_SHUTDOWN(ip->i_mount)) {
|
2011-11-08 15:56:15 +07:00
|
|
|
ioend->io_error = -EIO;
|
2011-08-24 12:59:25 +07:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2009-10-30 16:11:47 +07:00
|
|
|
/*
|
|
|
|
* For unwritten extents we need to issue transactions to convert a
|
|
|
|
* range to normal written extens after the data I/O has finished.
|
2015-10-12 11:28:39 +07:00
|
|
|
* Detecting and handling completion IO errors is done individually
|
|
|
|
* for each case as different cleanup operations need to be performed
|
|
|
|
* on error.
|
2009-10-30 16:11:47 +07:00
|
|
|
*/
|
2012-05-23 03:56:21 +07:00
|
|
|
if (ioend->io_type == XFS_IO_UNWRITTEN) {
|
2015-10-12 11:28:39 +07:00
|
|
|
if (ioend->io_error)
|
|
|
|
goto done;
|
2012-11-28 09:01:00 +07:00
|
|
|
error = xfs_iomap_write_unwritten(ip, ioend->io_offset,
|
|
|
|
ioend->io_size);
|
2012-03-13 15:41:05 +07:00
|
|
|
} else if (ioend->io_append_trans) {
|
2015-02-02 06:02:09 +07:00
|
|
|
error = xfs_setfilesize_ioend(ioend);
|
2012-02-29 16:53:50 +07:00
|
|
|
} else {
|
2012-03-13 15:41:05 +07:00
|
|
|
ASSERT(!xfs_ioend_is_append(ioend));
|
2009-10-30 16:11:47 +07:00
|
|
|
}
|
[XFS] Fix to prevent the notorious 'NULL files' problem after a crash.
The problem that has been addressed is that of synchronising updates of
the file size with writes that extend a file. Without the fix the update
of a file's size, as a result of a write beyond eof, is independent of
when the cached data is flushed to disk. Often the file size update would
be written to the filesystem log before the data is flushed to disk. When
a system crashes between these two events and the filesystem log is
replayed on mount the file's size will be set but since the contents never
made it to disk the file is full of holes. If some of the cached data was
flushed to disk then it may just be a section of the file at the end that
has holes.
There are existing fixes to help alleviate this problem, particularly in
the case where a file has been truncated, that force cached data to be
flushed to disk when the file is closed. If the system crashes while the
file(s) are still open then this flushing will never occur.
The fix that we have implemented is to introduce a second file size,
called the in-memory file size, that represents the current file size as
viewed by the user. The existing file size, called the on-disk file size,
is the one that get's written to the filesystem log and we only update it
when it is safe to do so. When we write to a file beyond eof we only
update the in- memory file size in the write operation. Later when the I/O
operation, that flushes the cached data to disk completes, an I/O
completion routine will update the on-disk file size. The on-disk file
size will be updated to the maximum offset of the I/O or to the value of
the in-memory file size if the I/O includes eof.
SGI-PV: 958522
SGI-Modid: xfs-linux-melb:xfs-kern:28322a
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Signed-off-by: David Chinner <dgc@sgi.com>
Signed-off-by: Tim Shimmin <tes@sgi.com>
2007-05-08 10:49:46 +07:00
|
|
|
|
2011-08-24 12:59:25 +07:00
|
|
|
done:
|
2012-11-28 09:01:00 +07:00
|
|
|
if (error)
|
2014-06-25 11:58:08 +07:00
|
|
|
ioend->io_error = error;
|
2012-02-29 16:53:48 +07:00
|
|
|
xfs_destroy_ioend(ioend);
|
2009-04-06 23:42:11 +07:00
|
|
|
}
|
|
|
|
|
2005-09-02 13:58:49 +07:00
|
|
|
/*
|
|
|
|
* Allocate and initialise an IO completion structure.
|
|
|
|
* We need to track unwritten extent write completion here initially.
|
|
|
|
* We'll need to extend this for updating the ondisk inode size later
|
|
|
|
* (vs. incore size).
|
|
|
|
*/
|
|
|
|
STATIC xfs_ioend_t *
|
|
|
|
xfs_alloc_ioend(
|
2006-01-11 11:40:13 +07:00
|
|
|
struct inode *inode,
|
|
|
|
unsigned int type)
|
2005-09-02 13:58:49 +07:00
|
|
|
{
|
|
|
|
xfs_ioend_t *ioend;
|
|
|
|
|
|
|
|
ioend = mempool_alloc(xfs_ioend_pool, GFP_NOFS);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set the count to 1 initially, which will prevent an I/O
|
|
|
|
* completion callback from happening before we have started
|
|
|
|
* all the I/O from calling the completion routine too early.
|
|
|
|
*/
|
|
|
|
atomic_set(&ioend->io_remaining, 1);
|
2006-06-09 11:58:38 +07:00
|
|
|
ioend->io_error = 0;
|
2006-01-11 11:40:13 +07:00
|
|
|
ioend->io_list = NULL;
|
|
|
|
ioend->io_type = type;
|
2007-08-29 08:46:28 +07:00
|
|
|
ioend->io_inode = inode;
|
2005-09-05 05:23:35 +07:00
|
|
|
ioend->io_buffer_head = NULL;
|
2006-01-11 11:40:13 +07:00
|
|
|
ioend->io_buffer_tail = NULL;
|
2005-09-02 13:58:49 +07:00
|
|
|
ioend->io_offset = 0;
|
|
|
|
ioend->io_size = 0;
|
2012-03-13 15:41:05 +07:00
|
|
|
ioend->io_append_trans = NULL;
|
2005-09-02 13:58:49 +07:00
|
|
|
|
2009-10-30 16:11:47 +07:00
|
|
|
INIT_WORK(&ioend->io_work, xfs_end_io);
|
2005-09-02 13:58:49 +07:00
|
|
|
return ioend;
|
|
|
|
}
|
|
|
|
|
2005-04-17 05:20:36 +07:00
|
|
|
STATIC int
|
|
|
|
xfs_map_blocks(
|
|
|
|
struct inode *inode,
|
|
|
|
loff_t offset,
|
2010-04-28 19:28:56 +07:00
|
|
|
struct xfs_bmbt_irec *imap,
|
2010-12-10 15:42:20 +07:00
|
|
|
int type,
|
|
|
|
int nonblocking)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
2010-12-10 15:42:20 +07:00
|
|
|
struct xfs_inode *ip = XFS_I(inode);
|
|
|
|
struct xfs_mount *mp = ip->i_mount;
|
2010-12-10 15:42:22 +07:00
|
|
|
ssize_t count = 1 << inode->i_blkbits;
|
2010-12-10 15:42:20 +07:00
|
|
|
xfs_fileoff_t offset_fsb, end_fsb;
|
|
|
|
int error = 0;
|
|
|
|
int bmapi_flags = XFS_BMAPI_ENTIRE;
|
|
|
|
int nimaps = 1;
|
|
|
|
|
|
|
|
if (XFS_FORCED_SHUTDOWN(mp))
|
2014-06-22 12:04:54 +07:00
|
|
|
return -EIO;
|
2010-12-10 15:42:20 +07:00
|
|
|
|
2012-05-23 03:56:21 +07:00
|
|
|
if (type == XFS_IO_UNWRITTEN)
|
2010-12-10 15:42:20 +07:00
|
|
|
bmapi_flags |= XFS_BMAPI_IGSTATE;
|
2010-12-10 15:42:21 +07:00
|
|
|
|
|
|
|
if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) {
|
|
|
|
if (nonblocking)
|
2014-06-22 12:04:54 +07:00
|
|
|
return -EAGAIN;
|
2010-12-10 15:42:21 +07:00
|
|
|
xfs_ilock(ip, XFS_ILOCK_SHARED);
|
2010-12-10 15:42:20 +07:00
|
|
|
}
|
|
|
|
|
2010-12-10 15:42:21 +07:00
|
|
|
ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE ||
|
|
|
|
(ip->i_df.if_flags & XFS_IFEXTENTS));
|
2012-06-08 12:44:53 +07:00
|
|
|
ASSERT(offset <= mp->m_super->s_maxbytes);
|
2010-12-10 15:42:21 +07:00
|
|
|
|
2012-06-08 12:44:53 +07:00
|
|
|
if (offset + count > mp->m_super->s_maxbytes)
|
|
|
|
count = mp->m_super->s_maxbytes - offset;
|
2010-12-10 15:42:20 +07:00
|
|
|
end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count);
|
|
|
|
offset_fsb = XFS_B_TO_FSBT(mp, offset);
|
2011-09-19 03:40:45 +07:00
|
|
|
error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb,
|
|
|
|
imap, &nimaps, bmapi_flags);
|
2010-12-10 15:42:21 +07:00
|
|
|
xfs_iunlock(ip, XFS_ILOCK_SHARED);
|
2010-12-10 15:42:20 +07:00
|
|
|
|
2010-12-10 15:42:21 +07:00
|
|
|
if (error)
|
2014-06-25 11:58:08 +07:00
|
|
|
return error;
|
2010-12-10 15:42:20 +07:00
|
|
|
|
2012-05-23 03:56:21 +07:00
|
|
|
if (type == XFS_IO_DELALLOC &&
|
2010-12-10 15:42:21 +07:00
|
|
|
(!nimaps || isnullstartblock(imap->br_startblock))) {
|
2013-09-29 17:56:04 +07:00
|
|
|
error = xfs_iomap_write_allocate(ip, offset, imap);
|
2010-12-10 15:42:20 +07:00
|
|
|
if (!error)
|
|
|
|
trace_xfs_map_blocks_alloc(ip, offset, count, type, imap);
|
2014-06-25 11:58:08 +07:00
|
|
|
return error;
|
2010-12-10 15:42:20 +07:00
|
|
|
}
|
|
|
|
|
2010-12-10 15:42:21 +07:00
|
|
|
#ifdef DEBUG
|
2012-05-23 03:56:21 +07:00
|
|
|
if (type == XFS_IO_UNWRITTEN) {
|
2010-12-10 15:42:21 +07:00
|
|
|
ASSERT(nimaps);
|
|
|
|
ASSERT(imap->br_startblock != HOLESTARTBLOCK);
|
|
|
|
ASSERT(imap->br_startblock != DELAYSTARTBLOCK);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
if (nimaps)
|
|
|
|
trace_xfs_map_blocks_found(ip, offset, count, type, imap);
|
|
|
|
return 0;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
2009-11-14 23:17:22 +07:00
|
|
|
STATIC int
|
2010-04-28 19:28:58 +07:00
|
|
|
xfs_imap_valid(
|
2010-04-28 19:28:54 +07:00
|
|
|
struct inode *inode,
|
2010-04-28 19:28:56 +07:00
|
|
|
struct xfs_bmbt_irec *imap,
|
2010-04-28 19:28:58 +07:00
|
|
|
xfs_off_t offset)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
2010-04-28 19:28:58 +07:00
|
|
|
offset >>= inode->i_blkbits;
|
2010-04-28 19:28:54 +07:00
|
|
|
|
2010-04-28 19:28:58 +07:00
|
|
|
return offset >= imap->br_startoff &&
|
|
|
|
offset < imap->br_startoff + imap->br_blockcount;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
2006-01-11 11:40:13 +07:00
|
|
|
/*
|
|
|
|
* BIO completion handler for buffered IO.
|
|
|
|
*/
|
2007-10-12 13:17:47 +07:00
|
|
|
STATIC void
|
2006-01-11 11:40:13 +07:00
|
|
|
xfs_end_bio(
|
2015-07-20 20:29:37 +07:00
|
|
|
struct bio *bio)
|
2006-01-11 11:40:13 +07:00
|
|
|
{
|
|
|
|
xfs_ioend_t *ioend = bio->bi_private;
|
|
|
|
|
2015-09-08 03:28:32 +07:00
|
|
|
if (!ioend->io_error)
|
|
|
|
ioend->io_error = bio->bi_error;
|
2006-01-11 11:40:13 +07:00
|
|
|
|
|
|
|
/* Toss bio and pass work off to an xfsdatad thread */
|
|
|
|
bio->bi_private = NULL;
|
|
|
|
bio->bi_end_io = NULL;
|
|
|
|
bio_put(bio);
|
2006-06-09 11:58:38 +07:00
|
|
|
|
2010-07-19 04:17:11 +07:00
|
|
|
xfs_finish_ioend(ioend);
|
2006-01-11 11:40:13 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
STATIC void
|
|
|
|
xfs_submit_ioend_bio(
|
2009-10-30 16:09:15 +07:00
|
|
|
struct writeback_control *wbc,
|
|
|
|
xfs_ioend_t *ioend,
|
|
|
|
struct bio *bio)
|
2006-01-11 11:40:13 +07:00
|
|
|
{
|
|
|
|
atomic_inc(&ioend->io_remaining);
|
|
|
|
bio->bi_private = ioend;
|
|
|
|
bio->bi_end_io = xfs_end_bio;
|
2011-03-09 17:56:30 +07:00
|
|
|
submit_bio(wbc->sync_mode == WB_SYNC_ALL ? WRITE_SYNC : WRITE, bio);
|
2006-01-11 11:40:13 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
STATIC struct bio *
|
|
|
|
xfs_alloc_ioend_bio(
|
|
|
|
struct buffer_head *bh)
|
|
|
|
{
|
2015-05-19 19:31:01 +07:00
|
|
|
struct bio *bio = bio_alloc(GFP_NOIO, BIO_MAX_PAGES);
|
2006-01-11 11:40:13 +07:00
|
|
|
|
|
|
|
ASSERT(bio->bi_private == NULL);
|
2013-10-12 05:44:27 +07:00
|
|
|
bio->bi_iter.bi_sector = bh->b_blocknr * (bh->b_size >> 9);
|
2006-01-11 11:40:13 +07:00
|
|
|
bio->bi_bdev = bh->b_bdev;
|
|
|
|
return bio;
|
|
|
|
}
|
|
|
|
|
|
|
|
STATIC void
|
|
|
|
xfs_start_buffer_writeback(
|
|
|
|
struct buffer_head *bh)
|
|
|
|
{
|
|
|
|
ASSERT(buffer_mapped(bh));
|
|
|
|
ASSERT(buffer_locked(bh));
|
|
|
|
ASSERT(!buffer_delay(bh));
|
|
|
|
ASSERT(!buffer_unwritten(bh));
|
|
|
|
|
|
|
|
mark_buffer_async_write(bh);
|
|
|
|
set_buffer_uptodate(bh);
|
|
|
|
clear_buffer_dirty(bh);
|
|
|
|
}
|
|
|
|
|
|
|
|
STATIC void
|
|
|
|
xfs_start_page_writeback(
|
|
|
|
struct page *page,
|
|
|
|
int clear_dirty,
|
|
|
|
int buffers)
|
|
|
|
{
|
|
|
|
ASSERT(PageLocked(page));
|
|
|
|
ASSERT(!PageWriteback(page));
|
2014-09-23 12:36:27 +07:00
|
|
|
|
|
|
|
/*
|
|
|
|
* if the page was not fully cleaned, we need to ensure that the higher
|
|
|
|
* layers come back to it correctly. That means we need to keep the page
|
|
|
|
* dirty, and for WB_SYNC_ALL writeback we need to ensure the
|
|
|
|
* PAGECACHE_TAG_TOWRITE index mark is not removed so another attempt to
|
|
|
|
* write this page in this writeback sweep will be made.
|
|
|
|
*/
|
|
|
|
if (clear_dirty) {
|
2006-12-21 06:24:01 +07:00
|
|
|
clear_page_dirty_for_io(page);
|
2014-09-23 12:36:27 +07:00
|
|
|
set_page_writeback(page);
|
|
|
|
} else
|
|
|
|
set_page_writeback_keepwrite(page);
|
|
|
|
|
2006-01-11 11:40:13 +07:00
|
|
|
unlock_page(page);
|
2014-09-23 12:36:27 +07:00
|
|
|
|
2007-10-17 13:30:42 +07:00
|
|
|
/* If no buffers on the page are to be written, finish it here */
|
|
|
|
if (!buffers)
|
2006-01-11 11:40:13 +07:00
|
|
|
end_page_writeback(page);
|
|
|
|
}
|
|
|
|
|
2013-08-07 17:11:09 +07:00
|
|
|
static inline int xfs_bio_add_buffer(struct bio *bio, struct buffer_head *bh)
|
2006-01-11 11:40:13 +07:00
|
|
|
{
|
|
|
|
return bio_add_page(bio, bh->b_page, bh->b_size, bh_offset(bh));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2006-01-18 09:38:12 +07:00
|
|
|
* Submit all of the bios for all of the ioends we have saved up, covering the
|
|
|
|
* initial writepage page and also any probed pages.
|
|
|
|
*
|
|
|
|
* Because we may have multiple ioends spanning a page, we need to start
|
|
|
|
* writeback on all the buffers before we submit them for I/O. If we mark the
|
|
|
|
* buffers as we got, then we can end up with a page that only has buffers
|
|
|
|
* marked async write and I/O complete on can occur before we mark the other
|
|
|
|
* buffers async write.
|
|
|
|
*
|
|
|
|
* The end result of this is that we trip a bug in end_page_writeback() because
|
|
|
|
* we call it twice for the one page as the code in end_buffer_async_write()
|
|
|
|
* assumes that all buffers on the page are started at the same time.
|
|
|
|
*
|
|
|
|
* The fix is two passes across the ioend list - one to start writeback on the
|
2006-03-29 05:55:14 +07:00
|
|
|
* buffer_heads, and then submit them for I/O on the second pass.
|
xfs: fix broken error handling in xfs_vm_writepage
When we shut down the filesystem, it might first be detected in
writeback when we are allocating a inode size transaction. This
happens after we have moved all the pages into the writeback state
and unlocked them. Unfortunately, if we fail to set up the
transaction we then abort writeback and try to invalidate the
current page. This then triggers are BUG() in block_invalidatepage()
because we are trying to invalidate an unlocked page.
Fixing this is a bit of a chicken and egg problem - we can't
allocate the transaction until we've clustered all the pages into
the IO and we know the size of it (i.e. whether the last block of
the IO is beyond the current EOF or not). However, we don't want to
hold pages locked for long periods of time, especially while we lock
other pages to cluster them into the write.
To fix this, we need to make a clear delineation in writeback where
errors can only be handled by IO completion processing. That is,
once we have marked a page for writeback and unlocked it, we have to
report errors via IO completion because we've already started the
IO. We may not have submitted any IO, but we've changed the page
state to indicate that it is under IO so we must now use the IO
completion path to report errors.
To do this, add an error field to xfs_submit_ioend() to pass it the
error that occurred during the building on the ioend chain. When
this is non-zero, mark each ioend with the error and call
xfs_finish_ioend() directly rather than building bios. This will
immediately push the ioends through completion processing with the
error that has occurred.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-11-12 18:09:45 +07:00
|
|
|
*
|
|
|
|
* If @fail is non-zero, it means that we have a situation where some part of
|
|
|
|
* the submission process has failed after we have marked paged for writeback
|
|
|
|
* and unlocked them. In this situation, we need to fail the ioend chain rather
|
|
|
|
* than submit it to IO. This typically only happens on a filesystem shutdown.
|
2006-01-11 11:40:13 +07:00
|
|
|
*/
|
|
|
|
STATIC void
|
|
|
|
xfs_submit_ioend(
|
2009-10-30 16:09:15 +07:00
|
|
|
struct writeback_control *wbc,
|
xfs: fix broken error handling in xfs_vm_writepage
When we shut down the filesystem, it might first be detected in
writeback when we are allocating a inode size transaction. This
happens after we have moved all the pages into the writeback state
and unlocked them. Unfortunately, if we fail to set up the
transaction we then abort writeback and try to invalidate the
current page. This then triggers are BUG() in block_invalidatepage()
because we are trying to invalidate an unlocked page.
Fixing this is a bit of a chicken and egg problem - we can't
allocate the transaction until we've clustered all the pages into
the IO and we know the size of it (i.e. whether the last block of
the IO is beyond the current EOF or not). However, we don't want to
hold pages locked for long periods of time, especially while we lock
other pages to cluster them into the write.
To fix this, we need to make a clear delineation in writeback where
errors can only be handled by IO completion processing. That is,
once we have marked a page for writeback and unlocked it, we have to
report errors via IO completion because we've already started the
IO. We may not have submitted any IO, but we've changed the page
state to indicate that it is under IO so we must now use the IO
completion path to report errors.
To do this, add an error field to xfs_submit_ioend() to pass it the
error that occurred during the building on the ioend chain. When
this is non-zero, mark each ioend with the error and call
xfs_finish_ioend() directly rather than building bios. This will
immediately push the ioends through completion processing with the
error that has occurred.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-11-12 18:09:45 +07:00
|
|
|
xfs_ioend_t *ioend,
|
|
|
|
int fail)
|
2006-01-11 11:40:13 +07:00
|
|
|
{
|
2006-01-18 09:38:12 +07:00
|
|
|
xfs_ioend_t *head = ioend;
|
2006-01-11 11:40:13 +07:00
|
|
|
xfs_ioend_t *next;
|
|
|
|
struct buffer_head *bh;
|
|
|
|
struct bio *bio;
|
|
|
|
sector_t lastblock = 0;
|
|
|
|
|
2006-01-18 09:38:12 +07:00
|
|
|
/* Pass 1 - start writeback */
|
|
|
|
do {
|
|
|
|
next = ioend->io_list;
|
2010-12-10 15:42:17 +07:00
|
|
|
for (bh = ioend->io_buffer_head; bh; bh = bh->b_private)
|
2006-01-18 09:38:12 +07:00
|
|
|
xfs_start_buffer_writeback(bh);
|
|
|
|
} while ((ioend = next) != NULL);
|
|
|
|
|
|
|
|
/* Pass 2 - submit I/O */
|
|
|
|
ioend = head;
|
2006-01-11 11:40:13 +07:00
|
|
|
do {
|
|
|
|
next = ioend->io_list;
|
|
|
|
bio = NULL;
|
|
|
|
|
xfs: fix broken error handling in xfs_vm_writepage
When we shut down the filesystem, it might first be detected in
writeback when we are allocating a inode size transaction. This
happens after we have moved all the pages into the writeback state
and unlocked them. Unfortunately, if we fail to set up the
transaction we then abort writeback and try to invalidate the
current page. This then triggers are BUG() in block_invalidatepage()
because we are trying to invalidate an unlocked page.
Fixing this is a bit of a chicken and egg problem - we can't
allocate the transaction until we've clustered all the pages into
the IO and we know the size of it (i.e. whether the last block of
the IO is beyond the current EOF or not). However, we don't want to
hold pages locked for long periods of time, especially while we lock
other pages to cluster them into the write.
To fix this, we need to make a clear delineation in writeback where
errors can only be handled by IO completion processing. That is,
once we have marked a page for writeback and unlocked it, we have to
report errors via IO completion because we've already started the
IO. We may not have submitted any IO, but we've changed the page
state to indicate that it is under IO so we must now use the IO
completion path to report errors.
To do this, add an error field to xfs_submit_ioend() to pass it the
error that occurred during the building on the ioend chain. When
this is non-zero, mark each ioend with the error and call
xfs_finish_ioend() directly rather than building bios. This will
immediately push the ioends through completion processing with the
error that has occurred.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-11-12 18:09:45 +07:00
|
|
|
/*
|
|
|
|
* If we are failing the IO now, just mark the ioend with an
|
|
|
|
* error and finish it. This will run IO completion immediately
|
|
|
|
* as there is only one reference to the ioend at this point in
|
|
|
|
* time.
|
|
|
|
*/
|
|
|
|
if (fail) {
|
2014-06-25 11:58:08 +07:00
|
|
|
ioend->io_error = fail;
|
xfs: fix broken error handling in xfs_vm_writepage
When we shut down the filesystem, it might first be detected in
writeback when we are allocating a inode size transaction. This
happens after we have moved all the pages into the writeback state
and unlocked them. Unfortunately, if we fail to set up the
transaction we then abort writeback and try to invalidate the
current page. This then triggers are BUG() in block_invalidatepage()
because we are trying to invalidate an unlocked page.
Fixing this is a bit of a chicken and egg problem - we can't
allocate the transaction until we've clustered all the pages into
the IO and we know the size of it (i.e. whether the last block of
the IO is beyond the current EOF or not). However, we don't want to
hold pages locked for long periods of time, especially while we lock
other pages to cluster them into the write.
To fix this, we need to make a clear delineation in writeback where
errors can only be handled by IO completion processing. That is,
once we have marked a page for writeback and unlocked it, we have to
report errors via IO completion because we've already started the
IO. We may not have submitted any IO, but we've changed the page
state to indicate that it is under IO so we must now use the IO
completion path to report errors.
To do this, add an error field to xfs_submit_ioend() to pass it the
error that occurred during the building on the ioend chain. When
this is non-zero, mark each ioend with the error and call
xfs_finish_ioend() directly rather than building bios. This will
immediately push the ioends through completion processing with the
error that has occurred.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-11-12 18:09:45 +07:00
|
|
|
xfs_finish_ioend(ioend);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2006-01-11 11:40:13 +07:00
|
|
|
for (bh = ioend->io_buffer_head; bh; bh = bh->b_private) {
|
|
|
|
|
|
|
|
if (!bio) {
|
|
|
|
retry:
|
|
|
|
bio = xfs_alloc_ioend_bio(bh);
|
|
|
|
} else if (bh->b_blocknr != lastblock + 1) {
|
2009-10-30 16:09:15 +07:00
|
|
|
xfs_submit_ioend_bio(wbc, ioend, bio);
|
2006-01-11 11:40:13 +07:00
|
|
|
goto retry;
|
|
|
|
}
|
|
|
|
|
2013-08-07 17:11:09 +07:00
|
|
|
if (xfs_bio_add_buffer(bio, bh) != bh->b_size) {
|
2009-10-30 16:09:15 +07:00
|
|
|
xfs_submit_ioend_bio(wbc, ioend, bio);
|
2006-01-11 11:40:13 +07:00
|
|
|
goto retry;
|
|
|
|
}
|
|
|
|
|
|
|
|
lastblock = bh->b_blocknr;
|
|
|
|
}
|
|
|
|
if (bio)
|
2009-10-30 16:09:15 +07:00
|
|
|
xfs_submit_ioend_bio(wbc, ioend, bio);
|
2010-07-19 04:17:11 +07:00
|
|
|
xfs_finish_ioend(ioend);
|
2006-01-11 11:40:13 +07:00
|
|
|
} while ((ioend = next) != NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Cancel submission of all buffer_heads so far in this endio.
|
|
|
|
* Toss the endio too. Only ever called for the initial page
|
|
|
|
* in a writepage request, so only ever one page.
|
|
|
|
*/
|
|
|
|
STATIC void
|
|
|
|
xfs_cancel_ioend(
|
|
|
|
xfs_ioend_t *ioend)
|
|
|
|
{
|
|
|
|
xfs_ioend_t *next;
|
|
|
|
struct buffer_head *bh, *next_bh;
|
|
|
|
|
|
|
|
do {
|
|
|
|
next = ioend->io_list;
|
|
|
|
bh = ioend->io_buffer_head;
|
|
|
|
do {
|
|
|
|
next_bh = bh->b_private;
|
|
|
|
clear_buffer_async_write(bh);
|
xfs: restore buffer_head unwritten bit on ioend cancel
xfs_vm_writepage() walks each buffer_head on the page, maps to the block
on disk and attaches to a running ioend structure that represents the
I/O submission. A new ioend is created when the type of I/O (unwritten,
delayed allocation or overwrite) required for a particular buffer_head
differs from the previous. If a buffer_head is a delalloc or unwritten
buffer, the associated bits are cleared by xfs_map_at_offset() once the
buffer_head is added to the ioend.
The process of mapping each buffer_head occurs in xfs_map_blocks() and
acquires the ilock in blocking or non-blocking mode, depending on the
type of writeback in progress. If the lock cannot be acquired for
non-blocking writeback, we cancel the ioend, redirty the page and
return. Writeback will revisit the page at some later point.
Note that we acquire the ilock for each buffer on the page. Therefore
during non-blocking writeback, it is possible to add an unwritten buffer
to the ioend, clear the unwritten state, fail to acquire the ilock when
mapping a subsequent buffer and cancel the ioend. If this occurs, the
unwritten status of the buffer sitting in the ioend has been lost. The
page will eventually hit writeback again, but xfs_vm_writepage() submits
overwrite I/O instead of unwritten I/O and does not perform unwritten
extent conversion at I/O completion. This leads to data corruption
because unwritten extents are treated as holes on reads and zeroes are
returned instead of reading from disk.
Modify xfs_cancel_ioend() to restore the buffer unwritten bit for ioends
of type XFS_IO_UNWRITTEN. This ensures that unwritten extent conversion
occurs once the page is eventually written back.
Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
2014-10-02 06:42:06 +07:00
|
|
|
/*
|
|
|
|
* The unwritten flag is cleared when added to the
|
|
|
|
* ioend. We're not submitting for I/O so mark the
|
|
|
|
* buffer unwritten again for next time around.
|
|
|
|
*/
|
|
|
|
if (ioend->io_type == XFS_IO_UNWRITTEN)
|
|
|
|
set_buffer_unwritten(bh);
|
2006-01-11 11:40:13 +07:00
|
|
|
unlock_buffer(bh);
|
|
|
|
} while ((bh = next_bh) != NULL);
|
|
|
|
|
|
|
|
mempool_free(ioend, xfs_ioend_pool);
|
|
|
|
} while ((ioend = next) != NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Test to see if we've been building up a completion structure for
|
|
|
|
* earlier buffers -- if so, we try to append to this ioend if we
|
|
|
|
* can, otherwise we finish off any current ioend and start another.
|
|
|
|
* Return true if we've finished the given ioend.
|
|
|
|
*/
|
|
|
|
STATIC void
|
|
|
|
xfs_add_to_ioend(
|
|
|
|
struct inode *inode,
|
|
|
|
struct buffer_head *bh,
|
2006-01-11 16:49:16 +07:00
|
|
|
xfs_off_t offset,
|
2006-01-11 11:40:13 +07:00
|
|
|
unsigned int type,
|
|
|
|
xfs_ioend_t **result,
|
|
|
|
int need_ioend)
|
|
|
|
{
|
|
|
|
xfs_ioend_t *ioend = *result;
|
|
|
|
|
|
|
|
if (!ioend || need_ioend || type != ioend->io_type) {
|
|
|
|
xfs_ioend_t *previous = *result;
|
|
|
|
|
|
|
|
ioend = xfs_alloc_ioend(inode, type);
|
|
|
|
ioend->io_offset = offset;
|
|
|
|
ioend->io_buffer_head = bh;
|
|
|
|
ioend->io_buffer_tail = bh;
|
|
|
|
if (previous)
|
|
|
|
previous->io_list = ioend;
|
|
|
|
*result = ioend;
|
|
|
|
} else {
|
|
|
|
ioend->io_buffer_tail->b_private = bh;
|
|
|
|
ioend->io_buffer_tail = bh;
|
|
|
|
}
|
|
|
|
|
|
|
|
bh->b_private = NULL;
|
|
|
|
ioend->io_size += bh->b_size;
|
|
|
|
}
|
|
|
|
|
2006-03-14 09:26:43 +07:00
|
|
|
STATIC void
|
|
|
|
xfs_map_buffer(
|
2010-04-28 19:28:52 +07:00
|
|
|
struct inode *inode,
|
2006-03-14 09:26:43 +07:00
|
|
|
struct buffer_head *bh,
|
2010-04-28 19:28:56 +07:00
|
|
|
struct xfs_bmbt_irec *imap,
|
2010-04-28 19:28:52 +07:00
|
|
|
xfs_off_t offset)
|
2006-03-14 09:26:43 +07:00
|
|
|
{
|
|
|
|
sector_t bn;
|
2010-04-28 19:28:54 +07:00
|
|
|
struct xfs_mount *m = XFS_I(inode)->i_mount;
|
2010-04-28 19:28:56 +07:00
|
|
|
xfs_off_t iomap_offset = XFS_FSB_TO_B(m, imap->br_startoff);
|
|
|
|
xfs_daddr_t iomap_bn = xfs_fsb_to_db(XFS_I(inode), imap->br_startblock);
|
2006-03-14 09:26:43 +07:00
|
|
|
|
2010-04-28 19:28:56 +07:00
|
|
|
ASSERT(imap->br_startblock != HOLESTARTBLOCK);
|
|
|
|
ASSERT(imap->br_startblock != DELAYSTARTBLOCK);
|
2006-03-14 09:26:43 +07:00
|
|
|
|
2010-04-28 19:28:55 +07:00
|
|
|
bn = (iomap_bn >> (inode->i_blkbits - BBSHIFT)) +
|
2010-04-28 19:28:54 +07:00
|
|
|
((offset - iomap_offset) >> inode->i_blkbits);
|
2006-03-14 09:26:43 +07:00
|
|
|
|
2010-04-28 19:28:52 +07:00
|
|
|
ASSERT(bn || XFS_IS_REALTIME_INODE(XFS_I(inode)));
|
2006-03-14 09:26:43 +07:00
|
|
|
|
|
|
|
bh->b_blocknr = bn;
|
|
|
|
set_buffer_mapped(bh);
|
|
|
|
}
|
|
|
|
|
2005-04-17 05:20:36 +07:00
|
|
|
STATIC void
|
|
|
|
xfs_map_at_offset(
|
2010-04-28 19:28:52 +07:00
|
|
|
struct inode *inode,
|
2005-04-17 05:20:36 +07:00
|
|
|
struct buffer_head *bh,
|
2010-04-28 19:28:56 +07:00
|
|
|
struct xfs_bmbt_irec *imap,
|
2010-04-28 19:28:52 +07:00
|
|
|
xfs_off_t offset)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
2010-04-28 19:28:56 +07:00
|
|
|
ASSERT(imap->br_startblock != HOLESTARTBLOCK);
|
|
|
|
ASSERT(imap->br_startblock != DELAYSTARTBLOCK);
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2010-04-28 19:28:56 +07:00
|
|
|
xfs_map_buffer(inode, bh, imap, offset);
|
2005-04-17 05:20:36 +07:00
|
|
|
set_buffer_mapped(bh);
|
|
|
|
clear_buffer_delay(bh);
|
2006-01-11 11:40:13 +07:00
|
|
|
clear_buffer_unwritten(bh);
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2014-03-07 12:19:14 +07:00
|
|
|
* Test if a given page contains at least one buffer of a given @type.
|
|
|
|
* If @check_all_buffers is true, then we walk all the buffers in the page to
|
|
|
|
* try to find one of the type passed in. If it is not set, then the caller only
|
|
|
|
* needs to check the first buffer on the page for a match.
|
2005-04-17 05:20:36 +07:00
|
|
|
*/
|
2014-03-07 12:19:14 +07:00
|
|
|
STATIC bool
|
2012-04-23 12:58:43 +07:00
|
|
|
xfs_check_page_type(
|
2006-01-11 16:48:14 +07:00
|
|
|
struct page *page,
|
2014-03-07 12:19:14 +07:00
|
|
|
unsigned int type,
|
|
|
|
bool check_all_buffers)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
2014-03-07 12:19:14 +07:00
|
|
|
struct buffer_head *bh;
|
|
|
|
struct buffer_head *head;
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2014-03-07 12:19:14 +07:00
|
|
|
if (PageWriteback(page))
|
|
|
|
return false;
|
|
|
|
if (!page->mapping)
|
|
|
|
return false;
|
|
|
|
if (!page_has_buffers(page))
|
|
|
|
return false;
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2014-03-07 12:19:14 +07:00
|
|
|
bh = head = page_buffers(page);
|
|
|
|
do {
|
|
|
|
if (buffer_unwritten(bh)) {
|
|
|
|
if (type == XFS_IO_UNWRITTEN)
|
|
|
|
return true;
|
|
|
|
} else if (buffer_delay(bh)) {
|
2014-04-04 02:56:30 +07:00
|
|
|
if (type == XFS_IO_DELALLOC)
|
2014-03-07 12:19:14 +07:00
|
|
|
return true;
|
|
|
|
} else if (buffer_dirty(bh) && buffer_mapped(bh)) {
|
2014-04-04 02:56:30 +07:00
|
|
|
if (type == XFS_IO_OVERWRITE)
|
2014-03-07 12:19:14 +07:00
|
|
|
return true;
|
|
|
|
}
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2014-03-07 12:19:14 +07:00
|
|
|
/* If we are only checking the first buffer, we are done now. */
|
|
|
|
if (!check_all_buffers)
|
|
|
|
break;
|
|
|
|
} while ((bh = bh->b_this_page) != head);
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2014-03-07 12:19:14 +07:00
|
|
|
return false;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Allocate & map buffers for page given the extent map. Write it out.
|
|
|
|
* except for the original page of a writepage, this is called on
|
|
|
|
* delalloc/unwritten pages only, for the original page it is possible
|
|
|
|
* that the page has no mapping at all.
|
|
|
|
*/
|
2006-01-11 11:40:13 +07:00
|
|
|
STATIC int
|
2005-04-17 05:20:36 +07:00
|
|
|
xfs_convert_page(
|
|
|
|
struct inode *inode,
|
|
|
|
struct page *page,
|
2006-01-11 16:48:14 +07:00
|
|
|
loff_t tindex,
|
2010-04-28 19:28:56 +07:00
|
|
|
struct xfs_bmbt_irec *imap,
|
2006-01-11 11:40:13 +07:00
|
|
|
xfs_ioend_t **ioendp,
|
2010-12-10 15:42:23 +07:00
|
|
|
struct writeback_control *wbc)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
2006-01-11 11:40:13 +07:00
|
|
|
struct buffer_head *bh, *head;
|
2006-01-11 16:48:47 +07:00
|
|
|
xfs_off_t end_offset;
|
|
|
|
unsigned long p_offset;
|
2006-01-11 11:40:13 +07:00
|
|
|
unsigned int type;
|
2005-05-06 03:33:20 +07:00
|
|
|
int len, page_dirty;
|
2006-01-11 11:40:13 +07:00
|
|
|
int count = 0, done = 0, uptodate = 1;
|
2006-01-11 16:48:47 +07:00
|
|
|
xfs_off_t offset = page_offset(page);
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2006-01-11 16:48:14 +07:00
|
|
|
if (page->index != tindex)
|
|
|
|
goto fail;
|
2008-08-02 17:01:03 +07:00
|
|
|
if (!trylock_page(page))
|
2006-01-11 16:48:14 +07:00
|
|
|
goto fail;
|
|
|
|
if (PageWriteback(page))
|
|
|
|
goto fail_unlock_page;
|
|
|
|
if (page->mapping != inode->i_mapping)
|
|
|
|
goto fail_unlock_page;
|
2014-03-07 12:19:14 +07:00
|
|
|
if (!xfs_check_page_type(page, (*ioendp)->io_type, false))
|
2006-01-11 16:48:14 +07:00
|
|
|
goto fail_unlock_page;
|
|
|
|
|
2005-05-06 03:33:20 +07:00
|
|
|
/*
|
|
|
|
* page_dirty is initially a count of buffers on the page before
|
2006-03-29 05:55:14 +07:00
|
|
|
* EOF and is decremented as we move each into a cleanable state.
|
2006-01-11 16:48:47 +07:00
|
|
|
*
|
|
|
|
* Derivation:
|
|
|
|
*
|
|
|
|
* End offset is the highest offset that this page should represent.
|
|
|
|
* If we are on the last page, (end_offset & (PAGE_CACHE_SIZE - 1))
|
|
|
|
* will evaluate non-zero and be less than PAGE_CACHE_SIZE and
|
|
|
|
* hence give us the correct page_dirty count. On any other page,
|
|
|
|
* it will be zero and in that case we need page_dirty to be the
|
|
|
|
* count of buffers on the page.
|
2005-05-06 03:33:20 +07:00
|
|
|
*/
|
2006-01-11 16:48:47 +07:00
|
|
|
end_offset = min_t(unsigned long long,
|
|
|
|
(xfs_off_t)(page->index + 1) << PAGE_CACHE_SHIFT,
|
|
|
|
i_size_read(inode));
|
|
|
|
|
2013-05-20 06:51:08 +07:00
|
|
|
/*
|
|
|
|
* If the current map does not span the entire page we are about to try
|
|
|
|
* to write, then give up. The only way we can write a page that spans
|
|
|
|
* multiple mappings in a single writeback iteration is via the
|
|
|
|
* xfs_vm_writepage() function. Data integrity writeback requires the
|
|
|
|
* entire page to be written in a single attempt, otherwise the part of
|
|
|
|
* the page we don't write here doesn't get written as part of the data
|
|
|
|
* integrity sync.
|
|
|
|
*
|
|
|
|
* For normal writeback, we also don't attempt to write partial pages
|
|
|
|
* here as it simply means that write_cache_pages() will see it under
|
|
|
|
* writeback and ignore the page until some point in the future, at
|
|
|
|
* which time this will be the only page in the file that needs
|
|
|
|
* writeback. Hence for more optimal IO patterns, we should always
|
|
|
|
* avoid partial page writeback due to multiple mappings on a page here.
|
|
|
|
*/
|
|
|
|
if (!xfs_imap_valid(inode, imap, end_offset))
|
|
|
|
goto fail_unlock_page;
|
|
|
|
|
2005-05-06 03:33:20 +07:00
|
|
|
len = 1 << inode->i_blkbits;
|
2006-01-11 16:48:47 +07:00
|
|
|
p_offset = min_t(unsigned long, end_offset & (PAGE_CACHE_SIZE - 1),
|
|
|
|
PAGE_CACHE_SIZE);
|
|
|
|
p_offset = p_offset ? roundup(p_offset, len) : PAGE_CACHE_SIZE;
|
|
|
|
page_dirty = p_offset / len;
|
2005-05-06 03:33:20 +07:00
|
|
|
|
2014-03-07 12:19:14 +07:00
|
|
|
/*
|
|
|
|
* The moment we find a buffer that doesn't match our current type
|
|
|
|
* specification or can't be written, abort the loop and start
|
|
|
|
* writeback. As per the above xfs_imap_valid() check, only
|
|
|
|
* xfs_vm_writepage() can handle partial page writeback fully - we are
|
|
|
|
* limited here to the buffers that are contiguous with the current
|
|
|
|
* ioend, and hence a buffer we can't write breaks that contiguity and
|
|
|
|
* we have to defer the rest of the IO to xfs_vm_writepage().
|
|
|
|
*/
|
2005-04-17 05:20:36 +07:00
|
|
|
bh = head = page_buffers(page);
|
|
|
|
do {
|
2006-01-11 16:48:47 +07:00
|
|
|
if (offset >= end_offset)
|
2005-04-17 05:20:36 +07:00
|
|
|
break;
|
2006-01-11 11:40:13 +07:00
|
|
|
if (!buffer_uptodate(bh))
|
|
|
|
uptodate = 0;
|
|
|
|
if (!(PageUptodate(page) || buffer_uptodate(bh))) {
|
|
|
|
done = 1;
|
2014-03-07 12:19:14 +07:00
|
|
|
break;
|
2006-01-11 11:40:13 +07:00
|
|
|
}
|
|
|
|
|
2010-12-10 15:42:23 +07:00
|
|
|
if (buffer_unwritten(bh) || buffer_delay(bh) ||
|
|
|
|
buffer_mapped(bh)) {
|
2006-01-11 16:48:47 +07:00
|
|
|
if (buffer_unwritten(bh))
|
2012-05-23 03:56:21 +07:00
|
|
|
type = XFS_IO_UNWRITTEN;
|
2010-12-10 15:42:23 +07:00
|
|
|
else if (buffer_delay(bh))
|
2012-05-23 03:56:21 +07:00
|
|
|
type = XFS_IO_DELALLOC;
|
2010-12-10 15:42:23 +07:00
|
|
|
else
|
2012-05-23 03:56:21 +07:00
|
|
|
type = XFS_IO_OVERWRITE;
|
2006-01-11 16:48:47 +07:00
|
|
|
|
2014-03-07 12:19:14 +07:00
|
|
|
/*
|
|
|
|
* imap should always be valid because of the above
|
|
|
|
* partial page end_offset check on the imap.
|
|
|
|
*/
|
|
|
|
ASSERT(xfs_imap_valid(inode, imap, offset));
|
2006-01-11 16:48:47 +07:00
|
|
|
|
2010-12-10 15:42:25 +07:00
|
|
|
lock_buffer(bh);
|
2012-05-23 03:56:21 +07:00
|
|
|
if (type != XFS_IO_OVERWRITE)
|
2010-12-10 15:42:23 +07:00
|
|
|
xfs_map_at_offset(inode, bh, imap, offset);
|
2010-06-24 06:45:48 +07:00
|
|
|
xfs_add_to_ioend(inode, bh, offset, type,
|
|
|
|
ioendp, done);
|
|
|
|
|
2006-01-11 16:48:47 +07:00
|
|
|
page_dirty--;
|
|
|
|
count++;
|
|
|
|
} else {
|
2010-12-10 15:42:23 +07:00
|
|
|
done = 1;
|
2014-03-07 12:19:14 +07:00
|
|
|
break;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
2006-01-11 16:49:16 +07:00
|
|
|
} while (offset += len, (bh = bh->b_this_page) != head);
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2006-01-11 11:40:13 +07:00
|
|
|
if (uptodate && bh == head)
|
|
|
|
SetPageUptodate(page);
|
|
|
|
|
2010-06-24 06:45:48 +07:00
|
|
|
if (count) {
|
2010-08-24 08:44:56 +07:00
|
|
|
if (--wbc->nr_to_write <= 0 &&
|
|
|
|
wbc->sync_mode == WB_SYNC_NONE)
|
2010-06-24 06:45:48 +07:00
|
|
|
done = 1;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
2010-06-24 06:45:48 +07:00
|
|
|
xfs_start_page_writeback(page, !page_dirty, count);
|
2006-01-11 11:40:13 +07:00
|
|
|
|
|
|
|
return done;
|
2006-01-11 16:48:14 +07:00
|
|
|
fail_unlock_page:
|
|
|
|
unlock_page(page);
|
|
|
|
fail:
|
|
|
|
return 1;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Convert & write out a cluster of pages in the same extent as defined
|
|
|
|
* by mp and following the start page.
|
|
|
|
*/
|
|
|
|
STATIC void
|
|
|
|
xfs_cluster_write(
|
|
|
|
struct inode *inode,
|
|
|
|
pgoff_t tindex,
|
2010-04-28 19:28:56 +07:00
|
|
|
struct xfs_bmbt_irec *imap,
|
2006-01-11 11:40:13 +07:00
|
|
|
xfs_ioend_t **ioendp,
|
2005-04-17 05:20:36 +07:00
|
|
|
struct writeback_control *wbc,
|
|
|
|
pgoff_t tlast)
|
|
|
|
{
|
2006-01-11 16:48:14 +07:00
|
|
|
struct pagevec pvec;
|
|
|
|
int done = 0, i;
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2006-01-11 16:48:14 +07:00
|
|
|
pagevec_init(&pvec, 0);
|
|
|
|
while (!done && tindex <= tlast) {
|
|
|
|
unsigned len = min_t(pgoff_t, PAGEVEC_SIZE, tlast - tindex + 1);
|
|
|
|
|
|
|
|
if (!pagevec_lookup(&pvec, inode->i_mapping, tindex, len))
|
2005-04-17 05:20:36 +07:00
|
|
|
break;
|
2006-01-11 16:48:14 +07:00
|
|
|
|
|
|
|
for (i = 0; i < pagevec_count(&pvec); i++) {
|
|
|
|
done = xfs_convert_page(inode, pvec.pages[i], tindex++,
|
2010-12-10 15:42:23 +07:00
|
|
|
imap, ioendp, wbc);
|
2006-01-11 16:48:14 +07:00
|
|
|
if (done)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
pagevec_release(&pvec);
|
|
|
|
cond_resched();
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-03-05 09:00:42 +07:00
|
|
|
STATIC void
|
|
|
|
xfs_vm_invalidatepage(
|
|
|
|
struct page *page,
|
2013-05-22 10:17:23 +07:00
|
|
|
unsigned int offset,
|
|
|
|
unsigned int length)
|
2010-03-05 09:00:42 +07:00
|
|
|
{
|
2013-05-22 10:58:01 +07:00
|
|
|
trace_xfs_invalidatepage(page->mapping->host, page, offset,
|
|
|
|
length);
|
|
|
|
block_invalidatepage(page, offset, length);
|
2010-03-05 09:00:42 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If the page has delalloc buffers on it, we need to punch them out before we
|
|
|
|
* invalidate the page. If we don't, we leave a stale delalloc mapping on the
|
|
|
|
* inode that can trip a BUG() in xfs_get_blocks() later on if a direct IO read
|
|
|
|
* is done on that same region - the delalloc extent is returned when none is
|
|
|
|
* supposed to be there.
|
|
|
|
*
|
|
|
|
* We prevent this by truncating away the delalloc regions on the page before
|
|
|
|
* invalidating it. Because they are delalloc, we can do this without needing a
|
|
|
|
* transaction. Indeed - if we get ENOSPC errors, we have to be able to do this
|
|
|
|
* truncation without a transaction as there is no space left for block
|
|
|
|
* reservation (typically why we see a ENOSPC in writeback).
|
|
|
|
*
|
|
|
|
* This is not a performance critical path, so for now just do the punching a
|
|
|
|
* buffer head at a time.
|
|
|
|
*/
|
|
|
|
STATIC void
|
|
|
|
xfs_aops_discard_page(
|
|
|
|
struct page *page)
|
|
|
|
{
|
|
|
|
struct inode *inode = page->mapping->host;
|
|
|
|
struct xfs_inode *ip = XFS_I(inode);
|
|
|
|
struct buffer_head *bh, *head;
|
|
|
|
loff_t offset = page_offset(page);
|
|
|
|
|
2014-03-07 12:19:14 +07:00
|
|
|
if (!xfs_check_page_type(page, XFS_IO_DELALLOC, true))
|
2010-03-05 09:00:42 +07:00
|
|
|
goto out_invalidate;
|
|
|
|
|
2010-03-15 09:36:35 +07:00
|
|
|
if (XFS_FORCED_SHUTDOWN(ip->i_mount))
|
|
|
|
goto out_invalidate;
|
|
|
|
|
2011-03-07 06:00:35 +07:00
|
|
|
xfs_alert(ip->i_mount,
|
2010-03-05 09:00:42 +07:00
|
|
|
"page discard on page %p, inode 0x%llx, offset %llu.",
|
|
|
|
page, ip->i_ino, offset);
|
|
|
|
|
|
|
|
xfs_ilock(ip, XFS_ILOCK_EXCL);
|
|
|
|
bh = head = page_buffers(page);
|
|
|
|
do {
|
|
|
|
int error;
|
2010-11-30 11:14:39 +07:00
|
|
|
xfs_fileoff_t start_fsb;
|
2010-03-05 09:00:42 +07:00
|
|
|
|
|
|
|
if (!buffer_delay(bh))
|
|
|
|
goto next_buffer;
|
|
|
|
|
2010-11-30 11:14:39 +07:00
|
|
|
start_fsb = XFS_B_TO_FSBT(ip->i_mount, offset);
|
|
|
|
error = xfs_bmap_punch_delalloc_range(ip, start_fsb, 1);
|
2010-03-05 09:00:42 +07:00
|
|
|
if (error) {
|
|
|
|
/* something screwed, just bail */
|
2010-03-15 09:36:35 +07:00
|
|
|
if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {
|
2011-03-07 06:00:35 +07:00
|
|
|
xfs_alert(ip->i_mount,
|
2010-03-05 09:00:42 +07:00
|
|
|
"page discard unable to remove delalloc mapping.");
|
2010-03-15 09:36:35 +07:00
|
|
|
}
|
2010-03-05 09:00:42 +07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
next_buffer:
|
2010-11-30 11:14:39 +07:00
|
|
|
offset += 1 << inode->i_blkbits;
|
2010-03-05 09:00:42 +07:00
|
|
|
|
|
|
|
} while ((bh = bh->b_this_page) != head);
|
|
|
|
|
|
|
|
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
|
|
|
out_invalidate:
|
2013-05-22 10:17:23 +07:00
|
|
|
xfs_vm_invalidatepage(page, 0, PAGE_CACHE_SIZE);
|
2010-03-05 09:00:42 +07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2005-04-17 05:20:36 +07:00
|
|
|
/*
|
2010-06-24 06:45:48 +07:00
|
|
|
* Write out a dirty page.
|
|
|
|
*
|
|
|
|
* For delalloc space on the page we need to allocate space and flush it.
|
|
|
|
* For unwritten space on the page we need to start the conversion to
|
|
|
|
* regular allocated space.
|
|
|
|
* For any other dirty buffer heads on the page we should flush them.
|
2005-04-17 05:20:36 +07:00
|
|
|
*/
|
|
|
|
STATIC int
|
2010-06-24 06:45:48 +07:00
|
|
|
xfs_vm_writepage(
|
|
|
|
struct page *page,
|
|
|
|
struct writeback_control *wbc)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
2010-06-24 06:45:48 +07:00
|
|
|
struct inode *inode = page->mapping->host;
|
2006-01-11 11:40:13 +07:00
|
|
|
struct buffer_head *bh, *head;
|
2010-04-28 19:28:56 +07:00
|
|
|
struct xfs_bmbt_irec imap;
|
2006-01-11 11:40:13 +07:00
|
|
|
xfs_ioend_t *ioend = NULL, *iohead = NULL;
|
2005-04-17 05:20:36 +07:00
|
|
|
loff_t offset;
|
2006-01-11 11:40:13 +07:00
|
|
|
unsigned int type;
|
2005-04-17 05:20:36 +07:00
|
|
|
__uint64_t end_offset;
|
2010-04-28 19:29:00 +07:00
|
|
|
pgoff_t end_index, last_index;
|
2010-12-10 15:42:22 +07:00
|
|
|
ssize_t len;
|
2010-12-10 15:42:20 +07:00
|
|
|
int err, imap_valid = 0, uptodate = 1;
|
2010-06-24 06:45:48 +07:00
|
|
|
int count = 0;
|
2010-12-10 15:42:20 +07:00
|
|
|
int nonblocking = 0;
|
2010-06-24 06:45:48 +07:00
|
|
|
|
2013-05-22 10:58:01 +07:00
|
|
|
trace_xfs_writepage(inode, page, 0, 0);
|
2010-06-24 06:45:48 +07:00
|
|
|
|
2010-06-24 06:46:01 +07:00
|
|
|
ASSERT(page_has_buffers(page));
|
|
|
|
|
2010-06-24 06:45:48 +07:00
|
|
|
/*
|
|
|
|
* Refuse to write the page out if we are called from reclaim context.
|
|
|
|
*
|
2010-06-28 21:34:44 +07:00
|
|
|
* This avoids stack overflows when called from deeply used stacks in
|
|
|
|
* random callers for direct reclaim or memcg reclaim. We explicitly
|
|
|
|
* allow reclaim from kswapd as the stack usage there is relatively low.
|
2010-06-24 06:45:48 +07:00
|
|
|
*
|
2011-11-01 07:07:45 +07:00
|
|
|
* This should never happen except in the case of a VM regression so
|
|
|
|
* warn about it.
|
2010-06-24 06:45:48 +07:00
|
|
|
*/
|
2011-11-01 07:07:45 +07:00
|
|
|
if (WARN_ON_ONCE((current->flags & (PF_MEMALLOC|PF_KSWAPD)) ==
|
|
|
|
PF_MEMALLOC))
|
2010-08-24 08:47:51 +07:00
|
|
|
goto redirty;
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2010-06-24 06:45:48 +07:00
|
|
|
/*
|
2011-07-08 19:34:05 +07:00
|
|
|
* Given that we do not allow direct reclaim to call us, we should
|
|
|
|
* never be called while in a filesystem transaction.
|
2010-06-24 06:45:48 +07:00
|
|
|
*/
|
2014-06-06 13:05:15 +07:00
|
|
|
if (WARN_ON_ONCE(current->flags & PF_FSTRANS))
|
2010-08-24 08:47:51 +07:00
|
|
|
goto redirty;
|
2010-06-24 06:45:48 +07:00
|
|
|
|
2005-04-17 05:20:36 +07:00
|
|
|
/* Is this page beyond the end of the file? */
|
|
|
|
offset = i_size_read(inode);
|
|
|
|
end_index = offset >> PAGE_CACHE_SHIFT;
|
|
|
|
last_index = (offset - 1) >> PAGE_CACHE_SHIFT;
|
2014-05-20 05:24:26 +07:00
|
|
|
|
|
|
|
/*
|
|
|
|
* The page index is less than the end_index, adjust the end_offset
|
|
|
|
* to the highest offset that this page should represent.
|
|
|
|
* -----------------------------------------------------
|
|
|
|
* | file mapping | <EOF> |
|
|
|
|
* -----------------------------------------------------
|
|
|
|
* | Page ... | Page N-2 | Page N-1 | Page N | |
|
|
|
|
* ^--------------------------------^----------|--------
|
|
|
|
* | desired writeback range | see else |
|
|
|
|
* ---------------------------------^------------------|
|
|
|
|
*/
|
|
|
|
if (page->index < end_index)
|
|
|
|
end_offset = (xfs_off_t)(page->index + 1) << PAGE_CACHE_SHIFT;
|
|
|
|
else {
|
|
|
|
/*
|
|
|
|
* Check whether the page to write out is beyond or straddles
|
|
|
|
* i_size or not.
|
|
|
|
* -------------------------------------------------------
|
|
|
|
* | file mapping | <EOF> |
|
|
|
|
* -------------------------------------------------------
|
|
|
|
* | Page ... | Page N-2 | Page N-1 | Page N | Beyond |
|
|
|
|
* ^--------------------------------^-----------|---------
|
|
|
|
* | | Straddles |
|
|
|
|
* ---------------------------------^-----------|--------|
|
|
|
|
*/
|
2012-07-03 23:20:00 +07:00
|
|
|
unsigned offset_into_page = offset & (PAGE_CACHE_SIZE - 1);
|
|
|
|
|
|
|
|
/*
|
2013-03-14 20:30:54 +07:00
|
|
|
* Skip the page if it is fully outside i_size, e.g. due to a
|
|
|
|
* truncate operation that is in progress. We must redirty the
|
|
|
|
* page so that reclaim stops reclaiming it. Otherwise
|
|
|
|
* xfs_vm_releasepage() is called on it and gets confused.
|
2014-05-20 05:24:26 +07:00
|
|
|
*
|
|
|
|
* Note that the end_index is unsigned long, it would overflow
|
|
|
|
* if the given offset is greater than 16TB on 32-bit system
|
|
|
|
* and if we do check the page is fully outside i_size or not
|
|
|
|
* via "if (page->index >= end_index + 1)" as "end_index + 1"
|
|
|
|
* will be evaluated to 0. Hence this page will be redirtied
|
|
|
|
* and be written out repeatedly which would result in an
|
|
|
|
* infinite loop, the user program that perform this operation
|
|
|
|
* will hang. Instead, we can verify this situation by checking
|
|
|
|
* if the page to write is totally beyond the i_size or if it's
|
|
|
|
* offset is just equal to the EOF.
|
2012-07-03 23:20:00 +07:00
|
|
|
*/
|
2014-05-20 05:24:26 +07:00
|
|
|
if (page->index > end_index ||
|
|
|
|
(page->index == end_index && offset_into_page == 0))
|
2013-03-14 20:30:54 +07:00
|
|
|
goto redirty;
|
2012-07-03 23:20:00 +07:00
|
|
|
|
|
|
|
/*
|
|
|
|
* The page straddles i_size. It must be zeroed out on each
|
|
|
|
* and every writepage invocation because it may be mmapped.
|
|
|
|
* "A file is mapped in multiples of the page size. For a file
|
2014-05-20 05:24:26 +07:00
|
|
|
* that is not a multiple of the page size, the remaining
|
2012-07-03 23:20:00 +07:00
|
|
|
* memory is zeroed when mapped, and writes to that region are
|
|
|
|
* not written out to the file."
|
|
|
|
*/
|
|
|
|
zero_user_segment(page, offset_into_page, PAGE_CACHE_SIZE);
|
2014-05-20 05:24:26 +07:00
|
|
|
|
|
|
|
/* Adjust the end_offset to the end of file */
|
|
|
|
end_offset = offset;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
2005-05-06 03:33:20 +07:00
|
|
|
len = 1 << inode->i_blkbits;
|
|
|
|
|
|
|
|
bh = head = page_buffers(page);
|
2006-01-11 11:40:13 +07:00
|
|
|
offset = page_offset(page);
|
2012-05-23 03:56:21 +07:00
|
|
|
type = XFS_IO_OVERWRITE;
|
2010-12-10 15:42:20 +07:00
|
|
|
|
2011-07-08 19:34:14 +07:00
|
|
|
if (wbc->sync_mode == WB_SYNC_NONE)
|
2010-12-10 15:42:20 +07:00
|
|
|
nonblocking = 1;
|
2006-01-11 11:40:13 +07:00
|
|
|
|
2005-04-17 05:20:36 +07:00
|
|
|
do {
|
2010-12-10 15:42:18 +07:00
|
|
|
int new_ioend = 0;
|
|
|
|
|
2005-04-17 05:20:36 +07:00
|
|
|
if (offset >= end_offset)
|
|
|
|
break;
|
|
|
|
if (!buffer_uptodate(bh))
|
|
|
|
uptodate = 0;
|
|
|
|
|
2010-06-24 06:45:30 +07:00
|
|
|
/*
|
2010-11-11 04:39:11 +07:00
|
|
|
* set_page_dirty dirties all buffers in a page, independent
|
|
|
|
* of their state. The dirty state however is entirely
|
|
|
|
* meaningless for holes (!mapped && uptodate), so skip
|
|
|
|
* buffers covering holes here.
|
2010-06-24 06:45:30 +07:00
|
|
|
*/
|
|
|
|
if (!buffer_mapped(bh) && buffer_uptodate(bh)) {
|
|
|
|
imap_valid = 0;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2010-12-10 15:42:24 +07:00
|
|
|
if (buffer_unwritten(bh)) {
|
2012-05-23 03:56:21 +07:00
|
|
|
if (type != XFS_IO_UNWRITTEN) {
|
|
|
|
type = XFS_IO_UNWRITTEN;
|
2010-12-10 15:42:24 +07:00
|
|
|
imap_valid = 0;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
2010-12-10 15:42:24 +07:00
|
|
|
} else if (buffer_delay(bh)) {
|
2012-05-23 03:56:21 +07:00
|
|
|
if (type != XFS_IO_DELALLOC) {
|
|
|
|
type = XFS_IO_DELALLOC;
|
2010-12-10 15:42:24 +07:00
|
|
|
imap_valid = 0;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
2010-06-24 06:45:48 +07:00
|
|
|
} else if (buffer_uptodate(bh)) {
|
2012-05-23 03:56:21 +07:00
|
|
|
if (type != XFS_IO_OVERWRITE) {
|
|
|
|
type = XFS_IO_OVERWRITE;
|
2010-12-10 15:42:16 +07:00
|
|
|
imap_valid = 0;
|
|
|
|
}
|
2010-12-10 15:42:24 +07:00
|
|
|
} else {
|
xfs: xfs_vm_writepage clear iomap_valid when !buffer_uptodate (REV2)
On filesytems with a block size smaller than PAGE_SIZE we currently have
a problem with unwritten extents. If a we have multi-block page for
which an unwritten extent has been allocated, and only some of the
buffers have been written to, and they are not contiguous, we can expose
stale data from disk in the blocks between the writes after extent
conversion.
Example of a page with unwritten and real data.
buffer content
0 empty b_state = 0
1 DATA b_state = 0x1023 Uptodate,Dirty,Mapped,Unwritten
2 DATA b_state = 0x1023 Uptodate,Dirty,Mapped,Unwritten
3 empty b_state = 0
4 empty b_state = 0
5 DATA b_state = 0x1023 Uptodate,Dirty,Mapped,Unwritten
6 DATA b_state = 0x1023 Uptodate,Dirty,Mapped,Unwritten
7 empty b_state = 0
Buffers 1, 2, 5, and 6 have been written to, leaving 0, 3, 4, and 7
empty. Currently buffers 1, 2, 5, and 6 are added to a single ioend,
and when IO has completed, extent conversion creates a real extent from
block 1 through block 6, leaving 0 and 7 unwritten. However buffers 3
and 4 were not written to disk, so stale data is exposed from those
blocks on a subsequent read.
Fix this by setting iomap_valid = 0 when we find a buffer that is not
Uptodate. This ensures that buffers 5 and 6 are not added to the same
ioend as buffers 1 and 2. Later these blocks will be converted into two
separate real extents, leaving the blocks in between unwritten.
Signed-off-by: Alain Renaud <arenaud@sgi.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-06-09 02:34:46 +07:00
|
|
|
if (PageUptodate(page))
|
2010-12-10 15:42:24 +07:00
|
|
|
ASSERT(buffer_mapped(bh));
|
xfs: xfs_vm_writepage clear iomap_valid when !buffer_uptodate (REV2)
On filesytems with a block size smaller than PAGE_SIZE we currently have
a problem with unwritten extents. If a we have multi-block page for
which an unwritten extent has been allocated, and only some of the
buffers have been written to, and they are not contiguous, we can expose
stale data from disk in the blocks between the writes after extent
conversion.
Example of a page with unwritten and real data.
buffer content
0 empty b_state = 0
1 DATA b_state = 0x1023 Uptodate,Dirty,Mapped,Unwritten
2 DATA b_state = 0x1023 Uptodate,Dirty,Mapped,Unwritten
3 empty b_state = 0
4 empty b_state = 0
5 DATA b_state = 0x1023 Uptodate,Dirty,Mapped,Unwritten
6 DATA b_state = 0x1023 Uptodate,Dirty,Mapped,Unwritten
7 empty b_state = 0
Buffers 1, 2, 5, and 6 have been written to, leaving 0, 3, 4, and 7
empty. Currently buffers 1, 2, 5, and 6 are added to a single ioend,
and when IO has completed, extent conversion creates a real extent from
block 1 through block 6, leaving 0 and 7 unwritten. However buffers 3
and 4 were not written to disk, so stale data is exposed from those
blocks on a subsequent read.
Fix this by setting iomap_valid = 0 when we find a buffer that is not
Uptodate. This ensures that buffers 5 and 6 are not added to the same
ioend as buffers 1 and 2. Later these blocks will be converted into two
separate real extents, leaving the blocks in between unwritten.
Signed-off-by: Alain Renaud <arenaud@sgi.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-06-09 02:34:46 +07:00
|
|
|
/*
|
|
|
|
* This buffer is not uptodate and will not be
|
|
|
|
* written to disk. Ensure that we will put any
|
|
|
|
* subsequent writeable buffers into a new
|
|
|
|
* ioend.
|
|
|
|
*/
|
|
|
|
imap_valid = 0;
|
2010-12-10 15:42:24 +07:00
|
|
|
continue;
|
|
|
|
}
|
2006-01-11 16:49:02 +07:00
|
|
|
|
2010-12-10 15:42:24 +07:00
|
|
|
if (imap_valid)
|
|
|
|
imap_valid = xfs_imap_valid(inode, &imap, offset);
|
|
|
|
if (!imap_valid) {
|
|
|
|
/*
|
|
|
|
* If we didn't have a valid mapping then we need to
|
|
|
|
* put the new mapping into a separate ioend structure.
|
|
|
|
* This ensures non-contiguous extents always have
|
|
|
|
* separate ioends, which is particularly important
|
|
|
|
* for unwritten extent conversion at I/O completion
|
|
|
|
* time.
|
|
|
|
*/
|
|
|
|
new_ioend = 1;
|
|
|
|
err = xfs_map_blocks(inode, offset, &imap, type,
|
|
|
|
nonblocking);
|
|
|
|
if (err)
|
|
|
|
goto error;
|
|
|
|
imap_valid = xfs_imap_valid(inode, &imap, offset);
|
|
|
|
}
|
|
|
|
if (imap_valid) {
|
2010-12-10 15:42:25 +07:00
|
|
|
lock_buffer(bh);
|
2012-05-23 03:56:21 +07:00
|
|
|
if (type != XFS_IO_OVERWRITE)
|
2010-12-10 15:42:24 +07:00
|
|
|
xfs_map_at_offset(inode, bh, &imap, offset);
|
|
|
|
xfs_add_to_ioend(inode, bh, offset, type, &ioend,
|
|
|
|
new_ioend);
|
|
|
|
count++;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
2006-01-11 11:40:13 +07:00
|
|
|
|
|
|
|
if (!iohead)
|
|
|
|
iohead = ioend;
|
|
|
|
|
|
|
|
} while (offset += len, ((bh = bh->b_this_page) != head));
|
2005-04-17 05:20:36 +07:00
|
|
|
|
|
|
|
if (uptodate && bh == head)
|
|
|
|
SetPageUptodate(page);
|
|
|
|
|
2010-06-24 06:45:48 +07:00
|
|
|
xfs_start_page_writeback(page, 1, count);
|
2005-04-17 05:20:36 +07:00
|
|
|
|
xfs: fix broken error handling in xfs_vm_writepage
When we shut down the filesystem, it might first be detected in
writeback when we are allocating a inode size transaction. This
happens after we have moved all the pages into the writeback state
and unlocked them. Unfortunately, if we fail to set up the
transaction we then abort writeback and try to invalidate the
current page. This then triggers are BUG() in block_invalidatepage()
because we are trying to invalidate an unlocked page.
Fixing this is a bit of a chicken and egg problem - we can't
allocate the transaction until we've clustered all the pages into
the IO and we know the size of it (i.e. whether the last block of
the IO is beyond the current EOF or not). However, we don't want to
hold pages locked for long periods of time, especially while we lock
other pages to cluster them into the write.
To fix this, we need to make a clear delineation in writeback where
errors can only be handled by IO completion processing. That is,
once we have marked a page for writeback and unlocked it, we have to
report errors via IO completion because we've already started the
IO. We may not have submitted any IO, but we've changed the page
state to indicate that it is under IO so we must now use the IO
completion path to report errors.
To do this, add an error field to xfs_submit_ioend() to pass it the
error that occurred during the building on the ioend chain. When
this is non-zero, mark each ioend with the error and call
xfs_finish_ioend() directly rather than building bios. This will
immediately push the ioends through completion processing with the
error that has occurred.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-11-12 18:09:45 +07:00
|
|
|
/* if there is no IO to be submitted for this page, we are done */
|
|
|
|
if (!ioend)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
ASSERT(iohead);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Any errors from this point onwards need tobe reported through the IO
|
|
|
|
* completion path as we have marked the initial page as under writeback
|
|
|
|
* and unlocked it.
|
|
|
|
*/
|
|
|
|
if (imap_valid) {
|
2010-04-28 19:29:00 +07:00
|
|
|
xfs_off_t end_index;
|
|
|
|
|
|
|
|
end_index = imap.br_startoff + imap.br_blockcount;
|
|
|
|
|
|
|
|
/* to bytes */
|
|
|
|
end_index <<= inode->i_blkbits;
|
|
|
|
|
|
|
|
/* to pages */
|
|
|
|
end_index = (end_index - 1) >> PAGE_CACHE_SHIFT;
|
|
|
|
|
|
|
|
/* check against file size */
|
|
|
|
if (end_index > last_index)
|
|
|
|
end_index = last_index;
|
2010-04-28 19:28:54 +07:00
|
|
|
|
2010-04-28 19:28:56 +07:00
|
|
|
xfs_cluster_write(inode, page->index + 1, &imap, &ioend,
|
2010-12-10 15:42:23 +07:00
|
|
|
wbc, end_index);
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
2012-03-13 15:41:05 +07:00
|
|
|
|
xfs: fix broken error handling in xfs_vm_writepage
When we shut down the filesystem, it might first be detected in
writeback when we are allocating a inode size transaction. This
happens after we have moved all the pages into the writeback state
and unlocked them. Unfortunately, if we fail to set up the
transaction we then abort writeback and try to invalidate the
current page. This then triggers are BUG() in block_invalidatepage()
because we are trying to invalidate an unlocked page.
Fixing this is a bit of a chicken and egg problem - we can't
allocate the transaction until we've clustered all the pages into
the IO and we know the size of it (i.e. whether the last block of
the IO is beyond the current EOF or not). However, we don't want to
hold pages locked for long periods of time, especially while we lock
other pages to cluster them into the write.
To fix this, we need to make a clear delineation in writeback where
errors can only be handled by IO completion processing. That is,
once we have marked a page for writeback and unlocked it, we have to
report errors via IO completion because we've already started the
IO. We may not have submitted any IO, but we've changed the page
state to indicate that it is under IO so we must now use the IO
completion path to report errors.
To do this, add an error field to xfs_submit_ioend() to pass it the
error that occurred during the building on the ioend chain. When
this is non-zero, mark each ioend with the error and call
xfs_finish_ioend() directly rather than building bios. This will
immediately push the ioends through completion processing with the
error that has occurred.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-11-12 18:09:45 +07:00
|
|
|
/*
|
|
|
|
* Reserve log space if we might write beyond the on-disk inode size.
|
|
|
|
*/
|
|
|
|
err = 0;
|
|
|
|
if (ioend->io_type != XFS_IO_UNWRITTEN && xfs_ioend_is_append(ioend))
|
|
|
|
err = xfs_setfilesize_trans_alloc(ioend);
|
|
|
|
|
|
|
|
xfs_submit_ioend(wbc, iohead, err);
|
2006-01-11 11:40:13 +07:00
|
|
|
|
2010-06-24 06:45:48 +07:00
|
|
|
return 0;
|
2005-04-17 05:20:36 +07:00
|
|
|
|
|
|
|
error:
|
2006-01-11 11:40:13 +07:00
|
|
|
if (iohead)
|
|
|
|
xfs_cancel_ioend(iohead);
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2010-08-24 08:47:51 +07:00
|
|
|
if (err == -EAGAIN)
|
|
|
|
goto redirty;
|
|
|
|
|
2010-06-24 06:46:01 +07:00
|
|
|
xfs_aops_discard_page(page);
|
2010-06-24 06:45:48 +07:00
|
|
|
ClearPageUptodate(page);
|
|
|
|
unlock_page(page);
|
2005-04-17 05:20:36 +07:00
|
|
|
return err;
|
2006-03-14 09:26:27 +07:00
|
|
|
|
2010-08-24 08:47:51 +07:00
|
|
|
redirty:
|
2006-03-14 09:26:27 +07:00
|
|
|
redirty_page_for_writepage(wbc, page);
|
|
|
|
unlock_page(page);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-06-09 12:27:16 +07:00
|
|
|
STATIC int
|
|
|
|
xfs_vm_writepages(
|
|
|
|
struct address_space *mapping,
|
|
|
|
struct writeback_control *wbc)
|
|
|
|
{
|
2007-08-29 08:44:37 +07:00
|
|
|
xfs_iflags_clear(XFS_I(mapping->host), XFS_ITRUNCATED);
|
2006-06-09 12:27:16 +07:00
|
|
|
return generic_writepages(mapping, wbc);
|
|
|
|
}
|
|
|
|
|
2006-03-14 09:26:27 +07:00
|
|
|
/*
|
|
|
|
* Called to move a page into cleanable state - and from there
|
2010-06-24 06:45:48 +07:00
|
|
|
* to be released. The page should already be clean. We always
|
2006-03-14 09:26:27 +07:00
|
|
|
* have buffer heads in this call.
|
|
|
|
*
|
2010-06-24 06:45:48 +07:00
|
|
|
* Returns 1 if the page is ok to release, 0 otherwise.
|
2006-03-14 09:26:27 +07:00
|
|
|
*/
|
|
|
|
STATIC int
|
2006-03-17 13:26:25 +07:00
|
|
|
xfs_vm_releasepage(
|
2006-03-14 09:26:27 +07:00
|
|
|
struct page *page,
|
|
|
|
gfp_t gfp_mask)
|
|
|
|
{
|
2010-06-24 06:46:01 +07:00
|
|
|
int delalloc, unwritten;
|
2006-03-14 09:26:27 +07:00
|
|
|
|
2013-05-22 10:58:01 +07:00
|
|
|
trace_xfs_releasepage(page->mapping->host, page, 0, 0);
|
2006-03-17 13:26:25 +07:00
|
|
|
|
2010-06-24 06:46:01 +07:00
|
|
|
xfs_count_page_state(page, &delalloc, &unwritten);
|
2006-03-14 09:26:27 +07:00
|
|
|
|
2014-06-06 13:05:15 +07:00
|
|
|
if (WARN_ON_ONCE(delalloc))
|
2006-03-14 09:26:27 +07:00
|
|
|
return 0;
|
2014-06-06 13:05:15 +07:00
|
|
|
if (WARN_ON_ONCE(unwritten))
|
2006-03-14 09:26:27 +07:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
return try_to_free_buffers(page);
|
|
|
|
}
|
|
|
|
|
2015-04-16 18:57:48 +07:00
|
|
|
/*
|
2015-04-16 19:00:00 +07:00
|
|
|
* When we map a DIO buffer, we may need to attach an ioend that describes the
|
|
|
|
* type of write IO we are doing. This passes to the completion function the
|
|
|
|
* operations it needs to perform. If the mapping is for an overwrite wholly
|
|
|
|
* within the EOF then we don't need an ioend and so we don't allocate one.
|
|
|
|
* This avoids the unnecessary overhead of allocating and freeing ioends for
|
|
|
|
* workloads that don't require transactions on IO completion.
|
2015-04-16 18:59:07 +07:00
|
|
|
*
|
|
|
|
* If we get multiple mappings in a single IO, we might be mapping different
|
|
|
|
* types. But because the direct IO can only have a single private pointer, we
|
|
|
|
* need to ensure that:
|
|
|
|
*
|
2015-04-16 19:00:00 +07:00
|
|
|
* a) i) the ioend spans the entire region of unwritten mappings; or
|
|
|
|
* ii) the ioend spans all the mappings that cross or are beyond EOF; and
|
2015-04-16 18:59:07 +07:00
|
|
|
* b) if it contains unwritten extents, it is *permanently* marked as such
|
|
|
|
*
|
|
|
|
* We could do this by chaining ioends like buffered IO does, but we only
|
|
|
|
* actually get one IO completion callback from the direct IO, and that spans
|
|
|
|
* the entire IO regardless of how many mappings and IOs are needed to complete
|
|
|
|
* the DIO. There is only going to be one reference to the ioend and its life
|
|
|
|
* cycle is constrained by the DIO completion code. hence we don't need
|
|
|
|
* reference counting here.
|
2015-04-16 18:57:48 +07:00
|
|
|
*/
|
|
|
|
static void
|
|
|
|
xfs_map_direct(
|
|
|
|
struct inode *inode,
|
|
|
|
struct buffer_head *bh_result,
|
|
|
|
struct xfs_bmbt_irec *imap,
|
|
|
|
xfs_off_t offset)
|
|
|
|
{
|
2015-04-16 18:59:07 +07:00
|
|
|
struct xfs_ioend *ioend;
|
|
|
|
xfs_off_t size = bh_result->b_size;
|
|
|
|
int type;
|
|
|
|
|
|
|
|
if (ISUNWRITTEN(imap))
|
|
|
|
type = XFS_IO_UNWRITTEN;
|
|
|
|
else
|
|
|
|
type = XFS_IO_OVERWRITE;
|
|
|
|
|
|
|
|
trace_xfs_gbmap_direct(XFS_I(inode), offset, size, type, imap);
|
|
|
|
|
|
|
|
if (bh_result->b_private) {
|
|
|
|
ioend = bh_result->b_private;
|
|
|
|
ASSERT(ioend->io_size > 0);
|
|
|
|
ASSERT(offset >= ioend->io_offset);
|
|
|
|
if (offset + size > ioend->io_offset + ioend->io_size)
|
|
|
|
ioend->io_size = offset - ioend->io_offset + size;
|
|
|
|
|
|
|
|
if (type == XFS_IO_UNWRITTEN && type != ioend->io_type)
|
|
|
|
ioend->io_type = XFS_IO_UNWRITTEN;
|
|
|
|
|
|
|
|
trace_xfs_gbmap_direct_update(XFS_I(inode), ioend->io_offset,
|
|
|
|
ioend->io_size, ioend->io_type,
|
|
|
|
imap);
|
2015-04-16 19:00:00 +07:00
|
|
|
} else if (type == XFS_IO_UNWRITTEN ||
|
|
|
|
offset + size > i_size_read(inode)) {
|
2015-04-16 18:59:07 +07:00
|
|
|
ioend = xfs_alloc_ioend(inode, type);
|
|
|
|
ioend->io_offset = offset;
|
|
|
|
ioend->io_size = size;
|
2015-04-16 19:00:00 +07:00
|
|
|
|
2015-04-16 18:59:07 +07:00
|
|
|
bh_result->b_private = ioend;
|
2015-04-16 19:00:00 +07:00
|
|
|
set_buffer_defer_completion(bh_result);
|
2015-04-16 18:59:07 +07:00
|
|
|
|
|
|
|
trace_xfs_gbmap_direct_new(XFS_I(inode), offset, size, type,
|
|
|
|
imap);
|
2015-04-16 19:00:00 +07:00
|
|
|
} else {
|
|
|
|
trace_xfs_gbmap_direct_none(XFS_I(inode), offset, size, type,
|
|
|
|
imap);
|
2015-04-16 18:57:48 +07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-16 18:58:21 +07:00
|
|
|
/*
|
|
|
|
* If this is O_DIRECT or the mpage code calling tell them how large the mapping
|
|
|
|
* is, so that we can avoid repeated get_blocks calls.
|
|
|
|
*
|
|
|
|
* If the mapping spans EOF, then we have to break the mapping up as the mapping
|
|
|
|
* for blocks beyond EOF must be marked new so that sub block regions can be
|
|
|
|
* correctly zeroed. We can't do this for mappings within EOF unless the mapping
|
|
|
|
* was just allocated or is unwritten, otherwise the callers would overwrite
|
|
|
|
* existing data with zeros. Hence we have to split the mapping into a range up
|
|
|
|
* to and including EOF, and a second mapping for beyond EOF.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
xfs_map_trim_size(
|
|
|
|
struct inode *inode,
|
|
|
|
sector_t iblock,
|
|
|
|
struct buffer_head *bh_result,
|
|
|
|
struct xfs_bmbt_irec *imap,
|
|
|
|
xfs_off_t offset,
|
|
|
|
ssize_t size)
|
|
|
|
{
|
|
|
|
xfs_off_t mapping_size;
|
|
|
|
|
|
|
|
mapping_size = imap->br_startoff + imap->br_blockcount - iblock;
|
|
|
|
mapping_size <<= inode->i_blkbits;
|
|
|
|
|
|
|
|
ASSERT(mapping_size > 0);
|
|
|
|
if (mapping_size > size)
|
|
|
|
mapping_size = size;
|
|
|
|
if (offset < i_size_read(inode) &&
|
|
|
|
offset + mapping_size >= i_size_read(inode)) {
|
|
|
|
/* limit mapping to block that spans EOF */
|
|
|
|
mapping_size = roundup_64(i_size_read(inode) - offset,
|
|
|
|
1 << inode->i_blkbits);
|
|
|
|
}
|
|
|
|
if (mapping_size > LONG_MAX)
|
|
|
|
mapping_size = LONG_MAX;
|
|
|
|
|
|
|
|
bh_result->b_size = mapping_size;
|
|
|
|
}
|
|
|
|
|
2005-04-17 05:20:36 +07:00
|
|
|
STATIC int
|
2006-03-29 07:44:40 +07:00
|
|
|
__xfs_get_blocks(
|
2005-04-17 05:20:36 +07:00
|
|
|
struct inode *inode,
|
|
|
|
sector_t iblock,
|
|
|
|
struct buffer_head *bh_result,
|
|
|
|
int create,
|
2015-06-04 06:18:53 +07:00
|
|
|
bool direct)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
2010-12-10 15:42:20 +07:00
|
|
|
struct xfs_inode *ip = XFS_I(inode);
|
|
|
|
struct xfs_mount *mp = ip->i_mount;
|
|
|
|
xfs_fileoff_t offset_fsb, end_fsb;
|
|
|
|
int error = 0;
|
|
|
|
int lockmode = 0;
|
2010-04-28 19:28:56 +07:00
|
|
|
struct xfs_bmbt_irec imap;
|
2010-12-10 15:42:20 +07:00
|
|
|
int nimaps = 1;
|
2005-11-02 11:13:13 +07:00
|
|
|
xfs_off_t offset;
|
|
|
|
ssize_t size;
|
2010-04-28 19:28:56 +07:00
|
|
|
int new = 0;
|
2010-12-10 15:42:20 +07:00
|
|
|
|
|
|
|
if (XFS_FORCED_SHUTDOWN(mp))
|
2014-06-22 12:04:54 +07:00
|
|
|
return -EIO;
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2005-11-02 11:13:13 +07:00
|
|
|
offset = (xfs_off_t)iblock << inode->i_blkbits;
|
2006-03-29 07:44:40 +07:00
|
|
|
ASSERT(bh_result->b_size >= (1 << inode->i_blkbits));
|
|
|
|
size = bh_result->b_size;
|
2008-09-17 13:50:14 +07:00
|
|
|
|
|
|
|
if (!create && direct && offset >= i_size_read(inode))
|
|
|
|
return 0;
|
|
|
|
|
2012-03-27 21:34:50 +07:00
|
|
|
/*
|
|
|
|
* Direct I/O is usually done on preallocated files, so try getting
|
|
|
|
* a block mapping without an exclusive lock first. For buffered
|
|
|
|
* writes we already have the exclusive iolock anyway, so avoiding
|
|
|
|
* a lock roundtrip here by taking the ilock exclusive from the
|
|
|
|
* beginning is a useful micro optimization.
|
|
|
|
*/
|
|
|
|
if (create && !direct) {
|
2010-12-10 15:42:20 +07:00
|
|
|
lockmode = XFS_ILOCK_EXCL;
|
|
|
|
xfs_ilock(ip, lockmode);
|
|
|
|
} else {
|
2013-12-07 03:30:09 +07:00
|
|
|
lockmode = xfs_ilock_data_map_shared(ip);
|
2010-12-10 15:42:20 +07:00
|
|
|
}
|
2010-06-24 08:44:35 +07:00
|
|
|
|
2012-06-08 12:44:53 +07:00
|
|
|
ASSERT(offset <= mp->m_super->s_maxbytes);
|
|
|
|
if (offset + size > mp->m_super->s_maxbytes)
|
|
|
|
size = mp->m_super->s_maxbytes - offset;
|
2010-12-10 15:42:20 +07:00
|
|
|
end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + size);
|
|
|
|
offset_fsb = XFS_B_TO_FSBT(mp, offset);
|
|
|
|
|
2011-09-19 03:40:45 +07:00
|
|
|
error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb,
|
|
|
|
&imap, &nimaps, XFS_BMAPI_ENTIRE);
|
2005-04-17 05:20:36 +07:00
|
|
|
if (error)
|
2010-12-10 15:42:20 +07:00
|
|
|
goto out_unlock;
|
|
|
|
|
|
|
|
if (create &&
|
|
|
|
(!nimaps ||
|
|
|
|
(imap.br_startblock == HOLESTARTBLOCK ||
|
|
|
|
imap.br_startblock == DELAYSTARTBLOCK))) {
|
xfs: Use preallocation for inodes with extsz hints
xfstest 229 exposes a problem with buffered IO, delayed allocation
and extent size hints. That is when we do delayed allocation during
buffered IO, we reserve space for the extent size hint alignment and
allocate the physical space to align the extent, but we do not zero
the regions of the extent that aren't written by the write(2)
syscall. The result is that we expose stale data in unwritten
regions of the extent size hints.
There are two ways to fix this. The first is to detect that we are
doing unaligned writes, check if there is already a mapping or data
over the extent size hint range, and if not zero the page cache
first before then doing the real write. This can be very expensive
for large extent size hints, especially if the subsequent writes
fill then entire extent size before the data is written to disk.
The second, and simpler way, is simply to turn off delayed
allocation when the extent size hint is set and use preallocation
instead. This results in unwritten extents being laid down on disk
and so only the written portions will be converted. This matches the
behaviour for direct IO, and will also work for the real time
device. The disadvantage of this approach is that for small extent
size hints we can get file fragmentation, but in general extent size
hints are fairly large (e.g. stripe width sized) so this isn't a big
deal.
Implement the second approach as it is simple and effective.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-04-23 12:58:44 +07:00
|
|
|
if (direct || xfs_get_extsz_hint(ip)) {
|
2012-03-27 21:34:50 +07:00
|
|
|
/*
|
2015-10-12 11:34:20 +07:00
|
|
|
* xfs_iomap_write_direct() expects the shared lock. It
|
|
|
|
* is unlocked on return.
|
2012-03-27 21:34:50 +07:00
|
|
|
*/
|
2015-10-12 11:34:20 +07:00
|
|
|
if (lockmode == XFS_ILOCK_EXCL)
|
|
|
|
xfs_ilock_demote(ip, lockmode);
|
|
|
|
|
2010-12-10 15:42:20 +07:00
|
|
|
error = xfs_iomap_write_direct(ip, offset, size,
|
|
|
|
&imap, nimaps);
|
2012-03-27 21:34:50 +07:00
|
|
|
if (error)
|
2014-06-25 11:58:08 +07:00
|
|
|
return error;
|
xfs: punch new delalloc blocks out of failed writes inside EOF.
When a partial write inside EOF fails, it can leave delayed
allocation blocks lying around because they don't get punched back
out. This leads to assert failures like:
XFS: Assertion failed: XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0, file: fs/xfs/xfs_super.c, line: 847
when evicting inodes from the cache. This can be trivially triggered
by xfstests 083, which takes between 5 and 15 executions on a 512
byte block size filesystem to trip over this. Debugging shows a
failed write due to ENOSPC calling xfs_vm_write_failed such as:
[ 5012.329024] ino 0xa0026: vwf to 0x17000, sze 0x1c85ae
and no action is taken on it. This leaves behind a delayed
allocation extent that has no page covering it and no data in it:
[ 5015.867162] ino 0xa0026: blks: 0x83 delay blocks 0x1, size 0x2538c0
[ 5015.868293] ext 0: off 0x4a, fsb 0x50306, len 0x1
[ 5015.869095] ext 1: off 0x4b, fsb 0x7899, len 0x6b
[ 5015.869900] ext 2: off 0xb6, fsb 0xffffffffe0008, len 0x1
^^^^^^^^^^^^^^^
[ 5015.871027] ext 3: off 0x36e, fsb 0x7a27, len 0xd
[ 5015.872206] ext 4: off 0x4cf, fsb 0x7a1d, len 0xa
So the delayed allocation extent is one block long at offset
0x16c00. Tracing shows that a bigger write:
xfs_file_buffered_write: size 0x1c85ae offset 0x959d count 0x1ca3f ioflags
allocates the block, and then fails with ENOSPC trying to allocate
the last block on the page, leading to a failed write with stale
delalloc blocks on it.
Because we've had an ENOSPC when trying to allocate 0x16e00, it
means that we are never goinge to call ->write_end on the page and
so the allocated new buffer will not get marked dirty or have the
buffer_new state cleared. In other works, what the above write is
supposed to end up with is this mapping for the page:
+------+------+------+------+------+------+------+------+
UMA UMA UMA UMA UMA UMA UND FAIL
where: U = uptodate
M = mapped
N = new
A = allocated
D = delalloc
FAIL = block we ENOSPC'd on.
and the key point being the buffer_new() state for the newly
allocated delayed allocation block. Except it doesn't - we're not
marking buffers new correctly.
That buffer_new() problem goes back to the xfs_iomap removal days,
where xfs_iomap() used to return a "new" status for any map with
newly allocated blocks, so that __xfs_get_blocks() could call
set_buffer_new() on it. We still have the "new" variable and the
check for it in the set_buffer_new() logic - except we never set it
now!
Hence that newly allocated delalloc block doesn't have the new flag
set on it, so when the write fails we cannot tell which blocks we
are supposed to punch out. WHy do we need the buffer_new flag? Well,
that's because we can have this case:
+------+------+------+------+------+------+------+------+
UMD UMD UMD UMD UMD UMD UND FAIL
where all the UMD buffers contain valid data from a previously
successful write() system call. We only want to punch the UND buffer
because that's the only one that we added in this write and it was
only this write that failed.
That implies that even the old buffer_new() logic was wrong -
because it would result in all those UMD buffers on the page having
set_buffer_new() called on them even though they aren't new. Hence
we shoul donly be calling set_buffer_new() for delalloc buffers that
were allocated (i.e. were a hole before xfs_iomap_write_delay() was
called).
So, fix this set_buffer_new logic according to how we need it to
work for handling failed writes correctly. Also, restore the new
buffer logic handling for blocks allocated via
xfs_iomap_write_direct(), because it should still set the buffer_new
flag appropriately for newly allocated blocks, too.
SO, now we have the buffer_new() being set appropriately in
__xfs_get_blocks(), we can detect the exact delalloc ranges that
we allocated in a failed write, and hence can now do a walk of the
buffers on a page to find them.
Except, it's not that easy. When block_write_begin() fails, it
unlocks and releases the page that we just had an error on, so we
can't use that page to handle errors anymore. We have to get access
to the page while it is still locked to walk the buffers. Hence we
have to open code block_write_begin() in xfs_vm_write_begin() to be
able to insert xfs_vm_write_failed() is the right place.
With that, we can pass the page and write range to
xfs_vm_write_failed() and walk the buffers on the page, looking for
delalloc buffers that are either new or beyond EOF and punch them
out. Handling buffers beyond EOF ensures we still handle the
existing case that xfs_vm_write_failed() handles.
Of special note is the truncate_pagecache() handling - that only
should be done for pages outside EOF - pages within EOF can still
contain valid, dirty data so we must not punch them out of the
cache.
That just leaves the xfs_vm_write_end() failure handling.
The only failure case here is that we didn't copy the entire range,
and generic_write_end() handles that by zeroing the region of the
page that wasn't copied, we don't have to punch out blocks within
the file because they are guaranteed to contain zeros. Hence we only
have to handle the existing "beyond EOF" case and don't need access
to the buffers on the page. Hence it remains largely unchanged.
Note that xfs_getbmap() can still trip over delalloc blocks beyond
EOF that are left there by speculative delayed allocation. Hence
this bug fix does not solve all known issues with bmap vs delalloc,
but it does fix all the the known accidental occurances of the
problem.
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-04-27 16:45:21 +07:00
|
|
|
new = 1;
|
2015-06-04 06:18:53 +07:00
|
|
|
|
2010-12-10 15:42:20 +07:00
|
|
|
} else {
|
2012-03-27 21:34:50 +07:00
|
|
|
/*
|
|
|
|
* Delalloc reservations do not require a transaction,
|
xfs: punch new delalloc blocks out of failed writes inside EOF.
When a partial write inside EOF fails, it can leave delayed
allocation blocks lying around because they don't get punched back
out. This leads to assert failures like:
XFS: Assertion failed: XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0, file: fs/xfs/xfs_super.c, line: 847
when evicting inodes from the cache. This can be trivially triggered
by xfstests 083, which takes between 5 and 15 executions on a 512
byte block size filesystem to trip over this. Debugging shows a
failed write due to ENOSPC calling xfs_vm_write_failed such as:
[ 5012.329024] ino 0xa0026: vwf to 0x17000, sze 0x1c85ae
and no action is taken on it. This leaves behind a delayed
allocation extent that has no page covering it and no data in it:
[ 5015.867162] ino 0xa0026: blks: 0x83 delay blocks 0x1, size 0x2538c0
[ 5015.868293] ext 0: off 0x4a, fsb 0x50306, len 0x1
[ 5015.869095] ext 1: off 0x4b, fsb 0x7899, len 0x6b
[ 5015.869900] ext 2: off 0xb6, fsb 0xffffffffe0008, len 0x1
^^^^^^^^^^^^^^^
[ 5015.871027] ext 3: off 0x36e, fsb 0x7a27, len 0xd
[ 5015.872206] ext 4: off 0x4cf, fsb 0x7a1d, len 0xa
So the delayed allocation extent is one block long at offset
0x16c00. Tracing shows that a bigger write:
xfs_file_buffered_write: size 0x1c85ae offset 0x959d count 0x1ca3f ioflags
allocates the block, and then fails with ENOSPC trying to allocate
the last block on the page, leading to a failed write with stale
delalloc blocks on it.
Because we've had an ENOSPC when trying to allocate 0x16e00, it
means that we are never goinge to call ->write_end on the page and
so the allocated new buffer will not get marked dirty or have the
buffer_new state cleared. In other works, what the above write is
supposed to end up with is this mapping for the page:
+------+------+------+------+------+------+------+------+
UMA UMA UMA UMA UMA UMA UND FAIL
where: U = uptodate
M = mapped
N = new
A = allocated
D = delalloc
FAIL = block we ENOSPC'd on.
and the key point being the buffer_new() state for the newly
allocated delayed allocation block. Except it doesn't - we're not
marking buffers new correctly.
That buffer_new() problem goes back to the xfs_iomap removal days,
where xfs_iomap() used to return a "new" status for any map with
newly allocated blocks, so that __xfs_get_blocks() could call
set_buffer_new() on it. We still have the "new" variable and the
check for it in the set_buffer_new() logic - except we never set it
now!
Hence that newly allocated delalloc block doesn't have the new flag
set on it, so when the write fails we cannot tell which blocks we
are supposed to punch out. WHy do we need the buffer_new flag? Well,
that's because we can have this case:
+------+------+------+------+------+------+------+------+
UMD UMD UMD UMD UMD UMD UND FAIL
where all the UMD buffers contain valid data from a previously
successful write() system call. We only want to punch the UND buffer
because that's the only one that we added in this write and it was
only this write that failed.
That implies that even the old buffer_new() logic was wrong -
because it would result in all those UMD buffers on the page having
set_buffer_new() called on them even though they aren't new. Hence
we shoul donly be calling set_buffer_new() for delalloc buffers that
were allocated (i.e. were a hole before xfs_iomap_write_delay() was
called).
So, fix this set_buffer_new logic according to how we need it to
work for handling failed writes correctly. Also, restore the new
buffer logic handling for blocks allocated via
xfs_iomap_write_direct(), because it should still set the buffer_new
flag appropriately for newly allocated blocks, too.
SO, now we have the buffer_new() being set appropriately in
__xfs_get_blocks(), we can detect the exact delalloc ranges that
we allocated in a failed write, and hence can now do a walk of the
buffers on a page to find them.
Except, it's not that easy. When block_write_begin() fails, it
unlocks and releases the page that we just had an error on, so we
can't use that page to handle errors anymore. We have to get access
to the page while it is still locked to walk the buffers. Hence we
have to open code block_write_begin() in xfs_vm_write_begin() to be
able to insert xfs_vm_write_failed() is the right place.
With that, we can pass the page and write range to
xfs_vm_write_failed() and walk the buffers on the page, looking for
delalloc buffers that are either new or beyond EOF and punch them
out. Handling buffers beyond EOF ensures we still handle the
existing case that xfs_vm_write_failed() handles.
Of special note is the truncate_pagecache() handling - that only
should be done for pages outside EOF - pages within EOF can still
contain valid, dirty data so we must not punch them out of the
cache.
That just leaves the xfs_vm_write_end() failure handling.
The only failure case here is that we didn't copy the entire range,
and generic_write_end() handles that by zeroing the region of the
page that wasn't copied, we don't have to punch out blocks within
the file because they are guaranteed to contain zeros. Hence we only
have to handle the existing "beyond EOF" case and don't need access
to the buffers on the page. Hence it remains largely unchanged.
Note that xfs_getbmap() can still trip over delalloc blocks beyond
EOF that are left there by speculative delayed allocation. Hence
this bug fix does not solve all known issues with bmap vs delalloc,
but it does fix all the the known accidental occurances of the
problem.
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-04-27 16:45:21 +07:00
|
|
|
* we can go on without dropping the lock here. If we
|
|
|
|
* are allocating a new delalloc block, make sure that
|
|
|
|
* we set the new flag so that we mark the buffer new so
|
|
|
|
* that we know that it is newly allocated if the write
|
|
|
|
* fails.
|
2012-03-27 21:34:50 +07:00
|
|
|
*/
|
xfs: punch new delalloc blocks out of failed writes inside EOF.
When a partial write inside EOF fails, it can leave delayed
allocation blocks lying around because they don't get punched back
out. This leads to assert failures like:
XFS: Assertion failed: XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0, file: fs/xfs/xfs_super.c, line: 847
when evicting inodes from the cache. This can be trivially triggered
by xfstests 083, which takes between 5 and 15 executions on a 512
byte block size filesystem to trip over this. Debugging shows a
failed write due to ENOSPC calling xfs_vm_write_failed such as:
[ 5012.329024] ino 0xa0026: vwf to 0x17000, sze 0x1c85ae
and no action is taken on it. This leaves behind a delayed
allocation extent that has no page covering it and no data in it:
[ 5015.867162] ino 0xa0026: blks: 0x83 delay blocks 0x1, size 0x2538c0
[ 5015.868293] ext 0: off 0x4a, fsb 0x50306, len 0x1
[ 5015.869095] ext 1: off 0x4b, fsb 0x7899, len 0x6b
[ 5015.869900] ext 2: off 0xb6, fsb 0xffffffffe0008, len 0x1
^^^^^^^^^^^^^^^
[ 5015.871027] ext 3: off 0x36e, fsb 0x7a27, len 0xd
[ 5015.872206] ext 4: off 0x4cf, fsb 0x7a1d, len 0xa
So the delayed allocation extent is one block long at offset
0x16c00. Tracing shows that a bigger write:
xfs_file_buffered_write: size 0x1c85ae offset 0x959d count 0x1ca3f ioflags
allocates the block, and then fails with ENOSPC trying to allocate
the last block on the page, leading to a failed write with stale
delalloc blocks on it.
Because we've had an ENOSPC when trying to allocate 0x16e00, it
means that we are never goinge to call ->write_end on the page and
so the allocated new buffer will not get marked dirty or have the
buffer_new state cleared. In other works, what the above write is
supposed to end up with is this mapping for the page:
+------+------+------+------+------+------+------+------+
UMA UMA UMA UMA UMA UMA UND FAIL
where: U = uptodate
M = mapped
N = new
A = allocated
D = delalloc
FAIL = block we ENOSPC'd on.
and the key point being the buffer_new() state for the newly
allocated delayed allocation block. Except it doesn't - we're not
marking buffers new correctly.
That buffer_new() problem goes back to the xfs_iomap removal days,
where xfs_iomap() used to return a "new" status for any map with
newly allocated blocks, so that __xfs_get_blocks() could call
set_buffer_new() on it. We still have the "new" variable and the
check for it in the set_buffer_new() logic - except we never set it
now!
Hence that newly allocated delalloc block doesn't have the new flag
set on it, so when the write fails we cannot tell which blocks we
are supposed to punch out. WHy do we need the buffer_new flag? Well,
that's because we can have this case:
+------+------+------+------+------+------+------+------+
UMD UMD UMD UMD UMD UMD UND FAIL
where all the UMD buffers contain valid data from a previously
successful write() system call. We only want to punch the UND buffer
because that's the only one that we added in this write and it was
only this write that failed.
That implies that even the old buffer_new() logic was wrong -
because it would result in all those UMD buffers on the page having
set_buffer_new() called on them even though they aren't new. Hence
we shoul donly be calling set_buffer_new() for delalloc buffers that
were allocated (i.e. were a hole before xfs_iomap_write_delay() was
called).
So, fix this set_buffer_new logic according to how we need it to
work for handling failed writes correctly. Also, restore the new
buffer logic handling for blocks allocated via
xfs_iomap_write_direct(), because it should still set the buffer_new
flag appropriately for newly allocated blocks, too.
SO, now we have the buffer_new() being set appropriately in
__xfs_get_blocks(), we can detect the exact delalloc ranges that
we allocated in a failed write, and hence can now do a walk of the
buffers on a page to find them.
Except, it's not that easy. When block_write_begin() fails, it
unlocks and releases the page that we just had an error on, so we
can't use that page to handle errors anymore. We have to get access
to the page while it is still locked to walk the buffers. Hence we
have to open code block_write_begin() in xfs_vm_write_begin() to be
able to insert xfs_vm_write_failed() is the right place.
With that, we can pass the page and write range to
xfs_vm_write_failed() and walk the buffers on the page, looking for
delalloc buffers that are either new or beyond EOF and punch them
out. Handling buffers beyond EOF ensures we still handle the
existing case that xfs_vm_write_failed() handles.
Of special note is the truncate_pagecache() handling - that only
should be done for pages outside EOF - pages within EOF can still
contain valid, dirty data so we must not punch them out of the
cache.
That just leaves the xfs_vm_write_end() failure handling.
The only failure case here is that we didn't copy the entire range,
and generic_write_end() handles that by zeroing the region of the
page that wasn't copied, we don't have to punch out blocks within
the file because they are guaranteed to contain zeros. Hence we only
have to handle the existing "beyond EOF" case and don't need access
to the buffers on the page. Hence it remains largely unchanged.
Note that xfs_getbmap() can still trip over delalloc blocks beyond
EOF that are left there by speculative delayed allocation. Hence
this bug fix does not solve all known issues with bmap vs delalloc,
but it does fix all the the known accidental occurances of the
problem.
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-04-27 16:45:21 +07:00
|
|
|
if (nimaps && imap.br_startblock == HOLESTARTBLOCK)
|
|
|
|
new = 1;
|
2010-12-10 15:42:20 +07:00
|
|
|
error = xfs_iomap_write_delay(ip, offset, size, &imap);
|
2012-03-27 21:34:50 +07:00
|
|
|
if (error)
|
|
|
|
goto out_unlock;
|
|
|
|
|
|
|
|
xfs_iunlock(ip, lockmode);
|
2010-12-10 15:42:20 +07:00
|
|
|
}
|
2015-04-16 18:59:07 +07:00
|
|
|
trace_xfs_get_blocks_alloc(ip, offset, size,
|
|
|
|
ISUNWRITTEN(&imap) ? XFS_IO_UNWRITTEN
|
|
|
|
: XFS_IO_DELALLOC, &imap);
|
2010-12-10 15:42:20 +07:00
|
|
|
} else if (nimaps) {
|
2015-04-16 18:59:07 +07:00
|
|
|
trace_xfs_get_blocks_found(ip, offset, size,
|
|
|
|
ISUNWRITTEN(&imap) ? XFS_IO_UNWRITTEN
|
|
|
|
: XFS_IO_OVERWRITE, &imap);
|
2012-03-27 21:34:50 +07:00
|
|
|
xfs_iunlock(ip, lockmode);
|
2010-12-10 15:42:20 +07:00
|
|
|
} else {
|
|
|
|
trace_xfs_get_blocks_notfound(ip, offset, size);
|
|
|
|
goto out_unlock;
|
|
|
|
}
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2015-04-16 18:58:21 +07:00
|
|
|
/* trim mapping down to size requested */
|
|
|
|
if (direct || size > (1 << inode->i_blkbits))
|
|
|
|
xfs_map_trim_size(inode, iblock, bh_result,
|
|
|
|
&imap, offset, size);
|
|
|
|
|
2015-04-16 18:57:48 +07:00
|
|
|
/*
|
|
|
|
* For unwritten extents do not report a disk address in the buffered
|
|
|
|
* read case (treat as if we're reading into a hole).
|
|
|
|
*/
|
2010-04-28 19:28:56 +07:00
|
|
|
if (imap.br_startblock != HOLESTARTBLOCK &&
|
2015-04-16 18:57:48 +07:00
|
|
|
imap.br_startblock != DELAYSTARTBLOCK &&
|
|
|
|
(create || !ISUNWRITTEN(&imap))) {
|
|
|
|
xfs_map_buffer(inode, bh_result, &imap, offset);
|
|
|
|
if (ISUNWRITTEN(&imap))
|
2005-04-17 05:20:36 +07:00
|
|
|
set_buffer_unwritten(bh_result);
|
2015-04-16 18:57:48 +07:00
|
|
|
/* direct IO needs special help */
|
|
|
|
if (create && direct)
|
|
|
|
xfs_map_direct(inode, bh_result, &imap, offset);
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
2006-03-29 07:44:40 +07:00
|
|
|
/*
|
|
|
|
* If this is a realtime file, data may be on a different device.
|
|
|
|
* to that pointed to from the buffer_head b_bdev currently.
|
|
|
|
*/
|
2010-04-28 19:28:52 +07:00
|
|
|
bh_result->b_bdev = xfs_find_bdev_for_inode(inode);
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2006-03-29 07:44:40 +07:00
|
|
|
/*
|
2007-02-10 14:36:35 +07:00
|
|
|
* If we previously allocated a block out beyond eof and we are now
|
|
|
|
* coming back to use it then we will need to flag it as new even if it
|
|
|
|
* has a disk address.
|
|
|
|
*
|
|
|
|
* With sub-block writes into unwritten extents we also need to mark
|
|
|
|
* the buffer as new so that the unwritten parts of the buffer gets
|
|
|
|
* correctly zeroed.
|
2005-04-17 05:20:36 +07:00
|
|
|
*/
|
|
|
|
if (create &&
|
|
|
|
((!buffer_mapped(bh_result) && !buffer_uptodate(bh_result)) ||
|
2007-02-10 14:36:35 +07:00
|
|
|
(offset >= i_size_read(inode)) ||
|
2010-04-28 19:28:56 +07:00
|
|
|
(new || ISUNWRITTEN(&imap))))
|
2005-04-17 05:20:36 +07:00
|
|
|
set_buffer_new(bh_result);
|
|
|
|
|
2010-04-28 19:28:56 +07:00
|
|
|
if (imap.br_startblock == DELAYSTARTBLOCK) {
|
2005-04-17 05:20:36 +07:00
|
|
|
BUG_ON(direct);
|
|
|
|
if (create) {
|
|
|
|
set_buffer_uptodate(bh_result);
|
|
|
|
set_buffer_mapped(bh_result);
|
|
|
|
set_buffer_delay(bh_result);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2010-12-10 15:42:20 +07:00
|
|
|
|
|
|
|
out_unlock:
|
|
|
|
xfs_iunlock(ip, lockmode);
|
2014-06-25 11:58:08 +07:00
|
|
|
return error;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2006-03-29 07:44:40 +07:00
|
|
|
xfs_get_blocks(
|
2005-04-17 05:20:36 +07:00
|
|
|
struct inode *inode,
|
|
|
|
sector_t iblock,
|
|
|
|
struct buffer_head *bh_result,
|
|
|
|
int create)
|
|
|
|
{
|
2015-06-04 06:18:53 +07:00
|
|
|
return __xfs_get_blocks(inode, iblock, bh_result, create, false);
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
2015-06-04 06:18:53 +07:00
|
|
|
int
|
2006-03-14 09:54:26 +07:00
|
|
|
xfs_get_blocks_direct(
|
2005-04-17 05:20:36 +07:00
|
|
|
struct inode *inode,
|
|
|
|
sector_t iblock,
|
|
|
|
struct buffer_head *bh_result,
|
|
|
|
int create)
|
|
|
|
{
|
2015-06-04 06:18:53 +07:00
|
|
|
return __xfs_get_blocks(inode, iblock, bh_result, create, true);
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
2015-06-04 06:18:53 +07:00
|
|
|
static void
|
|
|
|
__xfs_end_io_direct_write(
|
|
|
|
struct inode *inode,
|
|
|
|
struct xfs_ioend *ioend,
|
2010-07-19 04:17:11 +07:00
|
|
|
loff_t offset,
|
2015-06-04 06:18:53 +07:00
|
|
|
ssize_t size)
|
2005-09-05 05:22:52 +07:00
|
|
|
{
|
2015-06-04 06:18:53 +07:00
|
|
|
struct xfs_mount *mp = XFS_I(inode)->i_mount;
|
2015-04-16 19:00:00 +07:00
|
|
|
|
2015-06-04 06:18:53 +07:00
|
|
|
if (XFS_FORCED_SHUTDOWN(mp) || ioend->io_error)
|
2015-04-16 18:59:34 +07:00
|
|
|
goto out_end_io;
|
2005-09-05 05:22:52 +07:00
|
|
|
|
2011-12-19 03:00:12 +07:00
|
|
|
/*
|
2015-04-16 18:59:07 +07:00
|
|
|
* dio completion end_io functions are only called on writes if more
|
|
|
|
* than 0 bytes was written.
|
2011-12-19 03:00:12 +07:00
|
|
|
*/
|
2015-04-16 18:59:07 +07:00
|
|
|
ASSERT(size > 0);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The ioend only maps whole blocks, while the IO may be sector aligned.
|
2015-04-16 19:00:00 +07:00
|
|
|
* Hence the ioend offset/size may not match the IO offset/size exactly.
|
|
|
|
* Because we don't map overwrites within EOF into the ioend, the offset
|
|
|
|
* may not match, but only if the endio spans EOF. Either way, write
|
|
|
|
* the IO sizes into the ioend so that completion processing does the
|
|
|
|
* right thing.
|
2015-04-16 18:59:07 +07:00
|
|
|
*/
|
|
|
|
ASSERT(offset + size <= ioend->io_offset + ioend->io_size);
|
|
|
|
ioend->io_size = size;
|
|
|
|
ioend->io_offset = offset;
|
2005-09-05 05:22:52 +07:00
|
|
|
|
2011-12-19 03:00:12 +07:00
|
|
|
/*
|
2015-04-16 18:59:34 +07:00
|
|
|
* The ioend tells us whether we are doing unwritten extent conversion
|
|
|
|
* or an append transaction that updates the on-disk file size. These
|
|
|
|
* cases are the only cases where we should *potentially* be needing
|
2015-04-16 19:00:00 +07:00
|
|
|
* to update the VFS inode size.
|
2015-04-16 18:59:34 +07:00
|
|
|
*
|
|
|
|
* We need to update the in-core inode size here so that we don't end up
|
2015-04-16 19:00:00 +07:00
|
|
|
* with the on-disk inode size being outside the in-core inode size. We
|
|
|
|
* have no other method of updating EOF for AIO, so always do it here
|
|
|
|
* if necessary.
|
2015-04-16 19:03:07 +07:00
|
|
|
*
|
|
|
|
* We need to lock the test/set EOF update as we can be racing with
|
|
|
|
* other IO completions here to update the EOF. Failing to serialise
|
|
|
|
* here can result in EOF moving backwards and Bad Things Happen when
|
|
|
|
* that occurs.
|
2011-12-19 03:00:12 +07:00
|
|
|
*/
|
2015-06-04 06:18:53 +07:00
|
|
|
spin_lock(&XFS_I(inode)->i_flags_lock);
|
2015-02-02 06:02:09 +07:00
|
|
|
if (offset + size > i_size_read(inode))
|
|
|
|
i_size_write(inode, offset + size);
|
2015-06-04 06:18:53 +07:00
|
|
|
spin_unlock(&XFS_I(inode)->i_flags_lock);
|
2011-12-19 03:00:12 +07:00
|
|
|
|
2005-09-05 05:22:52 +07:00
|
|
|
/*
|
2015-04-16 18:59:34 +07:00
|
|
|
* If we are doing an append IO that needs to update the EOF on disk,
|
|
|
|
* do the transaction reserve now so we can use common end io
|
|
|
|
* processing. Stashing the error (if there is one) in the ioend will
|
|
|
|
* result in the ioend processing passing on the error if it is
|
|
|
|
* possible as we can't return it from here.
|
2005-09-05 05:22:52 +07:00
|
|
|
*/
|
2015-04-16 19:00:00 +07:00
|
|
|
if (ioend->io_type == XFS_IO_OVERWRITE)
|
2015-04-16 18:59:34 +07:00
|
|
|
ioend->io_error = xfs_setfilesize_trans_alloc(ioend);
|
2010-07-19 04:17:11 +07:00
|
|
|
|
2015-04-16 18:59:34 +07:00
|
|
|
out_end_io:
|
|
|
|
xfs_end_io(&ioend->io_work);
|
|
|
|
return;
|
2005-09-05 05:22:52 +07:00
|
|
|
}
|
|
|
|
|
2015-06-04 06:18:53 +07:00
|
|
|
/*
|
|
|
|
* Complete a direct I/O write request.
|
|
|
|
*
|
|
|
|
* The ioend structure is passed from __xfs_get_blocks() to tell us what to do.
|
|
|
|
* If no ioend exists (i.e. @private == NULL) then the write IO is an overwrite
|
|
|
|
* wholly within the EOF and so there is nothing for us to do. Note that in this
|
|
|
|
* case the completion can be called in interrupt context, whereas if we have an
|
|
|
|
* ioend we will always be called in task context (i.e. from a workqueue).
|
|
|
|
*/
|
|
|
|
STATIC void
|
|
|
|
xfs_end_io_direct_write(
|
|
|
|
struct kiocb *iocb,
|
|
|
|
loff_t offset,
|
|
|
|
ssize_t size,
|
|
|
|
void *private)
|
|
|
|
{
|
|
|
|
struct inode *inode = file_inode(iocb->ki_filp);
|
|
|
|
struct xfs_ioend *ioend = private;
|
|
|
|
|
|
|
|
trace_xfs_gbmap_direct_endio(XFS_I(inode), offset, size,
|
|
|
|
ioend ? ioend->io_type : 0, NULL);
|
|
|
|
|
|
|
|
if (!ioend) {
|
|
|
|
ASSERT(offset + size <= i_size_read(inode));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
__xfs_end_io_direct_write(inode, ioend, offset, size);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* For DAX we need a mapping buffer callback for unwritten extent conversion
|
|
|
|
* when page faults allocate blocks and then zero them. Note that in this
|
|
|
|
* case the mapping indicated by the ioend may extend beyond EOF. We most
|
|
|
|
* definitely do not want to extend EOF here, so we trim back the ioend size to
|
|
|
|
* EOF.
|
|
|
|
*/
|
|
|
|
#ifdef CONFIG_FS_DAX
|
|
|
|
void
|
|
|
|
xfs_end_io_dax_write(
|
|
|
|
struct buffer_head *bh,
|
|
|
|
int uptodate)
|
|
|
|
{
|
|
|
|
struct xfs_ioend *ioend = bh->b_private;
|
|
|
|
struct inode *inode = ioend->io_inode;
|
|
|
|
ssize_t size = ioend->io_size;
|
|
|
|
|
|
|
|
ASSERT(IS_DAX(ioend->io_inode));
|
|
|
|
|
|
|
|
/* if there was an error zeroing, then don't convert it */
|
|
|
|
if (!uptodate)
|
|
|
|
ioend->io_error = -EIO;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Trim update to EOF, so we don't extend EOF during unwritten extent
|
|
|
|
* conversion of partial EOF blocks.
|
|
|
|
*/
|
|
|
|
spin_lock(&XFS_I(inode)->i_flags_lock);
|
|
|
|
if (ioend->io_offset + size > i_size_read(inode))
|
|
|
|
size = i_size_read(inode) - ioend->io_offset;
|
|
|
|
spin_unlock(&XFS_I(inode)->i_flags_lock);
|
|
|
|
|
|
|
|
__xfs_end_io_direct_write(inode, ioend, ioend->io_offset, size);
|
|
|
|
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
void xfs_end_io_dax_write(struct buffer_head *bh, int uptodate) { }
|
|
|
|
#endif
|
|
|
|
|
2015-06-04 06:19:15 +07:00
|
|
|
static inline ssize_t
|
|
|
|
xfs_vm_do_dio(
|
|
|
|
struct inode *inode,
|
|
|
|
struct kiocb *iocb,
|
|
|
|
struct iov_iter *iter,
|
|
|
|
loff_t offset,
|
|
|
|
void (*endio)(struct kiocb *iocb,
|
|
|
|
loff_t offset,
|
|
|
|
ssize_t size,
|
|
|
|
void *private),
|
|
|
|
int flags)
|
|
|
|
{
|
|
|
|
struct block_device *bdev;
|
|
|
|
|
|
|
|
if (IS_DAX(inode))
|
|
|
|
return dax_do_io(iocb, inode, iter, offset,
|
|
|
|
xfs_get_blocks_direct, endio, 0);
|
|
|
|
|
|
|
|
bdev = xfs_find_bdev_for_inode(inode);
|
|
|
|
return __blockdev_direct_IO(iocb, inode, bdev, iter, offset,
|
|
|
|
xfs_get_blocks_direct, endio, NULL, flags);
|
|
|
|
}
|
|
|
|
|
2005-04-17 05:20:36 +07:00
|
|
|
STATIC ssize_t
|
2006-03-14 09:54:26 +07:00
|
|
|
xfs_vm_direct_IO(
|
2005-04-17 05:20:36 +07:00
|
|
|
struct kiocb *iocb,
|
2014-03-05 09:27:34 +07:00
|
|
|
struct iov_iter *iter,
|
|
|
|
loff_t offset)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
2010-07-19 04:17:11 +07:00
|
|
|
struct inode *inode = iocb->ki_filp->f_mapping->host;
|
|
|
|
|
2015-06-04 06:19:15 +07:00
|
|
|
if (iov_iter_rw(iter) == WRITE)
|
|
|
|
return xfs_vm_do_dio(inode, iocb, iter, offset,
|
|
|
|
xfs_end_io_direct_write, DIO_ASYNC_EXTEND);
|
|
|
|
return xfs_vm_do_dio(inode, iocb, iter, offset, NULL, 0);
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
xfs: punch new delalloc blocks out of failed writes inside EOF.
When a partial write inside EOF fails, it can leave delayed
allocation blocks lying around because they don't get punched back
out. This leads to assert failures like:
XFS: Assertion failed: XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0, file: fs/xfs/xfs_super.c, line: 847
when evicting inodes from the cache. This can be trivially triggered
by xfstests 083, which takes between 5 and 15 executions on a 512
byte block size filesystem to trip over this. Debugging shows a
failed write due to ENOSPC calling xfs_vm_write_failed such as:
[ 5012.329024] ino 0xa0026: vwf to 0x17000, sze 0x1c85ae
and no action is taken on it. This leaves behind a delayed
allocation extent that has no page covering it and no data in it:
[ 5015.867162] ino 0xa0026: blks: 0x83 delay blocks 0x1, size 0x2538c0
[ 5015.868293] ext 0: off 0x4a, fsb 0x50306, len 0x1
[ 5015.869095] ext 1: off 0x4b, fsb 0x7899, len 0x6b
[ 5015.869900] ext 2: off 0xb6, fsb 0xffffffffe0008, len 0x1
^^^^^^^^^^^^^^^
[ 5015.871027] ext 3: off 0x36e, fsb 0x7a27, len 0xd
[ 5015.872206] ext 4: off 0x4cf, fsb 0x7a1d, len 0xa
So the delayed allocation extent is one block long at offset
0x16c00. Tracing shows that a bigger write:
xfs_file_buffered_write: size 0x1c85ae offset 0x959d count 0x1ca3f ioflags
allocates the block, and then fails with ENOSPC trying to allocate
the last block on the page, leading to a failed write with stale
delalloc blocks on it.
Because we've had an ENOSPC when trying to allocate 0x16e00, it
means that we are never goinge to call ->write_end on the page and
so the allocated new buffer will not get marked dirty or have the
buffer_new state cleared. In other works, what the above write is
supposed to end up with is this mapping for the page:
+------+------+------+------+------+------+------+------+
UMA UMA UMA UMA UMA UMA UND FAIL
where: U = uptodate
M = mapped
N = new
A = allocated
D = delalloc
FAIL = block we ENOSPC'd on.
and the key point being the buffer_new() state for the newly
allocated delayed allocation block. Except it doesn't - we're not
marking buffers new correctly.
That buffer_new() problem goes back to the xfs_iomap removal days,
where xfs_iomap() used to return a "new" status for any map with
newly allocated blocks, so that __xfs_get_blocks() could call
set_buffer_new() on it. We still have the "new" variable and the
check for it in the set_buffer_new() logic - except we never set it
now!
Hence that newly allocated delalloc block doesn't have the new flag
set on it, so when the write fails we cannot tell which blocks we
are supposed to punch out. WHy do we need the buffer_new flag? Well,
that's because we can have this case:
+------+------+------+------+------+------+------+------+
UMD UMD UMD UMD UMD UMD UND FAIL
where all the UMD buffers contain valid data from a previously
successful write() system call. We only want to punch the UND buffer
because that's the only one that we added in this write and it was
only this write that failed.
That implies that even the old buffer_new() logic was wrong -
because it would result in all those UMD buffers on the page having
set_buffer_new() called on them even though they aren't new. Hence
we shoul donly be calling set_buffer_new() for delalloc buffers that
were allocated (i.e. were a hole before xfs_iomap_write_delay() was
called).
So, fix this set_buffer_new logic according to how we need it to
work for handling failed writes correctly. Also, restore the new
buffer logic handling for blocks allocated via
xfs_iomap_write_direct(), because it should still set the buffer_new
flag appropriately for newly allocated blocks, too.
SO, now we have the buffer_new() being set appropriately in
__xfs_get_blocks(), we can detect the exact delalloc ranges that
we allocated in a failed write, and hence can now do a walk of the
buffers on a page to find them.
Except, it's not that easy. When block_write_begin() fails, it
unlocks and releases the page that we just had an error on, so we
can't use that page to handle errors anymore. We have to get access
to the page while it is still locked to walk the buffers. Hence we
have to open code block_write_begin() in xfs_vm_write_begin() to be
able to insert xfs_vm_write_failed() is the right place.
With that, we can pass the page and write range to
xfs_vm_write_failed() and walk the buffers on the page, looking for
delalloc buffers that are either new or beyond EOF and punch them
out. Handling buffers beyond EOF ensures we still handle the
existing case that xfs_vm_write_failed() handles.
Of special note is the truncate_pagecache() handling - that only
should be done for pages outside EOF - pages within EOF can still
contain valid, dirty data so we must not punch them out of the
cache.
That just leaves the xfs_vm_write_end() failure handling.
The only failure case here is that we didn't copy the entire range,
and generic_write_end() handles that by zeroing the region of the
page that wasn't copied, we don't have to punch out blocks within
the file because they are guaranteed to contain zeros. Hence we only
have to handle the existing "beyond EOF" case and don't need access
to the buffers on the page. Hence it remains largely unchanged.
Note that xfs_getbmap() can still trip over delalloc blocks beyond
EOF that are left there by speculative delayed allocation. Hence
this bug fix does not solve all known issues with bmap vs delalloc,
but it does fix all the the known accidental occurances of the
problem.
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-04-27 16:45:21 +07:00
|
|
|
/*
|
|
|
|
* Punch out the delalloc blocks we have already allocated.
|
|
|
|
*
|
|
|
|
* Don't bother with xfs_setattr given that nothing can have made it to disk yet
|
|
|
|
* as the page is still locked at this point.
|
|
|
|
*/
|
|
|
|
STATIC void
|
|
|
|
xfs_vm_kill_delalloc_range(
|
|
|
|
struct inode *inode,
|
|
|
|
loff_t start,
|
|
|
|
loff_t end)
|
|
|
|
{
|
|
|
|
struct xfs_inode *ip = XFS_I(inode);
|
|
|
|
xfs_fileoff_t start_fsb;
|
|
|
|
xfs_fileoff_t end_fsb;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
start_fsb = XFS_B_TO_FSB(ip->i_mount, start);
|
|
|
|
end_fsb = XFS_B_TO_FSB(ip->i_mount, end);
|
|
|
|
if (end_fsb <= start_fsb)
|
|
|
|
return;
|
|
|
|
|
|
|
|
xfs_ilock(ip, XFS_ILOCK_EXCL);
|
|
|
|
error = xfs_bmap_punch_delalloc_range(ip, start_fsb,
|
|
|
|
end_fsb - start_fsb);
|
|
|
|
if (error) {
|
|
|
|
/* something screwed, just bail */
|
|
|
|
if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {
|
|
|
|
xfs_alert(ip->i_mount,
|
|
|
|
"xfs_vm_write_failed: unable to clean up ino %lld",
|
|
|
|
ip->i_ino);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
|
|
|
}
|
|
|
|
|
2010-06-14 16:17:31 +07:00
|
|
|
STATIC void
|
|
|
|
xfs_vm_write_failed(
|
xfs: punch new delalloc blocks out of failed writes inside EOF.
When a partial write inside EOF fails, it can leave delayed
allocation blocks lying around because they don't get punched back
out. This leads to assert failures like:
XFS: Assertion failed: XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0, file: fs/xfs/xfs_super.c, line: 847
when evicting inodes from the cache. This can be trivially triggered
by xfstests 083, which takes between 5 and 15 executions on a 512
byte block size filesystem to trip over this. Debugging shows a
failed write due to ENOSPC calling xfs_vm_write_failed such as:
[ 5012.329024] ino 0xa0026: vwf to 0x17000, sze 0x1c85ae
and no action is taken on it. This leaves behind a delayed
allocation extent that has no page covering it and no data in it:
[ 5015.867162] ino 0xa0026: blks: 0x83 delay blocks 0x1, size 0x2538c0
[ 5015.868293] ext 0: off 0x4a, fsb 0x50306, len 0x1
[ 5015.869095] ext 1: off 0x4b, fsb 0x7899, len 0x6b
[ 5015.869900] ext 2: off 0xb6, fsb 0xffffffffe0008, len 0x1
^^^^^^^^^^^^^^^
[ 5015.871027] ext 3: off 0x36e, fsb 0x7a27, len 0xd
[ 5015.872206] ext 4: off 0x4cf, fsb 0x7a1d, len 0xa
So the delayed allocation extent is one block long at offset
0x16c00. Tracing shows that a bigger write:
xfs_file_buffered_write: size 0x1c85ae offset 0x959d count 0x1ca3f ioflags
allocates the block, and then fails with ENOSPC trying to allocate
the last block on the page, leading to a failed write with stale
delalloc blocks on it.
Because we've had an ENOSPC when trying to allocate 0x16e00, it
means that we are never goinge to call ->write_end on the page and
so the allocated new buffer will not get marked dirty or have the
buffer_new state cleared. In other works, what the above write is
supposed to end up with is this mapping for the page:
+------+------+------+------+------+------+------+------+
UMA UMA UMA UMA UMA UMA UND FAIL
where: U = uptodate
M = mapped
N = new
A = allocated
D = delalloc
FAIL = block we ENOSPC'd on.
and the key point being the buffer_new() state for the newly
allocated delayed allocation block. Except it doesn't - we're not
marking buffers new correctly.
That buffer_new() problem goes back to the xfs_iomap removal days,
where xfs_iomap() used to return a "new" status for any map with
newly allocated blocks, so that __xfs_get_blocks() could call
set_buffer_new() on it. We still have the "new" variable and the
check for it in the set_buffer_new() logic - except we never set it
now!
Hence that newly allocated delalloc block doesn't have the new flag
set on it, so when the write fails we cannot tell which blocks we
are supposed to punch out. WHy do we need the buffer_new flag? Well,
that's because we can have this case:
+------+------+------+------+------+------+------+------+
UMD UMD UMD UMD UMD UMD UND FAIL
where all the UMD buffers contain valid data from a previously
successful write() system call. We only want to punch the UND buffer
because that's the only one that we added in this write and it was
only this write that failed.
That implies that even the old buffer_new() logic was wrong -
because it would result in all those UMD buffers on the page having
set_buffer_new() called on them even though they aren't new. Hence
we shoul donly be calling set_buffer_new() for delalloc buffers that
were allocated (i.e. were a hole before xfs_iomap_write_delay() was
called).
So, fix this set_buffer_new logic according to how we need it to
work for handling failed writes correctly. Also, restore the new
buffer logic handling for blocks allocated via
xfs_iomap_write_direct(), because it should still set the buffer_new
flag appropriately for newly allocated blocks, too.
SO, now we have the buffer_new() being set appropriately in
__xfs_get_blocks(), we can detect the exact delalloc ranges that
we allocated in a failed write, and hence can now do a walk of the
buffers on a page to find them.
Except, it's not that easy. When block_write_begin() fails, it
unlocks and releases the page that we just had an error on, so we
can't use that page to handle errors anymore. We have to get access
to the page while it is still locked to walk the buffers. Hence we
have to open code block_write_begin() in xfs_vm_write_begin() to be
able to insert xfs_vm_write_failed() is the right place.
With that, we can pass the page and write range to
xfs_vm_write_failed() and walk the buffers on the page, looking for
delalloc buffers that are either new or beyond EOF and punch them
out. Handling buffers beyond EOF ensures we still handle the
existing case that xfs_vm_write_failed() handles.
Of special note is the truncate_pagecache() handling - that only
should be done for pages outside EOF - pages within EOF can still
contain valid, dirty data so we must not punch them out of the
cache.
That just leaves the xfs_vm_write_end() failure handling.
The only failure case here is that we didn't copy the entire range,
and generic_write_end() handles that by zeroing the region of the
page that wasn't copied, we don't have to punch out blocks within
the file because they are guaranteed to contain zeros. Hence we only
have to handle the existing "beyond EOF" case and don't need access
to the buffers on the page. Hence it remains largely unchanged.
Note that xfs_getbmap() can still trip over delalloc blocks beyond
EOF that are left there by speculative delayed allocation. Hence
this bug fix does not solve all known issues with bmap vs delalloc,
but it does fix all the the known accidental occurances of the
problem.
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-04-27 16:45:21 +07:00
|
|
|
struct inode *inode,
|
|
|
|
struct page *page,
|
|
|
|
loff_t pos,
|
|
|
|
unsigned len)
|
2010-06-14 16:17:31 +07:00
|
|
|
{
|
2013-07-16 12:11:16 +07:00
|
|
|
loff_t block_offset;
|
xfs: punch new delalloc blocks out of failed writes inside EOF.
When a partial write inside EOF fails, it can leave delayed
allocation blocks lying around because they don't get punched back
out. This leads to assert failures like:
XFS: Assertion failed: XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0, file: fs/xfs/xfs_super.c, line: 847
when evicting inodes from the cache. This can be trivially triggered
by xfstests 083, which takes between 5 and 15 executions on a 512
byte block size filesystem to trip over this. Debugging shows a
failed write due to ENOSPC calling xfs_vm_write_failed such as:
[ 5012.329024] ino 0xa0026: vwf to 0x17000, sze 0x1c85ae
and no action is taken on it. This leaves behind a delayed
allocation extent that has no page covering it and no data in it:
[ 5015.867162] ino 0xa0026: blks: 0x83 delay blocks 0x1, size 0x2538c0
[ 5015.868293] ext 0: off 0x4a, fsb 0x50306, len 0x1
[ 5015.869095] ext 1: off 0x4b, fsb 0x7899, len 0x6b
[ 5015.869900] ext 2: off 0xb6, fsb 0xffffffffe0008, len 0x1
^^^^^^^^^^^^^^^
[ 5015.871027] ext 3: off 0x36e, fsb 0x7a27, len 0xd
[ 5015.872206] ext 4: off 0x4cf, fsb 0x7a1d, len 0xa
So the delayed allocation extent is one block long at offset
0x16c00. Tracing shows that a bigger write:
xfs_file_buffered_write: size 0x1c85ae offset 0x959d count 0x1ca3f ioflags
allocates the block, and then fails with ENOSPC trying to allocate
the last block on the page, leading to a failed write with stale
delalloc blocks on it.
Because we've had an ENOSPC when trying to allocate 0x16e00, it
means that we are never goinge to call ->write_end on the page and
so the allocated new buffer will not get marked dirty or have the
buffer_new state cleared. In other works, what the above write is
supposed to end up with is this mapping for the page:
+------+------+------+------+------+------+------+------+
UMA UMA UMA UMA UMA UMA UND FAIL
where: U = uptodate
M = mapped
N = new
A = allocated
D = delalloc
FAIL = block we ENOSPC'd on.
and the key point being the buffer_new() state for the newly
allocated delayed allocation block. Except it doesn't - we're not
marking buffers new correctly.
That buffer_new() problem goes back to the xfs_iomap removal days,
where xfs_iomap() used to return a "new" status for any map with
newly allocated blocks, so that __xfs_get_blocks() could call
set_buffer_new() on it. We still have the "new" variable and the
check for it in the set_buffer_new() logic - except we never set it
now!
Hence that newly allocated delalloc block doesn't have the new flag
set on it, so when the write fails we cannot tell which blocks we
are supposed to punch out. WHy do we need the buffer_new flag? Well,
that's because we can have this case:
+------+------+------+------+------+------+------+------+
UMD UMD UMD UMD UMD UMD UND FAIL
where all the UMD buffers contain valid data from a previously
successful write() system call. We only want to punch the UND buffer
because that's the only one that we added in this write and it was
only this write that failed.
That implies that even the old buffer_new() logic was wrong -
because it would result in all those UMD buffers on the page having
set_buffer_new() called on them even though they aren't new. Hence
we shoul donly be calling set_buffer_new() for delalloc buffers that
were allocated (i.e. were a hole before xfs_iomap_write_delay() was
called).
So, fix this set_buffer_new logic according to how we need it to
work for handling failed writes correctly. Also, restore the new
buffer logic handling for blocks allocated via
xfs_iomap_write_direct(), because it should still set the buffer_new
flag appropriately for newly allocated blocks, too.
SO, now we have the buffer_new() being set appropriately in
__xfs_get_blocks(), we can detect the exact delalloc ranges that
we allocated in a failed write, and hence can now do a walk of the
buffers on a page to find them.
Except, it's not that easy. When block_write_begin() fails, it
unlocks and releases the page that we just had an error on, so we
can't use that page to handle errors anymore. We have to get access
to the page while it is still locked to walk the buffers. Hence we
have to open code block_write_begin() in xfs_vm_write_begin() to be
able to insert xfs_vm_write_failed() is the right place.
With that, we can pass the page and write range to
xfs_vm_write_failed() and walk the buffers on the page, looking for
delalloc buffers that are either new or beyond EOF and punch them
out. Handling buffers beyond EOF ensures we still handle the
existing case that xfs_vm_write_failed() handles.
Of special note is the truncate_pagecache() handling - that only
should be done for pages outside EOF - pages within EOF can still
contain valid, dirty data so we must not punch them out of the
cache.
That just leaves the xfs_vm_write_end() failure handling.
The only failure case here is that we didn't copy the entire range,
and generic_write_end() handles that by zeroing the region of the
page that wasn't copied, we don't have to punch out blocks within
the file because they are guaranteed to contain zeros. Hence we only
have to handle the existing "beyond EOF" case and don't need access
to the buffers on the page. Hence it remains largely unchanged.
Note that xfs_getbmap() can still trip over delalloc blocks beyond
EOF that are left there by speculative delayed allocation. Hence
this bug fix does not solve all known issues with bmap vs delalloc,
but it does fix all the the known accidental occurances of the
problem.
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-04-27 16:45:21 +07:00
|
|
|
loff_t block_start;
|
|
|
|
loff_t block_end;
|
|
|
|
loff_t from = pos & (PAGE_CACHE_SIZE - 1);
|
|
|
|
loff_t to = from + len;
|
|
|
|
struct buffer_head *bh, *head;
|
2010-06-14 16:17:31 +07:00
|
|
|
|
2013-07-16 12:11:16 +07:00
|
|
|
/*
|
|
|
|
* The request pos offset might be 32 or 64 bit, this is all fine
|
|
|
|
* on 64-bit platform. However, for 64-bit pos request on 32-bit
|
|
|
|
* platform, the high 32-bit will be masked off if we evaluate the
|
|
|
|
* block_offset via (pos & PAGE_MASK) because the PAGE_MASK is
|
|
|
|
* 0xfffff000 as an unsigned long, hence the result is incorrect
|
|
|
|
* which could cause the following ASSERT failed in most cases.
|
|
|
|
* In order to avoid this, we can evaluate the block_offset of the
|
|
|
|
* start of the page by using shifts rather than masks the mismatch
|
|
|
|
* problem.
|
|
|
|
*/
|
|
|
|
block_offset = (pos >> PAGE_CACHE_SHIFT) << PAGE_CACHE_SHIFT;
|
|
|
|
|
xfs: punch new delalloc blocks out of failed writes inside EOF.
When a partial write inside EOF fails, it can leave delayed
allocation blocks lying around because they don't get punched back
out. This leads to assert failures like:
XFS: Assertion failed: XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0, file: fs/xfs/xfs_super.c, line: 847
when evicting inodes from the cache. This can be trivially triggered
by xfstests 083, which takes between 5 and 15 executions on a 512
byte block size filesystem to trip over this. Debugging shows a
failed write due to ENOSPC calling xfs_vm_write_failed such as:
[ 5012.329024] ino 0xa0026: vwf to 0x17000, sze 0x1c85ae
and no action is taken on it. This leaves behind a delayed
allocation extent that has no page covering it and no data in it:
[ 5015.867162] ino 0xa0026: blks: 0x83 delay blocks 0x1, size 0x2538c0
[ 5015.868293] ext 0: off 0x4a, fsb 0x50306, len 0x1
[ 5015.869095] ext 1: off 0x4b, fsb 0x7899, len 0x6b
[ 5015.869900] ext 2: off 0xb6, fsb 0xffffffffe0008, len 0x1
^^^^^^^^^^^^^^^
[ 5015.871027] ext 3: off 0x36e, fsb 0x7a27, len 0xd
[ 5015.872206] ext 4: off 0x4cf, fsb 0x7a1d, len 0xa
So the delayed allocation extent is one block long at offset
0x16c00. Tracing shows that a bigger write:
xfs_file_buffered_write: size 0x1c85ae offset 0x959d count 0x1ca3f ioflags
allocates the block, and then fails with ENOSPC trying to allocate
the last block on the page, leading to a failed write with stale
delalloc blocks on it.
Because we've had an ENOSPC when trying to allocate 0x16e00, it
means that we are never goinge to call ->write_end on the page and
so the allocated new buffer will not get marked dirty or have the
buffer_new state cleared. In other works, what the above write is
supposed to end up with is this mapping for the page:
+------+------+------+------+------+------+------+------+
UMA UMA UMA UMA UMA UMA UND FAIL
where: U = uptodate
M = mapped
N = new
A = allocated
D = delalloc
FAIL = block we ENOSPC'd on.
and the key point being the buffer_new() state for the newly
allocated delayed allocation block. Except it doesn't - we're not
marking buffers new correctly.
That buffer_new() problem goes back to the xfs_iomap removal days,
where xfs_iomap() used to return a "new" status for any map with
newly allocated blocks, so that __xfs_get_blocks() could call
set_buffer_new() on it. We still have the "new" variable and the
check for it in the set_buffer_new() logic - except we never set it
now!
Hence that newly allocated delalloc block doesn't have the new flag
set on it, so when the write fails we cannot tell which blocks we
are supposed to punch out. WHy do we need the buffer_new flag? Well,
that's because we can have this case:
+------+------+------+------+------+------+------+------+
UMD UMD UMD UMD UMD UMD UND FAIL
where all the UMD buffers contain valid data from a previously
successful write() system call. We only want to punch the UND buffer
because that's the only one that we added in this write and it was
only this write that failed.
That implies that even the old buffer_new() logic was wrong -
because it would result in all those UMD buffers on the page having
set_buffer_new() called on them even though they aren't new. Hence
we shoul donly be calling set_buffer_new() for delalloc buffers that
were allocated (i.e. were a hole before xfs_iomap_write_delay() was
called).
So, fix this set_buffer_new logic according to how we need it to
work for handling failed writes correctly. Also, restore the new
buffer logic handling for blocks allocated via
xfs_iomap_write_direct(), because it should still set the buffer_new
flag appropriately for newly allocated blocks, too.
SO, now we have the buffer_new() being set appropriately in
__xfs_get_blocks(), we can detect the exact delalloc ranges that
we allocated in a failed write, and hence can now do a walk of the
buffers on a page to find them.
Except, it's not that easy. When block_write_begin() fails, it
unlocks and releases the page that we just had an error on, so we
can't use that page to handle errors anymore. We have to get access
to the page while it is still locked to walk the buffers. Hence we
have to open code block_write_begin() in xfs_vm_write_begin() to be
able to insert xfs_vm_write_failed() is the right place.
With that, we can pass the page and write range to
xfs_vm_write_failed() and walk the buffers on the page, looking for
delalloc buffers that are either new or beyond EOF and punch them
out. Handling buffers beyond EOF ensures we still handle the
existing case that xfs_vm_write_failed() handles.
Of special note is the truncate_pagecache() handling - that only
should be done for pages outside EOF - pages within EOF can still
contain valid, dirty data so we must not punch them out of the
cache.
That just leaves the xfs_vm_write_end() failure handling.
The only failure case here is that we didn't copy the entire range,
and generic_write_end() handles that by zeroing the region of the
page that wasn't copied, we don't have to punch out blocks within
the file because they are guaranteed to contain zeros. Hence we only
have to handle the existing "beyond EOF" case and don't need access
to the buffers on the page. Hence it remains largely unchanged.
Note that xfs_getbmap() can still trip over delalloc blocks beyond
EOF that are left there by speculative delayed allocation. Hence
this bug fix does not solve all known issues with bmap vs delalloc,
but it does fix all the the known accidental occurances of the
problem.
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-04-27 16:45:21 +07:00
|
|
|
ASSERT(block_offset + from == pos);
|
2010-11-30 11:14:39 +07:00
|
|
|
|
xfs: punch new delalloc blocks out of failed writes inside EOF.
When a partial write inside EOF fails, it can leave delayed
allocation blocks lying around because they don't get punched back
out. This leads to assert failures like:
XFS: Assertion failed: XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0, file: fs/xfs/xfs_super.c, line: 847
when evicting inodes from the cache. This can be trivially triggered
by xfstests 083, which takes between 5 and 15 executions on a 512
byte block size filesystem to trip over this. Debugging shows a
failed write due to ENOSPC calling xfs_vm_write_failed such as:
[ 5012.329024] ino 0xa0026: vwf to 0x17000, sze 0x1c85ae
and no action is taken on it. This leaves behind a delayed
allocation extent that has no page covering it and no data in it:
[ 5015.867162] ino 0xa0026: blks: 0x83 delay blocks 0x1, size 0x2538c0
[ 5015.868293] ext 0: off 0x4a, fsb 0x50306, len 0x1
[ 5015.869095] ext 1: off 0x4b, fsb 0x7899, len 0x6b
[ 5015.869900] ext 2: off 0xb6, fsb 0xffffffffe0008, len 0x1
^^^^^^^^^^^^^^^
[ 5015.871027] ext 3: off 0x36e, fsb 0x7a27, len 0xd
[ 5015.872206] ext 4: off 0x4cf, fsb 0x7a1d, len 0xa
So the delayed allocation extent is one block long at offset
0x16c00. Tracing shows that a bigger write:
xfs_file_buffered_write: size 0x1c85ae offset 0x959d count 0x1ca3f ioflags
allocates the block, and then fails with ENOSPC trying to allocate
the last block on the page, leading to a failed write with stale
delalloc blocks on it.
Because we've had an ENOSPC when trying to allocate 0x16e00, it
means that we are never goinge to call ->write_end on the page and
so the allocated new buffer will not get marked dirty or have the
buffer_new state cleared. In other works, what the above write is
supposed to end up with is this mapping for the page:
+------+------+------+------+------+------+------+------+
UMA UMA UMA UMA UMA UMA UND FAIL
where: U = uptodate
M = mapped
N = new
A = allocated
D = delalloc
FAIL = block we ENOSPC'd on.
and the key point being the buffer_new() state for the newly
allocated delayed allocation block. Except it doesn't - we're not
marking buffers new correctly.
That buffer_new() problem goes back to the xfs_iomap removal days,
where xfs_iomap() used to return a "new" status for any map with
newly allocated blocks, so that __xfs_get_blocks() could call
set_buffer_new() on it. We still have the "new" variable and the
check for it in the set_buffer_new() logic - except we never set it
now!
Hence that newly allocated delalloc block doesn't have the new flag
set on it, so when the write fails we cannot tell which blocks we
are supposed to punch out. WHy do we need the buffer_new flag? Well,
that's because we can have this case:
+------+------+------+------+------+------+------+------+
UMD UMD UMD UMD UMD UMD UND FAIL
where all the UMD buffers contain valid data from a previously
successful write() system call. We only want to punch the UND buffer
because that's the only one that we added in this write and it was
only this write that failed.
That implies that even the old buffer_new() logic was wrong -
because it would result in all those UMD buffers on the page having
set_buffer_new() called on them even though they aren't new. Hence
we shoul donly be calling set_buffer_new() for delalloc buffers that
were allocated (i.e. were a hole before xfs_iomap_write_delay() was
called).
So, fix this set_buffer_new logic according to how we need it to
work for handling failed writes correctly. Also, restore the new
buffer logic handling for blocks allocated via
xfs_iomap_write_direct(), because it should still set the buffer_new
flag appropriately for newly allocated blocks, too.
SO, now we have the buffer_new() being set appropriately in
__xfs_get_blocks(), we can detect the exact delalloc ranges that
we allocated in a failed write, and hence can now do a walk of the
buffers on a page to find them.
Except, it's not that easy. When block_write_begin() fails, it
unlocks and releases the page that we just had an error on, so we
can't use that page to handle errors anymore. We have to get access
to the page while it is still locked to walk the buffers. Hence we
have to open code block_write_begin() in xfs_vm_write_begin() to be
able to insert xfs_vm_write_failed() is the right place.
With that, we can pass the page and write range to
xfs_vm_write_failed() and walk the buffers on the page, looking for
delalloc buffers that are either new or beyond EOF and punch them
out. Handling buffers beyond EOF ensures we still handle the
existing case that xfs_vm_write_failed() handles.
Of special note is the truncate_pagecache() handling - that only
should be done for pages outside EOF - pages within EOF can still
contain valid, dirty data so we must not punch them out of the
cache.
That just leaves the xfs_vm_write_end() failure handling.
The only failure case here is that we didn't copy the entire range,
and generic_write_end() handles that by zeroing the region of the
page that wasn't copied, we don't have to punch out blocks within
the file because they are guaranteed to contain zeros. Hence we only
have to handle the existing "beyond EOF" case and don't need access
to the buffers on the page. Hence it remains largely unchanged.
Note that xfs_getbmap() can still trip over delalloc blocks beyond
EOF that are left there by speculative delayed allocation. Hence
this bug fix does not solve all known issues with bmap vs delalloc,
but it does fix all the the known accidental occurances of the
problem.
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-04-27 16:45:21 +07:00
|
|
|
head = page_buffers(page);
|
|
|
|
block_start = 0;
|
|
|
|
for (bh = head; bh != head || !block_start;
|
|
|
|
bh = bh->b_this_page, block_start = block_end,
|
|
|
|
block_offset += bh->b_size) {
|
|
|
|
block_end = block_start + bh->b_size;
|
2010-11-30 11:14:39 +07:00
|
|
|
|
xfs: punch new delalloc blocks out of failed writes inside EOF.
When a partial write inside EOF fails, it can leave delayed
allocation blocks lying around because they don't get punched back
out. This leads to assert failures like:
XFS: Assertion failed: XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0, file: fs/xfs/xfs_super.c, line: 847
when evicting inodes from the cache. This can be trivially triggered
by xfstests 083, which takes between 5 and 15 executions on a 512
byte block size filesystem to trip over this. Debugging shows a
failed write due to ENOSPC calling xfs_vm_write_failed such as:
[ 5012.329024] ino 0xa0026: vwf to 0x17000, sze 0x1c85ae
and no action is taken on it. This leaves behind a delayed
allocation extent that has no page covering it and no data in it:
[ 5015.867162] ino 0xa0026: blks: 0x83 delay blocks 0x1, size 0x2538c0
[ 5015.868293] ext 0: off 0x4a, fsb 0x50306, len 0x1
[ 5015.869095] ext 1: off 0x4b, fsb 0x7899, len 0x6b
[ 5015.869900] ext 2: off 0xb6, fsb 0xffffffffe0008, len 0x1
^^^^^^^^^^^^^^^
[ 5015.871027] ext 3: off 0x36e, fsb 0x7a27, len 0xd
[ 5015.872206] ext 4: off 0x4cf, fsb 0x7a1d, len 0xa
So the delayed allocation extent is one block long at offset
0x16c00. Tracing shows that a bigger write:
xfs_file_buffered_write: size 0x1c85ae offset 0x959d count 0x1ca3f ioflags
allocates the block, and then fails with ENOSPC trying to allocate
the last block on the page, leading to a failed write with stale
delalloc blocks on it.
Because we've had an ENOSPC when trying to allocate 0x16e00, it
means that we are never goinge to call ->write_end on the page and
so the allocated new buffer will not get marked dirty or have the
buffer_new state cleared. In other works, what the above write is
supposed to end up with is this mapping for the page:
+------+------+------+------+------+------+------+------+
UMA UMA UMA UMA UMA UMA UND FAIL
where: U = uptodate
M = mapped
N = new
A = allocated
D = delalloc
FAIL = block we ENOSPC'd on.
and the key point being the buffer_new() state for the newly
allocated delayed allocation block. Except it doesn't - we're not
marking buffers new correctly.
That buffer_new() problem goes back to the xfs_iomap removal days,
where xfs_iomap() used to return a "new" status for any map with
newly allocated blocks, so that __xfs_get_blocks() could call
set_buffer_new() on it. We still have the "new" variable and the
check for it in the set_buffer_new() logic - except we never set it
now!
Hence that newly allocated delalloc block doesn't have the new flag
set on it, so when the write fails we cannot tell which blocks we
are supposed to punch out. WHy do we need the buffer_new flag? Well,
that's because we can have this case:
+------+------+------+------+------+------+------+------+
UMD UMD UMD UMD UMD UMD UND FAIL
where all the UMD buffers contain valid data from a previously
successful write() system call. We only want to punch the UND buffer
because that's the only one that we added in this write and it was
only this write that failed.
That implies that even the old buffer_new() logic was wrong -
because it would result in all those UMD buffers on the page having
set_buffer_new() called on them even though they aren't new. Hence
we shoul donly be calling set_buffer_new() for delalloc buffers that
were allocated (i.e. were a hole before xfs_iomap_write_delay() was
called).
So, fix this set_buffer_new logic according to how we need it to
work for handling failed writes correctly. Also, restore the new
buffer logic handling for blocks allocated via
xfs_iomap_write_direct(), because it should still set the buffer_new
flag appropriately for newly allocated blocks, too.
SO, now we have the buffer_new() being set appropriately in
__xfs_get_blocks(), we can detect the exact delalloc ranges that
we allocated in a failed write, and hence can now do a walk of the
buffers on a page to find them.
Except, it's not that easy. When block_write_begin() fails, it
unlocks and releases the page that we just had an error on, so we
can't use that page to handle errors anymore. We have to get access
to the page while it is still locked to walk the buffers. Hence we
have to open code block_write_begin() in xfs_vm_write_begin() to be
able to insert xfs_vm_write_failed() is the right place.
With that, we can pass the page and write range to
xfs_vm_write_failed() and walk the buffers on the page, looking for
delalloc buffers that are either new or beyond EOF and punch them
out. Handling buffers beyond EOF ensures we still handle the
existing case that xfs_vm_write_failed() handles.
Of special note is the truncate_pagecache() handling - that only
should be done for pages outside EOF - pages within EOF can still
contain valid, dirty data so we must not punch them out of the
cache.
That just leaves the xfs_vm_write_end() failure handling.
The only failure case here is that we didn't copy the entire range,
and generic_write_end() handles that by zeroing the region of the
page that wasn't copied, we don't have to punch out blocks within
the file because they are guaranteed to contain zeros. Hence we only
have to handle the existing "beyond EOF" case and don't need access
to the buffers on the page. Hence it remains largely unchanged.
Note that xfs_getbmap() can still trip over delalloc blocks beyond
EOF that are left there by speculative delayed allocation. Hence
this bug fix does not solve all known issues with bmap vs delalloc,
but it does fix all the the known accidental occurances of the
problem.
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-04-27 16:45:21 +07:00
|
|
|
/* skip buffers before the write */
|
|
|
|
if (block_end <= from)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* if the buffer is after the write, we're done */
|
|
|
|
if (block_start >= to)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (!buffer_delay(bh))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (!buffer_new(bh) && block_offset < i_size_read(inode))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
xfs_vm_kill_delalloc_range(inode, block_offset,
|
|
|
|
block_offset + bh->b_size);
|
2014-04-14 15:11:58 +07:00
|
|
|
|
|
|
|
/*
|
|
|
|
* This buffer does not contain data anymore. make sure anyone
|
|
|
|
* who finds it knows that for certain.
|
|
|
|
*/
|
|
|
|
clear_buffer_delay(bh);
|
|
|
|
clear_buffer_uptodate(bh);
|
|
|
|
clear_buffer_mapped(bh);
|
|
|
|
clear_buffer_new(bh);
|
|
|
|
clear_buffer_dirty(bh);
|
2010-06-14 16:17:31 +07:00
|
|
|
}
|
xfs: punch new delalloc blocks out of failed writes inside EOF.
When a partial write inside EOF fails, it can leave delayed
allocation blocks lying around because they don't get punched back
out. This leads to assert failures like:
XFS: Assertion failed: XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0, file: fs/xfs/xfs_super.c, line: 847
when evicting inodes from the cache. This can be trivially triggered
by xfstests 083, which takes between 5 and 15 executions on a 512
byte block size filesystem to trip over this. Debugging shows a
failed write due to ENOSPC calling xfs_vm_write_failed such as:
[ 5012.329024] ino 0xa0026: vwf to 0x17000, sze 0x1c85ae
and no action is taken on it. This leaves behind a delayed
allocation extent that has no page covering it and no data in it:
[ 5015.867162] ino 0xa0026: blks: 0x83 delay blocks 0x1, size 0x2538c0
[ 5015.868293] ext 0: off 0x4a, fsb 0x50306, len 0x1
[ 5015.869095] ext 1: off 0x4b, fsb 0x7899, len 0x6b
[ 5015.869900] ext 2: off 0xb6, fsb 0xffffffffe0008, len 0x1
^^^^^^^^^^^^^^^
[ 5015.871027] ext 3: off 0x36e, fsb 0x7a27, len 0xd
[ 5015.872206] ext 4: off 0x4cf, fsb 0x7a1d, len 0xa
So the delayed allocation extent is one block long at offset
0x16c00. Tracing shows that a bigger write:
xfs_file_buffered_write: size 0x1c85ae offset 0x959d count 0x1ca3f ioflags
allocates the block, and then fails with ENOSPC trying to allocate
the last block on the page, leading to a failed write with stale
delalloc blocks on it.
Because we've had an ENOSPC when trying to allocate 0x16e00, it
means that we are never goinge to call ->write_end on the page and
so the allocated new buffer will not get marked dirty or have the
buffer_new state cleared. In other works, what the above write is
supposed to end up with is this mapping for the page:
+------+------+------+------+------+------+------+------+
UMA UMA UMA UMA UMA UMA UND FAIL
where: U = uptodate
M = mapped
N = new
A = allocated
D = delalloc
FAIL = block we ENOSPC'd on.
and the key point being the buffer_new() state for the newly
allocated delayed allocation block. Except it doesn't - we're not
marking buffers new correctly.
That buffer_new() problem goes back to the xfs_iomap removal days,
where xfs_iomap() used to return a "new" status for any map with
newly allocated blocks, so that __xfs_get_blocks() could call
set_buffer_new() on it. We still have the "new" variable and the
check for it in the set_buffer_new() logic - except we never set it
now!
Hence that newly allocated delalloc block doesn't have the new flag
set on it, so when the write fails we cannot tell which blocks we
are supposed to punch out. WHy do we need the buffer_new flag? Well,
that's because we can have this case:
+------+------+------+------+------+------+------+------+
UMD UMD UMD UMD UMD UMD UND FAIL
where all the UMD buffers contain valid data from a previously
successful write() system call. We only want to punch the UND buffer
because that's the only one that we added in this write and it was
only this write that failed.
That implies that even the old buffer_new() logic was wrong -
because it would result in all those UMD buffers on the page having
set_buffer_new() called on them even though they aren't new. Hence
we shoul donly be calling set_buffer_new() for delalloc buffers that
were allocated (i.e. were a hole before xfs_iomap_write_delay() was
called).
So, fix this set_buffer_new logic according to how we need it to
work for handling failed writes correctly. Also, restore the new
buffer logic handling for blocks allocated via
xfs_iomap_write_direct(), because it should still set the buffer_new
flag appropriately for newly allocated blocks, too.
SO, now we have the buffer_new() being set appropriately in
__xfs_get_blocks(), we can detect the exact delalloc ranges that
we allocated in a failed write, and hence can now do a walk of the
buffers on a page to find them.
Except, it's not that easy. When block_write_begin() fails, it
unlocks and releases the page that we just had an error on, so we
can't use that page to handle errors anymore. We have to get access
to the page while it is still locked to walk the buffers. Hence we
have to open code block_write_begin() in xfs_vm_write_begin() to be
able to insert xfs_vm_write_failed() is the right place.
With that, we can pass the page and write range to
xfs_vm_write_failed() and walk the buffers on the page, looking for
delalloc buffers that are either new or beyond EOF and punch them
out. Handling buffers beyond EOF ensures we still handle the
existing case that xfs_vm_write_failed() handles.
Of special note is the truncate_pagecache() handling - that only
should be done for pages outside EOF - pages within EOF can still
contain valid, dirty data so we must not punch them out of the
cache.
That just leaves the xfs_vm_write_end() failure handling.
The only failure case here is that we didn't copy the entire range,
and generic_write_end() handles that by zeroing the region of the
page that wasn't copied, we don't have to punch out blocks within
the file because they are guaranteed to contain zeros. Hence we only
have to handle the existing "beyond EOF" case and don't need access
to the buffers on the page. Hence it remains largely unchanged.
Note that xfs_getbmap() can still trip over delalloc blocks beyond
EOF that are left there by speculative delayed allocation. Hence
this bug fix does not solve all known issues with bmap vs delalloc,
but it does fix all the the known accidental occurances of the
problem.
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-04-27 16:45:21 +07:00
|
|
|
|
2010-06-14 16:17:31 +07:00
|
|
|
}
|
|
|
|
|
xfs: punch new delalloc blocks out of failed writes inside EOF.
When a partial write inside EOF fails, it can leave delayed
allocation blocks lying around because they don't get punched back
out. This leads to assert failures like:
XFS: Assertion failed: XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0, file: fs/xfs/xfs_super.c, line: 847
when evicting inodes from the cache. This can be trivially triggered
by xfstests 083, which takes between 5 and 15 executions on a 512
byte block size filesystem to trip over this. Debugging shows a
failed write due to ENOSPC calling xfs_vm_write_failed such as:
[ 5012.329024] ino 0xa0026: vwf to 0x17000, sze 0x1c85ae
and no action is taken on it. This leaves behind a delayed
allocation extent that has no page covering it and no data in it:
[ 5015.867162] ino 0xa0026: blks: 0x83 delay blocks 0x1, size 0x2538c0
[ 5015.868293] ext 0: off 0x4a, fsb 0x50306, len 0x1
[ 5015.869095] ext 1: off 0x4b, fsb 0x7899, len 0x6b
[ 5015.869900] ext 2: off 0xb6, fsb 0xffffffffe0008, len 0x1
^^^^^^^^^^^^^^^
[ 5015.871027] ext 3: off 0x36e, fsb 0x7a27, len 0xd
[ 5015.872206] ext 4: off 0x4cf, fsb 0x7a1d, len 0xa
So the delayed allocation extent is one block long at offset
0x16c00. Tracing shows that a bigger write:
xfs_file_buffered_write: size 0x1c85ae offset 0x959d count 0x1ca3f ioflags
allocates the block, and then fails with ENOSPC trying to allocate
the last block on the page, leading to a failed write with stale
delalloc blocks on it.
Because we've had an ENOSPC when trying to allocate 0x16e00, it
means that we are never goinge to call ->write_end on the page and
so the allocated new buffer will not get marked dirty or have the
buffer_new state cleared. In other works, what the above write is
supposed to end up with is this mapping for the page:
+------+------+------+------+------+------+------+------+
UMA UMA UMA UMA UMA UMA UND FAIL
where: U = uptodate
M = mapped
N = new
A = allocated
D = delalloc
FAIL = block we ENOSPC'd on.
and the key point being the buffer_new() state for the newly
allocated delayed allocation block. Except it doesn't - we're not
marking buffers new correctly.
That buffer_new() problem goes back to the xfs_iomap removal days,
where xfs_iomap() used to return a "new" status for any map with
newly allocated blocks, so that __xfs_get_blocks() could call
set_buffer_new() on it. We still have the "new" variable and the
check for it in the set_buffer_new() logic - except we never set it
now!
Hence that newly allocated delalloc block doesn't have the new flag
set on it, so when the write fails we cannot tell which blocks we
are supposed to punch out. WHy do we need the buffer_new flag? Well,
that's because we can have this case:
+------+------+------+------+------+------+------+------+
UMD UMD UMD UMD UMD UMD UND FAIL
where all the UMD buffers contain valid data from a previously
successful write() system call. We only want to punch the UND buffer
because that's the only one that we added in this write and it was
only this write that failed.
That implies that even the old buffer_new() logic was wrong -
because it would result in all those UMD buffers on the page having
set_buffer_new() called on them even though they aren't new. Hence
we shoul donly be calling set_buffer_new() for delalloc buffers that
were allocated (i.e. were a hole before xfs_iomap_write_delay() was
called).
So, fix this set_buffer_new logic according to how we need it to
work for handling failed writes correctly. Also, restore the new
buffer logic handling for blocks allocated via
xfs_iomap_write_direct(), because it should still set the buffer_new
flag appropriately for newly allocated blocks, too.
SO, now we have the buffer_new() being set appropriately in
__xfs_get_blocks(), we can detect the exact delalloc ranges that
we allocated in a failed write, and hence can now do a walk of the
buffers on a page to find them.
Except, it's not that easy. When block_write_begin() fails, it
unlocks and releases the page that we just had an error on, so we
can't use that page to handle errors anymore. We have to get access
to the page while it is still locked to walk the buffers. Hence we
have to open code block_write_begin() in xfs_vm_write_begin() to be
able to insert xfs_vm_write_failed() is the right place.
With that, we can pass the page and write range to
xfs_vm_write_failed() and walk the buffers on the page, looking for
delalloc buffers that are either new or beyond EOF and punch them
out. Handling buffers beyond EOF ensures we still handle the
existing case that xfs_vm_write_failed() handles.
Of special note is the truncate_pagecache() handling - that only
should be done for pages outside EOF - pages within EOF can still
contain valid, dirty data so we must not punch them out of the
cache.
That just leaves the xfs_vm_write_end() failure handling.
The only failure case here is that we didn't copy the entire range,
and generic_write_end() handles that by zeroing the region of the
page that wasn't copied, we don't have to punch out blocks within
the file because they are guaranteed to contain zeros. Hence we only
have to handle the existing "beyond EOF" case and don't need access
to the buffers on the page. Hence it remains largely unchanged.
Note that xfs_getbmap() can still trip over delalloc blocks beyond
EOF that are left there by speculative delayed allocation. Hence
this bug fix does not solve all known issues with bmap vs delalloc,
but it does fix all the the known accidental occurances of the
problem.
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-04-27 16:45:21 +07:00
|
|
|
/*
|
|
|
|
* This used to call block_write_begin(), but it unlocks and releases the page
|
|
|
|
* on error, and we need that page to be able to punch stale delalloc blocks out
|
|
|
|
* on failure. hence we copy-n-waste it here and call xfs_vm_write_failed() at
|
|
|
|
* the appropriate point.
|
|
|
|
*/
|
2006-03-14 09:26:27 +07:00
|
|
|
STATIC int
|
2007-10-16 15:25:06 +07:00
|
|
|
xfs_vm_write_begin(
|
2006-03-14 09:26:27 +07:00
|
|
|
struct file *file,
|
2007-10-16 15:25:06 +07:00
|
|
|
struct address_space *mapping,
|
|
|
|
loff_t pos,
|
|
|
|
unsigned len,
|
|
|
|
unsigned flags,
|
|
|
|
struct page **pagep,
|
|
|
|
void **fsdata)
|
2006-03-14 09:26:27 +07:00
|
|
|
{
|
xfs: punch new delalloc blocks out of failed writes inside EOF.
When a partial write inside EOF fails, it can leave delayed
allocation blocks lying around because they don't get punched back
out. This leads to assert failures like:
XFS: Assertion failed: XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0, file: fs/xfs/xfs_super.c, line: 847
when evicting inodes from the cache. This can be trivially triggered
by xfstests 083, which takes between 5 and 15 executions on a 512
byte block size filesystem to trip over this. Debugging shows a
failed write due to ENOSPC calling xfs_vm_write_failed such as:
[ 5012.329024] ino 0xa0026: vwf to 0x17000, sze 0x1c85ae
and no action is taken on it. This leaves behind a delayed
allocation extent that has no page covering it and no data in it:
[ 5015.867162] ino 0xa0026: blks: 0x83 delay blocks 0x1, size 0x2538c0
[ 5015.868293] ext 0: off 0x4a, fsb 0x50306, len 0x1
[ 5015.869095] ext 1: off 0x4b, fsb 0x7899, len 0x6b
[ 5015.869900] ext 2: off 0xb6, fsb 0xffffffffe0008, len 0x1
^^^^^^^^^^^^^^^
[ 5015.871027] ext 3: off 0x36e, fsb 0x7a27, len 0xd
[ 5015.872206] ext 4: off 0x4cf, fsb 0x7a1d, len 0xa
So the delayed allocation extent is one block long at offset
0x16c00. Tracing shows that a bigger write:
xfs_file_buffered_write: size 0x1c85ae offset 0x959d count 0x1ca3f ioflags
allocates the block, and then fails with ENOSPC trying to allocate
the last block on the page, leading to a failed write with stale
delalloc blocks on it.
Because we've had an ENOSPC when trying to allocate 0x16e00, it
means that we are never goinge to call ->write_end on the page and
so the allocated new buffer will not get marked dirty or have the
buffer_new state cleared. In other works, what the above write is
supposed to end up with is this mapping for the page:
+------+------+------+------+------+------+------+------+
UMA UMA UMA UMA UMA UMA UND FAIL
where: U = uptodate
M = mapped
N = new
A = allocated
D = delalloc
FAIL = block we ENOSPC'd on.
and the key point being the buffer_new() state for the newly
allocated delayed allocation block. Except it doesn't - we're not
marking buffers new correctly.
That buffer_new() problem goes back to the xfs_iomap removal days,
where xfs_iomap() used to return a "new" status for any map with
newly allocated blocks, so that __xfs_get_blocks() could call
set_buffer_new() on it. We still have the "new" variable and the
check for it in the set_buffer_new() logic - except we never set it
now!
Hence that newly allocated delalloc block doesn't have the new flag
set on it, so when the write fails we cannot tell which blocks we
are supposed to punch out. WHy do we need the buffer_new flag? Well,
that's because we can have this case:
+------+------+------+------+------+------+------+------+
UMD UMD UMD UMD UMD UMD UND FAIL
where all the UMD buffers contain valid data from a previously
successful write() system call. We only want to punch the UND buffer
because that's the only one that we added in this write and it was
only this write that failed.
That implies that even the old buffer_new() logic was wrong -
because it would result in all those UMD buffers on the page having
set_buffer_new() called on them even though they aren't new. Hence
we shoul donly be calling set_buffer_new() for delalloc buffers that
were allocated (i.e. were a hole before xfs_iomap_write_delay() was
called).
So, fix this set_buffer_new logic according to how we need it to
work for handling failed writes correctly. Also, restore the new
buffer logic handling for blocks allocated via
xfs_iomap_write_direct(), because it should still set the buffer_new
flag appropriately for newly allocated blocks, too.
SO, now we have the buffer_new() being set appropriately in
__xfs_get_blocks(), we can detect the exact delalloc ranges that
we allocated in a failed write, and hence can now do a walk of the
buffers on a page to find them.
Except, it's not that easy. When block_write_begin() fails, it
unlocks and releases the page that we just had an error on, so we
can't use that page to handle errors anymore. We have to get access
to the page while it is still locked to walk the buffers. Hence we
have to open code block_write_begin() in xfs_vm_write_begin() to be
able to insert xfs_vm_write_failed() is the right place.
With that, we can pass the page and write range to
xfs_vm_write_failed() and walk the buffers on the page, looking for
delalloc buffers that are either new or beyond EOF and punch them
out. Handling buffers beyond EOF ensures we still handle the
existing case that xfs_vm_write_failed() handles.
Of special note is the truncate_pagecache() handling - that only
should be done for pages outside EOF - pages within EOF can still
contain valid, dirty data so we must not punch them out of the
cache.
That just leaves the xfs_vm_write_end() failure handling.
The only failure case here is that we didn't copy the entire range,
and generic_write_end() handles that by zeroing the region of the
page that wasn't copied, we don't have to punch out blocks within
the file because they are guaranteed to contain zeros. Hence we only
have to handle the existing "beyond EOF" case and don't need access
to the buffers on the page. Hence it remains largely unchanged.
Note that xfs_getbmap() can still trip over delalloc blocks beyond
EOF that are left there by speculative delayed allocation. Hence
this bug fix does not solve all known issues with bmap vs delalloc,
but it does fix all the the known accidental occurances of the
problem.
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-04-27 16:45:21 +07:00
|
|
|
pgoff_t index = pos >> PAGE_CACHE_SHIFT;
|
|
|
|
struct page *page;
|
|
|
|
int status;
|
2010-06-04 16:29:58 +07:00
|
|
|
|
xfs: punch new delalloc blocks out of failed writes inside EOF.
When a partial write inside EOF fails, it can leave delayed
allocation blocks lying around because they don't get punched back
out. This leads to assert failures like:
XFS: Assertion failed: XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0, file: fs/xfs/xfs_super.c, line: 847
when evicting inodes from the cache. This can be trivially triggered
by xfstests 083, which takes between 5 and 15 executions on a 512
byte block size filesystem to trip over this. Debugging shows a
failed write due to ENOSPC calling xfs_vm_write_failed such as:
[ 5012.329024] ino 0xa0026: vwf to 0x17000, sze 0x1c85ae
and no action is taken on it. This leaves behind a delayed
allocation extent that has no page covering it and no data in it:
[ 5015.867162] ino 0xa0026: blks: 0x83 delay blocks 0x1, size 0x2538c0
[ 5015.868293] ext 0: off 0x4a, fsb 0x50306, len 0x1
[ 5015.869095] ext 1: off 0x4b, fsb 0x7899, len 0x6b
[ 5015.869900] ext 2: off 0xb6, fsb 0xffffffffe0008, len 0x1
^^^^^^^^^^^^^^^
[ 5015.871027] ext 3: off 0x36e, fsb 0x7a27, len 0xd
[ 5015.872206] ext 4: off 0x4cf, fsb 0x7a1d, len 0xa
So the delayed allocation extent is one block long at offset
0x16c00. Tracing shows that a bigger write:
xfs_file_buffered_write: size 0x1c85ae offset 0x959d count 0x1ca3f ioflags
allocates the block, and then fails with ENOSPC trying to allocate
the last block on the page, leading to a failed write with stale
delalloc blocks on it.
Because we've had an ENOSPC when trying to allocate 0x16e00, it
means that we are never goinge to call ->write_end on the page and
so the allocated new buffer will not get marked dirty or have the
buffer_new state cleared. In other works, what the above write is
supposed to end up with is this mapping for the page:
+------+------+------+------+------+------+------+------+
UMA UMA UMA UMA UMA UMA UND FAIL
where: U = uptodate
M = mapped
N = new
A = allocated
D = delalloc
FAIL = block we ENOSPC'd on.
and the key point being the buffer_new() state for the newly
allocated delayed allocation block. Except it doesn't - we're not
marking buffers new correctly.
That buffer_new() problem goes back to the xfs_iomap removal days,
where xfs_iomap() used to return a "new" status for any map with
newly allocated blocks, so that __xfs_get_blocks() could call
set_buffer_new() on it. We still have the "new" variable and the
check for it in the set_buffer_new() logic - except we never set it
now!
Hence that newly allocated delalloc block doesn't have the new flag
set on it, so when the write fails we cannot tell which blocks we
are supposed to punch out. WHy do we need the buffer_new flag? Well,
that's because we can have this case:
+------+------+------+------+------+------+------+------+
UMD UMD UMD UMD UMD UMD UND FAIL
where all the UMD buffers contain valid data from a previously
successful write() system call. We only want to punch the UND buffer
because that's the only one that we added in this write and it was
only this write that failed.
That implies that even the old buffer_new() logic was wrong -
because it would result in all those UMD buffers on the page having
set_buffer_new() called on them even though they aren't new. Hence
we shoul donly be calling set_buffer_new() for delalloc buffers that
were allocated (i.e. were a hole before xfs_iomap_write_delay() was
called).
So, fix this set_buffer_new logic according to how we need it to
work for handling failed writes correctly. Also, restore the new
buffer logic handling for blocks allocated via
xfs_iomap_write_direct(), because it should still set the buffer_new
flag appropriately for newly allocated blocks, too.
SO, now we have the buffer_new() being set appropriately in
__xfs_get_blocks(), we can detect the exact delalloc ranges that
we allocated in a failed write, and hence can now do a walk of the
buffers on a page to find them.
Except, it's not that easy. When block_write_begin() fails, it
unlocks and releases the page that we just had an error on, so we
can't use that page to handle errors anymore. We have to get access
to the page while it is still locked to walk the buffers. Hence we
have to open code block_write_begin() in xfs_vm_write_begin() to be
able to insert xfs_vm_write_failed() is the right place.
With that, we can pass the page and write range to
xfs_vm_write_failed() and walk the buffers on the page, looking for
delalloc buffers that are either new or beyond EOF and punch them
out. Handling buffers beyond EOF ensures we still handle the
existing case that xfs_vm_write_failed() handles.
Of special note is the truncate_pagecache() handling - that only
should be done for pages outside EOF - pages within EOF can still
contain valid, dirty data so we must not punch them out of the
cache.
That just leaves the xfs_vm_write_end() failure handling.
The only failure case here is that we didn't copy the entire range,
and generic_write_end() handles that by zeroing the region of the
page that wasn't copied, we don't have to punch out blocks within
the file because they are guaranteed to contain zeros. Hence we only
have to handle the existing "beyond EOF" case and don't need access
to the buffers on the page. Hence it remains largely unchanged.
Note that xfs_getbmap() can still trip over delalloc blocks beyond
EOF that are left there by speculative delayed allocation. Hence
this bug fix does not solve all known issues with bmap vs delalloc,
but it does fix all the the known accidental occurances of the
problem.
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-04-27 16:45:21 +07:00
|
|
|
ASSERT(len <= PAGE_CACHE_SIZE);
|
|
|
|
|
2013-10-29 18:11:57 +07:00
|
|
|
page = grab_cache_page_write_begin(mapping, index, flags);
|
xfs: punch new delalloc blocks out of failed writes inside EOF.
When a partial write inside EOF fails, it can leave delayed
allocation blocks lying around because they don't get punched back
out. This leads to assert failures like:
XFS: Assertion failed: XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0, file: fs/xfs/xfs_super.c, line: 847
when evicting inodes from the cache. This can be trivially triggered
by xfstests 083, which takes between 5 and 15 executions on a 512
byte block size filesystem to trip over this. Debugging shows a
failed write due to ENOSPC calling xfs_vm_write_failed such as:
[ 5012.329024] ino 0xa0026: vwf to 0x17000, sze 0x1c85ae
and no action is taken on it. This leaves behind a delayed
allocation extent that has no page covering it and no data in it:
[ 5015.867162] ino 0xa0026: blks: 0x83 delay blocks 0x1, size 0x2538c0
[ 5015.868293] ext 0: off 0x4a, fsb 0x50306, len 0x1
[ 5015.869095] ext 1: off 0x4b, fsb 0x7899, len 0x6b
[ 5015.869900] ext 2: off 0xb6, fsb 0xffffffffe0008, len 0x1
^^^^^^^^^^^^^^^
[ 5015.871027] ext 3: off 0x36e, fsb 0x7a27, len 0xd
[ 5015.872206] ext 4: off 0x4cf, fsb 0x7a1d, len 0xa
So the delayed allocation extent is one block long at offset
0x16c00. Tracing shows that a bigger write:
xfs_file_buffered_write: size 0x1c85ae offset 0x959d count 0x1ca3f ioflags
allocates the block, and then fails with ENOSPC trying to allocate
the last block on the page, leading to a failed write with stale
delalloc blocks on it.
Because we've had an ENOSPC when trying to allocate 0x16e00, it
means that we are never goinge to call ->write_end on the page and
so the allocated new buffer will not get marked dirty or have the
buffer_new state cleared. In other works, what the above write is
supposed to end up with is this mapping for the page:
+------+------+------+------+------+------+------+------+
UMA UMA UMA UMA UMA UMA UND FAIL
where: U = uptodate
M = mapped
N = new
A = allocated
D = delalloc
FAIL = block we ENOSPC'd on.
and the key point being the buffer_new() state for the newly
allocated delayed allocation block. Except it doesn't - we're not
marking buffers new correctly.
That buffer_new() problem goes back to the xfs_iomap removal days,
where xfs_iomap() used to return a "new" status for any map with
newly allocated blocks, so that __xfs_get_blocks() could call
set_buffer_new() on it. We still have the "new" variable and the
check for it in the set_buffer_new() logic - except we never set it
now!
Hence that newly allocated delalloc block doesn't have the new flag
set on it, so when the write fails we cannot tell which blocks we
are supposed to punch out. WHy do we need the buffer_new flag? Well,
that's because we can have this case:
+------+------+------+------+------+------+------+------+
UMD UMD UMD UMD UMD UMD UND FAIL
where all the UMD buffers contain valid data from a previously
successful write() system call. We only want to punch the UND buffer
because that's the only one that we added in this write and it was
only this write that failed.
That implies that even the old buffer_new() logic was wrong -
because it would result in all those UMD buffers on the page having
set_buffer_new() called on them even though they aren't new. Hence
we shoul donly be calling set_buffer_new() for delalloc buffers that
were allocated (i.e. were a hole before xfs_iomap_write_delay() was
called).
So, fix this set_buffer_new logic according to how we need it to
work for handling failed writes correctly. Also, restore the new
buffer logic handling for blocks allocated via
xfs_iomap_write_direct(), because it should still set the buffer_new
flag appropriately for newly allocated blocks, too.
SO, now we have the buffer_new() being set appropriately in
__xfs_get_blocks(), we can detect the exact delalloc ranges that
we allocated in a failed write, and hence can now do a walk of the
buffers on a page to find them.
Except, it's not that easy. When block_write_begin() fails, it
unlocks and releases the page that we just had an error on, so we
can't use that page to handle errors anymore. We have to get access
to the page while it is still locked to walk the buffers. Hence we
have to open code block_write_begin() in xfs_vm_write_begin() to be
able to insert xfs_vm_write_failed() is the right place.
With that, we can pass the page and write range to
xfs_vm_write_failed() and walk the buffers on the page, looking for
delalloc buffers that are either new or beyond EOF and punch them
out. Handling buffers beyond EOF ensures we still handle the
existing case that xfs_vm_write_failed() handles.
Of special note is the truncate_pagecache() handling - that only
should be done for pages outside EOF - pages within EOF can still
contain valid, dirty data so we must not punch them out of the
cache.
That just leaves the xfs_vm_write_end() failure handling.
The only failure case here is that we didn't copy the entire range,
and generic_write_end() handles that by zeroing the region of the
page that wasn't copied, we don't have to punch out blocks within
the file because they are guaranteed to contain zeros. Hence we only
have to handle the existing "beyond EOF" case and don't need access
to the buffers on the page. Hence it remains largely unchanged.
Note that xfs_getbmap() can still trip over delalloc blocks beyond
EOF that are left there by speculative delayed allocation. Hence
this bug fix does not solve all known issues with bmap vs delalloc,
but it does fix all the the known accidental occurances of the
problem.
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-04-27 16:45:21 +07:00
|
|
|
if (!page)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
status = __block_write_begin(page, pos, len, xfs_get_blocks);
|
|
|
|
if (unlikely(status)) {
|
|
|
|
struct inode *inode = mapping->host;
|
2014-04-14 15:13:29 +07:00
|
|
|
size_t isize = i_size_read(inode);
|
xfs: punch new delalloc blocks out of failed writes inside EOF.
When a partial write inside EOF fails, it can leave delayed
allocation blocks lying around because they don't get punched back
out. This leads to assert failures like:
XFS: Assertion failed: XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0, file: fs/xfs/xfs_super.c, line: 847
when evicting inodes from the cache. This can be trivially triggered
by xfstests 083, which takes between 5 and 15 executions on a 512
byte block size filesystem to trip over this. Debugging shows a
failed write due to ENOSPC calling xfs_vm_write_failed such as:
[ 5012.329024] ino 0xa0026: vwf to 0x17000, sze 0x1c85ae
and no action is taken on it. This leaves behind a delayed
allocation extent that has no page covering it and no data in it:
[ 5015.867162] ino 0xa0026: blks: 0x83 delay blocks 0x1, size 0x2538c0
[ 5015.868293] ext 0: off 0x4a, fsb 0x50306, len 0x1
[ 5015.869095] ext 1: off 0x4b, fsb 0x7899, len 0x6b
[ 5015.869900] ext 2: off 0xb6, fsb 0xffffffffe0008, len 0x1
^^^^^^^^^^^^^^^
[ 5015.871027] ext 3: off 0x36e, fsb 0x7a27, len 0xd
[ 5015.872206] ext 4: off 0x4cf, fsb 0x7a1d, len 0xa
So the delayed allocation extent is one block long at offset
0x16c00. Tracing shows that a bigger write:
xfs_file_buffered_write: size 0x1c85ae offset 0x959d count 0x1ca3f ioflags
allocates the block, and then fails with ENOSPC trying to allocate
the last block on the page, leading to a failed write with stale
delalloc blocks on it.
Because we've had an ENOSPC when trying to allocate 0x16e00, it
means that we are never goinge to call ->write_end on the page and
so the allocated new buffer will not get marked dirty or have the
buffer_new state cleared. In other works, what the above write is
supposed to end up with is this mapping for the page:
+------+------+------+------+------+------+------+------+
UMA UMA UMA UMA UMA UMA UND FAIL
where: U = uptodate
M = mapped
N = new
A = allocated
D = delalloc
FAIL = block we ENOSPC'd on.
and the key point being the buffer_new() state for the newly
allocated delayed allocation block. Except it doesn't - we're not
marking buffers new correctly.
That buffer_new() problem goes back to the xfs_iomap removal days,
where xfs_iomap() used to return a "new" status for any map with
newly allocated blocks, so that __xfs_get_blocks() could call
set_buffer_new() on it. We still have the "new" variable and the
check for it in the set_buffer_new() logic - except we never set it
now!
Hence that newly allocated delalloc block doesn't have the new flag
set on it, so when the write fails we cannot tell which blocks we
are supposed to punch out. WHy do we need the buffer_new flag? Well,
that's because we can have this case:
+------+------+------+------+------+------+------+------+
UMD UMD UMD UMD UMD UMD UND FAIL
where all the UMD buffers contain valid data from a previously
successful write() system call. We only want to punch the UND buffer
because that's the only one that we added in this write and it was
only this write that failed.
That implies that even the old buffer_new() logic was wrong -
because it would result in all those UMD buffers on the page having
set_buffer_new() called on them even though they aren't new. Hence
we shoul donly be calling set_buffer_new() for delalloc buffers that
were allocated (i.e. were a hole before xfs_iomap_write_delay() was
called).
So, fix this set_buffer_new logic according to how we need it to
work for handling failed writes correctly. Also, restore the new
buffer logic handling for blocks allocated via
xfs_iomap_write_direct(), because it should still set the buffer_new
flag appropriately for newly allocated blocks, too.
SO, now we have the buffer_new() being set appropriately in
__xfs_get_blocks(), we can detect the exact delalloc ranges that
we allocated in a failed write, and hence can now do a walk of the
buffers on a page to find them.
Except, it's not that easy. When block_write_begin() fails, it
unlocks and releases the page that we just had an error on, so we
can't use that page to handle errors anymore. We have to get access
to the page while it is still locked to walk the buffers. Hence we
have to open code block_write_begin() in xfs_vm_write_begin() to be
able to insert xfs_vm_write_failed() is the right place.
With that, we can pass the page and write range to
xfs_vm_write_failed() and walk the buffers on the page, looking for
delalloc buffers that are either new or beyond EOF and punch them
out. Handling buffers beyond EOF ensures we still handle the
existing case that xfs_vm_write_failed() handles.
Of special note is the truncate_pagecache() handling - that only
should be done for pages outside EOF - pages within EOF can still
contain valid, dirty data so we must not punch them out of the
cache.
That just leaves the xfs_vm_write_end() failure handling.
The only failure case here is that we didn't copy the entire range,
and generic_write_end() handles that by zeroing the region of the
page that wasn't copied, we don't have to punch out blocks within
the file because they are guaranteed to contain zeros. Hence we only
have to handle the existing "beyond EOF" case and don't need access
to the buffers on the page. Hence it remains largely unchanged.
Note that xfs_getbmap() can still trip over delalloc blocks beyond
EOF that are left there by speculative delayed allocation. Hence
this bug fix does not solve all known issues with bmap vs delalloc,
but it does fix all the the known accidental occurances of the
problem.
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-04-27 16:45:21 +07:00
|
|
|
|
|
|
|
xfs_vm_write_failed(inode, page, pos, len);
|
|
|
|
unlock_page(page);
|
|
|
|
|
2014-04-14 15:13:29 +07:00
|
|
|
/*
|
|
|
|
* If the write is beyond EOF, we only want to kill blocks
|
|
|
|
* allocated in this write, not blocks that were previously
|
|
|
|
* written successfully.
|
|
|
|
*/
|
|
|
|
if (pos + len > isize) {
|
|
|
|
ssize_t start = max_t(ssize_t, pos, isize);
|
|
|
|
|
|
|
|
truncate_pagecache_range(inode, start, pos + len);
|
|
|
|
}
|
xfs: punch new delalloc blocks out of failed writes inside EOF.
When a partial write inside EOF fails, it can leave delayed
allocation blocks lying around because they don't get punched back
out. This leads to assert failures like:
XFS: Assertion failed: XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0, file: fs/xfs/xfs_super.c, line: 847
when evicting inodes from the cache. This can be trivially triggered
by xfstests 083, which takes between 5 and 15 executions on a 512
byte block size filesystem to trip over this. Debugging shows a
failed write due to ENOSPC calling xfs_vm_write_failed such as:
[ 5012.329024] ino 0xa0026: vwf to 0x17000, sze 0x1c85ae
and no action is taken on it. This leaves behind a delayed
allocation extent that has no page covering it and no data in it:
[ 5015.867162] ino 0xa0026: blks: 0x83 delay blocks 0x1, size 0x2538c0
[ 5015.868293] ext 0: off 0x4a, fsb 0x50306, len 0x1
[ 5015.869095] ext 1: off 0x4b, fsb 0x7899, len 0x6b
[ 5015.869900] ext 2: off 0xb6, fsb 0xffffffffe0008, len 0x1
^^^^^^^^^^^^^^^
[ 5015.871027] ext 3: off 0x36e, fsb 0x7a27, len 0xd
[ 5015.872206] ext 4: off 0x4cf, fsb 0x7a1d, len 0xa
So the delayed allocation extent is one block long at offset
0x16c00. Tracing shows that a bigger write:
xfs_file_buffered_write: size 0x1c85ae offset 0x959d count 0x1ca3f ioflags
allocates the block, and then fails with ENOSPC trying to allocate
the last block on the page, leading to a failed write with stale
delalloc blocks on it.
Because we've had an ENOSPC when trying to allocate 0x16e00, it
means that we are never goinge to call ->write_end on the page and
so the allocated new buffer will not get marked dirty or have the
buffer_new state cleared. In other works, what the above write is
supposed to end up with is this mapping for the page:
+------+------+------+------+------+------+------+------+
UMA UMA UMA UMA UMA UMA UND FAIL
where: U = uptodate
M = mapped
N = new
A = allocated
D = delalloc
FAIL = block we ENOSPC'd on.
and the key point being the buffer_new() state for the newly
allocated delayed allocation block. Except it doesn't - we're not
marking buffers new correctly.
That buffer_new() problem goes back to the xfs_iomap removal days,
where xfs_iomap() used to return a "new" status for any map with
newly allocated blocks, so that __xfs_get_blocks() could call
set_buffer_new() on it. We still have the "new" variable and the
check for it in the set_buffer_new() logic - except we never set it
now!
Hence that newly allocated delalloc block doesn't have the new flag
set on it, so when the write fails we cannot tell which blocks we
are supposed to punch out. WHy do we need the buffer_new flag? Well,
that's because we can have this case:
+------+------+------+------+------+------+------+------+
UMD UMD UMD UMD UMD UMD UND FAIL
where all the UMD buffers contain valid data from a previously
successful write() system call. We only want to punch the UND buffer
because that's the only one that we added in this write and it was
only this write that failed.
That implies that even the old buffer_new() logic was wrong -
because it would result in all those UMD buffers on the page having
set_buffer_new() called on them even though they aren't new. Hence
we shoul donly be calling set_buffer_new() for delalloc buffers that
were allocated (i.e. were a hole before xfs_iomap_write_delay() was
called).
So, fix this set_buffer_new logic according to how we need it to
work for handling failed writes correctly. Also, restore the new
buffer logic handling for blocks allocated via
xfs_iomap_write_direct(), because it should still set the buffer_new
flag appropriately for newly allocated blocks, too.
SO, now we have the buffer_new() being set appropriately in
__xfs_get_blocks(), we can detect the exact delalloc ranges that
we allocated in a failed write, and hence can now do a walk of the
buffers on a page to find them.
Except, it's not that easy. When block_write_begin() fails, it
unlocks and releases the page that we just had an error on, so we
can't use that page to handle errors anymore. We have to get access
to the page while it is still locked to walk the buffers. Hence we
have to open code block_write_begin() in xfs_vm_write_begin() to be
able to insert xfs_vm_write_failed() is the right place.
With that, we can pass the page and write range to
xfs_vm_write_failed() and walk the buffers on the page, looking for
delalloc buffers that are either new or beyond EOF and punch them
out. Handling buffers beyond EOF ensures we still handle the
existing case that xfs_vm_write_failed() handles.
Of special note is the truncate_pagecache() handling - that only
should be done for pages outside EOF - pages within EOF can still
contain valid, dirty data so we must not punch them out of the
cache.
That just leaves the xfs_vm_write_end() failure handling.
The only failure case here is that we didn't copy the entire range,
and generic_write_end() handles that by zeroing the region of the
page that wasn't copied, we don't have to punch out blocks within
the file because they are guaranteed to contain zeros. Hence we only
have to handle the existing "beyond EOF" case and don't need access
to the buffers on the page. Hence it remains largely unchanged.
Note that xfs_getbmap() can still trip over delalloc blocks beyond
EOF that are left there by speculative delayed allocation. Hence
this bug fix does not solve all known issues with bmap vs delalloc,
but it does fix all the the known accidental occurances of the
problem.
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-04-27 16:45:21 +07:00
|
|
|
|
|
|
|
page_cache_release(page);
|
|
|
|
page = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
*pagep = page;
|
|
|
|
return status;
|
2010-06-14 16:17:31 +07:00
|
|
|
}
|
|
|
|
|
xfs: punch new delalloc blocks out of failed writes inside EOF.
When a partial write inside EOF fails, it can leave delayed
allocation blocks lying around because they don't get punched back
out. This leads to assert failures like:
XFS: Assertion failed: XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0, file: fs/xfs/xfs_super.c, line: 847
when evicting inodes from the cache. This can be trivially triggered
by xfstests 083, which takes between 5 and 15 executions on a 512
byte block size filesystem to trip over this. Debugging shows a
failed write due to ENOSPC calling xfs_vm_write_failed such as:
[ 5012.329024] ino 0xa0026: vwf to 0x17000, sze 0x1c85ae
and no action is taken on it. This leaves behind a delayed
allocation extent that has no page covering it and no data in it:
[ 5015.867162] ino 0xa0026: blks: 0x83 delay blocks 0x1, size 0x2538c0
[ 5015.868293] ext 0: off 0x4a, fsb 0x50306, len 0x1
[ 5015.869095] ext 1: off 0x4b, fsb 0x7899, len 0x6b
[ 5015.869900] ext 2: off 0xb6, fsb 0xffffffffe0008, len 0x1
^^^^^^^^^^^^^^^
[ 5015.871027] ext 3: off 0x36e, fsb 0x7a27, len 0xd
[ 5015.872206] ext 4: off 0x4cf, fsb 0x7a1d, len 0xa
So the delayed allocation extent is one block long at offset
0x16c00. Tracing shows that a bigger write:
xfs_file_buffered_write: size 0x1c85ae offset 0x959d count 0x1ca3f ioflags
allocates the block, and then fails with ENOSPC trying to allocate
the last block on the page, leading to a failed write with stale
delalloc blocks on it.
Because we've had an ENOSPC when trying to allocate 0x16e00, it
means that we are never goinge to call ->write_end on the page and
so the allocated new buffer will not get marked dirty or have the
buffer_new state cleared. In other works, what the above write is
supposed to end up with is this mapping for the page:
+------+------+------+------+------+------+------+------+
UMA UMA UMA UMA UMA UMA UND FAIL
where: U = uptodate
M = mapped
N = new
A = allocated
D = delalloc
FAIL = block we ENOSPC'd on.
and the key point being the buffer_new() state for the newly
allocated delayed allocation block. Except it doesn't - we're not
marking buffers new correctly.
That buffer_new() problem goes back to the xfs_iomap removal days,
where xfs_iomap() used to return a "new" status for any map with
newly allocated blocks, so that __xfs_get_blocks() could call
set_buffer_new() on it. We still have the "new" variable and the
check for it in the set_buffer_new() logic - except we never set it
now!
Hence that newly allocated delalloc block doesn't have the new flag
set on it, so when the write fails we cannot tell which blocks we
are supposed to punch out. WHy do we need the buffer_new flag? Well,
that's because we can have this case:
+------+------+------+------+------+------+------+------+
UMD UMD UMD UMD UMD UMD UND FAIL
where all the UMD buffers contain valid data from a previously
successful write() system call. We only want to punch the UND buffer
because that's the only one that we added in this write and it was
only this write that failed.
That implies that even the old buffer_new() logic was wrong -
because it would result in all those UMD buffers on the page having
set_buffer_new() called on them even though they aren't new. Hence
we shoul donly be calling set_buffer_new() for delalloc buffers that
were allocated (i.e. were a hole before xfs_iomap_write_delay() was
called).
So, fix this set_buffer_new logic according to how we need it to
work for handling failed writes correctly. Also, restore the new
buffer logic handling for blocks allocated via
xfs_iomap_write_direct(), because it should still set the buffer_new
flag appropriately for newly allocated blocks, too.
SO, now we have the buffer_new() being set appropriately in
__xfs_get_blocks(), we can detect the exact delalloc ranges that
we allocated in a failed write, and hence can now do a walk of the
buffers on a page to find them.
Except, it's not that easy. When block_write_begin() fails, it
unlocks and releases the page that we just had an error on, so we
can't use that page to handle errors anymore. We have to get access
to the page while it is still locked to walk the buffers. Hence we
have to open code block_write_begin() in xfs_vm_write_begin() to be
able to insert xfs_vm_write_failed() is the right place.
With that, we can pass the page and write range to
xfs_vm_write_failed() and walk the buffers on the page, looking for
delalloc buffers that are either new or beyond EOF and punch them
out. Handling buffers beyond EOF ensures we still handle the
existing case that xfs_vm_write_failed() handles.
Of special note is the truncate_pagecache() handling - that only
should be done for pages outside EOF - pages within EOF can still
contain valid, dirty data so we must not punch them out of the
cache.
That just leaves the xfs_vm_write_end() failure handling.
The only failure case here is that we didn't copy the entire range,
and generic_write_end() handles that by zeroing the region of the
page that wasn't copied, we don't have to punch out blocks within
the file because they are guaranteed to contain zeros. Hence we only
have to handle the existing "beyond EOF" case and don't need access
to the buffers on the page. Hence it remains largely unchanged.
Note that xfs_getbmap() can still trip over delalloc blocks beyond
EOF that are left there by speculative delayed allocation. Hence
this bug fix does not solve all known issues with bmap vs delalloc,
but it does fix all the the known accidental occurances of the
problem.
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-04-27 16:45:21 +07:00
|
|
|
/*
|
2014-04-14 15:14:11 +07:00
|
|
|
* On failure, we only need to kill delalloc blocks beyond EOF in the range of
|
|
|
|
* this specific write because they will never be written. Previous writes
|
|
|
|
* beyond EOF where block allocation succeeded do not need to be trashed, so
|
|
|
|
* only new blocks from this write should be trashed. For blocks within
|
|
|
|
* EOF, generic_write_end() zeros them so they are safe to leave alone and be
|
|
|
|
* written with all the other valid data.
|
xfs: punch new delalloc blocks out of failed writes inside EOF.
When a partial write inside EOF fails, it can leave delayed
allocation blocks lying around because they don't get punched back
out. This leads to assert failures like:
XFS: Assertion failed: XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0, file: fs/xfs/xfs_super.c, line: 847
when evicting inodes from the cache. This can be trivially triggered
by xfstests 083, which takes between 5 and 15 executions on a 512
byte block size filesystem to trip over this. Debugging shows a
failed write due to ENOSPC calling xfs_vm_write_failed such as:
[ 5012.329024] ino 0xa0026: vwf to 0x17000, sze 0x1c85ae
and no action is taken on it. This leaves behind a delayed
allocation extent that has no page covering it and no data in it:
[ 5015.867162] ino 0xa0026: blks: 0x83 delay blocks 0x1, size 0x2538c0
[ 5015.868293] ext 0: off 0x4a, fsb 0x50306, len 0x1
[ 5015.869095] ext 1: off 0x4b, fsb 0x7899, len 0x6b
[ 5015.869900] ext 2: off 0xb6, fsb 0xffffffffe0008, len 0x1
^^^^^^^^^^^^^^^
[ 5015.871027] ext 3: off 0x36e, fsb 0x7a27, len 0xd
[ 5015.872206] ext 4: off 0x4cf, fsb 0x7a1d, len 0xa
So the delayed allocation extent is one block long at offset
0x16c00. Tracing shows that a bigger write:
xfs_file_buffered_write: size 0x1c85ae offset 0x959d count 0x1ca3f ioflags
allocates the block, and then fails with ENOSPC trying to allocate
the last block on the page, leading to a failed write with stale
delalloc blocks on it.
Because we've had an ENOSPC when trying to allocate 0x16e00, it
means that we are never goinge to call ->write_end on the page and
so the allocated new buffer will not get marked dirty or have the
buffer_new state cleared. In other works, what the above write is
supposed to end up with is this mapping for the page:
+------+------+------+------+------+------+------+------+
UMA UMA UMA UMA UMA UMA UND FAIL
where: U = uptodate
M = mapped
N = new
A = allocated
D = delalloc
FAIL = block we ENOSPC'd on.
and the key point being the buffer_new() state for the newly
allocated delayed allocation block. Except it doesn't - we're not
marking buffers new correctly.
That buffer_new() problem goes back to the xfs_iomap removal days,
where xfs_iomap() used to return a "new" status for any map with
newly allocated blocks, so that __xfs_get_blocks() could call
set_buffer_new() on it. We still have the "new" variable and the
check for it in the set_buffer_new() logic - except we never set it
now!
Hence that newly allocated delalloc block doesn't have the new flag
set on it, so when the write fails we cannot tell which blocks we
are supposed to punch out. WHy do we need the buffer_new flag? Well,
that's because we can have this case:
+------+------+------+------+------+------+------+------+
UMD UMD UMD UMD UMD UMD UND FAIL
where all the UMD buffers contain valid data from a previously
successful write() system call. We only want to punch the UND buffer
because that's the only one that we added in this write and it was
only this write that failed.
That implies that even the old buffer_new() logic was wrong -
because it would result in all those UMD buffers on the page having
set_buffer_new() called on them even though they aren't new. Hence
we shoul donly be calling set_buffer_new() for delalloc buffers that
were allocated (i.e. were a hole before xfs_iomap_write_delay() was
called).
So, fix this set_buffer_new logic according to how we need it to
work for handling failed writes correctly. Also, restore the new
buffer logic handling for blocks allocated via
xfs_iomap_write_direct(), because it should still set the buffer_new
flag appropriately for newly allocated blocks, too.
SO, now we have the buffer_new() being set appropriately in
__xfs_get_blocks(), we can detect the exact delalloc ranges that
we allocated in a failed write, and hence can now do a walk of the
buffers on a page to find them.
Except, it's not that easy. When block_write_begin() fails, it
unlocks and releases the page that we just had an error on, so we
can't use that page to handle errors anymore. We have to get access
to the page while it is still locked to walk the buffers. Hence we
have to open code block_write_begin() in xfs_vm_write_begin() to be
able to insert xfs_vm_write_failed() is the right place.
With that, we can pass the page and write range to
xfs_vm_write_failed() and walk the buffers on the page, looking for
delalloc buffers that are either new or beyond EOF and punch them
out. Handling buffers beyond EOF ensures we still handle the
existing case that xfs_vm_write_failed() handles.
Of special note is the truncate_pagecache() handling - that only
should be done for pages outside EOF - pages within EOF can still
contain valid, dirty data so we must not punch them out of the
cache.
That just leaves the xfs_vm_write_end() failure handling.
The only failure case here is that we didn't copy the entire range,
and generic_write_end() handles that by zeroing the region of the
page that wasn't copied, we don't have to punch out blocks within
the file because they are guaranteed to contain zeros. Hence we only
have to handle the existing "beyond EOF" case and don't need access
to the buffers on the page. Hence it remains largely unchanged.
Note that xfs_getbmap() can still trip over delalloc blocks beyond
EOF that are left there by speculative delayed allocation. Hence
this bug fix does not solve all known issues with bmap vs delalloc,
but it does fix all the the known accidental occurances of the
problem.
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-04-27 16:45:21 +07:00
|
|
|
*/
|
2010-06-14 16:17:31 +07:00
|
|
|
STATIC int
|
|
|
|
xfs_vm_write_end(
|
|
|
|
struct file *file,
|
|
|
|
struct address_space *mapping,
|
|
|
|
loff_t pos,
|
|
|
|
unsigned len,
|
|
|
|
unsigned copied,
|
|
|
|
struct page *page,
|
|
|
|
void *fsdata)
|
|
|
|
{
|
|
|
|
int ret;
|
2010-06-04 16:29:58 +07:00
|
|
|
|
xfs: punch new delalloc blocks out of failed writes inside EOF.
When a partial write inside EOF fails, it can leave delayed
allocation blocks lying around because they don't get punched back
out. This leads to assert failures like:
XFS: Assertion failed: XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0, file: fs/xfs/xfs_super.c, line: 847
when evicting inodes from the cache. This can be trivially triggered
by xfstests 083, which takes between 5 and 15 executions on a 512
byte block size filesystem to trip over this. Debugging shows a
failed write due to ENOSPC calling xfs_vm_write_failed such as:
[ 5012.329024] ino 0xa0026: vwf to 0x17000, sze 0x1c85ae
and no action is taken on it. This leaves behind a delayed
allocation extent that has no page covering it and no data in it:
[ 5015.867162] ino 0xa0026: blks: 0x83 delay blocks 0x1, size 0x2538c0
[ 5015.868293] ext 0: off 0x4a, fsb 0x50306, len 0x1
[ 5015.869095] ext 1: off 0x4b, fsb 0x7899, len 0x6b
[ 5015.869900] ext 2: off 0xb6, fsb 0xffffffffe0008, len 0x1
^^^^^^^^^^^^^^^
[ 5015.871027] ext 3: off 0x36e, fsb 0x7a27, len 0xd
[ 5015.872206] ext 4: off 0x4cf, fsb 0x7a1d, len 0xa
So the delayed allocation extent is one block long at offset
0x16c00. Tracing shows that a bigger write:
xfs_file_buffered_write: size 0x1c85ae offset 0x959d count 0x1ca3f ioflags
allocates the block, and then fails with ENOSPC trying to allocate
the last block on the page, leading to a failed write with stale
delalloc blocks on it.
Because we've had an ENOSPC when trying to allocate 0x16e00, it
means that we are never goinge to call ->write_end on the page and
so the allocated new buffer will not get marked dirty or have the
buffer_new state cleared. In other works, what the above write is
supposed to end up with is this mapping for the page:
+------+------+------+------+------+------+------+------+
UMA UMA UMA UMA UMA UMA UND FAIL
where: U = uptodate
M = mapped
N = new
A = allocated
D = delalloc
FAIL = block we ENOSPC'd on.
and the key point being the buffer_new() state for the newly
allocated delayed allocation block. Except it doesn't - we're not
marking buffers new correctly.
That buffer_new() problem goes back to the xfs_iomap removal days,
where xfs_iomap() used to return a "new" status for any map with
newly allocated blocks, so that __xfs_get_blocks() could call
set_buffer_new() on it. We still have the "new" variable and the
check for it in the set_buffer_new() logic - except we never set it
now!
Hence that newly allocated delalloc block doesn't have the new flag
set on it, so when the write fails we cannot tell which blocks we
are supposed to punch out. WHy do we need the buffer_new flag? Well,
that's because we can have this case:
+------+------+------+------+------+------+------+------+
UMD UMD UMD UMD UMD UMD UND FAIL
where all the UMD buffers contain valid data from a previously
successful write() system call. We only want to punch the UND buffer
because that's the only one that we added in this write and it was
only this write that failed.
That implies that even the old buffer_new() logic was wrong -
because it would result in all those UMD buffers on the page having
set_buffer_new() called on them even though they aren't new. Hence
we shoul donly be calling set_buffer_new() for delalloc buffers that
were allocated (i.e. were a hole before xfs_iomap_write_delay() was
called).
So, fix this set_buffer_new logic according to how we need it to
work for handling failed writes correctly. Also, restore the new
buffer logic handling for blocks allocated via
xfs_iomap_write_direct(), because it should still set the buffer_new
flag appropriately for newly allocated blocks, too.
SO, now we have the buffer_new() being set appropriately in
__xfs_get_blocks(), we can detect the exact delalloc ranges that
we allocated in a failed write, and hence can now do a walk of the
buffers on a page to find them.
Except, it's not that easy. When block_write_begin() fails, it
unlocks and releases the page that we just had an error on, so we
can't use that page to handle errors anymore. We have to get access
to the page while it is still locked to walk the buffers. Hence we
have to open code block_write_begin() in xfs_vm_write_begin() to be
able to insert xfs_vm_write_failed() is the right place.
With that, we can pass the page and write range to
xfs_vm_write_failed() and walk the buffers on the page, looking for
delalloc buffers that are either new or beyond EOF and punch them
out. Handling buffers beyond EOF ensures we still handle the
existing case that xfs_vm_write_failed() handles.
Of special note is the truncate_pagecache() handling - that only
should be done for pages outside EOF - pages within EOF can still
contain valid, dirty data so we must not punch them out of the
cache.
That just leaves the xfs_vm_write_end() failure handling.
The only failure case here is that we didn't copy the entire range,
and generic_write_end() handles that by zeroing the region of the
page that wasn't copied, we don't have to punch out blocks within
the file because they are guaranteed to contain zeros. Hence we only
have to handle the existing "beyond EOF" case and don't need access
to the buffers on the page. Hence it remains largely unchanged.
Note that xfs_getbmap() can still trip over delalloc blocks beyond
EOF that are left there by speculative delayed allocation. Hence
this bug fix does not solve all known issues with bmap vs delalloc,
but it does fix all the the known accidental occurances of the
problem.
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-04-27 16:45:21 +07:00
|
|
|
ASSERT(len <= PAGE_CACHE_SIZE);
|
|
|
|
|
2010-06-14 16:17:31 +07:00
|
|
|
ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata);
|
xfs: punch new delalloc blocks out of failed writes inside EOF.
When a partial write inside EOF fails, it can leave delayed
allocation blocks lying around because they don't get punched back
out. This leads to assert failures like:
XFS: Assertion failed: XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0, file: fs/xfs/xfs_super.c, line: 847
when evicting inodes from the cache. This can be trivially triggered
by xfstests 083, which takes between 5 and 15 executions on a 512
byte block size filesystem to trip over this. Debugging shows a
failed write due to ENOSPC calling xfs_vm_write_failed such as:
[ 5012.329024] ino 0xa0026: vwf to 0x17000, sze 0x1c85ae
and no action is taken on it. This leaves behind a delayed
allocation extent that has no page covering it and no data in it:
[ 5015.867162] ino 0xa0026: blks: 0x83 delay blocks 0x1, size 0x2538c0
[ 5015.868293] ext 0: off 0x4a, fsb 0x50306, len 0x1
[ 5015.869095] ext 1: off 0x4b, fsb 0x7899, len 0x6b
[ 5015.869900] ext 2: off 0xb6, fsb 0xffffffffe0008, len 0x1
^^^^^^^^^^^^^^^
[ 5015.871027] ext 3: off 0x36e, fsb 0x7a27, len 0xd
[ 5015.872206] ext 4: off 0x4cf, fsb 0x7a1d, len 0xa
So the delayed allocation extent is one block long at offset
0x16c00. Tracing shows that a bigger write:
xfs_file_buffered_write: size 0x1c85ae offset 0x959d count 0x1ca3f ioflags
allocates the block, and then fails with ENOSPC trying to allocate
the last block on the page, leading to a failed write with stale
delalloc blocks on it.
Because we've had an ENOSPC when trying to allocate 0x16e00, it
means that we are never goinge to call ->write_end on the page and
so the allocated new buffer will not get marked dirty or have the
buffer_new state cleared. In other works, what the above write is
supposed to end up with is this mapping for the page:
+------+------+------+------+------+------+------+------+
UMA UMA UMA UMA UMA UMA UND FAIL
where: U = uptodate
M = mapped
N = new
A = allocated
D = delalloc
FAIL = block we ENOSPC'd on.
and the key point being the buffer_new() state for the newly
allocated delayed allocation block. Except it doesn't - we're not
marking buffers new correctly.
That buffer_new() problem goes back to the xfs_iomap removal days,
where xfs_iomap() used to return a "new" status for any map with
newly allocated blocks, so that __xfs_get_blocks() could call
set_buffer_new() on it. We still have the "new" variable and the
check for it in the set_buffer_new() logic - except we never set it
now!
Hence that newly allocated delalloc block doesn't have the new flag
set on it, so when the write fails we cannot tell which blocks we
are supposed to punch out. WHy do we need the buffer_new flag? Well,
that's because we can have this case:
+------+------+------+------+------+------+------+------+
UMD UMD UMD UMD UMD UMD UND FAIL
where all the UMD buffers contain valid data from a previously
successful write() system call. We only want to punch the UND buffer
because that's the only one that we added in this write and it was
only this write that failed.
That implies that even the old buffer_new() logic was wrong -
because it would result in all those UMD buffers on the page having
set_buffer_new() called on them even though they aren't new. Hence
we shoul donly be calling set_buffer_new() for delalloc buffers that
were allocated (i.e. were a hole before xfs_iomap_write_delay() was
called).
So, fix this set_buffer_new logic according to how we need it to
work for handling failed writes correctly. Also, restore the new
buffer logic handling for blocks allocated via
xfs_iomap_write_direct(), because it should still set the buffer_new
flag appropriately for newly allocated blocks, too.
SO, now we have the buffer_new() being set appropriately in
__xfs_get_blocks(), we can detect the exact delalloc ranges that
we allocated in a failed write, and hence can now do a walk of the
buffers on a page to find them.
Except, it's not that easy. When block_write_begin() fails, it
unlocks and releases the page that we just had an error on, so we
can't use that page to handle errors anymore. We have to get access
to the page while it is still locked to walk the buffers. Hence we
have to open code block_write_begin() in xfs_vm_write_begin() to be
able to insert xfs_vm_write_failed() is the right place.
With that, we can pass the page and write range to
xfs_vm_write_failed() and walk the buffers on the page, looking for
delalloc buffers that are either new or beyond EOF and punch them
out. Handling buffers beyond EOF ensures we still handle the
existing case that xfs_vm_write_failed() handles.
Of special note is the truncate_pagecache() handling - that only
should be done for pages outside EOF - pages within EOF can still
contain valid, dirty data so we must not punch them out of the
cache.
That just leaves the xfs_vm_write_end() failure handling.
The only failure case here is that we didn't copy the entire range,
and generic_write_end() handles that by zeroing the region of the
page that wasn't copied, we don't have to punch out blocks within
the file because they are guaranteed to contain zeros. Hence we only
have to handle the existing "beyond EOF" case and don't need access
to the buffers on the page. Hence it remains largely unchanged.
Note that xfs_getbmap() can still trip over delalloc blocks beyond
EOF that are left there by speculative delayed allocation. Hence
this bug fix does not solve all known issues with bmap vs delalloc,
but it does fix all the the known accidental occurances of the
problem.
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-04-27 16:45:21 +07:00
|
|
|
if (unlikely(ret < len)) {
|
|
|
|
struct inode *inode = mapping->host;
|
|
|
|
size_t isize = i_size_read(inode);
|
|
|
|
loff_t to = pos + len;
|
|
|
|
|
|
|
|
if (to > isize) {
|
2014-04-14 15:14:11 +07:00
|
|
|
/* only kill blocks in this write beyond EOF */
|
|
|
|
if (pos > isize)
|
|
|
|
isize = pos;
|
xfs: punch new delalloc blocks out of failed writes inside EOF.
When a partial write inside EOF fails, it can leave delayed
allocation blocks lying around because they don't get punched back
out. This leads to assert failures like:
XFS: Assertion failed: XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0, file: fs/xfs/xfs_super.c, line: 847
when evicting inodes from the cache. This can be trivially triggered
by xfstests 083, which takes between 5 and 15 executions on a 512
byte block size filesystem to trip over this. Debugging shows a
failed write due to ENOSPC calling xfs_vm_write_failed such as:
[ 5012.329024] ino 0xa0026: vwf to 0x17000, sze 0x1c85ae
and no action is taken on it. This leaves behind a delayed
allocation extent that has no page covering it and no data in it:
[ 5015.867162] ino 0xa0026: blks: 0x83 delay blocks 0x1, size 0x2538c0
[ 5015.868293] ext 0: off 0x4a, fsb 0x50306, len 0x1
[ 5015.869095] ext 1: off 0x4b, fsb 0x7899, len 0x6b
[ 5015.869900] ext 2: off 0xb6, fsb 0xffffffffe0008, len 0x1
^^^^^^^^^^^^^^^
[ 5015.871027] ext 3: off 0x36e, fsb 0x7a27, len 0xd
[ 5015.872206] ext 4: off 0x4cf, fsb 0x7a1d, len 0xa
So the delayed allocation extent is one block long at offset
0x16c00. Tracing shows that a bigger write:
xfs_file_buffered_write: size 0x1c85ae offset 0x959d count 0x1ca3f ioflags
allocates the block, and then fails with ENOSPC trying to allocate
the last block on the page, leading to a failed write with stale
delalloc blocks on it.
Because we've had an ENOSPC when trying to allocate 0x16e00, it
means that we are never goinge to call ->write_end on the page and
so the allocated new buffer will not get marked dirty or have the
buffer_new state cleared. In other works, what the above write is
supposed to end up with is this mapping for the page:
+------+------+------+------+------+------+------+------+
UMA UMA UMA UMA UMA UMA UND FAIL
where: U = uptodate
M = mapped
N = new
A = allocated
D = delalloc
FAIL = block we ENOSPC'd on.
and the key point being the buffer_new() state for the newly
allocated delayed allocation block. Except it doesn't - we're not
marking buffers new correctly.
That buffer_new() problem goes back to the xfs_iomap removal days,
where xfs_iomap() used to return a "new" status for any map with
newly allocated blocks, so that __xfs_get_blocks() could call
set_buffer_new() on it. We still have the "new" variable and the
check for it in the set_buffer_new() logic - except we never set it
now!
Hence that newly allocated delalloc block doesn't have the new flag
set on it, so when the write fails we cannot tell which blocks we
are supposed to punch out. WHy do we need the buffer_new flag? Well,
that's because we can have this case:
+------+------+------+------+------+------+------+------+
UMD UMD UMD UMD UMD UMD UND FAIL
where all the UMD buffers contain valid data from a previously
successful write() system call. We only want to punch the UND buffer
because that's the only one that we added in this write and it was
only this write that failed.
That implies that even the old buffer_new() logic was wrong -
because it would result in all those UMD buffers on the page having
set_buffer_new() called on them even though they aren't new. Hence
we shoul donly be calling set_buffer_new() for delalloc buffers that
were allocated (i.e. were a hole before xfs_iomap_write_delay() was
called).
So, fix this set_buffer_new logic according to how we need it to
work for handling failed writes correctly. Also, restore the new
buffer logic handling for blocks allocated via
xfs_iomap_write_direct(), because it should still set the buffer_new
flag appropriately for newly allocated blocks, too.
SO, now we have the buffer_new() being set appropriately in
__xfs_get_blocks(), we can detect the exact delalloc ranges that
we allocated in a failed write, and hence can now do a walk of the
buffers on a page to find them.
Except, it's not that easy. When block_write_begin() fails, it
unlocks and releases the page that we just had an error on, so we
can't use that page to handle errors anymore. We have to get access
to the page while it is still locked to walk the buffers. Hence we
have to open code block_write_begin() in xfs_vm_write_begin() to be
able to insert xfs_vm_write_failed() is the right place.
With that, we can pass the page and write range to
xfs_vm_write_failed() and walk the buffers on the page, looking for
delalloc buffers that are either new or beyond EOF and punch them
out. Handling buffers beyond EOF ensures we still handle the
existing case that xfs_vm_write_failed() handles.
Of special note is the truncate_pagecache() handling - that only
should be done for pages outside EOF - pages within EOF can still
contain valid, dirty data so we must not punch them out of the
cache.
That just leaves the xfs_vm_write_end() failure handling.
The only failure case here is that we didn't copy the entire range,
and generic_write_end() handles that by zeroing the region of the
page that wasn't copied, we don't have to punch out blocks within
the file because they are guaranteed to contain zeros. Hence we only
have to handle the existing "beyond EOF" case and don't need access
to the buffers on the page. Hence it remains largely unchanged.
Note that xfs_getbmap() can still trip over delalloc blocks beyond
EOF that are left there by speculative delayed allocation. Hence
this bug fix does not solve all known issues with bmap vs delalloc,
but it does fix all the the known accidental occurances of the
problem.
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-04-27 16:45:21 +07:00
|
|
|
xfs_vm_kill_delalloc_range(inode, isize, to);
|
2014-04-14 15:14:11 +07:00
|
|
|
truncate_pagecache_range(inode, isize, to);
|
xfs: punch new delalloc blocks out of failed writes inside EOF.
When a partial write inside EOF fails, it can leave delayed
allocation blocks lying around because they don't get punched back
out. This leads to assert failures like:
XFS: Assertion failed: XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0, file: fs/xfs/xfs_super.c, line: 847
when evicting inodes from the cache. This can be trivially triggered
by xfstests 083, which takes between 5 and 15 executions on a 512
byte block size filesystem to trip over this. Debugging shows a
failed write due to ENOSPC calling xfs_vm_write_failed such as:
[ 5012.329024] ino 0xa0026: vwf to 0x17000, sze 0x1c85ae
and no action is taken on it. This leaves behind a delayed
allocation extent that has no page covering it and no data in it:
[ 5015.867162] ino 0xa0026: blks: 0x83 delay blocks 0x1, size 0x2538c0
[ 5015.868293] ext 0: off 0x4a, fsb 0x50306, len 0x1
[ 5015.869095] ext 1: off 0x4b, fsb 0x7899, len 0x6b
[ 5015.869900] ext 2: off 0xb6, fsb 0xffffffffe0008, len 0x1
^^^^^^^^^^^^^^^
[ 5015.871027] ext 3: off 0x36e, fsb 0x7a27, len 0xd
[ 5015.872206] ext 4: off 0x4cf, fsb 0x7a1d, len 0xa
So the delayed allocation extent is one block long at offset
0x16c00. Tracing shows that a bigger write:
xfs_file_buffered_write: size 0x1c85ae offset 0x959d count 0x1ca3f ioflags
allocates the block, and then fails with ENOSPC trying to allocate
the last block on the page, leading to a failed write with stale
delalloc blocks on it.
Because we've had an ENOSPC when trying to allocate 0x16e00, it
means that we are never goinge to call ->write_end on the page and
so the allocated new buffer will not get marked dirty or have the
buffer_new state cleared. In other works, what the above write is
supposed to end up with is this mapping for the page:
+------+------+------+------+------+------+------+------+
UMA UMA UMA UMA UMA UMA UND FAIL
where: U = uptodate
M = mapped
N = new
A = allocated
D = delalloc
FAIL = block we ENOSPC'd on.
and the key point being the buffer_new() state for the newly
allocated delayed allocation block. Except it doesn't - we're not
marking buffers new correctly.
That buffer_new() problem goes back to the xfs_iomap removal days,
where xfs_iomap() used to return a "new" status for any map with
newly allocated blocks, so that __xfs_get_blocks() could call
set_buffer_new() on it. We still have the "new" variable and the
check for it in the set_buffer_new() logic - except we never set it
now!
Hence that newly allocated delalloc block doesn't have the new flag
set on it, so when the write fails we cannot tell which blocks we
are supposed to punch out. WHy do we need the buffer_new flag? Well,
that's because we can have this case:
+------+------+------+------+------+------+------+------+
UMD UMD UMD UMD UMD UMD UND FAIL
where all the UMD buffers contain valid data from a previously
successful write() system call. We only want to punch the UND buffer
because that's the only one that we added in this write and it was
only this write that failed.
That implies that even the old buffer_new() logic was wrong -
because it would result in all those UMD buffers on the page having
set_buffer_new() called on them even though they aren't new. Hence
we shoul donly be calling set_buffer_new() for delalloc buffers that
were allocated (i.e. were a hole before xfs_iomap_write_delay() was
called).
So, fix this set_buffer_new logic according to how we need it to
work for handling failed writes correctly. Also, restore the new
buffer logic handling for blocks allocated via
xfs_iomap_write_direct(), because it should still set the buffer_new
flag appropriately for newly allocated blocks, too.
SO, now we have the buffer_new() being set appropriately in
__xfs_get_blocks(), we can detect the exact delalloc ranges that
we allocated in a failed write, and hence can now do a walk of the
buffers on a page to find them.
Except, it's not that easy. When block_write_begin() fails, it
unlocks and releases the page that we just had an error on, so we
can't use that page to handle errors anymore. We have to get access
to the page while it is still locked to walk the buffers. Hence we
have to open code block_write_begin() in xfs_vm_write_begin() to be
able to insert xfs_vm_write_failed() is the right place.
With that, we can pass the page and write range to
xfs_vm_write_failed() and walk the buffers on the page, looking for
delalloc buffers that are either new or beyond EOF and punch them
out. Handling buffers beyond EOF ensures we still handle the
existing case that xfs_vm_write_failed() handles.
Of special note is the truncate_pagecache() handling - that only
should be done for pages outside EOF - pages within EOF can still
contain valid, dirty data so we must not punch them out of the
cache.
That just leaves the xfs_vm_write_end() failure handling.
The only failure case here is that we didn't copy the entire range,
and generic_write_end() handles that by zeroing the region of the
page that wasn't copied, we don't have to punch out blocks within
the file because they are guaranteed to contain zeros. Hence we only
have to handle the existing "beyond EOF" case and don't need access
to the buffers on the page. Hence it remains largely unchanged.
Note that xfs_getbmap() can still trip over delalloc blocks beyond
EOF that are left there by speculative delayed allocation. Hence
this bug fix does not solve all known issues with bmap vs delalloc,
but it does fix all the the known accidental occurances of the
problem.
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-04-27 16:45:21 +07:00
|
|
|
}
|
|
|
|
}
|
2010-06-04 16:29:58 +07:00
|
|
|
return ret;
|
2006-03-14 09:26:27 +07:00
|
|
|
}
|
2005-04-17 05:20:36 +07:00
|
|
|
|
|
|
|
STATIC sector_t
|
2006-03-14 09:54:26 +07:00
|
|
|
xfs_vm_bmap(
|
2005-04-17 05:20:36 +07:00
|
|
|
struct address_space *mapping,
|
|
|
|
sector_t block)
|
|
|
|
{
|
|
|
|
struct inode *inode = (struct inode *)mapping->host;
|
2007-08-29 07:58:01 +07:00
|
|
|
struct xfs_inode *ip = XFS_I(inode);
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2010-06-24 08:57:09 +07:00
|
|
|
trace_xfs_vm_bmap(XFS_I(inode));
|
2008-03-06 09:44:57 +07:00
|
|
|
xfs_ilock(ip, XFS_IOLOCK_SHARED);
|
2012-11-12 18:53:56 +07:00
|
|
|
filemap_write_and_wait(mapping);
|
2008-03-06 09:44:57 +07:00
|
|
|
xfs_iunlock(ip, XFS_IOLOCK_SHARED);
|
2006-03-29 07:44:40 +07:00
|
|
|
return generic_block_bmap(mapping, block, xfs_get_blocks);
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
STATIC int
|
2006-03-14 09:54:26 +07:00
|
|
|
xfs_vm_readpage(
|
2005-04-17 05:20:36 +07:00
|
|
|
struct file *unused,
|
|
|
|
struct page *page)
|
|
|
|
{
|
2006-03-29 07:44:40 +07:00
|
|
|
return mpage_readpage(page, xfs_get_blocks);
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
STATIC int
|
2006-03-14 09:54:26 +07:00
|
|
|
xfs_vm_readpages(
|
2005-04-17 05:20:36 +07:00
|
|
|
struct file *unused,
|
|
|
|
struct address_space *mapping,
|
|
|
|
struct list_head *pages,
|
|
|
|
unsigned nr_pages)
|
|
|
|
{
|
2006-03-29 07:44:40 +07:00
|
|
|
return mpage_readpages(mapping, pages, nr_pages, xfs_get_blocks);
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
xfs: don't dirty buffers beyond EOF
generic/263 is failing fsx at this point with a page spanning
EOF that cannot be invalidated. The operations are:
1190 mapwrite 0x52c00 thru 0x5e569 (0xb96a bytes)
1191 mapread 0x5c000 thru 0x5d636 (0x1637 bytes)
1192 write 0x5b600 thru 0x771ff (0x1bc00 bytes)
where 1190 extents EOF from 0x54000 to 0x5e569. When the direct IO
write attempts to invalidate the cached page over this range, it
fails with -EBUSY and so any attempt to do page invalidation fails.
The real question is this: Why can't that page be invalidated after
it has been written to disk and cleaned?
Well, there's data on the first two buffers in the page (1k block
size, 4k page), but the third buffer on the page (i.e. beyond EOF)
is failing drop_buffers because it's bh->b_state == 0x3, which is
BH_Uptodate | BH_Dirty. IOWs, there's dirty buffers beyond EOF. Say
what?
OK, set_buffer_dirty() is called on all buffers from
__set_page_buffers_dirty(), regardless of whether the buffer is
beyond EOF or not, which means that when we get to ->writepage,
we have buffers marked dirty beyond EOF that we need to clean.
So, we need to implement our own .set_page_dirty method that
doesn't dirty buffers beyond EOF.
This is messy because the buffer code is not meant to be shared
and it has interesting locking issues on the buffer dirty bits.
So just copy and paste it and then modify it to suit what we need.
Note: the solutions the other filesystems and generic block code use
of marking the buffers clean in ->writepage does not work for XFS.
It still leaves dirty buffers beyond EOF and invalidations still
fail. Hence rather than play whack-a-mole, this patch simply
prevents those buffers from being dirtied in the first place.
cc: <stable@kernel.org>
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
2014-09-02 09:12:51 +07:00
|
|
|
/*
|
|
|
|
* This is basically a copy of __set_page_dirty_buffers() with one
|
|
|
|
* small tweak: buffers beyond EOF do not get marked dirty. If we mark them
|
|
|
|
* dirty, we'll never be able to clean them because we don't write buffers
|
|
|
|
* beyond EOF, and that means we can't invalidate pages that span EOF
|
|
|
|
* that have been marked dirty. Further, the dirty state can leak into
|
|
|
|
* the file interior if the file is extended, resulting in all sorts of
|
|
|
|
* bad things happening as the state does not match the underlying data.
|
|
|
|
*
|
|
|
|
* XXX: this really indicates that bufferheads in XFS need to die. Warts like
|
|
|
|
* this only exist because of bufferheads and how the generic code manages them.
|
|
|
|
*/
|
|
|
|
STATIC int
|
|
|
|
xfs_vm_set_page_dirty(
|
|
|
|
struct page *page)
|
|
|
|
{
|
|
|
|
struct address_space *mapping = page->mapping;
|
|
|
|
struct inode *inode = mapping->host;
|
|
|
|
loff_t end_offset;
|
|
|
|
loff_t offset;
|
|
|
|
int newly_dirty;
|
memcg: add per cgroup dirty page accounting
When modifying PG_Dirty on cached file pages, update the new
MEM_CGROUP_STAT_DIRTY counter. This is done in the same places where
global NR_FILE_DIRTY is managed. The new memcg stat is visible in the
per memcg memory.stat cgroupfs file. The most recent past attempt at
this was http://thread.gmane.org/gmane.linux.kernel.cgroups/8632
The new accounting supports future efforts to add per cgroup dirty
page throttling and writeback. It also helps an administrator break
down a container's memory usage and provides evidence to understand
memcg oom kills (the new dirty count is included in memcg oom kill
messages).
The ability to move page accounting between memcg
(memory.move_charge_at_immigrate) makes this accounting more
complicated than the global counter. The existing
mem_cgroup_{begin,end}_page_stat() lock is used to serialize move
accounting with stat updates.
Typical update operation:
memcg = mem_cgroup_begin_page_stat(page)
if (TestSetPageDirty()) {
[...]
mem_cgroup_update_page_stat(memcg)
}
mem_cgroup_end_page_stat(memcg)
Summary of mem_cgroup_end_page_stat() overhead:
- Without CONFIG_MEMCG it's a no-op
- With CONFIG_MEMCG and no inter memcg task movement, it's just
rcu_read_lock()
- With CONFIG_MEMCG and inter memcg task movement, it's
rcu_read_lock() + spin_lock_irqsave()
A memcg parameter is added to several routines because their callers
now grab mem_cgroup_begin_page_stat() which returns the memcg later
needed by for mem_cgroup_update_page_stat().
Because mem_cgroup_begin_page_stat() may disable interrupts, some
adjustments are needed:
- move __mark_inode_dirty() from __set_page_dirty() to its caller.
__mark_inode_dirty() locking does not want interrupts disabled.
- use spin_lock_irqsave(tree_lock) rather than spin_lock_irq() in
__delete_from_page_cache(), replace_page_cache_page(),
invalidate_complete_page2(), and __remove_mapping().
text data bss dec hex filename
8925147 1774832 1785856 12485835 be84cb vmlinux-!CONFIG_MEMCG-before
8925339 1774832 1785856 12486027 be858b vmlinux-!CONFIG_MEMCG-after
+192 text bytes
8965977 1784992 1785856 12536825 bf4bf9 vmlinux-CONFIG_MEMCG-before
8966750 1784992 1785856 12537598 bf4efe vmlinux-CONFIG_MEMCG-after
+773 text bytes
Performance tests run on v4.0-rc1-36-g4f671fe2f952. Lower is better for
all metrics, they're all wall clock or cycle counts. The read and write
fault benchmarks just measure fault time, they do not include I/O time.
* CONFIG_MEMCG not set:
baseline patched
kbuild 1m25.030000(+-0.088% 3 samples) 1m25.426667(+-0.120% 3 samples)
dd write 100 MiB 0.859211561 +-15.10% 0.874162885 +-15.03%
dd write 200 MiB 1.670653105 +-17.87% 1.669384764 +-11.99%
dd write 1000 MiB 8.434691190 +-14.15% 8.474733215 +-14.77%
read fault cycles 254.0(+-0.000% 10 samples) 253.0(+-0.000% 10 samples)
write fault cycles 2021.2(+-3.070% 10 samples) 1984.5(+-1.036% 10 samples)
* CONFIG_MEMCG=y root_memcg:
baseline patched
kbuild 1m25.716667(+-0.105% 3 samples) 1m25.686667(+-0.153% 3 samples)
dd write 100 MiB 0.855650830 +-14.90% 0.887557919 +-14.90%
dd write 200 MiB 1.688322953 +-12.72% 1.667682724 +-13.33%
dd write 1000 MiB 8.418601605 +-14.30% 8.673532299 +-15.00%
read fault cycles 266.0(+-0.000% 10 samples) 266.0(+-0.000% 10 samples)
write fault cycles 2051.7(+-1.349% 10 samples) 2049.6(+-1.686% 10 samples)
* CONFIG_MEMCG=y non-root_memcg:
baseline patched
kbuild 1m26.120000(+-0.273% 3 samples) 1m25.763333(+-0.127% 3 samples)
dd write 100 MiB 0.861723964 +-15.25% 0.818129350 +-14.82%
dd write 200 MiB 1.669887569 +-13.30% 1.698645885 +-13.27%
dd write 1000 MiB 8.383191730 +-14.65% 8.351742280 +-14.52%
read fault cycles 265.7(+-0.172% 10 samples) 267.0(+-0.000% 10 samples)
write fault cycles 2070.6(+-1.512% 10 samples) 2084.4(+-2.148% 10 samples)
As expected anon page faults are not affected by this patch.
tj: Updated to apply on top of the recent cancel_dirty_page() changes.
Signed-off-by: Sha Zhengju <handai.szj@gmail.com>
Signed-off-by: Greg Thelen <gthelen@google.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jens Axboe <axboe@fb.com>
2015-05-23 04:13:16 +07:00
|
|
|
struct mem_cgroup *memcg;
|
xfs: don't dirty buffers beyond EOF
generic/263 is failing fsx at this point with a page spanning
EOF that cannot be invalidated. The operations are:
1190 mapwrite 0x52c00 thru 0x5e569 (0xb96a bytes)
1191 mapread 0x5c000 thru 0x5d636 (0x1637 bytes)
1192 write 0x5b600 thru 0x771ff (0x1bc00 bytes)
where 1190 extents EOF from 0x54000 to 0x5e569. When the direct IO
write attempts to invalidate the cached page over this range, it
fails with -EBUSY and so any attempt to do page invalidation fails.
The real question is this: Why can't that page be invalidated after
it has been written to disk and cleaned?
Well, there's data on the first two buffers in the page (1k block
size, 4k page), but the third buffer on the page (i.e. beyond EOF)
is failing drop_buffers because it's bh->b_state == 0x3, which is
BH_Uptodate | BH_Dirty. IOWs, there's dirty buffers beyond EOF. Say
what?
OK, set_buffer_dirty() is called on all buffers from
__set_page_buffers_dirty(), regardless of whether the buffer is
beyond EOF or not, which means that when we get to ->writepage,
we have buffers marked dirty beyond EOF that we need to clean.
So, we need to implement our own .set_page_dirty method that
doesn't dirty buffers beyond EOF.
This is messy because the buffer code is not meant to be shared
and it has interesting locking issues on the buffer dirty bits.
So just copy and paste it and then modify it to suit what we need.
Note: the solutions the other filesystems and generic block code use
of marking the buffers clean in ->writepage does not work for XFS.
It still leaves dirty buffers beyond EOF and invalidations still
fail. Hence rather than play whack-a-mole, this patch simply
prevents those buffers from being dirtied in the first place.
cc: <stable@kernel.org>
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
2014-09-02 09:12:51 +07:00
|
|
|
|
|
|
|
if (unlikely(!mapping))
|
|
|
|
return !TestSetPageDirty(page);
|
|
|
|
|
|
|
|
end_offset = i_size_read(inode);
|
|
|
|
offset = page_offset(page);
|
|
|
|
|
|
|
|
spin_lock(&mapping->private_lock);
|
|
|
|
if (page_has_buffers(page)) {
|
|
|
|
struct buffer_head *head = page_buffers(page);
|
|
|
|
struct buffer_head *bh = head;
|
|
|
|
|
|
|
|
do {
|
|
|
|
if (offset < end_offset)
|
|
|
|
set_buffer_dirty(bh);
|
|
|
|
bh = bh->b_this_page;
|
|
|
|
offset += 1 << inode->i_blkbits;
|
|
|
|
} while (bh != head);
|
|
|
|
}
|
memcg: add per cgroup dirty page accounting
When modifying PG_Dirty on cached file pages, update the new
MEM_CGROUP_STAT_DIRTY counter. This is done in the same places where
global NR_FILE_DIRTY is managed. The new memcg stat is visible in the
per memcg memory.stat cgroupfs file. The most recent past attempt at
this was http://thread.gmane.org/gmane.linux.kernel.cgroups/8632
The new accounting supports future efforts to add per cgroup dirty
page throttling and writeback. It also helps an administrator break
down a container's memory usage and provides evidence to understand
memcg oom kills (the new dirty count is included in memcg oom kill
messages).
The ability to move page accounting between memcg
(memory.move_charge_at_immigrate) makes this accounting more
complicated than the global counter. The existing
mem_cgroup_{begin,end}_page_stat() lock is used to serialize move
accounting with stat updates.
Typical update operation:
memcg = mem_cgroup_begin_page_stat(page)
if (TestSetPageDirty()) {
[...]
mem_cgroup_update_page_stat(memcg)
}
mem_cgroup_end_page_stat(memcg)
Summary of mem_cgroup_end_page_stat() overhead:
- Without CONFIG_MEMCG it's a no-op
- With CONFIG_MEMCG and no inter memcg task movement, it's just
rcu_read_lock()
- With CONFIG_MEMCG and inter memcg task movement, it's
rcu_read_lock() + spin_lock_irqsave()
A memcg parameter is added to several routines because their callers
now grab mem_cgroup_begin_page_stat() which returns the memcg later
needed by for mem_cgroup_update_page_stat().
Because mem_cgroup_begin_page_stat() may disable interrupts, some
adjustments are needed:
- move __mark_inode_dirty() from __set_page_dirty() to its caller.
__mark_inode_dirty() locking does not want interrupts disabled.
- use spin_lock_irqsave(tree_lock) rather than spin_lock_irq() in
__delete_from_page_cache(), replace_page_cache_page(),
invalidate_complete_page2(), and __remove_mapping().
text data bss dec hex filename
8925147 1774832 1785856 12485835 be84cb vmlinux-!CONFIG_MEMCG-before
8925339 1774832 1785856 12486027 be858b vmlinux-!CONFIG_MEMCG-after
+192 text bytes
8965977 1784992 1785856 12536825 bf4bf9 vmlinux-CONFIG_MEMCG-before
8966750 1784992 1785856 12537598 bf4efe vmlinux-CONFIG_MEMCG-after
+773 text bytes
Performance tests run on v4.0-rc1-36-g4f671fe2f952. Lower is better for
all metrics, they're all wall clock or cycle counts. The read and write
fault benchmarks just measure fault time, they do not include I/O time.
* CONFIG_MEMCG not set:
baseline patched
kbuild 1m25.030000(+-0.088% 3 samples) 1m25.426667(+-0.120% 3 samples)
dd write 100 MiB 0.859211561 +-15.10% 0.874162885 +-15.03%
dd write 200 MiB 1.670653105 +-17.87% 1.669384764 +-11.99%
dd write 1000 MiB 8.434691190 +-14.15% 8.474733215 +-14.77%
read fault cycles 254.0(+-0.000% 10 samples) 253.0(+-0.000% 10 samples)
write fault cycles 2021.2(+-3.070% 10 samples) 1984.5(+-1.036% 10 samples)
* CONFIG_MEMCG=y root_memcg:
baseline patched
kbuild 1m25.716667(+-0.105% 3 samples) 1m25.686667(+-0.153% 3 samples)
dd write 100 MiB 0.855650830 +-14.90% 0.887557919 +-14.90%
dd write 200 MiB 1.688322953 +-12.72% 1.667682724 +-13.33%
dd write 1000 MiB 8.418601605 +-14.30% 8.673532299 +-15.00%
read fault cycles 266.0(+-0.000% 10 samples) 266.0(+-0.000% 10 samples)
write fault cycles 2051.7(+-1.349% 10 samples) 2049.6(+-1.686% 10 samples)
* CONFIG_MEMCG=y non-root_memcg:
baseline patched
kbuild 1m26.120000(+-0.273% 3 samples) 1m25.763333(+-0.127% 3 samples)
dd write 100 MiB 0.861723964 +-15.25% 0.818129350 +-14.82%
dd write 200 MiB 1.669887569 +-13.30% 1.698645885 +-13.27%
dd write 1000 MiB 8.383191730 +-14.65% 8.351742280 +-14.52%
read fault cycles 265.7(+-0.172% 10 samples) 267.0(+-0.000% 10 samples)
write fault cycles 2070.6(+-1.512% 10 samples) 2084.4(+-2.148% 10 samples)
As expected anon page faults are not affected by this patch.
tj: Updated to apply on top of the recent cancel_dirty_page() changes.
Signed-off-by: Sha Zhengju <handai.szj@gmail.com>
Signed-off-by: Greg Thelen <gthelen@google.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jens Axboe <axboe@fb.com>
2015-05-23 04:13:16 +07:00
|
|
|
/*
|
|
|
|
* Use mem_group_begin_page_stat() to keep PageDirty synchronized with
|
|
|
|
* per-memcg dirty page counters.
|
|
|
|
*/
|
|
|
|
memcg = mem_cgroup_begin_page_stat(page);
|
xfs: don't dirty buffers beyond EOF
generic/263 is failing fsx at this point with a page spanning
EOF that cannot be invalidated. The operations are:
1190 mapwrite 0x52c00 thru 0x5e569 (0xb96a bytes)
1191 mapread 0x5c000 thru 0x5d636 (0x1637 bytes)
1192 write 0x5b600 thru 0x771ff (0x1bc00 bytes)
where 1190 extents EOF from 0x54000 to 0x5e569. When the direct IO
write attempts to invalidate the cached page over this range, it
fails with -EBUSY and so any attempt to do page invalidation fails.
The real question is this: Why can't that page be invalidated after
it has been written to disk and cleaned?
Well, there's data on the first two buffers in the page (1k block
size, 4k page), but the third buffer on the page (i.e. beyond EOF)
is failing drop_buffers because it's bh->b_state == 0x3, which is
BH_Uptodate | BH_Dirty. IOWs, there's dirty buffers beyond EOF. Say
what?
OK, set_buffer_dirty() is called on all buffers from
__set_page_buffers_dirty(), regardless of whether the buffer is
beyond EOF or not, which means that when we get to ->writepage,
we have buffers marked dirty beyond EOF that we need to clean.
So, we need to implement our own .set_page_dirty method that
doesn't dirty buffers beyond EOF.
This is messy because the buffer code is not meant to be shared
and it has interesting locking issues on the buffer dirty bits.
So just copy and paste it and then modify it to suit what we need.
Note: the solutions the other filesystems and generic block code use
of marking the buffers clean in ->writepage does not work for XFS.
It still leaves dirty buffers beyond EOF and invalidations still
fail. Hence rather than play whack-a-mole, this patch simply
prevents those buffers from being dirtied in the first place.
cc: <stable@kernel.org>
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
2014-09-02 09:12:51 +07:00
|
|
|
newly_dirty = !TestSetPageDirty(page);
|
|
|
|
spin_unlock(&mapping->private_lock);
|
|
|
|
|
|
|
|
if (newly_dirty) {
|
|
|
|
/* sigh - __set_page_dirty() is static, so copy it here, too */
|
|
|
|
unsigned long flags;
|
|
|
|
|
|
|
|
spin_lock_irqsave(&mapping->tree_lock, flags);
|
|
|
|
if (page->mapping) { /* Race with truncate? */
|
|
|
|
WARN_ON_ONCE(!PageUptodate(page));
|
memcg: add per cgroup dirty page accounting
When modifying PG_Dirty on cached file pages, update the new
MEM_CGROUP_STAT_DIRTY counter. This is done in the same places where
global NR_FILE_DIRTY is managed. The new memcg stat is visible in the
per memcg memory.stat cgroupfs file. The most recent past attempt at
this was http://thread.gmane.org/gmane.linux.kernel.cgroups/8632
The new accounting supports future efforts to add per cgroup dirty
page throttling and writeback. It also helps an administrator break
down a container's memory usage and provides evidence to understand
memcg oom kills (the new dirty count is included in memcg oom kill
messages).
The ability to move page accounting between memcg
(memory.move_charge_at_immigrate) makes this accounting more
complicated than the global counter. The existing
mem_cgroup_{begin,end}_page_stat() lock is used to serialize move
accounting with stat updates.
Typical update operation:
memcg = mem_cgroup_begin_page_stat(page)
if (TestSetPageDirty()) {
[...]
mem_cgroup_update_page_stat(memcg)
}
mem_cgroup_end_page_stat(memcg)
Summary of mem_cgroup_end_page_stat() overhead:
- Without CONFIG_MEMCG it's a no-op
- With CONFIG_MEMCG and no inter memcg task movement, it's just
rcu_read_lock()
- With CONFIG_MEMCG and inter memcg task movement, it's
rcu_read_lock() + spin_lock_irqsave()
A memcg parameter is added to several routines because their callers
now grab mem_cgroup_begin_page_stat() which returns the memcg later
needed by for mem_cgroup_update_page_stat().
Because mem_cgroup_begin_page_stat() may disable interrupts, some
adjustments are needed:
- move __mark_inode_dirty() from __set_page_dirty() to its caller.
__mark_inode_dirty() locking does not want interrupts disabled.
- use spin_lock_irqsave(tree_lock) rather than spin_lock_irq() in
__delete_from_page_cache(), replace_page_cache_page(),
invalidate_complete_page2(), and __remove_mapping().
text data bss dec hex filename
8925147 1774832 1785856 12485835 be84cb vmlinux-!CONFIG_MEMCG-before
8925339 1774832 1785856 12486027 be858b vmlinux-!CONFIG_MEMCG-after
+192 text bytes
8965977 1784992 1785856 12536825 bf4bf9 vmlinux-CONFIG_MEMCG-before
8966750 1784992 1785856 12537598 bf4efe vmlinux-CONFIG_MEMCG-after
+773 text bytes
Performance tests run on v4.0-rc1-36-g4f671fe2f952. Lower is better for
all metrics, they're all wall clock or cycle counts. The read and write
fault benchmarks just measure fault time, they do not include I/O time.
* CONFIG_MEMCG not set:
baseline patched
kbuild 1m25.030000(+-0.088% 3 samples) 1m25.426667(+-0.120% 3 samples)
dd write 100 MiB 0.859211561 +-15.10% 0.874162885 +-15.03%
dd write 200 MiB 1.670653105 +-17.87% 1.669384764 +-11.99%
dd write 1000 MiB 8.434691190 +-14.15% 8.474733215 +-14.77%
read fault cycles 254.0(+-0.000% 10 samples) 253.0(+-0.000% 10 samples)
write fault cycles 2021.2(+-3.070% 10 samples) 1984.5(+-1.036% 10 samples)
* CONFIG_MEMCG=y root_memcg:
baseline patched
kbuild 1m25.716667(+-0.105% 3 samples) 1m25.686667(+-0.153% 3 samples)
dd write 100 MiB 0.855650830 +-14.90% 0.887557919 +-14.90%
dd write 200 MiB 1.688322953 +-12.72% 1.667682724 +-13.33%
dd write 1000 MiB 8.418601605 +-14.30% 8.673532299 +-15.00%
read fault cycles 266.0(+-0.000% 10 samples) 266.0(+-0.000% 10 samples)
write fault cycles 2051.7(+-1.349% 10 samples) 2049.6(+-1.686% 10 samples)
* CONFIG_MEMCG=y non-root_memcg:
baseline patched
kbuild 1m26.120000(+-0.273% 3 samples) 1m25.763333(+-0.127% 3 samples)
dd write 100 MiB 0.861723964 +-15.25% 0.818129350 +-14.82%
dd write 200 MiB 1.669887569 +-13.30% 1.698645885 +-13.27%
dd write 1000 MiB 8.383191730 +-14.65% 8.351742280 +-14.52%
read fault cycles 265.7(+-0.172% 10 samples) 267.0(+-0.000% 10 samples)
write fault cycles 2070.6(+-1.512% 10 samples) 2084.4(+-2.148% 10 samples)
As expected anon page faults are not affected by this patch.
tj: Updated to apply on top of the recent cancel_dirty_page() changes.
Signed-off-by: Sha Zhengju <handai.szj@gmail.com>
Signed-off-by: Greg Thelen <gthelen@google.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jens Axboe <axboe@fb.com>
2015-05-23 04:13:16 +07:00
|
|
|
account_page_dirtied(page, mapping, memcg);
|
xfs: don't dirty buffers beyond EOF
generic/263 is failing fsx at this point with a page spanning
EOF that cannot be invalidated. The operations are:
1190 mapwrite 0x52c00 thru 0x5e569 (0xb96a bytes)
1191 mapread 0x5c000 thru 0x5d636 (0x1637 bytes)
1192 write 0x5b600 thru 0x771ff (0x1bc00 bytes)
where 1190 extents EOF from 0x54000 to 0x5e569. When the direct IO
write attempts to invalidate the cached page over this range, it
fails with -EBUSY and so any attempt to do page invalidation fails.
The real question is this: Why can't that page be invalidated after
it has been written to disk and cleaned?
Well, there's data on the first two buffers in the page (1k block
size, 4k page), but the third buffer on the page (i.e. beyond EOF)
is failing drop_buffers because it's bh->b_state == 0x3, which is
BH_Uptodate | BH_Dirty. IOWs, there's dirty buffers beyond EOF. Say
what?
OK, set_buffer_dirty() is called on all buffers from
__set_page_buffers_dirty(), regardless of whether the buffer is
beyond EOF or not, which means that when we get to ->writepage,
we have buffers marked dirty beyond EOF that we need to clean.
So, we need to implement our own .set_page_dirty method that
doesn't dirty buffers beyond EOF.
This is messy because the buffer code is not meant to be shared
and it has interesting locking issues on the buffer dirty bits.
So just copy and paste it and then modify it to suit what we need.
Note: the solutions the other filesystems and generic block code use
of marking the buffers clean in ->writepage does not work for XFS.
It still leaves dirty buffers beyond EOF and invalidations still
fail. Hence rather than play whack-a-mole, this patch simply
prevents those buffers from being dirtied in the first place.
cc: <stable@kernel.org>
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
2014-09-02 09:12:51 +07:00
|
|
|
radix_tree_tag_set(&mapping->page_tree,
|
|
|
|
page_index(page), PAGECACHE_TAG_DIRTY);
|
|
|
|
}
|
|
|
|
spin_unlock_irqrestore(&mapping->tree_lock, flags);
|
|
|
|
}
|
memcg: add per cgroup dirty page accounting
When modifying PG_Dirty on cached file pages, update the new
MEM_CGROUP_STAT_DIRTY counter. This is done in the same places where
global NR_FILE_DIRTY is managed. The new memcg stat is visible in the
per memcg memory.stat cgroupfs file. The most recent past attempt at
this was http://thread.gmane.org/gmane.linux.kernel.cgroups/8632
The new accounting supports future efforts to add per cgroup dirty
page throttling and writeback. It also helps an administrator break
down a container's memory usage and provides evidence to understand
memcg oom kills (the new dirty count is included in memcg oom kill
messages).
The ability to move page accounting between memcg
(memory.move_charge_at_immigrate) makes this accounting more
complicated than the global counter. The existing
mem_cgroup_{begin,end}_page_stat() lock is used to serialize move
accounting with stat updates.
Typical update operation:
memcg = mem_cgroup_begin_page_stat(page)
if (TestSetPageDirty()) {
[...]
mem_cgroup_update_page_stat(memcg)
}
mem_cgroup_end_page_stat(memcg)
Summary of mem_cgroup_end_page_stat() overhead:
- Without CONFIG_MEMCG it's a no-op
- With CONFIG_MEMCG and no inter memcg task movement, it's just
rcu_read_lock()
- With CONFIG_MEMCG and inter memcg task movement, it's
rcu_read_lock() + spin_lock_irqsave()
A memcg parameter is added to several routines because their callers
now grab mem_cgroup_begin_page_stat() which returns the memcg later
needed by for mem_cgroup_update_page_stat().
Because mem_cgroup_begin_page_stat() may disable interrupts, some
adjustments are needed:
- move __mark_inode_dirty() from __set_page_dirty() to its caller.
__mark_inode_dirty() locking does not want interrupts disabled.
- use spin_lock_irqsave(tree_lock) rather than spin_lock_irq() in
__delete_from_page_cache(), replace_page_cache_page(),
invalidate_complete_page2(), and __remove_mapping().
text data bss dec hex filename
8925147 1774832 1785856 12485835 be84cb vmlinux-!CONFIG_MEMCG-before
8925339 1774832 1785856 12486027 be858b vmlinux-!CONFIG_MEMCG-after
+192 text bytes
8965977 1784992 1785856 12536825 bf4bf9 vmlinux-CONFIG_MEMCG-before
8966750 1784992 1785856 12537598 bf4efe vmlinux-CONFIG_MEMCG-after
+773 text bytes
Performance tests run on v4.0-rc1-36-g4f671fe2f952. Lower is better for
all metrics, they're all wall clock or cycle counts. The read and write
fault benchmarks just measure fault time, they do not include I/O time.
* CONFIG_MEMCG not set:
baseline patched
kbuild 1m25.030000(+-0.088% 3 samples) 1m25.426667(+-0.120% 3 samples)
dd write 100 MiB 0.859211561 +-15.10% 0.874162885 +-15.03%
dd write 200 MiB 1.670653105 +-17.87% 1.669384764 +-11.99%
dd write 1000 MiB 8.434691190 +-14.15% 8.474733215 +-14.77%
read fault cycles 254.0(+-0.000% 10 samples) 253.0(+-0.000% 10 samples)
write fault cycles 2021.2(+-3.070% 10 samples) 1984.5(+-1.036% 10 samples)
* CONFIG_MEMCG=y root_memcg:
baseline patched
kbuild 1m25.716667(+-0.105% 3 samples) 1m25.686667(+-0.153% 3 samples)
dd write 100 MiB 0.855650830 +-14.90% 0.887557919 +-14.90%
dd write 200 MiB 1.688322953 +-12.72% 1.667682724 +-13.33%
dd write 1000 MiB 8.418601605 +-14.30% 8.673532299 +-15.00%
read fault cycles 266.0(+-0.000% 10 samples) 266.0(+-0.000% 10 samples)
write fault cycles 2051.7(+-1.349% 10 samples) 2049.6(+-1.686% 10 samples)
* CONFIG_MEMCG=y non-root_memcg:
baseline patched
kbuild 1m26.120000(+-0.273% 3 samples) 1m25.763333(+-0.127% 3 samples)
dd write 100 MiB 0.861723964 +-15.25% 0.818129350 +-14.82%
dd write 200 MiB 1.669887569 +-13.30% 1.698645885 +-13.27%
dd write 1000 MiB 8.383191730 +-14.65% 8.351742280 +-14.52%
read fault cycles 265.7(+-0.172% 10 samples) 267.0(+-0.000% 10 samples)
write fault cycles 2070.6(+-1.512% 10 samples) 2084.4(+-2.148% 10 samples)
As expected anon page faults are not affected by this patch.
tj: Updated to apply on top of the recent cancel_dirty_page() changes.
Signed-off-by: Sha Zhengju <handai.szj@gmail.com>
Signed-off-by: Greg Thelen <gthelen@google.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jens Axboe <axboe@fb.com>
2015-05-23 04:13:16 +07:00
|
|
|
mem_cgroup_end_page_stat(memcg);
|
|
|
|
if (newly_dirty)
|
|
|
|
__mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
|
xfs: don't dirty buffers beyond EOF
generic/263 is failing fsx at this point with a page spanning
EOF that cannot be invalidated. The operations are:
1190 mapwrite 0x52c00 thru 0x5e569 (0xb96a bytes)
1191 mapread 0x5c000 thru 0x5d636 (0x1637 bytes)
1192 write 0x5b600 thru 0x771ff (0x1bc00 bytes)
where 1190 extents EOF from 0x54000 to 0x5e569. When the direct IO
write attempts to invalidate the cached page over this range, it
fails with -EBUSY and so any attempt to do page invalidation fails.
The real question is this: Why can't that page be invalidated after
it has been written to disk and cleaned?
Well, there's data on the first two buffers in the page (1k block
size, 4k page), but the third buffer on the page (i.e. beyond EOF)
is failing drop_buffers because it's bh->b_state == 0x3, which is
BH_Uptodate | BH_Dirty. IOWs, there's dirty buffers beyond EOF. Say
what?
OK, set_buffer_dirty() is called on all buffers from
__set_page_buffers_dirty(), regardless of whether the buffer is
beyond EOF or not, which means that when we get to ->writepage,
we have buffers marked dirty beyond EOF that we need to clean.
So, we need to implement our own .set_page_dirty method that
doesn't dirty buffers beyond EOF.
This is messy because the buffer code is not meant to be shared
and it has interesting locking issues on the buffer dirty bits.
So just copy and paste it and then modify it to suit what we need.
Note: the solutions the other filesystems and generic block code use
of marking the buffers clean in ->writepage does not work for XFS.
It still leaves dirty buffers beyond EOF and invalidations still
fail. Hence rather than play whack-a-mole, this patch simply
prevents those buffers from being dirtied in the first place.
cc: <stable@kernel.org>
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
2014-09-02 09:12:51 +07:00
|
|
|
return newly_dirty;
|
|
|
|
}
|
|
|
|
|
2006-06-28 18:26:44 +07:00
|
|
|
const struct address_space_operations xfs_address_space_operations = {
|
2006-03-14 09:54:26 +07:00
|
|
|
.readpage = xfs_vm_readpage,
|
|
|
|
.readpages = xfs_vm_readpages,
|
|
|
|
.writepage = xfs_vm_writepage,
|
2006-06-09 12:27:16 +07:00
|
|
|
.writepages = xfs_vm_writepages,
|
xfs: don't dirty buffers beyond EOF
generic/263 is failing fsx at this point with a page spanning
EOF that cannot be invalidated. The operations are:
1190 mapwrite 0x52c00 thru 0x5e569 (0xb96a bytes)
1191 mapread 0x5c000 thru 0x5d636 (0x1637 bytes)
1192 write 0x5b600 thru 0x771ff (0x1bc00 bytes)
where 1190 extents EOF from 0x54000 to 0x5e569. When the direct IO
write attempts to invalidate the cached page over this range, it
fails with -EBUSY and so any attempt to do page invalidation fails.
The real question is this: Why can't that page be invalidated after
it has been written to disk and cleaned?
Well, there's data on the first two buffers in the page (1k block
size, 4k page), but the third buffer on the page (i.e. beyond EOF)
is failing drop_buffers because it's bh->b_state == 0x3, which is
BH_Uptodate | BH_Dirty. IOWs, there's dirty buffers beyond EOF. Say
what?
OK, set_buffer_dirty() is called on all buffers from
__set_page_buffers_dirty(), regardless of whether the buffer is
beyond EOF or not, which means that when we get to ->writepage,
we have buffers marked dirty beyond EOF that we need to clean.
So, we need to implement our own .set_page_dirty method that
doesn't dirty buffers beyond EOF.
This is messy because the buffer code is not meant to be shared
and it has interesting locking issues on the buffer dirty bits.
So just copy and paste it and then modify it to suit what we need.
Note: the solutions the other filesystems and generic block code use
of marking the buffers clean in ->writepage does not work for XFS.
It still leaves dirty buffers beyond EOF and invalidations still
fail. Hence rather than play whack-a-mole, this patch simply
prevents those buffers from being dirtied in the first place.
cc: <stable@kernel.org>
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
2014-09-02 09:12:51 +07:00
|
|
|
.set_page_dirty = xfs_vm_set_page_dirty,
|
2006-03-17 13:26:25 +07:00
|
|
|
.releasepage = xfs_vm_releasepage,
|
|
|
|
.invalidatepage = xfs_vm_invalidatepage,
|
2007-10-16 15:25:06 +07:00
|
|
|
.write_begin = xfs_vm_write_begin,
|
2010-06-14 16:17:31 +07:00
|
|
|
.write_end = xfs_vm_write_end,
|
2006-03-14 09:54:26 +07:00
|
|
|
.bmap = xfs_vm_bmap,
|
|
|
|
.direct_IO = xfs_vm_direct_IO,
|
2006-02-01 18:05:41 +07:00
|
|
|
.migratepage = buffer_migrate_page,
|
2009-03-29 14:53:38 +07:00
|
|
|
.is_partially_uptodate = block_is_partially_uptodate,
|
2009-09-16 16:50:16 +07:00
|
|
|
.error_remove_page = generic_error_remove_page,
|
2005-04-17 05:20:36 +07:00
|
|
|
};
|