Re: 2.6.9bk6 msdos fs OOPS

From: OGAWA Hirofumi
Date: Thu Oct 28 2004 - 04:27:08 EST


Nigel Kukard <nkukard@xxxxxxxx> writes:

> OOPS is 100% reproducable. I boot into X, and run eog
> /mnt/camera/dcim/100cresi and BANG.

This is known problem. Can you please try the following patch?
Then, please send debugging output.

Thanks.
--
OGAWA Hirofumi <hirofumi@xxxxxxxxxxxxxxxxxx>



Signed-off-by: OGAWA Hirofumi <hirofumi@xxxxxxxxxxxxxxxxxx>
---

fs/fat/cache.c | 41 ++++++++++++++++++++++++++++++++++++++++-
1 files changed, 40 insertions(+), 1 deletion(-)

diff -puN fs/fat/cache.c~fat-debug fs/fat/cache.c
--- linux-2.6.9-final-a/fs/fat/cache.c~fat-debug 2004-10-17 23:45:27.000000000 +0900
+++ linux-2.6.9-final-a-hirofumi/fs/fat/cache.c 2004-10-18 09:38:31.000000000 +0900
@@ -11,6 +11,7 @@
#include <linux/fs.h>
#include <linux/msdos_fs.h>
#include <linux/buffer_head.h>
+#include <linux/sched.h>

/* this must be > 0. */
#define FAT_MAX_CACHE 8
@@ -20,6 +21,10 @@ struct fat_cache {
int nr_contig; /* number of contiguous clusters */
int fcluster; /* cluster number in the file. */
int dcluster; /* cluster number on disk. */
+ char comm[16];
+ pid_t pid;
+ unsigned int id;
+ unsigned long long tsc;
};

struct fat_cache_id {
@@ -134,6 +139,36 @@ static struct fat_cache *fat_cache_merge
return NULL;
}

+static void fat_cache_check(struct inode *inode, struct fat_cache_id *new)
+{
+ struct fat_cache *p;
+ unsigned long long tsc;
+
+ if (new->id == FAT_CACHE_VALID) {
+ list_for_each_entry(p, &MSDOS_I(inode)->cache_lru, cache_list) {
+ /* Find the same part as "new" in cluster-chain. */
+ if (p->fcluster == new->fcluster) {
+ BUG_ON(p->dcluster != new->dcluster);
+ goto dump_cache;
+ }
+ }
+ }
+ return;
+
+dump_cache:
+ rdtscll(tsc);
+ printk("%s: tsc %llu, comm %s, pid %d, id %u, "
+ "contig %d, fclus %d, dclus %d\n",
+ __FUNCTION__, tsc, current->comm, current->pid, new->id,
+ new->nr_contig, new->fcluster, new->dcluster);
+ list_for_each_entry(p, &MSDOS_I(inode)->cache_lru, cache_list) {
+ printk("tsc %llu, comm %s, pid %d, id %u, "
+ "contig %d, fclus %d, dclus %d\n",
+ p->tsc, p->comm, p->pid, p->id,
+ p->nr_contig, p->fcluster, p->dcluster);
+ }
+}
+
static void fat_cache_add(struct inode *inode, struct fat_cache_id *new)
{
struct fat_cache *cache, *tmp;
@@ -146,8 +181,8 @@ static void fat_cache_add(struct inode *
new->id != MSDOS_I(inode)->cache_valid_id)
goto out; /* this cache was invalidated */

+ fat_cache_check(inode, new);
cache = fat_cache_merge(inode, new);
- BUG_ON(new->id == FAT_CACHE_VALID && cache != NULL);
if (cache == NULL) {
if (MSDOS_I(inode)->nr_caches < fat_max_cache(inode)) {
MSDOS_I(inode)->nr_caches++;
@@ -171,6 +206,10 @@ static void fat_cache_add(struct inode *
cache->nr_contig = new->nr_contig;
}
out_update_lru:
+ strcpy(cache->comm, current->comm);
+ cache->pid = current->pid;
+ cache->id = new->id;
+ rdtscll(cache->tsc);
fat_cache_update_lru(inode, cache);
out:
spin_unlock(&MSDOS_I(inode)->cache_lru_lock);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/