forked from luck/tmp_suning_uos_patched
Contained in this update:
- Fix free space request handling when low on disk space - Remove redundant log failure error messages - Free truncate dirty pages instead of letting them build up forever -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABCgAGBQJYdnh5AAoJEPh/dxk0SrTrI5sP/2FYAxrj3Iw684e92PWeIe1c pZir+0LEmlXgly4wprli7/BO6WZjESuMF3huBZZxtYLx3UUvGRavHup620z3Xa2e YRdSiBnvchOe3F0UfFO9wT15vEOzwWS61FfX/g35t4mD6ItY0XISesTx4+XA3Cqi 8zf7OAjXI5WQietthwc9zmfhpyWgyw8CkeXVtqd5whNJN/6E80wh5IE6D6cJ1xkX 2qNicrrruTUACPyJxrTrR/0kkoxDoYgBapy3kqV0R1uK+ttNrGlGjfdapKs0tqMb ezksj0sy/rx+HjfGEHx52mTiYRRTHEsGt/yMa1pT8o0p2wvR0nxnvzkvV8DeMoX3 0wYRxATsv/t8Oog+ug6khB/FtppSGJML+XxG3bV9itgCkAIFAbb7vZRrThnzVqOr ChbQvBhchY4lYA1pef862QHLRraJF84HuY/ypyE6DX+nQWkGjDfEeHFPcm6eVSXG xEplK8wjs09pSklH/OQD+GsO4eedBHc4hdzDuBTjCmt867/Lk8Uw4RIjGMYjbBx2 ovU3pTHfdlO6/qJmfSWnBAAZjKAjna/p47ZfDLzio23hb1hK68Qe/z8+tPnAzkHW rowA6KfBi13tX6Njds/lceiYMrnMRPqNBA+Og1wCyljP2Q4shbADa6czrFDzPn6P xZbfhKK2CTbYSvxi5S3G =8bsr -----END PGP SIGNATURE----- Merge tag 'xfs-for-linus-4.10-rc4-1' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux Pull xfs fixes from Darrick Wong: "As promised last week, here's some stability fixes from Christoph and Jan Kara: - fix free space request handling when low on disk space - remove redundant log failure error messages - free truncated dirty pages instead of letting them build up forever" * tag 'xfs-for-linus-4.10-rc4-1' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: xfs: Timely free truncated dirty pages xfs: don't print warnings when xfs_log_force fails xfs: don't rely on ->total in xfs_alloc_space_available xfs: adjust allocation length in xfs_alloc_space_available xfs: fix bogus minleft manipulations xfs: bump up reserved blocks in xfs_alloc_set_aside
This commit is contained in:
commit
e28ac1fc31
@ -95,10 +95,7 @@ unsigned int
|
||||
xfs_alloc_set_aside(
|
||||
struct xfs_mount *mp)
|
||||
{
|
||||
unsigned int blocks;
|
||||
|
||||
blocks = 4 + (mp->m_sb.sb_agcount * XFS_ALLOC_AGFL_RESERVE);
|
||||
return blocks;
|
||||
return mp->m_sb.sb_agcount * (XFS_ALLOC_AGFL_RESERVE + 4);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -365,35 +362,11 @@ xfs_alloc_fix_len(
|
||||
return;
|
||||
ASSERT(rlen >= args->minlen && rlen <= args->maxlen);
|
||||
ASSERT(rlen % args->prod == args->mod);
|
||||
ASSERT(args->pag->pagf_freeblks + args->pag->pagf_flcount >=
|
||||
rlen + args->minleft);
|
||||
args->len = rlen;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fix up length if there is too little space left in the a.g.
|
||||
* Return 1 if ok, 0 if too little, should give up.
|
||||
*/
|
||||
STATIC int
|
||||
xfs_alloc_fix_minleft(
|
||||
xfs_alloc_arg_t *args) /* allocation argument structure */
|
||||
{
|
||||
xfs_agf_t *agf; /* a.g. freelist header */
|
||||
int diff; /* free space difference */
|
||||
|
||||
if (args->minleft == 0)
|
||||
return 1;
|
||||
agf = XFS_BUF_TO_AGF(args->agbp);
|
||||
diff = be32_to_cpu(agf->agf_freeblks)
|
||||
- args->len - args->minleft;
|
||||
if (diff >= 0)
|
||||
return 1;
|
||||
args->len += diff; /* shrink the allocated space */
|
||||
/* casts to (int) catch length underflows */
|
||||
if ((int)args->len >= (int)args->minlen)
|
||||
return 1;
|
||||
args->agbno = NULLAGBLOCK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the two btrees, logically removing from freespace the extent
|
||||
* starting at rbno, rlen blocks. The extent is contained within the
|
||||
@ -689,8 +662,6 @@ xfs_alloc_ag_vextent(
|
||||
xfs_alloc_arg_t *args) /* argument structure for allocation */
|
||||
{
|
||||
int error=0;
|
||||
xfs_extlen_t reservation;
|
||||
xfs_extlen_t oldmax;
|
||||
|
||||
ASSERT(args->minlen > 0);
|
||||
ASSERT(args->maxlen > 0);
|
||||
@ -698,20 +669,6 @@ xfs_alloc_ag_vextent(
|
||||
ASSERT(args->mod < args->prod);
|
||||
ASSERT(args->alignment > 0);
|
||||
|
||||
/*
|
||||
* Clamp maxlen to the amount of free space minus any reservations
|
||||
* that have been made.
|
||||
*/
|
||||
oldmax = args->maxlen;
|
||||
reservation = xfs_ag_resv_needed(args->pag, args->resv);
|
||||
if (args->maxlen > args->pag->pagf_freeblks - reservation)
|
||||
args->maxlen = args->pag->pagf_freeblks - reservation;
|
||||
if (args->maxlen == 0) {
|
||||
args->agbno = NULLAGBLOCK;
|
||||
args->maxlen = oldmax;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Branch to correct routine based on the type.
|
||||
*/
|
||||
@ -731,8 +688,6 @@ xfs_alloc_ag_vextent(
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
args->maxlen = oldmax;
|
||||
|
||||
if (error || args->agbno == NULLAGBLOCK)
|
||||
return error;
|
||||
|
||||
@ -841,9 +796,6 @@ xfs_alloc_ag_vextent_exact(
|
||||
args->len = XFS_AGBLOCK_MIN(tend, args->agbno + args->maxlen)
|
||||
- args->agbno;
|
||||
xfs_alloc_fix_len(args);
|
||||
if (!xfs_alloc_fix_minleft(args))
|
||||
goto not_found;
|
||||
|
||||
ASSERT(args->agbno + args->len <= tend);
|
||||
|
||||
/*
|
||||
@ -1149,12 +1101,7 @@ xfs_alloc_ag_vextent_near(
|
||||
XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
|
||||
ASSERT(ltbno + ltlen <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length));
|
||||
args->len = blen;
|
||||
if (!xfs_alloc_fix_minleft(args)) {
|
||||
xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
|
||||
trace_xfs_alloc_near_nominleft(args);
|
||||
return 0;
|
||||
}
|
||||
blen = args->len;
|
||||
|
||||
/*
|
||||
* We are allocating starting at bnew for blen blocks.
|
||||
*/
|
||||
@ -1346,12 +1293,6 @@ xfs_alloc_ag_vextent_near(
|
||||
*/
|
||||
args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen);
|
||||
xfs_alloc_fix_len(args);
|
||||
if (!xfs_alloc_fix_minleft(args)) {
|
||||
trace_xfs_alloc_near_nominleft(args);
|
||||
xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR);
|
||||
xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
|
||||
return 0;
|
||||
}
|
||||
rlen = args->len;
|
||||
(void)xfs_alloc_compute_diff(args->agbno, rlen, args->alignment,
|
||||
args->datatype, ltbnoa, ltlena, <new);
|
||||
@ -1553,8 +1494,6 @@ xfs_alloc_ag_vextent_size(
|
||||
}
|
||||
xfs_alloc_fix_len(args);
|
||||
|
||||
if (!xfs_alloc_fix_minleft(args))
|
||||
goto out_nominleft;
|
||||
rlen = args->len;
|
||||
XFS_WANT_CORRUPTED_GOTO(args->mp, rlen <= flen, error0);
|
||||
/*
|
||||
@ -2056,7 +1995,7 @@ xfs_alloc_space_available(
|
||||
int flags)
|
||||
{
|
||||
struct xfs_perag *pag = args->pag;
|
||||
xfs_extlen_t longest;
|
||||
xfs_extlen_t alloc_len, longest;
|
||||
xfs_extlen_t reservation; /* blocks that are still reserved */
|
||||
int available;
|
||||
|
||||
@ -2066,17 +2005,28 @@ xfs_alloc_space_available(
|
||||
reservation = xfs_ag_resv_needed(pag, args->resv);
|
||||
|
||||
/* do we have enough contiguous free space for the allocation? */
|
||||
alloc_len = args->minlen + (args->alignment - 1) + args->minalignslop;
|
||||
longest = xfs_alloc_longest_free_extent(args->mp, pag, min_free,
|
||||
reservation);
|
||||
if ((args->minlen + args->alignment + args->minalignslop - 1) > longest)
|
||||
if (longest < alloc_len)
|
||||
return false;
|
||||
|
||||
/* do we have enough free space remaining for the allocation? */
|
||||
available = (int)(pag->pagf_freeblks + pag->pagf_flcount -
|
||||
reservation - min_free - args->total);
|
||||
if (available < (int)args->minleft || available <= 0)
|
||||
reservation - min_free - args->minleft);
|
||||
if (available < (int)max(args->total, alloc_len))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Clamp maxlen to the amount of free space available for the actual
|
||||
* extent allocation.
|
||||
*/
|
||||
if (available < (int)args->maxlen && !(flags & XFS_ALLOC_FLAG_CHECK)) {
|
||||
args->maxlen = available;
|
||||
ASSERT(args->maxlen > 0);
|
||||
ASSERT(args->maxlen >= args->minlen);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2122,7 +2072,8 @@ xfs_alloc_fix_freelist(
|
||||
}
|
||||
|
||||
need = xfs_alloc_min_freelist(mp, pag);
|
||||
if (!xfs_alloc_space_available(args, need, flags))
|
||||
if (!xfs_alloc_space_available(args, need, flags |
|
||||
XFS_ALLOC_FLAG_CHECK))
|
||||
goto out_agbp_relse;
|
||||
|
||||
/*
|
||||
@ -2638,12 +2589,10 @@ xfs_alloc_vextent(
|
||||
xfs_agblock_t agsize; /* allocation group size */
|
||||
int error;
|
||||
int flags; /* XFS_ALLOC_FLAG_... locking flags */
|
||||
xfs_extlen_t minleft;/* minimum left value, temp copy */
|
||||
xfs_mount_t *mp; /* mount structure pointer */
|
||||
xfs_agnumber_t sagno; /* starting allocation group number */
|
||||
xfs_alloctype_t type; /* input allocation type */
|
||||
int bump_rotor = 0;
|
||||
int no_min = 0;
|
||||
xfs_agnumber_t rotorstep = xfs_rotorstep; /* inode32 agf stepper */
|
||||
|
||||
mp = args->mp;
|
||||
@ -2672,7 +2621,6 @@ xfs_alloc_vextent(
|
||||
trace_xfs_alloc_vextent_badargs(args);
|
||||
return 0;
|
||||
}
|
||||
minleft = args->minleft;
|
||||
|
||||
switch (type) {
|
||||
case XFS_ALLOCTYPE_THIS_AG:
|
||||
@ -2683,9 +2631,7 @@ xfs_alloc_vextent(
|
||||
*/
|
||||
args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno);
|
||||
args->pag = xfs_perag_get(mp, args->agno);
|
||||
args->minleft = 0;
|
||||
error = xfs_alloc_fix_freelist(args, 0);
|
||||
args->minleft = minleft;
|
||||
if (error) {
|
||||
trace_xfs_alloc_vextent_nofix(args);
|
||||
goto error0;
|
||||
@ -2750,9 +2696,7 @@ xfs_alloc_vextent(
|
||||
*/
|
||||
for (;;) {
|
||||
args->pag = xfs_perag_get(mp, args->agno);
|
||||
if (no_min) args->minleft = 0;
|
||||
error = xfs_alloc_fix_freelist(args, flags);
|
||||
args->minleft = minleft;
|
||||
if (error) {
|
||||
trace_xfs_alloc_vextent_nofix(args);
|
||||
goto error0;
|
||||
@ -2792,20 +2736,17 @@ xfs_alloc_vextent(
|
||||
* or switch to non-trylock mode.
|
||||
*/
|
||||
if (args->agno == sagno) {
|
||||
if (no_min == 1) {
|
||||
if (flags == 0) {
|
||||
args->agbno = NULLAGBLOCK;
|
||||
trace_xfs_alloc_vextent_allfailed(args);
|
||||
break;
|
||||
}
|
||||
if (flags == 0) {
|
||||
no_min = 1;
|
||||
} else {
|
||||
flags = 0;
|
||||
if (type == XFS_ALLOCTYPE_START_BNO) {
|
||||
args->agbno = XFS_FSB_TO_AGBNO(mp,
|
||||
args->fsbno);
|
||||
args->type = XFS_ALLOCTYPE_NEAR_BNO;
|
||||
}
|
||||
|
||||
flags = 0;
|
||||
if (type == XFS_ALLOCTYPE_START_BNO) {
|
||||
args->agbno = XFS_FSB_TO_AGBNO(mp,
|
||||
args->fsbno);
|
||||
args->type = XFS_ALLOCTYPE_NEAR_BNO;
|
||||
}
|
||||
}
|
||||
xfs_perag_put(args->pag);
|
||||
|
@ -56,7 +56,7 @@ typedef unsigned int xfs_alloctype_t;
|
||||
#define XFS_ALLOC_FLAG_FREEING 0x00000002 /* indicate caller is freeing extents*/
|
||||
#define XFS_ALLOC_FLAG_NORMAP 0x00000004 /* don't modify the rmapbt */
|
||||
#define XFS_ALLOC_FLAG_NOSHRINK 0x00000008 /* don't shrink the freelist */
|
||||
|
||||
#define XFS_ALLOC_FLAG_CHECK 0x00000010 /* test only, don't modify args */
|
||||
|
||||
/*
|
||||
* Argument structure for xfs_alloc routines.
|
||||
|
@ -3812,7 +3812,6 @@ xfs_bmap_btalloc(
|
||||
args.fsbno = 0;
|
||||
args.type = XFS_ALLOCTYPE_FIRST_AG;
|
||||
args.total = ap->minlen;
|
||||
args.minleft = 0;
|
||||
if ((error = xfs_alloc_vextent(&args)))
|
||||
return error;
|
||||
ap->dfops->dop_low = true;
|
||||
@ -4344,8 +4343,6 @@ xfs_bmapi_allocate(
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (bma->dfops->dop_low)
|
||||
bma->minleft = 0;
|
||||
if (bma->cur)
|
||||
bma->cur->bc_private.b.firstblock = *bma->firstblock;
|
||||
if (bma->blkno == NULLFSBLOCK)
|
||||
|
@ -502,12 +502,11 @@ xfs_bmbt_alloc_block(
|
||||
if (args.fsbno == NULLFSBLOCK && args.minleft) {
|
||||
/*
|
||||
* Could not find an AG with enough free space to satisfy
|
||||
* a full btree split. Try again without minleft and if
|
||||
* a full btree split. Try again and if
|
||||
* successful activate the lowspace algorithm.
|
||||
*/
|
||||
args.fsbno = 0;
|
||||
args.type = XFS_ALLOCTYPE_FIRST_AG;
|
||||
args.minleft = 0;
|
||||
error = xfs_alloc_vextent(&args);
|
||||
if (error)
|
||||
goto error0;
|
||||
|
@ -1152,19 +1152,22 @@ xfs_vm_releasepage(
|
||||
* block_invalidatepage() can send pages that are still marked dirty
|
||||
* but otherwise have invalidated buffers.
|
||||
*
|
||||
* We've historically freed buffers on the latter. Instead, quietly
|
||||
* filter out all dirty pages to avoid spurious buffer state warnings.
|
||||
* This can likely be removed once shrink_active_list() is fixed.
|
||||
* We want to release the latter to avoid unnecessary buildup of the
|
||||
* LRU, skip the former and warn if we've left any lingering
|
||||
* delalloc/unwritten buffers on clean pages. Skip pages with delalloc
|
||||
* or unwritten buffers and warn if the page is not dirty. Otherwise
|
||||
* try to release the buffers.
|
||||
*/
|
||||
if (PageDirty(page))
|
||||
return 0;
|
||||
|
||||
xfs_count_page_state(page, &delalloc, &unwritten);
|
||||
|
||||
if (WARN_ON_ONCE(delalloc))
|
||||
if (delalloc) {
|
||||
WARN_ON_ONCE(!PageDirty(page));
|
||||
return 0;
|
||||
if (WARN_ON_ONCE(unwritten))
|
||||
}
|
||||
if (unwritten) {
|
||||
WARN_ON_ONCE(!PageDirty(page));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return try_to_free_buffers(page);
|
||||
}
|
||||
|
@ -3317,12 +3317,8 @@ xfs_log_force(
|
||||
xfs_mount_t *mp,
|
||||
uint flags)
|
||||
{
|
||||
int error;
|
||||
|
||||
trace_xfs_log_force(mp, 0, _RET_IP_);
|
||||
error = _xfs_log_force(mp, flags, NULL);
|
||||
if (error)
|
||||
xfs_warn(mp, "%s: error %d returned.", __func__, error);
|
||||
_xfs_log_force(mp, flags, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3466,12 +3462,8 @@ xfs_log_force_lsn(
|
||||
xfs_lsn_t lsn,
|
||||
uint flags)
|
||||
{
|
||||
int error;
|
||||
|
||||
trace_xfs_log_force(mp, lsn, _RET_IP_);
|
||||
error = _xfs_log_force_lsn(mp, lsn, flags, NULL);
|
||||
if (error)
|
||||
xfs_warn(mp, "%s: error %d returned.", __func__, error);
|
||||
_xfs_log_force_lsn(mp, lsn, flags, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user