diff options
Diffstat (limited to 'fs/xfs/xfs_trans.c')
-rw-r--r-- | fs/xfs/xfs_trans.c | 118 |
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: | 251 | STATIC uint |
252 | xfs_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 | */ |
250 | STATIC uint | 269 | STATIC uint |
251 | xfs_calc_symlink_reservation( | 270 | xfs_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 | |||
281 | STATIC 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 | */ |
284 | STATIC uint | 297 | STATIC uint |
285 | xfs_calc_create_reservation( | 298 | xfs_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 | |||
308 | STATIC uint | ||
309 | xfs_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))), | 316 | STATIC uint |
294 | (xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) + | 317 | xfs_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 | */ | ||
342 | STATIC uint | ||
343 | xfs_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 |