aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDave Chinner <david@fromorbit.com>2013-06-27 02:04:54 -0400
committerBen Myers <bpm@sgi.com>2013-06-27 14:36:37 -0400
commitb8402b4729495ac719a3f532c2e33ac653b222a8 (patch)
tree04e352c8e96e462ebd8a0a7e1e9f1acae6ff95fa /fs
parent3ebe7d2d73179c4874aee4f32e043eb5acd9fa0f (diff)
xfs: Inode create transaction reservations
Define the log and space transaction sizes. Factor the current create log reservation macro into the two logical halves and reuse one half for the new icreate transactions. The icreate transaction is transparent to all the high level create code - the pre-calculated reservations will correctly set the reservations dependent on whether the filesystem supports the icreate transaction. Signed-off-by: Dave Chinner <david@fromorbit.com> Reviewed-by: Mark Tinguely <tinguely@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/xfs_trans.c118
1 files changed, 77 insertions, 41 deletions
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index 2fd7c1ff1d21..35a229981354 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -234,71 +234,93 @@ xfs_calc_remove_reservation(
234} 234}
235 235
236/* 236/*
237 * For symlink we can modify: 237 * For create, break it in to the two cases that the transaction
238 * covers. We start with the modify case - allocation done by modification
239 * of the state of existing inodes - and the allocation case.
240 */
241
242/*
243 * For create we can modify:
238 * the parent directory inode: inode size 244 * the parent directory inode: inode size
239 * the new inode: inode size 245 * the new inode: inode size
240 * the inode btree entry: 1 block 246 * the inode btree entry: block size
247 * the superblock for the nlink flag: sector size
241 * the directory btree: (max depth + v2) * dir block size 248 * the directory btree: (max depth + v2) * dir block size
242 * the directory inode's bmap btree: (max depth + v2) * block size 249 * the directory inode's bmap btree: (max depth + v2) * block size
243 * the blocks for the symlink: 1 kB 250 */
244 * Or in the first xact we allocate some inodes giving: 251STATIC uint
252xfs_calc_create_resv_modify(
253 struct xfs_mount *mp)
254{
255 return xfs_calc_buf_res(2, mp->m_sb.sb_inodesize) +
256 xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
257 (uint)XFS_FSB_TO_B(mp, 1) +
258 xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), XFS_FSB_TO_B(mp, 1));
259}
260
261/*
262 * For create we can allocate some inodes giving:
245 * the agi and agf of the ag getting the new inodes: 2 * sectorsize 263 * the agi and agf of the ag getting the new inodes: 2 * sectorsize
264 * the superblock for the nlink flag: sector size
246 * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize 265 * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize
247 * the inode btree: max depth * blocksize 266 * the inode btree: max depth * blocksize
248 * the allocation btrees: 2 trees * (2 * max depth - 1) * block size 267 * the allocation btrees: 2 trees * (max depth - 1) * block size
249 */ 268 */
250STATIC uint 269STATIC uint
251xfs_calc_symlink_reservation( 270xfs_calc_create_resv_alloc(
271 struct xfs_mount *mp)
272{
273 return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
274 mp->m_sb.sb_sectsize +
275 xfs_calc_buf_res(XFS_IALLOC_BLOCKS(mp), XFS_FSB_TO_B(mp, 1)) +
276 xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)) +
277 xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
278 XFS_FSB_TO_B(mp, 1));
279}
280
281STATIC uint
282__xfs_calc_create_reservation(
252 struct xfs_mount *mp) 283 struct xfs_mount *mp)
253{ 284{
254 return XFS_DQUOT_LOGRES(mp) + 285 return XFS_DQUOT_LOGRES(mp) +
255 MAX((xfs_calc_buf_res(2, mp->m_sb.sb_inodesize) + 286 MAX(xfs_calc_create_resv_alloc(mp),
256 xfs_calc_buf_res(1, XFS_FSB_TO_B(mp, 1)) + 287 xfs_calc_create_resv_modify(mp));
257 xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp),
258 XFS_FSB_TO_B(mp, 1)) +
259 xfs_calc_buf_res(1, 1024)),
260 (xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
261 xfs_calc_buf_res(XFS_IALLOC_BLOCKS(mp),
262 XFS_FSB_TO_B(mp, 1)) +
263 xfs_calc_buf_res(mp->m_in_maxlevels,
264 XFS_FSB_TO_B(mp, 1)) +
265 xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
266 XFS_FSB_TO_B(mp, 1))));
267} 288}
268 289
269/* 290/*
270 * For create we can modify: 291 * For icreate we can allocate some inodes giving:
271 * the parent directory inode: inode size
272 * the new inode: inode size
273 * the inode btree entry: block size
274 * the superblock for the nlink flag: sector size
275 * the directory btree: (max depth + v2) * dir block size
276 * the directory inode's bmap btree: (max depth + v2) * block size
277 * Or in the first xact we allocate some inodes giving:
278 * the agi and agf of the ag getting the new inodes: 2 * sectorsize 292 * the agi and agf of the ag getting the new inodes: 2 * sectorsize
279 * the superblock for the nlink flag: sector size 293 * the superblock for the nlink flag: sector size
280 * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize
281 * the inode btree: max depth * blocksize 294 * the inode btree: max depth * blocksize
282 * the allocation btrees: 2 trees * (max depth - 1) * block size 295 * the allocation btrees: 2 trees * (max depth - 1) * block size
283 */ 296 */
284STATIC uint 297STATIC uint
285xfs_calc_create_reservation( 298xfs_calc_icreate_resv_alloc(
286 struct xfs_mount *mp) 299 struct xfs_mount *mp)
287{ 300{
301 return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
302 mp->m_sb.sb_sectsize +
303 xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)) +
304 xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
305 XFS_FSB_TO_B(mp, 1));
306}
307
308STATIC uint
309xfs_calc_icreate_reservation(xfs_mount_t *mp)
310{
288 return XFS_DQUOT_LOGRES(mp) + 311 return XFS_DQUOT_LOGRES(mp) +
289 MAX((xfs_calc_buf_res(2, mp->m_sb.sb_inodesize) + 312 MAX(xfs_calc_icreate_resv_alloc(mp),
290 xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + 313 xfs_calc_create_resv_modify(mp));
291 (uint)XFS_FSB_TO_B(mp, 1) + 314}
292 xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), 315
293 XFS_FSB_TO_B(mp, 1))), 316STATIC uint
294 (xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) + 317xfs_calc_create_reservation(
295 mp->m_sb.sb_sectsize + 318 struct xfs_mount *mp)
296 xfs_calc_buf_res(XFS_IALLOC_BLOCKS(mp), 319{
297 XFS_FSB_TO_B(mp, 1)) + 320 if (xfs_sb_version_hascrc(&mp->m_sb))
298 xfs_calc_buf_res(mp->m_in_maxlevels, 321 return xfs_calc_icreate_reservation(mp);
299 XFS_FSB_TO_B(mp, 1)) + 322 return __xfs_calc_create_reservation(mp);
300 xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), 323
301 XFS_FSB_TO_B(mp, 1))));
302} 324}
303 325
304/* 326/*
@@ -311,6 +333,20 @@ xfs_calc_mkdir_reservation(
311 return xfs_calc_create_reservation(mp); 333 return xfs_calc_create_reservation(mp);
312} 334}
313 335
336
337/*
338 * Making a new symplink is the same as creating a new file, but
339 * with the added blocks for remote symlink data which can be up to 1kB in
340 * length (MAXPATHLEN).
341 */
342STATIC uint
343xfs_calc_symlink_reservation(
344 struct xfs_mount *mp)
345{
346 return xfs_calc_create_reservation(mp) +
347 xfs_calc_buf_res(1, MAXPATHLEN);
348}
349
314/* 350/*
315 * In freeing an inode we can modify: 351 * In freeing an inode we can modify:
316 * the inode being freed: inode size 352 * the inode being freed: inode size