未验证 提交 fcd81227 编写于 作者: O openeuler-ci-bot 提交者: Gitee

!1344 [sync] PR-1272: xfs: fix some problems recently

Merge Pull Request from: @openeuler-sync-bot 
 

Origin pull request: 
https://gitee.com/openeuler/kernel/pulls/1272 
 
PR sync from: Long Li <leo.lilong@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/W6KN2XSLJE5HZR2Y5D2OTDQ2GTLDGC5O/ 
Patchs 1-6 fix some problems recently.
Patchs 7-8 backport from mainline.

Darrick J. Wong (1):
  xfs: fix uninitialized variable access

Dave Chinner (1):
  xfs: set XFS_FEAT_NLINK correctly

Long Li (4):
  xfs: factor out xfs_defer_pending_abort
  xfs: don't leak intent item when recovery intents fail
  xfs: factor out xfs_destroy_perag()
  xfs: don't leak perag when growfs fails

Ye Bin (1):
  xfs: fix warning in xfs_vm_writepages()

yangerkun (1):
  xfs: fix mounting failed caused by sequencing problem in the log
    records


-- 
2.31.1
 
 
Link:https://gitee.com/openeuler/kernel/pulls/1344 

Reviewed-by: Jialin Zhang <zhangjialin11@huawei.com> 
Signed-off-by: Jialin Zhang <zhangjialin11@huawei.com> 
...@@ -210,21 +210,18 @@ xfs_defer_create_intents( ...@@ -210,21 +210,18 @@ xfs_defer_create_intents(
} }
} }
/* Abort all the intents that were committed. */ void
STATIC void xfs_defer_pending_abort(
xfs_defer_trans_abort( struct xfs_mount *mp,
struct xfs_trans *tp, struct list_head *dop_list)
struct list_head *dop_pending)
{ {
struct xfs_defer_pending *dfp; struct xfs_defer_pending *dfp;
const struct xfs_defer_op_type *ops; const struct xfs_defer_op_type *ops;
trace_xfs_defer_trans_abort(tp, _RET_IP_);
/* Abort intent items that don't have a done item. */ /* Abort intent items that don't have a done item. */
list_for_each_entry(dfp, dop_pending, dfp_list) { list_for_each_entry(dfp, dop_list, dfp_list) {
ops = defer_op_types[dfp->dfp_type]; ops = defer_op_types[dfp->dfp_type];
trace_xfs_defer_pending_abort(tp->t_mountp, dfp); trace_xfs_defer_pending_abort(mp, dfp);
if (dfp->dfp_intent && !dfp->dfp_done) { if (dfp->dfp_intent && !dfp->dfp_done) {
ops->abort_intent(dfp->dfp_intent); ops->abort_intent(dfp->dfp_intent);
dfp->dfp_intent = NULL; dfp->dfp_intent = NULL;
...@@ -232,6 +229,16 @@ xfs_defer_trans_abort( ...@@ -232,6 +229,16 @@ xfs_defer_trans_abort(
} }
} }
/* Abort all the intents that were committed. */
STATIC void
xfs_defer_trans_abort(
struct xfs_trans *tp,
struct list_head *dop_pending)
{
trace_xfs_defer_trans_abort(tp, _RET_IP_);
xfs_defer_pending_abort(tp->t_mountp, dop_pending);
}
/* Roll a transaction so we can do some deferred op processing. */ /* Roll a transaction so we can do some deferred op processing. */
STATIC int STATIC int
xfs_defer_trans_roll( xfs_defer_trans_roll(
...@@ -706,6 +713,7 @@ xfs_defer_ops_capture_and_commit( ...@@ -706,6 +713,7 @@ xfs_defer_ops_capture_and_commit(
/* Commit the transaction and add the capture structure to the list. */ /* Commit the transaction and add the capture structure to the list. */
error = xfs_trans_commit(tp); error = xfs_trans_commit(tp);
if (error) { if (error) {
xfs_defer_pending_abort(mp, &dfc->dfc_dfops);
xfs_defer_ops_release(mp, dfc); xfs_defer_ops_release(mp, dfc);
return error; return error;
} }
......
...@@ -36,6 +36,7 @@ struct xfs_defer_pending { ...@@ -36,6 +36,7 @@ struct xfs_defer_pending {
enum xfs_defer_ops_type dfp_type; enum xfs_defer_ops_type dfp_type;
}; };
void xfs_defer_pending_abort(struct xfs_mount *mp, struct list_head *dop_list);
void xfs_defer_add(struct xfs_trans *tp, enum xfs_defer_ops_type type, void xfs_defer_add(struct xfs_trans *tp, enum xfs_defer_ops_type type,
struct list_head *h); struct list_head *h);
int xfs_defer_finish_noroll(struct xfs_trans **tp); int xfs_defer_finish_noroll(struct xfs_trans **tp);
......
...@@ -18,6 +18,7 @@ enum xlog_recover_reorder { ...@@ -18,6 +18,7 @@ enum xlog_recover_reorder {
XLOG_REORDER_ITEM_LIST, XLOG_REORDER_ITEM_LIST,
XLOG_REORDER_INODE_BUFFER_LIST, XLOG_REORDER_INODE_BUFFER_LIST,
XLOG_REORDER_CANCEL_LIST, XLOG_REORDER_CANCEL_LIST,
XLOG_REORDER_SB_BUFFER_LIST,
}; };
struct xlog_recover_item_ops { struct xlog_recover_item_ops {
......
...@@ -70,6 +70,8 @@ xfs_sb_version_to_features( ...@@ -70,6 +70,8 @@ xfs_sb_version_to_features(
/* optional V4 features */ /* optional V4 features */
if (sbp->sb_rblocks > 0) if (sbp->sb_rblocks > 0)
features |= XFS_FEAT_REALTIME; features |= XFS_FEAT_REALTIME;
if (sbp->sb_versionnum & XFS_SB_VERSION_NLINKBIT)
features |= XFS_FEAT_NLINK;
if (sbp->sb_versionnum & XFS_SB_VERSION_ATTRBIT) if (sbp->sb_versionnum & XFS_SB_VERSION_ATTRBIT)
features |= XFS_FEAT_ATTR; features |= XFS_FEAT_ATTR;
if (sbp->sb_versionnum & XFS_SB_VERSION_QUOTABIT) if (sbp->sb_versionnum & XFS_SB_VERSION_QUOTABIT)
......
...@@ -162,6 +162,8 @@ xlog_recover_buf_reorder( ...@@ -162,6 +162,8 @@ xlog_recover_buf_reorder(
return XLOG_REORDER_CANCEL_LIST; return XLOG_REORDER_CANCEL_LIST;
if (buf_f->blf_flags & XFS_BLF_INODE_BUF) if (buf_f->blf_flags & XFS_BLF_INODE_BUF)
return XLOG_REORDER_INODE_BUFFER_LIST; return XLOG_REORDER_INODE_BUFFER_LIST;
if (buf_f->blf_blkno == XFS_SB_DADDR)
return XLOG_REORDER_SB_BUFFER_LIST;
return XLOG_REORDER_BUFFER_LIST; return XLOG_REORDER_BUFFER_LIST;
} }
......
...@@ -746,6 +746,7 @@ xfs_getfsmap_datadev_bnobt( ...@@ -746,6 +746,7 @@ xfs_getfsmap_datadev_bnobt(
{ {
struct xfs_alloc_rec_incore akeys[2]; struct xfs_alloc_rec_incore akeys[2];
memset(akeys, 0, sizeof(akeys));
info->missing_owner = XFS_FMR_OWN_UNKNOWN; info->missing_owner = XFS_FMR_OWN_UNKNOWN;
return __xfs_getfsmap_datadev(tp, keys, info, return __xfs_getfsmap_datadev(tp, keys, info,
xfs_getfsmap_datadev_bnobt_query, &akeys[0]); xfs_getfsmap_datadev_bnobt_query, &akeys[0]);
......
...@@ -76,7 +76,7 @@ xfs_growfs_data_private( ...@@ -76,7 +76,7 @@ xfs_growfs_data_private(
error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growdata, error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growdata,
XFS_GROWFS_SPACE_RES(mp), 0, XFS_TRANS_RESERVE, &tp); XFS_GROWFS_SPACE_RES(mp), 0, XFS_TRANS_RESERVE, &tp);
if (error) if (error)
return error; goto destroy_perag;
/* /*
* Write new AG headers to disk. Non-transactional, but need to be * Write new AG headers to disk. Non-transactional, but need to be
...@@ -167,6 +167,9 @@ xfs_growfs_data_private( ...@@ -167,6 +167,9 @@ xfs_growfs_data_private(
out_trans_cancel: out_trans_cancel:
xfs_trans_cancel(tp); xfs_trans_cancel(tp);
destroy_perag:
if (nagcount > oagcount)
xfs_destroy_perag(mp, oagcount, nagcount);
return error; return error;
} }
......
...@@ -534,6 +534,12 @@ xfs_iget_cache_hit( ...@@ -534,6 +534,12 @@ xfs_iget_cache_hit(
if (!igrab(inode)) if (!igrab(inode))
goto out_skip; goto out_skip;
if (!(flags & XFS_IGET_DONTCACHE)) {
spin_lock(&inode->i_lock);
inode->i_state &= ~I_DONTCACHE;
spin_unlock(&inode->i_lock);
}
/* We've got a live one. */ /* We've got a live one. */
spin_unlock(&ip->i_flags_lock); spin_unlock(&ip->i_flags_lock);
rcu_read_unlock(); rcu_read_unlock();
......
...@@ -1879,6 +1879,9 @@ xlog_recover_reorder_trans( ...@@ -1879,6 +1879,9 @@ xlog_recover_reorder_trans(
case XLOG_REORDER_BUFFER_LIST: case XLOG_REORDER_BUFFER_LIST:
list_move_tail(&item->ri_list, &buffer_list); list_move_tail(&item->ri_list, &buffer_list);
break; break;
case XLOG_REORDER_SB_BUFFER_LIST:
list_move(&item->ri_list, &buffer_list);
break;
case XLOG_REORDER_CANCEL_LIST: case XLOG_REORDER_CANCEL_LIST:
trace_xfs_log_recover_item_reorder_head(log, trace_xfs_log_recover_item_reorder_head(log,
trans, item, pass); trans, item, pass);
...@@ -1942,6 +1945,25 @@ xlog_recover_items_pass2( ...@@ -1942,6 +1945,25 @@ xlog_recover_items_pass2(
return error; return error;
} }
#define XLOG_RECOVER_COMMIT_QUEUE_MAX 100
static inline bool
xlog_recover_should_pass2(
struct xlog_recover_item *item,
int items_queued)
{
struct xfs_buf_log_format *buf_f;
if (items_queued >= XLOG_RECOVER_COMMIT_QUEUE_MAX)
return true;
if (ITEM_TYPE(item) == XFS_LI_BUF) {
buf_f = item->ri_buf[0].i_addr;
if (buf_f->blf_blkno == XFS_SB_DADDR)
return true;
}
return false;
}
/* /*
* Perform the transaction. * Perform the transaction.
* *
...@@ -1962,8 +1984,6 @@ xlog_recover_commit_trans( ...@@ -1962,8 +1984,6 @@ xlog_recover_commit_trans(
LIST_HEAD (ra_list); LIST_HEAD (ra_list);
LIST_HEAD (done_list); LIST_HEAD (done_list);
#define XLOG_RECOVER_COMMIT_QUEUE_MAX 100
hlist_del_init(&trans->r_list); hlist_del_init(&trans->r_list);
error = xlog_recover_reorder_trans(log, trans, pass); error = xlog_recover_reorder_trans(log, trans, pass);
...@@ -1983,7 +2003,7 @@ xlog_recover_commit_trans( ...@@ -1983,7 +2003,7 @@ xlog_recover_commit_trans(
item->ri_ops->ra_pass2(log, item); item->ri_ops->ra_pass2(log, item);
list_move_tail(&item->ri_list, &ra_list); list_move_tail(&item->ri_list, &ra_list);
items_queued++; items_queued++;
if (items_queued >= XLOG_RECOVER_COMMIT_QUEUE_MAX) { if (xlog_recover_should_pass2(item, items_queued)) {
error = xlog_recover_items_pass2(log, trans, error = xlog_recover_items_pass2(log, trans,
buffer_list, &ra_list); buffer_list, &ra_list);
list_splice_tail_init(&ra_list, &done_list); list_splice_tail_init(&ra_list, &done_list);
...@@ -2494,6 +2514,7 @@ xlog_abort_defer_ops( ...@@ -2494,6 +2514,7 @@ xlog_abort_defer_ops(
list_for_each_entry_safe(dfc, next, capture_list, dfc_list) { list_for_each_entry_safe(dfc, next, capture_list, dfc_list) {
list_del_init(&dfc->dfc_list); list_del_init(&dfc->dfc_list);
xfs_defer_pending_abort(mp, &dfc->dfc_dfops);
xfs_defer_ops_release(mp, dfc); xfs_defer_ops_release(mp, dfc);
} }
} }
......
...@@ -173,6 +173,27 @@ xfs_sb_validate_fsb_count( ...@@ -173,6 +173,27 @@ xfs_sb_validate_fsb_count(
return 0; return 0;
} }
void
xfs_destroy_perag(
xfs_mount_t *mp,
xfs_agnumber_t agstart,
xfs_agnumber_t agend)
{
xfs_agnumber_t index;
xfs_perag_t *pag;
for (index = agstart; index < agend; index++) {
spin_lock(&mp->m_perag_lock);
pag = radix_tree_delete(&mp->m_perag_tree, index);
spin_unlock(&mp->m_perag_lock);
if (!pag)
break;
xfs_buf_hash_destroy(pag);
xfs_iunlink_destroy(pag);
kmem_free(pag);
}
}
int int
xfs_initialize_perag( xfs_initialize_perag(
xfs_mount_t *mp, xfs_mount_t *mp,
...@@ -252,14 +273,7 @@ xfs_initialize_perag( ...@@ -252,14 +273,7 @@ xfs_initialize_perag(
kmem_free(pag); kmem_free(pag);
out_unwind_new_pags: out_unwind_new_pags:
/* unwind any prior newly initialized pags */ /* unwind any prior newly initialized pags */
for (index = first_initialised; index < agcount; index++) { xfs_destroy_perag(mp, first_initialised, agcount);
pag = radix_tree_delete(&mp->m_perag_tree, index);
if (!pag)
break;
xfs_buf_hash_destroy(pag);
xfs_iunlink_destroy(pag);
kmem_free(pag);
}
return error; return error;
} }
......
...@@ -564,6 +564,8 @@ extern void xfs_uuid_table_free(void); ...@@ -564,6 +564,8 @@ extern void xfs_uuid_table_free(void);
extern int xfs_log_sbcount(xfs_mount_t *); extern int xfs_log_sbcount(xfs_mount_t *);
extern uint64_t xfs_default_resblks(xfs_mount_t *mp); extern uint64_t xfs_default_resblks(xfs_mount_t *mp);
extern int xfs_mountfs(xfs_mount_t *mp); extern int xfs_mountfs(xfs_mount_t *mp);
extern void xfs_destroy_perag(xfs_mount_t *mp, xfs_agnumber_t agstart,
xfs_agnumber_t agend);
extern int xfs_initialize_perag(xfs_mount_t *mp, xfs_agnumber_t agcount, extern int xfs_initialize_perag(xfs_mount_t *mp, xfs_agnumber_t agcount,
xfs_agnumber_t *maxagi); xfs_agnumber_t *maxagi);
extern void xfs_unmountfs(xfs_mount_t *); extern void xfs_unmountfs(xfs_mount_t *);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册