X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Ffat%2Fmisc.c;h=ffe2cd9d38d6db01ee1d76a3fb15960c11fb8184;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=85a85ec5a8ce0f6d32d3ad9c5aa3400a5fb9ca0f;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/fs/fat/misc.c b/fs/fat/misc.c index 85a85ec5a..ffe2cd9d3 100644 --- a/fs/fat/misc.c +++ b/fs/fat/misc.c @@ -6,6 +6,7 @@ * and date_dos2unix for date==0 by Igor Zhbanov(bsg@uniyar.ac.ru) */ +#include #include #include #include @@ -14,26 +15,22 @@ * fat_fs_panic reports a severe file system problem and sets the file system * read-only. The file system can be made writable again by remounting it. */ - -static char panic_msg[512]; - void fat_fs_panic(struct super_block *s, const char *fmt, ...) { - int not_ro; va_list args; - va_start (args, fmt); - vsnprintf (panic_msg, sizeof(panic_msg), fmt, args); - va_end (args); + printk(KERN_ERR "FAT: Filesystem panic (dev %s)\n", s->s_id); - not_ro = !(s->s_flags & MS_RDONLY); - if (not_ro) - s->s_flags |= MS_RDONLY; + printk(KERN_ERR " "); + va_start(args, fmt); + vprintk(fmt, args); + va_end(args); + printk("\n"); - printk(KERN_ERR "FAT: Filesystem panic (dev %s)\n" - " %s\n", s->s_id, panic_msg); - if (not_ro) + if (!(s->s_flags & MS_RDONLY)) { + s->s_flags |= MS_RDONLY; printk(KERN_ERR " File system has been set read-only\n"); + } } void lock_fat(struct super_block *sb) @@ -69,7 +66,8 @@ void fat_clusters_flush(struct super_block *sb) printk(KERN_ERR "FAT: Did not find valid FSINFO signature.\n" " Found signature1 0x%08x signature2 0x%08x" " (sector = %lu)\n", - CF_LE_L(fsinfo->signature1), CF_LE_L(fsinfo->signature2), + le32_to_cpu(fsinfo->signature1), + le32_to_cpu(fsinfo->signature2), sbi->fsinfo_sector); } else { if (sbi->free_clusters != -1) @@ -88,10 +86,11 @@ void fat_clusters_flush(struct super_block *sb) int fat_add_cluster(struct inode *inode) { struct super_block *sb = inode->i_sb; + struct msdos_sb_info *sbi = MSDOS_SB(sb); int ret, count, limit, new_dclus, new_fclus, last; - int cluster_bits = MSDOS_SB(sb)->cluster_bits; - - /* + int cluster_bits = sbi->cluster_bits; + + /* * We must locate the last cluster of the file to add this new * one (new_dclus) to the end of the link list (the FAT). * @@ -111,18 +110,18 @@ int fat_add_cluster(struct inode *inode) /* find free FAT entry */ lock_fat(sb); - - if (MSDOS_SB(sb)->free_clusters == 0) { + + if (sbi->free_clusters == 0) { unlock_fat(sb); return -ENOSPC; } - limit = MSDOS_SB(sb)->clusters + 2; - new_dclus = MSDOS_SB(sb)->prev_free + 1; - for (count = 0; count < MSDOS_SB(sb)->clusters; count++, new_dclus++) { + limit = sbi->max_cluster; + new_dclus = sbi->prev_free + 1; + for (count = FAT_START_ENT; count < limit; count++, new_dclus++) { new_dclus = new_dclus % limit; - if (new_dclus < 2) - new_dclus = 2; + if (new_dclus < FAT_START_ENT) + new_dclus = FAT_START_ENT; ret = fat_access(sb, new_dclus, -1); if (ret < 0) { @@ -131,8 +130,8 @@ int fat_add_cluster(struct inode *inode) } else if (ret == FAT_ENT_FREE) break; } - if (count >= MSDOS_SB(sb)->clusters) { - MSDOS_SB(sb)->free_clusters = 0; + if (count >= limit) { + sbi->free_clusters = 0; unlock_fat(sb); return -ENOSPC; } @@ -143,11 +142,11 @@ int fat_add_cluster(struct inode *inode) return ret; } - MSDOS_SB(sb)->prev_free = new_dclus; - if (MSDOS_SB(sb)->free_clusters != -1) - MSDOS_SB(sb)->free_clusters--; + sbi->prev_free = new_dclus; + if (sbi->free_clusters != -1) + sbi->free_clusters--; fat_clusters_flush(sb); - + unlock_fat(sb); /* add new one to the last of the cluster chain */ @@ -155,7 +154,7 @@ int fat_add_cluster(struct inode *inode) ret = fat_access(sb, last, new_dclus); if (ret < 0) return ret; - fat_cache_add(inode, new_fclus, new_dclus); +// fat_cache_add(inode, new_fclus, new_dclus); } else { MSDOS_I(inode)->i_start = new_dclus; MSDOS_I(inode)->i_logstart = new_dclus; @@ -166,70 +165,28 @@ int fat_add_cluster(struct inode *inode) new_fclus, inode->i_blocks >> (cluster_bits - 9)); fat_cache_inval_inode(inode); } - inode->i_blocks += MSDOS_SB(sb)->cluster_size >> 9; + inode->i_blocks += sbi->cluster_size >> 9; return new_dclus; } -struct buffer_head *fat_extend_dir(struct inode *inode) -{ - struct super_block *sb = inode->i_sb; - struct buffer_head *bh, *res = NULL; - int nr, sec_per_clus = MSDOS_SB(sb)->sec_per_clus; - sector_t sector, last_sector; - - if (MSDOS_SB(sb)->fat_bits != 32) { - if (inode->i_ino == MSDOS_ROOT_INO) - return ERR_PTR(-ENOSPC); - } - - nr = fat_add_cluster(inode); - if (nr < 0) - return ERR_PTR(nr); - - sector = ((sector_t)nr - 2) * sec_per_clus + MSDOS_SB(sb)->data_start; - last_sector = sector + sec_per_clus; - for ( ; sector < last_sector; sector++) { - if ((bh = sb_getblk(sb, sector))) { - memset(bh->b_data, 0, sb->s_blocksize); - set_buffer_uptodate(bh); - mark_buffer_dirty(bh); - if (!res) - res = bh; - else - brelse(bh); - } - } - if (res == NULL) - res = ERR_PTR(-EIO); - if (inode->i_size & (sb->s_blocksize - 1)) { - fat_fs_panic(sb, "Odd directory size"); - inode->i_size = (inode->i_size + sb->s_blocksize) - & ~((loff_t)sb->s_blocksize - 1); - } - inode->i_size += MSDOS_SB(sb)->cluster_size; - MSDOS_I(inode)->mmu_private += MSDOS_SB(sb)->cluster_size; - - return res; -} - -/* Linear day numbers of the respective 1sts in non-leap years. */ - -static int day_n[] = { 0,31,59,90,120,151,181,212,243,273,304,334,0,0,0,0 }; - /* JanFebMarApr May Jun Jul Aug Sep Oct Nov Dec */ - - extern struct timezone sys_tz; +/* Linear day numbers of the respective 1sts in non-leap years. */ +static int day_n[] = { + /* Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec */ + 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, 0 +}; /* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */ - -int date_dos2unix(unsigned short time,unsigned short date) +int date_dos2unix(unsigned short time, unsigned short date) { - int month,year,secs; + int month, year, secs; - /* first subtract and mask after that... Otherwise, if - date == 0, bad things happen */ + /* + * first subtract and mask after that... Otherwise, if + * date == 0, bad things happen + */ month = ((date >> 5) - 1) & 15; year = date >> 9; secs = (time & 31)*2+60*((time >> 5) & 63)+(time >> 11)*3600+86400* @@ -240,12 +197,10 @@ int date_dos2unix(unsigned short time,unsigned short date) return secs; } - /* Convert linear UNIX date to a MS-DOS time/date pair. */ - -void fat_date_unix2dos(int unix_date,__le16 *time, __le16 *date) +void fat_date_unix2dos(int unix_date, __le16 *time, __le16 *date) { - int day,year,nl_day,month; + int day, year, nl_day, month; unix_date -= sys_tz.tz_minuteswest*60; @@ -257,20 +212,23 @@ void fat_date_unix2dos(int unix_date,__le16 *time, __le16 *date) (((unix_date/3600) % 24) << 11)); day = unix_date/86400-3652; year = day/365; - if ((year+3)/4+365*year > day) year--; + if ((year+3)/4+365*year > day) + year--; day -= (year+3)/4+365*year; if (day == 59 && !(year & 3)) { nl_day = day; month = 2; - } - else { + } else { nl_day = (year & 3) || day <= 59 ? day : day-1; - for (month = 0; month < 12; month++) - if (day_n[month] > nl_day) break; + for (month = 0; month < 12; month++) { + if (day_n[month] > nl_day) + break; + } } *date = cpu_to_le16(nl_day-day_n[month-1]+1+(month << 5)+(year << 9)); } +EXPORT_SYMBOL(fat_date_unix2dos); /* Returns the inode number of the directory entry at offset pos. If bh is non-NULL, it is brelse'd before. Pos is incremented. The buffer header is @@ -280,10 +238,10 @@ void fat_date_unix2dos(int unix_date,__le16 *time, __le16 *date) AV. want the next entry (took one explicit de=NULL in vfat/namei.c). AV. It's done in fat_get_entry() (inlined), here the slow case lives. AV. Additionally, when we return -1 (i.e. reached the end of directory) - AV. we make bh NULL. + AV. we make bh NULL. */ -int fat__get_entry(struct inode *dir, loff_t *pos,struct buffer_head **bh, +int fat__get_entry(struct inode *dir, loff_t *pos, struct buffer_head **bh, struct msdos_dir_entry **de, loff_t *i_pos) { struct super_block *sb = dir->i_sb; @@ -319,3 +277,5 @@ next: return 0; } + +EXPORT_SYMBOL(fat__get_entry);