This source file includes following definitions.
- min
- smb_fsync
- smb_make_open
- smb_file_read
- smb_file_write
1
2
3
4
5
6
7
8 #include <asm/segment.h>
9 #include <asm/system.h>
10
11 #include <linux/sched.h>
12 #include <linux/kernel.h>
13 #include <linux/errno.h>
14 #include <linux/fcntl.h>
15 #include <linux/stat.h>
16 #include <linux/mm.h>
17 #include <linux/smb_fs.h>
18 #include <linux/malloc.h>
19
20 static inline int min(int a, int b)
21 {
22 return a<b ? a : b;
23 }
24
25 static int
26 smb_fsync(struct inode *inode, struct file *file)
27 {
28 return 0;
29 }
30
31 int
32 smb_make_open(struct inode *i, int right)
33 {
34 struct smb_dirent *dirent;
35 int open_result;
36
37 if (i == NULL) {
38 printk("smb_make_open: got NULL inode\n");
39 return -EINVAL;
40 }
41
42 dirent = &(SMB_INOP(i)->finfo);
43
44 DDPRINTK("smb_make_open: dirent->opened = %d\n", dirent->opened);
45
46 if ((dirent->opened) == 0) {
47
48 open_result = smb_proc_open(SMB_SERVER(i),
49 dirent->path, dirent->len,
50 dirent);
51 if (open_result)
52 return open_result;
53
54 dirent->opened = 1;
55 }
56
57 if ( ((right == O_RDONLY) && ( (dirent->access == O_RDONLY)
58 || (dirent->access == O_RDWR)))
59 || ((right == O_WRONLY) && ( (dirent->access == O_WRONLY)
60 || (dirent->access == O_RDWR)))
61 || ((right == O_RDWR) && (dirent->access == O_RDWR)))
62 return 0;
63
64 return -EACCES;
65 }
66
67 static int
68 smb_file_read(struct inode *inode, struct file *file, char *buf, int count)
69 {
70 int result, bufsize, to_read, already_read;
71 off_t pos;
72 int errno;
73
74 DPRINTK("smb_file_read: enter %s\n", SMB_FINFO(inode)->path);
75
76 if (!inode) {
77 DPRINTK("smb_file_read: inode = NULL\n");
78 return -EINVAL;
79 }
80
81 if (!S_ISREG(inode->i_mode)) {
82 DPRINTK("smb_file_read: read from non-file, mode %07o\n",
83 inode->i_mode);
84 return -EINVAL;
85 }
86
87 if ((errno = smb_make_open(inode, O_RDONLY)) != 0)
88 return errno;
89
90 pos = file->f_pos;
91
92 if (pos + count > inode->i_size)
93 count = inode->i_size - pos;
94
95 if (count <= 0)
96 return 0;
97 bufsize = SMB_SERVER(inode)->max_xmit - SMB_HEADER_LEN - 5 * 2 - 5;
98
99 already_read = 0;
100
101
102 while (already_read < count) {
103
104 result = 0;
105 to_read = 0;
106
107 if ((SMB_SERVER(inode)->blkmode & 1) != 0) {
108 to_read = min(65535, count - already_read);
109 DPRINTK("smb_file_read: Raw %d bytes\n", to_read);
110 result = smb_proc_read_raw(SMB_SERVER(inode),
111 SMB_FINFO(inode),
112 pos, to_read, buf);
113 DPRINTK("smb_file_read: returned %d\n", result);
114 }
115
116 if (result <= 0) {
117 to_read = min(bufsize, count - already_read);
118 result = smb_proc_read(SMB_SERVER(inode),
119 SMB_FINFO(inode),
120 pos, to_read, buf, 1);
121 }
122
123 if (result < 0)
124 return result;
125 pos += result;
126 buf += result;
127 already_read += result;
128
129 if (result < to_read) {
130 break;
131 }
132 }
133
134 file->f_pos = pos;
135
136 if (!IS_RDONLY(inode)) inode->i_atime = CURRENT_TIME;
137 inode->i_dirt = 1;
138
139 DPRINTK("smb_file_read: exit %s\n", SMB_FINFO(inode)->path);
140
141 return already_read;
142 }
143
144 static int
145 smb_file_write(struct inode *inode, struct file *file, const char *buf, int count)
146 {
147 int result, bufsize, to_write, already_written;
148 off_t pos;
149 int errno;
150
151 if (!inode) {
152 DPRINTK("smb_file_write: inode = NULL\n");
153 return -EINVAL;
154 }
155
156 if (!S_ISREG(inode->i_mode)) {
157 DPRINTK("smb_file_write: write to non-file, mode %07o\n",
158 inode->i_mode);
159 return -EINVAL;
160 }
161
162 DPRINTK("smb_file_write: enter %s\n", SMB_FINFO(inode)->path);
163
164 if (count <= 0)
165 return 0;
166
167 if ((errno = smb_make_open(inode, O_RDWR)) != 0)
168 return errno;
169
170 pos = file->f_pos;
171
172 if (file->f_flags & O_APPEND)
173 pos = inode->i_size;
174
175 bufsize = SMB_SERVER(inode)->max_xmit - SMB_HEADER_LEN - 5 * 2 - 5;
176
177 already_written = 0;
178
179 DPRINTK("smb_write_file: blkmode = %d, blkmode & 2 = %d\n",
180 SMB_SERVER(inode)->blkmode,
181 SMB_SERVER(inode)->blkmode & 2);
182
183 while (already_written < count) {
184
185 result = 0;
186 to_write = 0;
187
188 if ((SMB_SERVER(inode)->blkmode & 2) != 0) {
189 to_write = min(65535, count - already_written);
190 DPRINTK("smb_file_write: Raw %d bytes\n", to_write);
191 result = smb_proc_write_raw(SMB_SERVER(inode),
192 SMB_FINFO(inode),
193 pos, to_write, buf);
194 DPRINTK("smb_file_write: returned %d\n", result);
195 }
196
197 if (result <= 0) {
198 to_write = min(bufsize, count - already_written);
199 result = smb_proc_write(SMB_SERVER(inode),
200 SMB_FINFO(inode),
201 pos, to_write, buf);
202 }
203
204 if (result < 0)
205 return result;
206
207 pos += result;
208 buf += result;
209 already_written += result;
210
211 if (result < to_write) {
212 break;
213 }
214 }
215
216 inode->i_mtime = inode->i_ctime = CURRENT_TIME;
217 inode->i_dirt = 1;
218
219 file->f_pos = pos;
220
221 if (pos > inode->i_size) {
222 inode->i_size = pos;
223 }
224
225 DPRINTK("smb_file_write: exit %s\n", SMB_FINFO(inode)->path);
226
227 return already_written;
228 }
229
230 static struct file_operations smb_file_operations = {
231 NULL,
232 smb_file_read,
233 smb_file_write,
234 NULL,
235 NULL,
236 smb_ioctl,
237 smb_mmap,
238 NULL,
239 NULL,
240 smb_fsync,
241 };
242
243 struct inode_operations smb_file_inode_operations = {
244 &smb_file_operations,
245 NULL,
246 NULL,
247 NULL,
248 NULL,
249 NULL,
250 NULL,
251 NULL,
252 NULL,
253 NULL,
254 NULL,
255 NULL,
256 NULL,
257 NULL,
258 NULL,
259 NULL
260 };
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277