Commit c544f64e authored by Dave Jones's avatar Dave Jones Committed by Linus Torvalds

[PATCH] Seperates bfs_sb_info from struct super_block.

Originally from Brian Gerst

(Includes the bfs fix sent prior to this one to this -- disregard
 earlier bfs related email)
parent 6bef9146
#define su_lasti u.bfs_sb.si_lasti
#define su_blocks u.bfs_sb.si_blocks
#define su_freeb u.bfs_sb.si_freeb
#define su_freei u.bfs_sb.si_freei
#define su_lf_ioff u.bfs_sb.si_lf_ioff
#define su_lf_sblk u.bfs_sb.si_lf_sblk
#define su_lf_eblk u.bfs_sb.si_lf_eblk
#define su_imap u.bfs_sb.si_imap
#define su_sbh u.bfs_sb.si_sbh
#define su_bfs_sb u.bfs_sb.si_bfs_sb
#define printf(format, args...) \ #define printf(format, args...) \
printk(KERN_ERR "BFS-fs: %s(): " format, __FUNCTION__, ## args) printk(KERN_ERR "BFS-fs: %s(): " format, __FUNCTION__, ## args)
...@@ -78,20 +78,21 @@ static int bfs_create(struct inode * dir, struct dentry * dentry, int mode) ...@@ -78,20 +78,21 @@ static int bfs_create(struct inode * dir, struct dentry * dentry, int mode)
int err; int err;
struct inode * inode; struct inode * inode;
struct super_block * s = dir->i_sb; struct super_block * s = dir->i_sb;
struct bfs_sb_info * info = BFS_SB(s);
unsigned long ino; unsigned long ino;
inode = new_inode(s); inode = new_inode(s);
if (!inode) if (!inode)
return -ENOSPC; return -ENOSPC;
lock_kernel(); lock_kernel();
ino = find_first_zero_bit(s->su_imap, s->su_lasti); ino = find_first_zero_bit(info->si_imap, info->si_lasti);
if (ino > s->su_lasti) { if (ino > info->si_lasti) {
unlock_kernel(); unlock_kernel();
iput(inode); iput(inode);
return -ENOSPC; return -ENOSPC;
} }
set_bit(ino, s->su_imap); set_bit(ino, info->si_imap);
s->su_freei--; info->si_freei--;
inode->i_uid = current->fsuid; inode->i_uid = current->fsuid;
inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid; inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
...@@ -318,11 +319,9 @@ static struct buffer_head * bfs_find_entry(struct inode * dir, ...@@ -318,11 +319,9 @@ static struct buffer_head * bfs_find_entry(struct inode * dir,
{ {
unsigned long block, offset; unsigned long block, offset;
struct buffer_head * bh; struct buffer_head * bh;
struct bfs_sb_info * info;
struct bfs_dirent * de; struct bfs_dirent * de;
*res_dir = NULL; *res_dir = NULL;
info = &dir->i_sb->u.bfs_sb;
if (namelen > BFS_NAMELEN) if (namelen > BFS_NAMELEN)
return NULL; return NULL;
bh = NULL; bh = NULL;
......
...@@ -60,10 +60,11 @@ static int bfs_get_block(struct inode * inode, sector_t block, ...@@ -60,10 +60,11 @@ static int bfs_get_block(struct inode * inode, sector_t block,
long phys; long phys;
int err; int err;
struct super_block *sb = inode->i_sb; struct super_block *sb = inode->i_sb;
struct bfs_sb_info *info = BFS_SB(sb);
struct bfs_inode_info *bi = BFS_I(inode); struct bfs_inode_info *bi = BFS_I(inode);
struct buffer_head *sbh = sb->su_sbh; struct buffer_head *sbh = info->si_sbh;
if (block < 0 || block > sb->su_blocks) if (block < 0 || block > info->si_blocks)
return -EIO; return -EIO;
phys = bi->i_sblock + block; phys = bi->i_sblock + block;
...@@ -89,12 +90,12 @@ static int bfs_get_block(struct inode * inode, sector_t block, ...@@ -89,12 +90,12 @@ static int bfs_get_block(struct inode * inode, sector_t block,
/* if the last data block for this file is the last allocated block, we can /* if the last data block for this file is the last allocated block, we can
extend the file trivially, without moving it anywhere */ extend the file trivially, without moving it anywhere */
if (bi->i_eblock == sb->su_lf_eblk) { if (bi->i_eblock == info->si_lf_eblk) {
dprintf("c=%d, b=%08lx, phys=%08lx (simple extension)\n", dprintf("c=%d, b=%08lx, phys=%08lx (simple extension)\n",
create, block, phys); create, block, phys);
map_bh(bh_result, sb, phys); map_bh(bh_result, sb, phys);
sb->su_freeb -= phys - bi->i_eblock; info->si_freeb -= phys - bi->i_eblock;
sb->su_lf_eblk = bi->i_eblock = phys; info->si_lf_eblk = bi->i_eblock = phys;
mark_inode_dirty(inode); mark_inode_dirty(inode);
mark_buffer_dirty(sbh); mark_buffer_dirty(sbh);
err = 0; err = 0;
...@@ -102,7 +103,7 @@ static int bfs_get_block(struct inode * inode, sector_t block, ...@@ -102,7 +103,7 @@ static int bfs_get_block(struct inode * inode, sector_t block,
} }
/* Ok, we have to move this entire file to the next free block */ /* Ok, we have to move this entire file to the next free block */
phys = sb->su_lf_eblk + 1; phys = info->si_lf_eblk + 1;
if (bi->i_sblock) { /* if data starts on block 0 then there is no data */ if (bi->i_sblock) { /* if data starts on block 0 then there is no data */
err = bfs_move_blocks(inode->i_sb, bi->i_sblock, err = bfs_move_blocks(inode->i_sb, bi->i_sblock,
bi->i_eblock, phys); bi->i_eblock, phys);
...@@ -116,11 +117,11 @@ static int bfs_get_block(struct inode * inode, sector_t block, ...@@ -116,11 +117,11 @@ static int bfs_get_block(struct inode * inode, sector_t block,
dprintf("c=%d, b=%08lx, phys=%08lx (moved)\n", create, block, phys); dprintf("c=%d, b=%08lx, phys=%08lx (moved)\n", create, block, phys);
bi->i_sblock = phys; bi->i_sblock = phys;
phys += block; phys += block;
sb->su_lf_eblk = bi->i_eblock = phys; info->si_lf_eblk = bi->i_eblock = phys;
/* this assumes nothing can write the inode back while we are here /* this assumes nothing can write the inode back while we are here
* and thus update inode->i_blocks! (XXX)*/ * and thus update inode->i_blocks! (XXX)*/
sb->su_freeb -= bi->i_eblock - bi->i_sblock + 1 - inode->i_blocks; info->si_freeb -= bi->i_eblock - bi->i_sblock + 1 - inode->i_blocks;
mark_inode_dirty(inode); mark_inode_dirty(inode);
mark_buffer_dirty(sbh); mark_buffer_dirty(sbh);
map_bh(bh_result, sb, phys); map_bh(bh_result, sb, phys);
......
...@@ -39,7 +39,7 @@ static void bfs_read_inode(struct inode * inode) ...@@ -39,7 +39,7 @@ static void bfs_read_inode(struct inode * inode)
struct buffer_head * bh; struct buffer_head * bh;
int block, off; int block, off;
if (ino < BFS_ROOT_INO || ino > inode->i_sb->su_lasti) { if (ino < BFS_ROOT_INO || ino > BFS_SB(inode->i_sb)->si_lasti) {
printf("Bad inode number %s:%08lx\n", inode->i_sb->s_id, ino); printf("Bad inode number %s:%08lx\n", inode->i_sb->s_id, ino);
make_bad_inode(inode); make_bad_inode(inode);
return; return;
...@@ -91,7 +91,7 @@ static void bfs_write_inode(struct inode * inode, int unused) ...@@ -91,7 +91,7 @@ static void bfs_write_inode(struct inode * inode, int unused)
struct buffer_head * bh; struct buffer_head * bh;
int block, off; int block, off;
if (ino < BFS_ROOT_INO || ino > inode->i_sb->su_lasti) { if (ino < BFS_ROOT_INO || ino > BFS_SB(inode->i_sb)->si_lasti) {
printf("Bad inode number %s:%08lx\n", inode->i_sb->s_id, ino); printf("Bad inode number %s:%08lx\n", inode->i_sb->s_id, ino);
return; return;
} }
...@@ -137,10 +137,11 @@ static void bfs_delete_inode(struct inode * inode) ...@@ -137,10 +137,11 @@ static void bfs_delete_inode(struct inode * inode)
struct buffer_head * bh; struct buffer_head * bh;
int block, off; int block, off;
struct super_block * s = inode->i_sb; struct super_block * s = inode->i_sb;
struct bfs_sb_info * info = BFS_SB(s);
dprintf("ino=%08lx\n", inode->i_ino); dprintf("ino=%08lx\n", inode->i_ino);
if (inode->i_ino < BFS_ROOT_INO || inode->i_ino > inode->i_sb->su_lasti) { if (inode->i_ino < BFS_ROOT_INO || inode->i_ino > info->si_lasti) {
printf("invalid ino=%08lx\n", inode->i_ino); printf("invalid ino=%08lx\n", inode->i_ino);
return; return;
} }
...@@ -159,9 +160,9 @@ static void bfs_delete_inode(struct inode * inode) ...@@ -159,9 +160,9 @@ static void bfs_delete_inode(struct inode * inode)
off = (ino - BFS_ROOT_INO)%BFS_INODES_PER_BLOCK; off = (ino - BFS_ROOT_INO)%BFS_INODES_PER_BLOCK;
di = (struct bfs_inode *)bh->b_data + off; di = (struct bfs_inode *)bh->b_data + off;
if (di->i_ino) { if (di->i_ino) {
s->su_freeb += BFS_FILEBLOCKS(di); info->si_freeb += BFS_FILEBLOCKS(di);
s->su_freei++; info->si_freei++;
clear_bit(di->i_ino, s->su_imap); clear_bit(di->i_ino, info->si_imap);
dump_imap("delete_inode", s); dump_imap("delete_inode", s);
} }
di->i_ino = 0; di->i_ino = 0;
...@@ -172,9 +173,9 @@ static void bfs_delete_inode(struct inode * inode) ...@@ -172,9 +173,9 @@ static void bfs_delete_inode(struct inode * inode)
/* if this was the last file, make the previous /* if this was the last file, make the previous
block "last files last block" even if there is no real file there, block "last files last block" even if there is no real file there,
saves us 1 gap */ saves us 1 gap */
if (s->su_lf_eblk == BFS_I(inode)->i_eblock) { if (info->si_lf_eblk == BFS_I(inode)->i_eblock) {
s->su_lf_eblk = BFS_I(inode)->i_sblock - 1; info->si_lf_eblk = BFS_I(inode)->i_sblock - 1;
mark_buffer_dirty(s->su_sbh); mark_buffer_dirty(info->si_sbh);
} }
unlock_kernel(); unlock_kernel();
clear_inode(inode); clear_inode(inode);
...@@ -182,18 +183,22 @@ static void bfs_delete_inode(struct inode * inode) ...@@ -182,18 +183,22 @@ static void bfs_delete_inode(struct inode * inode)
static void bfs_put_super(struct super_block *s) static void bfs_put_super(struct super_block *s)
{ {
brelse(s->su_sbh); struct bfs_sb_info *info = BFS_SB(s);
kfree(s->su_imap); brelse(info->si_sbh);
kfree(info->si_imap);
kfree(info);
s->u.generic_sbp = NULL;
} }
static int bfs_statfs(struct super_block *s, struct statfs *buf) static int bfs_statfs(struct super_block *s, struct statfs *buf)
{ {
struct bfs_sb_info *info = BFS_SB(s);
buf->f_type = BFS_MAGIC; buf->f_type = BFS_MAGIC;
buf->f_bsize = s->s_blocksize; buf->f_bsize = s->s_blocksize;
buf->f_blocks = s->su_blocks; buf->f_blocks = info->si_blocks;
buf->f_bfree = buf->f_bavail = s->su_freeb; buf->f_bfree = buf->f_bavail = info->si_freeb;
buf->f_files = s->su_lasti + 1 - BFS_ROOT_INO; buf->f_files = info->si_lasti + 1 - BFS_ROOT_INO;
buf->f_ffree = s->su_freei; buf->f_ffree = info->si_freei;
buf->f_fsid.val[0] = kdev_t_to_nr(s->s_dev); buf->f_fsid.val[0] = kdev_t_to_nr(s->s_dev);
buf->f_namelen = BFS_NAMELEN; buf->f_namelen = BFS_NAMELEN;
return 0; return 0;
...@@ -202,7 +207,7 @@ static int bfs_statfs(struct super_block *s, struct statfs *buf) ...@@ -202,7 +207,7 @@ static int bfs_statfs(struct super_block *s, struct statfs *buf)
static void bfs_write_super(struct super_block *s) static void bfs_write_super(struct super_block *s)
{ {
if (!(s->s_flags & MS_RDONLY)) if (!(s->s_flags & MS_RDONLY))
mark_buffer_dirty(s->su_sbh); mark_buffer_dirty(BFS_SB(s)->si_sbh);
s->s_dirt = 0; s->s_dirt = 0;
} }
...@@ -267,14 +272,14 @@ void dump_imap(const char *prefix, struct super_block * s) ...@@ -267,14 +272,14 @@ void dump_imap(const char *prefix, struct super_block * s)
if (!tmpbuf) if (!tmpbuf)
return; return;
for (i=s->su_lasti; i>=0; i--) { for (i=BFS_SB(s)->si_lasti; i>=0; i--) {
if (i>PAGE_SIZE-100) break; if (i>PAGE_SIZE-100) break;
if (test_bit(i, s->su_imap)) if (test_bit(i, BFS_SB(s)->si_imap))
strcat(tmpbuf, "1"); strcat(tmpbuf, "1");
else else
strcat(tmpbuf, "0"); strcat(tmpbuf, "0");
} }
printk(KERN_ERR "BFS-fs: %s: lasti=%08lx <%s>\n", prefix, s->su_lasti, tmpbuf); printk(KERN_ERR "BFS-fs: %s: lasti=%08lx <%s>\n", prefix, BFS_SB(s)->si_lasti, tmpbuf);
free_page((unsigned long)tmpbuf); free_page((unsigned long)tmpbuf);
#endif #endif
} }
...@@ -285,6 +290,13 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent) ...@@ -285,6 +290,13 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
struct bfs_super_block * bfs_sb; struct bfs_super_block * bfs_sb;
struct inode * inode; struct inode * inode;
int i, imap_len; int i, imap_len;
struct bfs_sb_info * info;
info = kmalloc(sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
s->u.generic_sbp = info;
memset(info, 0, sizeof(*info));
sb_set_blocksize(s, BFS_BSIZE); sb_set_blocksize(s, BFS_BSIZE);
...@@ -302,49 +314,49 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent) ...@@ -302,49 +314,49 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
printf("%s is unclean, continuing\n", s->s_id); printf("%s is unclean, continuing\n", s->s_id);
s->s_magic = BFS_MAGIC; s->s_magic = BFS_MAGIC;
s->su_bfs_sb = bfs_sb; info->si_bfs_sb = bfs_sb;
s->su_sbh = bh; info->si_sbh = bh;
s->su_lasti = (bfs_sb->s_start - BFS_BSIZE)/sizeof(struct bfs_inode) info->si_lasti = (bfs_sb->s_start - BFS_BSIZE)/sizeof(struct bfs_inode)
+ BFS_ROOT_INO - 1; + BFS_ROOT_INO - 1;
imap_len = s->su_lasti/8 + 1; imap_len = info->si_lasti/8 + 1;
s->su_imap = kmalloc(imap_len, GFP_KERNEL); info->si_imap = kmalloc(imap_len, GFP_KERNEL);
if (!s->su_imap) if (!info->si_imap)
goto out; goto out;
memset(s->su_imap, 0, imap_len); memset(info->si_imap, 0, imap_len);
for (i=0; i<BFS_ROOT_INO; i++) for (i=0; i<BFS_ROOT_INO; i++)
set_bit(i, s->su_imap); set_bit(i, info->si_imap);
s->s_op = &bfs_sops; s->s_op = &bfs_sops;
inode = iget(s, BFS_ROOT_INO); inode = iget(s, BFS_ROOT_INO);
if (!inode) { if (!inode) {
kfree(s->su_imap); kfree(info->si_imap);
goto out; goto out;
} }
s->s_root = d_alloc_root(inode); s->s_root = d_alloc_root(inode);
if (!s->s_root) { if (!s->s_root) {
iput(inode); iput(inode);
kfree(s->su_imap); kfree(info->si_imap);
goto out; goto out;
} }
s->su_blocks = (bfs_sb->s_end + 1)>>BFS_BSIZE_BITS; /* for statfs(2) */ info->si_blocks = (bfs_sb->s_end + 1)>>BFS_BSIZE_BITS; /* for statfs(2) */
s->su_freeb = (bfs_sb->s_end + 1 - bfs_sb->s_start)>>BFS_BSIZE_BITS; info->si_freeb = (bfs_sb->s_end + 1 - bfs_sb->s_start)>>BFS_BSIZE_BITS;
s->su_freei = 0; info->si_freei = 0;
s->su_lf_eblk = 0; info->si_lf_eblk = 0;
s->su_lf_sblk = 0; info->si_lf_sblk = 0;
s->su_lf_ioff = 0; info->si_lf_ioff = 0;
for (i=BFS_ROOT_INO; i<=s->su_lasti; i++) { for (i=BFS_ROOT_INO; i<=info->si_lasti; i++) {
inode = iget(s,i); inode = iget(s,i);
if (BFS_I(inode)->i_dsk_ino == 0) if (BFS_I(inode)->i_dsk_ino == 0)
s->su_freei++; info->si_freei++;
else { else {
set_bit(i, s->su_imap); set_bit(i, info->si_imap);
s->su_freeb -= inode->i_blocks; info->si_freeb -= inode->i_blocks;
if (BFS_I(inode)->i_eblock > s->su_lf_eblk) { if (BFS_I(inode)->i_eblock > info->si_lf_eblk) {
s->su_lf_eblk = BFS_I(inode)->i_eblock; info->si_lf_eblk = BFS_I(inode)->i_eblock;
s->su_lf_sblk = BFS_I(inode)->i_sblock; info->si_lf_sblk = BFS_I(inode)->i_sblock;
s->su_lf_ioff = BFS_INO2OFF(i); info->si_lf_ioff = BFS_INO2OFF(i);
} }
} }
iput(inode); iput(inode);
...@@ -358,6 +370,8 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent) ...@@ -358,6 +370,8 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
out: out:
brelse(bh); brelse(bh);
kfree(info);
s->u.generic_sbp = NULL;
return -EINVAL; return -EINVAL;
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#define _LINUX_BFS_FS_H #define _LINUX_BFS_FS_H
#include <linux/bfs_fs_i.h> #include <linux/bfs_fs_i.h>
#include <linux/bfs_fs_sb.h>
#define BFS_BSIZE_BITS 9 #define BFS_BSIZE_BITS 9
#define BFS_BSIZE (1<<BFS_BSIZE_BITS) #define BFS_BSIZE (1<<BFS_BSIZE_BITS)
...@@ -89,6 +90,11 @@ extern struct address_space_operations bfs_aops; ...@@ -89,6 +90,11 @@ extern struct address_space_operations bfs_aops;
extern struct inode_operations bfs_dir_inops; extern struct inode_operations bfs_dir_inops;
extern struct file_operations bfs_dir_operations; extern struct file_operations bfs_dir_operations;
static inline struct bfs_sb_info *BFS_SB(struct super_block *sb)
{
return sb->u.generic_sbp;
}
static inline struct bfs_inode_info *BFS_I(struct inode *inode) static inline struct bfs_inode_info *BFS_I(struct inode *inode)
{ {
return list_entry(inode, struct bfs_inode_info, vfs_inode); return list_entry(inode, struct bfs_inode_info, vfs_inode);
......
...@@ -684,7 +684,6 @@ struct quota_mount_options ...@@ -684,7 +684,6 @@ struct quota_mount_options
#include <linux/ufs_fs_sb.h> #include <linux/ufs_fs_sb.h>
#include <linux/romfs_fs_sb.h> #include <linux/romfs_fs_sb.h>
#include <linux/adfs_fs_sb.h> #include <linux/adfs_fs_sb.h>
#include <linux/bfs_fs_sb.h>
extern struct list_head super_blocks; extern struct list_head super_blocks;
extern spinlock_t sb_lock; extern spinlock_t sb_lock;
...@@ -728,7 +727,6 @@ struct super_block { ...@@ -728,7 +727,6 @@ struct super_block {
struct ufs_sb_info ufs_sb; struct ufs_sb_info ufs_sb;
struct romfs_sb_info romfs_sb; struct romfs_sb_info romfs_sb;
struct adfs_sb_info adfs_sb; struct adfs_sb_info adfs_sb;
struct bfs_sb_info bfs_sb;
void *generic_sbp; void *generic_sbp;
} u; } u;
/* /*
......
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