Commit 8b6225bb authored by Hirofumi Ogawa's avatar Hirofumi Ogawa Committed by Linus Torvalds

[PATCH] let fat handle MS_SYNCHRONOUS flag

Adds MS_SYNCHRONOUS flag support.
Signed-off-by: default avatarColin Leroy <colin@colino.net>
Signed-off-by: default avatarOGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 5c13dd39
......@@ -269,8 +269,12 @@ static int __fat_access(struct super_block *sb, int nr, int new_value)
*p_last = (*p_last & 0xf0) | (new_value >> 8);
}
mark_buffer_dirty(bh2);
if (sb->s_flags & MS_SYNCHRONOUS)
sync_dirty_buffer(bh2);
}
mark_buffer_dirty(bh);
if (sb->s_flags & MS_SYNCHRONOUS)
sync_dirty_buffer(bh);
for (copy = 1; copy < sbi->fats; copy++) {
b = sbi->fat_start + (first >> sb->s_blocksize_bits)
+ sbi->fat_length * copy;
......@@ -283,10 +287,14 @@ static int __fat_access(struct super_block *sb, int nr, int new_value)
}
memcpy(c_bh2->b_data, bh2->b_data, sb->s_blocksize);
mark_buffer_dirty(c_bh2);
if (sb->s_flags & MS_SYNCHRONOUS)
sync_dirty_buffer(c_bh2);
brelse(c_bh2);
}
memcpy(c_bh->b_data, bh->b_data, sb->s_blocksize);
mark_buffer_dirty(c_bh);
if (sb->s_flags & MS_SYNCHRONOUS)
sync_dirty_buffer(c_bh);
brelse(c_bh);
}
}
......
......@@ -778,6 +778,8 @@ static struct buffer_head *fat_extend_dir(struct inode *inode)
memset(bh->b_data, 0, sb->s_blocksize);
set_buffer_uptodate(bh);
mark_buffer_dirty(bh);
if (sb->s_flags & MS_SYNCHRONOUS)
sync_dirty_buffer(bh);
if (!res)
res = bh;
else
......@@ -842,6 +844,7 @@ EXPORT_SYMBOL(fat_add_entries);
int fat_new_dir(struct inode *dir, struct inode *parent, int is_vfat)
{
struct super_block *sb = dir->i_sb;
struct buffer_head *bh;
struct msdos_dir_entry *de;
__le16 date, time;
......@@ -851,26 +854,31 @@ int fat_new_dir(struct inode *dir, struct inode *parent, int is_vfat)
return PTR_ERR(bh);
/* zeroed out, so... */
fat_date_unix2dos(dir->i_mtime.tv_sec,&time,&date);
de = (struct msdos_dir_entry*)&bh->b_data[0];
memcpy(de[0].name,MSDOS_DOT,MSDOS_NAME);
memcpy(de[1].name,MSDOS_DOTDOT,MSDOS_NAME);
fat_date_unix2dos(dir->i_mtime.tv_sec, &time, &date);
de = (struct msdos_dir_entry *)bh->b_data;
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 = time;
de[0].date = de[1].date = date;
if (is_vfat) { /* extra timestamps */
if (is_vfat) {
/* extra timestamps */
de[0].ctime = de[1].ctime = time;
de[0].adate = de[0].cdate =
de[1].adate = de[1].cdate = date;
de[0].adate = de[0].cdate = de[1].adate = de[1].cdate = date;
}
de[0].start = cpu_to_le16(MSDOS_I(dir)->i_logstart);
de[0].starthi = cpu_to_le16(MSDOS_I(dir)->i_logstart>>16);
de[0].starthi = cpu_to_le16(MSDOS_I(dir)->i_logstart >> 16);
de[1].start = cpu_to_le16(MSDOS_I(parent)->i_logstart);
de[1].starthi = cpu_to_le16(MSDOS_I(parent)->i_logstart>>16);
de[1].starthi = cpu_to_le16(MSDOS_I(parent)->i_logstart >> 16);
mark_buffer_dirty(bh);
if (sb->s_flags & MS_SYNCHRONOUS)
sync_dirty_buffer(bh);
brelse(bh);
dir->i_atime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
mark_inode_dirty(dir);
if (IS_SYNC(dir))
fat_sync_inode(dir);
return 0;
}
......
......@@ -23,6 +23,9 @@ static ssize_t fat_file_aio_write(struct kiocb *iocb, const char __user *buf,
inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
mark_inode_dirty(inode);
// check the locking rules
// if (IS_SYNC(inode))
// fat_sync_inode(inode);
}
return retval;
}
......@@ -288,6 +291,8 @@ void fat_truncate(struct inode *inode)
unlock_kernel();
inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
mark_inode_dirty(inode);
if (IS_SYNC(inode))
fat_sync_inode(inode);
}
struct inode_operations fat_file_inode_operations = {
......
......@@ -501,11 +501,21 @@ static int fat_write_inode(struct inode *inode, int wait)
}
spin_unlock(&sbi->inode_hash_lock);
mark_buffer_dirty(bh);
if (wait)
sync_dirty_buffer(bh);
brelse(bh);
unlock_kernel();
return 0;
}
int fat_sync_inode(struct inode *inode)
{
return fat_write_inode(inode, 1);
}
EXPORT_SYMBOL(fat_sync_inode);
static int fat_show_options(struct seq_file *m, struct vfsmount *mnt);
static struct super_operations fat_sops = {
.alloc_inode = fat_alloc_inode,
......
......@@ -75,6 +75,8 @@ void fat_clusters_flush(struct super_block *sb)
if (sbi->prev_free != -1)
fsinfo->next_cluster = cpu_to_le32(sbi->prev_free);
mark_buffer_dirty(bh);
if (sb->s_flags & MS_SYNCHRONOUS)
sync_dirty_buffer(bh);
}
brelse(bh);
}
......
......@@ -663,6 +663,7 @@ static int vfat_add_entry(struct inode *dir, struct qstr *qname,
int is_dir, struct vfat_slot_info *sinfo_out,
struct buffer_head **bh, struct msdos_dir_entry **de)
{
struct super_block *sb = dir->i_sb;
struct msdos_dir_slot *dir_slots;
loff_t offset;
int res, slots, slot;
......@@ -702,6 +703,8 @@ static int vfat_add_entry(struct inode *dir, struct qstr *qname,
}
memcpy(*de, dir_slots + slot, sizeof(struct msdos_dir_slot));
mark_buffer_dirty(*bh);
if (sb->s_flags & MS_SYNCHRONOUS)
sync_dirty_buffer(*bh);
}
res = 0;
......@@ -713,8 +716,9 @@ static int vfat_add_entry(struct inode *dir, struct qstr *qname,
dir->i_mtime.tv_nsec = 0;
(*de)->ctime = (*de)->time;
(*de)->adate = (*de)->cdate = (*de)->date;
mark_buffer_dirty(*bh);
if (sb->s_flags & MS_SYNCHRONOUS)
sync_dirty_buffer(*bh);
/* slots can't be less than 1 */
sinfo_out->long_slots = slots - 1;
......@@ -820,9 +824,12 @@ static int vfat_create(struct inode *dir, struct dentry *dentry, int mode,
if (!inode)
goto out;
res = 0;
inode->i_version++;
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
mark_inode_dirty(inode);
inode->i_version++;
if (IS_SYNC(inode))
fat_sync_inode(inode);
dir->i_version++;
dentry->d_time = dentry->d_parent->d_inode->i_version;
d_instantiate(dentry, inode);
......@@ -835,15 +842,20 @@ static void vfat_remove_entry(struct inode *dir, struct vfat_slot_info *sinfo,
struct buffer_head *bh,
struct msdos_dir_entry *de)
{
struct super_block *sb = dir->i_sb;
loff_t offset, i_pos;
int i;
/* remove the shortname */
dir->i_mtime = dir->i_atime = CURRENT_TIME_SEC;
dir->i_version++;
mark_inode_dirty(dir);
/* remove the shortname */
de->name[0] = DELETED_FLAG;
mark_buffer_dirty(bh);
if (sb->s_flags & MS_SYNCHRONOUS)
sync_dirty_buffer(bh);
/* remove the longname */
offset = sinfo->longname_offset;
de = NULL;
......@@ -853,6 +865,8 @@ static void vfat_remove_entry(struct inode *dir, struct vfat_slot_info *sinfo,
de->name[0] = DELETED_FLAG;
de->attr = ATTR_NONE;
mark_buffer_dirty(bh);
if (sb->s_flags & MS_SYNCHRONOUS)
sync_dirty_buffer(bh);
}
brelse(bh);
}
......@@ -879,7 +893,7 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry)
inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
fat_detach(inode);
mark_inode_dirty(inode);
/* releases bh */
/* releases bh and syncs it if necessary */
vfat_remove_entry(dir, &sinfo, bh, de);
dir->i_nlink--;
out:
......@@ -903,7 +917,7 @@ static int vfat_unlink(struct inode *dir, struct dentry *dentry)
inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
fat_detach(inode);
mark_inode_dirty(inode);
/* releases bh */
/* releases bh and syncs it if necessary */
vfat_remove_entry(dir, &sinfo, bh, de);
out:
unlock_kernel();
......@@ -949,7 +963,7 @@ static int vfat_mkdir(struct inode *dir, struct dentry *dentry, int mode)
inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
fat_detach(inode);
mark_inode_dirty(inode);
/* releases bh */
/* releases bh ands syncs if necessary */
vfat_remove_entry(dir, &sinfo, bh, de);
iput(inode);
dir->i_nlink--;
......@@ -1027,8 +1041,11 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
if (is_dir) {
int start = MSDOS_I(new_dir)->i_logstart;
dotdot_de->start = cpu_to_le16(start);
dotdot_de->starthi = cpu_to_le16(start>>16);
dotdot_de->starthi = cpu_to_le16(start >> 16);
mark_buffer_dirty(dotdot_bh);
if (new_dir->i_sb->s_flags & MS_SYNCHRONOUS)
sync_dirty_buffer(dotdot_bh);
old_dir->i_nlink--;
if (new_inode) {
new_inode->i_nlink--;
......
......@@ -349,6 +349,7 @@ extern void fat_detach(struct inode *inode);
extern struct inode *fat_iget(struct super_block *sb, loff_t i_pos);
extern struct inode *fat_build_inode(struct super_block *sb,
struct msdos_dir_entry *de, loff_t i_pos, int *res);
extern int fat_sync_inode(struct inode *inode);
int fat_fill_super(struct super_block *sb, void *data, int silent,
struct inode_operations *fs_dir_inode_ops, int isvfat);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment