|
|
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:
1.1.1.5 ! root 27: static inline void wait_on_buffer(struct buffer_head * bh)
! 28: {
! 29: cli();
! 30: while (bh->b_lock)
! 31: sleep_on(&bh->b_wait);
! 32: sti();
! 33: }
! 34:
1.1 root 35: int minix_file_read(struct inode *, struct file *, char *, int);
36: static int minix_file_write(struct inode *, struct file *, char *, int);
37:
38: /*
39: * We have mostly NULL's here: the current defaults are ok for
40: * the minix filesystem.
41: */
42: static struct file_operations minix_file_operations = {
43: NULL, /* lseek - default */
44: minix_file_read, /* read */
45: minix_file_write, /* write */
46: NULL, /* readdir - bad */
47: NULL, /* select - default */
48: NULL, /* ioctl - default */
49: NULL, /* no special open is needed */
50: NULL /* release */
51: };
52:
53: struct inode_operations minix_file_inode_operations = {
54: &minix_file_operations, /* default file operations */
55: NULL, /* create */
56: NULL, /* lookup */
57: NULL, /* link */
58: NULL, /* unlink */
59: NULL, /* symlink */
60: NULL, /* mkdir */
61: NULL, /* rmdir */
62: NULL, /* mknod */
63: NULL, /* rename */
64: NULL, /* readlink */
65: NULL, /* follow_link */
66: minix_bmap, /* bmap */
67: minix_truncate /* truncate */
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: {
1.1.1.5 ! root 78: int read,left,chars;
1.1 root 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;
1.1.1.5 ! root 107: *bhb = minix_getblk(inode,block++,0);
! 108: if (*bhb && !(*bhb)->b_uptodate)
! 109: ll_rw_block(READ,*bhb);
1.1 root 110:
111: if (++bhb == &buflist[NBUF])
112: bhb = buflist;
113:
114: if (bhb != bhe)
115: continue;
116: }
117: if (*bhe) {
118: wait_on_buffer(*bhe);
119: if (!(*bhe)->b_uptodate) {
120: do {
121: brelse(*bhe);
122: if (++bhe == &buflist[NBUF])
123: bhe = buflist;
124: } while (bhe != bhb);
125: break;
126: }
127: }
128:
129: if (left < BLOCK_SIZE - offset)
130: chars = left;
131: else
132: chars = BLOCK_SIZE - offset;
133: filp->f_pos += chars;
134: left -= chars;
135: read += chars;
136: if (*bhe) {
137: memcpy_tofs(buf,offset+(*bhe)->b_data,chars);
138: brelse(*bhe);
139: buf += chars;
140: } else {
141: while (chars-->0)
142: put_fs_byte(0,buf++);
143: }
144: offset = 0;
145: if (++bhe == &buflist[NBUF])
146: bhe = buflist;
147: } while (left > 0);
148: if (!read)
149: return -EIO;
1.1.1.4 root 150: if (!IS_RDONLY(inode)) {
151: inode->i_atime = CURRENT_TIME;
152: inode->i_dirt = 1;
153: }
1.1 root 154: return read;
155: }
156:
157: static int minix_file_write(struct inode * inode, struct file * filp, char * buf, int count)
158: {
159: off_t pos;
1.1.1.5 ! root 160: int written,c;
1.1 root 161: struct buffer_head * bh;
162: char * p;
163:
164: if (!inode) {
165: printk("minix_file_write: inode = NULL\n");
166: return -EINVAL;
167: }
168: if (!S_ISREG(inode->i_mode)) {
169: printk("minix_file_write: mode = %07o\n",inode->i_mode);
170: return -EINVAL;
171: }
172: /*
173: * ok, append may not work when many processes are writing at the same time
174: * but so what. That way leads to madness anyway.
175: */
176: if (filp->f_flags & O_APPEND)
177: pos = inode->i_size;
178: else
179: pos = filp->f_pos;
180: written = 0;
181: while (written<count) {
1.1.1.5 ! root 182: bh = minix_getblk(inode,pos/BLOCK_SIZE,1);
! 183: if (!bh) {
1.1 root 184: if (!written)
185: written = -ENOSPC;
186: break;
187: }
188: c = BLOCK_SIZE - (pos % BLOCK_SIZE);
189: if (c > count-written)
190: c = count-written;
1.1.1.5 ! root 191: if (c != BLOCK_SIZE && !bh->b_uptodate) {
! 192: ll_rw_block(READ,bh);
! 193: wait_on_buffer(bh);
! 194: if (!bh->b_uptodate) {
! 195: brelse(bh);
! 196: if (!written)
! 197: written = -EIO;
! 198: break;
! 199: }
1.1 root 200: }
201: p = (pos % BLOCK_SIZE) + bh->b_data;
202: pos += c;
203: if (pos > inode->i_size) {
204: inode->i_size = pos;
205: inode->i_dirt = 1;
206: }
207: written += c;
208: memcpy_fromfs(p,buf,c);
209: buf += c;
210: bh->b_uptodate = 1;
211: bh->b_dirt = 1;
212: brelse(bh);
213: }
214: inode->i_mtime = CURRENT_TIME;
1.1.1.2 root 215: inode->i_ctime = CURRENT_TIME;
216: filp->f_pos = pos;
1.1 root 217: inode->i_dirt = 1;
218: return written;
219: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.