summaryrefslogtreecommitdiffstats
path: root/fs/bfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/bfs/inode.c')
-rw-r--r--fs/bfs/inode.c126
1 files changed, 42 insertions, 84 deletions
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c
index 8f3d9fd8960..883e77acd5a 100644
--- a/fs/bfs/inode.c
+++ b/fs/bfs/inode.c
@@ -12,9 +12,9 @@
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/fs.h>
-#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
#include <linux/vfs.h>
+#include <linux/writeback.h>
#include <asm/uaccess.h>
#include "bfs.h"
@@ -30,7 +30,6 @@ MODULE_LICENSE("GPL");
#define dprintf(x...)
#endif
-static void bfs_write_super(struct super_block *s);
void dump_imap(const char *prefix, struct super_block *s);
struct inode *bfs_iget(struct super_block *sb, unsigned long ino)
@@ -98,35 +97,40 @@ error:
return ERR_PTR(-EIO);
}
-static int bfs_write_inode(struct inode *inode, int wait)
+static struct bfs_inode *find_inode(struct super_block *sb, u16 ino, struct buffer_head **p)
+{
+ if ((ino < BFS_ROOT_INO) || (ino > BFS_SB(sb)->si_lasti)) {
+ printf("Bad inode number %s:%08x\n", sb->s_id, ino);
+ return ERR_PTR(-EIO);
+ }
+
+ ino -= BFS_ROOT_INO;
+
+ *p = sb_bread(sb, 1 + ino / BFS_INODES_PER_BLOCK);
+ if (!*p) {
+ printf("Unable to read inode %s:%08x\n", sb->s_id, ino);
+ return ERR_PTR(-EIO);
+ }
+
+ return (struct bfs_inode *)(*p)->b_data + ino % BFS_INODES_PER_BLOCK;
+}
+
+static int bfs_write_inode(struct inode *inode, struct writeback_control *wbc)
{
struct bfs_sb_info *info = BFS_SB(inode->i_sb);
unsigned int ino = (u16)inode->i_ino;
unsigned long i_sblock;
struct bfs_inode *di;
struct buffer_head *bh;
- int block, off;
int err = 0;
dprintf("ino=%08x\n", ino);
- if ((ino < BFS_ROOT_INO) || (ino > BFS_SB(inode->i_sb)->si_lasti)) {
- printf("Bad inode number %s:%08x\n", inode->i_sb->s_id, ino);
- return -EIO;
- }
+ di = find_inode(inode->i_sb, ino, &bh);
+ if (IS_ERR(di))
+ return PTR_ERR(di);
mutex_lock(&info->bfs_lock);
- block = (ino - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1;
- bh = sb_bread(inode->i_sb, block);
- if (!bh) {
- printf("Unable to read inode %s:%08x\n",
- inode->i_sb->s_id, ino);
- mutex_unlock(&info->bfs_lock);
- return -EIO;
- }
-
- off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK;
- di = (struct bfs_inode *)bh->b_data + off;
if (ino == BFS_ROOT_INO)
di->i_vtype = cpu_to_le32(BFS_VDIR);
@@ -147,7 +151,7 @@ static int bfs_write_inode(struct inode *inode, int wait)
di->i_eoffset = cpu_to_le32(i_sblock * BFS_BSIZE + inode->i_size - 1);
mark_buffer_dirty(bh);
- if (wait) {
+ if (wbc->sync_mode == WB_SYNC_ALL) {
sync_dirty_buffer(bh);
if (buffer_req(bh) && !buffer_uptodate(bh))
err = -EIO;
@@ -157,12 +161,11 @@ static int bfs_write_inode(struct inode *inode, int wait)
return err;
}
-static void bfs_delete_inode(struct inode *inode)
+static void bfs_evict_inode(struct inode *inode)
{
unsigned long ino = inode->i_ino;
struct bfs_inode *di;
struct buffer_head *bh;
- int block, off;
struct super_block *s = inode->i_sb;
struct bfs_sb_info *info = BFS_SB(s);
struct bfs_inode_info *bi = BFS_I(inode);
@@ -170,28 +173,19 @@ static void bfs_delete_inode(struct inode *inode)
dprintf("ino=%08lx\n", ino);
truncate_inode_pages(&inode->i_data, 0);
+ invalidate_inode_buffers(inode);
+ end_writeback(inode);
- if ((ino < BFS_ROOT_INO) || (ino > info->si_lasti)) {
- printf("invalid ino=%08lx\n", ino);
+ if (inode->i_nlink)
return;
- }
-
- inode->i_size = 0;
- inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
- mutex_lock(&info->bfs_lock);
- mark_inode_dirty(inode);
- block = (ino - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1;
- bh = sb_bread(s, block);
- if (!bh) {
- printf("Unable to read inode %s:%08lx\n",
- inode->i_sb->s_id, ino);
- mutex_unlock(&info->bfs_lock);
+ di = find_inode(s, inode->i_ino, &bh);
+ if (IS_ERR(di))
return;
- }
- off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK;
- di = (struct bfs_inode *)bh->b_data + off;
- memset((void *)di, 0, sizeof(struct bfs_inode));
+
+ mutex_lock(&info->bfs_lock);
+ /* clear on-disk inode */
+ memset(di, 0, sizeof(struct bfs_inode));
mark_buffer_dirty(bh);
brelse(bh);
@@ -208,32 +202,9 @@ static void bfs_delete_inode(struct inode *inode)
* "last block of the last file" even if there is no
* real file there, saves us 1 gap.
*/
- if (info->si_lf_eblk == bi->i_eblock) {
+ if (info->si_lf_eblk == bi->i_eblock)
info->si_lf_eblk = bi->i_sblock - 1;
- mark_buffer_dirty(info->si_sbh);
- }
- mutex_unlock(&info->bfs_lock);
- clear_inode(inode);
-}
-
-static int bfs_sync_fs(struct super_block *sb, int wait)
-{
- struct bfs_sb_info *info = BFS_SB(sb);
-
- mutex_lock(&info->bfs_lock);
- mark_buffer_dirty(info->si_sbh);
- sb->s_dirt = 0;
mutex_unlock(&info->bfs_lock);
-
- return 0;
-}
-
-static void bfs_write_super(struct super_block *sb)
-{
- if (!(sb->s_flags & MS_RDONLY))
- bfs_sync_fs(sb, 1);
- else
- sb->s_dirt = 0;
}
static void bfs_put_super(struct super_block *s)
@@ -243,18 +214,10 @@ static void bfs_put_super(struct super_block *s)
if (!info)
return;
- lock_kernel();
-
- if (s->s_dirt)
- bfs_write_super(s);
-
- brelse(info->si_sbh);
mutex_destroy(&info->bfs_lock);
kfree(info->si_imap);
kfree(info);
s->s_fs_info = NULL;
-
- unlock_kernel();
}
static int bfs_statfs(struct dentry *dentry, struct kstatfs *buf)
@@ -318,10 +281,8 @@ static const struct super_operations bfs_sops = {
.alloc_inode = bfs_alloc_inode,
.destroy_inode = bfs_destroy_inode,
.write_inode = bfs_write_inode,
- .delete_inode = bfs_delete_inode,
+ .evict_inode = bfs_evict_inode,
.put_super = bfs_put_super,
- .write_super = bfs_write_super,
- .sync_fs = bfs_sync_fs,
.statfs = bfs_statfs,
};
@@ -348,7 +309,7 @@ void dump_imap(const char *prefix, struct super_block *s)
static int bfs_fill_super(struct super_block *s, void *data, int silent)
{
- struct buffer_head *bh;
+ struct buffer_head *bh, *sbh;
struct bfs_super_block *bfs_sb;
struct inode *inode;
unsigned i, imap_len;
@@ -364,10 +325,10 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
sb_set_blocksize(s, BFS_BSIZE);
- info->si_sbh = sb_bread(s, 0);
- if (!info->si_sbh)
+ sbh = sb_bread(s, 0);
+ if (!sbh)
goto out;
- bfs_sb = (struct bfs_super_block *)info->si_sbh->b_data;
+ bfs_sb = (struct bfs_super_block *)sbh->b_data;
if (le32_to_cpu(bfs_sb->s_magic) != BFS_MAGIC) {
if (!silent)
printf("No BFS filesystem on %s (magic=%08x)\n",
@@ -471,10 +432,7 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
info->si_lf_eblk = eblock;
}
brelse(bh);
- if (!(s->s_flags & MS_RDONLY)) {
- mark_buffer_dirty(info->si_sbh);
- s->s_dirt = 1;
- }
+ brelse(sbh);
dump_imap("read_super", s);
return 0;
@@ -484,7 +442,7 @@ out3:
out2:
kfree(info->si_imap);
out1:
- brelse(info->si_sbh);
+ brelse(sbh);
out:
mutex_destroy(&info->bfs_lock);
kfree(info);