示例#1
0
s32 bdev_read(struct super_block *sb, u32 secno, struct buffer_head **bh, u32 num_secs, s32 read)
{
	BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info);
	FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
#ifdef CONFIG_EXFAT_KERNEL_DEBUG
	struct exfat_sb_info *sbi = EXFAT_SB(sb);
	long flags = sbi->debug_flags;

	if (flags & EXFAT_DEBUGFLAGS_ERROR_RW)
		return FFS_MEDIAERR;
#endif /* CONFIG_EXFAT_KERNEL_DEBUG */

	if (!p_bd->opened)
		return FFS_MEDIAERR;

	if (*bh)
		__brelse(*bh);

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

	if (*bh)
		return FFS_SUCCESS;

	WARN(!p_fs->dev_ejected,
		"[EXFAT] No bh, device seems wrong or to be ejected.\n");

	return FFS_MEDIAERR;
}
UINT16 nls_upper(struct super_block *sb, UINT16 a)
{
	FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);

	if (EXFAT_SB(sb)->options.casesensitive)
		return(a);
	if ((p_fs->vol_utbl)[get_col_index(a)] != NULL)
		return (p_fs->vol_utbl)[get_col_index(a)][get_row_index(a)];
	else
		return a;
}
示例#3
0
s32 bdev_write(struct super_block *sb, u32 secno, struct buffer_head *bh, u32 num_secs, s32 sync)
{
	s32 count;
	struct buffer_head *bh2;
	BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info);
	FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
#ifdef CONFIG_EXFAT_KERNEL_DEBUG
	struct exfat_sb_info *sbi = EXFAT_SB(sb);
	long flags = sbi->debug_flags;

	if (flags & EXFAT_DEBUGFLAGS_ERROR_RW)
		return FFS_MEDIAERR;
#endif /* CONFIG_EXFAT_KERNEL_DEBUG */

	if (!p_bd->opened)
		return FFS_MEDIAERR;

	if (secno == bh->b_blocknr) {
		lock_buffer(bh);
		set_buffer_uptodate(bh);
		mark_buffer_dirty(bh);
		unlock_buffer(bh);
		if (sync && (sync_dirty_buffer(bh) != 0))
			return FFS_MEDIAERR;
	} else {
		count = num_secs << p_bd->sector_size_bits;

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

		if (bh2 == NULL)
			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 FFS_SUCCESS;

no_bh:
	WARN(!p_fs->dev_ejected,
		"[EXFAT] No bh, device seems wrong or to be ejected.\n");

	return FFS_MEDIAERR;
}
INT32 bdev_sync(struct super_block *sb)
{
BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info);
#if EXFAT_CONFIG_KERNEL_DEBUG
struct exfat_sb_info *sbi = EXFAT_SB(sb);
long flags = sbi->debug_flags;

if (flags & EXFAT_DEBUGFLAGS_ERROR_RW)        return (FFS_MEDIAERR);
#endif /* EXFAT_CONFIG_KERNEL_DEBUG */

if (!p_bd->opened) return(FFS_MEDIAERR);

