Pull one more egcs 1.1.2 workaround.
[linux-2.6/linux-mips.git] / fs / smbfs / dir.c
blob1a74b5585ca28a23f2fe1ebb07bb003c50fa2cd5
1 /*
2 * dir.c
4 * Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
5 * Copyright (C) 1997 by Volker Lendecke
7 * Please add a note about your changes to smbfs in the ChangeLog file.
8 */
10 #include <linux/time.h>
11 #include <linux/errno.h>
12 #include <linux/kernel.h>
13 #include <linux/smp_lock.h>
14 #include <linux/ctype.h>
16 #include <linux/smb_fs.h>
17 #include <linux/smb_mount.h>
18 #include <linux/smbno.h>
20 #include "smb_debug.h"
21 #include "proto.h"
23 static int smb_readdir(struct file *, void *, filldir_t);
24 static int smb_dir_open(struct inode *, struct file *);
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 static int smb_make_node(struct inode *,struct dentry *,int,int);
34 static int smb_link(struct dentry *, struct inode *, struct dentry *);
36 struct file_operations smb_dir_operations =
38 .read = generic_read_dir,
39 .readdir = smb_readdir,
40 .ioctl = smb_ioctl,
41 .open = smb_dir_open,
44 struct inode_operations smb_dir_inode_operations =
46 .create = smb_create,
47 .lookup = smb_lookup,
48 .unlink = smb_unlink,
49 .mkdir = smb_mkdir,
50 .rmdir = smb_rmdir,
51 .rename = smb_rename,
52 .getattr = smb_getattr,
53 .setattr = smb_notify_change,
56 struct inode_operations smb_dir_inode_operations_unix =
58 .create = smb_create,
59 .lookup = smb_lookup,
60 .unlink = smb_unlink,
61 .mkdir = smb_mkdir,
62 .rmdir = smb_rmdir,
63 .rename = smb_rename,
64 .getattr = smb_getattr,
65 .setattr = smb_notify_change,
66 .symlink = smb_symlink,
67 .mknod = smb_make_node,
68 .link = smb_link,
72 * Read a directory, using filldir to fill the dirent memory.
73 * smb_proc_readdir does the actual reading from the smb server.
75 * The cache code is almost directly taken from ncpfs
77 static int
78 smb_readdir(struct file *filp, void *dirent, filldir_t filldir)
80 struct dentry *dentry = filp->f_dentry;
81 struct inode *dir = dentry->d_inode;
82 struct smb_sb_info *server = server_from_dentry(dentry);
83 union smb_dir_cache *cache = NULL;
84 struct smb_cache_control ctl;
85 struct page *page = NULL;
86 int result;
88 ctl.page = NULL;
89 ctl.cache = NULL;
91 VERBOSE("reading %s/%s, f_pos=%d\n",
92 DENTRY_PATH(dentry), (int) filp->f_pos);
94 result = 0;
96 lock_kernel();
98 switch ((unsigned int) filp->f_pos) {
99 case 0:
100 if (filldir(dirent, ".", 1, 0, dir->i_ino, DT_DIR) < 0)
101 goto out;
102 filp->f_pos = 1;
103 /* fallthrough */
104 case 1:
105 if (filldir(dirent, "..", 2, 1, parent_ino(dentry), DT_DIR) < 0)
106 goto out;
107 filp->f_pos = 2;
111 * Make sure our inode is up-to-date.
113 result = smb_revalidate_inode(dentry);
114 if (result)
115 goto out;
118 page = grab_cache_page(&dir->i_data, 0);
119 if (!page)
120 goto read_really;
122 ctl.cache = cache = kmap(page);
123 ctl.head = cache->head;
125 if (!PageUptodate(page) || !ctl.head.eof) {
126 VERBOSE("%s/%s, page uptodate=%d, eof=%d\n",
127 DENTRY_PATH(dentry), PageUptodate(page),ctl.head.eof);
128 goto init_cache;
131 if (filp->f_pos == 2) {
132 if (jiffies - ctl.head.time >= SMB_MAX_AGE(server))
133 goto init_cache;
136 * N.B. ncpfs checks mtime of dentry too here, we don't.
137 * 1. common smb servers do not update mtime on dir changes
138 * 2. it requires an extra smb request
139 * (revalidate has the same timeout as ctl.head.time)
141 * Instead smbfs invalidates its own cache on local changes
142 * and remote changes are not seen until timeout.
146 if (filp->f_pos > ctl.head.end)
147 goto finished;
149 ctl.fpos = filp->f_pos + (SMB_DIRCACHE_START - 2);
150 ctl.ofs = ctl.fpos / SMB_DIRCACHE_SIZE;
151 ctl.idx = ctl.fpos % SMB_DIRCACHE_SIZE;
153 for (;;) {
154 if (ctl.ofs != 0) {
155 ctl.page = find_lock_page(&dir->i_data, ctl.ofs);
156 if (!ctl.page)
157 goto invalid_cache;
158 ctl.cache = kmap(ctl.page);
159 if (!PageUptodate(ctl.page))
160 goto invalid_cache;
162 while (ctl.idx < SMB_DIRCACHE_SIZE) {
163 struct dentry *dent;
164 int res;
166 dent = smb_dget_fpos(ctl.cache->dentry[ctl.idx],
167 dentry, filp->f_pos);
168 if (!dent)
169 goto invalid_cache;
171 res = filldir(dirent, dent->d_name.name,
172 dent->d_name.len, filp->f_pos,
173 dent->d_inode->i_ino, DT_UNKNOWN);
174 dput(dent);
175 if (res)
176 goto finished;
177 filp->f_pos += 1;
178 ctl.idx += 1;
179 if (filp->f_pos > ctl.head.end)
180 goto finished;
182 if (ctl.page) {
183 kunmap(ctl.page);
184 SetPageUptodate(ctl.page);
185 unlock_page(ctl.page);
186 page_cache_release(ctl.page);
187 ctl.page = NULL;
189 ctl.idx = 0;
190 ctl.ofs += 1;
192 invalid_cache:
193 if (ctl.page) {
194 kunmap(ctl.page);
195 unlock_page(ctl.page);
196 page_cache_release(ctl.page);
197 ctl.page = NULL;
199 ctl.cache = cache;
200 init_cache:
201 smb_invalidate_dircache_entries(dentry);
202 ctl.head.time = jiffies;
203 ctl.head.eof = 0;
204 ctl.fpos = 2;
205 ctl.ofs = 0;
206 ctl.idx = SMB_DIRCACHE_START;
207 ctl.filled = 0;
208 ctl.valid = 1;
209 read_really:
210 result = server->ops->readdir(filp, dirent, filldir, &ctl);
211 if (ctl.idx == -1)
212 goto invalid_cache; /* retry */
213 ctl.head.end = ctl.fpos - 1;
214 ctl.head.eof = ctl.valid;
215 finished:
216 if (page) {
217 cache->head = ctl.head;
218 kunmap(page);
219 SetPageUptodate(page);
220 unlock_page(page);
221 page_cache_release(page);
223 if (ctl.page) {
224 kunmap(ctl.page);
225 SetPageUptodate(ctl.page);
226 unlock_page(ctl.page);
227 page_cache_release(ctl.page);
229 out:
230 unlock_kernel();
231 return result;
234 static int
235 smb_dir_open(struct inode *dir, struct file *file)
237 struct dentry *dentry = file->f_dentry;
238 struct smb_sb_info *server;
239 int error = 0;
241 VERBOSE("(%s/%s)\n", dentry->d_parent->d_name.name,
242 file->f_dentry->d_name.name);
245 * Directory timestamps in the core protocol aren't updated
246 * when a file is added, so we give them a very short TTL.
248 lock_kernel();
249 server = server_from_dentry(dentry);
250 if (server->opt.protocol < SMB_PROTOCOL_LANMAN2) {
251 unsigned long age = jiffies - SMB_I(dir)->oldmtime;
252 if (age > 2*HZ)
253 smb_invalid_dir_cache(dir);
257 * Note: in order to allow the smbmount process to open the
258 * mount point, we only revalidate if the connection is valid or
259 * if the process is trying to access something other than the root.
261 if (server->state == CONN_VALID || !IS_ROOT(dentry))
262 error = smb_revalidate_inode(dentry);
263 unlock_kernel();
264 return error;
268 * Dentry operations routines
270 static int smb_lookup_validate(struct dentry *, int);
271 static int smb_hash_dentry(struct dentry *, struct qstr *);
272 static int smb_compare_dentry(struct dentry *, struct qstr *, struct qstr *);
273 static int smb_delete_dentry(struct dentry *);
275 static struct dentry_operations smbfs_dentry_operations =
277 .d_revalidate = smb_lookup_validate,
278 .d_hash = smb_hash_dentry,
279 .d_compare = smb_compare_dentry,
280 .d_delete = smb_delete_dentry,
283 static struct dentry_operations smbfs_dentry_operations_case =
285 .d_revalidate = smb_lookup_validate,
286 .d_delete = smb_delete_dentry,
291 * This is the callback when the dcache has a lookup hit.
293 static int
294 smb_lookup_validate(struct dentry * dentry, int flags)
296 struct smb_sb_info *server = server_from_dentry(dentry);
297 struct inode * inode = dentry->d_inode;
298 unsigned long age = jiffies - dentry->d_time;
299 int valid;
302 * The default validation is based on dentry age:
303 * we believe in dentries for a few seconds. (But each
304 * successful server lookup renews the timestamp.)
306 valid = (age <= SMB_MAX_AGE(server));
307 #ifdef SMBFS_DEBUG_VERBOSE
308 if (!valid)
309 VERBOSE("%s/%s not valid, age=%lu\n",
310 DENTRY_PATH(dentry), age);
311 #endif
313 if (inode) {
314 lock_kernel();
315 if (is_bad_inode(inode)) {
316 PARANOIA("%s/%s has dud inode\n", DENTRY_PATH(dentry));
317 valid = 0;
318 } else if (!valid)
319 valid = (smb_revalidate_inode(dentry) == 0);
320 unlock_kernel();
321 } else {
323 * What should we do for negative dentries?
326 return valid;
329 static int
330 smb_hash_dentry(struct dentry *dir, struct qstr *this)
332 unsigned long hash;
333 int i;
335 hash = init_name_hash();
336 for (i=0; i < this->len ; i++)
337 hash = partial_name_hash(tolower(this->name[i]), hash);
338 this->hash = end_name_hash(hash);
340 return 0;
343 static int
344 smb_compare_dentry(struct dentry *dir, struct qstr *a, struct qstr *b)
346 int i, result = 1;
348 if (a->len != b->len)
349 goto out;
350 for (i=0; i < a->len; i++) {
351 if (tolower(a->name[i]) != tolower(b->name[i]))
352 goto out;
354 result = 0;
355 out:
356 return result;
360 * This is the callback from dput() when d_count is going to 0.
361 * We use this to unhash dentries with bad inodes.
363 static int
364 smb_delete_dentry(struct dentry * dentry)
366 if (dentry->d_inode) {
367 if (is_bad_inode(dentry->d_inode)) {
368 PARANOIA("bad inode, unhashing %s/%s\n",
369 DENTRY_PATH(dentry));
370 return 1;
372 } else {
373 /* N.B. Unhash negative dentries? */
375 return 0;
379 * Initialize a new dentry
381 void
382 smb_new_dentry(struct dentry *dentry)
384 struct smb_sb_info *server = server_from_dentry(dentry);
386 if (server->mnt->flags & SMB_MOUNT_CASE)
387 dentry->d_op = &smbfs_dentry_operations_case;
388 else
389 dentry->d_op = &smbfs_dentry_operations;
390 dentry->d_time = jiffies;
395 * Whenever a lookup succeeds, we know the parent directories
396 * are all valid, so we want to update the dentry timestamps.
397 * N.B. Move this to dcache?
399 void
400 smb_renew_times(struct dentry * dentry)
402 read_lock(&dparent_lock);
403 for (;;) {
404 dentry->d_time = jiffies;
405 if (IS_ROOT(dentry))
406 break;
407 dentry = dentry->d_parent;
409 read_unlock(&dparent_lock);
412 static struct dentry *
413 smb_lookup(struct inode *dir, struct dentry *dentry)
415 struct smb_fattr finfo;
416 struct inode *inode;
417 int error;
418 struct smb_sb_info *server;
420 error = -ENAMETOOLONG;
421 if (dentry->d_name.len > SMB_MAXNAMELEN)
422 goto out;
424 lock_kernel();
425 error = smb_proc_getattr(dentry, &finfo);
426 #ifdef SMBFS_PARANOIA
427 if (error && error != -ENOENT)
428 PARANOIA("find %s/%s failed, error=%d\n",
429 DENTRY_PATH(dentry), error);
430 #endif
432 inode = NULL;
433 if (error == -ENOENT)
434 goto add_entry;
435 if (!error) {
436 error = -EACCES;
437 finfo.f_ino = iunique(dentry->d_sb, 2);
438 inode = smb_iget(dir->i_sb, &finfo);
439 if (inode) {
440 add_entry:
441 server = server_from_dentry(dentry);
442 if (server->mnt->flags & SMB_MOUNT_CASE)
443 dentry->d_op = &smbfs_dentry_operations_case;
444 else
445 dentry->d_op = &smbfs_dentry_operations;
447 d_add(dentry, inode);
448 smb_renew_times(dentry);
449 error = 0;
452 unlock_kernel();
453 out:
454 return ERR_PTR(error);
458 * This code is common to all routines creating a new inode.
460 static int
461 smb_instantiate(struct dentry *dentry, __u16 fileid, int have_id)
463 struct smb_sb_info *server = server_from_dentry(dentry);
464 struct inode *inode;
465 int error;
466 struct smb_fattr fattr;
468 VERBOSE("file %s/%s, fileid=%u\n", DENTRY_PATH(dentry), fileid);
470 error = smb_proc_getattr(dentry, &fattr);
471 if (error)
472 goto out_close;
474 smb_renew_times(dentry);
475 fattr.f_ino = iunique(dentry->d_sb, 2);
476 inode = smb_iget(dentry->d_sb, &fattr);
477 if (!inode)
478 goto out_no_inode;
480 if (have_id) {
481 struct smb_inode_info *ei = SMB_I(inode);
482 ei->fileid = fileid;
483 ei->access = SMB_O_RDWR;
484 ei->open = server->generation;
486 d_instantiate(dentry, inode);
487 out:
488 return error;
490 out_no_inode:
491 error = -EACCES;
492 out_close:
493 if (have_id) {
494 PARANOIA("%s/%s failed, error=%d, closing %u\n",
495 DENTRY_PATH(dentry), error, fileid);
496 smb_close_fileid(dentry, fileid);
498 goto out;
501 /* N.B. How should the mode argument be used? */
502 static int
503 smb_create(struct inode *dir, struct dentry *dentry, int mode)
505 struct smb_sb_info *server = server_from_dentry(dentry);
506 __u16 fileid;
507 int error;
508 struct iattr attr;
510 VERBOSE("creating %s/%s, mode=%d\n", DENTRY_PATH(dentry), mode);
512 lock_kernel();
513 smb_invalid_dir_cache(dir);
514 error = smb_proc_create(dentry, 0, CURRENT_TIME, &fileid);
515 if (!error) {
516 if (server->opt.capabilities & SMB_CAP_UNIX) {
517 /* Set attributes for new file */
518 attr.ia_valid = ATTR_MODE;
519 attr.ia_mode = mode;
520 error = smb_proc_setattr_unix(dentry, &attr, 0, 0);
522 error = smb_instantiate(dentry, fileid, 1);
523 } else {
524 PARANOIA("%s/%s failed, error=%d\n",
525 DENTRY_PATH(dentry), error);
527 unlock_kernel();
528 return error;
531 /* N.B. How should the mode argument be used? */
532 static int
533 smb_mkdir(struct inode *dir, struct dentry *dentry, int mode)
535 struct smb_sb_info *server = server_from_dentry(dentry);
536 int error;
537 struct iattr attr;
539 lock_kernel();
540 smb_invalid_dir_cache(dir);
541 error = smb_proc_mkdir(dentry);
542 if (!error) {
543 if (server->opt.capabilities & SMB_CAP_UNIX) {
544 /* Set attributes for new directory */
545 attr.ia_valid = ATTR_MODE;
546 attr.ia_mode = mode;
547 error = smb_proc_setattr_unix(dentry, &attr, 0, 0);
549 error = smb_instantiate(dentry, 0, 0);
551 unlock_kernel();
552 return error;
555 static int
556 smb_rmdir(struct inode *dir, struct dentry *dentry)
558 struct inode *inode = dentry->d_inode;
559 int error;
562 * Close the directory if it's open.
564 lock_kernel();
565 smb_close(inode);
568 * Check that nobody else is using the directory..
570 error = -EBUSY;
571 if (!d_unhashed(dentry))
572 goto out;
574 smb_invalid_dir_cache(dir);
575 error = smb_proc_rmdir(dentry);
577 out:
578 unlock_kernel();
579 return error;
582 static int
583 smb_unlink(struct inode *dir, struct dentry *dentry)
585 int error;
588 * Close the file if it's open.
590 lock_kernel();
591 smb_close(dentry->d_inode);
593 smb_invalid_dir_cache(dir);
594 error = smb_proc_unlink(dentry);
595 if (!error)
596 smb_renew_times(dentry);
597 unlock_kernel();
598 return error;
601 static int
602 smb_rename(struct inode *old_dir, struct dentry *old_dentry,
603 struct inode *new_dir, struct dentry *new_dentry)
605 int error;
608 * Close any open files, and check whether to delete the
609 * target before attempting the rename.
611 lock_kernel();
612 if (old_dentry->d_inode)
613 smb_close(old_dentry->d_inode);
614 if (new_dentry->d_inode) {
615 smb_close(new_dentry->d_inode);
616 error = smb_proc_unlink(new_dentry);
617 if (error) {
618 VERBOSE("unlink %s/%s, error=%d\n",
619 DENTRY_PATH(new_dentry), error);
620 goto out;
622 /* FIXME */
623 d_delete(new_dentry);
626 smb_invalid_dir_cache(old_dir);
627 smb_invalid_dir_cache(new_dir);
628 error = smb_proc_mv(old_dentry, new_dentry);
629 if (!error) {
630 smb_renew_times(old_dentry);
631 smb_renew_times(new_dentry);
633 out:
634 unlock_kernel();
635 return error;
639 * FIXME: samba servers won't let you create device nodes unless uid/gid
640 * matches the connection credentials (and we don't know which those are ...)
642 static int
643 smb_make_node(struct inode *dir, struct dentry *dentry, int mode, int dev)
645 int error;
646 struct iattr attr;
648 attr.ia_valid = ATTR_MODE | ATTR_UID | ATTR_GID;
649 attr.ia_mode = mode;
650 attr.ia_uid = current->euid;
651 attr.ia_gid = current->egid;
653 smb_invalid_dir_cache(dir);
654 error = smb_proc_setattr_unix(dentry, &attr, MAJOR(dev), MINOR(dev));
655 if (!error) {
656 error = smb_instantiate(dentry, 0, 0);
658 return error;
662 * dentry = existing file
663 * new_dentry = new file
665 static int
666 smb_link(struct dentry *dentry, struct inode *dir, struct dentry *new_dentry)
668 int error;
670 DEBUG1("smb_link old=%s/%s new=%s/%s\n",
671 DENTRY_PATH(dentry), DENTRY_PATH(new_dentry));
672 smb_invalid_dir_cache(dir);
673 error = smb_proc_link(server_from_dentry(dentry), dentry, new_dentry);
674 if (!error) {
675 smb_renew_times(dentry);
676 error = smb_instantiate(new_dentry, 0, 0);
678 return error;