|
@@ -2437,6 +2437,7 @@ xfs_bmap_btalloc(
|
|
|
* Normal allocation, done through xfs_alloc_vextent.
|
|
|
*/
|
|
|
tryagain = isaligned = 0;
|
|
|
+ memset(&args, 0, sizeof(args));
|
|
|
args.tp = ap->tp;
|
|
|
args.mp = mp;
|
|
|
args.fsbno = ap->blkno;
|
|
@@ -3082,6 +3083,7 @@ xfs_bmap_extents_to_btree(
|
|
|
* Convert to a btree with two levels, one record in root.
|
|
|
*/
|
|
|
XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE);
|
|
|
+ memset(&args, 0, sizeof(args));
|
|
|
args.tp = tp;
|
|
|
args.mp = mp;
|
|
|
args.firstblock = *firstblock;
|
|
@@ -3237,6 +3239,7 @@ xfs_bmap_local_to_extents(
|
|
|
xfs_buf_t *bp; /* buffer for extent block */
|
|
|
xfs_bmbt_rec_host_t *ep;/* extent record pointer */
|
|
|
|
|
|
+ memset(&args, 0, sizeof(args));
|
|
|
args.tp = tp;
|
|
|
args.mp = ip->i_mount;
|
|
|
args.firstblock = *firstblock;
|
|
@@ -4616,12 +4619,11 @@ xfs_bmapi_delay(
|
|
|
|
|
|
|
|
|
STATIC int
|
|
|
-xfs_bmapi_allocate(
|
|
|
- struct xfs_bmalloca *bma,
|
|
|
- int flags)
|
|
|
+__xfs_bmapi_allocate(
|
|
|
+ struct xfs_bmalloca *bma)
|
|
|
{
|
|
|
struct xfs_mount *mp = bma->ip->i_mount;
|
|
|
- int whichfork = (flags & XFS_BMAPI_ATTRFORK) ?
|
|
|
+ int whichfork = (bma->flags & XFS_BMAPI_ATTRFORK) ?
|
|
|
XFS_ATTR_FORK : XFS_DATA_FORK;
|
|
|
struct xfs_ifork *ifp = XFS_IFORK_PTR(bma->ip, whichfork);
|
|
|
int tmp_logflags = 0;
|
|
@@ -4654,24 +4656,27 @@ xfs_bmapi_allocate(
|
|
|
* Indicate if this is the first user data in the file, or just any
|
|
|
* user data.
|
|
|
*/
|
|
|
- if (!(flags & XFS_BMAPI_METADATA)) {
|
|
|
+ if (!(bma->flags & XFS_BMAPI_METADATA)) {
|
|
|
bma->userdata = (bma->offset == 0) ?
|
|
|
XFS_ALLOC_INITIAL_USER_DATA : XFS_ALLOC_USERDATA;
|
|
|
}
|
|
|
|
|
|
- bma->minlen = (flags & XFS_BMAPI_CONTIG) ? bma->length : 1;
|
|
|
+ bma->minlen = (bma->flags & XFS_BMAPI_CONTIG) ? bma->length : 1;
|
|
|
|
|
|
/*
|
|
|
* Only want to do the alignment at the eof if it is userdata and
|
|
|
* allocation length is larger than a stripe unit.
|
|
|
*/
|
|
|
if (mp->m_dalign && bma->length >= mp->m_dalign &&
|
|
|
- !(flags & XFS_BMAPI_METADATA) && whichfork == XFS_DATA_FORK) {
|
|
|
+ !(bma->flags & XFS_BMAPI_METADATA) && whichfork == XFS_DATA_FORK) {
|
|
|
error = xfs_bmap_isaeof(bma, whichfork);
|
|
|
if (error)
|
|
|
return error;
|
|
|
}
|
|
|
|
|
|
+ if (bma->flags & XFS_BMAPI_STACK_SWITCH)
|
|
|
+ bma->stack_switch = 1;
|
|
|
+
|
|
|
error = xfs_bmap_alloc(bma);
|
|
|
if (error)
|
|
|
return error;
|
|
@@ -4706,7 +4711,7 @@ xfs_bmapi_allocate(
|
|
|
* A wasdelay extent has been initialized, so shouldn't be flagged
|
|
|
* as unwritten.
|
|
|
*/
|
|
|
- if (!bma->wasdel && (flags & XFS_BMAPI_PREALLOC) &&
|
|
|
+ if (!bma->wasdel && (bma->flags & XFS_BMAPI_PREALLOC) &&
|
|
|
xfs_sb_version_hasextflgbit(&mp->m_sb))
|
|
|
bma->got.br_state = XFS_EXT_UNWRITTEN;
|
|
|
|
|
@@ -4734,6 +4739,45 @@ xfs_bmapi_allocate(
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static void
|
|
|
+xfs_bmapi_allocate_worker(
|
|
|
+ struct work_struct *work)
|
|
|
+{
|
|
|
+ struct xfs_bmalloca *args = container_of(work,
|
|
|
+ struct xfs_bmalloca, work);
|
|
|
+ unsigned long pflags;
|
|
|
+
|
|
|
+ /* we are in a transaction context here */
|
|
|
+ current_set_flags_nested(&pflags, PF_FSTRANS);
|
|
|
+
|
|
|
+ args->result = __xfs_bmapi_allocate(args);
|
|
|
+ complete(args->done);
|
|
|
+
|
|
|
+ current_restore_flags_nested(&pflags, PF_FSTRANS);
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Some allocation requests often come in with little stack to work on. Push
|
|
|
+ * them off to a worker thread so there is lots of stack to use. Otherwise just
|
|
|
+ * call directly to avoid the context switch overhead here.
|
|
|
+ */
|
|
|
+int
|
|
|
+xfs_bmapi_allocate(
|
|
|
+ struct xfs_bmalloca *args)
|
|
|
+{
|
|
|
+ DECLARE_COMPLETION_ONSTACK(done);
|
|
|
+
|
|
|
+ if (!args->stack_switch)
|
|
|
+ return __xfs_bmapi_allocate(args);
|
|
|
+
|
|
|
+
|
|
|
+ args->done = &done;
|
|
|
+ INIT_WORK_ONSTACK(&args->work, xfs_bmapi_allocate_worker);
|
|
|
+ queue_work(xfs_alloc_wq, &args->work);
|
|
|
+ wait_for_completion(&done);
|
|
|
+ return args->result;
|
|
|
+}
|
|
|
+
|
|
|
STATIC int
|
|
|
xfs_bmapi_convert_unwritten(
|
|
|
struct xfs_bmalloca *bma,
|
|
@@ -4919,6 +4963,7 @@ xfs_bmapi_write(
|
|
|
bma.conv = !!(flags & XFS_BMAPI_CONVERT);
|
|
|
bma.wasdel = wasdelay;
|
|
|
bma.offset = bno;
|
|
|
+ bma.flags = flags;
|
|
|
|
|
|
/*
|
|
|
* There's a 32/64 bit type mismatch between the
|
|
@@ -4934,7 +4979,7 @@ xfs_bmapi_write(
|
|
|
|
|
|
ASSERT(len > 0);
|
|
|
ASSERT(bma.length > 0);
|
|
|
- error = xfs_bmapi_allocate(&bma, flags);
|
|
|
+ error = xfs_bmapi_allocate(&bma);
|
|
|
if (error)
|
|
|
goto error0;
|
|
|
if (bma.blkno == NULLFSBLOCK)
|