|
|
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:
11: #include <sys/dirent.h>
12:
13: #include <asm/segment.h>
14: #include <asm/system.h>
15:
1.1.1.3 ! root 16: #include <linux/fcntl.h>
1.1 root 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.