Commit 3cabb836 authored by Dave Chinner's avatar Dave Chinner

Merge branch 'xfs-misc-fixes-for-4.1' into for-next

parents 83d5f018 444a7022
...@@ -228,30 +228,19 @@ default behaviour. ...@@ -228,30 +228,19 @@ default behaviour.
Deprecated Mount Options Deprecated Mount Options
======================== ========================
delaylog/nodelaylog None at present.
Delayed logging is the only logging method that XFS supports
now, so these mount options are now ignored.
Due for removal in 3.12.
ihashsize=value
In memory inode hashes have been removed, so this option has
no function as of August 2007. Option is deprecated.
Due for removal in 3.12.
irixsgid
This behaviour is now controlled by a sysctl, so the mount
option is ignored.
Due for removal in 3.12. Removed Mount Options
=====================
osyncisdsync Name Removed
osyncisosync ---- -------
O_SYNC and O_DSYNC are fully supported, so there is no need delaylog/nodelaylog v3.20
for these options any more. ihashsize v3.20
irixsgid v3.20
osyncisdsync/osyncisosync v3.20
Due for removal in 3.12.
sysctls sysctls
======= =======
......
This diff is collapsed.
This diff is collapsed.
...@@ -168,7 +168,7 @@ xfs_btree_check_lptr( ...@@ -168,7 +168,7 @@ xfs_btree_check_lptr(
xfs_fsblock_t bno, /* btree block disk address */ xfs_fsblock_t bno, /* btree block disk address */
int level) /* btree block level */ int level) /* btree block level */
{ {
XFS_WANT_CORRUPTED_RETURN( XFS_WANT_CORRUPTED_RETURN(cur->bc_mp,
level > 0 && level > 0 &&
bno != NULLFSBLOCK && bno != NULLFSBLOCK &&
XFS_FSB_SANITY_CHECK(cur->bc_mp, bno)); XFS_FSB_SANITY_CHECK(cur->bc_mp, bno));
...@@ -187,7 +187,7 @@ xfs_btree_check_sptr( ...@@ -187,7 +187,7 @@ xfs_btree_check_sptr(
{ {
xfs_agblock_t agblocks = cur->bc_mp->m_sb.sb_agblocks; xfs_agblock_t agblocks = cur->bc_mp->m_sb.sb_agblocks;
XFS_WANT_CORRUPTED_RETURN( XFS_WANT_CORRUPTED_RETURN(cur->bc_mp,
level > 0 && level > 0 &&
bno != NULLAGBLOCK && bno != NULLAGBLOCK &&
bno != 0 && bno != 0 &&
...@@ -1825,7 +1825,7 @@ xfs_btree_lookup( ...@@ -1825,7 +1825,7 @@ xfs_btree_lookup(
error = xfs_btree_increment(cur, 0, &i); error = xfs_btree_increment(cur, 0, &i);
if (error) if (error)
goto error0; goto error0;
XFS_WANT_CORRUPTED_RETURN(i == 1); XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1);
XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
*stat = 1; *stat = 1;
return 0; return 0;
...@@ -2285,7 +2285,7 @@ xfs_btree_rshift( ...@@ -2285,7 +2285,7 @@ xfs_btree_rshift(
if (error) if (error)
goto error0; goto error0;
i = xfs_btree_lastrec(tcur, level); i = xfs_btree_lastrec(tcur, level);
XFS_WANT_CORRUPTED_GOTO(i == 1, error0); XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0);
error = xfs_btree_increment(tcur, level, &i); error = xfs_btree_increment(tcur, level, &i);
if (error) if (error)
...@@ -3138,7 +3138,7 @@ xfs_btree_insert( ...@@ -3138,7 +3138,7 @@ xfs_btree_insert(
goto error0; goto error0;
} }
XFS_WANT_CORRUPTED_GOTO(i == 1, error0); XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0);
level++; level++;
/* /*
...@@ -3582,15 +3582,15 @@ xfs_btree_delrec( ...@@ -3582,15 +3582,15 @@ xfs_btree_delrec(
* Actually any entry but the first would suffice. * Actually any entry but the first would suffice.
*/ */
i = xfs_btree_lastrec(tcur, level); i = xfs_btree_lastrec(tcur, level);
XFS_WANT_CORRUPTED_GOTO(i == 1, error0); XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0);
error = xfs_btree_increment(tcur, level, &i); error = xfs_btree_increment(tcur, level, &i);
if (error) if (error)
goto error0; goto error0;
XFS_WANT_CORRUPTED_GOTO(i == 1, error0); XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0);
i = xfs_btree_lastrec(tcur, level); i = xfs_btree_lastrec(tcur, level);
XFS_WANT_CORRUPTED_GOTO(i == 1, error0); XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0);
/* Grab a pointer to the block. */ /* Grab a pointer to the block. */
right = xfs_btree_get_block(tcur, level, &rbp); right = xfs_btree_get_block(tcur, level, &rbp);
...@@ -3634,12 +3634,12 @@ xfs_btree_delrec( ...@@ -3634,12 +3634,12 @@ xfs_btree_delrec(
rrecs = xfs_btree_get_numrecs(right); rrecs = xfs_btree_get_numrecs(right);
if (!xfs_btree_ptr_is_null(cur, &lptr)) { if (!xfs_btree_ptr_is_null(cur, &lptr)) {
i = xfs_btree_firstrec(tcur, level); i = xfs_btree_firstrec(tcur, level);
XFS_WANT_CORRUPTED_GOTO(i == 1, error0); XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0);
error = xfs_btree_decrement(tcur, level, &i); error = xfs_btree_decrement(tcur, level, &i);
if (error) if (error)
goto error0; goto error0;
XFS_WANT_CORRUPTED_GOTO(i == 1, error0); XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0);
} }
} }
...@@ -3653,13 +3653,13 @@ xfs_btree_delrec( ...@@ -3653,13 +3653,13 @@ xfs_btree_delrec(
* previous block. * previous block.
*/ */
i = xfs_btree_firstrec(tcur, level); i = xfs_btree_firstrec(tcur, level);
XFS_WANT_CORRUPTED_GOTO(i == 1, error0); XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0);
error = xfs_btree_decrement(tcur, level, &i); error = xfs_btree_decrement(tcur, level, &i);
if (error) if (error)
goto error0; goto error0;
i = xfs_btree_firstrec(tcur, level); i = xfs_btree_firstrec(tcur, level);
XFS_WANT_CORRUPTED_GOTO(i == 1, error0); XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0);
/* Grab a pointer to the block. */ /* Grab a pointer to the block. */
left = xfs_btree_get_block(tcur, level, &lbp); left = xfs_btree_get_block(tcur, level, &lbp);
......
...@@ -89,7 +89,7 @@ __xfs_dir3_data_check( ...@@ -89,7 +89,7 @@ __xfs_dir3_data_check(
* so just ensure that the count falls somewhere inside the * so just ensure that the count falls somewhere inside the
* block right now. * block right now.
*/ */
XFS_WANT_CORRUPTED_RETURN(be32_to_cpu(btp->count) < XFS_WANT_CORRUPTED_RETURN(mp, be32_to_cpu(btp->count) <
((char *)btp - p) / sizeof(struct xfs_dir2_leaf_entry)); ((char *)btp - p) / sizeof(struct xfs_dir2_leaf_entry));
break; break;
case cpu_to_be32(XFS_DIR3_DATA_MAGIC): case cpu_to_be32(XFS_DIR3_DATA_MAGIC):
...@@ -107,21 +107,21 @@ __xfs_dir3_data_check( ...@@ -107,21 +107,21 @@ __xfs_dir3_data_check(
bf = ops->data_bestfree_p(hdr); bf = ops->data_bestfree_p(hdr);
count = lastfree = freeseen = 0; count = lastfree = freeseen = 0;
if (!bf[0].length) { if (!bf[0].length) {
XFS_WANT_CORRUPTED_RETURN(!bf[0].offset); XFS_WANT_CORRUPTED_RETURN(mp, !bf[0].offset);
freeseen |= 1 << 0; freeseen |= 1 << 0;
} }
if (!bf[1].length) { if (!bf[1].length) {
XFS_WANT_CORRUPTED_RETURN(!bf[1].offset); XFS_WANT_CORRUPTED_RETURN(mp, !bf[1].offset);
freeseen |= 1 << 1; freeseen |= 1 << 1;
} }
if (!bf[2].length) { if (!bf[2].length) {
XFS_WANT_CORRUPTED_RETURN(!bf[2].offset); XFS_WANT_CORRUPTED_RETURN(mp, !bf[2].offset);
freeseen |= 1 << 2; freeseen |= 1 << 2;
} }
XFS_WANT_CORRUPTED_RETURN(be16_to_cpu(bf[0].length) >= XFS_WANT_CORRUPTED_RETURN(mp, be16_to_cpu(bf[0].length) >=
be16_to_cpu(bf[1].length)); be16_to_cpu(bf[1].length));
XFS_WANT_CORRUPTED_RETURN(be16_to_cpu(bf[1].length) >= XFS_WANT_CORRUPTED_RETURN(mp, be16_to_cpu(bf[1].length) >=
be16_to_cpu(bf[2].length)); be16_to_cpu(bf[2].length));
/* /*
* Loop over the data/unused entries. * Loop over the data/unused entries.
...@@ -134,18 +134,18 @@ __xfs_dir3_data_check( ...@@ -134,18 +134,18 @@ __xfs_dir3_data_check(
* doesn't need to be there. * doesn't need to be there.
*/ */
if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
XFS_WANT_CORRUPTED_RETURN(lastfree == 0); XFS_WANT_CORRUPTED_RETURN(mp, lastfree == 0);
XFS_WANT_CORRUPTED_RETURN( XFS_WANT_CORRUPTED_RETURN(mp,
be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) == be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) ==
(char *)dup - (char *)hdr); (char *)dup - (char *)hdr);
dfp = xfs_dir2_data_freefind(hdr, bf, dup); dfp = xfs_dir2_data_freefind(hdr, bf, dup);
if (dfp) { if (dfp) {
i = (int)(dfp - bf); i = (int)(dfp - bf);
XFS_WANT_CORRUPTED_RETURN( XFS_WANT_CORRUPTED_RETURN(mp,
(freeseen & (1 << i)) == 0); (freeseen & (1 << i)) == 0);
freeseen |= 1 << i; freeseen |= 1 << i;
} else { } else {
XFS_WANT_CORRUPTED_RETURN( XFS_WANT_CORRUPTED_RETURN(mp,
be16_to_cpu(dup->length) <= be16_to_cpu(dup->length) <=
be16_to_cpu(bf[2].length)); be16_to_cpu(bf[2].length));
} }
...@@ -160,13 +160,13 @@ __xfs_dir3_data_check( ...@@ -160,13 +160,13 @@ __xfs_dir3_data_check(
* The linear search is crude but this is DEBUG code. * The linear search is crude but this is DEBUG code.
*/ */
dep = (xfs_dir2_data_entry_t *)p; dep = (xfs_dir2_data_entry_t *)p;
XFS_WANT_CORRUPTED_RETURN(dep->namelen != 0); XFS_WANT_CORRUPTED_RETURN(mp, dep->namelen != 0);
XFS_WANT_CORRUPTED_RETURN( XFS_WANT_CORRUPTED_RETURN(mp,
!xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber))); !xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber)));
XFS_WANT_CORRUPTED_RETURN( XFS_WANT_CORRUPTED_RETURN(mp,
be16_to_cpu(*ops->data_entry_tag_p(dep)) == be16_to_cpu(*ops->data_entry_tag_p(dep)) ==
(char *)dep - (char *)hdr); (char *)dep - (char *)hdr);
XFS_WANT_CORRUPTED_RETURN( XFS_WANT_CORRUPTED_RETURN(mp,
ops->data_get_ftype(dep) < XFS_DIR3_FT_MAX); ops->data_get_ftype(dep) < XFS_DIR3_FT_MAX);
count++; count++;
lastfree = 0; lastfree = 0;
...@@ -183,14 +183,15 @@ __xfs_dir3_data_check( ...@@ -183,14 +183,15 @@ __xfs_dir3_data_check(
be32_to_cpu(lep[i].hashval) == hash) be32_to_cpu(lep[i].hashval) == hash)
break; break;
} }
XFS_WANT_CORRUPTED_RETURN(i < be32_to_cpu(btp->count)); XFS_WANT_CORRUPTED_RETURN(mp,
i < be32_to_cpu(btp->count));
} }
p += ops->data_entsize(dep->namelen); p += ops->data_entsize(dep->namelen);
} }
/* /*
* Need to have seen all the entries and all the bestfree slots. * Need to have seen all the entries and all the bestfree slots.
*/ */
XFS_WANT_CORRUPTED_RETURN(freeseen == 7); XFS_WANT_CORRUPTED_RETURN(mp, freeseen == 7);
if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) { hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) {
for (i = stale = 0; i < be32_to_cpu(btp->count); i++) { for (i = stale = 0; i < be32_to_cpu(btp->count); i++) {
...@@ -198,13 +199,13 @@ __xfs_dir3_data_check( ...@@ -198,13 +199,13 @@ __xfs_dir3_data_check(
cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
stale++; stale++;
if (i > 0) if (i > 0)
XFS_WANT_CORRUPTED_RETURN( XFS_WANT_CORRUPTED_RETURN(mp,
be32_to_cpu(lep[i].hashval) >= be32_to_cpu(lep[i].hashval) >=
be32_to_cpu(lep[i - 1].hashval)); be32_to_cpu(lep[i - 1].hashval));
} }
XFS_WANT_CORRUPTED_RETURN(count == XFS_WANT_CORRUPTED_RETURN(mp, count ==
be32_to_cpu(btp->count) - be32_to_cpu(btp->stale)); be32_to_cpu(btp->count) - be32_to_cpu(btp->stale));
XFS_WANT_CORRUPTED_RETURN(stale == be32_to_cpu(btp->stale)); XFS_WANT_CORRUPTED_RETURN(mp, stale == be32_to_cpu(btp->stale));
} }
return 0; return 0;
} }
......
...@@ -700,7 +700,7 @@ xfs_ialloc_next_rec( ...@@ -700,7 +700,7 @@ xfs_ialloc_next_rec(
error = xfs_inobt_get_rec(cur, rec, &i); error = xfs_inobt_get_rec(cur, rec, &i);
if (error) if (error)
return error; return error;
XFS_WANT_CORRUPTED_RETURN(i == 1); XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1);
} }
return 0; return 0;
...@@ -724,7 +724,7 @@ xfs_ialloc_get_rec( ...@@ -724,7 +724,7 @@ xfs_ialloc_get_rec(
error = xfs_inobt_get_rec(cur, rec, &i); error = xfs_inobt_get_rec(cur, rec, &i);
if (error) if (error)
return error; return error;
XFS_WANT_CORRUPTED_RETURN(i == 1); XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1);
} }
return 0; return 0;
...@@ -783,12 +783,12 @@ xfs_dialloc_ag_inobt( ...@@ -783,12 +783,12 @@ xfs_dialloc_ag_inobt(
error = xfs_inobt_lookup(cur, pagino, XFS_LOOKUP_LE, &i); error = xfs_inobt_lookup(cur, pagino, XFS_LOOKUP_LE, &i);
if (error) if (error)
goto error0; goto error0;
XFS_WANT_CORRUPTED_GOTO(i == 1, error0); XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
error = xfs_inobt_get_rec(cur, &rec, &j); error = xfs_inobt_get_rec(cur, &rec, &j);
if (error) if (error)
goto error0; goto error0;
XFS_WANT_CORRUPTED_GOTO(j == 1, error0); XFS_WANT_CORRUPTED_GOTO(mp, j == 1, error0);
if (rec.ir_freecount > 0) { if (rec.ir_freecount > 0) {
/* /*
...@@ -944,19 +944,19 @@ xfs_dialloc_ag_inobt( ...@@ -944,19 +944,19 @@ xfs_dialloc_ag_inobt(
error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i); error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i);
if (error) if (error)
goto error0; goto error0;
XFS_WANT_CORRUPTED_GOTO(i == 1, error0); XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
for (;;) { for (;;) {
error = xfs_inobt_get_rec(cur, &rec, &i); error = xfs_inobt_get_rec(cur, &rec, &i);
if (error) if (error)
goto error0; goto error0;
XFS_WANT_CORRUPTED_GOTO(i == 1, error0); XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
if (rec.ir_freecount > 0) if (rec.ir_freecount > 0)
break; break;
error = xfs_btree_increment(cur, 0, &i); error = xfs_btree_increment(cur, 0, &i);
if (error) if (error)
goto error0; goto error0;
XFS_WANT_CORRUPTED_GOTO(i == 1, error0); XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
} }
alloc_inode: alloc_inode:
...@@ -1016,7 +1016,7 @@ xfs_dialloc_ag_finobt_near( ...@@ -1016,7 +1016,7 @@ xfs_dialloc_ag_finobt_near(
error = xfs_inobt_get_rec(lcur, rec, &i); error = xfs_inobt_get_rec(lcur, rec, &i);
if (error) if (error)
return error; return error;
XFS_WANT_CORRUPTED_RETURN(i == 1); XFS_WANT_CORRUPTED_RETURN(lcur->bc_mp, i == 1);
/* /*
* See if we've landed in the parent inode record. The finobt * See if we've landed in the parent inode record. The finobt
...@@ -1039,10 +1039,10 @@ xfs_dialloc_ag_finobt_near( ...@@ -1039,10 +1039,10 @@ xfs_dialloc_ag_finobt_near(
error = xfs_inobt_get_rec(rcur, &rrec, &j); error = xfs_inobt_get_rec(rcur, &rrec, &j);
if (error) if (error)
goto error_rcur; goto error_rcur;
XFS_WANT_CORRUPTED_GOTO(j == 1, error_rcur); XFS_WANT_CORRUPTED_GOTO(lcur->bc_mp, j == 1, error_rcur);
} }
XFS_WANT_CORRUPTED_GOTO(i == 1 || j == 1, error_rcur); XFS_WANT_CORRUPTED_GOTO(lcur->bc_mp, i == 1 || j == 1, error_rcur);
if (i == 1 && j == 1) { if (i == 1 && j == 1) {
/* /*
* Both the left and right records are valid. Choose the closer * Both the left and right records are valid. Choose the closer
...@@ -1095,7 +1095,7 @@ xfs_dialloc_ag_finobt_newino( ...@@ -1095,7 +1095,7 @@ xfs_dialloc_ag_finobt_newino(
error = xfs_inobt_get_rec(cur, rec, &i); error = xfs_inobt_get_rec(cur, rec, &i);
if (error) if (error)
return error; return error;
XFS_WANT_CORRUPTED_RETURN(i == 1); XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1);
return 0; return 0;
} }
} }
...@@ -1106,12 +1106,12 @@ xfs_dialloc_ag_finobt_newino( ...@@ -1106,12 +1106,12 @@ xfs_dialloc_ag_finobt_newino(
error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i); error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i);
if (error) if (error)
return error; return error;
XFS_WANT_CORRUPTED_RETURN(i == 1); XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1);
error = xfs_inobt_get_rec(cur, rec, &i); error = xfs_inobt_get_rec(cur, rec, &i);
if (error) if (error)
return error; return error;
XFS_WANT_CORRUPTED_RETURN(i == 1); XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1);
return 0; return 0;
} }
...@@ -1133,19 +1133,19 @@ xfs_dialloc_ag_update_inobt( ...@@ -1133,19 +1133,19 @@ xfs_dialloc_ag_update_inobt(
error = xfs_inobt_lookup(cur, frec->ir_startino, XFS_LOOKUP_EQ, &i); error = xfs_inobt_lookup(cur, frec->ir_startino, XFS_LOOKUP_EQ, &i);
if (error) if (error)
return error; return error;
XFS_WANT_CORRUPTED_RETURN(i == 1); XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1);
error = xfs_inobt_get_rec(cur, &rec, &i); error = xfs_inobt_get_rec(cur, &rec, &i);
if (error) if (error)
return error; return error;
XFS_WANT_CORRUPTED_RETURN(i == 1); XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1);
ASSERT((XFS_AGINO_TO_OFFSET(cur->bc_mp, rec.ir_startino) % ASSERT((XFS_AGINO_TO_OFFSET(cur->bc_mp, rec.ir_startino) %
XFS_INODES_PER_CHUNK) == 0); XFS_INODES_PER_CHUNK) == 0);
rec.ir_free &= ~XFS_INOBT_MASK(offset); rec.ir_free &= ~XFS_INOBT_MASK(offset);
rec.ir_freecount--; rec.ir_freecount--;
XFS_WANT_CORRUPTED_RETURN((rec.ir_free == frec->ir_free) && XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, (rec.ir_free == frec->ir_free) &&
(rec.ir_freecount == frec->ir_freecount)); (rec.ir_freecount == frec->ir_freecount));
return xfs_inobt_update(cur, &rec); return xfs_inobt_update(cur, &rec);
...@@ -1475,14 +1475,14 @@ xfs_difree_inobt( ...@@ -1475,14 +1475,14 @@ xfs_difree_inobt(
__func__, error); __func__, error);
goto error0; goto error0;
} }
XFS_WANT_CORRUPTED_GOTO(i == 1, error0); XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
error = xfs_inobt_get_rec(cur, &rec, &i); error = xfs_inobt_get_rec(cur, &rec, &i);
if (error) { if (error) {
xfs_warn(mp, "%s: xfs_inobt_get_rec() returned error %d.", xfs_warn(mp, "%s: xfs_inobt_get_rec() returned error %d.",
__func__, error); __func__, error);
goto error0; goto error0;
} }
XFS_WANT_CORRUPTED_GOTO(i == 1, error0); XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
/* /*
* Get the offset in the inode chunk. * Get the offset in the inode chunk.
*/ */
...@@ -1592,7 +1592,7 @@ xfs_difree_finobt( ...@@ -1592,7 +1592,7 @@ xfs_difree_finobt(
* freed an inode in a previously fully allocated chunk. If not, * freed an inode in a previously fully allocated chunk. If not,
* something is out of sync. * something is out of sync.
*/ */
XFS_WANT_CORRUPTED_GOTO(ibtrec->ir_freecount == 1, error); XFS_WANT_CORRUPTED_GOTO(mp, ibtrec->ir_freecount == 1, error);
error = xfs_inobt_insert_rec(cur, ibtrec->ir_freecount, error = xfs_inobt_insert_rec(cur, ibtrec->ir_freecount,
ibtrec->ir_free, &i); ibtrec->ir_free, &i);
...@@ -1613,12 +1613,12 @@ xfs_difree_finobt( ...@@ -1613,12 +1613,12 @@ xfs_difree_finobt(
error = xfs_inobt_get_rec(cur, &rec, &i); error = xfs_inobt_get_rec(cur, &rec, &i);
if (error) if (error)
goto error; goto error;
XFS_WANT_CORRUPTED_GOTO(i == 1, error); XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error);
rec.ir_free |= XFS_INOBT_MASK(offset); rec.ir_free |= XFS_INOBT_MASK(offset);
rec.ir_freecount++; rec.ir_freecount++;
XFS_WANT_CORRUPTED_GOTO((rec.ir_free == ibtrec->ir_free) && XFS_WANT_CORRUPTED_GOTO(mp, (rec.ir_free == ibtrec->ir_free) &&
(rec.ir_freecount == ibtrec->ir_freecount), (rec.ir_freecount == ibtrec->ir_freecount),
error); error);
......
...@@ -111,14 +111,6 @@ xfs_mount_validate_sb( ...@@ -111,14 +111,6 @@ xfs_mount_validate_sb(
bool check_inprogress, bool check_inprogress,
bool check_version) bool check_version)
{ {
/*
* If the log device and data device have the
* same device number, the log is internal.
* Consequently, the sb_logstart should be non-zero. If
* we have a zero sb_logstart in this case, we may be trying to mount
* a volume filesystem in a non-volume manner.
*/
if (sbp->sb_magicnum != XFS_SB_MAGIC) { if (sbp->sb_magicnum != XFS_SB_MAGIC) {
xfs_warn(mp, "bad magic number"); xfs_warn(mp, "bad magic number");
return -EWRONGFS; return -EWRONGFS;
......
...@@ -537,9 +537,9 @@ xfs_buf_item_push( ...@@ -537,9 +537,9 @@ xfs_buf_item_push(
/* has a previous flush failed due to IO errors? */ /* has a previous flush failed due to IO errors? */
if ((bp->b_flags & XBF_WRITE_FAIL) && if ((bp->b_flags & XBF_WRITE_FAIL) &&
___ratelimit(&xfs_buf_write_fail_rl_state, "XFS:")) { ___ratelimit(&xfs_buf_write_fail_rl_state, "XFS: Failing async write")) {
xfs_warn(bp->b_target->bt_mount, xfs_warn(bp->b_target->bt_mount,
"Detected failing async write on buffer block 0x%llx. Retrying async write.", "Failing async write on buffer block 0x%llx. Retrying async write.",
(long long)bp->b_bn); (long long)bp->b_bn);
} }
......
...@@ -84,7 +84,7 @@ xfs_trim_extents( ...@@ -84,7 +84,7 @@ xfs_trim_extents(
error = xfs_alloc_get_rec(cur, &fbno, &flen, &i); error = xfs_alloc_get_rec(cur, &fbno, &flen, &i);
if (error) if (error)
goto out_del_cursor; goto out_del_cursor;
XFS_WANT_CORRUPTED_GOTO(i == 1, out_del_cursor); XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_del_cursor);
ASSERT(flen <= be32_to_cpu(XFS_BUF_TO_AGF(agbp)->agf_longest)); ASSERT(flen <= be32_to_cpu(XFS_BUF_TO_AGF(agbp)->agf_longest));
/* /*
......
...@@ -40,25 +40,25 @@ extern void xfs_verifier_error(struct xfs_buf *bp); ...@@ -40,25 +40,25 @@ extern void xfs_verifier_error(struct xfs_buf *bp);
/* /*
* Macros to set EFSCORRUPTED & return/branch. * Macros to set EFSCORRUPTED & return/branch.
*/ */
#define XFS_WANT_CORRUPTED_GOTO(x,l) \ #define XFS_WANT_CORRUPTED_GOTO(mp, x, l) \
{ \ { \
int fs_is_ok = (x); \ int fs_is_ok = (x); \
ASSERT(fs_is_ok); \ ASSERT(fs_is_ok); \
if (unlikely(!fs_is_ok)) { \ if (unlikely(!fs_is_ok)) { \
XFS_ERROR_REPORT("XFS_WANT_CORRUPTED_GOTO", \ XFS_ERROR_REPORT("XFS_WANT_CORRUPTED_GOTO", \
XFS_ERRLEVEL_LOW, NULL); \ XFS_ERRLEVEL_LOW, mp); \
error = -EFSCORRUPTED; \ error = -EFSCORRUPTED; \
goto l; \ goto l; \
} \ } \
} }
#define XFS_WANT_CORRUPTED_RETURN(x) \ #define XFS_WANT_CORRUPTED_RETURN(mp, x) \
{ \ { \
int fs_is_ok = (x); \ int fs_is_ok = (x); \
ASSERT(fs_is_ok); \ ASSERT(fs_is_ok); \
if (unlikely(!fs_is_ok)) { \ if (unlikely(!fs_is_ok)) { \
XFS_ERROR_REPORT("XFS_WANT_CORRUPTED_RETURN", \ XFS_ERROR_REPORT("XFS_WANT_CORRUPTED_RETURN", \
XFS_ERRLEVEL_LOW, NULL); \ XFS_ERRLEVEL_LOW, mp); \
return -EFSCORRUPTED; \ return -EFSCORRUPTED; \
} \ } \
} }
......
...@@ -439,11 +439,11 @@ xfs_iget( ...@@ -439,11 +439,11 @@ xfs_iget(
*ipp = ip; *ipp = ip;
/* /*
* If we have a real type for an on-disk inode, we can set ops(&unlock) * If we have a real type for an on-disk inode, we can setup the inode
* now. If it's a new inode being created, xfs_ialloc will handle it. * now. If it's a new inode being created, xfs_ialloc will handle it.
*/ */
if (xfs_iflags_test(ip, XFS_INEW) && ip->i_d.di_mode != 0) if (xfs_iflags_test(ip, XFS_INEW) && ip->i_d.di_mode != 0)
xfs_setup_inode(ip); xfs_setup_existing_inode(ip);
return 0; return 0;
out_error_or_again: out_error_or_again:
......
...@@ -818,7 +818,7 @@ xfs_ialloc( ...@@ -818,7 +818,7 @@ xfs_ialloc(
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
xfs_trans_log_inode(tp, ip, flags); xfs_trans_log_inode(tp, ip, flags);
/* now that we have an i_mode we can setup inode ops and unlock */ /* now that we have an i_mode we can setup the inode structure */
xfs_setup_inode(ip); xfs_setup_inode(ip);
*ipp = ip; *ipp = ip;
...@@ -1235,12 +1235,14 @@ xfs_create( ...@@ -1235,12 +1235,14 @@ xfs_create(
xfs_trans_cancel(tp, cancel_flags); xfs_trans_cancel(tp, cancel_flags);
out_release_inode: out_release_inode:
/* /*
* Wait until after the current transaction is aborted to * Wait until after the current transaction is aborted to finish the
* release the inode. This prevents recursive transactions * setup of the inode and release the inode. This prevents recursive
* and deadlocks from xfs_inactive. * transactions and deadlocks from xfs_inactive.
*/ */
if (ip) if (ip) {
xfs_finish_inode_setup(ip);
IRELE(ip); IRELE(ip);
}
xfs_qm_dqrele(udqp); xfs_qm_dqrele(udqp);
xfs_qm_dqrele(gdqp); xfs_qm_dqrele(gdqp);
...@@ -1345,12 +1347,14 @@ xfs_create_tmpfile( ...@@ -1345,12 +1347,14 @@ xfs_create_tmpfile(
xfs_trans_cancel(tp, cancel_flags); xfs_trans_cancel(tp, cancel_flags);
out_release_inode: out_release_inode:
/* /*
* Wait until after the current transaction is aborted to * Wait until after the current transaction is aborted to finish the
* release the inode. This prevents recursive transactions * setup of the inode and release the inode. This prevents recursive
* and deadlocks from xfs_inactive. * transactions and deadlocks from xfs_inactive.
*/ */
if (ip) if (ip) {
xfs_finish_inode_setup(ip);
IRELE(ip); IRELE(ip);
}
xfs_qm_dqrele(udqp); xfs_qm_dqrele(udqp);
xfs_qm_dqrele(gdqp); xfs_qm_dqrele(gdqp);
......
...@@ -391,6 +391,28 @@ int xfs_zero_eof(struct xfs_inode *ip, xfs_off_t offset, ...@@ -391,6 +391,28 @@ int xfs_zero_eof(struct xfs_inode *ip, xfs_off_t offset,
int xfs_iozero(struct xfs_inode *ip, loff_t pos, size_t count); int xfs_iozero(struct xfs_inode *ip, loff_t pos, size_t count);
/* from xfs_iops.c */
/*
* When setting up a newly allocated inode, we need to call
* xfs_finish_inode_setup() once the inode is fully instantiated at
* the VFS level to prevent the rest of the world seeing the inode
* before we've completed instantiation. Otherwise we can do it
* the moment the inode lookup is complete.
*/
extern void xfs_setup_inode(struct xfs_inode *ip);
static inline void xfs_finish_inode_setup(struct xfs_inode *ip)
{
xfs_iflags_clear(ip, XFS_INEW);
barrier();
unlock_new_inode(VFS_I(ip));
}
static inline void xfs_setup_existing_inode(struct xfs_inode *ip)
{
xfs_setup_inode(ip);
xfs_finish_inode_setup(ip);
}
#define IHOLD(ip) \ #define IHOLD(ip) \
do { \ do { \
ASSERT(atomic_read(&VFS_I(ip)->i_count) > 0) ; \ ASSERT(atomic_read(&VFS_I(ip)->i_count) > 0) ; \
......
...@@ -187,6 +187,8 @@ xfs_generic_create( ...@@ -187,6 +187,8 @@ xfs_generic_create(
else else
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
xfs_finish_inode_setup(ip);
out_free_acl: out_free_acl:
if (default_acl) if (default_acl)
posix_acl_release(default_acl); posix_acl_release(default_acl);
...@@ -195,6 +197,7 @@ xfs_generic_create( ...@@ -195,6 +197,7 @@ xfs_generic_create(
return error; return error;
out_cleanup_inode: out_cleanup_inode:
xfs_finish_inode_setup(ip);
if (!tmpfile) if (!tmpfile)
xfs_cleanup_inode(dir, inode, dentry); xfs_cleanup_inode(dir, inode, dentry);
iput(inode); iput(inode);
...@@ -367,9 +370,11 @@ xfs_vn_symlink( ...@@ -367,9 +370,11 @@ xfs_vn_symlink(
goto out_cleanup_inode; goto out_cleanup_inode;
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
xfs_finish_inode_setup(cip);
return 0; return 0;
out_cleanup_inode: out_cleanup_inode:
xfs_finish_inode_setup(cip);
xfs_cleanup_inode(dir, inode, dentry); xfs_cleanup_inode(dir, inode, dentry);
iput(inode); iput(inode);
out: out:
...@@ -1228,16 +1233,12 @@ xfs_diflags_to_iflags( ...@@ -1228,16 +1233,12 @@ xfs_diflags_to_iflags(
} }
/* /*
* Initialize the Linux inode, set up the operation vectors and * Initialize the Linux inode and set up the operation vectors.
* unlock the inode.
*
* When reading existing inodes from disk this is called directly
* from xfs_iget, when creating a new inode it is called from
* xfs_ialloc after setting up the inode.
* *
* We are always called with an uninitialised linux inode here. * When reading existing inodes from disk this is called directly from xfs_iget,
* We need to initialise the necessary fields and take a reference * when creating a new inode it is called from xfs_ialloc after setting up the
* on it. * inode. These callers have different criteria for clearing XFS_INEW, so leave
* it up to the caller to deal with unlocking the inode appropriately.
*/ */
void void
xfs_setup_inode( xfs_setup_inode(
...@@ -1324,9 +1325,4 @@ xfs_setup_inode( ...@@ -1324,9 +1325,4 @@ xfs_setup_inode(
inode_has_no_xattr(inode); inode_has_no_xattr(inode);
cache_no_acl(inode); cache_no_acl(inode);
} }
xfs_iflags_clear(ip, XFS_INEW);
barrier();
unlock_new_inode(inode);
} }
...@@ -25,8 +25,6 @@ extern const struct file_operations xfs_dir_file_operations; ...@@ -25,8 +25,6 @@ extern const struct file_operations xfs_dir_file_operations;
extern ssize_t xfs_vn_listxattr(struct dentry *, char *data, size_t size); extern ssize_t xfs_vn_listxattr(struct dentry *, char *data, size_t size);
extern void xfs_setup_inode(struct xfs_inode *);
/* /*
* Internal setattr interfaces. * Internal setattr interfaces.
*/ */
......
...@@ -229,7 +229,7 @@ xfs_bulkstat_grab_ichunk( ...@@ -229,7 +229,7 @@ xfs_bulkstat_grab_ichunk(
error = xfs_inobt_get_rec(cur, irec, &stat); error = xfs_inobt_get_rec(cur, irec, &stat);
if (error) if (error)
return error; return error;
XFS_WANT_CORRUPTED_RETURN(stat == 1); XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, stat == 1);
/* Check if the record contains the inode in request */ /* Check if the record contains the inode in request */
if (irec->ir_startino + XFS_INODES_PER_CHUNK <= agino) { if (irec->ir_startino + XFS_INODES_PER_CHUNK <= agino) {
......
...@@ -719,6 +719,7 @@ xfs_qm_qino_alloc( ...@@ -719,6 +719,7 @@ xfs_qm_qino_alloc(
xfs_trans_t *tp; xfs_trans_t *tp;
int error; int error;
int committed; int committed;
bool need_alloc = true;
*ip = NULL; *ip = NULL;
/* /*
...@@ -747,6 +748,7 @@ xfs_qm_qino_alloc( ...@@ -747,6 +748,7 @@ xfs_qm_qino_alloc(
return error; return error;
mp->m_sb.sb_gquotino = NULLFSINO; mp->m_sb.sb_gquotino = NULLFSINO;
mp->m_sb.sb_pquotino = NULLFSINO; mp->m_sb.sb_pquotino = NULLFSINO;
need_alloc = false;
} }
} }
...@@ -758,7 +760,7 @@ xfs_qm_qino_alloc( ...@@ -758,7 +760,7 @@ xfs_qm_qino_alloc(
return error; return error;
} }
if (!*ip) { if (need_alloc) {
error = xfs_dir_ialloc(&tp, NULL, S_IFREG, 1, 0, 0, 1, ip, error = xfs_dir_ialloc(&tp, NULL, S_IFREG, 1, 0, 0, 1, ip,
&committed); &committed);
if (error) { if (error) {
...@@ -794,11 +796,14 @@ xfs_qm_qino_alloc( ...@@ -794,11 +796,14 @@ xfs_qm_qino_alloc(
spin_unlock(&mp->m_sb_lock); spin_unlock(&mp->m_sb_lock);
xfs_log_sb(tp); xfs_log_sb(tp);
if ((error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES))) { error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
if (error) {
ASSERT(XFS_FORCED_SHUTDOWN(mp));
xfs_alert(mp, "%s failed (error %d)!", __func__, error); xfs_alert(mp, "%s failed (error %d)!", __func__, error);
return error;
} }
return 0; if (need_alloc)
xfs_finish_inode_setup(*ip);
return error;
} }
......
...@@ -109,8 +109,6 @@ static struct xfs_kobj xfs_dbg_kobj; /* global debug sysfs attrs */ ...@@ -109,8 +109,6 @@ static struct xfs_kobj xfs_dbg_kobj; /* global debug sysfs attrs */
#define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */ #define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */
#define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */ #define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */
#define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */ #define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */
#define MNTOPT_DELAYLOG "delaylog" /* Delayed logging enabled */
#define MNTOPT_NODELAYLOG "nodelaylog" /* Delayed logging disabled */
#define MNTOPT_DISCARD "discard" /* Discard unused blocks */ #define MNTOPT_DISCARD "discard" /* Discard unused blocks */
#define MNTOPT_NODISCARD "nodiscard" /* Do not discard unused blocks */ #define MNTOPT_NODISCARD "nodiscard" /* Do not discard unused blocks */
...@@ -361,28 +359,10 @@ xfs_parseargs( ...@@ -361,28 +359,10 @@ xfs_parseargs(
} else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) { } else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) {
mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
mp->m_qflags &= ~XFS_GQUOTA_ENFD; mp->m_qflags &= ~XFS_GQUOTA_ENFD;
} else if (!strcmp(this_char, MNTOPT_DELAYLOG)) {
xfs_warn(mp,
"delaylog is the default now, option is deprecated.");
} else if (!strcmp(this_char, MNTOPT_NODELAYLOG)) {
xfs_warn(mp,
"nodelaylog support has been removed, option is deprecated.");
} else if (!strcmp(this_char, MNTOPT_DISCARD)) { } else if (!strcmp(this_char, MNTOPT_DISCARD)) {
mp->m_flags |= XFS_MOUNT_DISCARD; mp->m_flags |= XFS_MOUNT_DISCARD;
} else if (!strcmp(this_char, MNTOPT_NODISCARD)) { } else if (!strcmp(this_char, MNTOPT_NODISCARD)) {
mp->m_flags &= ~XFS_MOUNT_DISCARD; mp->m_flags &= ~XFS_MOUNT_DISCARD;
} else if (!strcmp(this_char, "ihashsize")) {
xfs_warn(mp,
"ihashsize no longer used, option is deprecated.");
} else if (!strcmp(this_char, "osyncisdsync")) {
xfs_warn(mp,
"osyncisdsync has no effect, option is deprecated.");
} else if (!strcmp(this_char, "osyncisosync")) {
xfs_warn(mp,
"osyncisosync has no effect, option is deprecated.");
} else if (!strcmp(this_char, "irixsgid")) {
xfs_warn(mp,
"irixsgid is now a sysctl(2) variable, option is deprecated.");
} else { } else {
xfs_warn(mp, "unknown mount option [%s].", this_char); xfs_warn(mp, "unknown mount option [%s].", this_char);
return -EINVAL; return -EINVAL;
...@@ -1039,6 +1019,7 @@ xfs_fs_put_super( ...@@ -1039,6 +1019,7 @@ xfs_fs_put_super(
{ {
struct xfs_mount *mp = XFS_M(sb); struct xfs_mount *mp = XFS_M(sb);
xfs_notice(mp, "Unmounting Filesystem");
xfs_filestream_unmount(mp); xfs_filestream_unmount(mp);
xfs_unmountfs(mp); xfs_unmountfs(mp);
......
...@@ -177,7 +177,7 @@ xfs_symlink( ...@@ -177,7 +177,7 @@ xfs_symlink(
int pathlen; int pathlen;
struct xfs_bmap_free free_list; struct xfs_bmap_free free_list;
xfs_fsblock_t first_block; xfs_fsblock_t first_block;
bool unlock_dp_on_error = false; bool unlock_dp_on_error = false;
uint cancel_flags; uint cancel_flags;
int committed; int committed;
xfs_fileoff_t first_fsb; xfs_fileoff_t first_fsb;
...@@ -221,7 +221,7 @@ xfs_symlink( ...@@ -221,7 +221,7 @@ xfs_symlink(
XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT,
&udqp, &gdqp, &pdqp); &udqp, &gdqp, &pdqp);
if (error) if (error)
goto std_return; return error;
tp = xfs_trans_alloc(mp, XFS_TRANS_SYMLINK); tp = xfs_trans_alloc(mp, XFS_TRANS_SYMLINK);
cancel_flags = XFS_TRANS_RELEASE_LOG_RES; cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
...@@ -241,7 +241,7 @@ xfs_symlink( ...@@ -241,7 +241,7 @@ xfs_symlink(
} }
if (error) { if (error) {
cancel_flags = 0; cancel_flags = 0;
goto error_return; goto out_trans_cancel;
} }
xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
...@@ -252,7 +252,7 @@ xfs_symlink( ...@@ -252,7 +252,7 @@ xfs_symlink(
*/ */
if (dp->i_d.di_flags & XFS_DIFLAG_NOSYMLINKS) { if (dp->i_d.di_flags & XFS_DIFLAG_NOSYMLINKS) {
error = -EPERM; error = -EPERM;
goto error_return; goto out_trans_cancel;
} }
/* /*
...@@ -261,7 +261,7 @@ xfs_symlink( ...@@ -261,7 +261,7 @@ xfs_symlink(
error = xfs_trans_reserve_quota(tp, mp, udqp, gdqp, error = xfs_trans_reserve_quota(tp, mp, udqp, gdqp,
pdqp, resblks, 1, 0); pdqp, resblks, 1, 0);
if (error) if (error)
goto error_return; goto out_trans_cancel;
/* /*
* Check for ability to enter directory entry, if no space reserved. * Check for ability to enter directory entry, if no space reserved.
...@@ -269,7 +269,7 @@ xfs_symlink( ...@@ -269,7 +269,7 @@ xfs_symlink(
if (!resblks) { if (!resblks) {
error = xfs_dir_canenter(tp, dp, link_name); error = xfs_dir_canenter(tp, dp, link_name);
if (error) if (error)
goto error_return; goto out_trans_cancel;
} }
/* /*
* Initialize the bmap freelist prior to calling either * Initialize the bmap freelist prior to calling either
...@@ -282,15 +282,14 @@ xfs_symlink( ...@@ -282,15 +282,14 @@ xfs_symlink(
*/ */
error = xfs_dir_ialloc(&tp, dp, S_IFLNK | (mode & ~S_IFMT), 1, 0, error = xfs_dir_ialloc(&tp, dp, S_IFLNK | (mode & ~S_IFMT), 1, 0,
prid, resblks > 0, &ip, NULL); prid, resblks > 0, &ip, NULL);
if (error) { if (error)
if (error == -ENOSPC) goto out_trans_cancel;
goto error_return;
goto error1;
}
/* /*
* An error after we've joined dp to the transaction will result in the * Now we join the directory inode to the transaction. We do not do it
* transaction cancel unlocking dp so don't do it explicitly in the * earlier because xfs_dir_ialloc might commit the previous transaction
* (and release all the locks). An error from here on will result in
* the transaction cancel unlocking dp so don't do it explicitly in the
* error path. * error path.
*/ */
xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
...@@ -330,7 +329,7 @@ xfs_symlink( ...@@ -330,7 +329,7 @@ xfs_symlink(
XFS_BMAPI_METADATA, &first_block, resblks, XFS_BMAPI_METADATA, &first_block, resblks,
mval, &nmaps, &free_list); mval, &nmaps, &free_list);
if (error) if (error)
goto error2; goto out_bmap_cancel;
if (resblks) if (resblks)
resblks -= fs_blocks; resblks -= fs_blocks;
...@@ -348,7 +347,7 @@ xfs_symlink( ...@@ -348,7 +347,7 @@ xfs_symlink(
BTOBB(byte_cnt), 0); BTOBB(byte_cnt), 0);
if (!bp) { if (!bp) {
error = -ENOMEM; error = -ENOMEM;
goto error2; goto out_bmap_cancel;
} }
bp->b_ops = &xfs_symlink_buf_ops; bp->b_ops = &xfs_symlink_buf_ops;
...@@ -378,7 +377,7 @@ xfs_symlink( ...@@ -378,7 +377,7 @@ xfs_symlink(
error = xfs_dir_createname(tp, dp, link_name, ip->i_ino, error = xfs_dir_createname(tp, dp, link_name, ip->i_ino,
&first_block, &free_list, resblks); &first_block, &free_list, resblks);
if (error) if (error)
goto error2; goto out_bmap_cancel;
xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
...@@ -392,10 +391,13 @@ xfs_symlink( ...@@ -392,10 +391,13 @@ xfs_symlink(
} }
error = xfs_bmap_finish(&tp, &free_list, &committed); error = xfs_bmap_finish(&tp, &free_list, &committed);
if (error) { if (error)
goto error2; goto out_bmap_cancel;
}
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
if (error)
goto out_release_inode;
xfs_qm_dqrele(udqp); xfs_qm_dqrele(udqp);
xfs_qm_dqrele(gdqp); xfs_qm_dqrele(gdqp);
xfs_qm_dqrele(pdqp); xfs_qm_dqrele(pdqp);
...@@ -403,20 +405,28 @@ xfs_symlink( ...@@ -403,20 +405,28 @@ xfs_symlink(
*ipp = ip; *ipp = ip;
return 0; return 0;
error2: out_bmap_cancel:
IRELE(ip);
error1:
xfs_bmap_cancel(&free_list); xfs_bmap_cancel(&free_list);
cancel_flags |= XFS_TRANS_ABORT; cancel_flags |= XFS_TRANS_ABORT;
error_return: out_trans_cancel:
xfs_trans_cancel(tp, cancel_flags); xfs_trans_cancel(tp, cancel_flags);
out_release_inode:
/*
* Wait until after the current transaction is aborted to finish the
* setup of the inode and release the inode. This prevents recursive
* transactions and deadlocks from xfs_inactive.
*/
if (ip) {
xfs_finish_inode_setup(ip);
IRELE(ip);
}
xfs_qm_dqrele(udqp); xfs_qm_dqrele(udqp);
xfs_qm_dqrele(gdqp); xfs_qm_dqrele(gdqp);
xfs_qm_dqrele(pdqp); xfs_qm_dqrele(pdqp);
if (unlock_dp_on_error) if (unlock_dp_on_error)
xfs_iunlock(dp, XFS_ILOCK_EXCL); xfs_iunlock(dp, XFS_ILOCK_EXCL);
std_return:
return error; return error;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment