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