diff options
Diffstat (limited to 'fs/hpfs/buffer.c')
| -rw-r--r-- | fs/hpfs/buffer.c | 108 | 
1 files changed, 56 insertions, 52 deletions
diff --git a/fs/hpfs/buffer.c b/fs/hpfs/buffer.c index 4d0a1afa058..8057fe4e657 100644 --- a/fs/hpfs/buffer.c +++ b/fs/hpfs/buffer.c @@ -55,7 +55,7 @@ void *hpfs_map_sector(struct super_block *s, unsigned secno, struct buffer_head  	if (bh != NULL)  		return bh->b_data;  	else { -		printk("HPFS: hpfs_map_sector: read error\n"); +		pr_err("%s(): read error\n", __func__);  		return NULL;  	}  } @@ -76,7 +76,7 @@ void *hpfs_get_sector(struct super_block *s, unsigned secno, struct buffer_head  		set_buffer_uptodate(bh);  		return bh->b_data;  	} else { -		printk("HPFS: hpfs_get_sector: getblk failed\n"); +		pr_err("%s(): getblk failed\n", __func__);  		return NULL;  	}  } @@ -86,7 +86,6 @@ void *hpfs_get_sector(struct super_block *s, unsigned secno, struct buffer_head  void *hpfs_map_4sectors(struct super_block *s, unsigned secno, struct quad_buffer_head *qbh,  		   int ahead)  { -	struct buffer_head *bh;  	char *data;  	hpfs_lock_assert(s); @@ -94,40 +93,38 @@ void *hpfs_map_4sectors(struct super_block *s, unsigned secno, struct quad_buffe  	cond_resched();  	if (secno & 3) { -		printk("HPFS: hpfs_map_4sectors: unaligned read\n"); +		pr_err("%s(): unaligned read\n", __func__);  		return NULL;  	}  	hpfs_prefetch_sectors(s, secno, 4 + ahead); +	if (!(qbh->bh[0] = sb_bread(s, secno + 0))) goto bail0; +	if (!(qbh->bh[1] = sb_bread(s, secno + 1))) goto bail1; +	if (!(qbh->bh[2] = sb_bread(s, secno + 2))) goto bail2; +	if (!(qbh->bh[3] = sb_bread(s, secno + 3))) goto bail3; + +	if (likely(qbh->bh[1]->b_data == qbh->bh[0]->b_data + 1 * 512) && +	    likely(qbh->bh[2]->b_data == qbh->bh[0]->b_data + 2 * 512) && +	    likely(qbh->bh[3]->b_data == qbh->bh[0]->b_data + 3 * 512)) { +		return qbh->data = qbh->bh[0]->b_data; +	} +  	qbh->data = data = kmalloc(2048, GFP_NOFS);  	if (!data) { -		printk("HPFS: hpfs_map_4sectors: out of memory\n"); -		goto bail; +		pr_err("%s(): out of memory\n", __func__); +		goto bail4;  	} -	qbh->bh[0] = bh = sb_bread(s, secno); -	if (!bh) -		goto bail0; -	memcpy(data, bh->b_data, 512); - -	qbh->bh[1] = bh = sb_bread(s, secno + 1); -	if (!bh) -		goto bail1; -	memcpy(data + 512, bh->b_data, 512); - -	qbh->bh[2] = bh = sb_bread(s, secno + 2); -	if (!bh) -		goto bail2; -	memcpy(data + 2 * 512, bh->b_data, 512); - -	qbh->bh[3] = bh = sb_bread(s, secno + 3); -	if (!bh) -		goto bail3; -	memcpy(data + 3 * 512, bh->b_data, 512); +	memcpy(data + 0 * 512, qbh->bh[0]->b_data, 512); +	memcpy(data + 1 * 512, qbh->bh[1]->b_data, 512); +	memcpy(data + 2 * 512, qbh->bh[2]->b_data, 512); +	memcpy(data + 3 * 512, qbh->bh[3]->b_data, 512);  	return data; + bail4: +	brelse(qbh->bh[3]);   bail3:  	brelse(qbh->bh[2]);   bail2: @@ -135,9 +132,6 @@ void *hpfs_map_4sectors(struct super_block *s, unsigned secno, struct quad_buffe   bail1:  	brelse(qbh->bh[0]);   bail0: -	kfree(data); -	printk("HPFS: hpfs_map_4sectors: read error\n"); - bail:  	return NULL;  } @@ -151,48 +145,58 @@ void *hpfs_get_4sectors(struct super_block *s, unsigned secno,  	hpfs_lock_assert(s);  	if (secno & 3) { -		printk("HPFS: hpfs_get_4sectors: unaligned read\n"); +		pr_err("%s(): unaligned read\n", __func__);  		return NULL;  	} -	/*return hpfs_map_4sectors(s, secno, qbh, 0);*/ +	if (!hpfs_get_sector(s, secno + 0, &qbh->bh[0])) goto bail0; +	if (!hpfs_get_sector(s, secno + 1, &qbh->bh[1])) goto bail1; +	if (!hpfs_get_sector(s, secno + 2, &qbh->bh[2])) goto bail2; +	if (!hpfs_get_sector(s, secno + 3, &qbh->bh[3])) goto bail3; + +	if (likely(qbh->bh[1]->b_data == qbh->bh[0]->b_data + 1 * 512) && +	    likely(qbh->bh[2]->b_data == qbh->bh[0]->b_data + 2 * 512) && +	    likely(qbh->bh[3]->b_data == qbh->bh[0]->b_data + 3 * 512)) { +		return qbh->data = qbh->bh[0]->b_data; +	} +  	if (!(qbh->data = kmalloc(2048, GFP_NOFS))) { -		printk("HPFS: hpfs_get_4sectors: out of memory\n"); -		return NULL; +		pr_err("%s(): out of memory\n", __func__); +		goto bail4;  	} -	if (!(hpfs_get_sector(s, secno, &qbh->bh[0]))) goto bail0; -	if (!(hpfs_get_sector(s, secno + 1, &qbh->bh[1]))) goto bail1; -	if (!(hpfs_get_sector(s, secno + 2, &qbh->bh[2]))) goto bail2; -	if (!(hpfs_get_sector(s, secno + 3, &qbh->bh[3]))) goto bail3; -	memcpy(qbh->data, qbh->bh[0]->b_data, 512); -	memcpy(qbh->data + 512, qbh->bh[1]->b_data, 512); -	memcpy(qbh->data + 2*512, qbh->bh[2]->b_data, 512); -	memcpy(qbh->data + 3*512, qbh->bh[3]->b_data, 512);  	return qbh->data; -	bail3:	brelse(qbh->bh[2]); -	bail2:	brelse(qbh->bh[1]); -	bail1:	brelse(qbh->bh[0]); -	bail0: +bail4: +	brelse(qbh->bh[3]); +bail3: +	brelse(qbh->bh[2]); +bail2: +	brelse(qbh->bh[1]); +bail1: +	brelse(qbh->bh[0]); +bail0:  	return NULL;  }  void hpfs_brelse4(struct quad_buffer_head *qbh)  { -	brelse(qbh->bh[3]); -	brelse(qbh->bh[2]); -	brelse(qbh->bh[1]); +	if (unlikely(qbh->data != qbh->bh[0]->b_data)) +		kfree(qbh->data);  	brelse(qbh->bh[0]); -	kfree(qbh->data); +	brelse(qbh->bh[1]); +	brelse(qbh->bh[2]); +	brelse(qbh->bh[3]);  }	  void hpfs_mark_4buffers_dirty(struct quad_buffer_head *qbh)  { -	memcpy(qbh->bh[0]->b_data, qbh->data, 512); -	memcpy(qbh->bh[1]->b_data, qbh->data + 512, 512); -	memcpy(qbh->bh[2]->b_data, qbh->data + 2 * 512, 512); -	memcpy(qbh->bh[3]->b_data, qbh->data + 3 * 512, 512); +	if (unlikely(qbh->data != qbh->bh[0]->b_data)) { +		memcpy(qbh->bh[0]->b_data, qbh->data + 0 * 512, 512); +		memcpy(qbh->bh[1]->b_data, qbh->data + 1 * 512, 512); +		memcpy(qbh->bh[2]->b_data, qbh->data + 2 * 512, 512); +		memcpy(qbh->bh[3]->b_data, qbh->data + 3 * 512, 512); +	}  	mark_buffer_dirty(qbh->bh[0]);  	mark_buffer_dirty(qbh->bh[1]);  	mark_buffer_dirty(qbh->bh[2]);  | 
