Whamcloud - gitweb
Merge b_md into HEAD
[fs/lustre-release.git] / lustre / extN / htree-ext3-2.4.18.diff
index 9eba30c..4251251 100644 (file)
  static struct buffer_head * ext3_find_entry (struct dentry *dentry,
                                        struct ext3_dir_entry_2 ** res_dir)
  {
-@@ -119,10 +564,76 @@
+@@ -119,10 +564,70 @@
        int num = 0;
        int nblocks, i, err;
        struct inode *dir = dentry->d_parent->d_inode;
-+      int namelen;
-+      const u8 *name;
-+      unsigned blocksize;
 +      ext3_dirent *de, *top;
  
        *res_dir = NULL;
        sb = dir->i_sb;
-+      blocksize = sb->s_blocksize;
-+      namelen = dentry->d_name.len;
-+      name = dentry->d_name.name;
-+      if (namelen > EXT3_NAME_LEN)
++      if (dentry->d_name.len > EXT3_NAME_LEN)
 +              return NULL;
 +      if (ext3_dx && is_dx(dir)) {
-+              u32 hash = dx_hash (name, namelen);
++              u32 hash = dx_hash(dentry->d_name.name, dentry->d_name.len);
 +              struct dx_frame frames[2], *frame;
 +              if (!(frame = dx_probe (dir, hash, frames)))
 +                      return NULL;
 +              if (!(bh = ext3_bread (NULL,dir, block, 0, &err)))
 +                      goto dxfail;
 +              de = (ext3_dirent *) bh->b_data;
-+              top = (ext3_dirent *) ((char *) de + blocksize -
++              top = (ext3_dirent *) ((char *) de + sb->s_blocksize -
 +                              EXT3_DIR_REC_LEN(0));
 +              for (; de < top; de = ext3_next_entry(de))
-+                      if (ext3_match (namelen, name, de)) {
++                      if (ext3_match(dentry->d_name.len, dentry->d_name.name, de)) {
 +                              if (!ext3_check_dir_entry("ext3_find_entry",
 +                                        dir, de, bh,
 +                                        (block<<EXT3_BLOCK_SIZE_BITS(sb))
        nblocks = dir->i_size >> EXT3_BLOCK_SIZE_BITS(sb);
        start = dir->u.ext3_i.i_dir_start_lookup;
        if (start >= nblocks)
-@@ -237,6 +748,92 @@
+@@ -237,6 +748,90 @@
                de->file_type = ext3_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
  }
  
 +                      struct buffer_head **bh,struct dx_frame *frame,
 +                      u32 hash, int *error)
 +{
-+      unsigned blocksize = dir->i_sb->s_blocksize;
-+      unsigned count, continued;
++      unsigned count;
 +      struct buffer_head *bh2;
 +      u32 newblock;
-+      unsigned MAX_DX_MAP = PAGE_CACHE_SIZE/EXT3_DIR_REC_LEN(1) + 1;
 +      u32 hash2;
 +      struct dx_map_entry *map;
 +      char *data1 = (*bh)->b_data, *data2, *data3;
 +
 +      data2 = bh2->b_data;
 +
-+      map = kmalloc(sizeof(*map) * MAX_DX_MAP, GFP_KERNEL);
++      map = kmalloc(sizeof(*map) * PAGE_CACHE_SIZE/EXT3_DIR_REC_LEN(1) + 1,
++                    GFP_KERNEL);
 +      if (!map)
 +              panic("no memory for do_split\n");
-+      count = dx_make_map ((ext3_dirent *) data1, blocksize, map);
++      count = dx_make_map((ext3_dirent *)data1, dir->i_sb->s_blocksize, map);
 +      split = count/2; // need to adjust to actual middle
 +      dx_sort_map (map, count);
 +      hash2 = map[split].hash;
-+      continued = hash2 == map[split - 1].hash;
 +      dxtrace(printk("Split block %i at %x, %i/%i\n",
 +              dx_get_block(frame->at), hash2, split, count-split));
 +
 +      de = dx_copy_dirents (data1, data3, map, split);
 +      memcpy(data1, data3, (char *) de + de->rec_len - data3);
 +      de = (ext3_dirent *) ((char *) de - data3 + data1); // relocate de
-+      de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de);
-+      de2->rec_len = cpu_to_le16(data2 + blocksize - (char *) de2);
-+      dxtrace(dx_show_leaf ((ext3_dirent *) data1, blocksize, 1));
-+      dxtrace(dx_show_leaf ((ext3_dirent *) data2, blocksize, 1));
++      de->rec_len = cpu_to_le16(data1 + dir->i_sb->s_blocksize - (char *)de);
++      de2->rec_len = cpu_to_le16(data2 + dir->i_sb->s_blocksize-(char *)de2);
++      dxtrace(dx_show_leaf((ext3_dirent *)data1, dir->i_sb->s_blocksize, 1));
++      dxtrace(dx_show_leaf((ext3_dirent *)data2, dir->i_sb->s_blocksize, 1));
 +
 +      /* Which block gets the new entry? */
 +      if (hash >= hash2)
 +              swap(*bh, bh2);
 +              de = de2;
 +      }
-+      dx_insert_block (frame, hash2 + continued, newblock);
++      dx_insert_block(frame, hash2 + (hash2 == map[split-1].hash), newblock);
 +      ext3_journal_dirty_metadata (handle, bh2);
 +      brelse (bh2);
 +      ext3_journal_dirty_metadata (handle, frame->bh);
  /*
   *    ext3_add_entry()
   *
-@@ -251,6 +844,7 @@
- /*
-  * AKPM: the journalling code here looks wrong on the error paths
-  */
-+
- static int ext3_add_entry (handle_t *handle, struct dentry *dentry,
+@@ -255,118 +849,278 @@
        struct inode *inode)
  {
-@@ -258,117 +852,281 @@
-       const char *name = dentry->d_name.name;
-       int namelen = dentry->d_name.len;
+       struct inode *dir = dentry->d_parent->d_inode;
+-      const char *name = dentry->d_name.name;
+-      int namelen = dentry->d_name.len;
        unsigned long offset;
 -      unsigned short rec_len;
        struct buffer_head * bh;
 +      ext3_dirent *de;
 +      struct super_block * sb = dir->i_sb;
        int     retval;
-+      unsigned short reclen = EXT3_DIR_REC_LEN(namelen);
++      unsigned short reclen = EXT3_DIR_REC_LEN(dentry->d_name.len);
  
 -      sb = dir->i_sb;
-+      unsigned blocksize = sb->s_blocksize;
 +      unsigned nlen, rlen;
 +      u32 block, blocks;
 +      char *top;
  
-       if (!namelen)
+-      if (!namelen)
++      if (!dentry->d_name.len)
                return -EINVAL;
 -      bh = ext3_bread (handle, dir, 0, 0, &retval);
 -      if (!bh)
 +              u32 hash;
 +              char *data1;
 +
-+              hash = dx_hash(name, namelen);
++              hash = dx_hash(dentry->d_name.name, dentry->d_name.len);
 +              /* FIXME: do something if dx_probe() fails here */
 +              frame = dx_probe(dir, hash, frames);
 +              entries = frame->entries;
 +
 +              data1 = bh->b_data;
 +              de = (ext3_dirent *) data1;
-+              top = data1 + (0? 200: blocksize);
++              top = data1 + (0? 200: sb->s_blocksize);
 +              while ((char *) de < top)
 +              {
 +                      /* FIXME: check EEXIST and dir */
 +                              goto dxfail2;
 +                      node2 = (struct dx_node *)(bh2->b_data);
 +                      entries2 = node2->entries;
-+                      node2->fake.rec_len = cpu_to_le16(blocksize);
++                      node2->fake.rec_len = cpu_to_le16(sb->s_blocksize);
 +                      node2->fake.inode = 0;
 +                      BUFFER_TRACE(frame->bh, "get_write_access");
 +                      ext3_journal_get_write_access(handle, frame->bh);
 +              if(!bh)
 +                      return retval;
 +              de = (ext3_dirent *)bh->b_data;
-+              top = bh->b_data + blocksize - reclen;
++              top = bh->b_data + sb->s_blocksize - reclen;
 +              while ((char *) de <= top) {
 +                      if (!ext3_check_dir_entry("ext3_add_entry", dir, de,
 +                                                bh, offset)) {
 +                              brelse (bh);
 +                              return -EIO;
 +                      }
-+                      if (ext3_match (namelen, name, de)) {
++                      if (ext3_match(dentry->d_name.len,dentry->d_name.name,de)) {
                                brelse (bh);
                                return -EEXIST;
 -              }
 -                      ext3_journal_dirty_metadata(handle, bh);
 +                      nlen = EXT3_DIR_REC_LEN(de->name_len);
 +                      rlen = le16_to_cpu(de->rec_len);
-+                      if ((de->inode? rlen - nlen: rlen) >= reclen)
++                      if ((de->inode ? rlen - nlen: rlen) >= reclen)
 +                              goto add;
 +                      de = (ext3_dirent *)((char *)de + rlen);
 +                      offset += rlen;
 +              return retval;
 +      de = (ext3_dirent *) bh->b_data;
 +      de->inode = 0;
-+      de->rec_len = cpu_to_le16(rlen = blocksize);
++      de->rec_len = cpu_to_le16(rlen = sb->s_blocksize);
 +      nlen = 0;
 +      goto add;
 +
 +              ext3_set_de_type(dir->i_sb, de, inode->i_mode);
 +      } else
 +              de->inode = 0;
-+      de->name_len = namelen;
-+      memcpy (de->name, name, namelen);
++      de->name_len = dentry->d_name.len;
++      memcpy (de->name, dentry->d_name.name, dentry->d_name.len);
 +      /*
 +       * XXX shouldn't update any times until successful
 +       * completion of syscall, but too many callers depend
 +
 +              /* The 0th block becomes the root, move the dirents out */
 +              de = (ext3_dirent *) &root->info;
-+              len = ((char *) root) + blocksize - (char *) de;
++              len = ((char *) root) + sb->s_blocksize - (char *) de;
 +              memcpy (data1, de, len);
 +              de = (ext3_dirent *) data1;
 +              top = data1 + len;
 +              while (((char *) de2=(char*)de+le16_to_cpu(de->rec_len)) < top)
 +                      de = de2;
-+              de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de);
++              de->rec_len = cpu_to_le16(data1 + sb->s_blocksize - (char *)de);
 +              /* Initialize the root; the dot dirents already exist */
 +              de = (ext3_dirent *) (&root->dotdot);
-+              de->rec_len = cpu_to_le16(blocksize - EXT3_DIR_REC_LEN(2));
++              de->rec_len = cpu_to_le16(sb->s_blocksize-EXT3_DIR_REC_LEN(2));
 +              memset (&root->info, 0, sizeof(root->info));
 +              root->info.info_length = sizeof(root->info);
 +              entries = root->entries;
 +              dx_set_limit (entries, dx_root_limit(dir, sizeof(root->info)));
 +
 +              /* Initialize as for dx_probe */
-+              hash = dx_hash (name, namelen);
++              hash = dx_hash (dentry->d_name.name, dentry->d_name.len);
 +              frame = frames;
 +              frame->entries = entries;
 +              frame->at = entries;
 +      return -ENOENT;
  }
  
-+
  /*
-  * ext3_delete_entry deletes a directory entry by merging it with the
-  * previous entry
 @@ -451,7 +1212,8 @@
        struct inode * inode;
        int err;