/*
|
/*
|
* linux/fs/ufs/ufs_file.c
|
* linux/fs/ufs/ufs_file.c
|
*
|
*
|
* Copyright (C) 1996
|
* Copyright (C) 1996
|
* Adrian Rodriguez (adrian@franklins-tower.rutgers.edu)
|
* Adrian Rodriguez (adrian@franklins-tower.rutgers.edu)
|
* Laboratory for Computer Science Research Computing Facility
|
* Laboratory for Computer Science Research Computing Facility
|
* Rutgers, The State University of New Jersey
|
* Rutgers, The State University of New Jersey
|
*
|
*
|
* $Id: ufs_file.c,v 1.1 2005-12-20 10:26:35 jcastillo Exp $
|
* $Id: ufs_file.c,v 1.1 2005-12-20 10:26:35 jcastillo Exp $
|
*
|
*
|
*/
|
*/
|
|
|
#include <linux/fs.h>
|
#include <linux/fs.h>
|
|
|
/*
|
/*
|
* Return values:
|
* Return values:
|
* 0: bmap failed
|
* 0: bmap failed
|
* nonzero: absolute "block" number
|
* nonzero: absolute "block" number
|
*/
|
*/
|
int ufs_bmap (struct inode * inode, int block)
|
int ufs_bmap (struct inode * inode, int block)
|
{
|
{
|
unsigned long int fsblkno, phys_block, lfsblkno;
|
unsigned long int fsblkno, phys_block, lfsblkno;
|
struct buffer_head * bh;
|
struct buffer_head * bh;
|
|
|
/*
|
/*
|
* Note that contrary to what the BSD source calls these things,
|
* Note that contrary to what the BSD source calls these things,
|
* blkno and lblkno are *frags* (1024), not UFS blocks (8192).
|
* blkno and lblkno are *frags* (1024), not UFS blocks (8192).
|
* XXX - maybe I'm wrong, and ui_blocks is really 512-blocks...
|
* XXX - maybe I'm wrong, and ui_blocks is really 512-blocks...
|
*/
|
*/
|
|
|
/*
|
/*
|
* Ok, I think I figured out what is going on. ui_blocks is the
|
* Ok, I think I figured out what is going on. ui_blocks is the
|
* number of 512-byte blocks that are allocated to the file. The
|
* number of 512-byte blocks that are allocated to the file. The
|
* elements in ui_db[UFS_NDADDR] are pointers to 1024-byte aligned
|
* elements in ui_db[UFS_NDADDR] are pointers to 1024-byte aligned
|
* 8192 byte objects. The entire 8192 bytes (16 512-blocks) may
|
* 8192 byte objects. The entire 8192 bytes (16 512-blocks) may
|
* not be allocated to the file in question - use ui_blocks to see
|
* not be allocated to the file in question - use ui_blocks to see
|
* how many of the blocks are allocated. Also, use ui_size to see
|
* how many of the blocks are allocated. Also, use ui_size to see
|
* what fraction of the last block is allocated to the file, and
|
* what fraction of the last block is allocated to the file, and
|
* what fraction is unused. I have not yet seen a file with a
|
* what fraction is unused. I have not yet seen a file with a
|
* hole in it, but I'd guess that a hole must be at least 8192
|
* hole in it, but I'd guess that a hole must be at least 8192
|
* bytes of zeros, and it's represented by a zero in ui_db[X].
|
* bytes of zeros, and it's represented by a zero in ui_db[X].
|
*
|
*
|
* Yes, this means that there is more than one way to name a given
|
* Yes, this means that there is more than one way to name a given
|
* 512-byte block on the disk. Because of the 1024-byte alignment
|
* 512-byte block on the disk. Because of the 1024-byte alignment
|
* of 8192-byte filesystem blocks, a given 512-byte disk block
|
* of 8192-byte filesystem blocks, a given 512-byte disk block
|
* could be referred to in eight different ways.
|
* could be referred to in eight different ways.
|
*/
|
*/
|
|
|
/*
|
/*
|
* block is the logical 1024-block in the file
|
* block is the logical 1024-block in the file
|
* lfsblkno is the logical 8192-block in the file
|
* lfsblkno is the logical 8192-block in the file
|
* fsblkno is the physical 8192-block
|
* fsblkno is the physical 8192-block
|
* phys_block is the 1024-block
|
* phys_block is the 1024-block
|
*/
|
*/
|
lfsblkno = block>>3;
|
lfsblkno = block>>3;
|
|
|
if (block < UFS_NDADDR) {
|
if (block < UFS_NDADDR) {
|
/* It's a direct block */
|
/* It's a direct block */
|
fsblkno = inode->u.ufs_i.ui_db[lfsblkno]; /* XXX */
|
fsblkno = inode->u.ufs_i.ui_db[lfsblkno]; /* XXX */
|
#if 0
|
#if 0
|
phys_block = ufs_cgdmin(inode->i_sb, ufs_ino2cg(inode)) +
|
phys_block = ufs_cgdmin(inode->i_sb, ufs_ino2cg(inode)) +
|
blkno%(inode->i_sb->u.ufs_sb.s_fpg);
|
blkno%(inode->i_sb->u.ufs_sb.s_fpg);
|
#endif
|
#endif
|
phys_block = fsblkno + ((block & 0x7)<<10); /* XXX */
|
phys_block = fsblkno + ((block & 0x7)<<10); /* XXX */
|
if (inode->i_sb->u.ufs_sb.s_flags & UFS_DEBUG) {
|
if (inode->i_sb->u.ufs_sb.s_flags & UFS_DEBUG) {
|
printk("ufs_bmap: mapped ino %lu logical %u to %lu (phys %lu)\n",
|
printk("ufs_bmap: mapped ino %lu logical %u to %lu (phys %lu)\n",
|
inode->i_ino, block, fsblkno, phys_block);
|
inode->i_ino, block, fsblkno, phys_block);
|
}
|
}
|
return(phys_block);
|
return(phys_block);
|
} else {
|
} else {
|
/* Need to use indirect blocks */
|
/* Need to use indirect blocks */
|
/* XXX - bmap through indirect blocks not implemented */
|
/* XXX - bmap through indirect blocks not implemented */
|
block -= UFS_NDADDR;
|
block -= UFS_NDADDR;
|
if (block < (inode->i_sb->s_blocksize/sizeof(__u32))) {
|
if (block < (inode->i_sb->s_blocksize/sizeof(__u32))) {
|
bh = bread(inode->i_dev, inode->u.ufs_i.ui_ib[0],
|
bh = bread(inode->i_dev, inode->u.ufs_i.ui_ib[0],
|
BLOCK_SIZE);
|
BLOCK_SIZE);
|
if (bh == NULL) {
|
if (bh == NULL) {
|
printk("ufs_bmap: can't map block %u, ino %lu\n",
|
printk("ufs_bmap: can't map block %u, ino %lu\n",
|
block + UFS_NDADDR, inode->i_ino);
|
block + UFS_NDADDR, inode->i_ino);
|
return(0);
|
return(0);
|
}
|
}
|
phys_block = ((__u32 *)bh->b_data)[block];
|
phys_block = ((__u32 *)bh->b_data)[block];
|
brelse(bh);
|
brelse(bh);
|
printk("ufs_bmap: imap ino %lu block %u phys %lu\n",
|
printk("ufs_bmap: imap ino %lu block %u phys %lu\n",
|
inode->i_ino, block + UFS_NDADDR, phys_block);
|
inode->i_ino, block + UFS_NDADDR, phys_block);
|
return(phys_block);
|
return(phys_block);
|
} else {
|
} else {
|
printk("ufs_bmap: ino %lu: indirect blocks not implemented\n",
|
printk("ufs_bmap: ino %lu: indirect blocks not implemented\n",
|
inode->i_ino);
|
inode->i_ino);
|
return(0);
|
return(0);
|
}
|
}
|
}
|
}
|
|
|
return(0);
|
return(0);
|
}
|
}
|
|
|
static struct file_operations ufs_file_operations = {
|
static struct file_operations ufs_file_operations = {
|
NULL, /* lseek */
|
NULL, /* lseek */
|
generic_file_read, /* read */
|
generic_file_read, /* read */
|
NULL, /* write */
|
NULL, /* write */
|
NULL, /* readdir */
|
NULL, /* readdir */
|
NULL, /* select */
|
NULL, /* select */
|
NULL, /* ioctl */
|
NULL, /* ioctl */
|
generic_file_mmap, /* mmap */
|
generic_file_mmap, /* mmap */
|
NULL, /* open */
|
NULL, /* open */
|
NULL, /* release */
|
NULL, /* release */
|
file_fsync, /* fsync */
|
file_fsync, /* fsync */
|
NULL, /* fasync */
|
NULL, /* fasync */
|
NULL, /* check_media_change */
|
NULL, /* check_media_change */
|
NULL, /* revalidate */
|
NULL, /* revalidate */
|
};
|
};
|
|
|
struct inode_operations ufs_file_inode_operations = {
|
struct inode_operations ufs_file_inode_operations = {
|
&ufs_file_operations, /* default directory file operations */
|
&ufs_file_operations, /* default directory file operations */
|
NULL, /* create */
|
NULL, /* create */
|
NULL, /* lookup */
|
NULL, /* lookup */
|
NULL, /* link */
|
NULL, /* link */
|
NULL, /* unlink */
|
NULL, /* unlink */
|
NULL, /* symlink */
|
NULL, /* symlink */
|
NULL, /* mkdir */
|
NULL, /* mkdir */
|
NULL, /* rmdir */
|
NULL, /* rmdir */
|
NULL, /* mknod */
|
NULL, /* mknod */
|
NULL, /* rename */
|
NULL, /* rename */
|
NULL, /* readlink */
|
NULL, /* readlink */
|
NULL, /* follow_link */
|
NULL, /* follow_link */
|
generic_readpage, /* readpage */
|
generic_readpage, /* readpage */
|
NULL, /* writepage */
|
NULL, /* writepage */
|
ufs_bmap, /* bmap */
|
ufs_bmap, /* bmap */
|
NULL, /* truncate */
|
NULL, /* truncate */
|
NULL, /* permission */
|
NULL, /* permission */
|
NULL, /* smap */
|
NULL, /* smap */
|
};
|
};
|
|
|
|
|
/*
|
/*
|
* Local Variables: ***
|
* Local Variables: ***
|
* c-indent-level: 8 ***
|
* c-indent-level: 8 ***
|
* c-continued-statement-offset: 8 ***
|
* c-continued-statement-offset: 8 ***
|
* c-brace-offset: -8 ***
|
* c-brace-offset: -8 ***
|
* c-argdecl-indent: 0 ***
|
* c-argdecl-indent: 0 ***
|
* c-label-offset: -8 ***
|
* c-label-offset: -8 ***
|
* End: ***
|
* End: ***
|
*/
|
*/
|
|
|