return sync_blockdev(sb->s_bdev);
}
示例#5
0
void nls_uniname_to_cstring(struct super_block *sb, u8 *p_cstring, UNI_NAME_T *p_uniname)
{
	int i, j, len;
	u8 buf[MAX_CHARSET_SIZE];
	u16 *uniname = p_uniname->name;
	struct nls_table *nls = EXFAT_SB(sb)->nls_io;

	if (nls == NULL) {
		len = utf16s_to_utf8s(uniname, MAX_NAME_LENGTH, UTF16_HOST_ENDIAN, p_cstring, MAX_NAME_LENGTH);
		p_cstring[len] = 0;
		return;
	}

	i = 0;
	while (i < (MAX_NAME_LENGTH-1)) {
		if (*uniname == (u16) '\0')
			break;

		len = convert_uni_to_ch(nls, buf, *uniname, NULL);

		if (len > 1) {
			for (j = 0; j < len; j++)
				*p_cstring++ = (char) *(buf+j);
		} else { /* len == 1 */
			*p_cstring++ = (char) *buf;
		}

		uniname++;
		i++;
	}

	*p_cstring = '\0';
} /* end of nls_uniname_to_cstring */
void nls_uniname_to_cstring(struct super_block *sb, UINT8 *p_cstring, UNI_NAME_T *p_uniname)
{
	INT32 i, j, len;
	UINT8 buf[MAX_CHARSET_SIZE];
	UINT16 *uniname = p_uniname->name;
	struct nls_table *nls = EXFAT_SB(sb)->nls_io;

	i = 0;
	while (i < (MAX_NAME_LENGTH-1)) {
		if (*uniname == (UINT16) '\0') break;

		len = convert_uni_to_ch(nls, buf, *uniname, NULL);

		if (len > 1) {
			for (j = 0; j < len; j++)
				*p_cstring++ = (INT8) *(buf+j);
		} else {
			*p_cstring++ = (INT8) *buf;
		}

		uniname++;
		i++;
	}

	*p_cstring = '\0';
}
/*
 * Caller must be guarantee it have no race with truncate().  I.e. the
 * range of "iclusnr" and "iclusnr + len" must not be truncated.
 */
int exfat_get_cluster(struct inode *inode, u32 iclusnr, u32 clus_len,
		      struct exfat_clus_map *cmap)
{
	struct super_block *sb = inode->i_sb;
	struct exfat_sb_info *sbi = EXFAT_SB(sb);
	struct exfat_inode_info *exi = EXFAT_I(inode);
	struct exfat_cache_id cid;
	struct exfat_ent fatent;
	u32 clusnr;
	int err = 0, found_target;

	DEBUG0_ON(!exi->clusnr);

	if (exi->data_flag == EXFAT_DATA_CONTIGUOUS) {
		DEBUG_ON(clus_len >
		  (i_size_read(inode) + (sbi->clus_size - 1)) >> sbi->clus_bits,
			 "clus_len %u, i_size %lld, clus_size %lu\n",
			 clus_len, i_size_read(inode), sbi->clus_size);
		/* FIXME: should check clus_len limit from i_size? */
		cmap->iclusnr = iclusnr;
		cmap->clusnr = exi->clusnr + iclusnr;
		cmap->len = clus_len;
		printk("%s: contig: iclusnr %u, clusnr %u, len %u\n", __func__,
		       cmap->iclusnr, cmap->clusnr, cmap->len);
		return 0;
	}
INT32 bdev_close(struct super_block *sb)
{
BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info);

if (!p_bd->opened) return(FFS_SUCCESS);

p_bd->opened = FALSE;
return(FFS_SUCCESS);
}
void nls_cstring_to_uniname(struct super_block *sb, UNI_NAME_T *p_uniname, UINT8 *p_cstring, INT32 *p_lossy)
{
	INT32 i, j, lossy = FALSE;
	UINT8 *end_of_name;
	UINT8 upname[MAX_NAME_LENGTH * 2];
	UINT16 *uniname = p_uniname->name;
	struct nls_table *nls = EXFAT_SB(sb)->nls_io;


	/* strip all trailing spaces */
	end_of_name = p_cstring + STRLEN((INT8 *) p_cstring);

	while (*(--end_of_name) == ' ') {
		if (end_of_name < p_cstring) break;
	}
	*(++end_of_name) = '\0';

	if (STRCMP((INT8 *) p_cstring, ".") && STRCMP((INT8 *) p_cstring, "..")) {

		/* strip all trailing periods */
		while (*(--end_of_name) == '.') {
			if (end_of_name < p_cstring) break;
		}
		*(++end_of_name) = '\0';
	}

	if (*p_cstring == '\0')
		lossy = TRUE;

	i = j = 0;
	while (j < (MAX_NAME_LENGTH-1)) {
		if (*(p_cstring+i) == '\0') break;

		i += convert_ch_to_uni(nls, uniname, (UINT8 *)(p_cstring+i), &lossy);

		if ((*uniname < 0x0020) || WSTRCHR(bad_uni_chars, *uniname))
			lossy = TRUE;

		SET16_A(upname + j * 2, nls_upper(sb, *uniname));

		uniname++;
		j++;
	}

	if (*(p_cstring+i) != '\0')
		lossy = TRUE;
	*uniname = (UINT16) '\0';

	p_uniname->name_len = j;
	p_uniname->name_hash = calc_checksum_2byte((void *) upname, j<<1, 0, CS_DEFAULT);

	if (p_lossy != NULL)
		*p_lossy = lossy;
} /* end of nls_cstring_to_uniname */
示例#10
0
void nls_dosname_to_uniname(struct super_block *sb, UNI_NAME_T *p_uniname, DOS_NAME_T *p_dosname)
{
	int i = 0, j, n = 0;
	u8 buf[DOS_NAME_LENGTH+2];
	u8 *dosname = p_dosname->name;
	u16 *uniname = p_uniname->name;
	struct nls_table *nls = EXFAT_SB(sb)->nls_disk;

	if (*dosname == 0x05) {
		*buf = 0xE5;
		i++;
		n++;
	}

	for (; i < 8; i++, n++) {
		if (*(dosname+i) == ' ')
			break;

		if ((*(dosname+i) >= 'A') && (*(dosname+i) <= 'Z') && (p_dosname->name_case & 0x08))
			*(buf+n) = *(dosname+i) + ('a' - 'A');
		else
			*(buf+n) = *(dosname+i);
	}
	if (*(dosname+8) != ' ') {
		*(buf+n) = '.';
		n++;
	}

	for (i = 8; i < DOS_NAME_LENGTH; i++, n++) {
		if (*(dosname+i) == ' ')
			break;

		if ((*(dosname+i) >= 'A') && (*(dosname+i) <= 'Z') && (p_dosname->name_case & 0x10))
			*(buf+n) = *(dosname+i) + ('a' - 'A');
		else
			*(buf+n) = *(dosname+i);
	}
	*(buf+n) = '\0';

	i = j = 0;
	while (j < (MAX_NAME_LENGTH-1)) {
		if (*(buf+i) == '\0')
			break;

		i += convert_ch_to_uni(nls, uniname, (buf+i), NULL);

		uniname++;
		j++;
	}

	*uniname = (u16) '\0';
} /* end of nls_dosname_to_uniname */
示例#11
0
INT32 FsReleaseCache(struct super_block *sb)
{
	FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);

	sm_P(&(fs_struct[p_fs->drv].v_sem));

	FAT_release_all(sb);
	buf_release_all(sb);

	sm_V(&(fs_struct[p_fs->drv].v_sem));

	return 0;
}
示例#12
0
INT32 FsSyncVol(struct super_block *sb, INT32 do_sync)
{
	INT32 err;
	FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);

	sm_P(&(fs_struct[p_fs->drv].v_sem));

	err = ffsSyncVol(sb, do_sync);

	sm_V(&(fs_struct[p_fs->drv].v_sem));

	return(err);
}
示例#13
0
INT32 FsReadStat(struct inode *inode, DIR_ENTRY_T *info)
{
	INT32 err;
	struct super_block *sb = inode->i_sb;
	FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);

	sm_P(&(fs_struct[p_fs->drv].v_sem));

	err = ffsGetStat(inode, info);

	sm_V(&(fs_struct[p_fs->drv].v_sem));

	return(err);
}
示例#14
0
INT32 FsSetAttr(struct inode *inode, UINT32 attr)
{
	INT32 err;
	struct super_block *sb = inode->i_sb;
	FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);

	sm_P(&(fs_struct[p_fs->drv].v_sem));

	err = ffsSetAttr(inode, attr);

	sm_V(&(fs_struct[p_fs->drv].v_sem));

	return(err);
}
示例#15
0
/* FsSyncVol : synchronize a file system volume */
int FsSyncVol(struct super_block *sb, int do_sync)
{
	int err;
	FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);

	/* acquire the lock for file system critical section */
	sm_P(&p_fs->v_sem);

	err = ffsSyncVol(sb, do_sync);

	/* release the lock for file system critical section */
	sm_V(&p_fs->v_sem);

	return err;
} /* end of FsSyncVol */
示例#16
0
INT32 FsGetVolInfo(struct super_block *sb, VOL_INFO_T *info)
{
	INT32 err;
	FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);

	if (info == NULL) return(FFS_ERROR);

	sm_P(&(fs_struct[p_fs->drv].v_sem));

	err = ffsGetVolInfo(sb, info);

	sm_V(&(fs_struct[p_fs->drv].v_sem));

	return(err);
}
INT32 bdev_open(struct super_block *sb)
{
BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info);

