|
|
1.1 root 1: /*
2: * linux/fs/file_dev.c
3: *
4: * (C) 1991 Linus Torvalds
5: */
6:
7: #include <errno.h>
8: #include <fcntl.h>
1.1.1.3 ! root 9: #include <sys/dirent.h>
! 10: #include <sys/stat.h>
1.1 root 11:
12: #include <linux/sched.h>
13: #include <linux/minix_fs.h>
14: #include <linux/kernel.h>
15: #include <asm/segment.h>
16:
17: #define MIN(a,b) (((a)<(b))?(a):(b))
18: #define MAX(a,b) (((a)>(b))?(a):(b))
19:
1.1.1.3 ! root 20: int minix_readdir(struct inode * inode, struct file * filp, struct dirent * dirent)
! 21: {
! 22: unsigned int block,offset,i;
! 23: char c;
! 24: struct buffer_head * bh;
! 25: struct minix_dir_entry * de;
! 26:
! 27: if (!S_ISDIR(inode->i_mode))
! 28: return -EBADF;
! 29: if (filp->f_pos & 15)
! 30: return -EBADF;
! 31: while (filp->f_pos < inode->i_size) {
! 32: offset = filp->f_pos & 1023;
! 33: block = minix_bmap(inode,(filp->f_pos)>>BLOCK_SIZE_BITS);
! 34: if (!block || !(bh = bread(inode->i_dev,block))) {
! 35: filp->f_pos += 1024-offset;
! 36: continue;
! 37: }
! 38: de = (struct minix_dir_entry *) (offset + bh->b_data);
! 39: while (offset < 1024 && filp->f_pos < inode->i_size) {
! 40: offset += 16;
! 41: filp->f_pos += 16;
! 42: if (de->inode) {
! 43: for (i = 0; i < 14; i++)
! 44: if (c = de->name[i])
! 45: put_fs_byte(c,i+dirent->d_name);
! 46: else
! 47: break;
! 48: if (i) {
! 49: put_fs_long(de->inode,&dirent->d_ino);
! 50: put_fs_byte(0,i+dirent->d_name);
! 51: put_fs_word(i,&dirent->d_reclen);
! 52: brelse(bh);
! 53: return i;
! 54: }
! 55: }
! 56: de++;
! 57: }
! 58: brelse(bh);
! 59: }
! 60: return 0;
! 61: }
! 62:
1.1 root 63: int minix_file_read(struct inode * inode, struct file * filp, char * buf, int count)
64: {
65: int read,left,chars,nr;
66: struct buffer_head * bh;
67:
68: if (filp->f_pos > inode->i_size)
69: left = 0;
70: else
71: left = inode->i_size - filp->f_pos;
72: if (left > count)
73: left = count;
74: read = 0;
75: while (left > 0) {
1.1.1.3 ! root 76: if (nr = minix_bmap(inode,(filp->f_pos)>>BLOCK_SIZE_BITS)) {
1.1 root 77: if (!(bh=bread(inode->i_dev,nr)))
78: return read?read:-EIO;
79: } else
80: bh = NULL;
81: nr = filp->f_pos & (BLOCK_SIZE-1);
82: chars = MIN( BLOCK_SIZE-nr , left );
83: filp->f_pos += chars;
84: left -= chars;
85: read += chars;
86: if (bh) {
1.1.1.2 root 87: memcpy_tofs(buf,nr+bh->b_data,chars);
88: buf += chars;
1.1 root 89: brelse(bh);
90: } else {
91: while (chars-->0)
92: put_fs_byte(0,buf++);
93: }
94: }
95: inode->i_atime = CURRENT_TIME;
96: return read;
97: }
98:
99: int minix_file_write(struct inode * inode, struct file * filp, char * buf, int count)
100: {
101: off_t pos;
102: int written,block,c;
103: struct buffer_head * bh;
104: char * p;
105:
106: /*
107: * ok, append may not work when many processes are writing at the same time
108: * but so what. That way leads to madness anyway.
109: */
110: if (filp->f_flags & O_APPEND)
111: pos = inode->i_size;
112: else
113: pos = filp->f_pos;
114: written = 0;
115: while (written<count) {
116: if (!(block = minix_create_block(inode,pos/BLOCK_SIZE))) {
117: if (!written)
118: written = -ENOSPC;
119: break;
120: }
121: if (!(bh=bread(inode->i_dev,block))) {
122: if (!written)
123: written = -EIO;
124: break;
125: }
126: c = pos % BLOCK_SIZE;
127: p = c + bh->b_data;
128: c = BLOCK_SIZE-c;
129: if (c > count-written)
130: c = count-written;
131: pos += c;
132: if (pos > inode->i_size) {
133: inode->i_size = pos;
134: inode->i_dirt = 1;
135: }
136: written += c;
1.1.1.2 root 137: memcpy_fromfs(p,buf,c);
138: buf += c;
139: bh->b_dirt = 1;
1.1 root 140: brelse(bh);
141: }
142: inode->i_mtime = CURRENT_TIME;
143: if (!(filp->f_flags & O_APPEND)) {
144: filp->f_pos = pos;
145: inode->i_ctime = CURRENT_TIME;
146: }
1.1.1.3 ! root 147: inode->i_dirt = 1;
1.1 root 148: return written;
149: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.