This source file includes following definitions.
- affs_smap
- affs_file_read
1
2
3
4
5
6
7
8
9
10
11
12
13 #include <asm/segment.h>
14 #include <asm/system.h>
15
16 #include <linux/sched.h>
17 #include <linux/affs_fs.h>
18 #include <linux/fcntl.h>
19 #include <linux/kernel.h>
20 #include <linux/errno.h>
21 #include <linux/stat.h>
22 #include <linux/locks.h>
23
24 #include <linux/dirent.h>
25
26 #define NBUF 16
27
28 #define MIN(a,b) (((a)<(b))?(a):(b))
29 #define MAX(a,b) (((a)>(b))?(a):(b))
30
31 #include <linux/fs.h>
32 #include <linux/affs_fs.h>
33
34 #include "amigaffs.h"
35
36 int affs_file_read(struct inode *, struct file *, char *, int);
37
38
39
40
41
42 struct file_operations affs_file_operations = {
43 NULL,
44 affs_file_read,
45 NULL,
46 NULL,
47 NULL,
48 NULL,
49 generic_file_mmap,
50 NULL,
51 NULL,
52 NULL
53 };
54
55 struct inode_operations affs_file_inode_operations = {
56 &affs_file_operations,
57 NULL,
58 NULL,
59 NULL,
60 NULL,
61 NULL,
62 NULL,
63 NULL,
64 NULL,
65 NULL,
66 NULL,
67 NULL,
68 NULL ,
69 NULL,
70 NULL
71 };
72
73 static int affs_smap(struct inode *inode, int block)
74 {
75 struct buffer_head *bh;
76 int key;
77 void *fh_data;
78
79
80 #define KEY_SLOTS_PER_BLOCK 72
81
82 #ifdef DEBUG
83 printk ("affs_smap: ino=%d block=%d\n", inode->i_ino, block);
84 #endif
85
86 if (block < 0) {
87 printk("affs_smap: block < 0");
88 return 0;
89 }
90
91 key = inode->i_ino;
92 for (;;) {
93 bh = affs_pread (inode, key, &fh_data);
94 if (!bh)
95 return 0;
96 if (block < KEY_SLOTS_PER_BLOCK)
97 break;
98 block -= KEY_SLOTS_PER_BLOCK;
99 key = affs_get_extension (AFFS_I2BSIZE (inode), fh_data);
100 #ifdef DEBUG
101 printk ("affs_smap: reading extension block %d\n", key);
102 #endif
103 brelse (bh);
104 }
105 key = affs_get_key_entry (AFFS_I2BSIZE (inode), fh_data,
106 (KEY_SLOTS_PER_BLOCK - 1) - block);
107 brelse (bh);
108
109 #ifdef DEBUG
110 printk ("affs_smap: key=%d\n", key);
111 #endif
112 return key;
113 }
114
115
116
117
118
119
120
121 int affs_file_read(struct inode * inode, struct file * filp,
122 char * buf, int count)
123 {
124 char *start;
125 int left, offset, size, sector;
126 struct buffer_head *bh;
127 void *data;
128
129 if (!inode) {
130 printk("affs_file_read: inode = NULL\n");
131 return -EINVAL;
132 }
133 if (!(S_ISREG(inode->i_mode))) {
134 #ifdef DEBUG
135 printk("affs_file_read: mode = %07o\n",inode->i_mode);
136 #endif
137 return -EINVAL;
138 }
139 if (filp->f_pos >= inode->i_size || count <= 0)
140 return 0;
141
142 start = buf;
143 for (;;) {
144 left = MIN (inode->i_size - filp->f_pos,
145 count - (buf - start));
146 if (!left)
147 break;
148 sector = affs_smap (inode, filp->f_pos >> AFFS_BLOCK_BITS);
149 if (!sector)
150 break;
151 offset = filp->f_pos & (AFFS_BLOCK_SIZE - 1);
152 bh = affs_pread (inode, sector, &data);
153 if (!bh)
154 break;
155 size = MIN (AFFS_BLOCK_SIZE - offset, left);
156 filp->f_pos += size;
157 memcpy_tofs (buf, data + offset, size);
158 buf += size;
159 brelse (bh);
160 }
161 if (start == buf)
162 return -EIO;
163 return buf - start;
164
165 #if 0
166 if (filp->f_pos == 0 && count > 0) {
167 put_fs_byte ('X', buf++);
168 filp->f_pos++;
169 return 1;
170 }
171 else
172 return 0;
173 #endif
174 }