patch-1.3.94 linux/fs/ufs/ufs_file.c
Next file: linux/fs/ufs/ufs_inode.c
Previous file: linux/fs/ufs/ufs_dir.c
Back to the patch index
Back to the overall index
- Lines: 145
- Date:
Mon Apr 22 10:59:39 1996
- Orig file:
v1.3.93/linux/fs/ufs/ufs_file.c
- Orig date:
Thu Jan 1 02:00:00 1970
diff -u --recursive --new-file v1.3.93/linux/fs/ufs/ufs_file.c linux/fs/ufs/ufs_file.c
@@ -0,0 +1,144 @@
+/*
+ * linux/fs/ufs/ufs_file.c
+ *
+ * Copyright (C) 1996
+ * Adrian Rodriguez (adrian@franklins-tower.rutgers.edu)
+ * Laboratory for Computer Science Research Computing Facility
+ * Rutgers, The State University of New Jersey
+ *
+ * $Id: ufs_file.c,v 1.1 1996/04/21 14:41:08 davem Exp $
+ *
+ */
+
+#include <linux/fs.h>
+
+/*
+ * Return values:
+ * 0: bmap failed
+ * nonzero: absolute "block" number
+ */
+int ufs_bmap (struct inode * inode, int block)
+{
+ unsigned long int fsblkno, phys_block, lfsblkno;
+ struct buffer_head * bh;
+
+ /*
+ * Note that contrary to what the BSD source calls these things,
+ * blkno and lblkno are *frags* (1024), not UFS blocks (8192).
+ * 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
+ * number of 512-byte blocks that are allocated to the file. The
+ * elements in ui_db[UFS_NDADDR] are pointers to 1024-byte aligned
+ * 8192 byte objects. The entire 8192 bytes (16 512-blocks) may
+ * 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
+ * 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
+ * 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].
+ *
+ * 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
+ * of 8192-byte filesystem blocks, a given 512-byte disk block
+ * could be referred to in eight different ways.
+ */
+
+ /*
+ * block is the logical 1024-block in the file
+ * lfsblkno is the logical 8192-block in the file
+ * fsblkno is the physical 8192-block
+ * phys_block is the 1024-block
+ */
+ lfsblkno = block>>3;
+
+ if (block < UFS_NDADDR) {
+ /* It's a direct block */
+ fsblkno = inode->u.ufs_i.ui_db[lfsblkno]; /* XXX */
+#if 0
+ phys_block = ufs_cgdmin(inode->i_sb, ufs_ino2cg(inode)) +
+ blkno%(inode->i_sb->u.ufs_sb.s_fpg);
+#endif
+ phys_block = fsblkno + ((block & 0x7)<<10); /* XXX */
+ if (inode->i_sb->u.ufs_sb.s_flags & UFS_DEBUG) {
+ printk("ufs_bmap: mapped ino %lu logical %u to %lu (phys %lu)\n",
+ inode->i_ino, block, fsblkno, phys_block);
+ }
+ return(phys_block);
+ } else {
+ /* Need to use indirect blocks */
+ /* XXX - bmap through indirect blocks not implemented */
+ block -= UFS_NDADDR;
+ if (block < (inode->i_sb->s_blocksize/sizeof(__u32))) {
+ bh = bread(inode->i_dev, inode->u.ufs_i.ui_ib[0],
+ BLOCK_SIZE);
+ if (bh == NULL) {
+ printk("ufs_bmap: can't map block %lu, ino %lu\n",
+ block + UFS_NDADDR, inode->i_ino);
+ return(0);
+ }
+ phys_block = ((__u32 *)bh->b_data)[block];
+ brelse(bh);
+ printk("ufs_bmap: imap ino %lu block %lu phys %lu\n",
+ inode->i_ino, block + UFS_NDADDR, phys_block);
+ return(phys_block);
+ } else {
+ printk("ufs_bmap: ino %lu: indirect blocks not implemented\n",
+ inode->i_ino);
+ return(0);
+ }
+ }
+
+ return(0);
+}
+
+
+static struct file_operations ufs_file_operations = {
+ NULL, /* lseek */
+ &generic_file_read, /* read */
+ NULL, /* write */
+ NULL, /* readdir */
+ NULL, /* select */
+ NULL, /* ioctl */
+ &generic_file_mmap, /* mmap */
+ NULL, /* open */
+ NULL, /* release */
+ &file_fsync, /* fsync */ /* XXX - is this ok? */
+ NULL, /* fasync */
+ NULL, /* check_media_change */
+ NULL, /* revalidate */
+};
+
+struct inode_operations ufs_file_inode_operations = {
+ &ufs_file_operations, /* default directory file operations */
+ NULL, /* create */
+ NULL, /* lookup */
+ NULL, /* link */
+ NULL, /* unlink */
+ NULL, /* symlink */
+ NULL, /* mkdir */
+ NULL, /* rmdir */
+ NULL, /* mknod */
+ NULL, /* rename */
+ NULL, /* readlink */
+ NULL, /* follow_link */
+ &generic_readpage, /* readpage */
+ NULL, /* writepage */
+ &ufs_bmap, /* bmap */
+ NULL, /* truncate */
+ NULL, /* permission */
+ NULL, /* smap */
+};
+
+
+/*
+ * Local Variables: ***
+ * c-indent-level: 8 ***
+ * c-continued-statement-offset: 8 ***
+ * c-brace-offset: -8 ***
+ * c-argdecl-indent: 0 ***
+ * c-label-offset: -8 ***
+ * End: ***
+ */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this