diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/Kconfig | 6 | ||||
-rw-r--r-- | fs/dquot.c | 7 | ||||
-rw-r--r-- | fs/jffs/intrep.c | 114 | ||||
-rw-r--r-- | fs/jffs/intrep.h | 2 | ||||
-rw-r--r-- | fs/jffs/jffs_fm.c | 105 | ||||
-rw-r--r-- | fs/jffs/jffs_fm.h | 3 | ||||
-rw-r--r-- | fs/libfs.c | 1 | ||||
-rw-r--r-- | fs/ncpfs/dir.c | 13 | ||||
-rw-r--r-- | fs/ncpfs/ncplib_kernel.c | 40 | ||||
-rw-r--r-- | fs/ncpfs/ncplib_kernel.h | 3 | ||||
-rw-r--r-- | fs/partitions/Makefile | 1 | ||||
-rw-r--r-- | fs/partitions/check.c | 3 | ||||
-rw-r--r-- | fs/partitions/check.h | 4 | ||||
-rw-r--r-- | fs/partitions/msdos.c | 4 | ||||
-rw-r--r-- | fs/proc/Makefile | 1 | ||||
-rw-r--r-- | fs/proc/proc_misc.c | 6 | ||||
-rw-r--r-- | fs/proc/vmcore.c | 669 | ||||
-rw-r--r-- | fs/reiserfs/inode.c | 15 |
18 files changed, 811 insertions, 186 deletions
diff --git a/fs/Kconfig b/fs/Kconfig index 8157f2e2d515..062177956239 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
@@ -734,6 +734,12 @@ config PROC_KCORE | |||
734 | bool "/proc/kcore support" if !ARM | 734 | bool "/proc/kcore support" if !ARM |
735 | depends on PROC_FS && MMU | 735 | depends on PROC_FS && MMU |
736 | 736 | ||
737 | config PROC_VMCORE | ||
738 | bool "/proc/vmcore support (EXPERIMENTAL)" | ||
739 | depends on PROC_FS && EMBEDDED && EXPERIMENTAL && CRASH_DUMP | ||
740 | help | ||
741 | Exports the dump image of crashed kernel in ELF format. | ||
742 | |||
737 | config SYSFS | 743 | config SYSFS |
738 | bool "sysfs file system support" if EMBEDDED | 744 | bool "sysfs file system support" if EMBEDDED |
739 | default y | 745 | default y |
diff --git a/fs/dquot.c b/fs/dquot.c index 37212b039a4a..b9732335bcdc 100644 --- a/fs/dquot.c +++ b/fs/dquot.c | |||
@@ -409,13 +409,10 @@ out_dqlock: | |||
409 | * for this sb+type at all. */ | 409 | * for this sb+type at all. */ |
410 | static void invalidate_dquots(struct super_block *sb, int type) | 410 | static void invalidate_dquots(struct super_block *sb, int type) |
411 | { | 411 | { |
412 | struct dquot *dquot; | 412 | struct dquot *dquot, *tmp; |
413 | struct list_head *head; | ||
414 | 413 | ||
415 | spin_lock(&dq_list_lock); | 414 | spin_lock(&dq_list_lock); |
416 | for (head = inuse_list.next; head != &inuse_list;) { | 415 | list_for_each_entry_safe(dquot, tmp, &inuse_list, dq_inuse) { |
417 | dquot = list_entry(head, struct dquot, dq_inuse); | ||
418 | head = head->next; | ||
419 | if (dquot->dq_sb != sb) | 416 | if (dquot->dq_sb != sb) |
420 | continue; | 417 | continue; |
421 | if (dquot->dq_type != type) | 418 | if (dquot->dq_type != type) |
diff --git a/fs/jffs/intrep.c b/fs/jffs/intrep.c index 8cc6893fc56c..fc589ddd0762 100644 --- a/fs/jffs/intrep.c +++ b/fs/jffs/intrep.c | |||
@@ -175,8 +175,64 @@ jffs_hexdump(struct mtd_info *mtd, loff_t pos, int size) | |||
175 | } | 175 | } |
176 | } | 176 | } |
177 | 177 | ||
178 | /* Print the contents of a node. */ | ||
179 | static void | ||
180 | jffs_print_node(struct jffs_node *n) | ||
181 | { | ||
182 | D(printk("jffs_node: 0x%p\n", n)); | ||
183 | D(printk("{\n")); | ||
184 | D(printk(" 0x%08x, /* version */\n", n->version)); | ||
185 | D(printk(" 0x%08x, /* data_offset */\n", n->data_offset)); | ||
186 | D(printk(" 0x%08x, /* data_size */\n", n->data_size)); | ||
187 | D(printk(" 0x%08x, /* removed_size */\n", n->removed_size)); | ||
188 | D(printk(" 0x%08x, /* fm_offset */\n", n->fm_offset)); | ||
189 | D(printk(" 0x%02x, /* name_size */\n", n->name_size)); | ||
190 | D(printk(" 0x%p, /* fm, fm->offset: %u */\n", | ||
191 | n->fm, (n->fm ? n->fm->offset : 0))); | ||
192 | D(printk(" 0x%p, /* version_prev */\n", n->version_prev)); | ||
193 | D(printk(" 0x%p, /* version_next */\n", n->version_next)); | ||
194 | D(printk(" 0x%p, /* range_prev */\n", n->range_prev)); | ||
195 | D(printk(" 0x%p, /* range_next */\n", n->range_next)); | ||
196 | D(printk("}\n")); | ||
197 | } | ||
198 | |||
178 | #endif | 199 | #endif |
179 | 200 | ||
201 | /* Print the contents of a raw inode. */ | ||
202 | static void | ||
203 | jffs_print_raw_inode(struct jffs_raw_inode *raw_inode) | ||
204 | { | ||
205 | D(printk("jffs_raw_inode: inode number: %u\n", raw_inode->ino)); | ||
206 | D(printk("{\n")); | ||
207 | D(printk(" 0x%08x, /* magic */\n", raw_inode->magic)); | ||
208 | D(printk(" 0x%08x, /* ino */\n", raw_inode->ino)); | ||
209 | D(printk(" 0x%08x, /* pino */\n", raw_inode->pino)); | ||
210 | D(printk(" 0x%08x, /* version */\n", raw_inode->version)); | ||
211 | D(printk(" 0x%08x, /* mode */\n", raw_inode->mode)); | ||
212 | D(printk(" 0x%04x, /* uid */\n", raw_inode->uid)); | ||
213 | D(printk(" 0x%04x, /* gid */\n", raw_inode->gid)); | ||
214 | D(printk(" 0x%08x, /* atime */\n", raw_inode->atime)); | ||
215 | D(printk(" 0x%08x, /* mtime */\n", raw_inode->mtime)); | ||
216 | D(printk(" 0x%08x, /* ctime */\n", raw_inode->ctime)); | ||
217 | D(printk(" 0x%08x, /* offset */\n", raw_inode->offset)); | ||
218 | D(printk(" 0x%08x, /* dsize */\n", raw_inode->dsize)); | ||
219 | D(printk(" 0x%08x, /* rsize */\n", raw_inode->rsize)); | ||
220 | D(printk(" 0x%02x, /* nsize */\n", raw_inode->nsize)); | ||
221 | D(printk(" 0x%02x, /* nlink */\n", raw_inode->nlink)); | ||
222 | D(printk(" 0x%02x, /* spare */\n", | ||
223 | raw_inode->spare)); | ||
224 | D(printk(" %u, /* rename */\n", | ||
225 | raw_inode->rename)); | ||
226 | D(printk(" %u, /* deleted */\n", | ||
227 | raw_inode->deleted)); | ||
228 | D(printk(" 0x%02x, /* accurate */\n", | ||
229 | raw_inode->accurate)); | ||
230 | D(printk(" 0x%08x, /* dchksum */\n", raw_inode->dchksum)); | ||
231 | D(printk(" 0x%04x, /* nchksum */\n", raw_inode->nchksum)); | ||
232 | D(printk(" 0x%04x, /* chksum */\n", raw_inode->chksum)); | ||
233 | D(printk("}\n")); | ||
234 | } | ||
235 | |||
180 | #define flash_safe_acquire(arg) | 236 | #define flash_safe_acquire(arg) |
181 | #define flash_safe_release(arg) | 237 | #define flash_safe_release(arg) |
182 | 238 | ||
@@ -2507,64 +2563,6 @@ jffs_update_file(struct jffs_file *f, struct jffs_node *node) | |||
2507 | return 0; | 2563 | return 0; |
2508 | } | 2564 | } |
2509 | 2565 | ||
2510 | /* Print the contents of a node. */ | ||
2511 | void | ||
2512 | jffs_print_node(struct jffs_node *n) | ||
2513 | { | ||
2514 | D(printk("jffs_node: 0x%p\n", n)); | ||
2515 | D(printk("{\n")); | ||
2516 | D(printk(" 0x%08x, /* version */\n", n->version)); | ||
2517 | D(printk(" 0x%08x, /* data_offset */\n", n->data_offset)); | ||
2518 | D(printk(" 0x%08x, /* data_size */\n", n->data_size)); | ||
2519 | D(printk(" 0x%08x, /* removed_size */\n", n->removed_size)); | ||
2520 | D(printk(" 0x%08x, /* fm_offset */\n", n->fm_offset)); | ||
2521 | D(printk(" 0x%02x, /* name_size */\n", n->name_size)); | ||
2522 | D(printk(" 0x%p, /* fm, fm->offset: %u */\n", | ||
2523 | n->fm, (n->fm ? n->fm->offset : 0))); | ||
2524 | D(printk(" 0x%p, /* version_prev */\n", n->version_prev)); | ||
2525 | D(printk(" 0x%p, /* version_next */\n", n->version_next)); | ||
2526 | D(printk(" 0x%p, /* range_prev */\n", n->range_prev)); | ||
2527 | D(printk(" 0x%p, /* range_next */\n", n->range_next)); | ||
2528 | D(printk("}\n")); | ||
2529 | } | ||
2530 | |||
2531 | |||
2532 | /* Print the contents of a raw inode. */ | ||
2533 | void | ||
2534 | jffs_print_raw_inode(struct jffs_raw_inode *raw_inode) | ||
2535 | { | ||
2536 | D(printk("jffs_raw_inode: inode number: %u\n", raw_inode->ino)); | ||
2537 | D(printk("{\n")); | ||
2538 | D(printk(" 0x%08x, /* magic */\n", raw_inode->magic)); | ||
2539 | D(printk(" 0x%08x, /* ino */\n", raw_inode->ino)); | ||
2540 | D(printk(" 0x%08x, /* pino */\n", raw_inode->pino)); | ||
2541 | D(printk(" 0x%08x, /* version */\n", raw_inode->version)); | ||
2542 | D(printk(" 0x%08x, /* mode */\n", raw_inode->mode)); | ||
2543 | D(printk(" 0x%04x, /* uid */\n", raw_inode->uid)); | ||
2544 | D(printk(" 0x%04x, /* gid */\n", raw_inode->gid)); | ||
2545 | D(printk(" 0x%08x, /* atime */\n", raw_inode->atime)); | ||
2546 | D(printk(" 0x%08x, /* mtime */\n", raw_inode->mtime)); | ||
2547 | D(printk(" 0x%08x, /* ctime */\n", raw_inode->ctime)); | ||
2548 | D(printk(" 0x%08x, /* offset */\n", raw_inode->offset)); | ||
2549 | D(printk(" 0x%08x, /* dsize */\n", raw_inode->dsize)); | ||
2550 | D(printk(" 0x%08x, /* rsize */\n", raw_inode->rsize)); | ||
2551 | D(printk(" 0x%02x, /* nsize */\n", raw_inode->nsize)); | ||
2552 | D(printk(" 0x%02x, /* nlink */\n", raw_inode->nlink)); | ||
2553 | D(printk(" 0x%02x, /* spare */\n", | ||
2554 | raw_inode->spare)); | ||
2555 | D(printk(" %u, /* rename */\n", | ||
2556 | raw_inode->rename)); | ||
2557 | D(printk(" %u, /* deleted */\n", | ||
2558 | raw_inode->deleted)); | ||
2559 | D(printk(" 0x%02x, /* accurate */\n", | ||
2560 | raw_inode->accurate)); | ||
2561 | D(printk(" 0x%08x, /* dchksum */\n", raw_inode->dchksum)); | ||
2562 | D(printk(" 0x%04x, /* nchksum */\n", raw_inode->nchksum)); | ||
2563 | D(printk(" 0x%04x, /* chksum */\n", raw_inode->chksum)); | ||
2564 | D(printk("}\n")); | ||
2565 | } | ||
2566 | |||
2567 | |||
2568 | /* Print the contents of a file. */ | 2566 | /* Print the contents of a file. */ |
2569 | #if 0 | 2567 | #if 0 |
2570 | int | 2568 | int |
diff --git a/fs/jffs/intrep.h b/fs/jffs/intrep.h index 4ae97b17911c..5c7abe0e2695 100644 --- a/fs/jffs/intrep.h +++ b/fs/jffs/intrep.h | |||
@@ -49,8 +49,6 @@ int jffs_garbage_collect_thread(void *c); | |||
49 | void jffs_garbage_collect_trigger(struct jffs_control *c); | 49 | void jffs_garbage_collect_trigger(struct jffs_control *c); |
50 | 50 | ||
51 | /* For debugging purposes. */ | 51 | /* For debugging purposes. */ |
52 | void jffs_print_node(struct jffs_node *n); | ||
53 | void jffs_print_raw_inode(struct jffs_raw_inode *raw_inode); | ||
54 | #if 0 | 52 | #if 0 |
55 | int jffs_print_file(struct jffs_file *f); | 53 | int jffs_print_file(struct jffs_file *f); |
56 | #endif /* 0 */ | 54 | #endif /* 0 */ |
diff --git a/fs/jffs/jffs_fm.c b/fs/jffs/jffs_fm.c index 0cab8da49d3c..053e3a98a276 100644 --- a/fs/jffs/jffs_fm.c +++ b/fs/jffs/jffs_fm.c | |||
@@ -31,6 +31,60 @@ static void jffs_free_fm(struct jffs_fm *n); | |||
31 | extern kmem_cache_t *fm_cache; | 31 | extern kmem_cache_t *fm_cache; |
32 | extern kmem_cache_t *node_cache; | 32 | extern kmem_cache_t *node_cache; |
33 | 33 | ||
34 | #if CONFIG_JFFS_FS_VERBOSE > 0 | ||
35 | void | ||
36 | jffs_print_fmcontrol(struct jffs_fmcontrol *fmc) | ||
37 | { | ||
38 | D(printk("struct jffs_fmcontrol: 0x%p\n", fmc)); | ||
39 | D(printk("{\n")); | ||
40 | D(printk(" %u, /* flash_size */\n", fmc->flash_size)); | ||
41 | D(printk(" %u, /* used_size */\n", fmc->used_size)); | ||
42 | D(printk(" %u, /* dirty_size */\n", fmc->dirty_size)); | ||
43 | D(printk(" %u, /* free_size */\n", fmc->free_size)); | ||
44 | D(printk(" %u, /* sector_size */\n", fmc->sector_size)); | ||
45 | D(printk(" %u, /* min_free_size */\n", fmc->min_free_size)); | ||
46 | D(printk(" %u, /* max_chunk_size */\n", fmc->max_chunk_size)); | ||
47 | D(printk(" 0x%p, /* mtd */\n", fmc->mtd)); | ||
48 | D(printk(" 0x%p, /* head */ " | ||
49 | "(head->offset = 0x%08x)\n", | ||
50 | fmc->head, (fmc->head ? fmc->head->offset : 0))); | ||
51 | D(printk(" 0x%p, /* tail */ " | ||
52 | "(tail->offset + tail->size = 0x%08x)\n", | ||
53 | fmc->tail, | ||
54 | (fmc->tail ? fmc->tail->offset + fmc->tail->size : 0))); | ||
55 | D(printk(" 0x%p, /* head_extra */\n", fmc->head_extra)); | ||
56 | D(printk(" 0x%p, /* tail_extra */\n", fmc->tail_extra)); | ||
57 | D(printk("}\n")); | ||
58 | } | ||
59 | #endif /* CONFIG_JFFS_FS_VERBOSE > 0 */ | ||
60 | |||
61 | #if CONFIG_JFFS_FS_VERBOSE > 2 | ||
62 | static void | ||
63 | jffs_print_fm(struct jffs_fm *fm) | ||
64 | { | ||
65 | D(printk("struct jffs_fm: 0x%p\n", fm)); | ||
66 | D(printk("{\n")); | ||
67 | D(printk(" 0x%08x, /* offset */\n", fm->offset)); | ||
68 | D(printk(" %u, /* size */\n", fm->size)); | ||
69 | D(printk(" 0x%p, /* prev */\n", fm->prev)); | ||
70 | D(printk(" 0x%p, /* next */\n", fm->next)); | ||
71 | D(printk(" 0x%p, /* nodes */\n", fm->nodes)); | ||
72 | D(printk("}\n")); | ||
73 | } | ||
74 | #endif /* CONFIG_JFFS_FS_VERBOSE > 2 */ | ||
75 | |||
76 | #if 0 | ||
77 | void | ||
78 | jffs_print_node_ref(struct jffs_node_ref *ref) | ||
79 | { | ||
80 | D(printk("struct jffs_node_ref: 0x%p\n", ref)); | ||
81 | D(printk("{\n")); | ||
82 | D(printk(" 0x%p, /* node */\n", ref->node)); | ||
83 | D(printk(" 0x%p, /* next */\n", ref->next)); | ||
84 | D(printk("}\n")); | ||
85 | } | ||
86 | #endif /* 0 */ | ||
87 | |||
34 | /* This function creates a new shiny flash memory control structure. */ | 88 | /* This function creates a new shiny flash memory control structure. */ |
35 | struct jffs_fmcontrol * | 89 | struct jffs_fmcontrol * |
36 | jffs_build_begin(struct jffs_control *c, int unit) | 90 | jffs_build_begin(struct jffs_control *c, int unit) |
@@ -742,54 +796,3 @@ int jffs_get_node_inuse(void) | |||
742 | { | 796 | { |
743 | return no_jffs_node; | 797 | return no_jffs_node; |
744 | } | 798 | } |
745 | |||
746 | void | ||
747 | jffs_print_fmcontrol(struct jffs_fmcontrol *fmc) | ||
748 | { | ||
749 | D(printk("struct jffs_fmcontrol: 0x%p\n", fmc)); | ||
750 | D(printk("{\n")); | ||
751 | D(printk(" %u, /* flash_size */\n", fmc->flash_size)); | ||
752 | D(printk(" %u, /* used_size */\n", fmc->used_size)); | ||
753 | D(printk(" %u, /* dirty_size */\n", fmc->dirty_size)); | ||
754 | D(printk(" %u, /* free_size */\n", fmc->free_size)); | ||
755 | D(printk(" %u, /* sector_size */\n", fmc->sector_size)); | ||
756 | D(printk(" %u, /* min_free_size */\n", fmc->min_free_size)); | ||
757 | D(printk(" %u, /* max_chunk_size */\n", fmc->max_chunk_size)); | ||
758 | D(printk(" 0x%p, /* mtd */\n", fmc->mtd)); | ||
759 | D(printk(" 0x%p, /* head */ " | ||
760 | "(head->offset = 0x%08x)\n", | ||
761 | fmc->head, (fmc->head ? fmc->head->offset : 0))); | ||
762 | D(printk(" 0x%p, /* tail */ " | ||
763 | "(tail->offset + tail->size = 0x%08x)\n", | ||
764 | fmc->tail, | ||
765 | (fmc->tail ? fmc->tail->offset + fmc->tail->size : 0))); | ||
766 | D(printk(" 0x%p, /* head_extra */\n", fmc->head_extra)); | ||
767 | D(printk(" 0x%p, /* tail_extra */\n", fmc->tail_extra)); | ||
768 | D(printk("}\n")); | ||
769 | } | ||
770 | |||
771 | void | ||
772 | jffs_print_fm(struct jffs_fm *fm) | ||
773 | { | ||
774 | D(printk("struct jffs_fm: 0x%p\n", fm)); | ||
775 | D(printk("{\n")); | ||
776 | D(printk(" 0x%08x, /* offset */\n", fm->offset)); | ||
777 | D(printk(" %u, /* size */\n", fm->size)); | ||
778 | D(printk(" 0x%p, /* prev */\n", fm->prev)); | ||
779 | D(printk(" 0x%p, /* next */\n", fm->next)); | ||
780 | D(printk(" 0x%p, /* nodes */\n", fm->nodes)); | ||
781 | D(printk("}\n")); | ||
782 | } | ||
783 | |||
784 | #if 0 | ||
785 | void | ||
786 | jffs_print_node_ref(struct jffs_node_ref *ref) | ||
787 | { | ||
788 | D(printk("struct jffs_node_ref: 0x%p\n", ref)); | ||
789 | D(printk("{\n")); | ||
790 | D(printk(" 0x%p, /* node */\n", ref->node)); | ||
791 | D(printk(" 0x%p, /* next */\n", ref->next)); | ||
792 | D(printk("}\n")); | ||
793 | } | ||
794 | #endif /* 0 */ | ||
795 | |||
diff --git a/fs/jffs/jffs_fm.h b/fs/jffs/jffs_fm.h index bc291c431822..f64151e74122 100644 --- a/fs/jffs/jffs_fm.h +++ b/fs/jffs/jffs_fm.h | |||
@@ -139,8 +139,9 @@ int jffs_add_node(struct jffs_node *node); | |||
139 | void jffs_fmfree_partly(struct jffs_fmcontrol *fmc, struct jffs_fm *fm, | 139 | void jffs_fmfree_partly(struct jffs_fmcontrol *fmc, struct jffs_fm *fm, |
140 | __u32 size); | 140 | __u32 size); |
141 | 141 | ||
142 | #if CONFIG_JFFS_FS_VERBOSE > 0 | ||
142 | void jffs_print_fmcontrol(struct jffs_fmcontrol *fmc); | 143 | void jffs_print_fmcontrol(struct jffs_fmcontrol *fmc); |
143 | void jffs_print_fm(struct jffs_fm *fm); | 144 | #endif |
144 | #if 0 | 145 | #if 0 |
145 | void jffs_print_node_ref(struct jffs_node_ref *ref); | 146 | void jffs_print_node_ref(struct jffs_node_ref *ref); |
146 | #endif /* 0 */ | 147 | #endif /* 0 */ |
diff --git a/fs/libfs.c b/fs/libfs.c index 5025563e7379..58101dff2c66 100644 --- a/fs/libfs.c +++ b/fs/libfs.c | |||
@@ -183,6 +183,7 @@ struct file_operations simple_dir_operations = { | |||
183 | .llseek = dcache_dir_lseek, | 183 | .llseek = dcache_dir_lseek, |
184 | .read = generic_read_dir, | 184 | .read = generic_read_dir, |
185 | .readdir = dcache_readdir, | 185 | .readdir = dcache_readdir, |
186 | .fsync = simple_sync_file, | ||
186 | }; | 187 | }; |
187 | 188 | ||
188 | struct inode_operations simple_dir_inode_operations = { | 189 | struct inode_operations simple_dir_inode_operations = { |
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index 2dc2d8693968..a9f7a8ab1d59 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c | |||
@@ -705,18 +705,6 @@ ncp_do_readdir(struct file *filp, void *dirent, filldir_t filldir, | |||
705 | DPRINTK("ncp_do_readdir: init failed, err=%d\n", err); | 705 | DPRINTK("ncp_do_readdir: init failed, err=%d\n", err); |
706 | return; | 706 | return; |
707 | } | 707 | } |
708 | #ifdef USE_OLD_SLOW_DIRECTORY_LISTING | ||
709 | for (;;) { | ||
710 | err = ncp_search_for_file_or_subdir(server, &seq, &entry.i); | ||
711 | if (err) { | ||
712 | DPRINTK("ncp_do_readdir: search failed, err=%d\n", err); | ||
713 | break; | ||
714 | } | ||
715 | entry.volume = entry.i.volNumber; | ||
716 | if (!ncp_fill_cache(filp, dirent, filldir, ctl, &entry)) | ||
717 | break; | ||
718 | } | ||
719 | #else | ||
720 | /* We MUST NOT use server->buffer_size handshaked with server if we are | 708 | /* We MUST NOT use server->buffer_size handshaked with server if we are |
721 | using UDP, as for UDP server uses max. buffer size determined by | 709 | using UDP, as for UDP server uses max. buffer size determined by |
722 | MTU, and for TCP server uses hardwired value 65KB (== 66560 bytes). | 710 | MTU, and for TCP server uses hardwired value 65KB (== 66560 bytes). |
@@ -754,7 +742,6 @@ ncp_do_readdir(struct file *filp, void *dirent, filldir_t filldir, | |||
754 | } | 742 | } |
755 | } while (more); | 743 | } while (more); |
756 | vfree(buf); | 744 | vfree(buf); |
757 | #endif | ||
758 | return; | 745 | return; |
759 | } | 746 | } |
760 | 747 | ||
diff --git a/fs/ncpfs/ncplib_kernel.c b/fs/ncpfs/ncplib_kernel.c index e4eb5ed4bee4..c755e1848a42 100644 --- a/fs/ncpfs/ncplib_kernel.c +++ b/fs/ncpfs/ncplib_kernel.c | |||
@@ -845,46 +845,6 @@ out: | |||
845 | return result; | 845 | return result; |
846 | } | 846 | } |
847 | 847 | ||
848 | /* Search for everything */ | ||
849 | int ncp_search_for_file_or_subdir(struct ncp_server *server, | ||
850 | struct nw_search_sequence *seq, | ||
851 | struct nw_info_struct *target) | ||
852 | { | ||
853 | int result; | ||
854 | |||
855 | ncp_init_request(server); | ||
856 | ncp_add_byte(server, 3); /* subfunction */ | ||
857 | ncp_add_byte(server, server->name_space[seq->volNumber]); | ||
858 | ncp_add_byte(server, 0); /* data stream (???) */ | ||
859 | ncp_add_word(server, cpu_to_le16(0x8006)); /* Search attribs */ | ||
860 | ncp_add_dword(server, RIM_ALL); /* return info mask */ | ||
861 | ncp_add_mem(server, seq, 9); | ||
862 | #ifdef CONFIG_NCPFS_NFS_NS | ||
863 | if (server->name_space[seq->volNumber] == NW_NS_NFS) { | ||
864 | ncp_add_byte(server, 0); /* 0 byte pattern */ | ||
865 | } else | ||
866 | #endif | ||
867 | { | ||
868 | ncp_add_byte(server, 2); /* 2 byte pattern */ | ||
869 | ncp_add_byte(server, 0xff); /* following is a wildcard */ | ||
870 | ncp_add_byte(server, '*'); | ||
871 | } | ||
872 | |||
873 | if ((result = ncp_request(server, 87)) != 0) | ||
874 | goto out; | ||
875 | memcpy(seq, ncp_reply_data(server, 0), sizeof(*seq)); | ||
876 | ncp_extract_file_info(ncp_reply_data(server, 10), target); | ||
877 | |||
878 | ncp_unlock_server(server); | ||
879 | |||
880 | result = ncp_obtain_nfs_info(server, target); | ||
881 | return result; | ||
882 | |||
883 | out: | ||
884 | ncp_unlock_server(server); | ||
885 | return result; | ||
886 | } | ||
887 | |||
888 | int ncp_search_for_fileset(struct ncp_server *server, | 848 | int ncp_search_for_fileset(struct ncp_server *server, |
889 | struct nw_search_sequence *seq, | 849 | struct nw_search_sequence *seq, |
890 | int* more, | 850 | int* more, |
diff --git a/fs/ncpfs/ncplib_kernel.h b/fs/ncpfs/ncplib_kernel.h index 05ec2e9d90c6..9e4dc30c2435 100644 --- a/fs/ncpfs/ncplib_kernel.h +++ b/fs/ncpfs/ncplib_kernel.h | |||
@@ -87,9 +87,6 @@ int ncp_open_create_file_or_subdir(struct ncp_server *, struct inode *, char *, | |||
87 | 87 | ||
88 | int ncp_initialize_search(struct ncp_server *, struct inode *, | 88 | int ncp_initialize_search(struct ncp_server *, struct inode *, |
89 | struct nw_search_sequence *target); | 89 | struct nw_search_sequence *target); |
90 | int ncp_search_for_file_or_subdir(struct ncp_server *server, | ||
91 | struct nw_search_sequence *seq, | ||
92 | struct nw_info_struct *target); | ||
93 | int ncp_search_for_fileset(struct ncp_server *server, | 90 | int ncp_search_for_fileset(struct ncp_server *server, |
94 | struct nw_search_sequence *seq, | 91 | struct nw_search_sequence *seq, |
95 | int* more, int* cnt, | 92 | int* more, int* cnt, |
diff --git a/fs/partitions/Makefile b/fs/partitions/Makefile index 4c83c17969e1..66d5cc26fafb 100644 --- a/fs/partitions/Makefile +++ b/fs/partitions/Makefile | |||
@@ -17,4 +17,3 @@ obj-$(CONFIG_SUN_PARTITION) += sun.o | |||
17 | obj-$(CONFIG_ULTRIX_PARTITION) += ultrix.o | 17 | obj-$(CONFIG_ULTRIX_PARTITION) += ultrix.o |
18 | obj-$(CONFIG_IBM_PARTITION) += ibm.o | 18 | obj-$(CONFIG_IBM_PARTITION) += ibm.o |
19 | obj-$(CONFIG_EFI_PARTITION) += efi.o | 19 | obj-$(CONFIG_EFI_PARTITION) += efi.o |
20 | obj-$(CONFIG_NEC98_PARTITION) += nec98.o msdos.o | ||
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 2cab98a9a621..77e178f13162 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
@@ -79,9 +79,6 @@ static int (*check_part[])(struct parsed_partitions *, struct block_device *) = | |||
79 | #ifdef CONFIG_LDM_PARTITION | 79 | #ifdef CONFIG_LDM_PARTITION |
80 | ldm_partition, /* this must come before msdos */ | 80 | ldm_partition, /* this must come before msdos */ |
81 | #endif | 81 | #endif |
82 | #ifdef CONFIG_NEC98_PARTITION | ||
83 | nec98_partition, /* must be come before `msdos_partition' */ | ||
84 | #endif | ||
85 | #ifdef CONFIG_MSDOS_PARTITION | 82 | #ifdef CONFIG_MSDOS_PARTITION |
86 | msdos_partition, | 83 | msdos_partition, |
87 | #endif | 84 | #endif |
diff --git a/fs/partitions/check.h b/fs/partitions/check.h index 43adcc68e471..17ae8ecd9e8b 100644 --- a/fs/partitions/check.h +++ b/fs/partitions/check.h | |||
@@ -30,7 +30,3 @@ put_partition(struct parsed_partitions *p, int n, sector_t from, sector_t size) | |||
30 | 30 | ||
31 | extern int warn_no_part; | 31 | extern int warn_no_part; |
32 | 32 | ||
33 | extern void parse_bsd(struct parsed_partitions *state, | ||
34 | struct block_device *bdev, u32 offset, u32 size, | ||
35 | int origin, char *flavour, int max_partitions); | ||
36 | |||
diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c index 584a27b2bbd5..9935d254186e 100644 --- a/fs/partitions/msdos.c +++ b/fs/partitions/msdos.c | |||
@@ -202,12 +202,12 @@ parse_solaris_x86(struct parsed_partitions *state, struct block_device *bdev, | |||
202 | #endif | 202 | #endif |
203 | } | 203 | } |
204 | 204 | ||
205 | #if defined(CONFIG_BSD_DISKLABEL) || defined(CONFIG_NEC98_PARTITION) | 205 | #if defined(CONFIG_BSD_DISKLABEL) |
206 | /* | 206 | /* |
207 | * Create devices for BSD partitions listed in a disklabel, under a | 207 | * Create devices for BSD partitions listed in a disklabel, under a |
208 | * dos-like partition. See parse_extended() for more information. | 208 | * dos-like partition. See parse_extended() for more information. |
209 | */ | 209 | */ |
210 | void | 210 | static void |
211 | parse_bsd(struct parsed_partitions *state, struct block_device *bdev, | 211 | parse_bsd(struct parsed_partitions *state, struct block_device *bdev, |
212 | u32 offset, u32 size, int origin, char *flavour, | 212 | u32 offset, u32 size, int origin, char *flavour, |
213 | int max_partitions) | 213 | int max_partitions) |
diff --git a/fs/proc/Makefile b/fs/proc/Makefile index 738b9b602932..7431d7ba2d09 100644 --- a/fs/proc/Makefile +++ b/fs/proc/Makefile | |||
@@ -11,4 +11,5 @@ proc-y += inode.o root.o base.o generic.o array.o \ | |||
11 | kmsg.o proc_tty.o proc_misc.o | 11 | kmsg.o proc_tty.o proc_misc.o |
12 | 12 | ||
13 | proc-$(CONFIG_PROC_KCORE) += kcore.o | 13 | proc-$(CONFIG_PROC_KCORE) += kcore.o |
14 | proc-$(CONFIG_PROC_VMCORE) += vmcore.o | ||
14 | proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o | 15 | proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o |
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index 94b570ad037d..a3453555a94e 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <linux/jiffies.h> | 44 | #include <linux/jiffies.h> |
45 | #include <linux/sysrq.h> | 45 | #include <linux/sysrq.h> |
46 | #include <linux/vmalloc.h> | 46 | #include <linux/vmalloc.h> |
47 | #include <linux/crash_dump.h> | ||
47 | #include <asm/uaccess.h> | 48 | #include <asm/uaccess.h> |
48 | #include <asm/pgtable.h> | 49 | #include <asm/pgtable.h> |
49 | #include <asm/io.h> | 50 | #include <asm/io.h> |
@@ -618,6 +619,11 @@ void __init proc_misc_init(void) | |||
618 | (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE; | 619 | (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE; |
619 | } | 620 | } |
620 | #endif | 621 | #endif |
622 | #ifdef CONFIG_PROC_VMCORE | ||
623 | proc_vmcore = create_proc_entry("vmcore", S_IRUSR, NULL); | ||
624 | if (proc_vmcore) | ||
625 | proc_vmcore->proc_fops = &proc_vmcore_operations; | ||
626 | #endif | ||
621 | #ifdef CONFIG_MAGIC_SYSRQ | 627 | #ifdef CONFIG_MAGIC_SYSRQ |
622 | entry = create_proc_entry("sysrq-trigger", S_IWUSR, NULL); | 628 | entry = create_proc_entry("sysrq-trigger", S_IWUSR, NULL); |
623 | if (entry) | 629 | if (entry) |
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c new file mode 100644 index 000000000000..3b2e7b69e63a --- /dev/null +++ b/fs/proc/vmcore.c | |||
@@ -0,0 +1,669 @@ | |||
1 | /* | ||
2 | * fs/proc/vmcore.c Interface for accessing the crash | ||
3 | * dump from the system's previous life. | ||
4 | * Heavily borrowed from fs/proc/kcore.c | ||
5 | * Created by: Hariprasad Nellitheertha (hari@in.ibm.com) | ||
6 | * Copyright (C) IBM Corporation, 2004. All rights reserved | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #include <linux/config.h> | ||
11 | #include <linux/mm.h> | ||
12 | #include <linux/proc_fs.h> | ||
13 | #include <linux/user.h> | ||
14 | #include <linux/a.out.h> | ||
15 | #include <linux/elf.h> | ||
16 | #include <linux/elfcore.h> | ||
17 | #include <linux/proc_fs.h> | ||
18 | #include <linux/highmem.h> | ||
19 | #include <linux/bootmem.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/crash_dump.h> | ||
22 | #include <linux/list.h> | ||
23 | #include <asm/uaccess.h> | ||
24 | #include <asm/io.h> | ||
25 | |||
26 | /* List representing chunks of contiguous memory areas and their offsets in | ||
27 | * vmcore file. | ||
28 | */ | ||
29 | static LIST_HEAD(vmcore_list); | ||
30 | |||
31 | /* Stores the pointer to the buffer containing kernel elf core headers. */ | ||
32 | static char *elfcorebuf; | ||
33 | static size_t elfcorebuf_sz; | ||
34 | |||
35 | /* Total size of vmcore file. */ | ||
36 | static u64 vmcore_size; | ||
37 | |||
38 | struct proc_dir_entry *proc_vmcore = NULL; | ||
39 | |||
40 | /* Reads a page from the oldmem device from given offset. */ | ||
41 | static ssize_t read_from_oldmem(char *buf, size_t count, | ||
42 | loff_t *ppos, int userbuf) | ||
43 | { | ||
44 | unsigned long pfn, offset; | ||
45 | size_t nr_bytes; | ||
46 | ssize_t read = 0, tmp; | ||
47 | |||
48 | if (!count) | ||
49 | return 0; | ||
50 | |||
51 | offset = (unsigned long)(*ppos % PAGE_SIZE); | ||
52 | pfn = (unsigned long)(*ppos / PAGE_SIZE); | ||
53 | if (pfn > saved_max_pfn) | ||
54 | return -EINVAL; | ||
55 | |||
56 | do { | ||
57 | if (count > (PAGE_SIZE - offset)) | ||
58 | nr_bytes = PAGE_SIZE - offset; | ||
59 | else | ||
60 | nr_bytes = count; | ||
61 | |||
62 | tmp = copy_oldmem_page(pfn, buf, nr_bytes, offset, userbuf); | ||
63 | if (tmp < 0) | ||
64 | return tmp; | ||
65 | *ppos += nr_bytes; | ||
66 | count -= nr_bytes; | ||
67 | buf += nr_bytes; | ||
68 | read += nr_bytes; | ||
69 | ++pfn; | ||
70 | offset = 0; | ||
71 | } while (count); | ||
72 | |||
73 | return read; | ||
74 | } | ||
75 | |||
76 | /* Maps vmcore file offset to respective physical address in memroy. */ | ||
77 | static u64 map_offset_to_paddr(loff_t offset, struct list_head *vc_list, | ||
78 | struct vmcore **m_ptr) | ||
79 | { | ||
80 | struct vmcore *m; | ||
81 | u64 paddr; | ||
82 | |||
83 | list_for_each_entry(m, vc_list, list) { | ||
84 | u64 start, end; | ||
85 | start = m->offset; | ||
86 | end = m->offset + m->size - 1; | ||
87 | if (offset >= start && offset <= end) { | ||
88 | paddr = m->paddr + offset - start; | ||
89 | *m_ptr = m; | ||
90 | return paddr; | ||
91 | } | ||
92 | } | ||
93 | *m_ptr = NULL; | ||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | /* Read from the ELF header and then the crash dump. On error, negative value is | ||
98 | * returned otherwise number of bytes read are returned. | ||
99 | */ | ||
100 | static ssize_t read_vmcore(struct file *file, char __user *buffer, | ||
101 | size_t buflen, loff_t *fpos) | ||
102 | { | ||
103 | ssize_t acc = 0, tmp; | ||
104 | size_t tsz, nr_bytes; | ||
105 | u64 start; | ||
106 | struct vmcore *curr_m = NULL; | ||
107 | |||
108 | if (buflen == 0 || *fpos >= vmcore_size) | ||
109 | return 0; | ||
110 | |||
111 | /* trim buflen to not go beyond EOF */ | ||
112 | if (buflen > vmcore_size - *fpos) | ||
113 | buflen = vmcore_size - *fpos; | ||
114 | |||
115 | /* Read ELF core header */ | ||
116 | if (*fpos < elfcorebuf_sz) { | ||
117 | tsz = elfcorebuf_sz - *fpos; | ||
118 | if (buflen < tsz) | ||
119 | tsz = buflen; | ||
120 | if (copy_to_user(buffer, elfcorebuf + *fpos, tsz)) | ||
121 | return -EFAULT; | ||
122 | buflen -= tsz; | ||
123 | *fpos += tsz; | ||
124 | buffer += tsz; | ||
125 | acc += tsz; | ||
126 | |||
127 | /* leave now if filled buffer already */ | ||
128 | if (buflen == 0) | ||
129 | return acc; | ||
130 | } | ||
131 | |||
132 | start = map_offset_to_paddr(*fpos, &vmcore_list, &curr_m); | ||
133 | if (!curr_m) | ||
134 | return -EINVAL; | ||
135 | if ((tsz = (PAGE_SIZE - (start & ~PAGE_MASK))) > buflen) | ||
136 | tsz = buflen; | ||
137 | |||
138 | /* Calculate left bytes in current memory segment. */ | ||
139 | nr_bytes = (curr_m->size - (start - curr_m->paddr)); | ||
140 | if (tsz > nr_bytes) | ||
141 | tsz = nr_bytes; | ||
142 | |||
143 | while (buflen) { | ||
144 | tmp = read_from_oldmem(buffer, tsz, &start, 1); | ||
145 | if (tmp < 0) | ||
146 | return tmp; | ||
147 | buflen -= tsz; | ||
148 | *fpos += tsz; | ||
149 | buffer += tsz; | ||
150 | acc += tsz; | ||
151 | if (start >= (curr_m->paddr + curr_m->size)) { | ||
152 | if (curr_m->list.next == &vmcore_list) | ||
153 | return acc; /*EOF*/ | ||
154 | curr_m = list_entry(curr_m->list.next, | ||
155 | struct vmcore, list); | ||
156 | start = curr_m->paddr; | ||
157 | } | ||
158 | if ((tsz = (PAGE_SIZE - (start & ~PAGE_MASK))) > buflen) | ||
159 | tsz = buflen; | ||
160 | /* Calculate left bytes in current memory segment. */ | ||
161 | nr_bytes = (curr_m->size - (start - curr_m->paddr)); | ||
162 | if (tsz > nr_bytes) | ||
163 | tsz = nr_bytes; | ||
164 | } | ||
165 | return acc; | ||
166 | } | ||
167 | |||
168 | static int open_vmcore(struct inode *inode, struct file *filp) | ||
169 | { | ||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | struct file_operations proc_vmcore_operations = { | ||
174 | .read = read_vmcore, | ||
175 | .open = open_vmcore, | ||
176 | }; | ||
177 | |||
178 | static struct vmcore* __init get_new_element(void) | ||
179 | { | ||
180 | struct vmcore *p; | ||
181 | |||
182 | p = kmalloc(sizeof(*p), GFP_KERNEL); | ||
183 | if (p) | ||
184 | memset(p, 0, sizeof(*p)); | ||
185 | return p; | ||
186 | } | ||
187 | |||
188 | static u64 __init get_vmcore_size_elf64(char *elfptr) | ||
189 | { | ||
190 | int i; | ||
191 | u64 size; | ||
192 | Elf64_Ehdr *ehdr_ptr; | ||
193 | Elf64_Phdr *phdr_ptr; | ||
194 | |||
195 | ehdr_ptr = (Elf64_Ehdr *)elfptr; | ||
196 | phdr_ptr = (Elf64_Phdr*)(elfptr + sizeof(Elf64_Ehdr)); | ||
197 | size = sizeof(Elf64_Ehdr) + ((ehdr_ptr->e_phnum) * sizeof(Elf64_Phdr)); | ||
198 | for (i = 0; i < ehdr_ptr->e_phnum; i++) { | ||
199 | size += phdr_ptr->p_memsz; | ||
200 | phdr_ptr++; | ||
201 | } | ||
202 | return size; | ||
203 | } | ||
204 | |||
205 | static u64 __init get_vmcore_size_elf32(char *elfptr) | ||
206 | { | ||
207 | int i; | ||
208 | u64 size; | ||
209 | Elf32_Ehdr *ehdr_ptr; | ||
210 | Elf32_Phdr *phdr_ptr; | ||
211 | |||
212 | ehdr_ptr = (Elf32_Ehdr *)elfptr; | ||
213 | phdr_ptr = (Elf32_Phdr*)(elfptr + sizeof(Elf32_Ehdr)); | ||
214 | size = sizeof(Elf32_Ehdr) + ((ehdr_ptr->e_phnum) * sizeof(Elf32_Phdr)); | ||
215 | for (i = 0; i < ehdr_ptr->e_phnum; i++) { | ||
216 | size += phdr_ptr->p_memsz; | ||
217 | phdr_ptr++; | ||
218 | } | ||
219 | return size; | ||
220 | } | ||
221 | |||
222 | /* Merges all the PT_NOTE headers into one. */ | ||
223 | static int __init merge_note_headers_elf64(char *elfptr, size_t *elfsz, | ||
224 | struct list_head *vc_list) | ||
225 | { | ||
226 | int i, nr_ptnote=0, rc=0; | ||
227 | char *tmp; | ||
228 | Elf64_Ehdr *ehdr_ptr; | ||
229 | Elf64_Phdr phdr, *phdr_ptr; | ||
230 | Elf64_Nhdr *nhdr_ptr; | ||
231 | u64 phdr_sz = 0, note_off; | ||
232 | |||
233 | ehdr_ptr = (Elf64_Ehdr *)elfptr; | ||
234 | phdr_ptr = (Elf64_Phdr*)(elfptr + sizeof(Elf64_Ehdr)); | ||
235 | for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) { | ||
236 | int j; | ||
237 | void *notes_section; | ||
238 | struct vmcore *new; | ||
239 | u64 offset, max_sz, sz, real_sz = 0; | ||
240 | if (phdr_ptr->p_type != PT_NOTE) | ||
241 | continue; | ||
242 | nr_ptnote++; | ||
243 | max_sz = phdr_ptr->p_memsz; | ||
244 | offset = phdr_ptr->p_offset; | ||
245 | notes_section = kmalloc(max_sz, GFP_KERNEL); | ||
246 | if (!notes_section) | ||
247 | return -ENOMEM; | ||
248 | rc = read_from_oldmem(notes_section, max_sz, &offset, 0); | ||
249 | if (rc < 0) { | ||
250 | kfree(notes_section); | ||
251 | return rc; | ||
252 | } | ||
253 | nhdr_ptr = notes_section; | ||
254 | for (j = 0; j < max_sz; j += sz) { | ||
255 | if (nhdr_ptr->n_namesz == 0) | ||
256 | break; | ||
257 | sz = sizeof(Elf64_Nhdr) + | ||
258 | ((nhdr_ptr->n_namesz + 3) & ~3) + | ||
259 | ((nhdr_ptr->n_descsz + 3) & ~3); | ||
260 | real_sz += sz; | ||
261 | nhdr_ptr = (Elf64_Nhdr*)((char*)nhdr_ptr + sz); | ||
262 | } | ||
263 | |||
264 | /* Add this contiguous chunk of notes section to vmcore list.*/ | ||
265 | new = get_new_element(); | ||
266 | if (!new) { | ||
267 | kfree(notes_section); | ||
268 | return -ENOMEM; | ||
269 | } | ||
270 | new->paddr = phdr_ptr->p_offset; | ||
271 | new->size = real_sz; | ||
272 | list_add_tail(&new->list, vc_list); | ||
273 | phdr_sz += real_sz; | ||
274 | kfree(notes_section); | ||
275 | } | ||
276 | |||
277 | /* Prepare merged PT_NOTE program header. */ | ||
278 | phdr.p_type = PT_NOTE; | ||
279 | phdr.p_flags = 0; | ||
280 | note_off = sizeof(Elf64_Ehdr) + | ||
281 | (ehdr_ptr->e_phnum - nr_ptnote +1) * sizeof(Elf64_Phdr); | ||
282 | phdr.p_offset = note_off; | ||
283 | phdr.p_vaddr = phdr.p_paddr = 0; | ||
284 | phdr.p_filesz = phdr.p_memsz = phdr_sz; | ||
285 | phdr.p_align = 0; | ||
286 | |||
287 | /* Add merged PT_NOTE program header*/ | ||
288 | tmp = elfptr + sizeof(Elf64_Ehdr); | ||
289 | memcpy(tmp, &phdr, sizeof(phdr)); | ||
290 | tmp += sizeof(phdr); | ||
291 | |||
292 | /* Remove unwanted PT_NOTE program headers. */ | ||
293 | i = (nr_ptnote - 1) * sizeof(Elf64_Phdr); | ||
294 | *elfsz = *elfsz - i; | ||
295 | memmove(tmp, tmp+i, ((*elfsz)-sizeof(Elf64_Ehdr)-sizeof(Elf64_Phdr))); | ||
296 | |||
297 | /* Modify e_phnum to reflect merged headers. */ | ||
298 | ehdr_ptr->e_phnum = ehdr_ptr->e_phnum - nr_ptnote + 1; | ||
299 | |||
300 | return 0; | ||
301 | } | ||
302 | |||
303 | /* Merges all the PT_NOTE headers into one. */ | ||
304 | static int __init merge_note_headers_elf32(char *elfptr, size_t *elfsz, | ||
305 | struct list_head *vc_list) | ||
306 | { | ||
307 | int i, nr_ptnote=0, rc=0; | ||
308 | char *tmp; | ||
309 | Elf32_Ehdr *ehdr_ptr; | ||
310 | Elf32_Phdr phdr, *phdr_ptr; | ||
311 | Elf32_Nhdr *nhdr_ptr; | ||
312 | u64 phdr_sz = 0, note_off; | ||
313 | |||
314 | ehdr_ptr = (Elf32_Ehdr *)elfptr; | ||
315 | phdr_ptr = (Elf32_Phdr*)(elfptr + sizeof(Elf32_Ehdr)); | ||
316 | for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) { | ||
317 | int j; | ||
318 | void *notes_section; | ||
319 | struct vmcore *new; | ||
320 | u64 offset, max_sz, sz, real_sz = 0; | ||
321 | if (phdr_ptr->p_type != PT_NOTE) | ||
322 | continue; | ||
323 | nr_ptnote++; | ||
324 | max_sz = phdr_ptr->p_memsz; | ||
325 | offset = phdr_ptr->p_offset; | ||
326 | notes_section = kmalloc(max_sz, GFP_KERNEL); | ||
327 | if (!notes_section) | ||
328 | return -ENOMEM; | ||
329 | rc = read_from_oldmem(notes_section, max_sz, &offset, 0); | ||
330 | if (rc < 0) { | ||
331 | kfree(notes_section); | ||
332 | return rc; | ||
333 | } | ||
334 | nhdr_ptr = notes_section; | ||
335 | for (j = 0; j < max_sz; j += sz) { | ||
336 | if (nhdr_ptr->n_namesz == 0) | ||
337 | break; | ||
338 | sz = sizeof(Elf32_Nhdr) + | ||
339 | ((nhdr_ptr->n_namesz + 3) & ~3) + | ||
340 | ((nhdr_ptr->n_descsz + 3) & ~3); | ||
341 | real_sz += sz; | ||
342 | nhdr_ptr = (Elf32_Nhdr*)((char*)nhdr_ptr + sz); | ||
343 | } | ||
344 | |||
345 | /* Add this contiguous chunk of notes section to vmcore list.*/ | ||
346 | new = get_new_element(); | ||
347 | if (!new) { | ||
348 | kfree(notes_section); | ||
349 | return -ENOMEM; | ||
350 | } | ||
351 | new->paddr = phdr_ptr->p_offset; | ||
352 | new->size = real_sz; | ||
353 | list_add_tail(&new->list, vc_list); | ||
354 | phdr_sz += real_sz; | ||
355 | kfree(notes_section); | ||
356 | } | ||
357 | |||
358 | /* Prepare merged PT_NOTE program header. */ | ||
359 | phdr.p_type = PT_NOTE; | ||
360 | phdr.p_flags = 0; | ||
361 | note_off = sizeof(Elf32_Ehdr) + | ||
362 | (ehdr_ptr->e_phnum - nr_ptnote +1) * sizeof(Elf32_Phdr); | ||
363 | phdr.p_offset = note_off; | ||
364 | phdr.p_vaddr = phdr.p_paddr = 0; | ||
365 | phdr.p_filesz = phdr.p_memsz = phdr_sz; | ||
366 | phdr.p_align = 0; | ||
367 | |||
368 | /* Add merged PT_NOTE program header*/ | ||
369 | tmp = elfptr + sizeof(Elf32_Ehdr); | ||
370 | memcpy(tmp, &phdr, sizeof(phdr)); | ||
371 | tmp += sizeof(phdr); | ||
372 | |||
373 | /* Remove unwanted PT_NOTE program headers. */ | ||
374 | i = (nr_ptnote - 1) * sizeof(Elf32_Phdr); | ||
375 | *elfsz = *elfsz - i; | ||
376 | memmove(tmp, tmp+i, ((*elfsz)-sizeof(Elf32_Ehdr)-sizeof(Elf32_Phdr))); | ||
377 | |||
378 | /* Modify e_phnum to reflect merged headers. */ | ||
379 | ehdr_ptr->e_phnum = ehdr_ptr->e_phnum - nr_ptnote + 1; | ||
380 | |||
381 | return 0; | ||
382 | } | ||
383 | |||
384 | /* Add memory chunks represented by program headers to vmcore list. Also update | ||
385 | * the new offset fields of exported program headers. */ | ||
386 | static int __init process_ptload_program_headers_elf64(char *elfptr, | ||
387 | size_t elfsz, | ||
388 | struct list_head *vc_list) | ||
389 | { | ||
390 | int i; | ||
391 | Elf64_Ehdr *ehdr_ptr; | ||
392 | Elf64_Phdr *phdr_ptr; | ||
393 | loff_t vmcore_off; | ||
394 | struct vmcore *new; | ||
395 | |||
396 | ehdr_ptr = (Elf64_Ehdr *)elfptr; | ||
397 | phdr_ptr = (Elf64_Phdr*)(elfptr + sizeof(Elf64_Ehdr)); /* PT_NOTE hdr */ | ||
398 | |||
399 | /* First program header is PT_NOTE header. */ | ||
400 | vmcore_off = sizeof(Elf64_Ehdr) + | ||
401 | (ehdr_ptr->e_phnum) * sizeof(Elf64_Phdr) + | ||
402 | phdr_ptr->p_memsz; /* Note sections */ | ||
403 | |||
404 | for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) { | ||
405 | if (phdr_ptr->p_type != PT_LOAD) | ||
406 | continue; | ||
407 | |||
408 | /* Add this contiguous chunk of memory to vmcore list.*/ | ||
409 | new = get_new_element(); | ||
410 | if (!new) | ||
411 | return -ENOMEM; | ||
412 | new->paddr = phdr_ptr->p_offset; | ||
413 | new->size = phdr_ptr->p_memsz; | ||
414 | list_add_tail(&new->list, vc_list); | ||
415 | |||
416 | /* Update the program header offset. */ | ||
417 | phdr_ptr->p_offset = vmcore_off; | ||
418 | vmcore_off = vmcore_off + phdr_ptr->p_memsz; | ||
419 | } | ||
420 | return 0; | ||
421 | } | ||
422 | |||
423 | static int __init process_ptload_program_headers_elf32(char *elfptr, | ||
424 | size_t elfsz, | ||
425 | struct list_head *vc_list) | ||
426 | { | ||
427 | int i; | ||
428 | Elf32_Ehdr *ehdr_ptr; | ||
429 | Elf32_Phdr *phdr_ptr; | ||
430 | loff_t vmcore_off; | ||
431 | struct vmcore *new; | ||
432 | |||
433 | ehdr_ptr = (Elf32_Ehdr *)elfptr; | ||
434 | phdr_ptr = (Elf32_Phdr*)(elfptr + sizeof(Elf32_Ehdr)); /* PT_NOTE hdr */ | ||
435 | |||
436 | /* First program header is PT_NOTE header. */ | ||
437 | vmcore_off = sizeof(Elf32_Ehdr) + | ||
438 | (ehdr_ptr->e_phnum) * sizeof(Elf32_Phdr) + | ||
439 | phdr_ptr->p_memsz; /* Note sections */ | ||
440 | |||
441 | for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) { | ||
442 | if (phdr_ptr->p_type != PT_LOAD) | ||
443 | continue; | ||
444 | |||
445 | /* Add this contiguous chunk of memory to vmcore list.*/ | ||
446 | new = get_new_element(); | ||
447 | if (!new) | ||
448 | return -ENOMEM; | ||
449 | new->paddr = phdr_ptr->p_offset; | ||
450 | new->size = phdr_ptr->p_memsz; | ||
451 | list_add_tail(&new->list, vc_list); | ||
452 | |||
453 | /* Update the program header offset */ | ||
454 | phdr_ptr->p_offset = vmcore_off; | ||
455 | vmcore_off = vmcore_off + phdr_ptr->p_memsz; | ||
456 | } | ||
457 | return 0; | ||
458 | } | ||
459 | |||
460 | /* Sets offset fields of vmcore elements. */ | ||
461 | static void __init set_vmcore_list_offsets_elf64(char *elfptr, | ||
462 | struct list_head *vc_list) | ||
463 | { | ||
464 | loff_t vmcore_off; | ||
465 | Elf64_Ehdr *ehdr_ptr; | ||
466 | struct vmcore *m; | ||
467 | |||
468 | ehdr_ptr = (Elf64_Ehdr *)elfptr; | ||
469 | |||
470 | /* Skip Elf header and program headers. */ | ||
471 | vmcore_off = sizeof(Elf64_Ehdr) + | ||
472 | (ehdr_ptr->e_phnum) * sizeof(Elf64_Phdr); | ||
473 | |||
474 | list_for_each_entry(m, vc_list, list) { | ||
475 | m->offset = vmcore_off; | ||
476 | vmcore_off += m->size; | ||
477 | } | ||
478 | } | ||
479 | |||
480 | /* Sets offset fields of vmcore elements. */ | ||
481 | static void __init set_vmcore_list_offsets_elf32(char *elfptr, | ||
482 | struct list_head *vc_list) | ||
483 | { | ||
484 | loff_t vmcore_off; | ||
485 | Elf32_Ehdr *ehdr_ptr; | ||
486 | struct vmcore *m; | ||
487 | |||
488 | ehdr_ptr = (Elf32_Ehdr *)elfptr; | ||
489 | |||
490 | /* Skip Elf header and program headers. */ | ||
491 | vmcore_off = sizeof(Elf32_Ehdr) + | ||
492 | (ehdr_ptr->e_phnum) * sizeof(Elf32_Phdr); | ||
493 | |||
494 | list_for_each_entry(m, vc_list, list) { | ||
495 | m->offset = vmcore_off; | ||
496 | vmcore_off += m->size; | ||
497 | } | ||
498 | } | ||
499 | |||
500 | static int __init parse_crash_elf64_headers(void) | ||
501 | { | ||
502 | int rc=0; | ||
503 | Elf64_Ehdr ehdr; | ||
504 | u64 addr; | ||
505 | |||
506 | addr = elfcorehdr_addr; | ||
507 | |||
508 | /* Read Elf header */ | ||
509 | rc = read_from_oldmem((char*)&ehdr, sizeof(Elf64_Ehdr), &addr, 0); | ||
510 | if (rc < 0) | ||
511 | return rc; | ||
512 | |||
513 | /* Do some basic Verification. */ | ||
514 | if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 || | ||
515 | (ehdr.e_type != ET_CORE) || | ||
516 | !elf_check_arch(&ehdr) || | ||
517 | ehdr.e_ident[EI_CLASS] != ELFCLASS64 || | ||
518 | ehdr.e_ident[EI_VERSION] != EV_CURRENT || | ||
519 | ehdr.e_version != EV_CURRENT || | ||
520 | ehdr.e_ehsize != sizeof(Elf64_Ehdr) || | ||
521 | ehdr.e_phentsize != sizeof(Elf64_Phdr) || | ||
522 | ehdr.e_phnum == 0) { | ||
523 | printk(KERN_WARNING "Warning: Core image elf header is not" | ||
524 | "sane\n"); | ||
525 | return -EINVAL; | ||
526 | } | ||
527 | |||
528 | /* Read in all elf headers. */ | ||
529 | elfcorebuf_sz = sizeof(Elf64_Ehdr) + ehdr.e_phnum * sizeof(Elf64_Phdr); | ||
530 | elfcorebuf = kmalloc(elfcorebuf_sz, GFP_KERNEL); | ||
531 | if (!elfcorebuf) | ||
532 | return -ENOMEM; | ||
533 | addr = elfcorehdr_addr; | ||
534 | rc = read_from_oldmem(elfcorebuf, elfcorebuf_sz, &addr, 0); | ||
535 | if (rc < 0) { | ||
536 | kfree(elfcorebuf); | ||
537 | return rc; | ||
538 | } | ||
539 | |||
540 | /* Merge all PT_NOTE headers into one. */ | ||
541 | rc = merge_note_headers_elf64(elfcorebuf, &elfcorebuf_sz, &vmcore_list); | ||
542 | if (rc) { | ||
543 | kfree(elfcorebuf); | ||
544 | return rc; | ||
545 | } | ||
546 | rc = process_ptload_program_headers_elf64(elfcorebuf, elfcorebuf_sz, | ||
547 | &vmcore_list); | ||
548 | if (rc) { | ||
549 | kfree(elfcorebuf); | ||
550 | return rc; | ||
551 | } | ||
552 | set_vmcore_list_offsets_elf64(elfcorebuf, &vmcore_list); | ||
553 | return 0; | ||
554 | } | ||
555 | |||
556 | static int __init parse_crash_elf32_headers(void) | ||
557 | { | ||
558 | int rc=0; | ||
559 | Elf32_Ehdr ehdr; | ||
560 | u64 addr; | ||
561 | |||
562 | addr = elfcorehdr_addr; | ||
563 | |||
564 | /* Read Elf header */ | ||
565 | rc = read_from_oldmem((char*)&ehdr, sizeof(Elf32_Ehdr), &addr, 0); | ||
566 | if (rc < 0) | ||
567 | return rc; | ||
568 | |||
569 | /* Do some basic Verification. */ | ||
570 | if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 || | ||
571 | (ehdr.e_type != ET_CORE) || | ||
572 | !elf_check_arch(&ehdr) || | ||
573 | ehdr.e_ident[EI_CLASS] != ELFCLASS32|| | ||
574 | ehdr.e_ident[EI_VERSION] != EV_CURRENT || | ||
575 | ehdr.e_version != EV_CURRENT || | ||
576 | ehdr.e_ehsize != sizeof(Elf32_Ehdr) || | ||
577 | ehdr.e_phentsize != sizeof(Elf32_Phdr) || | ||
578 | ehdr.e_phnum == 0) { | ||
579 | printk(KERN_WARNING "Warning: Core image elf header is not" | ||
580 | "sane\n"); | ||
581 | return -EINVAL; | ||
582 | } | ||
583 | |||
584 | /* Read in all elf headers. */ | ||
585 | elfcorebuf_sz = sizeof(Elf32_Ehdr) + ehdr.e_phnum * sizeof(Elf32_Phdr); | ||
586 | elfcorebuf = kmalloc(elfcorebuf_sz, GFP_KERNEL); | ||
587 | if (!elfcorebuf) | ||
588 | return -ENOMEM; | ||
589 | addr = elfcorehdr_addr; | ||
590 | rc = read_from_oldmem(elfcorebuf, elfcorebuf_sz, &addr, 0); | ||
591 | if (rc < 0) { | ||
592 | kfree(elfcorebuf); | ||
593 | return rc; | ||
594 | } | ||
595 | |||
596 | /* Merge all PT_NOTE headers into one. */ | ||
597 | rc = merge_note_headers_elf32(elfcorebuf, &elfcorebuf_sz, &vmcore_list); | ||
598 | if (rc) { | ||
599 | kfree(elfcorebuf); | ||
600 | return rc; | ||
601 | } | ||
602 | rc = process_ptload_program_headers_elf32(elfcorebuf, elfcorebuf_sz, | ||
603 | &vmcore_list); | ||
604 | if (rc) { | ||
605 | kfree(elfcorebuf); | ||
606 | return rc; | ||
607 | } | ||
608 | set_vmcore_list_offsets_elf32(elfcorebuf, &vmcore_list); | ||
609 | return 0; | ||
610 | } | ||
611 | |||
612 | static int __init parse_crash_elf_headers(void) | ||
613 | { | ||
614 | unsigned char e_ident[EI_NIDENT]; | ||
615 | u64 addr; | ||
616 | int rc=0; | ||
617 | |||
618 | addr = elfcorehdr_addr; | ||
619 | rc = read_from_oldmem(e_ident, EI_NIDENT, &addr, 0); | ||
620 | if (rc < 0) | ||
621 | return rc; | ||
622 | if (memcmp(e_ident, ELFMAG, SELFMAG) != 0) { | ||
623 | printk(KERN_WARNING "Warning: Core image elf header" | ||
624 | " not found\n"); | ||
625 | return -EINVAL; | ||
626 | } | ||
627 | |||
628 | if (e_ident[EI_CLASS] == ELFCLASS64) { | ||
629 | rc = parse_crash_elf64_headers(); | ||
630 | if (rc) | ||
631 | return rc; | ||
632 | |||
633 | /* Determine vmcore size. */ | ||
634 | vmcore_size = get_vmcore_size_elf64(elfcorebuf); | ||
635 | } else if (e_ident[EI_CLASS] == ELFCLASS32) { | ||
636 | rc = parse_crash_elf32_headers(); | ||
637 | if (rc) | ||
638 | return rc; | ||
639 | |||
640 | /* Determine vmcore size. */ | ||
641 | vmcore_size = get_vmcore_size_elf32(elfcorebuf); | ||
642 | } else { | ||
643 | printk(KERN_WARNING "Warning: Core image elf header is not" | ||
644 | " sane\n"); | ||
645 | return -EINVAL; | ||
646 | } | ||
647 | return 0; | ||
648 | } | ||
649 | |||
650 | /* Init function for vmcore module. */ | ||
651 | static int __init vmcore_init(void) | ||
652 | { | ||
653 | int rc = 0; | ||
654 | |||
655 | /* If elfcorehdr= has been passed in cmdline, then capture the dump.*/ | ||
656 | if (!(elfcorehdr_addr < ELFCORE_ADDR_MAX)) | ||
657 | return rc; | ||
658 | rc = parse_crash_elf_headers(); | ||
659 | if (rc) { | ||
660 | printk(KERN_WARNING "Kdump: vmcore not initialized\n"); | ||
661 | return rc; | ||
662 | } | ||
663 | |||
664 | /* Initialize /proc/vmcore size if proc is already up. */ | ||
665 | if (proc_vmcore) | ||
666 | proc_vmcore->size = vmcore_size; | ||
667 | return 0; | ||
668 | } | ||
669 | module_init(vmcore_init) | ||
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 0d5817f81972..289d864fe731 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -254,6 +254,7 @@ static int _get_block_create_0 (struct inode * inode, long block, | |||
254 | char * p = NULL; | 254 | char * p = NULL; |
255 | int chars; | 255 | int chars; |
256 | int ret ; | 256 | int ret ; |
257 | int result ; | ||
257 | int done = 0 ; | 258 | int done = 0 ; |
258 | unsigned long offset ; | 259 | unsigned long offset ; |
259 | 260 | ||
@@ -262,10 +263,13 @@ static int _get_block_create_0 (struct inode * inode, long block, | |||
262 | (loff_t)block * inode->i_sb->s_blocksize + 1, TYPE_ANY, 3); | 263 | (loff_t)block * inode->i_sb->s_blocksize + 1, TYPE_ANY, 3); |
263 | 264 | ||
264 | research: | 265 | research: |
265 | if (search_for_position_by_key (inode->i_sb, &key, &path) != POSITION_FOUND) { | 266 | result = search_for_position_by_key (inode->i_sb, &key, &path) ; |
267 | if (result != POSITION_FOUND) { | ||
266 | pathrelse (&path); | 268 | pathrelse (&path); |
267 | if (p) | 269 | if (p) |
268 | kunmap(bh_result->b_page) ; | 270 | kunmap(bh_result->b_page) ; |
271 | if (result == IO_ERROR) | ||
272 | return -EIO; | ||
269 | // We do not return -ENOENT if there is a hole but page is uptodate, because it means | 273 | // We do not return -ENOENT if there is a hole but page is uptodate, because it means |
270 | // That there is some MMAPED data associated with it that is yet to be written to disk. | 274 | // That there is some MMAPED data associated with it that is yet to be written to disk. |
271 | if ((args & GET_BLOCK_NO_HOLE) && !PageUptodate(bh_result->b_page) ) { | 275 | if ((args & GET_BLOCK_NO_HOLE) && !PageUptodate(bh_result->b_page) ) { |
@@ -382,8 +386,9 @@ research: | |||
382 | 386 | ||
383 | // update key to look for the next piece | 387 | // update key to look for the next piece |
384 | set_cpu_key_k_offset (&key, cpu_key_k_offset (&key) + chars); | 388 | set_cpu_key_k_offset (&key, cpu_key_k_offset (&key) + chars); |
385 | if (search_for_position_by_key (inode->i_sb, &key, &path) != POSITION_FOUND) | 389 | result = search_for_position_by_key (inode->i_sb, &key, &path); |
386 | // we read something from tail, even if now we got IO_ERROR | 390 | if (result != POSITION_FOUND) |
391 | // i/o error most likely | ||
387 | break; | 392 | break; |
388 | bh = get_last_bh (&path); | 393 | bh = get_last_bh (&path); |
389 | ih = get_ih (&path); | 394 | ih = get_ih (&path); |
@@ -394,6 +399,10 @@ research: | |||
394 | 399 | ||
395 | finished: | 400 | finished: |
396 | pathrelse (&path); | 401 | pathrelse (&path); |
402 | |||
403 | if (result == IO_ERROR) | ||
404 | return -EIO; | ||
405 | |||
397 | /* this buffer has valid data, but isn't valid for io. mapping it to | 406 | /* this buffer has valid data, but isn't valid for io. mapping it to |
398 | * block #0 tells the rest of reiserfs it just has a tail in it | 407 | * block #0 tells the rest of reiserfs it just has a tail in it |
399 | */ | 408 | */ |