Beispiel #1
0
s32 bdev_mwrite(struct super_block *sb, u32 secno, struct buffer_head *bh, u32 num_secs, s32 sync)
{
	s32 count;
	struct buffer_head *bh2;
	FS_INFO_T *fsi = &(SDFAT_SB(sb)->fsi);
#ifdef CONFIG_SDFAT_DBG_IOCTL
	struct sdfat_sb_info *sbi = SDFAT_SB(sb);
	long flags = sbi->debug_flags;

	if (flags & SDFAT_DEBUGFLAGS_ERROR_RW)	
		return -EIO;
#endif /* CONFIG_SDFAT_DBG_IOCTL */

	if (!fsi->bd_opened) 
		return -EIO;

	if (secno == bh->b_blocknr) {
		set_buffer_uptodate(bh);
		mark_buffer_dirty(bh);
		if (sync && (sync_dirty_buffer(bh) != 0))
			return -EIO;
	} else {
		count = num_secs << sb->s_blocksize_bits;

		bh2 = __getblk(sb->s_bdev, secno, count);

		if (!bh2)
			goto no_bh;

		lock_buffer(bh2);
		memcpy(bh2->b_data, bh->b_data, count);
		set_buffer_uptodate(bh2);
		mark_buffer_dirty(bh2);
		unlock_buffer(bh2);
		if (sync && (sync_dirty_buffer(bh2) != 0)) {
			__brelse(bh2);
			goto no_bh;
		}
		__brelse(bh2);
	}

	return 0;

no_bh:
	/* 
	 * patch 1.2.4 : reset ONCE warning message per volume.
	 */
	if(!(fsi->prev_eio & SDFAT_EIO_WRITE)) {
		fsi->prev_eio |= SDFAT_EIO_WRITE;
		sdfat_log_msg(sb, KERN_ERR, "%s: No bh. I/O error.", __func__);
#ifdef CONFIG_SDFAT_DEBUG
		sdfat_debug_warn_on(1);
#endif
	}

	return -EIO;
}
Beispiel #2
0
static inline void fat_dir_readahead(struct inode *dir, sector_t iblock,
				     sector_t phys)
{
	struct super_block *sb = dir->i_sb;
	struct sdfat_sb_info *sbi = SDFAT_SB(sb);
	struct buffer_head *bh;
	int sec;

	/* This is not a first sector of cluster, or sec_per_clus == 1 */
	if ((iblock & (sbi->sec_per_clus - 1)) || sbi->sec_per_clus == 1)
		return;
	/* root dir of FAT12/FAT16 */
	if ((sbi->fat_bits != 32) && (dir->i_ino == MSDOS_ROOT_INO))
		return;

	bh = sb_find_get_block(sb, phys);
	if (bh == NULL || !buffer_uptodate(bh)) {
		for (sec = 0; sec < sbi->sec_per_clus; sec++){
			/* Modified by Panasonic (SAV), 2009-oct-5 */
			meta_breadahead(sb, phys + sec, BH_Dirent);
			/*-----------------------------------------*/
		}
	}
	brelse(bh);
}
Beispiel #3
0
static inline loff_t fat_make_i_pos(struct super_block *sb,
				    struct buffer_head *bh,
				    struct msdos_dir_entry *de)
{
	return ((loff_t)bh->b_blocknr << SDFAT_SB(sb)->dir_per_block_bits)
		| (de - (struct msdos_dir_entry *)bh->b_data);
}
Beispiel #4
0
s32 bdev_close_dev(struct super_block *sb)
{
	FS_INFO_T *fsi = &(SDFAT_SB(sb)->fsi);

	fsi->bd_opened = false;
	return 0;
}
Beispiel #5
0
s32 bdev_sync_all(struct super_block *sb)
{
	FS_INFO_T *fsi = &(SDFAT_SB(sb)->fsi);
#ifdef CONFIG_SDFAT_DBG_IOCTL
	struct sdfat_sb_info *sbi = SDFAT_SB(sb);
	long flags = sbi->debug_flags;

	if (flags & SDFAT_DEBUGFLAGS_ERROR_RW)	
		return -EIO;
#endif /* CONFIG_SDFAT_DBG_IOCTL */

	if (!fsi->bd_opened) 
		return -EIO;

	return sync_blockdev(sb->s_bdev);
}
Beispiel #6
0
/*======================================================================*/
s32 bdev_open_dev(struct super_block *sb)
{
	FS_INFO_T *fsi = &(SDFAT_SB(sb)->fsi);

	if (fsi->bd_opened) 
		return 0;

	fsi->bd_opened = true;
	return 0;
}
Beispiel #7
0
s32 bdev_mread(struct super_block *sb, u32 secno, struct buffer_head **bh, u32 num_secs, s32 read)
{
	FS_INFO_T *fsi = &(SDFAT_SB(sb)->fsi);
	u8 blksize_bits = sb->s_blocksize_bits;
#ifdef CONFIG_SDFAT_DBG_IOCTL
	struct sdfat_sb_info *sbi = SDFAT_SB(sb);
	long flags = sbi->debug_flags;

	if (flags & SDFAT_DEBUGFLAGS_ERROR_RW)	
		return -EIO;
#endif /* CONFIG_SDFAT_DBG_IOCTL */

	if (!fsi->bd_opened) 
		return -EIO;

	brelse(*bh);

	if (read)
		*bh = __bread(sb->s_bdev, secno, num_secs << blksize_bits);
	else
		*bh = __getblk(sb->s_bdev, secno, num_secs << blksize_bits);

	/* read successfully */
	if (*bh)
		return 0;

	/* 
	 * patch 1.2.4 : reset ONCE warning message per volume.
	 */
	if(!(fsi->prev_eio & SDFAT_EIO_READ)) {
		fsi->prev_eio |= SDFAT_EIO_READ;
		sdfat_log_msg(sb, KERN_ERR, "%s: No bh. I/O error.", __func__);
#ifdef CONFIG_SDFAT_DEBUG
		sdfat_debug_warn_on(1);
#endif
	}

	return -EIO;

}
Beispiel #8
0
static inline int fat_get_entry(struct inode *dir, loff_t *pos,
				struct buffer_head **bh,
				struct msdos_dir_entry **de)
{
	/* Fast stuff first */
	if (*bh && *de &&
	    (*de - (struct msdos_dir_entry *)(*bh)->b_data) < SDFAT_SB(dir->i_sb)->dir_per_block - 1) {
		*pos += sizeof(struct msdos_dir_entry);
		(*de)++;
		return 0;
	}
	return fat__get_entry(dir, pos, bh, de);
}
Beispiel #9
0
/* Make a readahead request */
s32 bdev_readahead(struct super_block *sb, u32 secno, u32 num_secs)
{
	FS_INFO_T *fsi = &(SDFAT_SB(sb)->fsi);
	int i;

	if (!fsi->bd_opened) 
		return -EIO;

	for (i = 0; i < num_secs; i++)
		__breadahead(sb->s_bdev, secno + i, 1 << sb->s_blocksize_bits);

	return 0;
}
Beispiel #10
0
s32 bdev_check_bdi_valid(struct super_block *sb)
{
	FS_INFO_T *fsi = &(SDFAT_SB(sb)->fsi);
	if (!sb->s_bdi || (sb->s_bdi == &default_backing_dev_info)) {
		if (!(fsi->prev_eio & SDFAT_EIO_BDI)) {
			fsi->prev_eio |= SDFAT_EIO_BDI;
			sdfat_log_msg(sb, KERN_ERR, "%s: block device is "
				"eliminated.(bdi:%p)", __func__, sb->s_bdi);
#ifdef CONFIG_SDFAT_DEBUG
			sdfat_debug_warn_on(1);
#endif
		}
		return -ENXIO;
	}
	return 0;
}
Beispiel #11
0
s32 read_msect(struct super_block *sb, u32 sec, struct buffer_head **bh, s32 num_secs, s32 read)
{
	FS_INFO_T *fsi = &(SDFAT_SB(sb)->fsi);
	BUG_ON(!bh);

	if ( ((sec+num_secs) > fsi->num_sectors) && (fsi->num_sectors > 0) ) {
		sdfat_fs_error_ratelimit(sb, "%s: out of range(sect:%d len:%d)",
						__func__ ,sec, num_secs);
		return -EIO;
	}

	if (bdev_mread(sb, sec, bh, num_secs, read)) {
		sdfat_fs_error_ratelimit(sb, "%s: I/O error (sect:%d len:%d)",
						__func__,sec, num_secs);
		return -EIO;
	}

	return 0;
} /* end of read_msect */
Beispiel #12
0
s32 write_sect(struct super_block *sb, u32 sec, struct buffer_head *bh, s32 sync)
{
	FS_INFO_T *fsi = &(SDFAT_SB(sb)->fsi);
	BUG_ON(!bh);

	if ( (sec >= fsi->num_sectors)
					&& (fsi->num_sectors > 0) ) {
		sdfat_fs_error_ratelimit(sb, "%s: out of range (sect:%d)", 
								__func__, sec);
		return -EIO;
	}

	if (bdev_mwrite(sb, sec, bh, 1, sync)) {
		sdfat_fs_error_ratelimit(sb, "%s: I/O error (sect:%d)",
								__func__, sec);
		return -EIO;
	}

	return 0;
} /* end of write_sect */