Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://oss.sgi.com/xfs/xfs
Browse files Browse the repository at this point in the history
* 'for-linus' of git://oss.sgi.com/xfs/xfs:
  [XFS] XFS: Check for valid transaction headers in recovery
  [XFS] handle memory allocation failures during log initialisation
  [XFS] Account for allocated blocks when expanding directories
  [XFS] Wait for all I/O on truncate to zero file size
  [XFS] Fix use-after-free with log and quotas
  • Loading branch information
Linus Torvalds committed Nov 11, 2008
2 parents ad1164b + 220ca31 commit 04ca2c1
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 7 deletions.
5 changes: 5 additions & 0 deletions fs/xfs/xfs_da_btree.c
Original file line number Diff line number Diff line change
Expand Up @@ -1566,11 +1566,14 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
int nmap, error, w, count, c, got, i, mapi;
xfs_trans_t *tp;
xfs_mount_t *mp;
xfs_drfsbno_t nblks;

dp = args->dp;
mp = dp->i_mount;
w = args->whichfork;
tp = args->trans;
nblks = dp->i_d.di_nblocks;

/*
* For new directories adjust the file offset and block count.
*/
Expand Down Expand Up @@ -1647,6 +1650,8 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
}
if (mapp != &map)
kmem_free(mapp);
/* account for newly allocated blocks in reserved blocks total */
args->total -= dp->i_d.di_nblocks - nblks;
*new_blkno = (xfs_dablk_t)bno;
return 0;
}
Expand Down
6 changes: 6 additions & 0 deletions fs/xfs/xfs_dir2.c
Original file line number Diff line number Diff line change
Expand Up @@ -525,11 +525,13 @@ xfs_dir2_grow_inode(
xfs_mount_t *mp;
int nmap; /* number of bmap entries */
xfs_trans_t *tp;
xfs_drfsbno_t nblks;

xfs_dir2_trace_args_s("grow_inode", args, space);
dp = args->dp;
tp = args->trans;
mp = dp->i_mount;
nblks = dp->i_d.di_nblocks;
/*
* Set lowest possible block in the space requested.
*/
Expand Down Expand Up @@ -622,7 +624,11 @@ xfs_dir2_grow_inode(
*/
if (mapp != &map)
kmem_free(mapp);

/* account for newly allocated blocks in reserved blocks total */
args->total -= dp->i_d.di_nblocks - nblks;
*dbp = xfs_dir2_da_to_db(mp, (xfs_dablk_t)bno);

/*
* Update file's size if this is the data space and it grew.
*/
Expand Down
2 changes: 1 addition & 1 deletion fs/xfs/xfs_inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1414,7 +1414,7 @@ xfs_itruncate_start(
mp = ip->i_mount;

/* wait for the completion of any pending DIOs */
if (new_size < ip->i_size)
if (new_size == 0 || new_size < ip->i_size)
vn_iowait(ip);

/*
Expand Down
39 changes: 36 additions & 3 deletions fs/xfs/xfs_log.c
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,11 @@ xfs_log_mount(
}

mp->m_log = xlog_alloc_log(mp, log_target, blk_offset, num_bblks);
if (!mp->m_log) {
cmn_err(CE_WARN, "XFS: Log allocation failed: No memory!");
error = ENOMEM;
goto out;
}

/*
* Initialize the AIL now we have a log.
Expand Down Expand Up @@ -601,6 +606,7 @@ xfs_log_mount(
return 0;
error:
xfs_log_unmount_dealloc(mp);
out:
return error;
} /* xfs_log_mount */

Expand Down Expand Up @@ -1217,7 +1223,9 @@ xlog_alloc_log(xfs_mount_t *mp,
int i;
int iclogsize;

log = (xlog_t *)kmem_zalloc(sizeof(xlog_t), KM_SLEEP);
log = kmem_zalloc(sizeof(xlog_t), KM_MAYFAIL);
if (!log)
return NULL;

log->l_mp = mp;
log->l_targ = log_target;
Expand Down Expand Up @@ -1249,6 +1257,8 @@ xlog_alloc_log(xfs_mount_t *mp,
xlog_get_iclog_buffer_size(mp, log);

bp = xfs_buf_get_empty(log->l_iclog_size, mp->m_logdev_targp);
if (!bp)
goto out_free_log;
XFS_BUF_SET_IODONE_FUNC(bp, xlog_iodone);
XFS_BUF_SET_BDSTRAT_FUNC(bp, xlog_bdstrat_cb);
XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)1);
Expand All @@ -1275,13 +1285,17 @@ xlog_alloc_log(xfs_mount_t *mp,
iclogsize = log->l_iclog_size;
ASSERT(log->l_iclog_size >= 4096);
for (i=0; i < log->l_iclog_bufs; i++) {
*iclogp = (xlog_in_core_t *)
kmem_zalloc(sizeof(xlog_in_core_t), KM_SLEEP);
*iclogp = kmem_zalloc(sizeof(xlog_in_core_t), KM_MAYFAIL);
if (!*iclogp)
goto out_free_iclog;

iclog = *iclogp;
iclog->ic_prev = prev_iclog;
prev_iclog = iclog;

bp = xfs_buf_get_noaddr(log->l_iclog_size, mp->m_logdev_targp);
if (!bp)
goto out_free_iclog;
if (!XFS_BUF_CPSEMA(bp))
ASSERT(0);
XFS_BUF_SET_IODONE_FUNC(bp, xlog_iodone);
Expand Down Expand Up @@ -1323,6 +1337,25 @@ xlog_alloc_log(xfs_mount_t *mp,
log->l_iclog->ic_prev = prev_iclog; /* re-write 1st prev ptr */

return log;

out_free_iclog:
for (iclog = log->l_iclog; iclog; iclog = prev_iclog) {
prev_iclog = iclog->ic_next;
if (iclog->ic_bp) {
sv_destroy(&iclog->ic_force_wait);
sv_destroy(&iclog->ic_write_wait);
xfs_buf_free(iclog->ic_bp);
xlog_trace_iclog_dealloc(iclog);
}
kmem_free(iclog);
}
spinlock_destroy(&log->l_icloglock);
spinlock_destroy(&log->l_grant_lock);
xlog_trace_loggrant_dealloc(log);
xfs_buf_free(log->l_xbuf);
out_free_log:
kmem_free(log);
return NULL;
} /* xlog_alloc_log */


Expand Down
8 changes: 7 additions & 1 deletion fs/xfs/xfs_log_recover.c
Original file line number Diff line number Diff line change
Expand Up @@ -1419,7 +1419,13 @@ xlog_recover_add_to_trans(
return 0;
item = trans->r_itemq;
if (item == NULL) {
ASSERT(*(uint *)dp == XFS_TRANS_HEADER_MAGIC);
/* we need to catch log corruptions here */
if (*(uint *)dp != XFS_TRANS_HEADER_MAGIC) {
xlog_warn("XFS: xlog_recover_add_to_trans: "
"bad header magic number");
ASSERT(0);
return XFS_ERROR(EIO);
}
if (len == sizeof(xfs_trans_header_t))
xlog_recover_add_item(&trans->r_itemq);
memcpy(&trans->r_theader, dp, len); /* d, s, l */
Expand Down
5 changes: 3 additions & 2 deletions fs/xfs/xfs_mount.c
Original file line number Diff line number Diff line change
Expand Up @@ -1245,6 +1245,9 @@ xfs_unmountfs(

XFS_QM_DQPURGEALL(mp, XFS_QMOPT_QUOTALL | XFS_QMOPT_UMOUNTING);

if (mp->m_quotainfo)
XFS_QM_DONE(mp);

/*
* Flush out the log synchronously so that we know for sure
* that nothing is pinned. This is important because bflush()
Expand Down Expand Up @@ -1297,8 +1300,6 @@ xfs_unmountfs(
xfs_errortag_clearall(mp, 0);
#endif
xfs_free_perag(mp);
if (mp->m_quotainfo)
XFS_QM_DONE(mp);
}

STATIC void
Expand Down

0 comments on commit 04ca2c1

Please sign in to comment.