diff options
author | Christoph Hellwig <hch@infradead.org> | 2012-04-23 01:58:37 -0400 |
---|---|---|
committer | Ben Myers <bpm@sgi.com> | 2012-05-14 17:20:29 -0400 |
commit | fe7257fd4b8ae9a3e354d9edb61890973e373ef0 (patch) | |
tree | 471b9ecc1cb21207cb95291d1ec5b81c393b060f | |
parent | 4c46819a8097a75d3b378c5e56d2bcf47bb7408d (diff) |
xfs: do not write the buffer from xfs_qm_dqflush
Instead of writing the buffer directly from inside xfs_qm_dqflush return it
to the caller and let the caller decide what to do with the buffer. Also
remove the pincount check in xfs_qm_dqflush that all non-blocking callers
already implement and the now unused flags parameter and the XFS_DQ_IS_DIRTY
check that all callers already perform.
[ Dave Chinner: fixed build error cause by missing '{'. ]
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
-rw-r--r-- | fs/xfs/xfs_dquot.c | 43 | ||||
-rw-r--r-- | fs/xfs/xfs_dquot.h | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_dquot_item.c | 21 | ||||
-rw-r--r-- | fs/xfs/xfs_qm.c | 25 |
4 files changed, 53 insertions, 38 deletions
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index 786a61e1cccd..53757d83e4f6 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c | |||
@@ -878,8 +878,8 @@ xfs_qm_dqflush_done( | |||
878 | */ | 878 | */ |
879 | int | 879 | int |
880 | xfs_qm_dqflush( | 880 | xfs_qm_dqflush( |
881 | xfs_dquot_t *dqp, | 881 | struct xfs_dquot *dqp, |
882 | uint flags) | 882 | struct xfs_buf **bpp) |
883 | { | 883 | { |
884 | struct xfs_mount *mp = dqp->q_mount; | 884 | struct xfs_mount *mp = dqp->q_mount; |
885 | struct xfs_buf *bp; | 885 | struct xfs_buf *bp; |
@@ -891,14 +891,8 @@ xfs_qm_dqflush( | |||
891 | 891 | ||
892 | trace_xfs_dqflush(dqp); | 892 | trace_xfs_dqflush(dqp); |
893 | 893 | ||
894 | /* | 894 | *bpp = NULL; |
895 | * If not dirty, or it's pinned and we are not supposed to block, nada. | 895 | |
896 | */ | ||
897 | if (!XFS_DQ_IS_DIRTY(dqp) || | ||
898 | ((flags & SYNC_TRYLOCK) && atomic_read(&dqp->q_pincount) > 0)) { | ||
899 | xfs_dqfunlock(dqp); | ||
900 | return 0; | ||
901 | } | ||
902 | xfs_qm_dqunpin_wait(dqp); | 896 | xfs_qm_dqunpin_wait(dqp); |
903 | 897 | ||
904 | /* | 898 | /* |
@@ -918,9 +912,8 @@ xfs_qm_dqflush( | |||
918 | xfs_trans_ail_delete(mp->m_ail, lip); | 912 | xfs_trans_ail_delete(mp->m_ail, lip); |
919 | else | 913 | else |
920 | spin_unlock(&mp->m_ail->xa_lock); | 914 | spin_unlock(&mp->m_ail->xa_lock); |
921 | 915 | error = XFS_ERROR(EIO); | |
922 | xfs_dqfunlock(dqp); | 916 | goto out_unlock; |
923 | return XFS_ERROR(EIO); | ||
924 | } | 917 | } |
925 | 918 | ||
926 | /* | 919 | /* |
@@ -928,11 +921,8 @@ xfs_qm_dqflush( | |||
928 | */ | 921 | */ |
929 | error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, dqp->q_blkno, | 922 | error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, dqp->q_blkno, |
930 | mp->m_quotainfo->qi_dqchunklen, 0, &bp); | 923 | mp->m_quotainfo->qi_dqchunklen, 0, &bp); |
931 | if (error) { | 924 | if (error) |
932 | ASSERT(error != ENOENT); | 925 | goto out_unlock; |
933 | xfs_dqfunlock(dqp); | ||
934 | return error; | ||
935 | } | ||
936 | 926 | ||
937 | /* | 927 | /* |
938 | * Calculate the location of the dquot inside the buffer. | 928 | * Calculate the location of the dquot inside the buffer. |
@@ -978,20 +968,13 @@ xfs_qm_dqflush( | |||
978 | xfs_log_force(mp, 0); | 968 | xfs_log_force(mp, 0); |
979 | } | 969 | } |
980 | 970 | ||
981 | if (flags & SYNC_WAIT) | ||
982 | error = xfs_bwrite(bp); | ||
983 | else | ||
984 | xfs_buf_delwri_queue(bp); | ||
985 | |||
986 | xfs_buf_relse(bp); | ||
987 | |||
988 | trace_xfs_dqflush_done(dqp); | 971 | trace_xfs_dqflush_done(dqp); |
972 | *bpp = bp; | ||
973 | return 0; | ||
989 | 974 | ||
990 | /* | 975 | out_unlock: |
991 | * dqp is still locked, but caller is free to unlock it now. | 976 | xfs_dqfunlock(dqp); |
992 | */ | 977 | return XFS_ERROR(EIO); |
993 | return error; | ||
994 | |||
995 | } | 978 | } |
996 | 979 | ||
997 | /* | 980 | /* |
diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h index ef9190bd8b30..5f2a2f2c0c5b 100644 --- a/fs/xfs/xfs_dquot.h +++ b/fs/xfs/xfs_dquot.h | |||
@@ -141,7 +141,7 @@ static inline xfs_dquot_t *xfs_inode_dquot(struct xfs_inode *ip, int type) | |||
141 | extern int xfs_qm_dqread(struct xfs_mount *, xfs_dqid_t, uint, | 141 | extern int xfs_qm_dqread(struct xfs_mount *, xfs_dqid_t, uint, |
142 | uint, struct xfs_dquot **); | 142 | uint, struct xfs_dquot **); |
143 | extern void xfs_qm_dqdestroy(xfs_dquot_t *); | 143 | extern void xfs_qm_dqdestroy(xfs_dquot_t *); |
144 | extern int xfs_qm_dqflush(xfs_dquot_t *, uint); | 144 | extern int xfs_qm_dqflush(struct xfs_dquot *, struct xfs_buf **); |
145 | extern void xfs_qm_dqunpin_wait(xfs_dquot_t *); | 145 | extern void xfs_qm_dqunpin_wait(xfs_dquot_t *); |
146 | extern void xfs_qm_adjust_dqtimers(xfs_mount_t *, | 146 | extern void xfs_qm_adjust_dqtimers(xfs_mount_t *, |
147 | xfs_disk_dquot_t *); | 147 | xfs_disk_dquot_t *); |
diff --git a/fs/xfs/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c index 34baeae45265..8d8295814272 100644 --- a/fs/xfs/xfs_dquot_item.c +++ b/fs/xfs/xfs_dquot_item.c | |||
@@ -119,10 +119,12 @@ xfs_qm_dquot_logitem_push( | |||
119 | struct xfs_log_item *lip) | 119 | struct xfs_log_item *lip) |
120 | { | 120 | { |
121 | struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot; | 121 | struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot; |
122 | struct xfs_buf *bp = NULL; | ||
122 | int error; | 123 | int error; |
123 | 124 | ||
124 | ASSERT(XFS_DQ_IS_LOCKED(dqp)); | 125 | ASSERT(XFS_DQ_IS_LOCKED(dqp)); |
125 | ASSERT(!completion_done(&dqp->q_flush)); | 126 | ASSERT(!completion_done(&dqp->q_flush)); |
127 | ASSERT(atomic_read(&dqp->q_pincount) == 0); | ||
126 | 128 | ||
127 | /* | 129 | /* |
128 | * Since we were able to lock the dquot's flush lock and | 130 | * Since we were able to lock the dquot's flush lock and |
@@ -133,10 +135,16 @@ xfs_qm_dquot_logitem_push( | |||
133 | * lock without sleeping, then there must not have been | 135 | * lock without sleeping, then there must not have been |
134 | * anyone in the process of flushing the dquot. | 136 | * anyone in the process of flushing the dquot. |
135 | */ | 137 | */ |
136 | error = xfs_qm_dqflush(dqp, SYNC_TRYLOCK); | 138 | error = xfs_qm_dqflush(dqp, &bp); |
137 | if (error) | 139 | if (error) { |
138 | xfs_warn(dqp->q_mount, "%s: push error %d on dqp %p", | 140 | xfs_warn(dqp->q_mount, "%s: push error %d on dqp %p", |
139 | __func__, error, dqp); | 141 | __func__, error, dqp); |
142 | goto out_unlock; | ||
143 | } | ||
144 | |||
145 | xfs_buf_delwri_queue(bp); | ||
146 | xfs_buf_relse(bp); | ||
147 | out_unlock: | ||
140 | xfs_dqunlock(dqp); | 148 | xfs_dqunlock(dqp); |
141 | } | 149 | } |
142 | 150 | ||
@@ -239,6 +247,15 @@ xfs_qm_dquot_logitem_trylock( | |||
239 | if (!xfs_dqlock_nowait(dqp)) | 247 | if (!xfs_dqlock_nowait(dqp)) |
240 | return XFS_ITEM_LOCKED; | 248 | return XFS_ITEM_LOCKED; |
241 | 249 | ||
250 | /* | ||
251 | * Re-check the pincount now that we stabilized the value by | ||
252 | * taking the quota lock. | ||
253 | */ | ||
254 | if (atomic_read(&dqp->q_pincount) > 0) { | ||
255 | xfs_dqunlock(dqp); | ||
256 | return XFS_ITEM_PINNED; | ||
257 | } | ||
258 | |||
242 | if (!xfs_dqflock_nowait(dqp)) { | 259 | if (!xfs_dqflock_nowait(dqp)) { |
243 | /* | 260 | /* |
244 | * dquot has already been flushed to the backing buffer, | 261 | * dquot has already been flushed to the backing buffer, |
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index 18ba438386ab..95aecf52475d 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c | |||
@@ -175,16 +175,21 @@ xfs_qm_dqpurge( | |||
175 | * we're unmounting, we do care, so we flush it and wait. | 175 | * we're unmounting, we do care, so we flush it and wait. |
176 | */ | 176 | */ |
177 | if (XFS_DQ_IS_DIRTY(dqp)) { | 177 | if (XFS_DQ_IS_DIRTY(dqp)) { |
178 | int error; | 178 | struct xfs_buf *bp = NULL; |
179 | int error; | ||
179 | 180 | ||
180 | /* | 181 | /* |
181 | * We don't care about getting disk errors here. We need | 182 | * We don't care about getting disk errors here. We need |
182 | * to purge this dquot anyway, so we go ahead regardless. | 183 | * to purge this dquot anyway, so we go ahead regardless. |
183 | */ | 184 | */ |
184 | error = xfs_qm_dqflush(dqp, SYNC_WAIT); | 185 | error = xfs_qm_dqflush(dqp, &bp); |
185 | if (error) | 186 | if (error) { |
186 | xfs_warn(mp, "%s: dquot %p flush failed", | 187 | xfs_warn(mp, "%s: dquot %p flush failed", |
187 | __func__, dqp); | 188 | __func__, dqp); |
189 | } else { | ||
190 | error = xfs_bwrite(bp); | ||
191 | xfs_buf_relse(bp); | ||
192 | } | ||
188 | xfs_dqflock(dqp); | 193 | xfs_dqflock(dqp); |
189 | } | 194 | } |
190 | 195 | ||
@@ -1200,6 +1205,7 @@ STATIC int | |||
1200 | xfs_qm_flush_one( | 1205 | xfs_qm_flush_one( |
1201 | struct xfs_dquot *dqp) | 1206 | struct xfs_dquot *dqp) |
1202 | { | 1207 | { |
1208 | struct xfs_buf *bp = NULL; | ||
1203 | int error = 0; | 1209 | int error = 0; |
1204 | 1210 | ||
1205 | xfs_dqlock(dqp); | 1211 | xfs_dqlock(dqp); |
@@ -1211,8 +1217,12 @@ xfs_qm_flush_one( | |||
1211 | if (!xfs_dqflock_nowait(dqp)) | 1217 | if (!xfs_dqflock_nowait(dqp)) |
1212 | xfs_dqflock_pushbuf_wait(dqp); | 1218 | xfs_dqflock_pushbuf_wait(dqp); |
1213 | 1219 | ||
1214 | error = xfs_qm_dqflush(dqp, 0); | 1220 | error = xfs_qm_dqflush(dqp, &bp); |
1221 | if (error) | ||
1222 | goto out_unlock; | ||
1215 | 1223 | ||
1224 | xfs_buf_delwri_queue(bp); | ||
1225 | xfs_buf_relse(bp); | ||
1216 | out_unlock: | 1226 | out_unlock: |
1217 | xfs_dqunlock(dqp); | 1227 | xfs_dqunlock(dqp); |
1218 | return error; | 1228 | return error; |
@@ -1479,18 +1489,23 @@ xfs_qm_dqreclaim_one( | |||
1479 | * dirty dquots. | 1489 | * dirty dquots. |
1480 | */ | 1490 | */ |
1481 | if (XFS_DQ_IS_DIRTY(dqp)) { | 1491 | if (XFS_DQ_IS_DIRTY(dqp)) { |
1492 | struct xfs_buf *bp = NULL; | ||
1493 | |||
1482 | trace_xfs_dqreclaim_dirty(dqp); | 1494 | trace_xfs_dqreclaim_dirty(dqp); |
1483 | 1495 | ||
1484 | /* | 1496 | /* |
1485 | * We flush it delayed write, so don't bother releasing the | 1497 | * We flush it delayed write, so don't bother releasing the |
1486 | * freelist lock. | 1498 | * freelist lock. |
1487 | */ | 1499 | */ |
1488 | error = xfs_qm_dqflush(dqp, 0); | 1500 | error = xfs_qm_dqflush(dqp, &bp); |
1489 | if (error) { | 1501 | if (error) { |
1490 | xfs_warn(mp, "%s: dquot %p flush failed", | 1502 | xfs_warn(mp, "%s: dquot %p flush failed", |
1491 | __func__, dqp); | 1503 | __func__, dqp); |
1504 | goto out_busy; | ||
1492 | } | 1505 | } |
1493 | 1506 | ||
1507 | xfs_buf_delwri_queue(bp); | ||
1508 | xfs_buf_relse(bp); | ||
1494 | /* | 1509 | /* |
1495 | * Give the dquot another try on the freelist, as the | 1510 | * Give the dquot another try on the freelist, as the |
1496 | * flushing will take some time. | 1511 | * flushing will take some time. |