Commit 316f4b9f98a353ac1be93199694fd97272378815

Authored by Mark Fasheh
1 parent 1d410a6e33

ocfs2: Move directory manipulation code into dir.c

The code for adding, removing, deleting directory entries was splattered all
over namei.c. I'd rather have this all centralized, so that it's easier to
make changes for inline dir data, and eventually indexed directories.

None of the code in any of the functions was changed. I only removed the
static keyword from some prototypes so that they could be exported.

Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
Reviewed-by: Joel Becker <joel.becker@oracle.com>

Showing 5 changed files with 461 additions and 467 deletions Side-by-side Diff

... ... @@ -55,10 +55,16 @@
55 55 #include "journal.h"
56 56 #include "namei.h"
57 57 #include "suballoc.h"
  58 +#include "super.h"
58 59 #include "uptodate.h"
59 60  
60 61 #include "buffer_head_io.h"
61 62  
  63 +#define NAMEI_RA_CHUNKS 2
  64 +#define NAMEI_RA_BLOCKS 4
  65 +#define NAMEI_RA_SIZE (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
  66 +#define NAMEI_RA_INDEX(c,b) (((c) * NAMEI_RA_BLOCKS) + (b))
  67 +
62 68 static unsigned char ocfs2_filetype_table[] = {
63 69 DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK
64 70 };
65 71  
... ... @@ -67,7 +73,348 @@
67 73 struct inode *dir,
68 74 struct buffer_head *parent_fe_bh,
69 75 struct buffer_head **new_de_bh);
  76 +static int ocfs2_do_extend_dir(struct super_block *sb,
  77 + handle_t *handle,
  78 + struct inode *dir,
  79 + struct buffer_head *parent_fe_bh,
  80 + struct ocfs2_alloc_context *data_ac,
  81 + struct ocfs2_alloc_context *meta_ac,
  82 + struct buffer_head **new_bh);
  83 +
  84 +int ocfs2_check_dir_entry(struct inode * dir,
  85 + struct ocfs2_dir_entry * de,
  86 + struct buffer_head * bh,
  87 + unsigned long offset)
  88 +{
  89 + const char *error_msg = NULL;
  90 + const int rlen = le16_to_cpu(de->rec_len);
  91 +
  92 + if (rlen < OCFS2_DIR_REC_LEN(1))
  93 + error_msg = "rec_len is smaller than minimal";
  94 + else if (rlen % 4 != 0)
  95 + error_msg = "rec_len % 4 != 0";
  96 + else if (rlen < OCFS2_DIR_REC_LEN(de->name_len))
  97 + error_msg = "rec_len is too small for name_len";
  98 + else if (((char *) de - bh->b_data) + rlen > dir->i_sb->s_blocksize)
  99 + error_msg = "directory entry across blocks";
  100 +
  101 + if (error_msg != NULL)
  102 + mlog(ML_ERROR, "bad entry in directory #%llu: %s - "
  103 + "offset=%lu, inode=%llu, rec_len=%d, name_len=%d\n",
  104 + (unsigned long long)OCFS2_I(dir)->ip_blkno, error_msg,
  105 + offset, (unsigned long long)le64_to_cpu(de->inode), rlen,
  106 + de->name_len);
  107 + return error_msg == NULL ? 1 : 0;
  108 +}
  109 +
  110 +static inline int ocfs2_match(int len,
  111 + const char * const name,
  112 + struct ocfs2_dir_entry *de)
  113 +{
  114 + if (len != de->name_len)
  115 + return 0;
  116 + if (!de->inode)
  117 + return 0;
  118 + return !memcmp(name, de->name, len);
  119 +}
  120 +
70 121 /*
  122 + * Returns 0 if not found, -1 on failure, and 1 on success
  123 + */
  124 +static int inline ocfs2_search_dirblock(struct buffer_head *bh,
  125 + struct inode *dir,
  126 + const char *name, int namelen,
  127 + unsigned long offset,
  128 + struct ocfs2_dir_entry **res_dir)
  129 +{
  130 + struct ocfs2_dir_entry *de;
  131 + char *dlimit, *de_buf;
  132 + int de_len;
  133 + int ret = 0;
  134 +
  135 + mlog_entry_void();
  136 +
  137 + de_buf = bh->b_data;
  138 + dlimit = de_buf + dir->i_sb->s_blocksize;
  139 +
  140 + while (de_buf < dlimit) {
  141 + /* this code is executed quadratically often */
  142 + /* do minimal checking `by hand' */
  143 +
  144 + de = (struct ocfs2_dir_entry *) de_buf;
  145 +
  146 + if (de_buf + namelen <= dlimit &&
  147 + ocfs2_match(namelen, name, de)) {
  148 + /* found a match - just to be sure, do a full check */
  149 + if (!ocfs2_check_dir_entry(dir, de, bh, offset)) {
  150 + ret = -1;
  151 + goto bail;
  152 + }
  153 + *res_dir = de;
  154 + ret = 1;
  155 + goto bail;
  156 + }
  157 +
  158 + /* prevent looping on a bad block */
  159 + de_len = le16_to_cpu(de->rec_len);
  160 + if (de_len <= 0) {
  161 + ret = -1;
  162 + goto bail;
  163 + }
  164 +
  165 + de_buf += de_len;
  166 + offset += de_len;
  167 + }
  168 +
  169 +bail:
  170 + mlog_exit(ret);
  171 + return ret;
  172 +}
  173 +
  174 +struct buffer_head *ocfs2_find_entry(const char *name, int namelen,
  175 + struct inode *dir,
  176 + struct ocfs2_dir_entry **res_dir)
  177 +{
  178 + struct super_block *sb;
  179 + struct buffer_head *bh_use[NAMEI_RA_SIZE];
  180 + struct buffer_head *bh, *ret = NULL;
  181 + unsigned long start, block, b;
  182 + int ra_max = 0; /* Number of bh's in the readahead
  183 + buffer, bh_use[] */
  184 + int ra_ptr = 0; /* Current index into readahead
  185 + buffer */
  186 + int num = 0;
  187 + int nblocks, i, err;
  188 +
  189 + mlog_entry_void();
  190 +
  191 + *res_dir = NULL;
  192 + sb = dir->i_sb;
  193 +
  194 + nblocks = i_size_read(dir) >> sb->s_blocksize_bits;
  195 + start = OCFS2_I(dir)->ip_dir_start_lookup;
  196 + if (start >= nblocks)
  197 + start = 0;
  198 + block = start;
  199 +
  200 +restart:
  201 + do {
  202 + /*
  203 + * We deal with the read-ahead logic here.
  204 + */
  205 + if (ra_ptr >= ra_max) {
  206 + /* Refill the readahead buffer */
  207 + ra_ptr = 0;
  208 + b = block;
  209 + for (ra_max = 0; ra_max < NAMEI_RA_SIZE; ra_max++) {
  210 + /*
  211 + * Terminate if we reach the end of the
  212 + * directory and must wrap, or if our
  213 + * search has finished at this block.
  214 + */
  215 + if (b >= nblocks || (num && block == start)) {
  216 + bh_use[ra_max] = NULL;
  217 + break;
  218 + }
  219 + num++;
  220 +
  221 + bh = ocfs2_bread(dir, b++, &err, 1);
  222 + bh_use[ra_max] = bh;
  223 + }
  224 + }
  225 + if ((bh = bh_use[ra_ptr++]) == NULL)
  226 + goto next;
  227 + wait_on_buffer(bh);
  228 + if (!buffer_uptodate(bh)) {
  229 + /* read error, skip block & hope for the best */
  230 + ocfs2_error(dir->i_sb, "reading directory %llu, "
  231 + "offset %lu\n",
  232 + (unsigned long long)OCFS2_I(dir)->ip_blkno,
  233 + block);
  234 + brelse(bh);
  235 + goto next;
  236 + }
  237 + i = ocfs2_search_dirblock(bh, dir, name, namelen,
  238 + block << sb->s_blocksize_bits,
  239 + res_dir);
  240 + if (i == 1) {
  241 + OCFS2_I(dir)->ip_dir_start_lookup = block;
  242 + ret = bh;
  243 + goto cleanup_and_exit;
  244 + } else {
  245 + brelse(bh);
  246 + if (i < 0)
  247 + goto cleanup_and_exit;
  248 + }
  249 + next:
  250 + if (++block >= nblocks)
  251 + block = 0;
  252 + } while (block != start);
  253 +
  254 + /*
  255 + * If the directory has grown while we were searching, then
  256 + * search the last part of the directory before giving up.
  257 + */
  258 + block = nblocks;
  259 + nblocks = i_size_read(dir) >> sb->s_blocksize_bits;
  260 + if (block < nblocks) {
  261 + start = 0;
  262 + goto restart;
  263 + }
  264 +
  265 +cleanup_and_exit:
  266 + /* Clean up the read-ahead blocks */
  267 + for (; ra_ptr < ra_max; ra_ptr++)
  268 + brelse(bh_use[ra_ptr]);
  269 +
  270 + mlog_exit_ptr(ret);
  271 + return ret;
  272 +}
  273 +
  274 +/*
  275 + * ocfs2_delete_entry deletes a directory entry by merging it with the
  276 + * previous entry
  277 + */
  278 +int ocfs2_delete_entry(handle_t *handle,
  279 + struct inode *dir,
  280 + struct ocfs2_dir_entry *de_del,
  281 + struct buffer_head *bh)
  282 +{
  283 + struct ocfs2_dir_entry *de, *pde;
  284 + int i, status = -ENOENT;
  285 +
  286 + mlog_entry("(0x%p, 0x%p, 0x%p, 0x%p)\n", handle, dir, de_del, bh);
  287 +
  288 + i = 0;
  289 + pde = NULL;
  290 + de = (struct ocfs2_dir_entry *) bh->b_data;
  291 + while (i < bh->b_size) {
  292 + if (!ocfs2_check_dir_entry(dir, de, bh, i)) {
  293 + status = -EIO;
  294 + mlog_errno(status);
  295 + goto bail;
  296 + }
  297 + if (de == de_del) {
  298 + status = ocfs2_journal_access(handle, dir, bh,
  299 + OCFS2_JOURNAL_ACCESS_WRITE);
  300 + if (status < 0) {
  301 + status = -EIO;
  302 + mlog_errno(status);
  303 + goto bail;
  304 + }
  305 + if (pde)
  306 + pde->rec_len =
  307 + cpu_to_le16(le16_to_cpu(pde->rec_len) +
  308 + le16_to_cpu(de->rec_len));
  309 + else
  310 + de->inode = 0;
  311 + dir->i_version++;
  312 + status = ocfs2_journal_dirty(handle, bh);
  313 + goto bail;
  314 + }
  315 + i += le16_to_cpu(de->rec_len);
  316 + pde = de;
  317 + de = (struct ocfs2_dir_entry *)((char *)de + le16_to_cpu(de->rec_len));
  318 + }
  319 +bail:
  320 + mlog_exit(status);
  321 + return status;
  322 +}
  323 +
  324 +/* we don't always have a dentry for what we want to add, so people
  325 + * like orphan dir can call this instead.
  326 + *
  327 + * If you pass me insert_bh, I'll skip the search of the other dir
  328 + * blocks and put the record in there.
  329 + */
  330 +int __ocfs2_add_entry(handle_t *handle,
  331 + struct inode *dir,
  332 + const char *name, int namelen,
  333 + struct inode *inode, u64 blkno,
  334 + struct buffer_head *parent_fe_bh,
  335 + struct buffer_head *insert_bh)
  336 +{
  337 + unsigned long offset;
  338 + unsigned short rec_len;
  339 + struct ocfs2_dir_entry *de, *de1;
  340 + struct super_block *sb;
  341 + int retval, status;
  342 +
  343 + mlog_entry_void();
  344 +
  345 + sb = dir->i_sb;
  346 +
  347 + if (!namelen)
  348 + return -EINVAL;
  349 +
  350 + rec_len = OCFS2_DIR_REC_LEN(namelen);
  351 + offset = 0;
  352 + de = (struct ocfs2_dir_entry *) insert_bh->b_data;
  353 + while (1) {
  354 + BUG_ON((char *)de >= sb->s_blocksize + insert_bh->b_data);
  355 + /* These checks should've already been passed by the
  356 + * prepare function, but I guess we can leave them
  357 + * here anyway. */
  358 + if (!ocfs2_check_dir_entry(dir, de, insert_bh, offset)) {
  359 + retval = -ENOENT;
  360 + goto bail;
  361 + }
  362 + if (ocfs2_match(namelen, name, de)) {
  363 + retval = -EEXIST;
  364 + goto bail;
  365 + }
  366 + if (((le64_to_cpu(de->inode) == 0) &&
  367 + (le16_to_cpu(de->rec_len) >= rec_len)) ||
  368 + (le16_to_cpu(de->rec_len) >=
  369 + (OCFS2_DIR_REC_LEN(de->name_len) + rec_len))) {
  370 + dir->i_mtime = dir->i_ctime = CURRENT_TIME;
  371 + retval = ocfs2_mark_inode_dirty(handle, dir, parent_fe_bh);
  372 + if (retval < 0) {
  373 + mlog_errno(retval);
  374 + goto bail;
  375 + }
  376 +
  377 + status = ocfs2_journal_access(handle, dir, insert_bh,
  378 + OCFS2_JOURNAL_ACCESS_WRITE);
  379 + /* By now the buffer is marked for journaling */
  380 + offset += le16_to_cpu(de->rec_len);
  381 + if (le64_to_cpu(de->inode)) {
  382 + de1 = (struct ocfs2_dir_entry *)((char *) de +
  383 + OCFS2_DIR_REC_LEN(de->name_len));
  384 + de1->rec_len =
  385 + cpu_to_le16(le16_to_cpu(de->rec_len) -
  386 + OCFS2_DIR_REC_LEN(de->name_len));
  387 + de->rec_len = cpu_to_le16(OCFS2_DIR_REC_LEN(de->name_len));
  388 + de = de1;
  389 + }
  390 + de->file_type = OCFS2_FT_UNKNOWN;
  391 + if (blkno) {
  392 + de->inode = cpu_to_le64(blkno);
  393 + ocfs2_set_de_type(de, inode->i_mode);
  394 + } else
  395 + de->inode = 0;
  396 + de->name_len = namelen;
  397 + memcpy(de->name, name, namelen);
  398 +
  399 + dir->i_version++;
  400 + status = ocfs2_journal_dirty(handle, insert_bh);
  401 + retval = 0;
  402 + goto bail;
  403 + }
  404 + offset += le16_to_cpu(de->rec_len);
  405 + de = (struct ocfs2_dir_entry *) ((char *) de + le16_to_cpu(de->rec_len));
  406 + }
  407 +
  408 + /* when you think about it, the assert above should prevent us
  409 + * from ever getting here. */
  410 + retval = -ENOSPC;
  411 +bail:
  412 +
  413 + mlog_exit(retval);
  414 + return retval;
  415 +}
  416 +
  417 +/*
71 418 * ocfs2_readdir()
72 419 *
73 420 */
74 421  
... ... @@ -347,14 +694,83 @@
347 694 return 1;
348 695 }
349 696  
  697 +int ocfs2_fill_new_dir(struct ocfs2_super *osb,
  698 + handle_t *handle,
  699 + struct inode *parent,
  700 + struct inode *inode,
  701 + struct buffer_head *fe_bh,
  702 + struct ocfs2_alloc_context *data_ac)
  703 +{
  704 + int status;
  705 + struct buffer_head *new_bh = NULL;
  706 + struct ocfs2_dir_entry *de = NULL;
  707 +
  708 + mlog_entry_void();
  709 +
  710 + status = ocfs2_do_extend_dir(osb->sb, handle, inode, fe_bh,
  711 + data_ac, NULL, &new_bh);
  712 + if (status < 0) {
  713 + mlog_errno(status);
  714 + goto bail;
  715 + }
  716 +
  717 + ocfs2_set_new_buffer_uptodate(inode, new_bh);
  718 +
  719 + status = ocfs2_journal_access(handle, inode, new_bh,
  720 + OCFS2_JOURNAL_ACCESS_CREATE);
  721 + if (status < 0) {
  722 + mlog_errno(status);
  723 + goto bail;
  724 + }
  725 + memset(new_bh->b_data, 0, osb->sb->s_blocksize);
  726 +
  727 + de = (struct ocfs2_dir_entry *) new_bh->b_data;
  728 + de->inode = cpu_to_le64(OCFS2_I(inode)->ip_blkno);
  729 + de->name_len = 1;
  730 + de->rec_len =
  731 + cpu_to_le16(OCFS2_DIR_REC_LEN(de->name_len));
  732 + strcpy(de->name, ".");
  733 + ocfs2_set_de_type(de, S_IFDIR);
  734 + de = (struct ocfs2_dir_entry *) ((char *)de + le16_to_cpu(de->rec_len));
  735 + de->inode = cpu_to_le64(OCFS2_I(parent)->ip_blkno);
  736 + de->rec_len = cpu_to_le16(inode->i_sb->s_blocksize -
  737 + OCFS2_DIR_REC_LEN(1));
  738 + de->name_len = 2;
  739 + strcpy(de->name, "..");
  740 + ocfs2_set_de_type(de, S_IFDIR);
  741 +
  742 + status = ocfs2_journal_dirty(handle, new_bh);
  743 + if (status < 0) {
  744 + mlog_errno(status);
  745 + goto bail;
  746 + }
  747 +
  748 + i_size_write(inode, inode->i_sb->s_blocksize);
  749 + inode->i_nlink = 2;
  750 + inode->i_blocks = ocfs2_inode_sector_count(inode);
  751 + status = ocfs2_mark_inode_dirty(handle, inode, fe_bh);
  752 + if (status < 0) {
  753 + mlog_errno(status);
  754 + goto bail;
  755 + }
  756 +
  757 + status = 0;
  758 +bail:
  759 + if (new_bh)
  760 + brelse(new_bh);
  761 +
  762 + mlog_exit(status);
  763 + return status;
  764 +}
  765 +
350 766 /* returns a bh of the 1st new block in the allocation. */
351   -int ocfs2_do_extend_dir(struct super_block *sb,
352   - handle_t *handle,
353   - struct inode *dir,
354   - struct buffer_head *parent_fe_bh,
355   - struct ocfs2_alloc_context *data_ac,
356   - struct ocfs2_alloc_context *meta_ac,
357   - struct buffer_head **new_bh)
  767 +static int ocfs2_do_extend_dir(struct super_block *sb,
  768 + handle_t *handle,
  769 + struct inode *dir,
  770 + struct buffer_head *parent_fe_bh,
  771 + struct ocfs2_alloc_context *data_ac,
  772 + struct ocfs2_alloc_context *meta_ac,
  773 + struct buffer_head **new_bh)
358 774 {
359 775 int status;
360 776 int extend;
... ... @@ -26,6 +26,31 @@
26 26 #ifndef OCFS2_DIR_H
27 27 #define OCFS2_DIR_H
28 28  
  29 +struct buffer_head *ocfs2_find_entry(const char *name,
  30 + int namelen,
  31 + struct inode *dir,
  32 + struct ocfs2_dir_entry **res_dir);
  33 +int ocfs2_delete_entry(handle_t *handle,
  34 + struct inode *dir,
  35 + struct ocfs2_dir_entry *de_del,
  36 + struct buffer_head *bh);
  37 +int __ocfs2_add_entry(handle_t *handle,
  38 + struct inode *dir,
  39 + const char *name, int namelen,
  40 + struct inode *inode, u64 blkno,
  41 + struct buffer_head *parent_fe_bh,
  42 + struct buffer_head *insert_bh);
  43 +static inline int ocfs2_add_entry(handle_t *handle,
  44 + struct dentry *dentry,
  45 + struct inode *inode, u64 blkno,
  46 + struct buffer_head *parent_fe_bh,
  47 + struct buffer_head *insert_bh)
  48 +{
  49 + return __ocfs2_add_entry(handle, dentry->d_parent->d_inode,
  50 + dentry->d_name.name, dentry->d_name.len,
  51 + inode, blkno, parent_fe_bh, insert_bh);
  52 +}
  53 +
29 54 int ocfs2_check_dir_for_entry(struct inode *dir,
30 55 const char *name,
31 56 int namelen);
... ... @@ -44,12 +69,17 @@
44 69 int namelen,
45 70 struct buffer_head **ret_de_bh);
46 71 struct ocfs2_alloc_context;
47   -int ocfs2_do_extend_dir(struct super_block *sb,
48   - handle_t *handle,
49   - struct inode *dir,
50   - struct buffer_head *parent_fe_bh,
51   - struct ocfs2_alloc_context *data_ac,
52   - struct ocfs2_alloc_context *meta_ac,
53   - struct buffer_head **new_bh);
  72 +int ocfs2_fill_new_dir(struct ocfs2_super *osb,
  73 + handle_t *handle,
  74 + struct inode *parent,
  75 + struct inode *inode,
  76 + struct buffer_head *fe_bh,
  77 + struct ocfs2_alloc_context *data_ac);
  78 +
  79 +int ocfs2_check_dir_entry(struct inode *dir,
  80 + struct ocfs2_dir_entry *de,
  81 + struct buffer_head *bh,
  82 + unsigned long offset);
  83 +
54 84 #endif /* OCFS2_DIR_H */
... ... @@ -35,13 +35,13 @@
35 35 #include "ocfs2.h"
36 36  
37 37 #include "alloc.h"
  38 +#include "dir.h"
38 39 #include "dlmglue.h"
39 40 #include "extent_map.h"
40 41 #include "heartbeat.h"
41 42 #include "inode.h"
42 43 #include "journal.h"
43 44 #include "localalloc.h"
44   -#include "namei.h"
45 45 #include "slot_map.h"
46 46 #include "super.h"
47 47 #include "vote.h"
... ... @@ -64,29 +64,6 @@
64 64  
65 65 #include "buffer_head_io.h"
66 66  
67   -#define NAMEI_RA_CHUNKS 2
68   -#define NAMEI_RA_BLOCKS 4
69   -#define NAMEI_RA_SIZE (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
70   -#define NAMEI_RA_INDEX(c,b) (((c) * NAMEI_RA_BLOCKS) + (b))
71   -
72   -static int inline ocfs2_search_dirblock(struct buffer_head *bh,
73   - struct inode *dir,
74   - const char *name, int namelen,
75   - unsigned long offset,
76   - struct ocfs2_dir_entry **res_dir);
77   -
78   -static int ocfs2_delete_entry(handle_t *handle,
79   - struct inode *dir,
80   - struct ocfs2_dir_entry *de_del,
81   - struct buffer_head *bh);
82   -
83   -static int __ocfs2_add_entry(handle_t *handle,
84   - struct inode *dir,
85   - const char *name, int namelen,
86   - struct inode *inode, u64 blkno,
87   - struct buffer_head *parent_fe_bh,
88   - struct buffer_head *insert_bh);
89   -
90 67 static int ocfs2_mknod_locked(struct ocfs2_super *osb,
91 68 struct inode *dir,
92 69 struct dentry *dentry, int mode,
... ... @@ -97,13 +74,6 @@
97 74 struct inode **ret_inode,
98 75 struct ocfs2_alloc_context *inode_ac);
99 76  
100   -static int ocfs2_fill_new_dir(struct ocfs2_super *osb,
101   - handle_t *handle,
102   - struct inode *parent,
103   - struct inode *inode,
104   - struct buffer_head *fe_bh,
105   - struct ocfs2_alloc_context *data_ac);
106   -
107 77 static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
108 78 struct inode **ret_orphan_dir,
109 79 struct inode *inode,
... ... @@ -123,17 +93,6 @@
123 93 struct inode *inode,
124 94 const char *symname);
125 95  
126   -static inline int ocfs2_add_entry(handle_t *handle,
127   - struct dentry *dentry,
128   - struct inode *inode, u64 blkno,
129   - struct buffer_head *parent_fe_bh,
130   - struct buffer_head *insert_bh)
131   -{
132   - return __ocfs2_add_entry(handle, dentry->d_parent->d_inode,
133   - dentry->d_name.name, dentry->d_name.len,
134   - inode, blkno, parent_fe_bh, insert_bh);
135   -}
136   -
137 96 /* An orphan dir name is an 8 byte value, printed as a hex string */
138 97 #define OCFS2_ORPHAN_NAMELEN ((int)(2 * sizeof(u64)))
139 98  
... ... @@ -232,75 +191,6 @@
232 191 return ret;
233 192 }
234 193  
235   -static int ocfs2_fill_new_dir(struct ocfs2_super *osb,
236   - handle_t *handle,
237   - struct inode *parent,
238   - struct inode *inode,
239   - struct buffer_head *fe_bh,
240   - struct ocfs2_alloc_context *data_ac)
241   -{
242   - int status;
243   - struct buffer_head *new_bh = NULL;
244   - struct ocfs2_dir_entry *de = NULL;
245   -
246   - mlog_entry_void();
247   -
248   - status = ocfs2_do_extend_dir(osb->sb, handle, inode, fe_bh,
249   - data_ac, NULL, &new_bh);
250   - if (status < 0) {
251   - mlog_errno(status);
252   - goto bail;
253   - }
254   -
255   - ocfs2_set_new_buffer_uptodate(inode, new_bh);
256   -
257   - status = ocfs2_journal_access(handle, inode, new_bh,
258   - OCFS2_JOURNAL_ACCESS_CREATE);
259   - if (status < 0) {
260   - mlog_errno(status);
261   - goto bail;
262   - }
263   - memset(new_bh->b_data, 0, osb->sb->s_blocksize);
264   -
265   - de = (struct ocfs2_dir_entry *) new_bh->b_data;
266   - de->inode = cpu_to_le64(OCFS2_I(inode)->ip_blkno);
267   - de->name_len = 1;
268   - de->rec_len =
269   - cpu_to_le16(OCFS2_DIR_REC_LEN(de->name_len));
270   - strcpy(de->name, ".");
271   - ocfs2_set_de_type(de, S_IFDIR);
272   - de = (struct ocfs2_dir_entry *) ((char *)de + le16_to_cpu(de->rec_len));
273   - de->inode = cpu_to_le64(OCFS2_I(parent)->ip_blkno);
274   - de->rec_len = cpu_to_le16(inode->i_sb->s_blocksize -
275   - OCFS2_DIR_REC_LEN(1));
276   - de->name_len = 2;
277   - strcpy(de->name, "..");
278   - ocfs2_set_de_type(de, S_IFDIR);
279   -
280   - status = ocfs2_journal_dirty(handle, new_bh);
281   - if (status < 0) {
282   - mlog_errno(status);
283   - goto bail;
284   - }
285   -
286   - i_size_write(inode, inode->i_sb->s_blocksize);
287   - inode->i_nlink = 2;
288   - inode->i_blocks = ocfs2_inode_sector_count(inode);
289   - status = ocfs2_mark_inode_dirty(handle, inode, fe_bh);
290   - if (status < 0) {
291   - mlog_errno(status);
292   - goto bail;
293   - }
294   -
295   - status = 0;
296   -bail:
297   - if (new_bh)
298   - brelse(new_bh);
299   -
300   - mlog_exit(status);
301   - return status;
302   -}
303   -
304 194 static int ocfs2_mknod(struct inode *dir,
305 195 struct dentry *dentry,
306 196 int mode,
... ... @@ -1765,329 +1655,6 @@
1765 1655 mlog_exit(status);
1766 1656  
1767 1657 return status;
1768   -}
1769   -
1770   -int ocfs2_check_dir_entry(struct inode * dir,
1771   - struct ocfs2_dir_entry * de,
1772   - struct buffer_head * bh,
1773   - unsigned long offset)
1774   -{
1775   - const char *error_msg = NULL;
1776   - const int rlen = le16_to_cpu(de->rec_len);
1777   -
1778   - if (rlen < OCFS2_DIR_REC_LEN(1))
1779   - error_msg = "rec_len is smaller than minimal";
1780   - else if (rlen % 4 != 0)
1781   - error_msg = "rec_len % 4 != 0";
1782   - else if (rlen < OCFS2_DIR_REC_LEN(de->name_len))
1783   - error_msg = "rec_len is too small for name_len";
1784   - else if (((char *) de - bh->b_data) + rlen > dir->i_sb->s_blocksize)
1785   - error_msg = "directory entry across blocks";
1786   -
1787   - if (error_msg != NULL)
1788   - mlog(ML_ERROR, "bad entry in directory #%llu: %s - "
1789   - "offset=%lu, inode=%llu, rec_len=%d, name_len=%d\n",
1790   - (unsigned long long)OCFS2_I(dir)->ip_blkno, error_msg,
1791   - offset, (unsigned long long)le64_to_cpu(de->inode), rlen,
1792   - de->name_len);
1793   - return error_msg == NULL ? 1 : 0;
1794   -}
1795   -
1796   -/* we don't always have a dentry for what we want to add, so people
1797   - * like orphan dir can call this instead.
1798   - *
1799   - * If you pass me insert_bh, I'll skip the search of the other dir
1800   - * blocks and put the record in there.
1801   - */
1802   -static int __ocfs2_add_entry(handle_t *handle,
1803   - struct inode *dir,
1804   - const char *name, int namelen,
1805   - struct inode *inode, u64 blkno,
1806   - struct buffer_head *parent_fe_bh,
1807   - struct buffer_head *insert_bh)
1808   -{
1809   - unsigned long offset;
1810   - unsigned short rec_len;
1811   - struct ocfs2_dir_entry *de, *de1;
1812   - struct super_block *sb;
1813   - int retval, status;
1814   -
1815   - mlog_entry_void();
1816   -
1817   - sb = dir->i_sb;
1818   -
1819   - if (!namelen)
1820   - return -EINVAL;
1821   -
1822   - rec_len = OCFS2_DIR_REC_LEN(namelen);
1823   - offset = 0;
1824   - de = (struct ocfs2_dir_entry *) insert_bh->b_data;
1825   - while (1) {
1826   - BUG_ON((char *)de >= sb->s_blocksize + insert_bh->b_data);
1827   - /* These checks should've already been passed by the
1828   - * prepare function, but I guess we can leave them
1829   - * here anyway. */
1830   - if (!ocfs2_check_dir_entry(dir, de, insert_bh, offset)) {
1831   - retval = -ENOENT;
1832   - goto bail;
1833   - }
1834   - if (ocfs2_match(namelen, name, de)) {
1835   - retval = -EEXIST;
1836   - goto bail;
1837   - }
1838   - if (((le64_to_cpu(de->inode) == 0) &&
1839   - (le16_to_cpu(de->rec_len) >= rec_len)) ||
1840   - (le16_to_cpu(de->rec_len) >=
1841   - (OCFS2_DIR_REC_LEN(de->name_len) + rec_len))) {
1842   - dir->i_mtime = dir->i_ctime = CURRENT_TIME;
1843   - retval = ocfs2_mark_inode_dirty(handle, dir, parent_fe_bh);
1844   - if (retval < 0) {
1845   - mlog_errno(retval);
1846   - goto bail;
1847   - }
1848   -
1849   - status = ocfs2_journal_access(handle, dir, insert_bh,
1850   - OCFS2_JOURNAL_ACCESS_WRITE);
1851   - /* By now the buffer is marked for journaling */
1852   - offset += le16_to_cpu(de->rec_len);
1853   - if (le64_to_cpu(de->inode)) {
1854   - de1 = (struct ocfs2_dir_entry *)((char *) de +
1855   - OCFS2_DIR_REC_LEN(de->name_len));
1856   - de1->rec_len =
1857   - cpu_to_le16(le16_to_cpu(de->rec_len) -
1858   - OCFS2_DIR_REC_LEN(de->name_len));
1859   - de->rec_len = cpu_to_le16(OCFS2_DIR_REC_LEN(de->name_len));
1860   - de = de1;
1861   - }
1862   - de->file_type = OCFS2_FT_UNKNOWN;
1863   - if (blkno) {
1864   - de->inode = cpu_to_le64(blkno);
1865   - ocfs2_set_de_type(de, inode->i_mode);
1866   - } else
1867   - de->inode = 0;
1868   - de->name_len = namelen;
1869   - memcpy(de->name, name, namelen);
1870   -
1871   - dir->i_version++;
1872   - status = ocfs2_journal_dirty(handle, insert_bh);
1873   - retval = 0;
1874   - goto bail;
1875   - }
1876   - offset += le16_to_cpu(de->rec_len);
1877   - de = (struct ocfs2_dir_entry *) ((char *) de + le16_to_cpu(de->rec_len));
1878   - }
1879   -
1880   - /* when you think about it, the assert above should prevent us
1881   - * from ever getting here. */
1882   - retval = -ENOSPC;
1883   -bail:
1884   -
1885   - mlog_exit(retval);
1886   - return retval;
1887   -}
1888   -
1889   -
1890   -/*
1891   - * ocfs2_delete_entry deletes a directory entry by merging it with the
1892   - * previous entry
1893   - */
1894   -static int ocfs2_delete_entry(handle_t *handle,
1895   - struct inode *dir,
1896   - struct ocfs2_dir_entry *de_del,
1897   - struct buffer_head *bh)
1898   -{
1899   - struct ocfs2_dir_entry *de, *pde;
1900   - int i, status = -ENOENT;
1901   -
1902   - mlog_entry("(0x%p, 0x%p, 0x%p, 0x%p)\n", handle, dir, de_del, bh);
1903   -
1904   - i = 0;
1905   - pde = NULL;
1906   - de = (struct ocfs2_dir_entry *) bh->b_data;
1907   - while (i < bh->b_size) {
1908   - if (!ocfs2_check_dir_entry(dir, de, bh, i)) {
1909   - status = -EIO;
1910   - mlog_errno(status);
1911   - goto bail;
1912   - }
1913   - if (de == de_del) {
1914   - status = ocfs2_journal_access(handle, dir, bh,
1915   - OCFS2_JOURNAL_ACCESS_WRITE);
1916   - if (status < 0) {
1917   - status = -EIO;
1918   - mlog_errno(status);
1919   - goto bail;
1920   - }
1921   - if (pde)
1922   - pde->rec_len =
1923   - cpu_to_le16(le16_to_cpu(pde->rec_len) +
1924   - le16_to_cpu(de->rec_len));
1925   - else
1926   - de->inode = 0;
1927   - dir->i_version++;
1928   - status = ocfs2_journal_dirty(handle, bh);
1929   - goto bail;
1930   - }
1931   - i += le16_to_cpu(de->rec_len);
1932   - pde = de;
1933   - de = (struct ocfs2_dir_entry *)((char *)de + le16_to_cpu(de->rec_len));
1934   - }
1935   -bail:
1936   - mlog_exit(status);
1937   - return status;
1938   -}
1939   -
1940   -/*
1941   - * Returns 0 if not found, -1 on failure, and 1 on success
1942   - */
1943   -static int inline ocfs2_search_dirblock(struct buffer_head *bh,
1944   - struct inode *dir,
1945   - const char *name, int namelen,
1946   - unsigned long offset,
1947   - struct ocfs2_dir_entry **res_dir)
1948   -{
1949   - struct ocfs2_dir_entry *de;
1950   - char *dlimit, *de_buf;
1951   - int de_len;
1952   - int ret = 0;
1953   -
1954   - mlog_entry_void();
1955   -
1956   - de_buf = bh->b_data;
1957   - dlimit = de_buf + dir->i_sb->s_blocksize;
1958   -
1959   - while (de_buf < dlimit) {
1960   - /* this code is executed quadratically often */
1961   - /* do minimal checking `by hand' */
1962   -
1963   - de = (struct ocfs2_dir_entry *) de_buf;
1964   -
1965   - if (de_buf + namelen <= dlimit &&
1966   - ocfs2_match(namelen, name, de)) {
1967   - /* found a match - just to be sure, do a full check */
1968   - if (!ocfs2_check_dir_entry(dir, de, bh, offset)) {
1969   - ret = -1;
1970   - goto bail;
1971   - }
1972   - *res_dir = de;
1973   - ret = 1;
1974   - goto bail;
1975   - }
1976   -
1977   - /* prevent looping on a bad block */
1978   - de_len = le16_to_cpu(de->rec_len);
1979   - if (de_len <= 0) {
1980   - ret = -1;
1981   - goto bail;
1982   - }
1983   -
1984   - de_buf += de_len;
1985   - offset += de_len;
1986   - }
1987   -
1988   -bail:
1989   - mlog_exit(ret);
1990   - return ret;
1991   -}
1992   -
1993   -struct buffer_head *ocfs2_find_entry(const char *name, int namelen,
1994   - struct inode *dir,
1995   - struct ocfs2_dir_entry **res_dir)
1996   -{
1997   - struct super_block *sb;
1998   - struct buffer_head *bh_use[NAMEI_RA_SIZE];
1999   - struct buffer_head *bh, *ret = NULL;
2000   - unsigned long start, block, b;
2001   - int ra_max = 0; /* Number of bh's in the readahead
2002   - buffer, bh_use[] */
2003   - int ra_ptr = 0; /* Current index into readahead
2004   - buffer */
2005   - int num = 0;
2006   - int nblocks, i, err;
2007   -
2008   - mlog_entry_void();
2009   -
2010   - *res_dir = NULL;
2011   - sb = dir->i_sb;
2012   -
2013   - nblocks = i_size_read(dir) >> sb->s_blocksize_bits;
2014   - start = OCFS2_I(dir)->ip_dir_start_lookup;
2015   - if (start >= nblocks)
2016   - start = 0;
2017   - block = start;
2018   -
2019   -restart:
2020   - do {
2021   - /*
2022   - * We deal with the read-ahead logic here.
2023   - */
2024   - if (ra_ptr >= ra_max) {
2025   - /* Refill the readahead buffer */
2026   - ra_ptr = 0;
2027   - b = block;
2028   - for (ra_max = 0; ra_max < NAMEI_RA_SIZE; ra_max++) {
2029   - /*
2030   - * Terminate if we reach the end of the
2031   - * directory and must wrap, or if our
2032   - * search has finished at this block.
2033   - */
2034   - if (b >= nblocks || (num && block == start)) {
2035   - bh_use[ra_max] = NULL;
2036   - break;
2037   - }
2038   - num++;
2039   -
2040   - bh = ocfs2_bread(dir, b++, &err, 1);
2041   - bh_use[ra_max] = bh;
2042   - }
2043   - }
2044   - if ((bh = bh_use[ra_ptr++]) == NULL)
2045   - goto next;
2046   - wait_on_buffer(bh);
2047   - if (!buffer_uptodate(bh)) {
2048   - /* read error, skip block & hope for the best */
2049   - ocfs2_error(dir->i_sb, "reading directory %llu, "
2050   - "offset %lu\n",
2051   - (unsigned long long)OCFS2_I(dir)->ip_blkno,
2052   - block);
2053   - brelse(bh);
2054   - goto next;
2055   - }
2056   - i = ocfs2_search_dirblock(bh, dir, name, namelen,
2057   - block << sb->s_blocksize_bits,
2058   - res_dir);
2059   - if (i == 1) {
2060   - OCFS2_I(dir)->ip_dir_start_lookup = block;
2061   - ret = bh;
2062   - goto cleanup_and_exit;
2063   - } else {
2064   - brelse(bh);
2065   - if (i < 0)
2066   - goto cleanup_and_exit;
2067   - }
2068   - next:
2069   - if (++block >= nblocks)
2070   - block = 0;
2071   - } while (block != start);
2072   -
2073   - /*
2074   - * If the directory has grown while we were searching, then
2075   - * search the last part of the directory before giving up.
2076   - */
2077   - block = nblocks;
2078   - nblocks = i_size_read(dir) >> sb->s_blocksize_bits;
2079   - if (block < nblocks) {
2080   - start = 0;
2081   - goto restart;
2082   - }
2083   -
2084   -cleanup_and_exit:
2085   - /* Clean up the read-ahead blocks */
2086   - for (; ra_ptr < ra_max; ra_ptr++)
2087   - brelse(bh_use[ra_ptr]);
2088   -
2089   - mlog_exit_ptr(ret);
2090   - return ret;
2091 1658 }
2092 1659  
2093 1660 static int ocfs2_blkno_stringify(u64 blkno, char *name)
... ... @@ -30,30 +30,11 @@
30 30  
31 31 struct dentry *ocfs2_get_parent(struct dentry *child);
32 32  
33   -int ocfs2_check_dir_entry (struct inode *dir,
34   - struct ocfs2_dir_entry *de,
35   - struct buffer_head *bh,
36   - unsigned long offset);
37   -struct buffer_head *ocfs2_find_entry(const char *name,
38   - int namelen,
39   - struct inode *dir,
40   - struct ocfs2_dir_entry **res_dir);
41 33 int ocfs2_orphan_del(struct ocfs2_super *osb,
42 34 handle_t *handle,
43 35 struct inode *orphan_dir_inode,
44 36 struct inode *inode,
45 37 struct buffer_head *orphan_dir_bh);
46   -
47   -static inline int ocfs2_match(int len,
48   - const char * const name,
49   - struct ocfs2_dir_entry *de)
50   -{
51   - if (len != de->name_len)
52   - return 0;
53   - if (!de->inode)
54   - return 0;
55   - return !memcmp(name, de->name, len);
56   -}
57 38  
58 39 #endif /* OCFS2_NAMEI_H */