* better
[mascara-docs.git] / i386 / linux-2.3.21 / fs / smbfs / dir.c
blobcbaa646b397d2e9a2143f0495b03a1f7e136ead2
1 /*
2 * dir.c
4 * Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
5 * Copyright (C) 1997 by Volker Lendecke
7 */
9 #include <linux/sched.h>
10 #include <linux/errno.h>
11 #include <linux/kernel.h>
13 #include <linux/smb_fs.h>
14 #include <linux/smbno.h>
16 #define SMBFS_PARANOIA 1
17 /* #define SMBFS_DEBUG_VERBOSE 1 */
18 /* #define pr_debug printk */
19 #define SMBFS_MAX_AGE 5*HZ
21 static ssize_t smb_dir_read(struct file *, char *, size_t, loff_t *);
22 static int smb_readdir(struct file *, void *, filldir_t);
23 static int smb_dir_open(struct inode *, struct file *);
25 static struct dentry *smb_lookup(struct inode *, struct dentry *);
26 static int smb_create(struct inode *, struct dentry *, int);
27 static int smb_mkdir(struct inode *, struct dentry *, int);
28 static int smb_rmdir(struct inode *, struct dentry *);
29 static int smb_unlink(struct inode *, struct dentry *);
30 static int smb_rename(struct inode *, struct dentry *,
31 struct inode *, struct dentry *);
33 static struct file_operations smb_dir_operations =
35 NULL, /* lseek - default */
36 smb_dir_read, /* read - bad */
37 NULL, /* write - bad */
38 smb_readdir, /* readdir */
39 NULL, /* poll - default */
40 smb_ioctl, /* ioctl */
41 NULL, /* mmap */
42 smb_dir_open, /* open(struct inode *, struct file *) */
43 NULL, /* flush */
44 NULL, /* no special release code */
45 NULL /* fsync */
48 struct inode_operations smb_dir_inode_operations =
50 &smb_dir_operations, /* default directory file ops */
51 smb_create, /* create */
52 smb_lookup, /* lookup */
53 NULL, /* link */
54 smb_unlink, /* unlink */
55 NULL, /* symlink */
56 smb_mkdir, /* mkdir */
57 smb_rmdir, /* rmdir */
58 NULL, /* mknod */
59 smb_rename, /* rename */
60 NULL, /* readlink */
61 NULL, /* follow_link */
62 NULL, /* get_block */
63 NULL, /* readpage */
64 NULL, /* writepage */
65 NULL, /* flushpage */
66 NULL, /* truncate */
67 NULL, /* permission */
68 NULL, /* smap */
69 smb_revalidate_inode, /* revalidate */
72 static ssize_t
73 smb_dir_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
75 return -EISDIR;
78 static int
79 smb_readdir(struct file *filp, void *dirent, filldir_t filldir)
81 struct dentry *dentry = filp->f_dentry;
82 struct inode *dir = dentry->d_inode;
83 struct cache_head *cachep;
84 int result;
86 #ifdef SMBFS_DEBUG_VERBOSE
87 printk("smb_readdir: reading %s/%s, f_pos=%d\n",
88 dentry->d_parent->d_name.name, dentry->d_name.name, (int) filp->f_pos);
89 #endif
91 * Make sure our inode is up-to-date.
93 result = smb_revalidate_inode(dentry);
94 if (result)
95 goto out;
97 * Get the cache pointer ...
99 result = -EIO;
100 cachep = smb_get_dircache(dentry);
101 if (!cachep)
102 goto out;
104 * Make sure the cache is up-to-date.
106 if (!cachep->valid)
108 result = smb_refill_dircache(cachep, dentry);
109 if (result)
110 goto out_free;
113 result = 0;
114 switch ((unsigned int) filp->f_pos)
116 case 0:
117 if (filldir(dirent, ".", 1, 0, dir->i_ino) < 0)
118 goto out_free;
119 filp->f_pos = 1;
120 case 1:
121 if (filldir(dirent, "..", 2, 1,
122 dentry->d_parent->d_inode->i_ino) < 0)
123 goto out_free;
124 filp->f_pos = 2;
127 while (1)
129 struct cache_dirent this_dirent, *entry = &this_dirent;
131 if (!smb_find_in_cache(cachep, filp->f_pos, entry))
132 break;
134 * Check whether to look up the inode number.
136 if (!entry->ino) {
137 struct qstr qname;
138 /* N.B. Make cache_dirent name a qstr! */
139 qname.name = entry->name;
140 qname.len = entry->len;
141 entry->ino = find_inode_number(dentry, &qname);
142 if (!entry->ino)
143 entry->ino = smb_invent_inos(1);
146 if (filldir(dirent, entry->name, entry->len,
147 filp->f_pos, entry->ino) < 0)
148 break;
149 filp->f_pos += 1;
153 * Release the dircache.
155 out_free:
156 smb_free_dircache(cachep);
157 out:
158 return result;
162 * Note: in order to allow the smbclient process to open the
163 * mount point, we don't revalidate if conn_pid is NULL.
165 static int
166 smb_dir_open(struct inode *dir, struct file *file)
168 struct dentry *dentry = file->f_dentry;
169 struct smb_sb_info *server = server_from_dentry(dentry);
170 int error = 0;
171 #ifdef SMBFS_DEBUG_VERBOSE
172 printk("smb_dir_open: (%s/%s)\n", dentry->d_parent->d_name.name,
173 file->f_dentry->d_name.name);
174 #endif
176 * Directory timestamps in the core protocol aren't updated
177 * when a file is added, so we give them a very short TTL.
179 if (server->opt.protocol < SMB_PROTOCOL_LANMAN2)
181 unsigned long age = jiffies - dir->u.smbfs_i.oldmtime;
182 if (age > 2*HZ)
183 smb_invalid_dir_cache(dir);
186 if (server->conn_pid)
187 error = smb_revalidate_inode(dentry);
188 return error;
192 * Dentry operations routines
194 static int smb_lookup_validate(struct dentry *, int);
195 static int smb_hash_dentry(struct dentry *, struct qstr *);
196 static int smb_compare_dentry(struct dentry *, struct qstr *, struct qstr *);
197 static void smb_delete_dentry(struct dentry *);
199 static struct dentry_operations smbfs_dentry_operations =
201 smb_lookup_validate, /* d_revalidate(struct dentry *) */
202 smb_hash_dentry, /* d_hash */
203 smb_compare_dentry, /* d_compare */
204 smb_delete_dentry /* d_delete(struct dentry *) */
208 * This is the callback when the dcache has a lookup hit.
210 static int
211 smb_lookup_validate(struct dentry * dentry, int flags)
213 struct inode * inode = dentry->d_inode;
214 unsigned long age = jiffies - dentry->d_time;
215 int valid;
218 * The default validation is based on dentry age:
219 * we believe in dentries for 5 seconds. (But each
220 * successful server lookup renews the timestamp.)
222 valid = (age <= SMBFS_MAX_AGE);
223 #ifdef SMBFS_DEBUG_VERBOSE
224 if (!valid)
225 printk("smb_lookup_validate: %s/%s not valid, age=%lu\n",
226 dentry->d_parent->d_name.name, dentry->d_name.name, age);
227 #endif
229 if (inode)
231 if (is_bad_inode(inode))
233 #ifdef SMBFS_PARANOIA
234 printk("smb_lookup_validate: %s/%s has dud inode\n",
235 dentry->d_parent->d_name.name, dentry->d_name.name);
236 #endif
237 valid = 0;
238 } else if (!valid)
239 valid = (smb_revalidate_inode(dentry) == 0);
240 } else
243 * What should we do for negative dentries?
246 return valid;
250 * XXX: It would be better to use the tolower from linux/ctype.h,
251 * but _ctype is needed and it is not exported.
253 #define tolower(c) (((c) >= 'A' && (c) <= 'Z') ? (c)-('A'-'a') : (c))
255 static int
256 smb_hash_dentry(struct dentry *dir, struct qstr *this)
258 unsigned long hash;
259 int i;
261 hash = init_name_hash();
262 for (i=0; i < this->len ; i++)
263 hash = partial_name_hash(tolower(this->name[i]), hash);
264 this->hash = end_name_hash(hash);
266 return 0;
269 static int
270 smb_compare_dentry(struct dentry *dir, struct qstr *a, struct qstr *b)
272 int i, result = 1;
274 if (a->len != b->len)
275 goto out;
276 for (i=0; i < a->len; i++)
278 if (tolower(a->name[i]) != tolower(b->name[i]))
279 goto out;
281 result = 0;
282 out:
283 return result;
287 * This is the callback from dput() when d_count is going to 0.
288 * We use this to unhash dentries with bad inodes and close files.
290 static void
291 smb_delete_dentry(struct dentry * dentry)
293 if (dentry->d_inode)
295 if (is_bad_inode(dentry->d_inode))
297 #ifdef SMBFS_PARANOIA
298 printk("smb_delete_dentry: bad inode, unhashing %s/%s\n",
299 dentry->d_parent->d_name.name, dentry->d_name.name);
300 #endif
301 d_drop(dentry);
303 smb_close_dentry(dentry);
304 } else
306 /* N.B. Unhash negative dentries? */
311 * Whenever a lookup succeeds, we know the parent directories
312 * are all valid, so we want to update the dentry timestamps.
313 * N.B. Move this to dcache?
315 void
316 smb_renew_times(struct dentry * dentry)
318 for (;;)
320 dentry->d_time = jiffies;
321 if (IS_ROOT(dentry))
322 break;
323 dentry = dentry->d_parent;
327 static struct dentry *
328 smb_lookup(struct inode *dir, struct dentry *dentry)
330 struct smb_fattr finfo;
331 struct inode *inode;
332 int error;
334 error = -ENAMETOOLONG;
335 if (dentry->d_name.len > SMB_MAXNAMELEN)
336 goto out;
338 error = smb_proc_getattr(dentry, &finfo);
339 #ifdef SMBFS_PARANOIA
340 if (error && error != -ENOENT)
341 printk("smb_lookup: find %s/%s failed, error=%d\n",
342 dentry->d_parent->d_name.name, dentry->d_name.name, error);
343 #endif
345 inode = NULL;
346 if (error == -ENOENT)
347 goto add_entry;
348 if (!error)
350 error = -EACCES;
351 finfo.f_ino = smb_invent_inos(1);
352 inode = smb_iget(dir->i_sb, &finfo);
353 if (inode)
355 add_entry:
356 dentry->d_op = &smbfs_dentry_operations;
357 d_add(dentry, inode);
358 smb_renew_times(dentry);
359 error = 0;
362 out:
363 return ERR_PTR(error);
367 * This code is common to all routines creating a new inode.
369 static int
370 smb_instantiate(struct dentry *dentry, __u16 fileid, int have_id)
372 struct smb_sb_info *server = server_from_dentry(dentry);
373 struct inode *inode;
374 int error;
375 struct smb_fattr fattr;
377 #ifdef SMBFS_DEBUG_VERBOSE
378 printk("smb_instantiate: file %s/%s, fileid=%u\n",
379 dentry->d_parent->d_name.name, dentry->d_name.name, fileid);
380 #endif
381 error = smb_proc_getattr(dentry, &fattr);
382 if (error)
383 goto out_close;
385 smb_renew_times(dentry);
386 fattr.f_ino = smb_invent_inos(1);
387 inode = smb_iget(dentry->d_sb, &fattr);
388 if (!inode)
389 goto out_no_inode;
391 if (have_id)
393 inode->u.smbfs_i.fileid = fileid;
394 inode->u.smbfs_i.access = SMB_O_RDWR;
395 inode->u.smbfs_i.open = server->generation;
397 d_instantiate(dentry, inode);
398 out:
399 return error;
401 out_no_inode:
402 error = -EACCES;
403 out_close:
404 if (have_id)
406 #ifdef SMBFS_PARANOIA
407 printk("smb_instantiate: %s/%s failed, error=%d, closing %u\n",
408 dentry->d_parent->d_name.name, dentry->d_name.name, error, fileid);
409 #endif
410 smb_close_fileid(dentry, fileid);
412 goto out;
415 /* N.B. How should the mode argument be used? */
416 static int
417 smb_create(struct inode *dir, struct dentry *dentry, int mode)
419 __u16 fileid;
420 int error;
422 #ifdef SMBFS_DEBUG_VERBOSE
423 printk("smb_create: creating %s/%s, mode=%d\n",
424 dentry->d_parent->d_name.name, dentry->d_name.name, mode);
425 #endif
427 smb_invalid_dir_cache(dir);
428 error = smb_proc_create(dentry, 0, CURRENT_TIME, &fileid);
429 if (!error)
431 error = smb_instantiate(dentry, fileid, 1);
432 } else
434 #ifdef SMBFS_PARANOIA
435 printk("smb_create: %s/%s failed, error=%d\n",
436 dentry->d_parent->d_name.name, dentry->d_name.name, error);
437 #endif
439 return error;
442 /* N.B. How should the mode argument be used? */
443 static int
444 smb_mkdir(struct inode *dir, struct dentry *dentry, int mode)
446 int error;
448 smb_invalid_dir_cache(dir);
449 error = smb_proc_mkdir(dentry);
450 if (!error)
452 error = smb_instantiate(dentry, 0, 0);
454 return error;
457 static int
458 smb_rmdir(struct inode *dir, struct dentry *dentry)
460 struct inode *inode = dentry->d_inode;
461 int error;
464 * Close the directory if it's open.
466 smb_close(inode);
469 * Check that nobody else is using the directory..
471 error = -EBUSY;
472 if (!list_empty(&dentry->d_hash))
473 goto out;
475 smb_invalid_dir_cache(dir);
476 error = smb_proc_rmdir(dentry);
478 out:
479 return error;
482 static int
483 smb_unlink(struct inode *dir, struct dentry *dentry)
485 int error;
488 * Close the file if it's open.
490 smb_close(dentry->d_inode);
492 smb_invalid_dir_cache(dir);
493 error = smb_proc_unlink(dentry);
494 if (!error)
496 smb_renew_times(dentry);
497 d_delete(dentry);
499 return error;
502 static int
503 smb_rename(struct inode *old_dir, struct dentry *old_dentry,
504 struct inode *new_dir, struct dentry *new_dentry)
506 int error;
509 * Close any open files, and check whether to delete the
510 * target before attempting the rename.
512 if (old_dentry->d_inode)
513 smb_close(old_dentry->d_inode);
514 if (new_dentry->d_inode)
516 smb_close(new_dentry->d_inode);
517 error = smb_proc_unlink(new_dentry);
518 if (error)
520 #ifdef SMBFS_DEBUG_VERBOSE
521 printk("smb_rename: unlink %s/%s, error=%d\n",
522 new_dentry->d_parent->d_name.name, new_dentry->d_name.name, error);
523 #endif
524 goto out;
526 /* FIXME */
527 d_delete(new_dentry);
530 smb_invalid_dir_cache(old_dir);
531 smb_invalid_dir_cache(new_dir);
532 error = smb_proc_mv(old_dentry, new_dentry);
533 if (!error)
535 smb_renew_times(old_dentry);
536 smb_renew_times(new_dentry);
538 out:
539 return error;