Whamcloud - gitweb
This should fix the extN bug. I have not enabled indexed directories by
authoradilger <adilger>
Mon, 22 Jul 2002 18:27:07 +0000 (18:27 +0000)
committeradilger <adilger>
Mon, 22 Jul 2002 18:27:07 +0000 (18:27 +0000)
default yet, so it should not affect anything either way.

lustre/extN/htree-ext3-2.4.18.diff

index edfcec2..efba400 100644 (file)
@@ -57,7 +57,7 @@
   */
  
  #include <linux/fs.h>
-@@ -38,6 +42,439 @@
+@@ -38,6 +42,456 @@
  #define NAMEI_RA_SIZE        (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
  #define NAMEI_RA_INDEX(c,b)  (((c) * NAMEI_RA_BLOCKS) + (b))
  
 + * Probe for a directory leaf block to search
 + */
 +
-+static struct dx_frame *dx_probe (struct inode *dir, u32 hash, struct dx_frame *frame)
++static struct dx_frame *
++dx_probe(struct inode *dir, u32 hash, struct dx_frame *frame_in)
 +{
 +      unsigned count, indirect;
 +      struct dx_entry *at, *entries, *p, *q, *m;
 +      struct dx_root *root;
 +      struct buffer_head *bh;
++      struct dx_frame *frame = frame_in;
 +      int err;
-+      if (!(bh = ext3_bread (NULL,dir, 0, 0,&err)))
++
++      frame->bh = NULL;
++      if (!(bh = ext3_bread(NULL, dir, 0, 0, &err)))
 +              goto fail;
 +      root = (struct dx_root *) bh->b_data;
-+      if (root->info.hash_version > 0 || root->info.unused_flags & 1)
++      if (root->info.hash_version > 0 || root->info.unused_flags & 1) {
++              brelse(bh);
 +              goto fail;
-+      if ((indirect = root->info.indirect_levels) > 1)
++      }
++      if ((indirect = root->info.indirect_levels) > 1) {
++              brelse(bh);
 +              goto fail;
++      }
 +      entries = (struct dx_entry *) (((char *) &root->info) + root->info.info_length);
 +      assert (dx_get_limit(entries) == dx_root_limit(dir, root->info.info_length));
 +      dxtrace (printk("Look up %x", hash));
 +              frame++;
 +      }
 +fail2:
-+      brelse(frame->bh);
++      while (frame >= frame_in) {
++              brelse(frame->bh);
++              frame--;
++      }
 +fail:
 +      return NULL;
 +}
 +
 +static void dx_release (struct dx_frame *frames)
 +{
-+      if (((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels)
++      if (frames[0].bh == NULL)
++              return;
++
++      if (((struct dx_root *)frames[0].bh->b_data)->info.indirect_levels)
 +              brelse (frames[1].bh);
 +      brelse (frames[0].bh);
 +}
 +      } while(more);
 +}
 +
-+static void dx_insert_block (struct dx_frame *frame, u32 hash, u32 block)
++static void dx_insert_block(struct dx_frame *frame, u32 hash, u32 block)
 +{
-+      struct dx_entry *entries = frame->entries, *at = frame->at;
-+      assert (dx_get_count (entries) < dx_get_limit (entries) &&
-+              frame->at < frame->entries+dx_get_count(entries));
-+      memmove (at + 2, at+1, (char *) (entries + dx_get_count(entries)) - (char *) (at));
-+      dx_set_hash(at + 1, hash);
-+      dx_set_block(at + 1, block);
-+      dx_set_count(entries, dx_get_count(entries) + 1);
++      struct dx_entry *entries = frame->entries;
++      struct dx_entry *old = frame->at, *new = old + 1;
++      int count = dx_get_count(entries);
++
++      assert(count < dx_get_limit(entries));
++      assert(old < entries + count);
++      memmove(new + 1, new, (char *)(entries + count) - (char *)(new));
++      dx_set_hash(new, hash);
++      dx_set_block(new, block);
++      dx_set_count(entries, count + 1);
 +}
 +#endif
 +
 -                              if (dir->i_size == 0) {
 -                                      brelse(bh);
 -                                      return -ENOENT;
-+      if (ext3_dx && is_dx(dir))
-+      {
++      if (ext3_dx && is_dx(dir)) {
 +              struct dx_frame frames[2], *frame;
 +              struct dx_entry *entries, *at;
 +              u32 hash;
 +              char *data1;
 +
-+              hash = dx_hash (name, namelen);
-+              frame = dx_probe (dir, hash, frames); // do something if null
++              hash = dx_hash(name, namelen);
++              /* FIXME: do something if dx_probe() fails here */
++              frame = dx_probe(dir, hash, frames);
 +              entries = frame->entries;
 +              at = frame->at;
 +
-+              if (!(bh = ext3_bread (handle,dir, dx_get_block(frame->at), 0,&retval)))
++              if (!(bh = ext3_bread(handle,dir, dx_get_block(at), 0,&retval)))
 +                      goto dxfail1;
 +
 +              BUFFER_TRACE(bh, "get_write_access");