Commit d8f94035 authored by Christoph Hellwig's avatar Christoph Hellwig

Access sysvfs superblock fields through SYSV_SB() abstraction.

parent 085c9a18
......@@ -31,7 +31,7 @@ static inline u32 *get_chunk(struct super_block *sb, struct buffer_head *bh)
{
char *bh_data = bh->b_data;
if (sb->sv_type == FSTYPE_SYSV4)
if (SYSV_SB(sb)->s_type == FSTYPE_SYSV4)
return (u32*)(bh_data+4);
else
return (u32*)(bh_data+2);
......@@ -41,28 +41,29 @@ static inline u32 *get_chunk(struct super_block *sb, struct buffer_head *bh)
void sysv_free_block(struct super_block * sb, u32 nr)
{
struct sysv_sb_info * sbi = SYSV_SB(sb);
struct buffer_head * bh;
u32 *blocks = sb->sv_bcache;
u32 *blocks = sbi->s_bcache;
unsigned count;
unsigned block = fs32_to_cpu(sb, nr);
unsigned block = fs32_to_cpu(sbi, nr);
/*
* This code does not work at all for AFS (it has a bitmap
* free list). As AFS is supposed to be read-only no one
* should call this for an AFS filesystem anyway...
*/
if (sb->sv_type == FSTYPE_AFS)
if (sbi->s_type == FSTYPE_AFS)
return;
if (block < sb->sv_firstdatazone || block >= sb->sv_nzones) {
if (block < sbi->s_firstdatazone || block >= sbi->s_nzones) {
printk("sysv_free_block: trying to free block not in datazone\n");
return;
}
lock_super(sb);
count = fs16_to_cpu(sb, *sb->sv_bcache_count);
count = fs16_to_cpu(sbi, *sbi->s_bcache_count);
if (count > sb->sv_flc_size) {
if (count > sbi->s_flc_size) {
printk("sysv_free_block: flc_count > flc_size\n");
unlock_super(sb);
return;
......@@ -71,8 +72,8 @@ void sysv_free_block(struct super_block * sb, u32 nr)
* into this block being freed, ditto if it's completely empty
* (applies only on Coherent).
*/
if (count == sb->sv_flc_size || count == 0) {
block += sb->sv_block_base;
if (count == sbi->s_flc_size || count == 0) {
block += sbi->s_block_base;
bh = sb_getblk(sb, block);
if (!bh) {
printk("sysv_free_block: getblk() failed\n");
......@@ -80,42 +81,43 @@ void sysv_free_block(struct super_block * sb, u32 nr)
return;
}
memset(bh->b_data, 0, sb->s_blocksize);
*(u16*)bh->b_data = cpu_to_fs16(sb, count);
*(u16*)bh->b_data = cpu_to_fs16(sbi, count);
memcpy(get_chunk(sb,bh), blocks, count * sizeof(sysv_zone_t));
mark_buffer_dirty(bh);
mark_buffer_uptodate(bh, 1);
brelse(bh);
count = 0;
}
sb->sv_bcache[count++] = nr;
sbi->s_bcache[count++] = nr;
*sb->sv_bcache_count = cpu_to_fs16(sb, count);
fs32_add(sb, sb->sv_free_blocks, 1);
*sbi->s_bcache_count = cpu_to_fs16(sbi, count);
fs32_add(sbi, sbi->s_free_blocks, 1);
dirty_sb(sb);
unlock_super(sb);
}
u32 sysv_new_block(struct super_block * sb)
{
struct sysv_sb_info *sbi = SYSV_SB(sb);
unsigned int block;
u32 nr;
struct buffer_head * bh;
unsigned count;
lock_super(sb);
count = fs16_to_cpu(sb, *sb->sv_bcache_count);
count = fs16_to_cpu(sbi, *sbi->s_bcache_count);
if (count == 0) /* Applies only to Coherent FS */
goto Enospc;
nr = sb->sv_bcache[--count];
nr = sbi->s_bcache[--count];
if (nr == 0) /* Applies only to Xenix FS, SystemV FS */
goto Enospc;
block = fs32_to_cpu(sb, nr);
block = fs32_to_cpu(sbi, nr);
*sb->sv_bcache_count = cpu_to_fs16(sb, count);
*sbi->s_bcache_count = cpu_to_fs16(sbi, count);
if (block < sb->sv_firstdatazone || block >= sb->sv_nzones) {
if (block < sbi->s_firstdatazone || block >= sbi->s_nzones) {
printk("sysv_new_block: new block %d is not in data zone\n",
block);
goto Enospc;
......@@ -124,26 +126,26 @@ u32 sysv_new_block(struct super_block * sb)
if (count == 0) { /* the last block continues the free list */
unsigned count;
block += sb->sv_block_base;
block += sbi->s_block_base;
if (!(bh = sb_bread(sb, block))) {
printk("sysv_new_block: cannot read free-list block\n");
/* retry this same block next time */
*sb->sv_bcache_count = cpu_to_fs16(sb, 1);
*sbi->s_bcache_count = cpu_to_fs16(sbi, 1);
goto Enospc;
}
count = fs16_to_cpu(sb, *(u16*)bh->b_data);
if (count > sb->sv_flc_size) {
count = fs16_to_cpu(sbi, *(u16*)bh->b_data);
if (count > sbi->s_flc_size) {
printk("sysv_new_block: free-list block with >flc_size entries\n");
brelse(bh);
goto Enospc;
}
*sb->sv_bcache_count = cpu_to_fs16(sb, count);
memcpy(sb->sv_bcache, get_chunk(sb, bh),
*sbi->s_bcache_count = cpu_to_fs16(sbi, count);
memcpy(sbi->s_bcache, get_chunk(sb, bh),
count * sizeof(sysv_zone_t));
brelse(bh);
}
/* Now the free list head in the superblock is valid again. */
fs32_add(sb, sb->sv_free_blocks, -1);
fs32_add(sbi, sbi->s_free_blocks, -1);
dirty_sb(sb);
unlock_super(sb);
return nr;
......@@ -155,6 +157,7 @@ u32 sysv_new_block(struct super_block * sb)
unsigned long sysv_count_free_blocks(struct super_block * sb)
{
struct sysv_sb_info * sbi = SYSV_SB(sb);
int sb_count;
int count;
struct buffer_head * bh = NULL;
......@@ -167,21 +170,21 @@ unsigned long sysv_count_free_blocks(struct super_block * sb)
* free list). As AFS is supposed to be read-only we just
* lie and say it has no free block at all.
*/
if (sb->sv_type == FSTYPE_AFS)
if (sbi->s_type == FSTYPE_AFS)
return 0;
lock_super(sb);
sb_count = fs32_to_cpu(sb, *sb->sv_free_blocks);
sb_count = fs32_to_cpu(sbi, *sbi->s_free_blocks);
if (0)
goto trust_sb;
/* this causes a lot of disk traffic ... */
count = 0;
n = fs16_to_cpu(sb, *sb->sv_bcache_count);
blocks = sb->sv_bcache;
n = fs16_to_cpu(sbi, *sbi->s_bcache_count);
blocks = sbi->s_bcache;
while (1) {
if (n > sb->sv_flc_size)
if (n > sbi->s_flc_size)
goto E2big;
block = 0;
while (n && (block = blocks[--n]) != 0)
......@@ -189,17 +192,17 @@ unsigned long sysv_count_free_blocks(struct super_block * sb)
if (block == 0)
break;
block = fs32_to_cpu(sb, block);
block = fs32_to_cpu(sbi, block);
if (bh)
brelse(bh);
if (block < sb->sv_firstdatazone || block >= sb->sv_nzones)
if (block < sbi->s_firstdatazone || block >= sbi->s_nzones)
goto Einval;
block += sb->sv_block_base;
block += sbi->s_block_base;
bh = sb_bread(sb, block);
if (!bh)
goto Eio;
n = fs16_to_cpu(sb, *(u16*)bh->b_data);
n = fs16_to_cpu(sbi, *(u16*)bh->b_data);
blocks = get_chunk(sb, bh);
}
if (bh)
......@@ -228,7 +231,7 @@ unsigned long sysv_count_free_blocks(struct super_block * sb)
printk("sysv_count_free_blocks: free block count was %d, "
"correcting to %d\n", sb_count, count);
if (!(sb->s_flags & MS_RDONLY)) {
*sb->sv_free_blocks = cpu_to_fs32(sb, count);
*sbi->s_free_blocks = cpu_to_fs32(sbi, count);
dirty_sb(sb);
}
goto done;
......
......@@ -104,7 +104,8 @@ static int sysv_readdir(struct file * filp, void * dirent, filldir_t filldir)
over = filldir(dirent, name, strnlen(name,SYSV_NAMELEN),
(n<<PAGE_CACHE_SHIFT) | offset,
fs16_to_cpu(sb, de->inode), DT_UNKNOWN);
fs16_to_cpu(SYSV_SB(sb), de->inode),
DT_UNKNOWN);
if (over) {
dir_put_page(page);
goto done;
......@@ -228,7 +229,7 @@ int sysv_add_link(struct dentry *dentry, struct inode *inode)
goto out_unlock;
memcpy (de->name, name, namelen);
memset (de->name + namelen, 0, SYSV_DIRSIZE - namelen - 2);
de->inode = cpu_to_fs16(inode->i_sb, inode->i_ino);
de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino);
err = dir_commit_chunk(page, from, to);
dir->i_mtime = dir->i_ctime = CURRENT_TIME;
mark_inode_dirty(dir);
......@@ -280,10 +281,10 @@ int sysv_make_empty(struct inode *inode, struct inode *dir)
memset(base, 0, PAGE_CACHE_SIZE);
de = (struct sysv_dir_entry *) base;
de->inode = cpu_to_fs16(inode->i_sb, inode->i_ino);
de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino);
strcpy(de->name,".");
de++;
de->inode = cpu_to_fs16(inode->i_sb, dir->i_ino);
de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), dir->i_ino);
strcpy(de->name,"..");
err = dir_commit_chunk(page, 0, 2 * SYSV_DIRSIZE);
......@@ -321,7 +322,8 @@ int sysv_empty_dir(struct inode * inode)
if (de->name[0] != '.')
goto not_empty;
if (!de->name[1]) {
if (de->inode == cpu_to_fs16(sb, inode->i_ino))
if (de->inode == cpu_to_fs16(SYSV_SB(sb),
inode->i_ino))
continue;
goto not_empty;
}
......@@ -350,7 +352,7 @@ void sysv_set_link(struct sysv_dir_entry *de, struct page *page,
err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
if (err)
BUG();
de->inode = cpu_to_fs16(inode->i_sb, inode->i_ino);
de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino);
err = dir_commit_chunk(page, from, to);
UnlockPage(page);
dir_put_page(page);
......@@ -377,7 +379,7 @@ ino_t sysv_inode_by_name(struct dentry *dentry)
ino_t res = 0;
if (de) {
res = fs16_to_cpu(dentry->d_sb, de->inode);
res = fs16_to_cpu(SYSV_SB(dentry->d_sb), de->inode);
dir_put_page(page);
}
return res;
......
......@@ -37,33 +37,38 @@
static inline sysv_ino_t *
sv_sb_fic_inode(struct super_block * sb, unsigned int i)
{
if (sb->sv_bh1 == sb->sv_bh2)
return &sb->sv_sb_fic_inodes[i];
struct sysv_sb_info *sbi = SYSV_SB(sb);
if (sbi->s_bh1 == sbi->s_bh2)
return &sbi->s_sb_fic_inodes[i];
else {
/* 512 byte Xenix FS */
unsigned int offset = offsetof(struct xenix_super_block, s_inode[i]);
if (offset < 512)
return (sysv_ino_t*)(sb->sv_sbd1 + offset);
return (sysv_ino_t*)(sbi->s_sbd1 + offset);
else
return (sysv_ino_t*)(sb->sv_sbd2 + offset);
return (sysv_ino_t*)(sbi->s_sbd2 + offset);
}
}
struct sysv_inode *
sysv_raw_inode(struct super_block *sb, unsigned ino, struct buffer_head **bh)
{
struct sysv_sb_info *sbi = SYSV_SB(sb);
struct sysv_inode *res;
int block = sb->sv_firstinodezone + sb->sv_block_base;
block += (ino-1) >> sb->sv_inodes_per_block_bits;
int block = sbi->s_firstinodezone + sbi->s_block_base;
block += (ino-1) >> sbi->s_inodes_per_block_bits;
*bh = sb_bread(sb, block);
if (!*bh)
return NULL;
res = (struct sysv_inode *) (*bh)->b_data;
return res + ((ino-1) & sb->sv_inodes_per_block_1);
res = (struct sysv_inode *)(*bh)->b_data;
return res + ((ino-1) & sbi->s_inodes_per_block_1);
}
static int refill_free_cache(struct super_block *sb)
{
struct sysv_sb_info *sbi = SYSV_SB(sb);
struct buffer_head * bh;
struct sysv_inode * raw_inode;
int i = 0, ino;
......@@ -72,13 +77,13 @@ static int refill_free_cache(struct super_block *sb)
raw_inode = sysv_raw_inode(sb, ino, &bh);
if (!raw_inode)
goto out;
while (ino <= sb->sv_ninodes) {
while (ino <= sbi->s_ninodes) {
if (raw_inode->i_mode == 0 && raw_inode->i_nlink == 0) {
*sv_sb_fic_inode(sb,i++) = cpu_to_fs16(sb, ino);
if (i == sb->sv_fic_size)
*sv_sb_fic_inode(sb,i++) = cpu_to_fs16(SYSV_SB(sb), ino);
if (i == sbi->s_fic_size)
break;
}
if ((ino++ & sb->sv_inodes_per_block_1) == 0) {
if ((ino++ & sbi->s_inodes_per_block_1) == 0) {
brelse(bh);
raw_inode = sysv_raw_inode(sb, ino, &bh);
if (!raw_inode)
......@@ -93,7 +98,8 @@ static int refill_free_cache(struct super_block *sb)
void sysv_free_inode(struct inode * inode)
{
struct super_block * sb;
struct super_block *sb = inode->i_sb;
struct sysv_sb_info *sbi = SYSV_SB(sb);
unsigned int ino;
struct buffer_head * bh;
struct sysv_inode * raw_inode;
......@@ -101,7 +107,7 @@ void sysv_free_inode(struct inode * inode)
sb = inode->i_sb;
ino = inode->i_ino;
if (ino <= SYSV_ROOT_INO || ino > sb->sv_ninodes) {
if (ino <= SYSV_ROOT_INO || ino > sbi->s_ninodes) {
printk("sysv_free_inode: inode 0,1,2 or nonexistent inode\n");
return;
}
......@@ -113,12 +119,12 @@ void sysv_free_inode(struct inode * inode)
return;
}
lock_super(sb);
count = fs16_to_cpu(sb, *sb->sv_sb_fic_count);
if (count < sb->sv_fic_size) {
*sv_sb_fic_inode(sb,count++) = cpu_to_fs16(sb, ino);
*sb->sv_sb_fic_count = cpu_to_fs16(sb, count);
count = fs16_to_cpu(sbi, *sbi->s_sb_fic_count);
if (count < sbi->s_fic_size) {
*sv_sb_fic_inode(sb,count++) = cpu_to_fs16(sbi, ino);
*sbi->s_sb_fic_count = cpu_to_fs16(sbi, count);
}
fs16_add(sb, sb->sv_sb_total_free_inodes, 1);
fs16_add(sbi, sbi->s_sb_total_free_inodes, 1);
dirty_sb(sb);
memset(raw_inode, 0, sizeof(struct sysv_inode));
mark_buffer_dirty(bh);
......@@ -128,18 +134,18 @@ void sysv_free_inode(struct inode * inode)
struct inode * sysv_new_inode(const struct inode * dir, mode_t mode)
{
struct inode * inode;
struct super_block * sb;
struct super_block *sb = dir->i_sb;
struct sysv_sb_info *sbi = SYSV_SB(sb);
struct inode *inode;
u16 ino;
unsigned count;
sb = dir->i_sb;
inode = new_inode(sb);
if (!inode)
return ERR_PTR(-ENOMEM);
lock_super(sb);
count = fs16_to_cpu(sb, *sb->sv_sb_fic_count);
count = fs16_to_cpu(sbi, *sbi->s_sb_fic_count);
if (count == 0 || (*sv_sb_fic_inode(sb,count-1) == 0)) {
count = refill_free_cache(sb);
if (count == 0) {
......@@ -150,8 +156,8 @@ struct inode * sysv_new_inode(const struct inode * dir, mode_t mode)
}
/* Now count > 0. */
ino = *sv_sb_fic_inode(sb,--count);
*sb->sv_sb_fic_count = cpu_to_fs16(sb, count);
fs16_add(sb, sb->sv_sb_total_free_inodes, -1);
*sbi->s_sb_fic_count = cpu_to_fs16(sbi, count);
fs16_add(sbi, sbi->s_sb_total_free_inodes, -1);
dirty_sb(sb);
if (dir->i_mode & S_ISGID) {
......@@ -162,7 +168,7 @@ struct inode * sysv_new_inode(const struct inode * dir, mode_t mode)
inode->i_gid = current->fsgid;
inode->i_uid = current->fsuid;
inode->i_ino = fs16_to_cpu(sb, ino);
inode->i_ino = fs16_to_cpu(sbi, ino);
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
inode->i_blocks = inode->i_blksize = 0;
memset(SYSV_I(inode)->i_data, 0, sizeof(SYSV_I(inode)->i_data));
......@@ -180,13 +186,14 @@ struct inode * sysv_new_inode(const struct inode * dir, mode_t mode)
unsigned long sysv_count_free_inodes(struct super_block * sb)
{
struct sysv_sb_info *sbi = SYSV_SB(sb);
struct buffer_head * bh;
struct sysv_inode * raw_inode;
int ino, count, sb_count;
lock_super(sb);
sb_count = fs16_to_cpu(sb, *sb->sv_sb_total_free_inodes);
sb_count = fs16_to_cpu(sbi, *sbi->s_sb_total_free_inodes);
if (0)
goto trust_sb;
......@@ -197,10 +204,10 @@ unsigned long sysv_count_free_inodes(struct super_block * sb)
raw_inode = sysv_raw_inode(sb, ino, &bh);
if (!raw_inode)
goto Eio;
while (ino <= sb->sv_ninodes) {
while (ino <= sbi->s_ninodes) {
if (raw_inode->i_mode == 0 && raw_inode->i_nlink == 0)
count++;
if ((ino++ & sb->sv_inodes_per_block_1) == 0) {
if ((ino++ & sbi->s_inodes_per_block_1) == 0) {
brelse(bh);
raw_inode = sysv_raw_inode(sb, ino, &bh);
if (!raw_inode)
......@@ -220,7 +227,7 @@ unsigned long sysv_count_free_inodes(struct super_block * sb)
"free inode count was %d, correcting to %d\n",
sb_count, count);
if (!(sb->s_flags & MS_RDONLY)) {
*sb->sv_sb_total_free_inodes = cpu_to_fs16(sb, count);
*sbi->s_sb_total_free_inodes = cpu_to_fs16(SYSV_SB(sb), count);
dirty_sb(sb);
}
goto out;
......
......@@ -33,42 +33,53 @@
/* This is only called on sync() and umount(), when s_dirt=1. */
static void sysv_write_super(struct super_block *sb)
{
if (!(sb->s_flags & MS_RDONLY)) {
/* If we are going to write out the super block,
then attach current time stamp.
But if the filesystem was marked clean, keep it clean. */
unsigned long time = CURRENT_TIME;
unsigned long old_time = fs32_to_cpu(sb, *sb->sv_sb_time);
if (sb->sv_type == FSTYPE_SYSV4)
if (*sb->sv_sb_state == cpu_to_fs32(sb, 0x7c269d38 - old_time))
*sb->sv_sb_state = cpu_to_fs32(sb, 0x7c269d38 - time);
*sb->sv_sb_time = cpu_to_fs32(sb, time);
mark_buffer_dirty(sb->sv_bh2);
struct sysv_sb_info *sbi = SYSV_SB(sb);
unsigned long time = CURRENT_TIME, old_time;
if (sb->s_flags & MS_RDONLY)
goto clean;
/*
* If we are going to write out the super block,
* then attach current time stamp.
* But if the filesystem was marked clean, keep it clean.
*/
old_time = fs32_to_cpu(sbi, *sbi->s_sb_time);
if (sbi->s_type == FSTYPE_SYSV4) {
if (*sbi->s_sb_state == cpu_to_fs32(sbi, 0x7c269d38 - old_time))
*sbi->s_sb_state = cpu_to_fs32(sbi, 0x7c269d38 - time);
*sbi->s_sb_time = cpu_to_fs32(sbi, time);
mark_buffer_dirty(sbi->s_bh2);
}
clean:
sb->s_dirt = 0;
}
static void sysv_put_super(struct super_block *sb)
{
struct sysv_sb_info *sbi = SYSV_SB(sb);
if (!(sb->s_flags & MS_RDONLY)) {
/* XXX ext2 also updates the state here */
mark_buffer_dirty(sb->sv_bh1);
if (sb->sv_bh1 != sb->sv_bh2)
mark_buffer_dirty(sb->sv_bh2);
mark_buffer_dirty(sbi->s_bh1);
if (sbi->s_bh1 != sbi->s_bh2)
mark_buffer_dirty(sbi->s_bh2);
}
brelse(sb->sv_bh1);
if (sb->sv_bh1 != sb->sv_bh2)
brelse(sb->sv_bh2);
brelse(sbi->s_bh1);
if (sbi->s_bh1 != sbi->s_bh2)
brelse(sbi->s_bh2);
}
static int sysv_statfs(struct super_block *sb, struct statfs *buf)
{
struct sysv_sb_info *sbi = SYSV_SB(sb);
buf->f_type = sb->s_magic;
buf->f_bsize = sb->s_blocksize;
buf->f_blocks = sb->sv_ndatazones;
buf->f_blocks = sbi->s_ndatazones;
buf->f_bavail = buf->f_bfree = sysv_count_free_blocks(sb);
buf->f_files = sb->sv_ninodes;
buf->f_files = sbi->s_ninodes;
buf->f_ffree = sysv_count_free_inodes(sb);
buf->f_namelen = SYSV_NAMELEN;
return 0;
......@@ -77,15 +88,15 @@ static int sysv_statfs(struct super_block *sb, struct statfs *buf)
/*
* NXI <-> N0XI for PDP, XIN <-> XIN0 for le32, NIX <-> 0NIX for be32
*/
static inline void read3byte(struct super_block *sb,
static inline void read3byte(struct sysv_sb_info *sbi,
unsigned char * from, unsigned char * to)
{
if (sb->sv_bytesex == BYTESEX_PDP) {
if (sbi->s_bytesex == BYTESEX_PDP) {
to[0] = from[0];
to[1] = 0;
to[2] = from[1];
to[3] = from[2];
} else if (sb->sv_bytesex == BYTESEX_LE) {
} else if (sbi->s_bytesex == BYTESEX_LE) {
to[0] = from[0];
to[1] = from[1];
to[2] = from[2];
......@@ -98,14 +109,14 @@ static inline void read3byte(struct super_block *sb,
}
}
static inline void write3byte(struct super_block *sb,
static inline void write3byte(struct sysv_sb_info *sbi,
unsigned char * from, unsigned char * to)
{
if (sb->sv_bytesex == BYTESEX_PDP) {
if (sbi->s_bytesex == BYTESEX_PDP) {
to[0] = from[0];
to[1] = from[2];
to[2] = from[3];
} else if (sb->sv_bytesex == BYTESEX_LE) {
} else if (sbi->s_bytesex == BYTESEX_LE) {
to[0] = from[0];
to[1] = from[1];
to[2] = from[2];
......@@ -144,6 +155,7 @@ void sysv_set_inode(struct inode *inode, dev_t rdev)
static void sysv_read_inode(struct inode *inode)
{
struct super_block * sb = inode->i_sb;
struct sysv_sb_info * sbi = SYSV_SB(sb);
struct buffer_head * bh;
struct sysv_inode * raw_inode;
struct sysv_inode_info * si;
......@@ -151,7 +163,7 @@ static void sysv_read_inode(struct inode *inode)
dev_t rdev = 0;
ino = inode->i_ino;
if (!ino || ino > sb->sv_ninodes) {
if (!ino || ino > sbi->s_ninodes) {
printk("Bad inode number on dev %s: %d is out of range\n",
inode->i_sb->s_id, ino);
goto bad_inode;
......@@ -163,23 +175,23 @@ static void sysv_read_inode(struct inode *inode)
goto bad_inode;
}
/* SystemV FS: kludge permissions if ino==SYSV_ROOT_INO ?? */
inode->i_mode = fs16_to_cpu(sb, raw_inode->i_mode);
inode->i_uid = (uid_t)fs16_to_cpu(sb, raw_inode->i_uid);
inode->i_gid = (gid_t)fs16_to_cpu(sb, raw_inode->i_gid);
inode->i_nlink = fs16_to_cpu(sb, raw_inode->i_nlink);
inode->i_size = fs32_to_cpu(sb, raw_inode->i_size);
inode->i_atime = fs32_to_cpu(sb, raw_inode->i_atime);
inode->i_mtime = fs32_to_cpu(sb, raw_inode->i_mtime);
inode->i_ctime = fs32_to_cpu(sb, raw_inode->i_ctime);
inode->i_mode = fs16_to_cpu(sbi, raw_inode->i_mode);
inode->i_uid = (uid_t)fs16_to_cpu(sbi, raw_inode->i_uid);
inode->i_gid = (gid_t)fs16_to_cpu(sbi, raw_inode->i_gid);
inode->i_nlink = fs16_to_cpu(sbi, raw_inode->i_nlink);
inode->i_size = fs32_to_cpu(sbi, raw_inode->i_size);
inode->i_atime = fs32_to_cpu(sbi, raw_inode->i_atime);
inode->i_mtime = fs32_to_cpu(sbi, raw_inode->i_mtime);
inode->i_ctime = fs32_to_cpu(sbi, raw_inode->i_ctime);
inode->i_blocks = inode->i_blksize = 0;
si = SYSV_I(inode);
for (block = 0; block < 10+1+1+1; block++)
read3byte(sb, &raw_inode->i_a.i_addb[3*block],
read3byte(sbi, &raw_inode->i_a.i_addb[3*block],
(unsigned char*)&si->i_data[block]);
brelse(bh);
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
rdev = (u16)fs32_to_cpu(sb, si->i_data[0]);
rdev = (u16)fs32_to_cpu(sbi, si->i_data[0]);
si->i_dir_start_lookup = 0;
sysv_set_inode(inode, rdev);
return;
......@@ -192,13 +204,14 @@ static void sysv_read_inode(struct inode *inode)
static struct buffer_head * sysv_update_inode(struct inode * inode)
{
struct super_block * sb = inode->i_sb;
struct sysv_sb_info * sbi = SYSV_SB(sb);
struct buffer_head * bh;
struct sysv_inode * raw_inode;
struct sysv_inode_info * si;
unsigned int ino, block;
ino = inode->i_ino;
if (!ino || ino > sb->sv_ninodes) {
if (!ino || ino > sbi->s_ninodes) {
printk("Bad inode number on dev %s: %d is out of range\n",
inode->i_sb->s_id, ino);
return 0;
......@@ -209,20 +222,20 @@ static struct buffer_head * sysv_update_inode(struct inode * inode)
return 0;
}
raw_inode->i_mode = cpu_to_fs16(sb, inode->i_mode);
raw_inode->i_uid = cpu_to_fs16(sb, fs_high2lowuid(inode->i_uid));
raw_inode->i_gid = cpu_to_fs16(sb, fs_high2lowgid(inode->i_gid));
raw_inode->i_nlink = cpu_to_fs16(sb, inode->i_nlink);
raw_inode->i_size = cpu_to_fs32(sb, inode->i_size);
raw_inode->i_atime = cpu_to_fs32(sb, inode->i_atime);
raw_inode->i_mtime = cpu_to_fs32(sb, inode->i_mtime);
raw_inode->i_ctime = cpu_to_fs32(sb, inode->i_ctime);
raw_inode->i_mode = cpu_to_fs16(sbi, inode->i_mode);
raw_inode->i_uid = cpu_to_fs16(sbi, fs_high2lowuid(inode->i_uid));
raw_inode->i_gid = cpu_to_fs16(sbi, fs_high2lowgid(inode->i_gid));
raw_inode->i_nlink = cpu_to_fs16(sbi, inode->i_nlink);
raw_inode->i_size = cpu_to_fs32(sbi, inode->i_size);
raw_inode->i_atime = cpu_to_fs32(sbi, inode->i_atime);
raw_inode->i_mtime = cpu_to_fs32(sbi, inode->i_mtime);
raw_inode->i_ctime = cpu_to_fs32(sbi, inode->i_ctime);
si = SYSV_I(inode);
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
si->i_data[0] = cpu_to_fs32(sb, kdev_t_to_nr(inode->i_rdev));
si->i_data[0] = cpu_to_fs32(sbi, kdev_t_to_nr(inode->i_rdev));
for (block = 0; block < 10+1+1+1; block++)
write3byte(sb, (unsigned char*)&si->i_data[block],
write3byte(sbi, (unsigned char*)&si->i_data[block],
&raw_inode->i_a.i_addb[3*block]);
mark_buffer_dirty(bh);
return bh;
......
......@@ -24,9 +24,10 @@ static inline void dirty_indirect(struct buffer_head *bh, struct inode *inode)
static int block_to_path(struct inode *inode, long block, int offsets[DEPTH])
{
struct super_block *sb = inode->i_sb;
int ptrs_bits = sb->sv_ind_per_block_bits;
unsigned long indirect_blocks = sb->sv_ind_per_block,
double_blocks = sb->sv_ind_per_block_2;
struct sysv_sb_info *sbi = SYSV_SB(sb);
int ptrs_bits = sbi->s_ind_per_block_bits;
unsigned long indirect_blocks = sbi->s_ind_per_block,
double_blocks = sbi->s_ind_per_block_2;
int n = 0;
if (block < 0) {
......@@ -51,9 +52,9 @@ static int block_to_path(struct inode *inode, long block, int offsets[DEPTH])
return n;
}
static inline int block_to_cpu(struct super_block *sb, u32 nr)
static inline int block_to_cpu(struct sysv_sb_info *sbi, u32 nr)
{
return sb->sv_block_base + fs32_to_cpu(sb, nr);
return sbi->s_block_base + fs32_to_cpu(sbi, nr);
}
typedef struct {
......@@ -95,7 +96,7 @@ static Indirect *get_branch(struct inode *inode,
if (!p->key)
goto no_block;
while (--depth) {
int block = block_to_cpu(sb, p->key);
int block = block_to_cpu(SYSV_SB(sb), p->key);
bh = sb_bread(sb, block);
if (!bh)
goto failure;
......@@ -137,7 +138,7 @@ static int alloc_branch(struct inode *inode,
* Get buffer_head for parent block, zero it out and set
* the pointer to new one, then send parent to disk.
*/
parent = block_to_cpu(inode->i_sb, branch[n-1].key);
parent = block_to_cpu(SYSV_SB(inode->i_sb), branch[n-1].key);
bh = sb_getblk(inode->i_sb, parent);
lock_buffer(bh);
memset(bh->b_data, 0, blocksize);
......@@ -211,7 +212,8 @@ static int get_block(struct inode *inode, sector_t iblock, struct buffer_head *b
/* Simplest case - block found, no allocation needed */
if (!partial) {
got_it:
map_bh(bh_result, sb, block_to_cpu(sb, chain[depth-1].key));
map_bh(bh_result, sb, block_to_cpu(SYSV_SB(sb),
chain[depth-1].key));
/* Clean up and exit */
partial = chain+depth-1; /* the whole chain */
goto cleanup;
......@@ -332,7 +334,7 @@ static void free_branches(struct inode *inode, u32 *p, u32 *q, int depth)
if (!nr)
continue;
*p = 0;
block = block_to_cpu(sb, nr);
block = block_to_cpu(SYSV_SB(sb), nr);
bh = sb_bread(sb, block);
if (!bh)
continue;
......
......@@ -138,7 +138,7 @@ static int sysv_link(struct dentry * old_dentry, struct inode * dir,
{
struct inode *inode = old_dentry->d_inode;
if (inode->i_nlink >= inode->i_sb->sv_link_max)
if (inode->i_nlink >= SYSV_SB(inode->i_sb)->s_link_max)
return -EMLINK;
inode->i_ctime = CURRENT_TIME;
......@@ -153,7 +153,7 @@ static int sysv_mkdir(struct inode * dir, struct dentry *dentry, int mode)
struct inode * inode;
int err = -EMLINK;
if (dir->i_nlink >= dir->i_sb->sv_link_max)
if (dir->i_nlink >= SYSV_SB(dir->i_sb)->s_link_max)
goto out;
inc_count(dir);
......@@ -271,7 +271,7 @@ static int sysv_rename(struct inode * old_dir, struct dentry * old_dentry,
} else {
if (dir_de) {
err = -EMLINK;
if (new_dir->i_nlink >= new_dir->i_sb->sv_link_max)
if (new_dir->i_nlink >= SYSV_SB(new_dir->i_sb)->s_link_max)
goto out_dir;
}
inc_count(old_inode);
......
This diff is collapsed.
......@@ -19,16 +19,20 @@
#include <linux/stat.h> /* declares S_IFLNK etc. */
#include <linux/sched.h> /* declares wake_up() */
#include <linux/sysv_fs_sb.h> /* defines the sv_... shortcuts */
/* temporary hack. */
#include <linux/sysv_fs_sb.h>
#include <linux/sysv_fs_i.h>
static inline struct sysv_inode_info *SYSV_I(struct inode *inode)
{
/* I think list_entry should have a more descriptive name.. --hch */
return list_entry(inode, struct sysv_inode_info, vfs_inode);
}
/* end temporary hack. */
static inline struct sysv_sb_info *SYSV_SB(struct super_block *sb)
{
return &sb->u.sysv_sb;
}
/* Layout on disk */
......@@ -346,61 +350,63 @@ extern struct sysv_inode *sysv_raw_inode(struct super_block *, unsigned, struct
static inline void dirty_sb(struct super_block *sb)
{
mark_buffer_dirty(sb->sv_bh1);
if (sb->sv_bh1 != sb->sv_bh2)
mark_buffer_dirty(sb->sv_bh2);
struct sysv_sb_info *sbi = SYSV_SB(sb);
mark_buffer_dirty(sbi->s_bh1);
if (sbi->s_bh1 != sbi->s_bh2)
mark_buffer_dirty(sbi->s_bh2);
sb->s_dirt = 1;
}
static inline u32 fs32_to_cpu(struct super_block *sb, u32 n)
static inline u32 fs32_to_cpu(struct sysv_sb_info *sbi, u32 n)
{
if (sb->sv_bytesex == BYTESEX_PDP)
if (sbi->s_bytesex == BYTESEX_PDP)
return PDP_swab(n);
else if (sb->sv_bytesex == BYTESEX_LE)
else if (sbi->s_bytesex == BYTESEX_LE)
return le32_to_cpu(n);
else
return be32_to_cpu(n);
}
static inline u32 cpu_to_fs32(struct super_block *sb, u32 n)
static inline u32 cpu_to_fs32(struct sysv_sb_info *sbi, u32 n)
{
if (sb->sv_bytesex == BYTESEX_PDP)
if (sbi->s_bytesex == BYTESEX_PDP)
return PDP_swab(n);
else if (sb->sv_bytesex == BYTESEX_LE)
else if (sbi->s_bytesex == BYTESEX_LE)
return cpu_to_le32(n);
else
return cpu_to_be32(n);
}
static inline u32 fs32_add(struct super_block *sb, u32 *n, int d)
static inline u32 fs32_add(struct sysv_sb_info *sbi, u32 *n, int d)
{
if (sb->sv_bytesex == BYTESEX_PDP)
if (sbi->s_bytesex == BYTESEX_PDP)
return *n = PDP_swab(PDP_swab(*n)+d);
else if (sb->sv_bytesex == BYTESEX_LE)
else if (sbi->s_bytesex == BYTESEX_LE)
return *n = cpu_to_le32(le32_to_cpu(*n)+d);
else
return *n = cpu_to_be32(be32_to_cpu(*n)+d);
}
static inline u16 fs16_to_cpu(struct super_block *sb, u16 n)
static inline u16 fs16_to_cpu(struct sysv_sb_info *sbi, u16 n)
{
if (sb->sv_bytesex != BYTESEX_BE)
if (sbi->s_bytesex != BYTESEX_BE)
return le16_to_cpu(n);
else
return be16_to_cpu(n);
}
static inline u16 cpu_to_fs16(struct super_block *sb, u16 n)
static inline u16 cpu_to_fs16(struct sysv_sb_info *sbi, u16 n)
{
if (sb->sv_bytesex != BYTESEX_BE)
if (sbi->s_bytesex != BYTESEX_BE)
return cpu_to_le16(n);
else
return cpu_to_be16(n);
}
static inline u16 fs16_add(struct super_block *sb, u16 *n, int d)
static inline u16 fs16_add(struct sysv_sb_info *sbi, u16 *n, int d)
{
if (sb->sv_bytesex != BYTESEX_BE)
if (sbi->s_bytesex != BYTESEX_BE)
return *n = cpu_to_le16(le16_to_cpu(*n)+d);
else
return *n = cpu_to_be16(be16_to_cpu(*n)+d);
......
......@@ -11,6 +11,7 @@
*/
struct sysv_sb_info {
struct super_block *s_sb; /* VFS superblock */
int s_type; /* file system type: FSTYPE_{XENIX|SYSV|COH} */
char s_bytesex; /* bytesex (le/be/pdp) */
char s_truncate; /* if 1: names > SYSV_NAMELEN chars are truncated */
......@@ -52,38 +53,4 @@ struct sysv_sb_info {
};
/* The field s_toobig_block is currently unused. */
/* sv_ == u.sysv_sb.s_ */
#define sv_type u.sysv_sb.s_type
#define sv_bytesex u.sysv_sb.s_bytesex
#define sv_truncate u.sysv_sb.s_truncate
#define sv_link_max u.sysv_sb.s_link_max
#define sv_inodes_per_block u.sysv_sb.s_inodes_per_block
#define sv_inodes_per_block_1 u.sysv_sb.s_inodes_per_block_1
#define sv_inodes_per_block_bits u.sysv_sb.s_inodes_per_block_bits
#define sv_ind_per_block u.sysv_sb.s_ind_per_block
#define sv_ind_per_block_bits u.sysv_sb.s_ind_per_block_bits
#define sv_ind_per_block_2 u.sysv_sb.s_ind_per_block_2
#define sv_toobig_block u.sysv_sb.s_toobig_block
#define sv_block_base u.sysv_sb.s_block_base
#define sv_fic_size u.sysv_sb.s_fic_size
#define sv_flc_size u.sysv_sb.s_flc_size
#define sv_bh1 u.sysv_sb.s_bh1
#define sv_bh2 u.sysv_sb.s_bh2
#define sv_sbd1 u.sysv_sb.s_sbd1
#define sv_sbd2 u.sysv_sb.s_sbd2
#define sv_sb_fic_count u.sysv_sb.s_sb_fic_count
#define sv_sb_fic_inodes u.sysv_sb.s_sb_fic_inodes
#define sv_sb_total_free_inodes u.sysv_sb.s_sb_total_free_inodes
#define sv_bcache_count u.sysv_sb.s_bcache_count
#define sv_bcache u.sysv_sb.s_bcache
#define sv_free_blocks u.sysv_sb.s_free_blocks
#define sv_sb_time u.sysv_sb.s_sb_time
#define sv_sb_state u.sysv_sb.s_sb_state
#define sv_firstinodezone u.sysv_sb.s_firstinodezone
#define sv_firstdatazone u.sysv_sb.s_firstdatazone
#define sv_ninodes u.sysv_sb.s_ninodes
#define sv_ndatazones u.sysv_sb.s_ndatazones
#define sv_nzones u.sysv_sb.s_nzones
#define sv_namelen u.sysv_sb.s_namelen
#endif
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