aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/Kconfig6
-rw-r--r--fs/dquot.c7
-rw-r--r--fs/jffs/intrep.c114
-rw-r--r--fs/jffs/intrep.h2
-rw-r--r--fs/jffs/jffs_fm.c105
-rw-r--r--fs/jffs/jffs_fm.h3
-rw-r--r--fs/libfs.c1
-rw-r--r--fs/ncpfs/dir.c13
-rw-r--r--fs/ncpfs/ncplib_kernel.c40
-rw-r--r--fs/ncpfs/ncplib_kernel.h3
-rw-r--r--fs/partitions/Makefile1
-rw-r--r--fs/partitions/check.c3
-rw-r--r--fs/partitions/check.h4
-rw-r--r--fs/partitions/msdos.c4
-rw-r--r--fs/proc/Makefile1
-rw-r--r--fs/proc/proc_misc.c6
-rw-r--r--fs/proc/vmcore.c669
-rw-r--r--fs/reiserfs/inode.c15
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
737config 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
737config SYSFS 743config 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. */
410static void invalidate_dquots(struct super_block *sb, int type) 410static 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. */
179static void
180jffs_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. */
202static void
203jffs_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. */
2511void
2512jffs_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. */
2533void
2534jffs_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
2570int 2568int
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);
49void jffs_garbage_collect_trigger(struct jffs_control *c); 49void jffs_garbage_collect_trigger(struct jffs_control *c);
50 50
51/* For debugging purposes. */ 51/* For debugging purposes. */
52void jffs_print_node(struct jffs_node *n);
53void jffs_print_raw_inode(struct jffs_raw_inode *raw_inode);
54#if 0 52#if 0
55int jffs_print_file(struct jffs_file *f); 53int 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);
31extern kmem_cache_t *fm_cache; 31extern kmem_cache_t *fm_cache;
32extern kmem_cache_t *node_cache; 32extern kmem_cache_t *node_cache;
33 33
34#if CONFIG_JFFS_FS_VERBOSE > 0
35void
36jffs_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
62static void
63jffs_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
77void
78jffs_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. */
35struct jffs_fmcontrol * 89struct jffs_fmcontrol *
36jffs_build_begin(struct jffs_control *c, int unit) 90jffs_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
746void
747jffs_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
771void
772jffs_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
785void
786jffs_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);
139void jffs_fmfree_partly(struct jffs_fmcontrol *fmc, struct jffs_fm *fm, 139void 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
142void jffs_print_fmcontrol(struct jffs_fmcontrol *fmc); 143void jffs_print_fmcontrol(struct jffs_fmcontrol *fmc);
143void jffs_print_fm(struct jffs_fm *fm); 144#endif
144#if 0 145#if 0
145void jffs_print_node_ref(struct jffs_node_ref *ref); 146void 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
188struct inode_operations simple_dir_inode_operations = { 189struct 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 */
849int 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
883out:
884 ncp_unlock_server(server);
885 return result;
886}
887
888int ncp_search_for_fileset(struct ncp_server *server, 848int 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
88int ncp_initialize_search(struct ncp_server *, struct inode *, 88int ncp_initialize_search(struct ncp_server *, struct inode *,
89 struct nw_search_sequence *target); 89 struct nw_search_sequence *target);
90int ncp_search_for_file_or_subdir(struct ncp_server *server,
91 struct nw_search_sequence *seq,
92 struct nw_info_struct *target);
93int ncp_search_for_fileset(struct ncp_server *server, 90int 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
17obj-$(CONFIG_ULTRIX_PARTITION) += ultrix.o 17obj-$(CONFIG_ULTRIX_PARTITION) += ultrix.o
18obj-$(CONFIG_IBM_PARTITION) += ibm.o 18obj-$(CONFIG_IBM_PARTITION) += ibm.o
19obj-$(CONFIG_EFI_PARTITION) += efi.o 19obj-$(CONFIG_EFI_PARTITION) += efi.o
20obj-$(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
31extern int warn_no_part; 31extern int warn_no_part;
32 32
33extern 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 */
210void 210static void
211parse_bsd(struct parsed_partitions *state, struct block_device *bdev, 211parse_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
13proc-$(CONFIG_PROC_KCORE) += kcore.o 13proc-$(CONFIG_PROC_KCORE) += kcore.o
14proc-$(CONFIG_PROC_VMCORE) += vmcore.o
14proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o 15proc-$(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 */
29static LIST_HEAD(vmcore_list);
30
31/* Stores the pointer to the buffer containing kernel elf core headers. */
32static char *elfcorebuf;
33static size_t elfcorebuf_sz;
34
35/* Total size of vmcore file. */
36static u64 vmcore_size;
37
38struct proc_dir_entry *proc_vmcore = NULL;
39
40/* Reads a page from the oldmem device from given offset. */
41static 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. */
77static 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 */
100static 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
168static int open_vmcore(struct inode *inode, struct file *filp)
169{
170 return 0;
171}
172
173struct file_operations proc_vmcore_operations = {
174 .read = read_vmcore,
175 .open = open_vmcore,
176};
177
178static 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
188static 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
205static 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. */
223static 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. */
304static 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. */
386static 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
423static 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. */
461static 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. */
481static 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
500static 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
556static 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
612static 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. */
651static 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}
669module_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
264research: 265research:
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
395finished: 400finished:
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 */