]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - fs/afs/mntpt.c
MIPS: Fix always CONFIG_LOONGSON_UART_BASE=y
[mv-sheeva.git] / fs / afs / mntpt.c
index 6153417caf57e2b9219bbfdd40970c262b65fdcf..aa59184151d05be48e35527ab205170f6c43d4f2 100644 (file)
@@ -24,7 +24,6 @@ static struct dentry *afs_mntpt_lookup(struct inode *dir,
                                       struct dentry *dentry,
                                       struct nameidata *nd);
 static int afs_mntpt_open(struct inode *inode, struct file *file);
-static void *afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd);
 static void afs_mntpt_expiry_timed_out(struct work_struct *work);
 
 const struct file_operations afs_mntpt_file_operations = {
@@ -34,13 +33,11 @@ const struct file_operations afs_mntpt_file_operations = {
 
 const struct inode_operations afs_mntpt_inode_operations = {
        .lookup         = afs_mntpt_lookup,
-       .follow_link    = afs_mntpt_follow_link,
        .readlink       = page_readlink,
        .getattr        = afs_getattr,
 };
 
 const struct inode_operations afs_autocell_inode_operations = {
-       .follow_link    = afs_mntpt_follow_link,
        .getattr        = afs_getattr,
 };
 
@@ -88,6 +85,7 @@ int afs_mntpt_check_symlink(struct afs_vnode *vnode, struct key *key)
                _debug("symlink is a mountpoint");
                spin_lock(&vnode->lock);
                set_bit(AFS_VNODE_MOUNTPOINT, &vnode->flags);
+               vnode->vfs_inode.i_flags |= S_AUTOMOUNT;
                spin_unlock(&vnode->lock);
        }
 
@@ -238,52 +236,24 @@ error_no_devname:
 }
 
 /*
- * follow a link from a mountpoint directory, thus causing it to be mounted
+ * handle an automount point
  */
-static void *afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd)
+struct vfsmount *afs_d_automount(struct path *path)
 {
        struct vfsmount *newmnt;
-       int err;
 
-       _enter("%p{%s},{%s:%p{%s},}",
-              dentry,
-              dentry->d_name.name,
-              nd->path.mnt->mnt_devname,
-              dentry,
-              nd->path.dentry->d_name.name);
-
-       dput(nd->path.dentry);
-       nd->path.dentry = dget(dentry);
+       _enter("{%s,%s}", path->mnt->mnt_devname, path->dentry->d_name.name);
 
-       newmnt = afs_mntpt_do_automount(nd->path.dentry);
-       if (IS_ERR(newmnt)) {
-               path_put(&nd->path);
-               return (void *)newmnt;
-       }
-
-       mntget(newmnt);
-       err = do_add_mount(newmnt, &nd->path, MNT_SHRINKABLE, &afs_vfsmounts);
-       switch (err) {
-       case 0:
-               path_put(&nd->path);
-               nd->path.mnt = newmnt;
-               nd->path.dentry = dget(newmnt->mnt_root);
-               schedule_delayed_work(&afs_mntpt_expiry_timer,
-                                     afs_mntpt_expiry_timeout * HZ);
-               break;
-       case -EBUSY:
-               /* someone else made a mount here whilst we were busy */
-               while (d_mountpoint(nd->path.dentry) &&
-                      follow_down(&nd->path))
-                       ;
-               err = 0;
-       default:
-               mntput(newmnt);
-               break;
-       }
+       newmnt = afs_mntpt_do_automount(path->dentry);
+       if (IS_ERR(newmnt))
+               return newmnt;
 
-       _leave(" = %d", err);
-       return ERR_PTR(err);
+       mntget(newmnt); /* prevent immediate expiration */
+       mnt_set_expiry(newmnt, &afs_vfsmounts);
+       queue_delayed_work(afs_wq, &afs_mntpt_expiry_timer,
+                          afs_mntpt_expiry_timeout * HZ);
+       _leave(" = %p {%s}", newmnt, newmnt->mnt_devname);
+       return newmnt;
 }
 
 /*
@@ -295,8 +265,8 @@ static void afs_mntpt_expiry_timed_out(struct work_struct *work)
 
        if (!list_empty(&afs_vfsmounts)) {
                mark_mounts_for_expiry(&afs_vfsmounts);
-               schedule_delayed_work(&afs_mntpt_expiry_timer,
-                                     afs_mntpt_expiry_timeout * HZ);
+               queue_delayed_work(afs_wq, &afs_mntpt_expiry_timer,
+                                  afs_mntpt_expiry_timeout * HZ);
        }
 
        _leave("");
@@ -310,6 +280,5 @@ void afs_mntpt_kill_timer(void)
        _enter("");
 
        ASSERT(list_empty(&afs_vfsmounts));
-       cancel_delayed_work(&afs_mntpt_expiry_timer);
-       flush_scheduled_work();
+       cancel_delayed_work_sync(&afs_mntpt_expiry_timer);
 }