Re: [patch] Real-Time Preemption, -VP-2.6.9-rc4-mm1-U3

From: OGAWA Hirofumi
Date: Sun Oct 17 2004 - 10:38:52 EST


Dominik Karall <dominik.karall@xxxxxxx> writes:

> i could reproduce it now, but only once. it appeared when i started an avi
> movie from my fat32 partition. mplayer stopped at buffering 2% and does not
> play the movie. i tried to start mplayer again and reproduce it, but the bug
> does not appear again. mplayer only stopped at 2% buffering and does nothing
> more. it seems like the file couldn't be read clearly now from the fat32
> partition, as it does not work with xine and others too.
> here is the bug i get now:
>
> ------------[ cut here ]------------
> kernel BUG at fs/fat/cache.c:150!

Probably this BUG_ON() was wrong. Does this bug occur only by the
specific file?

If so, please do "filefrag -v filename" against that file.

Then, can you try the attached patch? This patch removes the BUG_ON(),
and instead adds printk() for debugging. When the bug occured, it prints
the current cache.

Thanks.
--
OGAWA Hirofumi <hirofumi@xxxxxxxxxxxxxxxxxx>



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

fs/fat/cache.c | 26 +++++++++++++++++++++++++-
1 files changed, 25 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 00:26:44.000000000 +0900
@@ -134,6 +134,30 @@ 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;
+
+ 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:
+ printk("%s: id %u, contig %d, fclus %d, dclus %d\n", __FUNCTION__,
+ new->id, new->nr_contig, new->fcluster, new->dcluster);
+ list_for_each_entry(p, &MSDOS_I(inode)->cache_lru, cache_list) {
+ printk("contig %d, fclus %d, dclus %d\n",
+ 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 +170,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++;
_