146 lines
3.7 KiB
C
146 lines
3.7 KiB
C
/*
|
|
* linux/fs/minix/inode.c
|
|
*
|
|
* (C) 1991 Linus Torvalds
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <sys/stat.h>
|
|
|
|
#include <linux/sched.h>
|
|
#include <linux/minix_fs.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/mm.h>
|
|
#include <asm/system.h>
|
|
|
|
static int _bmap(struct inode * inode,int block,int create)
|
|
{
|
|
struct buffer_head * bh;
|
|
int i;
|
|
|
|
if (block<0)
|
|
panic("_bmap: block<0");
|
|
if (block >= 7+512+512*512)
|
|
panic("_bmap: block>big");
|
|
if (block<7) {
|
|
if (create && !inode->i_data[block])
|
|
if (inode->i_data[block]=minix_new_block(inode->i_dev)) {
|
|
inode->i_ctime=CURRENT_TIME;
|
|
inode->i_dirt=1;
|
|
}
|
|
return inode->i_data[block];
|
|
}
|
|
block -= 7;
|
|
if (block<512) {
|
|
if (create && !inode->i_data[7])
|
|
if (inode->i_data[7]=minix_new_block(inode->i_dev)) {
|
|
inode->i_dirt=1;
|
|
inode->i_ctime=CURRENT_TIME;
|
|
}
|
|
if (!inode->i_data[7])
|
|
return 0;
|
|
if (!(bh = bread(inode->i_dev,inode->i_data[7])))
|
|
return 0;
|
|
i = ((unsigned short *) (bh->b_data))[block];
|
|
if (create && !i)
|
|
if (i=minix_new_block(inode->i_dev)) {
|
|
((unsigned short *) (bh->b_data))[block]=i;
|
|
bh->b_dirt=1;
|
|
}
|
|
brelse(bh);
|
|
return i;
|
|
}
|
|
block -= 512;
|
|
if (create && !inode->i_data[8])
|
|
if (inode->i_data[8]=minix_new_block(inode->i_dev)) {
|
|
inode->i_dirt=1;
|
|
inode->i_ctime=CURRENT_TIME;
|
|
}
|
|
if (!inode->i_data[8])
|
|
return 0;
|
|
if (!(bh=bread(inode->i_dev,inode->i_data[8])))
|
|
return 0;
|
|
i = ((unsigned short *)bh->b_data)[block>>9];
|
|
if (create && !i)
|
|
if (i=minix_new_block(inode->i_dev)) {
|
|
((unsigned short *) (bh->b_data))[block>>9]=i;
|
|
bh->b_dirt=1;
|
|
}
|
|
brelse(bh);
|
|
if (!i)
|
|
return 0;
|
|
if (!(bh=bread(inode->i_dev,i)))
|
|
return 0;
|
|
i = ((unsigned short *)bh->b_data)[block&511];
|
|
if (create && !i)
|
|
if (i=minix_new_block(inode->i_dev)) {
|
|
((unsigned short *) (bh->b_data))[block&511]=i;
|
|
bh->b_dirt=1;
|
|
}
|
|
brelse(bh);
|
|
return i;
|
|
}
|
|
|
|
int minix_bmap(struct inode * inode,int block)
|
|
{
|
|
return _bmap(inode,block,0);
|
|
}
|
|
|
|
int minix_create_block(struct inode * inode, int block)
|
|
{
|
|
return _bmap(inode,block,1);
|
|
}
|
|
|
|
void minix_read_inode(struct inode * inode)
|
|
{
|
|
struct buffer_head * bh;
|
|
struct minix_inode * raw_inode;
|
|
int block;
|
|
|
|
block = 2 + inode->i_sb->s_imap_blocks + inode->i_sb->s_zmap_blocks +
|
|
(inode->i_ino-1)/MINIX_INODES_PER_BLOCK;
|
|
if (!(bh=bread(inode->i_dev,block)))
|
|
panic("unable to read i-node block");
|
|
raw_inode = ((struct minix_inode *) bh->b_data) +
|
|
(inode->i_ino-1)%MINIX_INODES_PER_BLOCK;
|
|
inode->i_mode = raw_inode->i_mode;
|
|
inode->i_uid = raw_inode->i_uid;
|
|
inode->i_gid = raw_inode->i_gid;
|
|
inode->i_nlink = raw_inode->i_nlinks;
|
|
inode->i_size = raw_inode->i_size;
|
|
inode->i_mtime = inode->i_atime = inode->i_ctime = raw_inode->i_time;
|
|
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
|
|
inode->i_rdev = raw_inode->i_zone[0];
|
|
else for (block = 0; block < 9; block++)
|
|
inode->i_data[block] = raw_inode->i_zone[block];
|
|
brelse(bh);
|
|
inode->i_op = &minix_inode_operations;
|
|
}
|
|
|
|
void minix_write_inode(struct inode * inode)
|
|
{
|
|
struct buffer_head * bh;
|
|
struct minix_inode * raw_inode;
|
|
int block;
|
|
|
|
block = 2 + inode->i_sb->s_imap_blocks + inode->i_sb->s_zmap_blocks +
|
|
(inode->i_ino-1)/MINIX_INODES_PER_BLOCK;
|
|
if (!(bh=bread(inode->i_dev,block)))
|
|
panic("unable to read i-node block");
|
|
raw_inode = ((struct minix_inode *)bh->b_data) +
|
|
(inode->i_ino-1)%MINIX_INODES_PER_BLOCK;
|
|
raw_inode->i_mode = inode->i_mode;
|
|
raw_inode->i_uid = inode->i_uid;
|
|
raw_inode->i_gid = inode->i_gid;
|
|
raw_inode->i_nlinks = inode->i_nlink;
|
|
raw_inode->i_size = inode->i_size;
|
|
raw_inode->i_time = inode->i_mtime;
|
|
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
|
|
raw_inode->i_zone[0] = inode->i_rdev;
|
|
else for (block = 0; block < 9; block++)
|
|
raw_inode->i_zone[block] = inode->i_data[block];
|
|
bh->b_dirt=1;
|
|
inode->i_dirt=0;
|
|
brelse(bh);
|
|
}
|