if (p_bd->opened) return(FFS_SUCCESS);

p_bd->sector_size = bdev_logical_block_size(sb->s_bdev);
p_bd->sector_size_bits = my_log2(p_bd->sector_size);
p_bd->sector_size_mask = p_bd->sector_size - 1;
p_bd->num_sectors = i_size_read(sb->s_bdev->bd_inode) >> p_bd->sector_size_bits;

p_bd->opened = TRUE;

return(FFS_SUCCESS);
}
示例#18
0
/* FsReleaseCache: Release FAT & buf cache */
INT32 FsReleaseCache(struct super_block *sb)
{
	FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);

	/* acquire the lock for file system critical section */
	sm_P(&(fs_struct[p_fs->drv].v_sem));

	FAT_release_all(sb);
	buf_release_all(sb);

	/* release the lock for file system critical section */
	sm_V(&(fs_struct[p_fs->drv].v_sem));

	return 0;
} /* FsReleaseCache */
示例#19
0
/* FsSyncVol : synchronize a file system volume */
INT32 FsSyncVol(struct super_block *sb, INT32 do_sync)
{
	INT32 err;
	FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);

	/* acquire the lock for file system critical section */
	sm_P(&(fs_struct[p_fs->drv].v_sem));

	err = ffsSyncVol(sb, do_sync);

	/* release the lock for file system critical section */
	sm_V(&(fs_struct[p_fs->drv].v_sem));

	return(err);
} /* end of FsSyncVol */
示例#20
0
/* FsSetAttr : set the attribute of a given file */
int FsSetAttr(struct inode *inode, u32 attr)
{
	int err;
	struct super_block *sb = inode->i_sb;
	FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);

	/* acquire the lock for file system critical section */
	sm_P(&p_fs->v_sem);

	err = ffsSetAttr(inode, attr);

	/* release the lock for file system critical section */
	sm_V(&p_fs->v_sem);

	return err;
} /* end of FsSetAttr */
示例#21
0
INT32 FsMoveFile(struct inode *old_parent_inode, FILE_ID_T *fid, struct inode *new_parent_inode, struct dentry *new_dentry)
{
	INT32 err;
	struct super_block *sb = old_parent_inode->i_sb;
	FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);

	if (fid == NULL) return(FFS_INVALIDFID);

	sm_P(&(fs_struct[p_fs->drv].v_sem));

	err = ffsMoveFile(old_parent_inode, fid, new_parent_inode, new_dentry);

	sm_V(&(fs_struct[p_fs->drv].v_sem));

	return(err);
}
示例#22
0
INT32 FsMapCluster(struct inode *inode, INT32 clu_offset, UINT32 *clu)
{
	INT32 err;
	struct super_block *sb = inode->i_sb;
	FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);

	if (clu == NULL) return(FFS_ERROR);

	sm_P(&(fs_struct[p_fs->drv].v_sem));

	err = ffsMapCluster(inode, clu_offset, clu);

	sm_V(&(fs_struct[p_fs->drv].v_sem));

	return(err);
}
示例#23
0
INT32 FsReadDir(struct inode *inode, DIR_ENTRY_T *dir_entry)
{
	INT32 err;
	struct super_block *sb = inode->i_sb;
	FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);

	if (dir_entry == NULL) return(FFS_ERROR);

	sm_P(&(fs_struct[p_fs->drv].v_sem));

	err = ffsReadDir(inode, dir_entry);

	sm_V(&(fs_struct[p_fs->drv].v_sem));

	return(err);
}
示例#24
0
INT32 FsRemoveEntry(struct inode *inode, FILE_ID_T *fid)
{
	INT32 err;
	struct super_block *sb = inode->i_sb;
	FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);

	if (fid == NULL) return(FFS_INVALIDFID);

	sm_P(&(fs_struct[p_fs->drv].v_sem));

	err = ffsRemoveEntry(inode, fid);

	sm_V(&(fs_struct[p_fs->drv].v_sem));

	return(err);
}
示例#25
0
/* FsReadStat : get the information of a given file */
INT32 FsReadStat(struct inode *inode, DIR_ENTRY_T *info)
{
	INT32 err;
	struct super_block *sb = inode->i_sb;
	FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);

	/* acquire the lock for file system critical section */
	sm_P(&(fs_struct[p_fs->drv].v_sem));

	err = ffsGetStat(inode, info);

	/* release the lock for file system critical section */
	sm_V(&(fs_struct[p_fs->drv].v_sem));

	return(err);
} /* end of FsReadStat */
示例#26
0
/* FsSetAttr : set the attribute of a given file */
INT32 FsSetAttr(struct inode *inode, UINT32 attr)
{
	INT32 err;
	struct super_block *sb = inode->i_sb;
	FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);

	/* acquire the lock for file system critical section */
	sm_P(&(fs_struct[p_fs->drv].v_sem));

	err = ffsSetAttr(inode, attr);

	/* release the lock for file system critical section */
	sm_V(&(fs_struct[p_fs->drv].v_sem));

	return(err);
} /* end of FsSetAttr */
示例#27
0
INT32 FsCreateDir(struct inode *inode, UINT8 *path, FILE_ID_T *fid)
{
	INT32 err;
	struct super_block *sb = inode->i_sb;
	FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);

	if ((fid == NULL) || (path == NULL) || (STRLEN(path) == 0))
		return(FFS_ERROR);

	sm_P(&(fs_struct[p_fs->drv].v_sem));

	err = ffsCreateDir(inode, path, fid);

	sm_V(&(fs_struct[p_fs->drv].v_sem));

	return(err);
}
示例#28
0
INT32 FsTruncateFile(struct inode *inode, UINT64 old_size, UINT64 new_size)
{
	INT32 err;
	struct super_block *sb = inode->i_sb;
	FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);

	sm_P(&(fs_struct[p_fs->drv].v_sem));

	PRINTK("FsTruncateFile entered (inode %p size %llu)\n", inode, new_size);

	err = ffsTruncateFile(inode, old_size, new_size);

	PRINTK("FsTruncateFile exitted (%d)\n", err);

	sm_V(&(fs_struct[p_fs->drv].v_sem));

	return(err);
}
示例#29
0
INT32 FsWriteStat(struct inode *inode, DIR_ENTRY_T *info)
{
	INT32 err;
	struct super_block *sb = inode->i_sb;
	FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);

	sm_P(&(fs_struct[p_fs->drv].v_sem));

	PRINTK("FsWriteStat entered (inode %p info %p\n", inode, info);

	err = ffsSetStat(inode, info);

	sm_V(&(fs_struct[p_fs->drv].v_sem));

	PRINTK("FsWriteStat exited (%d)\n", err);

	return(err);
}
示例#30
0
/* FsGetVolInfo : get the information of a file system volume */
INT32 FsGetVolInfo(struct super_block *sb, VOL_INFO_T *info)
{
	INT32 err;
	FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);

	/* check the validity of pointer parameters */
	if (info == NULL) return(FFS_ERROR);

	/* acquire the lock for file system critical section */
	sm_P(&(fs_struct[p_fs->drv].v_sem));

	err = ffsGetVolInfo(sb, info);

	/* release the lock for file system critical section */
	sm_V(&(fs_struct[p_fs->drv].v_sem));

	return(err);
} /* end of FsGetVolInfo */