aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/namei.c
diff options
context:
space:
mode:
authorMark Fasheh <mfasheh@suse.com>2008-11-12 19:27:44 -0500
committerMark Fasheh <mfasheh@suse.com>2009-04-03 14:39:15 -0400
commit9b7895efac906d66d19856194e1ba61f37e231a4 (patch)
tree1ee6d2630cf3617251638170dcaceef41ddda8ec /fs/ocfs2/namei.c
parent4a12ca3a00a244e1fd1e673d151ea38b71e11d55 (diff)
ocfs2: Add a name indexed b-tree to directory inodes
This patch makes use of Ocfs2's flexible btree code to add an additional tree to directory inodes. The new tree stores an array of small, fixed-length records in each leaf block. Each record stores a hash value, and pointer to a block in the traditional (unindexed) directory tree where a dirent with the given name hash resides. Lookup exclusively uses this tree to find dirents, thus providing us with constant time name lookups. Some of the hashing code was copied from ext3. Unfortunately, it has lots of unfixed checkpatch errors. I left that as-is so that tracking changes would be easier. Signed-off-by: Mark Fasheh <mfasheh@suse.com> Acked-by: Joel Becker <joel.becker@oracle.com>
Diffstat (limited to 'fs/ocfs2/namei.c')
-rw-r--r--fs/ocfs2/namei.c45
1 files changed, 31 insertions, 14 deletions
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index d3a5a09d88f..0c550719320 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(