summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_bmap.c92
-rw-r--r--fs/xfs/xfs_bmap.h4
-rw-r--r--fs/xfs/xfs_filestream.c2
3 files changed, 48 insertions, 50 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 68edf99bfad6..608a0013791b 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -2006,9 +2006,9 @@ xfs_bmap_adjacent(
XFS_FSB_TO_AGBNO(mp, x) < mp->m_sb.sb_agblocks)
mp = ap->ip->i_mount;
- nullfb = ap->firstblock == NULLFSBLOCK;
+ nullfb = *ap->firstblock == NULLFSBLOCK;
rt = XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata;
- fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock);
+ fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, *ap->firstblock);
/*
* If allocating at eof, and there's a previous real block,
* try to use its last block as our starting point.
@@ -2380,8 +2380,8 @@ xfs_bmap_btalloc(
ASSERT(!error);
ASSERT(ap->alen);
}
- nullfb = ap->firstblock == NULLFSBLOCK;
- fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock);
+ nullfb = *ap->firstblock == NULLFSBLOCK;
+ fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, *ap->firstblock);
if (nullfb) {
if (ap->userdata && xfs_inode_is_filestream(ap->ip)) {
ag = xfs_filestream_lookup_ag(ap->ip);
@@ -2391,7 +2391,7 @@ xfs_bmap_btalloc(
ap->rval = XFS_INO_TO_FSB(mp, ap->ip->i_ino);
}
} else
- ap->rval = ap->firstblock;
+ ap->rval = *ap->firstblock;
xfs_bmap_adjacent(ap);
@@ -2402,7 +2402,7 @@ xfs_bmap_btalloc(
if (nullfb || XFS_FSB_TO_AGNO(mp, ap->rval) == fb_agno)
;
else
- ap->rval = ap->firstblock;
+ ap->rval = *ap->firstblock;
/*
* Normal allocation, done through xfs_alloc_vextent.
*/
@@ -2413,13 +2413,13 @@ xfs_bmap_btalloc(
/* Trim the allocation back to the maximum an AG can fit. */
args.maxlen = MIN(ap->alen, XFS_ALLOC_AG_MAX_USABLE(mp));
- args.firstblock = ap->firstblock;
+ args.firstblock = *ap->firstblock;
blen = 0;
if (nullfb) {
error = xfs_bmap_btalloc_nullfb(ap, &args, &blen);
if (error)
return error;
- } else if (ap->low) {
+ } else if (ap->flist->xbf_low) {
if (xfs_inode_is_filestream(ap->ip))
args.type = XFS_ALLOCTYPE_FIRST_AG;
else
@@ -2452,7 +2452,7 @@ xfs_bmap_btalloc(
* is >= the stripe unit and the allocation offset is
* at the end of file.
*/
- if (!ap->low && ap->aeof) {
+ if (!ap->flist->xbf_low && ap->aeof) {
if (!ap->off) {
args.alignment = mp->m_dalign;
atype = args.type;
@@ -2540,12 +2540,25 @@ xfs_bmap_btalloc(
args.minleft = 0;
if ((error = xfs_alloc_vextent(&args)))
return error;
- ap->low = 1;
+ ap->flist->xbf_low = 1;
}
if (args.fsbno != NULLFSBLOCK) {
- ap->firstblock = ap->rval = args.fsbno;
+ /*
+ * check the allocation happened at the same or higher AG than
+ * the first block that was allocated.
+ */
+ ASSERT(*ap->firstblock == NULLFSBLOCK ||
+ XFS_FSB_TO_AGNO(mp, *ap->firstblock) ==
+ XFS_FSB_TO_AGNO(mp, args.fsbno) ||
+ (ap->flist->xbf_low &&
+ XFS_FSB_TO_AGNO(mp, *ap->firstblock) <
+ XFS_FSB_TO_AGNO(mp, args.fsbno)));
+
+ ap->rval = args.fsbno;
+ if (*ap->firstblock == NULLFSBLOCK)
+ *ap->firstblock = args.fsbno;
ASSERT(nullfb || fb_agno == args.agno ||
- (ap->low && fb_agno < args.agno));
+ (ap->flist->xbf_low && fb_agno < args.agno));
ap->alen = args.len;
ap->ip->i_d.di_nblocks += args.len;
xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE);
@@ -4596,8 +4609,6 @@ xfs_bmapi_allocate(
struct xfs_bmalloca *bma,
xfs_extnum_t *lastx,
struct xfs_btree_cur **cur,
- xfs_fsblock_t *firstblock,
- struct xfs_bmap_free *flist,
int flags,
int *nallocs,
int *logflags)
@@ -4647,9 +4658,7 @@ xfs_bmapi_allocate(
*/
bma->alen = alen;
bma->off = aoff;
- bma->firstblock = *firstblock;
bma->minlen = (flags & XFS_BMAPI_CONTIG) ? alen : 1;
- bma->low = flist->xbf_low;
bma->aeof = 0;
/*
@@ -4671,24 +4680,18 @@ xfs_bmapi_allocate(
* Copy out result fields.
*/
abno = bma->rval;
- flist->xbf_low = bma->low;
alen = bma->alen;
aoff = bma->off;
- ASSERT(*firstblock == NULLFSBLOCK ||
- XFS_FSB_TO_AGNO(mp, *firstblock) ==
- XFS_FSB_TO_AGNO(mp, bma->firstblock) ||
- (flist->xbf_low &&
- XFS_FSB_TO_AGNO(mp, *firstblock) <
- XFS_FSB_TO_AGNO(mp, bma->firstblock)));
- *firstblock = bma->firstblock;
+ if (bma->flist->xbf_low)
+ bma->minleft = 0;
if (*cur)
- (*cur)->bc_private.b.firstblock = *firstblock;
+ (*cur)->bc_private.b.firstblock = *bma->firstblock;
if (abno == NULLFSBLOCK)
return 0;
if ((ifp->if_flags & XFS_IFBROOT) && !*cur) {
(*cur) = xfs_bmbt_init_cursor(mp, bma->tp, bma->ip, whichfork);
- (*cur)->bc_private.b.firstblock = *firstblock;
- (*cur)->bc_private.b.flist = flist;
+ (*cur)->bc_private.b.firstblock = *bma->firstblock;
+ (*cur)->bc_private.b.flist = bma->flist;
}
/*
* Bump the number of extents we've allocated
@@ -4715,11 +4718,12 @@ xfs_bmapi_allocate(
if (bma->wasdel) {
error = xfs_bmap_add_extent_delay_real(bma->tp, bma->ip, lastx,
- cur, &bma->got, firstblock, flist, logflags);
+ cur, &bma->got, bma->firstblock, bma->flist,
+ logflags);
} else {
error = xfs_bmap_add_extent_hole_real(bma->tp, bma->ip, lastx,
- cur, &bma->got, firstblock, flist, logflags,
- whichfork);
+ cur, &bma->got, bma->firstblock, bma->flist,
+ logflags, whichfork);
}
if (error)
@@ -4746,8 +4750,6 @@ xfs_bmapi_convert_unwritten(
xfs_filblks_t len,
xfs_extnum_t *lastx,
struct xfs_btree_cur **cur,
- xfs_fsblock_t *firstblock,
- struct xfs_bmap_free *flist,
int flags,
int *logflags)
{
@@ -4776,14 +4778,14 @@ xfs_bmapi_convert_unwritten(
if ((ifp->if_flags & XFS_IFBROOT) && !*cur) {
*cur = xfs_bmbt_init_cursor(bma->ip->i_mount, bma->tp,
bma->ip, whichfork);
- (*cur)->bc_private.b.firstblock = *firstblock;
- (*cur)->bc_private.b.flist = flist;
+ (*cur)->bc_private.b.firstblock = *bma->firstblock;
+ (*cur)->bc_private.b.flist = bma->flist;
}
mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN)
? XFS_EXT_NORM : XFS_EXT_UNWRITTEN;
error = xfs_bmap_add_extent_unwritten_real(bma->tp, bma->ip, lastx,
- cur, mval, firstblock, flist, logflags);
+ cur, mval, bma->firstblock, bma->flist, logflags);
if (error)
return error;
@@ -4838,7 +4840,6 @@ xfs_bmapi_write(
int error; /* error return */
xfs_extnum_t lastx; /* last useful extent number */
int logflags; /* flags for transaction logging */
- xfs_extlen_t minleft; /* min blocks left after allocation */
int n; /* current extent index */
int nallocs; /* number of extents alloc'd */
xfs_fileoff_t obno; /* old block number (offset) */
@@ -4900,11 +4901,11 @@ xfs_bmapi_write(
if (*firstblock == NULLFSBLOCK) {
if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE)
- minleft = be16_to_cpu(ifp->if_broot->bb_level) + 1;
+ bma.minleft = be16_to_cpu(ifp->if_broot->bb_level) + 1;
else
- minleft = 1;
+ bma.minleft = 1;
} else {
- minleft = 0;
+ bma.minleft = 0;
}
if (!(ifp->if_flags & XFS_IFEXTENTS)) {
@@ -4923,6 +4924,8 @@ xfs_bmapi_write(
bma.ip = ip;
bma.total = total;
bma.userdata = 0;
+ bma.flist = flist;
+ bma.firstblock = firstblock;
while (bno < end && n < *nmap) {
inhole = eof || bma.got.br_startoff > bno;
@@ -4938,16 +4941,12 @@ xfs_bmapi_write(
bma.wasdel = wasdelay;
bma.alen = len;
bma.off = bno;
- bma.minleft = minleft;
- error = xfs_bmapi_allocate(&bma, &lastx, &cur,
- firstblock, flist, flags, &nallocs,
- &tmp_logflags);
+ error = xfs_bmapi_allocate(&bma, &lastx, &cur, flags,
+ &nallocs, &tmp_logflags);
logflags |= tmp_logflags;
if (error)
goto error0;
- if (flist && flist->xbf_low)
- minleft = 0;
if (bma.rval == NULLFSBLOCK)
break;
}
@@ -4958,8 +4957,7 @@ xfs_bmapi_write(
/* Execute unwritten extent conversion if necessary */
error = xfs_bmapi_convert_unwritten(&bma, mval, len, &lastx,
- &cur, firstblock, flist,
- flags, &tmp_logflags);
+ &cur, flags, &tmp_logflags);
logflags |= tmp_logflags;
if (error == EAGAIN)
continue;
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h
index 6e8f8aee7cdb..6e7c7a50d248 100644
--- a/fs/xfs/xfs_bmap.h
+++ b/fs/xfs/xfs_bmap.h
@@ -109,7 +109,8 @@ static inline void xfs_bmap_init(xfs_bmap_free_t *flp, xfs_fsblock_t *fbp)
* Argument structure for xfs_bmap_alloc.
*/
typedef struct xfs_bmalloca {
- xfs_fsblock_t firstblock; /* i/o first block allocated */
+ xfs_fsblock_t *firstblock; /* i/o first block allocated */
+ struct xfs_bmap_free *flist; /* bmap freelist */
xfs_fsblock_t rval; /* starting block of new extent */
xfs_fileoff_t off; /* offset in file filling in */
struct xfs_trans *tp; /* transaction pointer */
@@ -123,7 +124,6 @@ typedef struct xfs_bmalloca {
char eof; /* set if allocating past last extent */
char wasdel; /* replacing a delayed allocation */
char userdata;/* set if is user data */
- char low; /* low on space, using seq'l ags */
char aeof; /* allocated space at eof */
char conv; /* overwriting unwritten extents */
} xfs_bmalloca_t;
diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c
index 3ff3d9e23ded..137f957b8c7e 100644
--- a/fs/xfs/xfs_filestream.c
+++ b/fs/xfs/xfs_filestream.c
@@ -761,7 +761,7 @@ xfs_filestream_new_ag(
*/
ag = (ag == NULLAGNUMBER) ? 0 : (ag + 1) % mp->m_sb.sb_agcount;
flags = (ap->userdata ? XFS_PICK_USERDATA : 0) |
- (ap->low ? XFS_PICK_LOWSPACE : 0);
+ (ap->flist->xbf_low ? XFS_PICK_LOWSPACE : 0);
err = _xfs_filestream_pick_ag(mp, ag, agp, flags, minlen);
if (err || *agp == NULLAGNUMBER)