Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 359284
b: refs/heads/master
c: b88a105
h: refs/heads/master
v: v3
  • Loading branch information
Oleksij Rempel authored and Linus Torvalds committed Feb 28, 2013
1 parent 4f5ddfa commit 96d54d0
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6b46419b0462ae565880f02e9cd0baf9b25ea71f
refs/heads/master: b88a105802e9aeb6e234e8106659f5d1271081bb
2 changes: 2 additions & 0 deletions trunk/fs/fat/fat.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ struct msdos_sb_info {

spinlock_t dir_hash_lock;
struct hlist_head dir_hashtable[FAT_HASH_SIZE];

unsigned int dirty; /* fs state before mount */
};

#define FAT_CACHE_VALID 0 /* special case for valid cache */
Expand Down
66 changes: 66 additions & 0 deletions trunk/fs/fat/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -488,10 +488,59 @@ static void fat_evict_inode(struct inode *inode)
fat_detach(inode);
}

static void fat_set_state(struct super_block *sb,
unsigned int set, unsigned int force)
{
struct buffer_head *bh;
struct fat_boot_sector *b;
struct msdos_sb_info *sbi = sb->s_fs_info;

/* do not change any thing if mounted read only */
if ((sb->s_flags & MS_RDONLY) && !force)
return;

/* do not change state if fs was dirty */
if (sbi->dirty) {
/* warn only on set (mount). */
if (set)
fat_msg(sb, KERN_WARNING, "Volume was not properly "
"unmounted. Some data may be corrupt. "
"Please run fsck.");
return;
}

bh = sb_bread(sb, 0);
if (bh == NULL) {
fat_msg(sb, KERN_ERR, "unable to read boot sector "
"to mark fs as dirty");
return;
}

b = (struct fat_boot_sector *) bh->b_data;

if (sbi->fat_bits == 32) {
if (set)
b->fat32.state |= FAT_STATE_DIRTY;
else
b->fat32.state &= ~FAT_STATE_DIRTY;
} else /* fat 16 and 12 */ {
if (set)
b->fat16.state |= FAT_STATE_DIRTY;
else
b->fat16.state &= ~FAT_STATE_DIRTY;
}

mark_buffer_dirty(bh);
sync_dirty_buffer(bh);
brelse(bh);
}

static void fat_put_super(struct super_block *sb)
{
struct msdos_sb_info *sbi = MSDOS_SB(sb);

fat_set_state(sb, 0, 0);

iput(sbi->fsinfo_inode);
iput(sbi->fat_inode);

Expand Down Expand Up @@ -566,8 +615,18 @@ static void __exit fat_destroy_inodecache(void)

static int fat_remount(struct super_block *sb, int *flags, char *data)
{
int new_rdonly;
struct msdos_sb_info *sbi = MSDOS_SB(sb);
*flags |= MS_NODIRATIME | (sbi->options.isvfat ? 0 : MS_NOATIME);

/* make sure we update state on remount. */
new_rdonly = *flags & MS_RDONLY;
if (new_rdonly != (sb->s_flags & MS_RDONLY)) {
if (new_rdonly)
fat_set_state(sb, 0, 0);
else
fat_set_state(sb, 1, 1);
}
return 0;
}

Expand Down Expand Up @@ -1362,6 +1421,12 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
if (sbi->fat_bits != 32)
sbi->fat_bits = (total_clusters > MAX_FAT12) ? 16 : 12;

/* some OSes set FAT_STATE_DIRTY and clean it on unmount. */
if (sbi->fat_bits == 32)
sbi->dirty = b->fat32.state & FAT_STATE_DIRTY;
else /* fat 16 or 12 */
sbi->dirty = b->fat16.state & FAT_STATE_DIRTY;

/* check that FAT table does not overflow */
fat_clusters = sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits;
total_clusters = min(total_clusters, fat_clusters - FAT_START_ENT);
Expand Down Expand Up @@ -1456,6 +1521,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
"the device does not support discard");
}

fat_set_state(sb, 1, 0);
return 0;

out_invalid:
Expand Down
2 changes: 2 additions & 0 deletions trunk/include/uapi/linux/msdos_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@
#define IS_FSINFO(x) (le32_to_cpu((x)->signature1) == FAT_FSINFO_SIG1 \
&& le32_to_cpu((x)->signature2) == FAT_FSINFO_SIG2)

#define FAT_STATE_DIRTY 0x01

struct __fat_dirent {
long d_ino;
__kernel_off_t d_off;
Expand Down

0 comments on commit 96d54d0

Please sign in to comment.