diff options
Diffstat (limited to 'fs/bfs')
| -rw-r--r-- | fs/bfs/bfs.h | 1 | ||||
| -rw-r--r-- | fs/bfs/dir.c | 15 | ||||
| -rw-r--r-- | fs/bfs/inode.c | 43 |
3 files changed, 42 insertions, 17 deletions
diff --git a/fs/bfs/bfs.h b/fs/bfs/bfs.h index 606f9378b2f0..b08afe733e63 100644 --- a/fs/bfs/bfs.h +++ b/fs/bfs/bfs.h @@ -35,6 +35,7 @@ struct bfs_inode_info { unsigned long i_dsk_ino; /* inode number from the disk, can be 0 */ unsigned long i_sblock; unsigned long i_eblock; + struct mapping_metadata_bhs i_metadata_bhs; struct inode vfs_inode; }; diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c index c375e22c4c0c..91a4871fa051 100644 --- a/fs/bfs/dir.c +++ b/fs/bfs/dir.c @@ -35,7 +35,7 @@ static int bfs_readdir(struct file *f, struct dir_context *ctx) int block; if (ctx->pos & (BFS_DIRENT_SIZE - 1)) { - printf("Bad f_pos=%08lx for %s:%08lx\n", + printf("Bad f_pos=%08lx for %s:%08llx\n", (unsigned long)ctx->pos, dir->i_sb->s_id, dir->i_ino); return -EINVAL; @@ -71,12 +71,12 @@ static int bfs_readdir(struct file *f, struct dir_context *ctx) const struct file_operations bfs_dir_operations = { .read = generic_read_dir, .iterate_shared = bfs_readdir, - .fsync = generic_file_fsync, + .fsync = simple_fsync, .llseek = generic_file_llseek, }; static int bfs_create(struct mnt_idmap *idmap, struct inode *dir, - struct dentry *dentry, umode_t mode, bool excl) + struct dentry *dentry, umode_t mode) { int err; struct inode *inode; @@ -180,13 +180,13 @@ static int bfs_unlink(struct inode *dir, struct dentry *dentry) goto out_brelse; if (!inode->i_nlink) { - printf("unlinking non-existent file %s:%lu (nlink=%d)\n", + printf("unlinking non-existent file %s:%llu (nlink=%d)\n", inode->i_sb->s_id, inode->i_ino, inode->i_nlink); set_nlink(inode, 1); } de->ino = 0; - mark_buffer_dirty_inode(bh, dir); + mmb_mark_buffer_dirty(bh, &BFS_I(dir)->i_metadata_bhs); inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir)); mark_inode_dirty(dir); inode_set_ctime_to_ts(inode, inode_get_ctime(dir)); @@ -246,7 +246,7 @@ static int bfs_rename(struct mnt_idmap *idmap, struct inode *old_dir, inode_set_ctime_current(new_inode); inode_dec_link_count(new_inode); } - mark_buffer_dirty_inode(old_bh, old_dir); + mmb_mark_buffer_dirty(old_bh, &BFS_I(old_dir)->i_metadata_bhs); error = 0; end_rename: @@ -296,7 +296,8 @@ static int bfs_add_entry(struct inode *dir, const struct qstr *child, int ino) for (i = 0; i < BFS_NAMELEN; i++) de->name[i] = (i < namelen) ? name[i] : 0; - mark_buffer_dirty_inode(bh, dir); + mmb_mark_buffer_dirty(bh, + &BFS_I(dir)->i_metadata_bhs); brelse(bh); return 0; } diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index 9da02f5cb6cd..06e3a848b4ef 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c @@ -136,7 +136,6 @@ static int bfs_write_inode(struct inode *inode, struct writeback_control *wbc) unsigned long i_sblock; struct bfs_inode *di; struct buffer_head *bh; - int err = 0; dprintf("ino=%08x\n", ino); @@ -165,13 +164,31 @@ static int bfs_write_inode(struct inode *inode, struct writeback_control *wbc) di->i_eoffset = cpu_to_le32(i_sblock * BFS_BSIZE + inode->i_size - 1); mark_buffer_dirty(bh); - if (wbc->sync_mode == WB_SYNC_ALL) { - sync_dirty_buffer(bh); - if (buffer_req(bh) && !buffer_uptodate(bh)) - err = -EIO; - } brelse(bh); mutex_unlock(&info->bfs_lock); + set_inode_metadata_writeback(inode); + return 0; +} + +static int bfs_sync_inode_metadata(struct inode *inode, + struct writeback_control *wbc) +{ + int err = 0; + struct bfs_inode *di; + struct buffer_head *bh; + + di = find_inode(inode->i_sb, (u16)inode->i_ino, &bh); + if (IS_ERR(di)) + return PTR_ERR(di); + + sync_dirty_buffer(bh); + if (buffer_write_io_error(bh)) { + err = -EIO; + goto out; + } + err = mmb_sync(&BFS_I(inode)->i_metadata_bhs); +out: + brelse(bh); return err; } @@ -187,7 +204,9 @@ static void bfs_evict_inode(struct inode *inode) dprintf("ino=%08lx\n", ino); truncate_inode_pages_final(&inode->i_data); - invalidate_inode_buffers(inode); + if (inode->i_nlink) + mmb_sync(&BFS_I(inode)->i_metadata_bhs); + mmb_invalidate(&BFS_I(inode)->i_metadata_bhs); clear_inode(inode); if (inode->i_nlink) @@ -257,6 +276,8 @@ static struct inode *bfs_alloc_inode(struct super_block *sb) bi = alloc_inode_sb(sb, bfs_inode_cachep, GFP_KERNEL); if (!bi) return NULL; + mmb_init(&bi->i_metadata_bhs, &bi->vfs_inode.i_data); + return &bi->vfs_inode; } @@ -298,6 +319,7 @@ static const struct super_operations bfs_sops = { .alloc_inode = bfs_alloc_inode, .free_inode = bfs_free_inode, .write_inode = bfs_write_inode, + .sync_inode_metadata = bfs_sync_inode_metadata, .evict_inode = bfs_evict_inode, .put_super = bfs_put_super, .statfs = bfs_statfs, @@ -307,7 +329,7 @@ void bfs_dump_imap(const char *prefix, struct super_block *s) { #ifdef DEBUG int i; - char *tmpbuf = (char *)get_zeroed_page(GFP_KERNEL); + char *tmpbuf = kzalloc(PAGE_SIZE, GFP_KERNEL); if (!tmpbuf) return; @@ -319,7 +341,7 @@ void bfs_dump_imap(const char *prefix, struct super_block *s) strcat(tmpbuf, "0"); } printf("%s: lasti=%08lx <%s>\n", prefix, BFS_SB(s)->si_lasti, tmpbuf); - free_page((unsigned long)tmpbuf); + kfree(tmpbuf); #endif } @@ -342,7 +364,8 @@ static int bfs_fill_super(struct super_block *s, struct fs_context *fc) s->s_time_min = 0; s->s_time_max = U32_MAX; - sb_set_blocksize(s, BFS_BSIZE); + if (!sb_set_blocksize(s, BFS_BSIZE)) + goto out; sbh = sb_bread(s, 0); if (!sbh) |
