aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ocfs2/dir.c430
-rw-r--r--fs/ocfs2/dir.h44
-rw-r--r--fs/ocfs2/journal.c2
-rw-r--r--fs/ocfs2/namei.c433
-rw-r--r--fs/ocfs2/namei.h19
5 files changed, 461 insertions, 467 deletions
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index 0d5fdde959c8..8e0ae022b2e9 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -55,10 +55,16 @@
55#include "journal.h" 55#include "journal.h"
56#include "namei.h" 56#include "namei.h"
57#include "suballoc.h" 57#include "suballoc.h"
58#include "super.h"
58#include "uptodate.h" 59#include "uptodate.h"
59 60
60#include "buffer_head_io.h" 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
62static unsigned char ocfs2_filetype_table[] = { 68static unsigned char ocfs2_filetype_table[] = {
63 DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK 69 DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK
64}; 70};
@@ -67,6 +73,347 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,
67 struct inode *dir, 73 struct inode *dir,
68 struct buffer_head *parent_fe_bh, 74 struct buffer_head *parent_fe_bh,
69 struct buffer_head **new_de_bh); 75 struct buffer_head **new_de_bh);
76static 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
84int 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
110static 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
121/*
122 * Returns 0 if not found, -1 on failure, and 1 on success
123 */
124static 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
169bail:
170 mlog_exit(ret);
171 return ret;
172}
173
174struct 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
200restart:
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
265cleanup_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 */
278int 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 }
319bail:
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 */
330int __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;
411bail:
412
413 mlog_exit(retval);
414 return retval;
415}
416
70/* 417/*
71 * ocfs2_readdir() 418 * ocfs2_readdir()
72 * 419 *
@@ -347,14 +694,83 @@ int ocfs2_empty_dir(struct inode *inode)
347 return 1; 694 return 1;
348} 695}
349 696
697int 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;
758bail:
759 if (new_bh)
760 brelse(new_bh);
761
762 mlog_exit(status);
763 return status;
764}
765
350/* returns a bh of the 1st new block in the allocation. */ 766/* returns a bh of the 1st new block in the allocation. */
351int ocfs2_do_extend_dir(struct super_block *sb, 767static int ocfs2_do_extend_dir(struct super_block *sb,
352 handle_t *handle, 768 handle_t *handle,
353 struct inode *dir, 769 struct inode *dir,
354 struct buffer_head *parent_fe_bh, 770 struct buffer_head *parent_fe_bh,
355 struct ocfs2_alloc_context *data_ac, 771 struct ocfs2_alloc_context *data_ac,
356 struct ocfs2_alloc_context *meta_ac, 772 struct ocfs2_alloc_context *meta_ac,
357 struct buffer_head **new_bh) 773 struct buffer_head **new_bh)
358{ 774{
359 int status; 775 int status;
360 int extend; 776 int extend;
diff --git a/fs/ocfs2/dir.h b/fs/ocfs2/dir.h
index 3f67e146864a..7bf9c0a01cdf 100644
--- a/fs/ocfs2/dir.h
+++ b/fs/ocfs2/dir.h
@@ -26,6 +26,31 @@
26#ifndef OCFS2_DIR_H 26#ifndef OCFS2_DIR_H
27#define OCFS2_DIR_H 27#define OCFS2_DIR_H
28 28
29struct buffer_head *ocfs2_find_entry(const char *name,
30 int namelen,
31 struct inode *dir,
32 struct ocfs2_dir_entry **res_dir);
33int ocfs2_delete_entry(handle_t *handle,
34 struct inode *dir,
35 struct ocfs2_dir_entry *de_del,
36 struct buffer_head *bh);
37int __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);
43static 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
29int ocfs2_check_dir_for_entry(struct inode *dir, 54int ocfs2_check_dir_for_entry(struct inode *dir,
30 const char *name, 55 const char *name,
31 int namelen); 56 int namelen);
@@ -44,11 +69,16 @@ int ocfs2_prepare_dir_for_insert(struct ocfs2_super *osb,
44 int namelen, 69 int namelen,
45 struct buffer_head **ret_de_bh); 70 struct buffer_head **ret_de_bh);
46struct ocfs2_alloc_context; 71struct ocfs2_alloc_context;
47int ocfs2_do_extend_dir(struct super_block *sb, 72int ocfs2_fill_new_dir(struct ocfs2_super *osb,
48 handle_t *handle, 73 handle_t *handle,
49 struct inode *dir, 74 struct inode *parent,
50 struct buffer_head *parent_fe_bh, 75 struct inode *inode,
51 struct ocfs2_alloc_context *data_ac, 76 struct buffer_head *fe_bh,
52 struct ocfs2_alloc_context *meta_ac, 77 struct ocfs2_alloc_context *data_ac);
53 struct buffer_head **new_bh); 78
79int ocfs2_check_dir_entry(struct inode *dir,
80 struct ocfs2_dir_entry *de,
81 struct buffer_head *bh,
82 unsigned long offset);
83
54#endif /* OCFS2_DIR_H */ 84#endif /* OCFS2_DIR_H */
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
index dbfb20bb27ea..8bbfc80e5c5c 100644
--- a/fs/ocfs2/journal.c
+++ b/fs/ocfs2/journal.c
@@ -35,13 +35,13 @@
35#include "ocfs2.h" 35#include "ocfs2.h"
36 36
37#include "alloc.h" 37#include "alloc.h"
38#include "dir.h"
38#include "dlmglue.h" 39#include "dlmglue.h"
39#include "extent_map.h" 40#include "extent_map.h"
40#include "heartbeat.h" 41#include "heartbeat.h"
41#include "inode.h" 42#include "inode.h"
42#include "journal.h" 43#include "journal.h"
43#include "localalloc.h" 44#include "localalloc.h"
44#include "namei.h"
45#include "slot_map.h" 45#include "slot_map.h"
46#include "super.h" 46#include "super.h"
47#include "vote.h" 47#include "vote.h"
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index 701e6d04ed5d..aae6c0bf6696 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -64,29 +64,6 @@
64 64
65#include "buffer_head_io.h" 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
72static 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
78static int ocfs2_delete_entry(handle_t *handle,
79 struct inode *dir,
80 struct ocfs2_dir_entry *de_del,
81 struct buffer_head *bh);
82
83static 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
90static int ocfs2_mknod_locked(struct ocfs2_super *osb, 67static int ocfs2_mknod_locked(struct ocfs2_super *osb,
91 struct inode *dir, 68 struct inode *dir,
92 struct dentry *dentry, int mode, 69 struct dentry *dentry, int mode,
@@ -97,13 +74,6 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
97 struct inode **ret_inode, 74 struct inode **ret_inode,
98 struct ocfs2_alloc_context *inode_ac); 75 struct ocfs2_alloc_context *inode_ac);
99 76
100static 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
107static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, 77static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
108 struct inode **ret_orphan_dir, 78 struct inode **ret_orphan_dir,
109 struct inode *inode, 79 struct inode *inode,
@@ -123,17 +93,6 @@ static int ocfs2_create_symlink_data(struct ocfs2_super *osb,
123 struct inode *inode, 93 struct inode *inode,
124 const char *symname); 94 const char *symname);
125 95
126static 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/* An orphan dir name is an 8 byte value, printed as a hex string */ 96/* An orphan dir name is an 8 byte value, printed as a hex string */
138#define OCFS2_ORPHAN_NAMELEN ((int)(2 * sizeof(u64))) 97#define OCFS2_ORPHAN_NAMELEN ((int)(2 * sizeof(u64)))
139 98
@@ -232,75 +191,6 @@ bail:
232 return ret; 191 return ret;
233} 192}
234 193
235static 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;
296bail:
297 if (new_bh)
298 brelse(new_bh);
299
300 mlog_exit(status);
301 return status;
302}
303
304static int ocfs2_mknod(struct inode *dir, 194static int ocfs2_mknod(struct inode *dir,
305 struct dentry *dentry, 195 struct dentry *dentry,
306 int mode, 196 int mode,
@@ -1767,329 +1657,6 @@ bail:
1767 return status; 1657 return status;
1768} 1658}
1769 1659
1770int 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 */
1802static 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;
1883bail:
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 */
1894static 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 }
1935bail:
1936 mlog_exit(status);
1937 return status;
1938}
1939
1940/*
1941 * Returns 0 if not found, -1 on failure, and 1 on success
1942 */
1943static 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
1988bail:
1989 mlog_exit(ret);
1990 return ret;
1991}
1992
1993struct 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
2019restart:
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
2084cleanup_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}
2092
2093static int ocfs2_blkno_stringify(u64 blkno, char *name) 1660static int ocfs2_blkno_stringify(u64 blkno, char *name)
2094{ 1661{
2095 int status, namelen; 1662 int status, namelen;
diff --git a/fs/ocfs2/namei.h b/fs/ocfs2/namei.h
index 0975c7b7212b..688aef64c879 100644
--- a/fs/ocfs2/namei.h
+++ b/fs/ocfs2/namei.h
@@ -30,29 +30,10 @@ extern const struct inode_operations ocfs2_dir_iops;
30 30
31struct dentry *ocfs2_get_parent(struct dentry *child); 31struct dentry *ocfs2_get_parent(struct dentry *child);
32 32
33int ocfs2_check_dir_entry (struct inode *dir,
34 struct ocfs2_dir_entry *de,
35 struct buffer_head *bh,
36 unsigned long offset);
37struct buffer_head *ocfs2_find_entry(const char *name,
38 int namelen,
39 struct inode *dir,
40 struct ocfs2_dir_entry **res_dir);
41int ocfs2_orphan_del(struct ocfs2_super *osb, 33int ocfs2_orphan_del(struct ocfs2_super *osb,
42 handle_t *handle, 34 handle_t *handle,
43 struct inode *orphan_dir_inode, 35 struct inode *orphan_dir_inode,
44 struct inode *inode, 36 struct inode *inode,
45 struct buffer_head *orphan_dir_bh); 37 struct buffer_head *orphan_dir_bh);
46 38
47static 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
58#endif /* OCFS2_NAMEI_H */ 39#endif /* OCFS2_NAMEI_H */