clean
[linux-2.4.21-pre4.git] / fs / smbfs / dir.c
1 /*
2  *  dir.c
3  *
4  *  Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
5  *  Copyright (C) 1997 by Volker Lendecke
6  *
7  *  Please add a note about your changes to smbfs in the ChangeLog file.
8  */
9
10 #include <linux/sched.h>
11 #include <linux/errno.h>
12 #include <linux/kernel.h>
13 #include <linux/smp_lock.h>
14 #include <linux/ctype.h>
15
16 #include <linux/smb_fs.h>
17 #include <linux/smb_mount.h>
18 #include <linux/smbno.h>
19
20 #include "smb_debug.h"
21 #include "proto.h"
22
23 static int smb_readdir(struct file *, void *, filldir_t);
24 static int smb_dir_open(struct inode *, struct file *);
25
26 static struct dentry *smb_lookup(struct inode *, struct dentry *);
27 static int smb_create(struct inode *, struct dentry *, int);
28 static int smb_mkdir(struct inode *, struct dentry *, int);
29 static int smb_rmdir(struct inode *, struct dentry *);
30 static int smb_unlink(struct inode *, struct dentry *);
31 static int smb_rename(struct inode *, struct dentry *,
32                       struct inode *, struct dentry *);
33
34 struct file_operations smb_dir_operations =
35 {
36         read:           generic_read_dir,
37         readdir:        smb_readdir,
38         ioctl:          smb_ioctl,
39         open:           smb_dir_open,
40 };
41
42 struct inode_operations smb_dir_inode_operations =
43 {
44         create:         smb_create,
45         lookup:         smb_lookup,
46         unlink:         smb_unlink,
47         mkdir:          smb_mkdir,
48         rmdir:          smb_rmdir,
49         rename:         smb_rename,
50         revalidate:     smb_revalidate_inode,
51         setattr:        smb_notify_change,
52 };
53
54 /*
55  * Read a directory, using filldir to fill the dirent memory.
56  * smb_proc_readdir does the actual reading from the smb server.
57  *
58  * The cache code is almost directly taken from ncpfs
59  */
60 static int 
61 smb_readdir(struct file *filp, void *dirent, filldir_t filldir)
62 {
63         struct dentry *dentry = filp->f_dentry;
64         struct inode *dir = dentry->d_inode;
65         struct smb_sb_info *server = server_from_dentry(dentry);
66         union  smb_dir_cache *cache = NULL;
67         struct smb_cache_control ctl;
68         struct page *page = NULL;
69         int result;
70
71         ctl.page  = NULL;
72         ctl.cache = NULL;
73
74         VERBOSE("reading %s/%s, f_pos=%d\n",
75                 DENTRY_PATH(dentry),  (int) filp->f_pos);
76
77         result = 0;
78         switch ((unsigned int) filp->f_pos) {
79         case 0:
80                 if (filldir(dirent, ".", 1, 0, dir->i_ino, DT_DIR) < 0)
81                         goto out;
82                 filp->f_pos = 1;
83                 /* fallthrough */
84         case 1:
85                 if (filldir(dirent, "..", 2, 1,
86                             dentry->d_parent->d_inode->i_ino, DT_DIR) < 0)
87                         goto out;
88                 filp->f_pos = 2;
89         }
90
91         /*
92          * Make sure our inode is up-to-date.
93          */
94         result = smb_revalidate_inode(dentry);
95         if (result)
96                 goto out;
97
98
99         page = grab_cache_page(&dir->i_data, 0);
100         if (!page)
101                 goto read_really;
102
103         ctl.cache = cache = kmap(page);
104         ctl.head  = cache->head;
105
106         if (!Page_Uptodate(page) || !ctl.head.eof) {
107                 VERBOSE("%s/%s, page uptodate=%d, eof=%d\n",
108                          DENTRY_PATH(dentry), Page_Uptodate(page),ctl.head.eof);
109                 goto init_cache;
110         }
111
112         if (filp->f_pos == 2) {
113                 if (jiffies - ctl.head.time >= SMB_MAX_AGE(server))
114                         goto init_cache;
115
116                 /*
117                  * N.B. ncpfs checks mtime of dentry too here, we don't.
118                  *   1. common smb servers do not update mtime on dir changes
119                  *   2. it requires an extra smb request
120                  *      (revalidate has the same timeout as ctl.head.time)
121                  *
122                  * Instead smbfs invalidates its own cache on local changes
123                  * and remote changes are not seen until timeout.
124                  */
125         }
126
127         if (filp->f_pos > ctl.head.end)
128                 goto finished;
129
130         ctl.fpos = filp->f_pos + (SMB_DIRCACHE_START - 2);
131         ctl.ofs  = ctl.fpos / SMB_DIRCACHE_SIZE;
132         ctl.idx  = ctl.fpos % SMB_DIRCACHE_SIZE;
133
134         for (;;) {
135                 if (ctl.ofs != 0) {
136                         ctl.page = find_lock_page(&dir->i_data, ctl.ofs);
137                         if (!ctl.page)
138                                 goto invalid_cache;
139                         ctl.cache = kmap(ctl.page);
140                         if (!Page_Uptodate(ctl.page))
141                                 goto invalid_cache;
142                 }
143                 while (ctl.idx < SMB_DIRCACHE_SIZE) {
144                         struct dentry *dent;
145                         int res;
146
147                         dent = smb_dget_fpos(ctl.cache->dentry[ctl.idx],
148                                              dentry, filp->f_pos);
149                         if (!dent)
150                                 goto invalid_cache;
151
152                         res = filldir(dirent, dent->d_name.name,
153                                       dent->d_name.len, filp->f_pos,
154                                       dent->d_inode->i_ino, DT_UNKNOWN);
155                         dput(dent);
156                         if (res)
157                                 goto finished;
158                         filp->f_pos += 1;
159                         ctl.idx += 1;
160                         if (filp->f_pos > ctl.head.end)
161                                 goto finished;
162                 }
163                 if (ctl.page) {
164                         kunmap(ctl.page);
165                         SetPageUptodate(ctl.page);
166                         UnlockPage(ctl.page);
167                         page_cache_release(ctl.page);
168                         ctl.page = NULL;
169                 }
170                 ctl.idx  = 0;
171                 ctl.ofs += 1;
172         }
173 invalid_cache:
174         if (ctl.page) {
175                 kunmap(ctl.page);
176                 UnlockPage(ctl.page);
177                 page_cache_release(ctl.page);
178                 ctl.page = NULL;
179         }
180         ctl.cache = cache;
181 init_cache:
182         smb_invalidate_dircache_entries(dentry);
183         ctl.head.time = jiffies;
184         ctl.head.eof = 0;
185         ctl.fpos = 2;
186         ctl.ofs = 0;
187         ctl.idx = SMB_DIRCACHE_START;
188         ctl.filled = 0;
189         ctl.valid  = 1;
190 read_really:
191         result = smb_proc_readdir(filp, dirent, filldir, &ctl);
192         if (ctl.idx == -1)
193                 goto invalid_cache;     /* retry */
194         ctl.head.end = ctl.fpos - 1;
195         ctl.head.eof = ctl.valid;
196 finished:
197         if (page) {
198                 cache->head = ctl.head;
199                 kunmap(page);
200                 SetPageUptodate(page);
201                 UnlockPage(page);
202                 page_cache_release(page);
203         }
204         if (ctl.page) {
205                 kunmap(ctl.page);
206                 SetPageUptodate(ctl.page);
207                 UnlockPage(ctl.page);
208                 page_cache_release(ctl.page);
209         }
210 out:
211         return result;
212 }
213
214 static int
215 smb_dir_open(struct inode *dir, struct file *file)
216 {
217         struct dentry *dentry = file->f_dentry;
218         struct smb_sb_info *server;
219         int error = 0;
220
221         VERBOSE("(%s/%s)\n", dentry->d_parent->d_name.name,
222                 file->f_dentry->d_name.name);
223
224         /*
225          * Directory timestamps in the core protocol aren't updated
226          * when a file is added, so we give them a very short TTL.
227          */
228         lock_kernel();
229         server = server_from_dentry(dentry);
230         if (server->opt.protocol < SMB_PROTOCOL_LANMAN2) {
231                 unsigned long age = jiffies - dir->u.smbfs_i.oldmtime;
232                 if (age > 2*HZ)
233                         smb_invalid_dir_cache(dir);
234         }
235
236         /*
237          * Note: in order to allow the smbmount process to open the
238          * mount point, we only revalidate if the connection is valid or
239          * if the process is trying to access something other than the root.
240          */
241         if (server->state == CONN_VALID || !IS_ROOT(dentry))
242                 error = smb_revalidate_inode(dentry);
243         unlock_kernel();
244         return error;
245 }
246
247 /*
248  * Dentry operations routines
249  */
250 static int smb_lookup_validate(struct dentry *, int);
251 static int smb_hash_dentry(struct dentry *, struct qstr *);
252 static int smb_compare_dentry(struct dentry *, struct qstr *, struct qstr *);
253 static int smb_delete_dentry(struct dentry *);
254
255 static struct dentry_operations smbfs_dentry_operations =
256 {
257         d_revalidate:   smb_lookup_validate,
258         d_hash:         smb_hash_dentry,
259         d_compare:      smb_compare_dentry,
260         d_delete:       smb_delete_dentry,
261 };
262
263 static struct dentry_operations smbfs_dentry_operations_case =
264 {
265         d_revalidate:   smb_lookup_validate,
266         d_delete:       smb_delete_dentry,
267 };
268
269
270 /*
271  * This is the callback when the dcache has a lookup hit.
272  */
273 static int
274 smb_lookup_validate(struct dentry * dentry, int flags)
275 {
276         struct smb_sb_info *server = server_from_dentry(dentry);
277         struct inode * inode = dentry->d_inode;
278         unsigned long age = jiffies - dentry->d_time;
279         int valid;
280
281         /*
282          * The default validation is based on dentry age:
283          * we believe in dentries for a few seconds.  (But each
284          * successful server lookup renews the timestamp.)
285          */
286         valid = (age <= SMB_MAX_AGE(server));
287 #ifdef SMBFS_DEBUG_VERBOSE
288         if (!valid)
289                 VERBOSE("%s/%s not valid, age=%lu\n", 
290                         DENTRY_PATH(dentry), age);
291 #endif
292
293         if (inode) {
294                 lock_kernel();
295                 if (is_bad_inode(inode)) {
296                         PARANOIA("%s/%s has dud inode\n", DENTRY_PATH(dentry));
297                         valid = 0;
298                 } else if (!valid)
299                         valid = (smb_revalidate_inode(dentry) == 0);
300                 unlock_kernel();
301         } else {
302                 /*
303                  * What should we do for negative dentries?
304                  */
305         }
306         return valid;
307 }
308
309 static int 
310 smb_hash_dentry(struct dentry *dir, struct qstr *this)
311 {
312         unsigned long hash;
313         int i;
314
315         hash = init_name_hash();
316         for (i=0; i < this->len ; i++)
317                 hash = partial_name_hash(tolower(this->name[i]), hash);
318         this->hash = end_name_hash(hash);
319   
320         return 0;
321 }
322
323 static int
324 smb_compare_dentry(struct dentry *dir, struct qstr *a, struct qstr *b)
325 {
326         int i, result = 1;
327
328         if (a->len != b->len)
329                 goto out;
330         for (i=0; i < a->len; i++) {
331                 if (tolower(a->name[i]) != tolower(b->name[i]))
332                         goto out;
333         }
334         result = 0;
335 out:
336         return result;
337 }
338
339 /*
340  * This is the callback from dput() when d_count is going to 0.
341  * We use this to unhash dentries with bad inodes.
342  */
343 static int
344 smb_delete_dentry(struct dentry * dentry)
345 {
346         if (dentry->d_inode) {
347                 if (is_bad_inode(dentry->d_inode)) {
348                         PARANOIA("bad inode, unhashing %s/%s\n",
349                                  DENTRY_PATH(dentry));
350                         return 1;
351                 }
352         } else {
353                 /* N.B. Unhash negative dentries? */
354         }
355         return 0;
356 }
357
358 /*
359  * Initialize a new dentry
360  */
361 void
362 smb_new_dentry(struct dentry *dentry)
363 {
364         struct smb_sb_info *server = server_from_dentry(dentry);
365
366         if (server->mnt->flags & SMB_MOUNT_CASE)
367                 dentry->d_op = &smbfs_dentry_operations_case;
368         else
369                 dentry->d_op = &smbfs_dentry_operations;
370         dentry->d_time = jiffies;
371 }
372
373
374 /*
375  * Whenever a lookup succeeds, we know the parent directories
376  * are all valid, so we want to update the dentry timestamps.
377  * N.B. Move this to dcache?
378  */
379 void
380 smb_renew_times(struct dentry * dentry)
381 {
382         for (;;) {
383                 dentry->d_time = jiffies;
384                 if (IS_ROOT(dentry))
385                         break;
386                 dentry = dentry->d_parent;
387         }
388 }
389
390 static struct dentry *
391 smb_lookup(struct inode *dir, struct dentry *dentry)
392 {
393         struct smb_fattr finfo;
394         struct inode *inode;
395         int error;
396         struct smb_sb_info *server;
397
398         error = -ENAMETOOLONG;
399         if (dentry->d_name.len > SMB_MAXNAMELEN)
400                 goto out;
401
402         error = smb_proc_getattr(dentry, &finfo);
403 #ifdef SMBFS_PARANOIA
404         if (error && error != -ENOENT)
405                 PARANOIA("find %s/%s failed, error=%d\n",
406                          DENTRY_PATH(dentry), error);
407 #endif
408
409         inode = NULL;
410         if (error == -ENOENT)
411                 goto add_entry;
412         if (!error) {
413                 error = -EACCES;
414                 finfo.f_ino = iunique(dentry->d_sb, 2);
415                 inode = smb_iget(dir->i_sb, &finfo);
416                 if (inode) {
417         add_entry:
418                         server = server_from_dentry(dentry);
419                         if (server->mnt->flags & SMB_MOUNT_CASE)
420                                 dentry->d_op = &smbfs_dentry_operations_case;
421                         else
422                                 dentry->d_op = &smbfs_dentry_operations;
423
424                         d_add(dentry, inode);
425                         smb_renew_times(dentry);
426                         error = 0;
427                 }
428         }
429 out:
430         return ERR_PTR(error);
431 }
432
433 /*
434  * This code is common to all routines creating a new inode.
435  */
436 static int
437 smb_instantiate(struct dentry *dentry, __u16 fileid, int have_id)
438 {
439         struct smb_sb_info *server = server_from_dentry(dentry);
440         struct inode *inode;
441         int error;
442         struct smb_fattr fattr;
443
444         VERBOSE("file %s/%s, fileid=%u\n", DENTRY_PATH(dentry), fileid);
445
446         error = smb_proc_getattr(dentry, &fattr);
447         if (error)
448                 goto out_close;
449
450         smb_renew_times(dentry);
451         fattr.f_ino = iunique(dentry->d_sb, 2);
452         inode = smb_iget(dentry->d_sb, &fattr);
453         if (!inode)
454                 goto out_no_inode;
455
456         if (have_id) {
457                 inode->u.smbfs_i.fileid = fileid;
458                 inode->u.smbfs_i.access = SMB_O_RDWR;
459                 inode->u.smbfs_i.open = server->generation;
460         }
461         d_instantiate(dentry, inode);
462 out:
463         return error;
464
465 out_no_inode:
466         error = -EACCES;
467 out_close:
468         if (have_id) {
469                 PARANOIA("%s/%s failed, error=%d, closing %u\n",
470                          DENTRY_PATH(dentry), error, fileid);
471                 smb_close_fileid(dentry, fileid);
472         }
473         goto out;
474 }
475
476 /* N.B. How should the mode argument be used? */
477 static int
478 smb_create(struct inode *dir, struct dentry *dentry, int mode)
479 {
480         __u16 fileid;
481         int error;
482
483         VERBOSE("creating %s/%s, mode=%d\n", DENTRY_PATH(dentry), mode);
484
485         smb_invalid_dir_cache(dir);
486         error = smb_proc_create(dentry, 0, CURRENT_TIME, &fileid);
487         if (!error) {
488                 error = smb_instantiate(dentry, fileid, 1);
489         } else {
490                 PARANOIA("%s/%s failed, error=%d\n",
491                          DENTRY_PATH(dentry), error);
492         }
493         return error;
494 }
495
496 /* N.B. How should the mode argument be used? */
497 static int
498 smb_mkdir(struct inode *dir, struct dentry *dentry, int mode)
499 {
500         int error;
501
502         smb_invalid_dir_cache(dir);
503         error = smb_proc_mkdir(dentry);
504         if (!error) {
505                 error = smb_instantiate(dentry, 0, 0);
506         }
507         return error;
508 }
509
510 static int
511 smb_rmdir(struct inode *dir, struct dentry *dentry)
512 {
513         struct inode *inode = dentry->d_inode;
514         int error;
515
516         /*
517          * Close the directory if it's open.
518          */
519         smb_close(inode);
520
521         /*
522          * Check that nobody else is using the directory..
523          */
524         error = -EBUSY;
525         if (!d_unhashed(dentry))
526                 goto out;
527
528         smb_invalid_dir_cache(dir);
529         error = smb_proc_rmdir(dentry);
530
531 out:
532         return error;
533 }
534
535 static int
536 smb_unlink(struct inode *dir, struct dentry *dentry)
537 {
538         int error;
539
540         /*
541          * Close the file if it's open.
542          */
543         smb_close(dentry->d_inode);
544
545         smb_invalid_dir_cache(dir);
546         error = smb_proc_unlink(dentry);
547         if (!error)
548                 smb_renew_times(dentry);
549         return error;
550 }
551
552 static int
553 smb_rename(struct inode *old_dir, struct dentry *old_dentry,
554            struct inode *new_dir, struct dentry *new_dentry)
555 {
556         int error;
557
558         /*
559          * Close any open files, and check whether to delete the
560          * target before attempting the rename.
561          */
562         if (old_dentry->d_inode)
563                 smb_close(old_dentry->d_inode);
564         if (new_dentry->d_inode) {
565                 smb_close(new_dentry->d_inode);
566                 error = smb_proc_unlink(new_dentry);
567                 if (error) {
568                         VERBOSE("unlink %s/%s, error=%d\n",
569                                 DENTRY_PATH(new_dentry), error);
570                         goto out;
571                 }
572                 /* FIXME */
573                 d_delete(new_dentry);
574         }
575
576         smb_invalid_dir_cache(old_dir);
577         smb_invalid_dir_cache(new_dir);
578         error = smb_proc_mv(old_dentry, new_dentry);
579         if (!error) {
580                 smb_renew_times(old_dentry);
581                 smb_renew_times(new_dentry);
582         }
583 out:
584         return error;
585 }