diff options
Diffstat (limited to 'fs/ocfs2/namei.c')
-rw-r--r-- | fs/ocfs2/namei.c | 45 |
1 files changed, 31 insertions, 14 deletions
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index d3a5a09d88ff..0c5507193200 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
@@ -231,8 +231,9 @@ static int ocfs2_mknod(struct inode *dir, | |||
231 | struct inode *inode = NULL; | 231 | struct inode *inode = NULL; |
232 | struct ocfs2_alloc_context *inode_ac = NULL; | 232 | struct ocfs2_alloc_context *inode_ac = NULL; |
233 | struct ocfs2_alloc_context *data_ac = NULL; | 233 | struct ocfs2_alloc_context *data_ac = NULL; |
234 | struct ocfs2_alloc_context *xattr_ac = NULL; | 234 | struct ocfs2_alloc_context *meta_ac = NULL; |
235 | int want_clusters = 0; | 235 | int want_clusters = 0; |
236 | int want_meta = 0; | ||
236 | int xattr_credits = 0; | 237 | int xattr_credits = 0; |
237 | struct ocfs2_security_xattr_info si = { | 238 | struct ocfs2_security_xattr_info si = { |
238 | .enable = 1, | 239 | .enable = 1, |
@@ -308,17 +309,31 @@ static int ocfs2_mknod(struct inode *dir, | |||
308 | 309 | ||
309 | /* calculate meta data/clusters for setting security and acl xattr */ | 310 | /* calculate meta data/clusters for setting security and acl xattr */ |
310 | status = ocfs2_calc_xattr_init(dir, parent_fe_bh, mode, | 311 | status = ocfs2_calc_xattr_init(dir, parent_fe_bh, mode, |
311 | &si, &want_clusters, | 312 | &si, &want_clusters, |
312 | &xattr_credits, &xattr_ac); | 313 | &xattr_credits, &want_meta); |
313 | if (status < 0) { | 314 | if (status < 0) { |
314 | mlog_errno(status); | 315 | mlog_errno(status); |
315 | goto leave; | 316 | goto leave; |
316 | } | 317 | } |
317 | 318 | ||
318 | /* Reserve a cluster if creating an extent based directory. */ | 319 | /* Reserve a cluster if creating an extent based directory. */ |
319 | if (S_ISDIR(mode) && !ocfs2_supports_inline_data(osb)) | 320 | if (S_ISDIR(mode) && !ocfs2_supports_inline_data(osb)) { |
320 | want_clusters += 1; | 321 | want_clusters += 1; |
321 | 322 | ||
323 | /* Dir indexing requires extra space as well */ | ||
324 | if (ocfs2_supports_indexed_dirs(osb)) { | ||
325 | want_clusters++; | ||
326 | want_meta++; | ||
327 | } | ||
328 | } | ||
329 | |||
330 | status = ocfs2_reserve_new_metadata_blocks(osb, want_meta, &meta_ac); | ||
331 | if (status < 0) { | ||
332 | if (status != -ENOSPC) | ||
333 | mlog_errno(status); | ||
334 | goto leave; | ||
335 | } | ||
336 | |||
322 | status = ocfs2_reserve_clusters(osb, want_clusters, &data_ac); | 337 | status = ocfs2_reserve_clusters(osb, want_clusters, &data_ac); |
323 | if (status < 0) { | 338 | if (status < 0) { |
324 | if (status != -ENOSPC) | 339 | if (status != -ENOSPC) |
@@ -326,8 +341,9 @@ static int ocfs2_mknod(struct inode *dir, | |||
326 | goto leave; | 341 | goto leave; |
327 | } | 342 | } |
328 | 343 | ||
329 | handle = ocfs2_start_trans(osb, ocfs2_mknod_credits(osb->sb) + | 344 | handle = ocfs2_start_trans(osb, ocfs2_mknod_credits(osb->sb, |
330 | xattr_credits); | 345 | S_ISDIR(mode), |
346 | xattr_credits)); | ||
331 | if (IS_ERR(handle)) { | 347 | if (IS_ERR(handle)) { |
332 | status = PTR_ERR(handle); | 348 | status = PTR_ERR(handle); |
333 | handle = NULL; | 349 | handle = NULL; |
@@ -355,7 +371,7 @@ static int ocfs2_mknod(struct inode *dir, | |||
355 | 371 | ||
356 | if (S_ISDIR(mode)) { | 372 | if (S_ISDIR(mode)) { |
357 | status = ocfs2_fill_new_dir(osb, handle, dir, inode, | 373 | status = ocfs2_fill_new_dir(osb, handle, dir, inode, |
358 | new_fe_bh, data_ac); | 374 | new_fe_bh, data_ac, meta_ac); |
359 | if (status < 0) { | 375 | if (status < 0) { |
360 | mlog_errno(status); | 376 | mlog_errno(status); |
361 | goto leave; | 377 | goto leave; |
@@ -377,7 +393,7 @@ static int ocfs2_mknod(struct inode *dir, | |||
377 | } | 393 | } |
378 | 394 | ||
379 | status = ocfs2_init_acl(handle, inode, dir, new_fe_bh, parent_fe_bh, | 395 | status = ocfs2_init_acl(handle, inode, dir, new_fe_bh, parent_fe_bh, |
380 | xattr_ac, data_ac); | 396 | meta_ac, data_ac); |
381 | if (status < 0) { | 397 | if (status < 0) { |
382 | mlog_errno(status); | 398 | mlog_errno(status); |
383 | goto leave; | 399 | goto leave; |
@@ -385,7 +401,7 @@ static int ocfs2_mknod(struct inode *dir, | |||
385 | 401 | ||
386 | if (si.enable) { | 402 | if (si.enable) { |
387 | status = ocfs2_init_security_set(handle, inode, new_fe_bh, &si, | 403 | status = ocfs2_init_security_set(handle, inode, new_fe_bh, &si, |
388 | xattr_ac, data_ac); | 404 | meta_ac, data_ac); |
389 | if (status < 0) { | 405 | if (status < 0) { |
390 | mlog_errno(status); | 406 | mlog_errno(status); |
391 | goto leave; | 407 | goto leave; |
@@ -440,8 +456,8 @@ leave: | |||
440 | if (data_ac) | 456 | if (data_ac) |
441 | ocfs2_free_alloc_context(data_ac); | 457 | ocfs2_free_alloc_context(data_ac); |
442 | 458 | ||
443 | if (xattr_ac) | 459 | if (meta_ac) |
444 | ocfs2_free_alloc_context(xattr_ac); | 460 | ocfs2_free_alloc_context(meta_ac); |
445 | 461 | ||
446 | mlog_exit(status); | 462 | mlog_exit(status); |
447 | 463 | ||
@@ -463,6 +479,7 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb, | |||
463 | struct ocfs2_extent_list *fel; | 479 | struct ocfs2_extent_list *fel; |
464 | u64 fe_blkno = 0; | 480 | u64 fe_blkno = 0; |
465 | u16 suballoc_bit; | 481 | u16 suballoc_bit; |
482 | u16 feat; | ||
466 | 483 | ||
467 | mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry, | 484 | mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry, |
468 | inode->i_mode, (unsigned long)dev, dentry->d_name.len, | 485 | inode->i_mode, (unsigned long)dev, dentry->d_name.len, |
@@ -526,11 +543,11 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb, | |||
526 | fe->i_dtime = 0; | 543 | fe->i_dtime = 0; |
527 | 544 | ||
528 | /* | 545 | /* |
529 | * If supported, directories start with inline data. | 546 | * If supported, directories start with inline data. If inline |
547 | * isn't supported, but indexing is, we start them as indexed. | ||
530 | */ | 548 | */ |
549 | feat = le16_to_cpu(fe->i_dyn_features); | ||
531 | if (S_ISDIR(inode->i_mode) && ocfs2_supports_inline_data(osb)) { | 550 | if (S_ISDIR(inode->i_mode) && ocfs2_supports_inline_data(osb)) { |
532 | u16 feat = le16_to_cpu(fe->i_dyn_features); | ||
533 | |||
534 | fe->i_dyn_features = cpu_to_le16(feat | OCFS2_INLINE_DATA_FL); | 551 | fe->i_dyn_features = cpu_to_le16(feat | OCFS2_INLINE_DATA_FL); |
535 | 552 | ||
536 | fe->id2.i_data.id_count = cpu_to_le16( | 553 | fe->id2.i_data.id_count = cpu_to_le16( |