[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Problem mounting usb stick with FAT{16,32} formated on Windows machine



|| On Sun, 12 Dec 2004 14:40:08 -0200
|| Otavio Salvador <otavio@debian.org> wrote: 

os> Maybe can be one problem on fat support but I'm not sure. Anyone have
os> some idea where this problem is and how fix it?

I did a look on fedora 2.6.9 kernel source and it apply a patch on fat
fs module. I'm including this part here to someone check if it can be
related.

--- a/fs/fat/cache.c	2004-10-15 20:05:40 -07:00
+++ b/fs/fat/cache.c	2004-10-15 20:05:40 -07:00
@@ -45,13 +45,13 @@
 	}
 	if (sbi->fat_bits == 32) {
 		p_first = p_last = NULL; /* GCC needs that stuff */
-		next = CF_LE_L(((__u32 *) bh->b_data)[(first &
+		next = CF_LE_L(((__le32 *) bh->b_data)[(first &
 		    (sb->s_blocksize - 1)) >> 2]);
 		/* Fscking Microsoft marketing department. Their "32" is 28. */
 		next &= 0x0fffffff;
 	} else if (sbi->fat_bits == 16) {
 		p_first = p_last = NULL; /* GCC needs that stuff */
-		next = CF_LE_W(((__u16 *) bh->b_data)[(first &
+		next = CF_LE_W(((__le16 *) bh->b_data)[(first &
 		    (sb->s_blocksize - 1)) >> 1]);
 	} else {
 		p_first = &((__u8 *)bh->b_data)[first & (sb->s_blocksize - 1)];
@@ -63,10 +63,10 @@
 	}
 	if (new_value != -1) {
 		if (sbi->fat_bits == 32) {
-			((__u32 *)bh->b_data)[(first & (sb->s_blocksize - 1)) >> 2]
+			((__le32 *)bh->b_data)[(first & (sb->s_blocksize - 1)) >> 2]
 				= CT_LE_L(new_value);
 		} else if (sbi->fat_bits == 16) {
-			((__u16 *)bh->b_data)[(first & (sb->s_blocksize - 1)) >> 1]
+			((__le16 *)bh->b_data)[(first & (sb->s_blocksize - 1)) >> 1]
 				= CT_LE_W(new_value);
 		} else {
 			if (nr & 1) {
@@ -146,7 +146,8 @@
 	sbi->cache = sbi->cache_array;
 }
 
-void fat_cache_lookup(struct inode *inode, int cluster, int *f_clu, int *d_clu)
+static void
+fat_cache_lookup(struct inode *inode, int cluster, int *f_clu, int *d_clu)
 {
 	struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
 	struct fat_cache *walk;
--- a/fs/fat/dir.c	2004-10-15 20:04:40 -07:00
+++ b/fs/fat/dir.c	2004-10-15 20:04:40 -07:00
@@ -93,14 +93,6 @@
 }
 #endif
 
-static inline unsigned char
-fat_tolower(struct nls_table *t, unsigned char c)
-{
-	unsigned char nc = t->charset2lower[c];
-
-	return nc ? nc : c;
-}
-
 static inline int
 fat_short2uni(struct nls_table *t, unsigned char *c, int clen, wchar_t *uni)
 {
@@ -140,17 +132,6 @@
 	return charlen;
 }
 
-static int
-fat_strnicmp(struct nls_table *t, const unsigned char *s1,
-					const unsigned char *s2, int len)
-{
-	while(len--)
-		if (fat_tolower(t, *s1++) != fat_tolower(t, *s2++))
-			return 1;
-
-	return 0;
-}
-
 static inline int
 fat_shortname2uni(struct nls_table *nls, unsigned char *buf, int buf_size,
 		  wchar_t *uni_buf, unsigned short opt, int lower)
@@ -311,7 +292,7 @@
 			:uni16_to_x8(bufname, bufuname, uni_xlate, nls_io);
 		if (xlate_len == name_len)
 			if ((!anycase && !memcmp(name, bufname, xlate_len)) ||
-			    (anycase && !fat_strnicmp(nls_io, name, bufname,
+			    (anycase && !nls_strnicmp(nls_io, name, bufname,
 								xlate_len)))
 				goto Found;
 
@@ -322,7 +303,7 @@
 			if (xlate_len != name_len)
 				continue;
 			if ((!anycase && !memcmp(name, bufname, xlate_len)) ||
-			    (anycase && !fat_strnicmp(nls_io, name, bufname,
+			    (anycase && !nls_strnicmp(nls_io, name, bufname,
 								xlate_len)))
 				goto Found;
 		}
@@ -733,7 +714,7 @@
 {
 	struct buffer_head *bh;
 	struct msdos_dir_entry *de;
-	__u16 date, time;
+	__le16 date, time;
 
 	bh = fat_extend_dir(dir);
 	if (IS_ERR(bh))
@@ -745,12 +726,12 @@
 	memcpy(de[0].name,MSDOS_DOT,MSDOS_NAME);
 	memcpy(de[1].name,MSDOS_DOTDOT,MSDOS_NAME);
 	de[0].attr = de[1].attr = ATTR_DIR;
-	de[0].time = de[1].time = CT_LE_W(time);
-	de[0].date = de[1].date = CT_LE_W(date);
+	de[0].time = de[1].time = time;
+	de[0].date = de[1].date = date;
 	if (is_vfat) {	/* extra timestamps */
-		de[0].ctime = de[1].ctime = CT_LE_W(time);
+		de[0].ctime = de[1].ctime = time;
 		de[0].adate = de[0].cdate =
-			de[1].adate = de[1].cdate = CT_LE_W(date);
+			de[1].adate = de[1].cdate = date;
 	}
 	de[0].start = CT_LE_W(MSDOS_I(dir)->i_logstart);
 	de[0].starthi = CT_LE_W(MSDOS_I(dir)->i_logstart>>16);
--- a/fs/fat/file.c	2004-10-15 20:04:58 -07:00
+++ b/fs/fat/file.c	2004-10-15 20:04:58 -07:00
@@ -90,12 +90,6 @@
 	const unsigned int cluster_size = sbi->cluster_size;
 	int nr_clusters;
 
-	/* Why no return value?  Surely the disk could fail... */
-	if (IS_RDONLY (inode))
-		return /* -EPERM */;
-	if (IS_IMMUTABLE(inode))
-		return /* -EPERM */;
-
 	/* 
 	 * This protects against truncating a file bigger than it was then
 	 * trying to write into the hole.
--- a/fs/fat/inode.c	2004-10-15 20:05:15 -07:00
+++ b/fs/fat/inode.c	2004-10-15 20:05:15 -07:00
@@ -59,7 +59,7 @@
 #define FAT_HASH_SIZE	(1UL << FAT_HASH_BITS)
 #define FAT_HASH_MASK	(FAT_HASH_SIZE-1)
 static struct list_head fat_inode_hashtable[FAT_HASH_SIZE];
-spinlock_t fat_inode_lock = SPIN_LOCK_UNLOCKED;
+static spinlock_t fat_inode_lock = SPIN_LOCK_UNLOCKED;
 
 void fat_hash_init(void)
 {
@@ -579,12 +579,11 @@
  * of i_logstart is used to store the directory entry offset.
  */
 
-struct dentry *fat_decode_fh(struct super_block *sb, __u32 *fh,
-			     int len, int fhtype, 
-			     int (*acceptable)(void *context, struct dentry *de),
-			     void *context)
+static struct dentry *
+fat_decode_fh(struct super_block *sb, __u32 *fh, int len, int fhtype, 
+	      int (*acceptable)(void *context, struct dentry *de),
+	      void *context)
 {
-
 	if (fhtype != 3)
 		return ERR_PTR(-ESTALE);
 	if (len < 5)
@@ -593,7 +592,7 @@
 	return sb->s_export_op->find_exported_dentry(sb, fh, NULL, acceptable, context);
 }
 
-struct dentry *fat_get_dentry(struct super_block *sb, void *inump)
+static struct dentry *fat_get_dentry(struct super_block *sb, void *inump)
 {
 	struct inode *inode = NULL;
 	struct dentry *result;
@@ -653,7 +652,8 @@
 	return result;
 }
 
-int fat_encode_fh(struct dentry *de, __u32 *fh, int *lenp, int connectable)
+static int
+fat_encode_fh(struct dentry *de, __u32 *fh, int *lenp, int connectable)
 {
 	int len = *lenp;
 	struct inode *inode =  de->d_inode;
@@ -676,7 +676,7 @@
 	return 3;
 }
 
-struct dentry *fat_get_parent(struct dentry *child)
+static struct dentry *fat_get_parent(struct dentry *child)
 {
 	struct buffer_head *bh=NULL;
 	struct msdos_dir_entry *de = NULL;
@@ -744,7 +744,7 @@
 {
 	fat_inode_cachep = kmem_cache_create("fat_inode_cache",
 					     sizeof(struct msdos_inode_info),
-					     0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
+					     0, SLAB_RECLAIM_ACCOUNT,
 					     init_once, NULL);
 	if (fat_inode_cachep == NULL)
 		return -ENOMEM;
@@ -857,7 +857,7 @@
 		brelse(bh);
 		goto out_invalid;
 	}
-	logical_sector_size = CF_LE_W(get_unaligned((u16 *)&b->sector_size));
+	logical_sector_size = CF_LE_W(get_unaligned((__le16 *)&b->sector_size));
 	if (!logical_sector_size
 	    || (logical_sector_size & (logical_sector_size - 1))
 	    || (logical_sector_size < 512)
@@ -957,7 +957,7 @@
 	sbi->dir_per_block_bits = ffs(sbi->dir_per_block) - 1;
 
 	sbi->dir_start = sbi->fat_start + sbi->fats * sbi->fat_length;
-	sbi->dir_entries = CF_LE_W(get_unaligned((u16 *)&b->dir_entries));
+	sbi->dir_entries = CF_LE_W(get_unaligned((__le16 *)&b->dir_entries));
 	if (sbi->dir_entries & (sbi->dir_per_block - 1)) {
 		if (!silent)
 			printk(KERN_ERR "FAT: bogus directroy-entries per block"
@@ -969,7 +969,7 @@
 	rootdir_sectors = sbi->dir_entries
 		* sizeof(struct msdos_dir_entry) / sb->s_blocksize;
 	sbi->data_start = sbi->dir_start + rootdir_sectors;
-	total_sectors = CF_LE_W(get_unaligned((u16 *)&b->sectors));
+	total_sectors = CF_LE_W(get_unaligned((__le16 *)&b->sectors));
 	if (total_sectors == 0)
 		total_sectors = CF_LE_L(b->total_sect);
 
@@ -1227,7 +1227,7 @@
 	return 0;
 }
 
-void fat_write_inode(struct inode *inode, int wait)
+int fat_write_inode(struct inode *inode, int wait)
 {
 	struct super_block *sb = inode->i_sb;
 	struct buffer_head *bh;
@@ -1237,14 +1237,14 @@
 retry:
 	i_pos = MSDOS_I(inode)->i_pos;
 	if (inode->i_ino == MSDOS_ROOT_INO || !i_pos) {
-		return;
+		return 0;
 	}
 	lock_kernel();
 	if (!(bh = sb_bread(sb, i_pos >> MSDOS_SB(sb)->dir_per_block_bits))) {
 		printk(KERN_ERR "FAT: unable to read inode block "
 		       "for updating (i_pos %lld)\n", i_pos);
 		unlock_kernel();
-		return /* -EIO */;
+		return -EIO;
 	}
 	spin_lock(&fat_inode_lock);
 	if (i_pos != MSDOS_I(inode)->i_pos) {
@@ -1268,19 +1268,16 @@
 	    MSDOS_I(inode)->i_attrs;
 	raw_entry->start = CT_LE_W(MSDOS_I(inode)->i_logstart);
 	raw_entry->starthi = CT_LE_W(MSDOS_I(inode)->i_logstart >> 16);
-	fat_date_unix2dos(inode->i_mtime.tv_sec,&raw_entry->time,&raw_entry->date);
-	raw_entry->time = CT_LE_W(raw_entry->time);
-	raw_entry->date = CT_LE_W(raw_entry->date);
+	fat_date_unix2dos(inode->i_mtime.tv_sec, &raw_entry->time, &raw_entry->date);
 	if (MSDOS_SB(sb)->options.isvfat) {
 		fat_date_unix2dos(inode->i_ctime.tv_sec,&raw_entry->ctime,&raw_entry->cdate);
 		raw_entry->ctime_ms = MSDOS_I(inode)->i_ctime_ms; /* use i_ctime.tv_nsec? */
-		raw_entry->ctime = CT_LE_W(raw_entry->ctime);
-		raw_entry->cdate = CT_LE_W(raw_entry->cdate);
 	}
 	spin_unlock(&fat_inode_lock);
 	mark_buffer_dirty(bh);
 	brelse(bh);
 	unlock_kernel();
+	return 0;
 }
 
 
--- a/fs/fat/misc.c	2004-10-15 20:05:40 -07:00
+++ b/fs/fat/misc.c	2004-10-15 20:05:40 -07:00
@@ -73,9 +73,9 @@
 		       sbi->fsinfo_sector);
 	} else {
 		if (sbi->free_clusters != -1)
-			fsinfo->free_clusters = CF_LE_L(sbi->free_clusters);
+			fsinfo->free_clusters = cpu_to_le32(sbi->free_clusters);
 		if (sbi->prev_free != -1)
-			fsinfo->next_cluster = CF_LE_L(sbi->prev_free);
+			fsinfo->next_cluster = cpu_to_le32(sbi->prev_free);
 		mark_buffer_dirty(bh);
 	}
 	brelse(bh);
@@ -243,8 +243,7 @@
 
 /* Convert linear UNIX date to a MS-DOS time/date pair. */
 
-void fat_date_unix2dos(int unix_date,unsigned short *time,
-    unsigned short *date)
+void fat_date_unix2dos(int unix_date,__le16 *time, __le16 *date)
 {
 	int day,year,nl_day,month;
 
@@ -254,8 +253,8 @@
 	if (unix_date < 315532800)
 		unix_date = 315532800;
 
-	*time = (unix_date % 60)/2+(((unix_date/60) % 60) << 5)+
-	    (((unix_date/3600) % 24) << 11);
+	*time = cpu_to_le16((unix_date % 60)/2+(((unix_date/60) % 60) << 5)+
+	    (((unix_date/3600) % 24) << 11));
 	day = unix_date/86400-3652;
 	year = day/365;
 	if ((year+3)/4+365*year > day) year--;
@@ -269,7 +268,7 @@
 		for (month = 0; month < 12; month++)
 			if (day_n[month] > nl_day) break;
 	}
-	*date = nl_day-day_n[month-1]+1+(month << 5)+(year << 9);
+	*date = cpu_to_le16(nl_day-day_n[month-1]+1+(month << 5)+(year << 9));
 }
 
 
--- a/fs/vfat/namei.c	2004-10-15 20:05:18 -07:00
+++ b/fs/vfat/namei.c	2004-10-15 20:05:18 -07:00
@@ -73,33 +73,6 @@
 	return ret;
 }
 
-static inline unsigned char
-vfat_tolower(struct nls_table *t, unsigned char c)
-{
-	unsigned char nc = t->charset2lower[c];
-
-	return nc ? nc : c;
-}
-
-static inline unsigned char
-vfat_toupper(struct nls_table *t, unsigned char c)
-{
-	unsigned char nc = t->charset2upper[c];
-
-	return nc ? nc : c;
-}
-
-static inline int
-vfat_strnicmp(struct nls_table *t, const unsigned char *s1,
-					const unsigned char *s2, int len)
-{
-	while(len--)
-		if (vfat_tolower(t, *s1++) != vfat_tolower(t, *s2++))
-			return 1;
-
-	return 0;
-}
-
 /* returns the length of a struct qstr, ignoring trailing dots */
 static unsigned int vfat_striptail_len(struct qstr *qstr)
 {
@@ -142,7 +115,7 @@
 
 	hash = init_name_hash();
 	while (len--)
-		hash = partial_name_hash(vfat_tolower(t, *name++), hash);
+		hash = partial_name_hash(nls_tolower(t, *name++), hash);
 	qstr->hash = end_name_hash(hash);
 
 	return 0;
@@ -160,7 +133,7 @@
 	alen = vfat_striptail_len(a);
 	blen = vfat_striptail_len(b);
 	if (alen == blen) {
-		if (vfat_strnicmp(t, a->name, b->name, alen) == 0)
+		if (nls_strnicmp(t, a->name, b->name, alen) == 0)
 			return 0;
 	}
 	return 1;
@@ -341,7 +314,7 @@
 			info->upper = 0;
 		}
 
-		buf[0] = vfat_toupper(nls, buf[0]);
+		buf[0] = nls_toupper(nls, buf[0]);
 		if (isalpha(buf[0])) {
 			if (buf[0] == prev)
 				info->lower = 0;
@@ -704,7 +677,8 @@
 	de->attr = is_dir ? ATTR_DIR : ATTR_ARCH;
 	de->lcase = lcase;
 	de->adate = de->cdate = de->date = 0;
-	de->ctime_ms = de->ctime = de->time = 0;
+	de->ctime = de->time = 0;
+	de->ctime_ms = 0;
 	de->start = 0;
 	de->starthi = 0;
 	de->size = 0;
@@ -1073,8 +1047,8 @@
 
 	if (is_dir) {
 		int start = MSDOS_I(new_dir)->i_logstart;
-		dotdot_de->start = CT_LE_W(start);
-		dotdot_de->starthi = CT_LE_W(start>>16);
+		dotdot_de->start = cpu_to_le16(start);
+		dotdot_de->starthi = cpu_to_le16(start>>16);
 		mark_buffer_dirty(dotdot_bh);
 		old_dir->i_nlink--;
 		if (new_inode) {
-- 
        O T A V I O    S A L V A D O R
---------------------------------------------
 E-mail: otavio@debian.org      UIN: 5906116
 GNU/Linux User: 239058     GPG ID: 49A5F855
 Home Page: http://www.freedom.ind.br/otavio
---------------------------------------------
"Microsoft gives you Windows ... Linux gives
 you the whole house."

Attachment: pgp9DLl3OPRod.pgp
Description: PGP signature


Reply to: