2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-12-15 16:53:54 +08:00

xfs: bugfixes for 3.6-rc7

- fix a regression related to xfs_sync_worker racing with unmount.
 - fix a race while discarding xfs buffers.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.10 (GNU/Linux)
 
 iQIcBAABAgAGBQJQWO3uAAoJENaLyazVq6ZOjfcP+gJkcJLS5+qmyNEcW2IUH0+E
 4WptMdBCLgZGa54aGAJ2mwg0FysyyTiTXjOSETRiBU+N3bAhgweucRsxc8z+awen
 L+InHr8YgQyAoY0nhEcXI/EuHaF9OlgVT6YCOqr/V4gtLO+aczovQS1wA3w/pjAk
 RWa4z+VlH+D9KenatoCcHSY6PIPO9pLs4Gfb7D/9BLFN+f6OnIaUlkwIQSuumuaw
 Lt/sw24/FEBYyzspmGfJT1fjDZK4VI4QoPEAVuvGiJCGFzSW2RDmlb48ZXsnGBbM
 f83tKjB7praQhXnBt56/S5YThgWzt8eaJVIhSExtEh1tisb5iWNQzVPk+USXUE9t
 DNTxtJjwiECbslyVYkTDUKnhdPGtHkpQSN96RBUDvQYfoLHQ/aXbxfPIZGEt24YM
 A/TbCFDFQrI91Rn3TkAxygvfOkxWxE9TB1PmwfgrJGFDWNxg84OBiCX9IMNi3NUF
 glqoKn6aI5fZH6gHVU7xA+bnfJYYRIxUtgIHJ1sYH6dH185G5Yj3m9bojcN7DnmM
 x1kLf0lscumgdB3OGLgpe5IrrFKM+ncclkS24X3eWOCvnWiEXBwajPqA8LloekZA
 X+IyGhoSfg2yRJAYEipRD+H0XouNM/AsLMcI/VbEoLGebxpsKCkg0VwCbd/4xISO
 90Q9jWXC4dzUVRc60rPw
 =ZcGP
 -----END PGP SIGNATURE-----

Merge tag 'for-linus-v3.6-rc7' of git://oss.sgi.com/xfs/xfs

Pull xfs bugfixes from Ben Myers:
 - fix a regression related to xfs_sync_worker racing with unmount.
 - fix a race while discarding xfs buffers.

* tag 'for-linus-v3.6-rc7' of git://oss.sgi.com/xfs/xfs:
  xfs: stop the sync worker before xfs_unmountfs
  xfs: fix race while discarding buffers [V4]
This commit is contained in:
Linus Torvalds 2012-09-21 12:43:01 -07:00
commit 789f95b788
3 changed files with 29 additions and 18 deletions

View File

