1 /* 2 * linux/fs/ufs/ufs_file.c 3 * 4 * Copyright (C) 1996 5 * Adrian Rodriguez (adrian@franklins-tower.rutgers.edu) 6 * Laboratory for Computer Science Research Computing Facility 7 * Rutgers, The State University of New Jersey 8 * 9 * $Id: ufs_file.c,v 1.3 1996/04/25 09:12:02 davem Exp $ 10 * 11 */ 12 13 #include <linux/fs.h> 14 15 /* 16 * Return values: 17 * 0: bmap failed 18 * nonzero: absolute "block" number 19 */ 20 int ufs_bmap (struct inode * inode, int block) /* */ 21 { 22 unsigned long int fsblkno, phys_block, lfsblkno; 23 struct buffer_head * bh; 24 25 /* 26 * Note that contrary to what the BSD source calls these things, 27 * blkno and lblkno are *frags* (1024), not UFS blocks (8192). 28 * XXX - maybe I'm wrong, and ui_blocks is really 512-blocks... 29 */ 30 31 /* 32 * Ok, I think I figured out what is going on. ui_blocks is the 33 * number of 512-byte blocks that are allocated to the file. The 34 * elements in ui_db[UFS_NDADDR] are pointers to 1024-byte aligned 35 * 8192 byte objects. The entire 8192 bytes (16 512-blocks) may 36 * not be allocated to the file in question - use ui_blocks to see 37 * how many of the blocks are allocated. Also, use ui_size to see 38 * what fraction of the last block is allocated to the file, and 39 * what fraction is unused. I have not yet seen a file with a 40 * hole in it, but I'd guess that a hole must be at least 8192 41 * bytes of zeros, and it's represented by a zero in ui_db[X]. 42 * 43 * Yes, this means that there is more than one way to name a given 44 * 512-byte block on the disk. Because of the 1024-byte alignment 45 * of 8192-byte filesystem blocks, a given 512-byte disk block 46 * could be referred to in eight different ways. 47 */ 48 49 /* 50 * block is the logical 1024-block in the file 51 * lfsblkno is the logical 8192-block in the file 52 * fsblkno is the physical 8192-block 53 * phys_block is the 1024-block 54 */ 55 lfsblkno = block>>3; 56 57 if (block < UFS_NDADDR) { 58 /* It's a direct block */ 59 fsblkno = inode->u.ufs_i.ui_db[lfsblkno]; /* XXX */ 60 #if 0 61 phys_block = ufs_cgdmin(inode->i_sb, ufs_ino2cg(inode)) + 62 blkno%(inode->i_sb->u.ufs_sb.s_fpg); 63 #endif 64 phys_block = fsblkno + ((block & 0x7)<<10); /* XXX */ 65 if (inode->i_sb->u.ufs_sb.s_flags & UFS_DEBUG) { 66 printk("ufs_bmap: mapped ino %lu logical %u to %lu (phys %lu)\n", 67 inode->i_ino, block, fsblkno, phys_block); 68 } 69 return(phys_block); 70 } else { 71 /* Need to use indirect blocks */ 72 /* XXX - bmap through indirect blocks not implemented */ 73 block -= UFS_NDADDR; 74 if (block < (inode->i_sb->s_blocksize/sizeof(__u32))) { 75 bh = bread(inode->i_dev, inode->u.ufs_i.ui_ib[0], 76 BLOCK_SIZE); 77 if (bh == NULL) { 78 printk("ufs_bmap: can't map block %u, ino %lu\n", 79 block + UFS_NDADDR, inode->i_ino); 80 return(0); 81 } 82 phys_block = ((__u32 *)bh->b_data)[block]; 83 brelse(bh); 84 printk("ufs_bmap: imap ino %lu block %u phys %lu\n", 85 inode->i_ino, block + UFS_NDADDR, phys_block); 86 return(phys_block); 87 } else { 88 printk("ufs_bmap: ino %lu: indirect blocks not implemented\n", 89 inode->i_ino); 90 return(0); 91 } 92 } 93 94 return(0); 95 } 96 97 static struct file_operations ufs_file_operations = { 98 NULL, /* lseek */ 99 generic_file_read, /* read */ 100 NULL, /* write */ 101 NULL, /* readdir */ 102 NULL, /* select */ 103 NULL, /* ioctl */ 104 generic_file_mmap, /* mmap */ 105 NULL, /* open */ 106 NULL, /* release */ 107 file_fsync, /* fsync */ 108 NULL, /* fasync */ 109 NULL, /* check_media_change */ 110 NULL, /* revalidate */ 111 }; 112 113 struct inode_operations ufs_file_inode_operations = { 114 &ufs_file_operations, /* default directory file operations */ 115 NULL, /* create */ 116 NULL, /* lookup */ 117 NULL, /* link */ 118 NULL, /* unlink */ 119 NULL, /* symlink */ 120 NULL, /* mkdir */ 121 NULL, /* rmdir */ 122 NULL, /* mknod */ 123 NULL, /* rename */ 124 NULL, /* readlink */ 125 NULL, /* follow_link */ 126 generic_readpage, /* readpage */ 127 NULL, /* writepage */ 128 ufs_bmap, /* bmap */ 129 NULL, /* truncate */ 130 NULL, /* permission */ 131 NULL, /* smap */ 132 }; 133 134 135 /* 136 * Local Variables: *** 137 * c-indent-level: 8 *** 138 * c-continued-statement-offset: 8 *** 139 * c-brace-offset: -8 *** 140 * c-argdecl-indent: 0 *** 141 * c-label-offset: -8 *** 142 * End: *** 143 */