aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2017-01-25 10:49:34 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-04-08 03:30:30 -0400
commit9be1c33d4a995d6369b94c7bb6ae0e8d18e7d658 (patch)
tree16a18e5e8c2a3828e1e917318e664b3da65e05f8
parent8b08aec62c247db69f5e2a813912f65a46797fc2 (diff)
xfs: only update mount/resv fields on success in __xfs_ag_resv_init
commit 4dfa2b84118fd6c95202ae87e62adf5000ccd4d0 upstream. Try to reserve the blocks first and only then update the fields in or hanging off the mount structure. This way we can call __xfs_ag_resv_init again after a previous failure. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--fs/xfs/libxfs/xfs_ag_resv.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/fs/xfs/libxfs/xfs_ag_resv.c b/fs/xfs/libxfs/xfs_ag_resv.c
index d346d42c54d1..94234bff40dc 100644
--- a/fs/xfs/libxfs/xfs_ag_resv.c
+++ b/fs/xfs/libxfs/xfs_ag_resv.c
@@ -200,22 +200,27 @@ __xfs_ag_resv_init(
200 struct xfs_mount *mp = pag->pag_mount; 200 struct xfs_mount *mp = pag->pag_mount;
201 struct xfs_ag_resv *resv; 201 struct xfs_ag_resv *resv;
202 int error; 202 int error;
203 xfs_extlen_t reserved;
203 204
204 resv = xfs_perag_resv(pag, type);
205 if (used > ask) 205 if (used > ask)
206 ask = used; 206 ask = used;
207 resv->ar_asked = ask; 207 reserved = ask - used;
208 resv->ar_reserved = resv->ar_orig_reserved = ask - used;
209 mp->m_ag_max_usable -= ask;
210 208
211 trace_xfs_ag_resv_init(pag, type, ask); 209 error = xfs_mod_fdblocks(mp, -(int64_t)reserved, true);
212 210 if (error) {
213 error = xfs_mod_fdblocks(mp, -(int64_t)resv->ar_reserved, true);
214 if (error)
215 trace_xfs_ag_resv_init_error(pag->pag_mount, pag->pag_agno, 211 trace_xfs_ag_resv_init_error(pag->pag_mount, pag->pag_agno,
216 error, _RET_IP_); 212 error, _RET_IP_);
213 return error;
214 }
217 215
218 return error; 216 mp->m_ag_max_usable -= ask;
217
218 resv = xfs_perag_resv(pag, type);
219 resv->ar_asked = ask;
220 resv->ar_reserved = resv->ar_orig_reserved = reserved;
221
222 trace_xfs_ag_resv_init(pag, type, ask);
223 return 0;
219} 224}
220 225
221/* Create a per-AG block reservation. */ 226/* Create a per-AG block reservation. */