mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-10 07:10:27 +00:00
Merge branch 'xfs-for-linus-v3.13-rc5' into for-next
This commit is contained in:
commit
324bb26144
@ -3648,10 +3648,19 @@ xfs_bmap_btalloc(
|
|||||||
int isaligned;
|
int isaligned;
|
||||||
int tryagain;
|
int tryagain;
|
||||||
int error;
|
int error;
|
||||||
|
int stripe_align;
|
||||||
|
|
||||||
ASSERT(ap->length);
|
ASSERT(ap->length);
|
||||||
|
|
||||||
mp = ap->ip->i_mount;
|
mp = ap->ip->i_mount;
|
||||||
|
|
||||||
|
/* stripe alignment for allocation is determined by mount parameters */
|
||||||
|
stripe_align = 0;
|
||||||
|
if (mp->m_swidth && (mp->m_flags & XFS_MOUNT_SWALLOC))
|
||||||
|
stripe_align = mp->m_swidth;
|
||||||
|
else if (mp->m_dalign)
|
||||||
|
stripe_align = mp->m_dalign;
|
||||||
|
|
||||||
align = ap->userdata ? xfs_get_extsz_hint(ap->ip) : 0;
|
align = ap->userdata ? xfs_get_extsz_hint(ap->ip) : 0;
|
||||||
if (unlikely(align)) {
|
if (unlikely(align)) {
|
||||||
error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev,
|
error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev,
|
||||||
@ -3660,6 +3669,8 @@ xfs_bmap_btalloc(
|
|||||||
ASSERT(!error);
|
ASSERT(!error);
|
||||||
ASSERT(ap->length);
|
ASSERT(ap->length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
nullfb = *ap->firstblock == NULLFSBLOCK;
|
nullfb = *ap->firstblock == NULLFSBLOCK;
|
||||||
fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, *ap->firstblock);
|
fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, *ap->firstblock);
|
||||||
if (nullfb) {
|
if (nullfb) {
|
||||||
@ -3735,7 +3746,7 @@ xfs_bmap_btalloc(
|
|||||||
*/
|
*/
|
||||||
if (!ap->flist->xbf_low && ap->aeof) {
|
if (!ap->flist->xbf_low && ap->aeof) {
|
||||||
if (!ap->offset) {
|
if (!ap->offset) {
|
||||||
args.alignment = mp->m_dalign;
|
args.alignment = stripe_align;
|
||||||
atype = args.type;
|
atype = args.type;
|
||||||
isaligned = 1;
|
isaligned = 1;
|
||||||
/*
|
/*
|
||||||
@ -3760,13 +3771,13 @@ xfs_bmap_btalloc(
|
|||||||
* of minlen+alignment+slop doesn't go up
|
* of minlen+alignment+slop doesn't go up
|
||||||
* between the calls.
|
* between the calls.
|
||||||
*/
|
*/
|
||||||
if (blen > mp->m_dalign && blen <= args.maxlen)
|
if (blen > stripe_align && blen <= args.maxlen)
|
||||||
nextminlen = blen - mp->m_dalign;
|
nextminlen = blen - stripe_align;
|
||||||
else
|
else
|
||||||
nextminlen = args.minlen;
|
nextminlen = args.minlen;
|
||||||
if (nextminlen + mp->m_dalign > args.minlen + 1)
|
if (nextminlen + stripe_align > args.minlen + 1)
|
||||||
args.minalignslop =
|
args.minalignslop =
|
||||||
nextminlen + mp->m_dalign -
|
nextminlen + stripe_align -
|
||||||
args.minlen - 1;
|
args.minlen - 1;
|
||||||
else
|
else
|
||||||
args.minalignslop = 0;
|
args.minalignslop = 0;
|
||||||
@ -3788,7 +3799,7 @@ xfs_bmap_btalloc(
|
|||||||
*/
|
*/
|
||||||
args.type = atype;
|
args.type = atype;
|
||||||
args.fsbno = ap->blkno;
|
args.fsbno = ap->blkno;
|
||||||
args.alignment = mp->m_dalign;
|
args.alignment = stripe_align;
|
||||||
args.minlen = nextminlen;
|
args.minlen = nextminlen;
|
||||||
args.minalignslop = 0;
|
args.minalignslop = 0;
|
||||||
isaligned = 1;
|
isaligned = 1;
|
||||||
|
@ -1187,7 +1187,12 @@ xfs_zero_remaining_bytes(
|
|||||||
XFS_BUF_UNWRITE(bp);
|
XFS_BUF_UNWRITE(bp);
|
||||||
XFS_BUF_READ(bp);
|
XFS_BUF_READ(bp);
|
||||||
XFS_BUF_SET_ADDR(bp, xfs_fsb_to_db(ip, imap.br_startblock));
|
XFS_BUF_SET_ADDR(bp, xfs_fsb_to_db(ip, imap.br_startblock));
|
||||||
xfsbdstrat(mp, bp);
|
|
||||||
|
if (XFS_FORCED_SHUTDOWN(mp)) {
|
||||||
|
error = XFS_ERROR(EIO);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
xfs_buf_iorequest(bp);
|
||||||
error = xfs_buf_iowait(bp);
|
error = xfs_buf_iowait(bp);
|
||||||
if (error) {
|
if (error) {
|
||||||
xfs_buf_ioerror_alert(bp,
|
xfs_buf_ioerror_alert(bp,
|
||||||
@ -1200,7 +1205,12 @@ xfs_zero_remaining_bytes(
|
|||||||
XFS_BUF_UNDONE(bp);
|
XFS_BUF_UNDONE(bp);
|
||||||
XFS_BUF_UNREAD(bp);
|
XFS_BUF_UNREAD(bp);
|
||||||
XFS_BUF_WRITE(bp);
|
XFS_BUF_WRITE(bp);
|
||||||
xfsbdstrat(mp, bp);
|
|
||||||
|
if (XFS_FORCED_SHUTDOWN(mp)) {
|
||||||
|
error = XFS_ERROR(EIO);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
xfs_buf_iorequest(bp);
|
||||||
error = xfs_buf_iowait(bp);
|
error = xfs_buf_iowait(bp);
|
||||||
if (error) {
|
if (error) {
|
||||||
xfs_buf_ioerror_alert(bp,
|
xfs_buf_ioerror_alert(bp,
|
||||||
|
@ -698,7 +698,11 @@ xfs_buf_read_uncached(
|
|||||||
bp->b_flags |= XBF_READ;
|
bp->b_flags |= XBF_READ;
|
||||||
bp->b_ops = ops;
|
bp->b_ops = ops;
|
||||||
|
|
||||||
xfsbdstrat(target->bt_mount, bp);
|
if (XFS_FORCED_SHUTDOWN(target->bt_mount)) {
|
||||||
|
xfs_buf_relse(bp);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
xfs_buf_iorequest(bp);
|
||||||
xfs_buf_iowait(bp);
|
xfs_buf_iowait(bp);
|
||||||
return bp;
|
return bp;
|
||||||
}
|
}
|
||||||
@ -1089,7 +1093,7 @@ xfs_bioerror(
|
|||||||
* This is meant for userdata errors; metadata bufs come with
|
* This is meant for userdata errors; metadata bufs come with
|
||||||
* iodone functions attached, so that we can track down errors.
|
* iodone functions attached, so that we can track down errors.
|
||||||
*/
|
*/
|
||||||
STATIC int
|
int
|
||||||
xfs_bioerror_relse(
|
xfs_bioerror_relse(
|
||||||
struct xfs_buf *bp)
|
struct xfs_buf *bp)
|
||||||
{
|
{
|
||||||
@ -1152,7 +1156,7 @@ xfs_bwrite(
|
|||||||
ASSERT(xfs_buf_islocked(bp));
|
ASSERT(xfs_buf_islocked(bp));
|
||||||
|
|
||||||
bp->b_flags |= XBF_WRITE;
|
bp->b_flags |= XBF_WRITE;
|
||||||
bp->b_flags &= ~(XBF_ASYNC | XBF_READ | _XBF_DELWRI_Q);
|
bp->b_flags &= ~(XBF_ASYNC | XBF_READ | _XBF_DELWRI_Q | XBF_WRITE_FAIL);
|
||||||
|
|
||||||
xfs_bdstrat_cb(bp);
|
xfs_bdstrat_cb(bp);
|
||||||
|
|
||||||
@ -1164,25 +1168,6 @@ xfs_bwrite(
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Wrapper around bdstrat so that we can stop data from going to disk in case
|
|
||||||
* we are shutting down the filesystem. Typically user data goes thru this
|
|
||||||
* path; one of the exceptions is the superblock.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
xfsbdstrat(
|
|
||||||
struct xfs_mount *mp,
|
|
||||||
struct xfs_buf *bp)
|
|
||||||
{
|
|
||||||
if (XFS_FORCED_SHUTDOWN(mp)) {
|
|
||||||
trace_xfs_bdstrat_shut(bp, _RET_IP_);
|
|
||||||
xfs_bioerror_relse(bp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
xfs_buf_iorequest(bp);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC void
|
STATIC void
|
||||||
_xfs_buf_ioend(
|
_xfs_buf_ioend(
|
||||||
xfs_buf_t *bp,
|
xfs_buf_t *bp,
|
||||||
@ -1516,6 +1501,12 @@ xfs_wait_buftarg(
|
|||||||
struct xfs_buf *bp;
|
struct xfs_buf *bp;
|
||||||
bp = list_first_entry(&dispose, struct xfs_buf, b_lru);
|
bp = list_first_entry(&dispose, struct xfs_buf, b_lru);
|
||||||
list_del_init(&bp->b_lru);
|
list_del_init(&bp->b_lru);
|
||||||
|
if (bp->b_flags & XBF_WRITE_FAIL) {
|
||||||
|
xfs_alert(btp->bt_mount,
|
||||||
|
"Corruption Alert: Buffer at block 0x%llx had permanent write failures!\n"
|
||||||
|
"Please run xfs_repair to determine the extent of the problem.",
|
||||||
|
(long long)bp->b_bn);
|
||||||
|
}
|
||||||
xfs_buf_rele(bp);
|
xfs_buf_rele(bp);
|
||||||
}
|
}
|
||||||
if (loop++ != 0)
|
if (loop++ != 0)
|
||||||
@ -1789,7 +1780,7 @@ __xfs_buf_delwri_submit(
|
|||||||
|
|
||||||
blk_start_plug(&plug);
|
blk_start_plug(&plug);
|
||||||
list_for_each_entry_safe(bp, n, io_list, b_list) {
|
list_for_each_entry_safe(bp, n, io_list, b_list) {
|
||||||
bp->b_flags &= ~(_XBF_DELWRI_Q | XBF_ASYNC);
|
bp->b_flags &= ~(_XBF_DELWRI_Q | XBF_ASYNC | XBF_WRITE_FAIL);
|
||||||
bp->b_flags |= XBF_WRITE;
|
bp->b_flags |= XBF_WRITE;
|
||||||
|
|
||||||
if (!wait) {
|
if (!wait) {
|
||||||
|
@ -45,6 +45,7 @@ typedef enum {
|
|||||||
#define XBF_ASYNC (1 << 4) /* initiator will not wait for completion */
|
#define XBF_ASYNC (1 << 4) /* initiator will not wait for completion */
|
||||||
#define XBF_DONE (1 << 5) /* all pages in the buffer uptodate */
|
#define XBF_DONE (1 << 5) /* all pages in the buffer uptodate */
|
||||||
#define XBF_STALE (1 << 6) /* buffer has been staled, do not find it */
|
#define XBF_STALE (1 << 6) /* buffer has been staled, do not find it */
|
||||||
|
#define XBF_WRITE_FAIL (1 << 24)/* async writes have failed on this buffer */
|
||||||
|
|
||||||
/* I/O hints for the BIO layer */
|
/* I/O hints for the BIO layer */
|
||||||
#define XBF_SYNCIO (1 << 10)/* treat this buffer as synchronous I/O */
|
#define XBF_SYNCIO (1 << 10)/* treat this buffer as synchronous I/O */
|
||||||
@ -70,6 +71,7 @@ typedef unsigned int xfs_buf_flags_t;
|
|||||||
{ XBF_ASYNC, "ASYNC" }, \
|
{ XBF_ASYNC, "ASYNC" }, \
|
||||||
{ XBF_DONE, "DONE" }, \
|
{ XBF_DONE, "DONE" }, \
|
||||||
{ XBF_STALE, "STALE" }, \
|
{ XBF_STALE, "STALE" }, \
|
||||||
|
{ XBF_WRITE_FAIL, "WRITE_FAIL" }, \
|
||||||
{ XBF_SYNCIO, "SYNCIO" }, \
|
{ XBF_SYNCIO, "SYNCIO" }, \
|
||||||
{ XBF_FUA, "FUA" }, \
|
{ XBF_FUA, "FUA" }, \
|
||||||
{ XBF_FLUSH, "FLUSH" }, \
|
{ XBF_FLUSH, "FLUSH" }, \
|
||||||
@ -80,6 +82,7 @@ typedef unsigned int xfs_buf_flags_t;
|
|||||||
{ _XBF_DELWRI_Q, "DELWRI_Q" }, \
|
{ _XBF_DELWRI_Q, "DELWRI_Q" }, \
|
||||||
{ _XBF_COMPOUND, "COMPOUND" }
|
{ _XBF_COMPOUND, "COMPOUND" }
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Internal state flags.
|
* Internal state flags.
|
||||||
*/
|
*/
|
||||||
@ -269,9 +272,6 @@ extern void xfs_buf_unlock(xfs_buf_t *);
|
|||||||
|
|
||||||
/* Buffer Read and Write Routines */
|
/* Buffer Read and Write Routines */
|
||||||
extern int xfs_bwrite(struct xfs_buf *bp);
|
extern int xfs_bwrite(struct xfs_buf *bp);
|
||||||
|
|
||||||
extern void xfsbdstrat(struct xfs_mount *, struct xfs_buf *);
|
|
||||||
|
|
||||||
extern void xfs_buf_ioend(xfs_buf_t *, int);
|
extern void xfs_buf_ioend(xfs_buf_t *, int);
|
||||||
extern void xfs_buf_ioerror(xfs_buf_t *, int);
|
extern void xfs_buf_ioerror(xfs_buf_t *, int);
|
||||||
extern void xfs_buf_ioerror_alert(struct xfs_buf *, const char *func);
|
extern void xfs_buf_ioerror_alert(struct xfs_buf *, const char *func);
|
||||||
@ -282,6 +282,8 @@ extern void xfs_buf_iomove(xfs_buf_t *, size_t, size_t, void *,
|
|||||||
#define xfs_buf_zero(bp, off, len) \
|
#define xfs_buf_zero(bp, off, len) \
|
||||||
xfs_buf_iomove((bp), (off), (len), NULL, XBRW_ZERO)
|
xfs_buf_iomove((bp), (off), (len), NULL, XBRW_ZERO)
|
||||||
|
|
||||||
|
extern int xfs_bioerror_relse(struct xfs_buf *);
|
||||||
|
|
||||||
static inline int xfs_buf_geterror(xfs_buf_t *bp)
|
static inline int xfs_buf_geterror(xfs_buf_t *bp)
|
||||||
{
|
{
|
||||||
return bp ? bp->b_error : ENOMEM;
|
return bp ? bp->b_error : ENOMEM;
|
||||||
@ -301,7 +303,8 @@ extern void xfs_buf_terminate(void);
|
|||||||
|
|
||||||
#define XFS_BUF_ZEROFLAGS(bp) \
|
#define XFS_BUF_ZEROFLAGS(bp) \
|
||||||
((bp)->b_flags &= ~(XBF_READ|XBF_WRITE|XBF_ASYNC| \
|
((bp)->b_flags &= ~(XBF_READ|XBF_WRITE|XBF_ASYNC| \
|
||||||
XBF_SYNCIO|XBF_FUA|XBF_FLUSH))
|
XBF_SYNCIO|XBF_FUA|XBF_FLUSH| \
|
||||||
|
XBF_WRITE_FAIL))
|
||||||
|
|
||||||
void xfs_buf_stale(struct xfs_buf *bp);
|
void xfs_buf_stale(struct xfs_buf *bp);
|
||||||
#define XFS_BUF_UNSTALE(bp) ((bp)->b_flags &= ~XBF_STALE)
|
#define XFS_BUF_UNSTALE(bp) ((bp)->b_flags &= ~XBF_STALE)
|
||||||
|
@ -495,6 +495,14 @@ xfs_buf_item_unpin(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Buffer IO error rate limiting. Limit it to no more than 10 messages per 30
|
||||||
|
* seconds so as to not spam logs too much on repeated detection of the same
|
||||||
|
* buffer being bad..
|
||||||
|
*/
|
||||||
|
|
||||||
|
DEFINE_RATELIMIT_STATE(xfs_buf_write_fail_rl_state, 30 * HZ, 10);
|
||||||
|
|
||||||
STATIC uint
|
STATIC uint
|
||||||
xfs_buf_item_push(
|
xfs_buf_item_push(
|
||||||
struct xfs_log_item *lip,
|
struct xfs_log_item *lip,
|
||||||
@ -523,6 +531,14 @@ xfs_buf_item_push(
|
|||||||
|
|
||||||
trace_xfs_buf_item_push(bip);
|
trace_xfs_buf_item_push(bip);
|
||||||
|
|
||||||
|
/* has a previous flush failed due to IO errors? */
|
||||||
|
if ((bp->b_flags & XBF_WRITE_FAIL) &&
|
||||||
|
___ratelimit(&xfs_buf_write_fail_rl_state, "XFS:")) {
|
||||||
|
xfs_warn(bp->b_target->bt_mount,
|
||||||
|
"Detected failing async write on buffer block 0x%llx. Retrying async write.\n",
|
||||||
|
(long long)bp->b_bn);
|
||||||
|
}
|
||||||
|
|
||||||
if (!xfs_buf_delwri_queue(bp, buffer_list))
|
if (!xfs_buf_delwri_queue(bp, buffer_list))
|
||||||
rval = XFS_ITEM_FLUSHING;
|
rval = XFS_ITEM_FLUSHING;
|
||||||
xfs_buf_unlock(bp);
|
xfs_buf_unlock(bp);
|
||||||
@ -1095,8 +1111,9 @@ xfs_buf_iodone_callbacks(
|
|||||||
|
|
||||||
xfs_buf_ioerror(bp, 0); /* errno of 0 unsets the flag */
|
xfs_buf_ioerror(bp, 0); /* errno of 0 unsets the flag */
|
||||||
|
|
||||||
if (!XFS_BUF_ISSTALE(bp)) {
|
if (!(bp->b_flags & (XBF_STALE|XBF_WRITE_FAIL))) {
|
||||||
bp->b_flags |= XBF_WRITE | XBF_ASYNC | XBF_DONE;
|
bp->b_flags |= XBF_WRITE | XBF_ASYNC |
|
||||||
|
XBF_DONE | XBF_WRITE_FAIL;
|
||||||
xfs_buf_iorequest(bp);
|
xfs_buf_iorequest(bp);
|
||||||
} else {
|
} else {
|
||||||
xfs_buf_relse(bp);
|
xfs_buf_relse(bp);
|
||||||
|
@ -193,7 +193,10 @@ xlog_bread_noalign(
|
|||||||
bp->b_io_length = nbblks;
|
bp->b_io_length = nbblks;
|
||||||
bp->b_error = 0;
|
bp->b_error = 0;
|
||||||
|
|
||||||
xfsbdstrat(log->l_mp, bp);
|
if (XFS_FORCED_SHUTDOWN(log->l_mp))
|
||||||
|
return XFS_ERROR(EIO);
|
||||||
|
|
||||||
|
xfs_buf_iorequest(bp);
|
||||||
error = xfs_buf_iowait(bp);
|
error = xfs_buf_iowait(bp);
|
||||||
if (error)
|
if (error)
|
||||||
xfs_buf_ioerror_alert(bp, __func__);
|
xfs_buf_ioerror_alert(bp, __func__);
|
||||||
@ -4408,7 +4411,13 @@ xlog_do_recover(
|
|||||||
XFS_BUF_READ(bp);
|
XFS_BUF_READ(bp);
|
||||||
XFS_BUF_UNASYNC(bp);
|
XFS_BUF_UNASYNC(bp);
|
||||||
bp->b_ops = &xfs_sb_buf_ops;
|
bp->b_ops = &xfs_sb_buf_ops;
|
||||||
xfsbdstrat(log->l_mp, bp);
|
|
||||||
|
if (XFS_FORCED_SHUTDOWN(log->l_mp)) {
|
||||||
|
xfs_buf_relse(bp);
|
||||||
|
return XFS_ERROR(EIO);
|
||||||
|
}
|
||||||
|
|
||||||
|
xfs_buf_iorequest(bp);
|
||||||
error = xfs_buf_iowait(bp);
|
error = xfs_buf_iowait(bp);
|
||||||
if (error) {
|
if (error) {
|
||||||
xfs_buf_ioerror_alert(bp, __func__);
|
xfs_buf_ioerror_alert(bp, __func__);
|
||||||
|
@ -314,7 +314,18 @@ xfs_trans_read_buf_map(
|
|||||||
ASSERT(bp->b_iodone == NULL);
|
ASSERT(bp->b_iodone == NULL);
|
||||||
XFS_BUF_READ(bp);
|
XFS_BUF_READ(bp);
|
||||||
bp->b_ops = ops;
|
bp->b_ops = ops;
|
||||||
xfsbdstrat(tp->t_mountp, bp);
|
|
||||||
|
/*
|
||||||
|
* XXX(hch): clean up the error handling here to be less
|
||||||
|
* of a mess..
|
||||||
|
*/
|
||||||
|
if (XFS_FORCED_SHUTDOWN(mp)) {
|
||||||
|
trace_xfs_bdstrat_shut(bp, _RET_IP_);
|
||||||
|
xfs_bioerror_relse(bp);
|
||||||
|
} else {
|
||||||
|
xfs_buf_iorequest(bp);
|
||||||
|
}
|
||||||
|
|
||||||
error = xfs_buf_iowait(bp);
|
error = xfs_buf_iowait(bp);
|
||||||
if (error) {
|
if (error) {
|
||||||
xfs_buf_ioerror_alert(bp, __func__);
|
xfs_buf_ioerror_alert(bp, __func__);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user