Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a6ddeee3 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'xfs-for-linus-v3.13-rc5' of git://oss.sgi.com/xfs/xfs

Pull xfs bugfixes from Ben Myers:
 "This contains fixes for some asserts
   related to project quotas, a memory leak, a hang when disabling group or
   project quotas before disabling user quotas, Dave's email address, several
   fixes for the alignment of file allocation to stripe unit/width geometry, a
   fix for an assertion with xfs_zero_remaining_bytes, and the behavior of
   metadata writeback in the face of IO errors.

   Details:
   - fix memory leak in xfs_dir2_node_removename
   - fix quota assertion in xfs_setattr_size
   - fix quota assertions in xfs_qm_vop_create_dqattach
   - fix for hang when disabling group and project quotas before
     disabling user quotas
   - fix Dave Chinner's email address in MAINTAINERS
   - fix for file allocation alignment
   - fix for assertion in xfs_buf_stale by removing xfsbdstrat
   - fix for alignment with swalloc mount option
   - fix for "retry forever" semantics on IO errors"

* tag 'xfs-for-linus-v3.13-rc5' of git://oss.sgi.com/xfs/xfs:
  xfs: abort metadata writeback on permanent errors
  xfs: swalloc doesn't align allocations properly
  xfs: remove xfsbdstrat error
  xfs: align initial file allocations correctly
  MAINTAINERS: fix incorrect mail address of XFS maintainer
  xfs: fix infinite loop by detaching the group/project hints from user dquot
  xfs: fix assertion failure at xfs_setattr_nonsize
  xfs: fix false assertion at xfs_qm_vop_create_dqattach
  xfs: fix memory leak in xfs_dir2_node_removename
parents 40b64acd ac8809f9
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -9588,7 +9588,7 @@ F: drivers/xen/*swiotlb*

XFS FILESYSTEM
P:	Silicon Graphics Inc
M:	Dave Chinner <dchinner@fromorbit.com>
M:	Dave Chinner <david@fromorbit.com>
M:	Ben Myers <bpm@sgi.com>
M:	xfs@oss.sgi.com
L:	xfs@oss.sgi.com
+24 −8
Original line number Diff line number Diff line
@@ -1635,7 +1635,7 @@ xfs_bmap_last_extent(
 * blocks at the end of the file which do not start at the previous data block,
 * we will try to align the new blocks at stripe unit boundaries.
 *
 * Returns 0 in bma->aeof if the file (fork) is empty as any new write will be
 * Returns 1 in bma->aeof if the file (fork) is empty as any new write will be
 * at, or past the EOF.
 */
