URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [fs/] [ufs/] [ufs_file.c] - Rev 1765
Compare with Previous | Blame | View Log
/* * 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.1.1 2001-09-10 07:44:40 simons 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 %u, 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 %u 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 */ 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: *** */