This source file includes following definitions.
- nfs_dir_read
- nfs_readdir
- nfs_lookup_cache_index
- nfs_lookup_cache_lookup
- nfs_lookup_cache_add
- nfs_lookup_cache_remove
- nfs_lookup_cache_refresh
- nfs_lookup
- nfs_create
- nfs_mknod
- nfs_mkdir
- nfs_rmdir
- nfs_unlink
- nfs_symlink
- nfs_link
- nfs_rename
- nfs_refresh_inode
1
2
3
4
5
6
7
8
9 #ifdef MODULE
10 #include <linux/module.h>
11 #endif
12
13 #include <linux/sched.h>
14 #include <linux/errno.h>
15 #include <linux/stat.h>
16 #include <linux/nfs_fs.h>
17 #include <linux/fcntl.h>
18 #include <linux/string.h>
19 #include <linux/kernel.h>
20 #include <linux/malloc.h>
21 #include <linux/mm.h>
22
23 #include <asm/segment.h>
24
25 static int nfs_dir_read(struct inode *, struct file *filp, char *buf,
26 int count);
27 static int nfs_readdir(struct inode *, struct file *, void *, filldir_t);
28 static int nfs_lookup(struct inode *dir, const char *name, int len,
29 struct inode **result);
30 static int nfs_create(struct inode *dir, const char *name, int len, int mode,
31 struct inode **result);
32 static int nfs_mkdir(struct inode *dir, const char *name, int len, int mode);
33 static int nfs_rmdir(struct inode *dir, const char *name, int len);
34 static int nfs_unlink(struct inode *dir, const char *name, int len);
35 static int nfs_symlink(struct inode *inode, const char *name, int len,
36 const char *symname);
37 static int nfs_link(struct inode *oldinode, struct inode *dir,
38 const char *name, int len);
39 static int nfs_mknod(struct inode *dir, const char *name, int len, int mode,
40 int rdev);
41 static int nfs_rename(struct inode *old_dir, const char *old_name,
42 int old_len, struct inode *new_dir, const char *new_name,
43 int new_len);
44
45 static struct file_operations nfs_dir_operations = {
46 NULL,
47 nfs_dir_read,
48 NULL,
49 nfs_readdir,
50 NULL,
51 NULL,
52 NULL,
53 NULL,
54 NULL,
55 NULL
56 };
57
58 struct inode_operations nfs_dir_inode_operations = {
59 &nfs_dir_operations,
60 nfs_create,
61 nfs_lookup,
62 nfs_link,
63 nfs_unlink,
64 nfs_symlink,
65 nfs_mkdir,
66 nfs_rmdir,
67 nfs_mknod,
68 nfs_rename,
69 NULL,
70 NULL,
71 NULL,
72 NULL,
73 NULL
74 };
75
76 static int nfs_dir_read(struct inode *inode, struct file *filp, char *buf,
77 int count)
78 {
79 return -EISDIR;
80 }
81
82
83
84
85
86
87
88
89
90 static int nfs_readdir(struct inode *inode, struct file *filp,
91 void *dirent, filldir_t filldir)
92 {
93 static int c_dev = 0;
94 static int c_ino;
95 static int c_size;
96 static struct nfs_entry *c_entry = NULL;
97
98 int result;
99 int i, index = 0;
100 struct nfs_entry *entry;
101
102 if (!inode || !S_ISDIR(inode->i_mode)) {
103 printk("nfs_readdir: inode is NULL or not a directory\n");
104 return -EBADF;
105 }
106
107
108
109 if (c_entry == NULL) {
110 i = sizeof (struct nfs_entry)*NFS_READDIR_CACHE_SIZE;
111 c_entry = (struct nfs_entry *) kmalloc(i, GFP_KERNEL);
112 for (i = 0; i < NFS_READDIR_CACHE_SIZE; i++) {
113 c_entry[i].name = (char *) kmalloc(NFS_MAXNAMLEN + 1,
114 GFP_KERNEL);
115 }
116 }
117 entry = NULL;
118
119
120
121 if (inode->i_dev == c_dev && inode->i_ino == c_ino) {
122 for (i = 0; i < c_size; i++) {
123 if (filp->f_pos == c_entry[i].cookie) {
124 if (i == c_size - 1) {
125 if (c_entry[i].eof)
126 return 0;
127 }
128 else
129 entry = c_entry + (index = i + 1);
130 break;
131 }
132 }
133 }
134
135
136
137 if (!entry) {
138 result = nfs_proc_readdir(NFS_SERVER(inode), NFS_FH(inode),
139 filp->f_pos, NFS_READDIR_CACHE_SIZE, c_entry);
140 if (result < 0) {
141 c_dev = 0;
142 return result;
143 }
144 if (result > 0) {
145 c_dev = inode->i_dev;
146 c_ino = inode->i_ino;
147 c_size = result;
148 entry = c_entry + (index = 0);
149 }
150 }
151
152
153 if (!entry)
154 return 0;
155 while (index < c_size) {
156 int nextpos = entry->cookie;
157 if (filldir(dirent, entry->name, strlen(entry->name), filp->f_pos, entry->fileid) < 0)
158 break;
159 filp->f_pos = nextpos;
160
161 if (inode->i_dev != c_dev)
162 break;
163 if (inode->i_ino != c_ino)
164 break;
165 if (nextpos != entry->cookie)
166 break;
167 index++;
168 entry++;
169 }
170 return 0;
171 }
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186 static struct nfs_lookup_cache_entry {
187 int dev;
188 int inode;
189 char filename[NFS_MAXNAMLEN + 1];
190 struct nfs_fh fhandle;
191 struct nfs_fattr fattr;
192 int expiration_date;
193 } nfs_lookup_cache[NFS_LOOKUP_CACHE_SIZE];
194
195 static struct nfs_lookup_cache_entry *nfs_lookup_cache_index(struct inode *dir,
196 const char *filename)
197 {
198 struct nfs_lookup_cache_entry *entry;
199 int i;
200
201 for (i = 0; i < NFS_LOOKUP_CACHE_SIZE; i++) {
202 entry = nfs_lookup_cache + i;
203 if (entry->dev == dir->i_dev && entry->inode == dir->i_ino
204 && !strncmp(filename, entry->filename, NFS_MAXNAMLEN))
205 return entry;
206 }
207 return NULL;
208 }
209
210 static int nfs_lookup_cache_lookup(struct inode *dir, const char *filename,
211 struct nfs_fh *fhandle,
212 struct nfs_fattr *fattr)
213 {
214 static int nfs_lookup_cache_in_use = 0;
215
216 struct nfs_lookup_cache_entry *entry;
217
218 if (!nfs_lookup_cache_in_use) {
219 memset(nfs_lookup_cache, 0, sizeof(nfs_lookup_cache));
220 nfs_lookup_cache_in_use = 1;
221 }
222 if ((entry = nfs_lookup_cache_index(dir, filename))) {
223 if (jiffies > entry->expiration_date) {
224 entry->dev = 0;
225 return 0;
226 }
227 *fhandle = entry->fhandle;
228 *fattr = entry->fattr;
229 return 1;
230 }
231 return 0;
232 }
233
234 static void nfs_lookup_cache_add(struct inode *dir, const char *filename,
235 struct nfs_fh *fhandle,
236 struct nfs_fattr *fattr)
237 {
238 static int nfs_lookup_cache_pos = 0;
239 struct nfs_lookup_cache_entry *entry;
240
241
242 if (fattr->size == -1 || fattr->uid == -1 || fattr->gid == -1
243 || fattr->atime.seconds == -1 || fattr->mtime.seconds == -1)
244 return;
245 if (!(entry = nfs_lookup_cache_index(dir, filename))) {
246 entry = nfs_lookup_cache + nfs_lookup_cache_pos++;
247 if (nfs_lookup_cache_pos == NFS_LOOKUP_CACHE_SIZE)
248 nfs_lookup_cache_pos = 0;
249 }
250 entry->dev = dir->i_dev;
251 entry->inode = dir->i_ino;
252 strcpy(entry->filename, filename);
253 entry->fhandle = *fhandle;
254 entry->fattr = *fattr;
255 entry->expiration_date = jiffies + (S_ISDIR(fattr->mode)
256 ? NFS_SERVER(dir)->acdirmax : NFS_SERVER(dir)->acregmax);
257 }
258
259 static void nfs_lookup_cache_remove(struct inode *dir, struct inode *inode,
260 const char *filename)
261 {
262 struct nfs_lookup_cache_entry *entry;
263 int dev;
264 int fileid;
265 int i;
266
267 if (inode) {
268 dev = inode->i_dev;
269 fileid = inode->i_ino;
270 }
271 else if ((entry = nfs_lookup_cache_index(dir, filename))) {
272 dev = entry->dev;
273 fileid = entry->fattr.fileid;
274 }
275 else
276 return;
277 for (i = 0; i < NFS_LOOKUP_CACHE_SIZE; i++) {
278 entry = nfs_lookup_cache + i;
279 if (entry->dev == dev && entry->fattr.fileid == fileid)
280 entry->dev = 0;
281 }
282 }
283
284 static void nfs_lookup_cache_refresh(struct inode *file,
285 struct nfs_fattr *fattr)
286 {
287 struct nfs_lookup_cache_entry *entry;
288 int dev = file->i_dev;
289 int fileid = file->i_ino;
290 int i;
291
292 for (i = 0; i < NFS_LOOKUP_CACHE_SIZE; i++) {
293 entry = nfs_lookup_cache + i;
294 if (entry->dev == dev && entry->fattr.fileid == fileid)
295 entry->fattr = *fattr;
296 }
297 }
298
299 static int nfs_lookup(struct inode *dir, const char *__name, int len,
300 struct inode **result)
301 {
302 struct nfs_fh fhandle;
303 struct nfs_fattr fattr;
304 char name[len > NFS_MAXNAMLEN? 1 : len+1];
305 int error;
306
307 *result = NULL;
308 if (!dir || !S_ISDIR(dir->i_mode)) {
309 printk("nfs_lookup: inode is NULL or not a directory\n");
310 iput(dir);
311 return -ENOENT;
312 }
313 if (len > NFS_MAXNAMLEN) {
314 iput(dir);
315 return -ENAMETOOLONG;
316 }
317 memcpy(name,__name,len);
318 name[len] = '\0';
319 if (len == 1 && name[0] == '.') {
320 *result = dir;
321 return 0;
322 }
323 if ((NFS_SERVER(dir)->flags & NFS_MOUNT_NOAC)
324 || !nfs_lookup_cache_lookup(dir, name, &fhandle, &fattr)) {
325 if ((error = nfs_proc_lookup(NFS_SERVER(dir), NFS_FH(dir),
326 name, &fhandle, &fattr))) {
327 iput(dir);
328 return error;
329 }
330 nfs_lookup_cache_add(dir, name, &fhandle, &fattr);
331 }
332 if (!(*result = nfs_fhget(dir->i_sb, &fhandle, &fattr))) {
333 iput(dir);
334 return -EACCES;
335 }
336 iput(dir);
337 return 0;
338 }
339
340 static int nfs_create(struct inode *dir, const char *name, int len, int mode,
341 struct inode **result)
342 {
343 struct nfs_sattr sattr;
344 struct nfs_fattr fattr;
345 struct nfs_fh fhandle;
346 int error;
347
348 *result = NULL;
349 if (!dir || !S_ISDIR(dir->i_mode)) {
350 printk("nfs_create: inode is NULL or not a directory\n");
351 iput(dir);
352 return -ENOENT;
353 }
354 if (len > NFS_MAXNAMLEN) {
355 iput(dir);
356 return -ENAMETOOLONG;
357 }
358 sattr.mode = mode;
359 sattr.uid = sattr.gid = sattr.size = (unsigned) -1;
360 sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1;
361 if ((error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dir),
362 name, &sattr, &fhandle, &fattr))) {
363 iput(dir);
364 return error;
365 }
366 if (!(*result = nfs_fhget(dir->i_sb, &fhandle, &fattr))) {
367 iput(dir);
368 return -EACCES;
369 }
370 nfs_lookup_cache_add(dir, name, &fhandle, &fattr);
371 iput(dir);
372 return 0;
373 }
374
375 static int nfs_mknod(struct inode *dir, const char *name, int len,
376 int mode, int rdev)
377 {
378 struct nfs_sattr sattr;
379 struct nfs_fattr fattr;
380 struct nfs_fh fhandle;
381 int error;
382
383 if (!dir || !S_ISDIR(dir->i_mode)) {
384 printk("nfs_mknod: inode is NULL or not a directory\n");
385 iput(dir);
386 return -ENOENT;
387 }
388 if (len > NFS_MAXNAMLEN) {
389 iput(dir);
390 return -ENAMETOOLONG;
391 }
392 sattr.mode = mode;
393 sattr.uid = sattr.gid = (unsigned) -1;
394 if (S_ISCHR(mode) || S_ISBLK(mode))
395 sattr.size = rdev;
396 else
397 sattr.size = (unsigned) -1;
398 sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1;
399 error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dir),
400 name, &sattr, &fhandle, &fattr);
401 if (!error)
402 nfs_lookup_cache_add(dir, name, &fhandle, &fattr);
403 iput(dir);
404 return error;
405 }
406
407 static int nfs_mkdir(struct inode *dir, const char *name, int len, int mode)
408 {
409 struct nfs_sattr sattr;
410 struct nfs_fattr fattr;
411 struct nfs_fh fhandle;
412 int error;
413
414 if (!dir || !S_ISDIR(dir->i_mode)) {
415 printk("nfs_mkdir: inode is NULL or not a directory\n");
416 iput(dir);
417 return -ENOENT;
418 }
419 if (len > NFS_MAXNAMLEN) {
420 iput(dir);
421 return -ENAMETOOLONG;
422 }
423 sattr.mode = mode;
424 sattr.uid = sattr.gid = sattr.size = (unsigned) -1;
425 sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1;
426 error = nfs_proc_mkdir(NFS_SERVER(dir), NFS_FH(dir),
427 name, &sattr, &fhandle, &fattr);
428 if (!error)
429 nfs_lookup_cache_add(dir, name, &fhandle, &fattr);
430 iput(dir);
431 return error;
432 }
433
434 static int nfs_rmdir(struct inode *dir, const char *name, int len)
435 {
436 int error;
437
438 if (!dir || !S_ISDIR(dir->i_mode)) {
439 printk("nfs_rmdir: inode is NULL or not a directory\n");
440 iput(dir);
441 return -ENOENT;
442 }
443 if (len > NFS_MAXNAMLEN) {
444 iput(dir);
445 return -ENAMETOOLONG;
446 }
447 error = nfs_proc_rmdir(NFS_SERVER(dir), NFS_FH(dir), name);
448 if (!error)
449 nfs_lookup_cache_remove(dir, NULL, name);
450 iput(dir);
451 return error;
452 }
453
454 static int nfs_unlink(struct inode *dir, const char *name, int len)
455 {
456 int error;
457
458 if (!dir || !S_ISDIR(dir->i_mode)) {
459 printk("nfs_unlink: inode is NULL or not a directory\n");
460 iput(dir);
461 return -ENOENT;
462 }
463 if (len > NFS_MAXNAMLEN) {
464 iput(dir);
465 return -ENAMETOOLONG;
466 }
467 error = nfs_proc_remove(NFS_SERVER(dir), NFS_FH(dir), name);
468 if (!error)
469 nfs_lookup_cache_remove(dir, NULL, name);
470 iput(dir);
471 return error;
472 }
473
474 static int nfs_symlink(struct inode *dir, const char *name, int len,
475 const char *symname)
476 {
477 struct nfs_sattr sattr;
478 int error;
479
480 if (!dir || !S_ISDIR(dir->i_mode)) {
481 printk("nfs_symlink: inode is NULL or not a directory\n");
482 iput(dir);
483 return -ENOENT;
484 }
485 if (len > NFS_MAXNAMLEN) {
486 iput(dir);
487 return -ENAMETOOLONG;
488 }
489 if (strlen(symname) > NFS_MAXPATHLEN) {
490 iput(dir);
491 return -ENAMETOOLONG;
492 }
493 sattr.mode = S_IFLNK | S_IRWXUGO;
494 sattr.uid = sattr.gid = sattr.size = (unsigned) -1;
495 sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1;
496 error = nfs_proc_symlink(NFS_SERVER(dir), NFS_FH(dir),
497 name, symname, &sattr);
498 iput(dir);
499 return error;
500 }
501
502 static int nfs_link(struct inode *oldinode, struct inode *dir,
503 const char *name, int len)
504 {
505 int error;
506
507 if (!oldinode) {
508 printk("nfs_link: old inode is NULL\n");
509 iput(oldinode);
510 iput(dir);
511 return -ENOENT;
512 }
513 if (!dir || !S_ISDIR(dir->i_mode)) {
514 printk("nfs_link: dir is NULL or not a directory\n");
515 iput(oldinode);
516 iput(dir);
517 return -ENOENT;
518 }
519 if (len > NFS_MAXNAMLEN) {
520 iput(oldinode);
521 iput(dir);
522 return -ENAMETOOLONG;
523 }
524 error = nfs_proc_link(NFS_SERVER(oldinode), NFS_FH(oldinode),
525 NFS_FH(dir), name);
526 if (!error)
527 nfs_lookup_cache_remove(dir, oldinode, NULL);
528 iput(oldinode);
529 iput(dir);
530 return error;
531 }
532
533 static int nfs_rename(struct inode *old_dir, const char *old_name, int old_len,
534 struct inode *new_dir, const char *new_name, int new_len)
535 {
536 int error;
537
538 if (!old_dir || !S_ISDIR(old_dir->i_mode)) {
539 printk("nfs_rename: old inode is NULL or not a directory\n");
540 iput(old_dir);
541 iput(new_dir);
542 return -ENOENT;
543 }
544 if (!new_dir || !S_ISDIR(new_dir->i_mode)) {
545 printk("nfs_rename: new inode is NULL or not a directory\n");
546 iput(old_dir);
547 iput(new_dir);
548 return -ENOENT;
549 }
550 if (old_len > NFS_MAXNAMLEN || new_len > NFS_MAXNAMLEN) {
551 iput(old_dir);
552 iput(new_dir);
553 return -ENAMETOOLONG;
554 }
555 error = nfs_proc_rename(NFS_SERVER(old_dir),
556 NFS_FH(old_dir), old_name,
557 NFS_FH(new_dir), new_name);
558 if (!error) {
559 nfs_lookup_cache_remove(old_dir, NULL, old_name);
560 nfs_lookup_cache_remove(new_dir, NULL, new_name);
561 }
562 iput(old_dir);
563 iput(new_dir);
564 return error;
565 }
566
567
568
569
570
571
572
573 void nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
574 {
575 int was_empty;
576
577 if (!inode || !fattr) {
578 printk("nfs_refresh_inode: inode or fattr is NULL\n");
579 return;
580 }
581 if (inode->i_ino != fattr->fileid) {
582 printk("nfs_refresh_inode: inode number mismatch\n");
583 return;
584 }
585 was_empty = inode->i_mode == 0;
586 inode->i_mode = fattr->mode;
587 inode->i_nlink = fattr->nlink;
588 inode->i_uid = fattr->uid;
589 inode->i_gid = fattr->gid;
590 inode->i_size = fattr->size;
591 inode->i_blksize = fattr->blocksize;
592 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
593 inode->i_rdev = fattr->rdev;
594 else
595 inode->i_rdev = 0;
596 inode->i_blocks = fattr->blocks;
597 inode->i_atime = fattr->atime.seconds;
598 inode->i_mtime = fattr->mtime.seconds;
599 inode->i_ctime = fattr->ctime.seconds;
600 if (was_empty) {
601 if (S_ISREG(inode->i_mode))
602 inode->i_op = &nfs_file_inode_operations;
603 else if (S_ISDIR(inode->i_mode))
604 inode->i_op = &nfs_dir_inode_operations;
605 else if (S_ISLNK(inode->i_mode))
606 inode->i_op = &nfs_symlink_inode_operations;
607 else if (S_ISCHR(inode->i_mode))
608 inode->i_op = &chrdev_inode_operations;
609 else if (S_ISBLK(inode->i_mode))
610 inode->i_op = &blkdev_inode_operations;
611 else if (S_ISFIFO(inode->i_mode))
612 init_fifo(inode);
613 else
614 inode->i_op = NULL;
615 }
616 nfs_lookup_cache_refresh(inode, fattr);
617 }
618