Import 2.1.118
[davej-history.git] / fs / autofs / root.c
blob41694e8ebb6f9eb52130f46fb7308f60d2527959
1 /* -*- linux-c -*- --------------------------------------------------------- *
3 * linux/fs/autofs/root.c
5 * Copyright 1997 Transmeta Corporation -- All Rights Reserved
7 * This file is part of the Linux kernel and is made available under
8 * the terms of the GNU General Public License, version 2, or at your
9 * option, any later version, incorporated herein by reference.
11 * ------------------------------------------------------------------------- */
13 #include <linux/errno.h>
14 #include <linux/stat.h>
15 #include <linux/param.h>
16 #include "autofs_i.h"
18 static int autofs_root_readdir(struct file *,void *,filldir_t);
19 static int autofs_root_lookup(struct inode *,struct dentry *);
20 static int autofs_root_symlink(struct inode *,struct dentry *,const char *);
21 static int autofs_root_unlink(struct inode *,struct dentry *);
22 static int autofs_root_rmdir(struct inode *,struct dentry *);
23 static int autofs_root_mkdir(struct inode *,struct dentry *,int);
24 static int autofs_root_ioctl(struct inode *, struct file *,unsigned int,unsigned long);
26 static struct file_operations autofs_root_operations = {
27 NULL, /* llseek */
28 NULL, /* read */
29 NULL, /* write */
30 autofs_root_readdir, /* readdir */
31 NULL, /* poll */
32 autofs_root_ioctl, /* ioctl */
33 NULL, /* mmap */
34 NULL, /* open */
35 NULL, /* flush */
36 NULL, /* release */
37 NULL, /* fsync */
38 NULL, /* fasync */
39 NULL, /* check_media_change */
40 NULL, /* revalidate */
41 NULL /* lock */
44 struct inode_operations autofs_root_inode_operations = {
45 &autofs_root_operations, /* file operations */
46 NULL, /* create */
47 autofs_root_lookup, /* lookup */
48 NULL, /* link */
49 autofs_root_unlink, /* unlink */
50 autofs_root_symlink, /* symlink */
51 autofs_root_mkdir, /* mkdir */
52 autofs_root_rmdir, /* rmdir */
53 NULL, /* mknod */
54 NULL, /* rename */
55 NULL, /* readlink */
56 NULL, /* follow_link */
57 NULL, /* readpage */
58 NULL, /* writepage */
59 NULL, /* bmap */
60 NULL, /* truncate */
61 NULL, /* permission */
62 NULL, /* smap */
63 NULL, /* updatepage */
64 NULL /* revalidate */
67 static int autofs_root_readdir(struct file *filp, void *dirent, filldir_t filldir)
69 struct autofs_dir_ent *ent;
70 struct autofs_dirhash *dirhash;
71 struct inode * inode = filp->f_dentry->d_inode;
72 off_t onr, nr;
74 if (!inode || !S_ISDIR(inode->i_mode))
75 return -ENOTDIR;
77 dirhash = &((struct autofs_sb_info *)inode->i_sb->u.generic_sbp)->dirhash;
78 nr = filp->f_pos;
80 switch(nr)
82 case 0:
83 if (filldir(dirent, ".", 1, nr, inode->i_ino) < 0)
84 return 0;
85 filp->f_pos = ++nr;
86 /* fall through */
87 case 1:
88 if (filldir(dirent, "..", 2, nr, inode->i_ino) < 0)
89 return 0;
90 filp->f_pos = ++nr;
91 /* fall through */
92 default:
93 while ( onr = nr, ent = autofs_hash_enum(dirhash,&nr) ) {
94 if (filldir(dirent,ent->name,ent->len,onr,ent->ino) < 0)
95 return 0;
96 filp->f_pos = nr;
98 break;
101 return 0;
104 static int try_to_fill_dentry(struct dentry *dentry, struct super_block *sb, struct autofs_sb_info *sbi)
106 struct inode * inode;
107 struct autofs_dir_ent *ent;
108 int status = 0;
110 if ( !(ent = autofs_hash_lookup(&sbi->dirhash, &dentry->d_name)) ) {
111 do {
112 if ( status && dentry->d_inode ) {
113 printk("autofs warning: lookup failure on existing dentry, status = %d, name = %s\n", status, dentry->d_name.name);
114 break;
117 /* Turn this into a real negative dentry? */
118 if (status == -ENOENT) {
119 dentry->d_time = jiffies + AUTOFS_NEGATIVE_TIMEOUT;
120 dentry->d_flags &= ~DCACHE_AUTOFS_PENDING;
121 return 1;
122 } else if (status) {
123 /* Return a negative dentry, but leave it "pending" */
124 return 1;
126 status = autofs_wait(sbi, &dentry->d_name);
127 } while (!(ent = autofs_hash_lookup(&sbi->dirhash, &dentry->d_name)) );
130 /* Abuse this field as a pointer to the directory entry, used to
131 find the expire list pointers */
132 dentry->d_time = (unsigned long) ent;
134 if (!dentry->d_inode) {
135 inode = iget(sb, ent->ino);
136 if (!inode) {
137 /* Failed, but leave pending for next time */
138 return 1;
140 dentry->d_inode = inode;
143 /* If this is a directory that isn't a mount point, bitch at the
144 daemon and fix it in user space */
145 if ( S_ISDIR(dentry->d_inode->i_mode) && dentry->d_mounts == dentry ) {
146 return !autofs_wait(sbi, &dentry->d_name);
149 /* We don't update the usages for the autofs daemon itself, this
150 is necessary for recursive autofs mounts */
151 if ( !autofs_oz_mode(sbi) )
152 autofs_update_usage(&sbi->dirhash,ent);
154 dentry->d_flags &= ~DCACHE_AUTOFS_PENDING;
155 return 1;
160 * Revalidate is called on every cache lookup. Some of those
161 * cache lookups may actually happen while the dentry is not
162 * yet completely filled in, and revalidate has to delay such
163 * lookups..
165 static int autofs_revalidate(struct dentry * dentry)
167 struct autofs_sb_info *sbi;
168 struct inode * dir = dentry->d_parent->d_inode;
169 struct autofs_dir_ent *ent;
171 sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp;
173 /* Pending dentry */
174 if ( dentry->d_flags & DCACHE_AUTOFS_PENDING ) {
175 if (autofs_oz_mode(sbi))
176 return 1;
177 else
178 return try_to_fill_dentry(dentry, dir->i_sb, sbi);
181 /* Negative dentry.. invalidate if "old" */
182 if (!dentry->d_inode)
183 return (dentry->d_time - jiffies <= AUTOFS_NEGATIVE_TIMEOUT);
185 /* Check for a non-mountpoint directory */
186 if ( S_ISDIR(dentry->d_inode->i_mode) && dentry->d_mounts == dentry ) {
187 if (autofs_oz_mode(sbi))
188 return 1;
189 else
190 return try_to_fill_dentry(dentry, dir->i_sb, sbi);
193 /* Update the usage list */
194 if ( !autofs_oz_mode(sbi) ) {
195 ent = (struct autofs_dir_ent *) dentry->d_time;
196 autofs_update_usage(&sbi->dirhash,ent);
198 return 1;
201 static struct dentry_operations autofs_dentry_operations = {
202 autofs_revalidate, /* d_revalidate */
203 NULL, /* d_hash */
204 NULL, /* d_compare */
207 static int autofs_root_lookup(struct inode *dir, struct dentry * dentry)
209 struct autofs_sb_info *sbi;
210 struct inode *res;
211 int oz_mode;
213 DPRINTK(("autofs_root_lookup: name = "));
214 autofs_say(dentry->d_name.name,dentry->d_name.len);
216 if (!S_ISDIR(dir->i_mode))
217 return -ENOTDIR;
219 res = NULL;
220 sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp;
222 oz_mode = autofs_oz_mode(sbi);
223 DPRINTK(("autofs_lookup: pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d\n", current->pid, current->pgrp, sbi->catatonic, oz_mode));
226 * Mark the dentry incomplete, but add it. This is needed so
227 * that the VFS layer knows about the dentry, and we can count
228 * on catching any lookups through the revalidate.
230 * Let all the hard work be done by the revalidate function that
231 * needs to be able to do this anyway..
233 * We need to do this before we release the directory semaphore.
235 dentry->d_op = &autofs_dentry_operations;
236 dentry->d_flags |= DCACHE_AUTOFS_PENDING;
237 d_add(dentry, NULL);
239 up(&dir->i_sem);
240 autofs_revalidate(dentry);
241 down(&dir->i_sem);
244 * If we are still pending, check if we had to handle
245 * a signal. If so we can force a restart..
247 if (dentry->d_flags & DCACHE_AUTOFS_PENDING) {
248 if (signal_pending(current))
249 return -ERESTARTNOINTR;
252 return 0;
255 static int autofs_root_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
257 struct autofs_sb_info *sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp;
258 struct autofs_dirhash *dh = &sbi->dirhash;
259 struct autofs_dir_ent *ent;
260 unsigned int n;
261 int slsize;
262 struct autofs_symlink *sl;
264 DPRINTK(("autofs_root_symlink: %s <- ", symname));
265 autofs_say(dentry->d_name.name,dentry->d_name.len);
267 if ( !autofs_oz_mode(sbi) )
268 return -EPERM;
270 if ( autofs_hash_lookup(dh, &dentry->d_name) )
271 return -EEXIST;
273 n = find_first_zero_bit(sbi->symlink_bitmap,AUTOFS_MAX_SYMLINKS);
274 if ( n >= AUTOFS_MAX_SYMLINKS )
275 return -ENOSPC;
277 set_bit(n,sbi->symlink_bitmap);
278 sl = &sbi->symlink[n];
279 sl->len = strlen(symname);
280 sl->data = kmalloc(slsize = sl->len+1, GFP_KERNEL);
281 if ( !sl->data ) {
282 clear_bit(n,sbi->symlink_bitmap);
283 return -ENOSPC;
286 ent = kmalloc(sizeof(struct autofs_dir_ent), GFP_KERNEL);
287 if ( !ent ) {
288 kfree(sl->data);
289 clear_bit(n,sbi->symlink_bitmap);
290 return -ENOSPC;
293 ent->name = kmalloc(dentry->d_name.len+1, GFP_KERNEL);
294 if ( !ent->name ) {
295 kfree(sl->data);
296 kfree(ent);
297 clear_bit(n,sbi->symlink_bitmap);
298 return -ENOSPC;
301 memcpy(sl->data,symname,slsize);
302 sl->mtime = CURRENT_TIME;
304 ent->ino = AUTOFS_FIRST_SYMLINK + n;
305 ent->hash = dentry->d_name.hash;
306 memcpy(ent->name, dentry->d_name.name, 1+(ent->len = dentry->d_name.len));
308 autofs_hash_insert(dh,ent);
309 d_instantiate(dentry, iget(dir->i_sb,ent->ino));
311 return 0;
315 * NOTE!
317 * Normal filesystems would do a "d_delete()" to tell the VFS dcache
318 * that the file no longer exists. However, doing that means that the
319 * VFS layer can turn the dentry into a negative dentry, which we
320 * obviously do not want (we're dropping the entry not because it
321 * doesn't exist, but because it has timed out).
323 * Also see autofs_root_rmdir()..
325 static int autofs_root_unlink(struct inode *dir, struct dentry *dentry)
327 struct autofs_sb_info *sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp;
328 struct autofs_dirhash *dh = &sbi->dirhash;
329 struct autofs_dir_ent *ent;
330 unsigned int n;
332 if ( !autofs_oz_mode(sbi) )
333 return -EPERM;
335 ent = autofs_hash_lookup(dh, &dentry->d_name);
336 if ( !ent )
337 return -ENOENT;
339 n = ent->ino - AUTOFS_FIRST_SYMLINK;
340 if ( n >= AUTOFS_MAX_SYMLINKS || !test_bit(n,sbi->symlink_bitmap) )
341 return -EINVAL; /* Not a symlink inode, can't unlink */
343 autofs_hash_delete(ent);
344 clear_bit(n,sbi->symlink_bitmap);
345 kfree(sbi->symlink[n].data);
346 d_drop(dentry);
348 return 0;
351 static int autofs_root_rmdir(struct inode *dir, struct dentry *dentry)
353 struct autofs_sb_info *sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp;
354 struct autofs_dirhash *dh = &sbi->dirhash;
355 struct autofs_dir_ent *ent;
357 if ( !autofs_oz_mode(sbi) )
358 return -EPERM;
360 ent = autofs_hash_lookup(dh, &dentry->d_name);
361 if ( !ent )
362 return -ENOENT;
364 if ( (unsigned int)ent->ino < AUTOFS_FIRST_DIR_INO )
365 return -ENOTDIR; /* Not a directory */
367 autofs_hash_delete(ent);
368 dir->i_nlink--;
369 d_drop(dentry);
371 return 0;
374 static int autofs_root_mkdir(struct inode *dir, struct dentry *dentry, int mode)
376 struct autofs_sb_info *sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp;
377 struct autofs_dirhash *dh = &sbi->dirhash;
378 struct autofs_dir_ent *ent;
380 if ( !autofs_oz_mode(sbi) )
381 return -EPERM;
383 ent = autofs_hash_lookup(dh, &dentry->d_name);
384 if ( ent )
385 return -EEXIST;
387 if ( sbi->next_dir_ino < AUTOFS_FIRST_DIR_INO ) {
388 printk("autofs: Out of inode numbers -- what the heck did you do??\n");
389 return -ENOSPC;
392 ent = kmalloc(sizeof(struct autofs_dir_ent), GFP_KERNEL);
393 if ( !ent )
394 return -ENOSPC;
396 ent->name = kmalloc(dentry->d_name.len+1, GFP_KERNEL);
397 if ( !ent->name ) {
398 kfree(ent);
399 return -ENOSPC;
402 ent->hash = dentry->d_name.hash;
403 memcpy(ent->name, dentry->d_name.name, 1+(ent->len = dentry->d_name.len));
404 ent->ino = sbi->next_dir_ino++;
405 autofs_hash_insert(dh,ent);
406 dir->i_nlink++;
407 d_instantiate(dentry, iget(dir->i_sb,ent->ino));
409 return 0;
412 /* Get/set timeout ioctl() operation */
413 static inline int autofs_get_set_timeout(struct autofs_sb_info *sbi,
414 unsigned long *p)
416 int rv;
417 unsigned long ntimeout;
419 if ( (rv = get_user(ntimeout, p)) ||
420 (rv = put_user(sbi->exp_timeout/HZ, p)) )
421 return rv;
423 if ( ntimeout > ULONG_MAX/HZ )
424 sbi->exp_timeout = 0;
425 else
426 sbi->exp_timeout = ntimeout * HZ;
428 return 0;
431 /* Return protocol version */
432 static inline int autofs_get_protover(int *p)
434 return put_user(AUTOFS_PROTO_VERSION, p);
437 /* Perform an expiry operation */
438 static inline int autofs_expire_run(struct super_block *sb,
439 struct autofs_sb_info *sbi,
440 struct autofs_packet_expire *pkt_p)
442 struct autofs_dir_ent *ent;
443 struct autofs_packet_expire pkt;
445 memset(&pkt,0,sizeof pkt);
447 pkt.hdr.proto_version = AUTOFS_PROTO_VERSION;
448 pkt.hdr.type = autofs_ptype_expire;
450 if ( !sbi->exp_timeout ||
451 !(ent = autofs_expire(sb,sbi)) )
452 return -EAGAIN;
454 pkt.len = ent->len;
455 memcpy(pkt.name, ent->name, pkt.len);
456 pkt.name[pkt.len] = '\0';
458 if ( copy_to_user(pkt_p, &pkt, sizeof(struct autofs_packet_expire)) )
459 return -EFAULT;
461 return 0;
465 * ioctl()'s on the root directory is the chief method for the daemon to
466 * generate kernel reactions
468 static int autofs_root_ioctl(struct inode *inode, struct file *filp,
469 unsigned int cmd, unsigned long arg)
471 struct autofs_sb_info *sbi =
472 (struct autofs_sb_info *)inode->i_sb->u.generic_sbp;
474 DPRINTK(("autofs_ioctl: cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",cmd,arg,sbi,current->pgrp));
476 if ( _IOC_TYPE(cmd) != _IOC_TYPE(AUTOFS_IOC_FIRST) ||
477 _IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT )
478 return -ENOTTY;
480 if ( !autofs_oz_mode(sbi) && !capable(CAP_SYS_ADMIN) )
481 return -EPERM;
483 switch(cmd) {
484 case AUTOFS_IOC_READY: /* Wait queue: go ahead and retry */
485 return autofs_wait_release(sbi,arg,0);
486 case AUTOFS_IOC_FAIL: /* Wait queue: fail with ENOENT */
487 return autofs_wait_release(sbi,arg,-ENOENT);
488 case AUTOFS_IOC_CATATONIC: /* Enter catatonic mode (daemon shutdown) */
489 autofs_catatonic_mode(sbi);
490 return 0;
491 case AUTOFS_IOC_PROTOVER: /* Get protocol version */
492 return autofs_get_protover((int *)arg);
493 case AUTOFS_IOC_SETTIMEOUT:
494 return autofs_get_set_timeout(sbi,(unsigned long *)arg);
495 case AUTOFS_IOC_EXPIRE:
496 return autofs_expire_run(inode->i_sb,sbi,
497 (struct autofs_packet_expire *)arg);
498 default:
499 return -ENOSYS;