STATIC int
@@ -1650,9 +1650,14 @@ xfs_bmap_isaeof(
	bma->aeof = 0;
	error = xfs_bmap_last_extent(NULL, bma->ip, whichfork, &rec,
				     &is_empty);
	if (error || is_empty)
	if (error)
		return error;

	if (is_empty) {
		bma->aeof = 1;
		return 0;
	}

	/*
	 * Check if we are allocation or past the last extent, or at least into
	 * the last delayed allocated extent.
@@ -3643,10 +3648,19 @@ xfs_bmap_btalloc(
	int		isaligned;
	int		tryagain;
	int		error;
	int		stripe_align;

	ASSERT(ap->length);

	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;
	if (unlikely(align)) {
		error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev,
@@ -3655,6 +3669,8 @@ xfs_bmap_btalloc(
		ASSERT(!error);
		ASSERT(ap->length);
	}


	nullfb = *ap->firstblock == NULLFSBLOCK;
	fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, *ap->firstblock);
	if (nullfb) {
@@ -3730,7 +3746,7 @@ xfs_bmap_btalloc(
	 */
	if (!ap->flist->xbf_low && ap->aeof) {
		if (!ap->offset) {
			args.alignment = mp->m_dalign;
			args.alignment = stripe_align;
			atype = args.type;
			isaligned = 1;
			/*
@@ -3755,13 +3771,13 @@ xfs_bmap_btalloc(
			 * of minlen+alignment+slop doesn't go up
			 * between the calls.
			 */
			if (blen > mp->m_dalign && blen <= args.maxlen)
				nextminlen = blen - mp->m_dalign;
			if (blen > stripe_align && blen <= args.maxlen)
				nextminlen = blen - stripe_align;
			else
				nextminlen = args.minlen;
			if (nextminlen + mp->m_dalign > args.minlen + 1)
			if (nextminlen + stripe_align > args.minlen + 1)
				args.minalignslop =
					nextminlen + mp->m_dalign -
					nextminlen + stripe_align -
					args.minlen - 1;
			else
				args.minalignslop = 0;
@@ -3783,7 +3799,7 @@ xfs_bmap_btalloc(
		 */
		args.type = atype;
		args.fsbno = ap->blkno;
		args.alignment = mp->m_dalign;
		args.alignment = stripe_align;
		args.minlen = nextminlen;
		args.minalignslop = 0;
		isaligned = 1;
+12 −2
Original line number Diff line number Diff line
@@ -1187,7 +1187,12 @@ xfs_zero_remaining_bytes(
		XFS_BUF_UNWRITE(bp);
		XFS_BUF_READ(bp);
		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);
		if (error) {
			xfs_buf_ioerror_alert(bp,
@@ -1200,7 +1205,12 @@ xfs_zero_remaining_bytes(
		XFS_BUF_UNDONE(bp);
		XFS_BUF_UNREAD(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);
		if (error) {
			xfs_buf_ioerror_alert(bp,
+14 −23
Original line number Diff line number Diff line
@@ -698,7 +698,11 @@ xfs_buf_read_uncached(
	bp->b_flags |= XBF_READ;
	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);
	return bp;
}
@@ -1089,7 +1093,7 @@ xfs_bioerror(
 * This is meant for userdata errors; metadata bufs come with
 * iodone functions attached, so that we can track down errors.
 */
STATIC int
int
xfs_bioerror_relse(
	struct xfs_buf	*bp)
{
@@ -1152,7 +1156,7 @@ xfs_bwrite(
	ASSERT(xfs_buf_islocked(bp));

	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);

@@ -1164,25 +1168,6 @@ xfs_bwrite(
	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
_xfs_buf_ioend(
	xfs_buf_t		*bp,
@@ -1516,6 +1501,12 @@ xfs_wait_buftarg(
			struct xfs_buf *bp;
			bp = list_first_entry(&dispose, struct xfs_buf, 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);
		}
		if (loop++ != 0)
@@ -1799,7 +1790,7 @@ __xfs_buf_delwri_submit(

	blk_start_plug(&plug);
	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;

		if (!wait) {
+7 −4
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ typedef enum {
#define XBF_ASYNC	 (1 << 4) /* initiator will not wait for completion */
#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_WRITE_FAIL	 (1 << 24)/* async writes have failed on this buffer */

/* I/O hints for the BIO layer */
#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_DONE,		"DONE" }, \
	{ XBF_STALE,		"STALE" }, \
	{ XBF_WRITE_FAIL,	"WRITE_FAIL" }, \
	{ XBF_SYNCIO,		"SYNCIO" }, \
	{ XBF_FUA,		"FUA" }, \
	{ XBF_FLUSH,		"FLUSH" }, \
@@ -80,6 +82,7 @@ typedef unsigned int xfs_buf_flags_t;
	{ _XBF_DELWRI_Q,	"DELWRI_Q" }, \
	{ _XBF_COMPOUND,	"COMPOUND" }


/*
 * Internal state flags.
 */
@@ -269,9 +272,6 @@ extern void xfs_buf_unlock(xfs_buf_t *);

/* Buffer Read and Write Routines */
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_ioerror(xfs_buf_t *, int);
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) \
	    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)
{
	return bp ? bp->b_error : ENOMEM;
@@ -301,7 +303,8 @@ extern void xfs_buf_terminate(void);

#define XFS_BUF_ZEROFLAGS(bp) \
	((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);
#define XFS_BUF_UNSTALE(bp)	((bp)->b_flags &= ~XBF_STALE)
Loading