@ -96,6 +96,7 @@ xfs_buf_lru_add(
atomic_inc(&bp->b_hold); atomic_inc(&bp->b_hold);
list_add_tail(&bp->b_lru, &btp->bt_lru); list_add_tail(&bp->b_lru, &btp->bt_lru);
btp->bt_lru_nr++; btp->bt_lru_nr++;
bp->b_lru_flags &= ~_XBF_LRU_DISPOSE;
} }
spin_unlock(&btp->bt_lru_lock); spin_unlock(&btp->bt_lru_lock);
} }
@ -154,7 +155,8 @@ xfs_buf_stale(
struct xfs_buftarg *btp = bp->b_target; struct xfs_buftarg *btp = bp->b_target;
spin_lock(&btp->bt_lru_lock); spin_lock(&btp->bt_lru_lock);
if (!list_empty(&bp->b_lru)) { if (!list_empty(&bp->b_lru) &&
!(bp->b_lru_flags & _XBF_LRU_DISPOSE)) {
list_del_init(&bp->b_lru); list_del_init(&bp->b_lru);
btp->bt_lru_nr--; btp->bt_lru_nr--;
atomic_dec(&bp->b_hold); atomic_dec(&bp->b_hold);
@ -1501,6 +1503,7 @@ xfs_buftarg_shrink(
*/ */
list_move(&bp->b_lru, &dispose); list_move(&bp->b_lru, &dispose);
btp->bt_lru_nr--; btp->bt_lru_nr--;
bp->b_lru_flags |= _XBF_LRU_DISPOSE;
} }
spin_unlock(&btp->bt_lru_lock); spin_unlock(&btp->bt_lru_lock);

View File

@ -38,27 +38,28 @@ typedef enum {
XBRW_ZERO = 3, /* Zero target memory */ XBRW_ZERO = 3, /* Zero target memory */
} xfs_buf_rw_t; } xfs_buf_rw_t;
#define XBF_READ (1 << 0) /* buffer intended for reading from device */ #define XBF_READ (1 << 0) /* buffer intended for reading from device */
#define XBF_WRITE (1 << 1) /* buffer intended for writing to device */ #define XBF_WRITE (1 << 1) /* buffer intended for writing to device */
#define XBF_READ_AHEAD (1 << 2) /* asynchronous read-ahead */ #define XBF_READ_AHEAD (1 << 2) /* asynchronous read-ahead */
#define XBF_ASYNC (1 << 4) /* initiator will not wait for completion */ #define XBF_ASYNC (1 << 4) /* initiator will not wait for completion */
#define XBF_DONE (1 << 5) /* all pages in the buffer uptodate */ #define XBF_DONE (1 << 5) /* all pages in the buffer uptodate */
#define XBF_STALE (1 << 6) /* buffer has been staled, do not find it */ #define XBF_STALE (1 << 6) /* buffer has been staled, do not find it */
/* I/O hints for the BIO layer */ /* I/O hints for the BIO layer */
#define XBF_SYNCIO (1 << 10)/* treat this buffer as synchronous I/O */ #define XBF_SYNCIO (1 << 10)/* treat this buffer as synchronous I/O */
#define XBF_FUA (1 << 11)/* force cache write through mode */ #define XBF_FUA (1 << 11)/* force cache write through mode */
#define XBF_FLUSH (1 << 12)/* flush the disk cache before a write */ #define XBF_FLUSH (1 << 12)/* flush the disk cache before a write */
/* flags used only as arguments to access routines */ /* flags used only as arguments to access routines */
#define XBF_TRYLOCK (1 << 16)/* lock requested, but do not wait */ #define XBF_TRYLOCK (1 << 16)/* lock requested, but do not wait */
#define XBF_UNMAPPED (1 << 17)/* do not map the buffer */ #define XBF_UNMAPPED (1 << 17)/* do not map the buffer */
/* flags used only internally */ /* flags used only internally */
#define _XBF_PAGES (1 << 20)/* backed by refcounted pages */ #define _XBF_PAGES (1 << 20)/* backed by refcounted pages */
#define _XBF_KMEM (1 << 21)/* backed by heap memory */ #define _XBF_KMEM (1 << 21)/* backed by heap memory */
#define _XBF_DELWRI_Q (1 << 22)/* buffer on a delwri queue */ #define _XBF_DELWRI_Q (1 << 22)/* buffer on a delwri queue */
#define _XBF_COMPOUND (1 << 23)/* compound buffer */ #define _XBF_COMPOUND (1 << 23)/* compound buffer */
#define _XBF_LRU_DISPOSE (1 << 24)/* buffer being discarded */
typedef unsigned int xfs_buf_flags_t; typedef unsigned int xfs_buf_flags_t;
@ -72,12 +73,13 @@ typedef unsigned int xfs_buf_flags_t;
{ XBF_SYNCIO, "SYNCIO" }, \ { XBF_SYNCIO, "SYNCIO" }, \
{ XBF_FUA, "FUA" }, \ { XBF_FUA, "FUA" }, \
{ XBF_FLUSH, "FLUSH" }, \ { XBF_FLUSH, "FLUSH" }, \
{ XBF_TRYLOCK, "TRYLOCK" }, /* should never be set */\ { XBF_TRYLOCK, "TRYLOCK" }, /* should never be set */\
{ XBF_UNMAPPED, "UNMAPPED" }, /* ditto */\ { XBF_UNMAPPED, "UNMAPPED" }, /* ditto */\
{ _XBF_PAGES, "PAGES" }, \ { _XBF_PAGES, "PAGES" }, \
{ _XBF_KMEM, "KMEM" }, \ { _XBF_KMEM, "KMEM" }, \
{ _XBF_DELWRI_Q, "DELWRI_Q" }, \ { _XBF_DELWRI_Q, "DELWRI_Q" }, \
{ _XBF_COMPOUND, "COMPOUND" } { _XBF_COMPOUND, "COMPOUND" }, \
{ _XBF_LRU_DISPOSE, "LRU_DISPOSE" }
typedef struct xfs_buftarg { typedef struct xfs_buftarg {
dev_t bt_dev; dev_t bt_dev;
@ -124,7 +126,12 @@ typedef struct xfs_buf {
xfs_buf_flags_t b_flags; /* status flags */ xfs_buf_flags_t b_flags; /* status flags */
struct semaphore b_sema; /* semaphore for lockables */ struct semaphore b_sema; /* semaphore for lockables */
/*
* concurrent access to b_lru and b_lru_flags are protected by
* bt_lru_lock and not by b_sema
*/
struct list_head b_lru; /* lru list */ struct list_head b_lru; /* lru list */
xfs_buf_flags_t b_lru_flags; /* internal lru status flags */
wait_queue_head_t b_waiters; /* unpin waiters */ wait_queue_head_t b_waiters; /* unpin waiters */
struct list_head b_list; struct list_head b_list;
struct xfs_perag *b_pag; /* contains rbtree root */ struct xfs_perag *b_pag; /* contains rbtree root */

View File

@ -919,6 +919,7 @@ xfs_fs_put_super(
struct xfs_mount *mp = XFS_M(sb); struct xfs_mount *mp = XFS_M(sb);
xfs_filestream_unmount(mp); xfs_filestream_unmount(mp);
cancel_delayed_work_sync(&mp->m_sync_work);
xfs_unmountfs(mp); xfs_unmountfs(mp);
xfs_syncd_stop(mp); xfs_syncd_stop(mp);
xfs_freesb(mp); xfs_freesb(mp);