|
|
1.1 root 1: /* 1.1.1.2 ! root 2: * linux/fs/minix/file.c 1.1 root 3: * 1.1.1.2 ! root 4: * (C) 1991 Linus Torvalds ! 5: * ! 6: * minix regular file handling primitives 1.1 root 7: */ 8: 9: #include <errno.h> 10: #include <fcntl.h> 11: 12: #include <sys/dirent.h> 13: 14: #include <asm/segment.h> 15: #include <asm/system.h> 16: 17: #include <linux/sched.h> 18: #include <linux/minix_fs.h> 19: #include <linux/kernel.h> 1.1.1.2 ! root 20: #include <linux/stat.h> 1.1 root 21: 22: #define NBUF 16 23: 24: #define MIN(a,b) (((a)<(b))?(a):(b)) 25: #define MAX(a,b) (((a)>(b))?(a):(b)) 26: 27: #include <linux/fs.h> 28: #include <linux/minix_fs.h> 29: 30: int minix_file_read(struct inode *, struct file *, char *, int); 31: static int minix_file_write(struct inode *, struct file *, char *, int); 32: 33: /* 34: * We have mostly NULL's here: the current defaults are ok for 35: * the minix filesystem. 36: */ 37: static struct file_operations minix_file_operations = { 38: NULL, /* lseek - default */ 39: minix_file_read, /* read */ 40: minix_file_write, /* write */ 41: NULL, /* readdir - bad */ 42: NULL, /* select - default */ 43: NULL, /* ioctl - default */ 44: NULL, /* no special open is needed */ 45: NULL /* release */ 46: }; 47: 48: struct inode_operations minix_file_inode_operations = { 49: &minix_file_operations, /* default file operations */ 50: NULL, /* create */ 51: NULL, /* lookup */ 52: NULL, /* link */ 53: NULL, /* unlink */ 54: NULL, /* symlink */ 55: NULL, /* mkdir */ 56: NULL, /* rmdir */ 57: NULL, /* mknod */ 58: NULL, /* rename */ 59: NULL, /* readlink */ 60: NULL, /* follow_link */ 61: minix_bmap, /* bmap */ 62: minix_truncate /* truncate */ 63: }; 64: 65: static inline void wait_on_buffer(struct buffer_head * bh) 66: { 67: cli(); 68: while (bh->b_lock) 69: sleep_on(&bh->b_wait); 70: sti(); 71: } 72: 73: /* 74: * minix_file_read() is also needed by the directory read-routine, 75: * so it's not static. NOTE! reading directories directly is a bad idea, 76: * but has to be supported for now for compatability reasons with older 77: * versions. 78: */ 79: int minix_file_read(struct inode * inode, struct file * filp, char * buf, int count) 80: { 81: int read,left,chars,nr; 82: int block, blocks, offset; 83: struct buffer_head ** bhb, ** bhe; 84: struct buffer_head * buflist[NBUF]; 85: 86: if (!inode) { 87: printk("minix_file_read: inode = NULL\n"); 88: return -EINVAL; 89: } 90: if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) { 91: printk("minix_file_read: mode = %07o\n",inode->i_mode); 92: return -EINVAL; 93: } 94: if (filp->f_pos > inode->i_size) 95: left = 0; 96: else 97: left = inode->i_size - filp->f_pos; 98: if (left > count) 99: left = count; 100: if (left <= 0) 101: return 0; 102: read = 0; 103: block = filp->f_pos >> BLOCK_SIZE_BITS; 104: offset = filp->f_pos & (BLOCK_SIZE-1); 105: blocks = (left + offset + BLOCK_SIZE - 1) / BLOCK_SIZE; 106: bhb = bhe = buflist; 107: do { 108: if (blocks) { 109: --blocks; 110: if (nr = minix_bmap(inode,block++)) { 111: *bhb = getblk(inode->i_dev,nr); 112: if (!(*bhb)->b_uptodate) 113: ll_rw_block(READ,*bhb); 114: } else 115: *bhb = NULL; 116: 117: if (++bhb == &buflist[NBUF]) 118: bhb = buflist; 119: 120: if (bhb != bhe) 121: continue; 122: } 123: if (*bhe) { 124: wait_on_buffer(*bhe); 125: if (!(*bhe)->b_uptodate) { 126: do { 127: brelse(*bhe); 128: if (++bhe == &buflist[NBUF]) 129: bhe = buflist; 130: } while (bhe != bhb); 131: break; 132: } 133: } 134: 135: if (left < BLOCK_SIZE - offset) 136: chars = left; 137: else 138: chars = BLOCK_SIZE - offset; 139: filp->f_pos += chars; 140: left -= chars; 141: read += chars; 142: if (*bhe) { 143: memcpy_tofs(buf,offset+(*bhe)->b_data,chars); 144: brelse(*bhe); 145: buf += chars; 146: } else { 147: while (chars-->0) 148: put_fs_byte(0,buf++); 149: } 150: offset = 0; 151: if (++bhe == &buflist[NBUF]) 152: bhe = buflist; 153: } while (left > 0); 154: if (!read) 155: return -EIO; 156: inode->i_atime = CURRENT_TIME; 157: inode->i_dirt = 1; 158: return read; 159: } 160: 161: static int minix_file_write(struct inode * inode, struct file * filp, char * buf, int count) 162: { 163: off_t pos; 164: int written,block,c; 165: struct buffer_head * bh; 166: char * p; 167: 168: if (!inode) { 169: printk("minix_file_write: inode = NULL\n"); 170: return -EINVAL; 171: } 172: if (!S_ISREG(inode->i_mode)) { 173: printk("minix_file_write: mode = %07o\n",inode->i_mode); 174: return -EINVAL; 175: } 176: /* 177: * ok, append may not work when many processes are writing at the same time 178: * but so what. That way leads to madness anyway. 179: */ 180: if (filp->f_flags & O_APPEND) 181: pos = inode->i_size; 182: else 183: pos = filp->f_pos; 184: written = 0; 185: while (written<count) { 186: if (!(block = minix_create_block(inode,pos/BLOCK_SIZE))) { 187: if (!written) 188: written = -ENOSPC; 189: break; 190: } 191: c = BLOCK_SIZE - (pos % BLOCK_SIZE); 192: if (c > count-written) 193: c = count-written; 194: if (c == BLOCK_SIZE) 195: bh = getblk(inode->i_dev, block); 196: else 197: bh = bread(inode->i_dev,block); 198: if (!bh) { 199: if (!written) 200: written = -EIO; 201: break; 202: } 203: p = (pos % BLOCK_SIZE) + bh->b_data; 204: pos += c; 205: if (pos > inode->i_size) { 206: inode->i_size = pos; 207: inode->i_dirt = 1; 208: } 209: written += c; 210: memcpy_fromfs(p,buf,c); 211: buf += c; 212: bh->b_uptodate = 1; 213: bh->b_dirt = 1; 214: brelse(bh); 215: } 216: inode->i_mtime = CURRENT_TIME; 1.1.1.2 ! root 217: inode->i_ctime = CURRENT_TIME; ! 218: filp->f_pos = pos; 1.1 root 219: inode->i_dirt = 1; 220: return written; 221: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.