xfs: bulkstat doesn't release AGI buffer on error
PATCH 1/1 xfs: bulkstat doesn't release AGI buffer on error
From: Dave Chinner <[email protected]>
The recent refactoring of the bulkstat code left a small landmine in the code. If a inobt read fails, then the tree walk is aborted and returns without releasing the AGI buffer or freeing the cursor. This can lead to a subsequent bulkstat call hanging trying to grab the AGI buffer again.
--- fs/xfs/xfs_itable.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
fs/xfs/xfs_itable.c +10 -6
@@ -427,7 +427,7 @@ xfs_bulkstat( error =xfs_bulkstat_grab_ichunk (cur, agino, &icount, &r);if (error) -break ; + goto del_cursor;if (icount) { irbp->ir_startino = r.ir_startino; irbp->ir_freecount = r.ir_freecount;
@@ -442,7 +442,7 @@ xfs_bulkstat( error =xfs_inobt_lookup (cur,0 ,XFS_LOOKUP_GE , &tmp); }if (error) -break ; + goto del_cursor;/* * Loop through inode btree records in this ag,
@@ -454,7 +454,7 @@ xfs_bulkstat( error =xfs_inobt_get_rec (cur, &r, &i);if (error || i ==0 ) { end_of_ag =1 ; -break ; + goto del_cursor; }/*
@@ -476,13 +476,17 @@ xfs_bulkstat( error =xfs_btree_increment (cur,0 , &tmp);cond_resched (); } +/* -* Drop the btree buffers and the agi buffer. -* We can't hold any of the locks these represent -* when calling iget. +* Drop the btree buffers and the agi buffer as we can't hold any +* of the locks these represent when calling iget. If there is a +* pending error, then we are done. */ +del_cursor:xfs_btree_del_cursor (cur,XFS_BTREE_NOERROR );xfs_buf_relse (agbp); +if (error) +break ;/* * Now format all the good inodes into the user's buffer. */
Signature · 6 lines
2.0.0 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Quoted 10 lines · Dave Chinner
From: Dave Chinner <[email protected]>
The recent refactoring of the bulkstat code left a small landmine in the code. If a inobt read fails, then the tree walk is aborted and returns without releasing the AGI buffer or freeing the cursor. This can lead to a subsequent bulkstat call hanging trying to grab the AGI buffer again.
Signed-off-by Dave Chinner <[email protected]>---
Quoted 62 lines
fs/xfs/xfs_itable.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)fs/xfs/xfs_itable.c +10
-6@@ -427,7 +427,7 @@ xfs_bulkstat( error =xfs_bulkstat_grab_ichunk (cur, agino, &icount, &r);if (error) -break ; + goto del_cursor;if (icount) { irbp->ir_startino = r.ir_startino; irbp->ir_freecount = r.ir_freecount;@@ -442,7 +442,7 @@ xfs_bulkstat( error =xfs_inobt_lookup (cur,0 ,XFS_LOOKUP_GE , &tmp); }if (error) -break ; + goto del_cursor;/* * Loop through inode btree records in this ag, @@ -454,7 +454,7 @@ xfs_bulkstat( error =xfs_inobt_get_rec (cur, &r, &i);if (error || i ==0 ) { end_of_ag =1 ; -break ; + goto del_cursor; }/* @@ -476,13 +476,17 @@ xfs_bulkstat( error =xfs_btree_increment (cur,0 , &tmp);cond_resched (); } +/* -* Drop the btree buffers and the agi buffer. -* We can't hold any of the locks these represent -* when calling iget. +* Drop the btree buffers and the agi buffer as we can't hold any +* of the locks these represent when calling iget. If there is a +* pending error, then we are done. */ +del_cursor:xfs_btree_del_cursor (cur,XFS_BTREE_NOERROR );xfs_buf_relse (agbp); +if (error) +break ;/* * Now format all the good inodes into the user's buffer. */ Signature · 6 lines
2.0.0 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Quoted 9 lines · Dave Chinner
From: Dave Chinner <[email protected]>
The recent refactoring of the bulkstat code left a small landmine in the code. If a inobt read fails, then the tree walk is aborted and returns without releasing the AGI buffer or freeing the cursor. This can lead to a subsequent bulkstat call hanging trying to grab the AGI buffer again.
Signed-off-by Dave Chinner <[email protected]>
Can you add a cc: stable, too?
Quoted 47 lines
--- fs/xfs/xfs_itable.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)fs/xfs/xfs_itable.c +6
-6@@ -427,7 +427,7 @@ xfs_bulkstat( error =xfs_bulkstat_grab_ichunk (cur, agino, &icount, &r);if (error) -break ; + goto del_cursor;if (icount) { irbp->ir_startino = r.ir_startino; irbp->ir_freecount = r.ir_freecount;@@ -442,7 +442,7 @@ xfs_bulkstat( error =xfs_inobt_lookup (cur,0 ,XFS_LOOKUP_GE , &tmp); }if (error) -break ; + goto del_cursor;/* * Loop through inode btree records in this ag, @@ -454,7 +454,7 @@ xfs_bulkstat( error =xfs_inobt_get_rec (cur, &r, &i);if (error || i ==0 ) { end_of_ag =1 ; -break ; + goto del_cursor; }/* @@ -476,13 +476,17 @@ xfs_bulkstat( error =xfs_btree_increment (cur,0 , &tmp);cond_resched (); } +/* -* Drop the btree buffers and the agi buffer. -* We can't hold any of the locks these represent -* when calling iget. +* Drop the btree buffers and the agi buffer as we can't hold any +* of the locks these represent when calling iget. If there is a
fs/xfs/xfs_itable.c xfs_bulkstat( · line 492
Quoted 10 lines
fs/xfs/xfs_itable.c +4
-0+* pending error, then we are done. */ +del_cursor:xfs_btree_del_cursor (cur,XFS_BTREE_NOERROR );xfs_buf_relse (agbp); +if (error) +break ;/* * Now format all the good inodes into the user's buffer. */
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs