36 static inline unsigned exofs_chunk_size(
struct inode *
inode)
38 return inode->
i_sb->s_blocksize;
41 static inline void exofs_put_page(
struct page *
page)
48 static inline unsigned long dir_pages(
struct inode *
inode)
53 static unsigned exofs_last_byte(
struct inode *inode,
unsigned long page_nr)
55 loff_t last_byte = inode->
i_size;
63 static int exofs_commit_chunk(
struct page *
page, loff_t
pos,
unsigned len)
66 struct inode *
dir = mapping->
host;
71 if (!PageUptodate(page))
72 SetPageUptodate(page);
74 if (pos+len > dir->
i_size) {
75 i_size_write(dir, pos+len);
76 mark_inode_dirty(dir);
88 static void exofs_check_page(
struct page *page)
90 struct inode *dir = page->
mapping->host;
91 unsigned chunk_size = exofs_chunk_size(dir);
99 if ((dir->
i_size >> PAGE_CACHE_SHIFT) == page->
index) {
101 if (limit & (chunk_size - 1))
116 if (((offs + rec_len - 1) ^ offs) & ~(chunk_size-1))
122 SetPageChecked(page);
127 "size of directory(0x%lx) is not a multiple of chunk size\n",
132 error =
"rec_len is smaller than minimal";
135 error =
"unaligned directory entry";
138 error =
"rec_len is too small for name_len";
141 error =
"directory entry across blocks";
145 "ERROR [exofs_check_page]: bad entry in directory(0x%lx): %s - "
146 "offset=%lu, inode=0x%llu, rec_len=%d, name_len=%d\n",
147 dir->
i_ino, error, (page->
index<<PAGE_CACHE_SHIFT)+offs,
154 "entry in directory(0x%lx) spans the page boundary"
155 "offset=%lu, inode=0x%llx\n",
156 dir->
i_ino, (page->
index<<PAGE_CACHE_SHIFT)+offs,
159 SetPageChecked(page);
163 static struct page *exofs_get_page(
struct inode *dir,
unsigned long n)
166 struct page *page = read_mapping_page(mapping, n,
NULL);
170 if (!PageChecked(page))
171 exofs_check_page(page);
178 exofs_put_page(page);
179 return ERR_PTR(-
EIO);
182 static inline int exofs_match(
int len,
const unsigned char *
name,
198 static inline unsigned
199 exofs_validate_entry(
char *base,
unsigned offset,
unsigned mask)
204 while ((
char *)p < (
char *)de) {
207 p = exofs_next_entry(p);
209 return (
char *)p - base;
212 static unsigned char exofs_filetype_table[
EXOFS_FT_MAX] = {
224 static unsigned char exofs_type_by_mode[
S_IFMT >>
S_SHIFT] = {
235 void exofs_set_de_type(
struct exofs_dir_entry *de,
struct inode *inode)
244 loff_t pos = filp->
f_pos;
245 struct inode *inode = filp->
f_path.dentry->d_inode;
248 unsigned long npages = dir_pages(inode);
249 unsigned chunk_mask = ~(exofs_chunk_size(inode)-1);
250 unsigned char *types =
NULL;
256 types = exofs_filetype_table;
258 for ( ; n < npages; n++, offset = 0) {
261 struct page *page = exofs_get_page(inode, n);
264 EXOFS_ERR(
"ERROR: bad page in directory(0x%lx)\n",
267 return PTR_ERR(page);
272 offset = exofs_validate_entry(kaddr, offset,
280 limit = kaddr + exofs_last_byte(inode, n) -
282 for (; (
char *)de <= limit; de = exofs_next_entry(de)) {
285 "zero-length entry in directory(0x%lx)\n",
287 exofs_put_page(page);
297 offset = (
char *)de - kaddr;
299 (n<<PAGE_CACHE_SHIFT) | offset,
303 exofs_put_page(page);
309 exofs_put_page(page);
318 const unsigned char *name = dentry->
d_name.name;
322 unsigned long npages = dir_pages(dir);
323 struct page *page =
NULL;
338 page = exofs_get_page(dir, n);
342 kaddr += exofs_last_byte(dir, n) - reclen;
343 while ((
char *) de <= kaddr) {
346 "directory(0x%lx)\n",
348 exofs_put_page(page);
351 if (exofs_match(namelen, name, de))
353 de = exofs_next_entry(de);
355 exofs_put_page(page);
359 }
while (n != start);
371 struct page *page = exofs_get_page(dir, 0);
375 de = exofs_next_entry(
393 exofs_put_page(page);
406 exofs_put_page(page);
412 struct page *page,
struct inode *inode)
423 EXOFS_ERR(
"exofs_set_link: exofs_write_begin FAILED => %d\n",
427 exofs_set_de_type(de, inode);
429 err = exofs_commit_chunk(page, pos, len);
430 exofs_put_page(page);
432 mark_inode_dirty(dir);
438 struct inode *dir = dentry->
d_parent->d_inode;
439 const unsigned char *name = dentry->
d_name.name;
441 unsigned chunk_size = exofs_chunk_size(dir);
444 struct page *page =
NULL;
447 unsigned long npages = dir_pages(dir);
453 for (n = 0; n <= npages; n++) {
456 page = exofs_get_page(dir, n);
462 dir_end = kaddr + exofs_last_byte(dir, n);
465 while ((
char *)de <= kaddr) {
466 if ((
char *)de == dir_end) {
468 rec_len = chunk_size;
475 "zero-length entry in directory(0x%lx)\n",
481 if (exofs_match(namelen, name, de))
485 if (!de->
inode_no && rec_len >= reclen)
487 if (rec_len >= name_len + reclen)
492 exofs_put_page(page);
495 EXOFS_ERR(
"exofs_add_link: BAD dentry=%p or inode=0x%lx\n",
496 dentry, inode->
i_ino);
516 exofs_set_de_type(de, inode);
517 err = exofs_commit_chunk(page, pos, rec_len);
519 mark_inode_dirty(dir);
523 exofs_put_page(page);
534 struct inode *inode = mapping->
host;
537 unsigned from = ((
char *)dir - kaddr) & ~(exofs_chunk_size(inode)-1);
547 "zero-length entry in directory(0x%lx)\n",
553 de = exofs_next_entry(de);
562 EXOFS_ERR(
"exofs_delete_entry: exofs_write_begin FAILED => %d\n",
568 err = exofs_commit_chunk(page, pos, to - from);
570 mark_inode_dirty(inode);
573 exofs_put_page(page);
578 #define THIS_DIR ".\0\0"
579 #define PARENT_DIR "..\0"
584 struct page *page = grab_cache_page(mapping, 0);
585 unsigned chunk_size = exofs_chunk_size(inode);
606 exofs_set_de_type(de, inode);
613 exofs_set_de_type(de, inode);
615 err = exofs_commit_chunk(page, 0, chunk_size);
623 struct page *page =
NULL;
624 unsigned long i, npages = dir_pages(inode);
626 for (i = 0; i < npages; i++) {
629 page = exofs_get_page(inode, i);
638 while ((
char *)de <= kaddr) {
641 "zero-length directory entry"
642 "kaddr=%p, de=%p\n", kaddr, de);
647 if (de->
name[0] !=
'.')
655 }
else if (de->
name[1] !=
'.')
658 de = exofs_next_entry(de);
660 exofs_put_page(page);
665 exofs_put_page(page);
672 .readdir = exofs_readdir,