lkml.org 
[lkml]   [1999]   [Jan]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    SubjectRe: 2.2.0p6: autofs bug! unmountable filesystem
    Date
    > Hi,
    >
    > I can reproduce a autofs bug whereby the autofs filesystem cannot be
    > unmounted.
    >
    > It is simple: first mount the autofs filesystem. I have RH5.2 so to do
    > this I use /etc/rc.d/init.d/autofs start
    >
    > Now I mount my CD rom drive by doing cd /misc/cd
    >
    > This next step seems to break things. _Manually_ umount /misc/cd, rather
    > than letting autofs timeout (before doing the the cwd will need to be
    > moved from /misc/cd :-)
    >
    > Now, /misc cannot be unmounted, it is permanently reported as busy. Not
    > good.

    Hi there,

    Try the following patch, please:

    diff -ur stock/linux-2.2.0-pre6/fs/autofs/autofs_i.h linux-2.2.0-pre6/fs/autofs/autofs_i.h
    --- stock/linux-2.2.0-pre6/fs/autofs/autofs_i.h Fri Jan 8 15:53:20 1999
    +++ linux-2.2.0-pre6/fs/autofs/autofs_i.h Mon Jan 11 11:02:16 1999
    @@ -92,10 +92,6 @@

    #define AUTOFS_SYMLINK_BITMAP_LEN ((AUTOFS_MAX_SYMLINKS+31)/32)

    -#ifndef END_OF_TIME
    -#define END_OF_TIME ((time_t)((unsigned long)((time_t)(~0UL)) >> 1))
    -#endif
    -
    #define AUTOFS_SBI_MAGIC 0x6d4a556d

    struct autofs_sb_info {
    @@ -111,6 +107,11 @@
    u32 symlink_bitmap[AUTOFS_SYMLINK_BITMAP_LEN];
    };

    +extern inline struct autofs_sb_info *autofs_sbi(struct super_block *sb)
    +{
    + return (struct autofs_sb_info *)(sb->u.generic_sbp);
    +}
    +
    /* autofs_oz_mode(): do we see the man behind the curtain? (The
    processes which do manipulations for us in user space sees the raw
    filesystem without "magic".) */
    @@ -126,6 +127,7 @@
    void autofs_hash_insert(struct autofs_dirhash *,struct autofs_dir_ent *);
    void autofs_hash_delete(struct autofs_dir_ent *);
    struct autofs_dir_ent *autofs_hash_enum(const struct autofs_dirhash *,off_t *,struct autofs_dir_ent *);
    +void autofs_hash_dputall(struct autofs_dirhash *);
    void autofs_hash_nuke(struct autofs_dirhash *);

    /* Expiration-handling functions */
    diff -ur stock/linux-2.2.0-pre6/fs/autofs/dirhash.c linux-2.2.0-pre6/fs/autofs/dirhash.c
    --- stock/linux-2.2.0-pre6/fs/autofs/dirhash.c Tue Oct 27 14:13:53 1998
    +++ linux-2.2.0-pre6/fs/autofs/dirhash.c Mon Jan 11 11:06:40 1999
    @@ -47,7 +47,7 @@

    ent = dh->expiry_head.exp_next;

    - if ( ent == &(dh->expiry_head) )
    + if ( ent == &(dh->expiry_head) || sbi->catatonic )
    return NULL; /* No entries */

    while ( jiffies - ent->last_usage >= timeout ) {
    @@ -62,8 +62,10 @@
    dentry = ent->dentry;

    if ( !dentry ) {
    + /* Should only happen in catatonic mode */
    printk("autofs: dentry == NULL but inode range is directory, entry %s\n", ent->name);
    autofs_delete_usage(ent);
    + continue;
    }

    if ( !dentry->d_inode ) {
    @@ -200,6 +202,23 @@

    *ptr = ((bucket+1) << 16) + ecount;
    return ent;
    +}
    +
    +/* Iterate over all the ents, and remove all dentry pointers. Used on
    + entering catatonic mode, in order to make the filesystem unmountable. */
    +void autofs_hash_dputall(struct autofs_dirhash *dh)
    +{
    + int i;
    + struct autofs_dir_ent *ent, *nent;
    +
    + for ( i = 0 ; i < AUTOFS_HASH_SIZE ; i++ ) {
    + for ( ent = dh->h[i] ; ent ; ent = ent->next ) {
    + if ( ent->dentry ) {
    + dput(ent->dentry);
    + ent->dentry = NULL;
    + }
    + }
    + }
    }

    /* Delete everything. This is used on filesystem destruction, so we
    diff -ur stock/linux-2.2.0-pre6/fs/autofs/inode.c linux-2.2.0-pre6/fs/autofs/inode.c
    --- stock/linux-2.2.0-pre6/fs/autofs/inode.c Thu Dec 17 16:51:36 1998
    +++ linux-2.2.0-pre6/fs/autofs/inode.c Mon Jan 11 10:46:26 1999
    @@ -34,8 +34,7 @@

    static void autofs_put_super(struct super_block *sb)
    {
    - struct autofs_sb_info *sbi =
    - (struct autofs_sb_info *) sb->u.generic_sbp;
    + struct autofs_sb_info *sbi = autofs_sbi(sb);
    unsigned int n;

    if ( !sbi->catatonic )
    @@ -297,8 +296,7 @@
    {
    ino_t ino = inode->i_ino;
    unsigned int n;
    - struct autofs_sb_info *sbi =
    - (struct autofs_sb_info *) inode->i_sb->u.generic_sbp;
    + struct autofs_sb_info *sbi = autofs_sbi(inode->i_sb);

    /* Initialize to the default case (stub directory) */

    diff -ur stock/linux-2.2.0-pre6/fs/autofs/root.c linux-2.2.0-pre6/fs/autofs/root.c
    --- stock/linux-2.2.0-pre6/fs/autofs/root.c Thu Dec 17 16:51:36 1998
    +++ linux-2.2.0-pre6/fs/autofs/root.c Mon Jan 11 11:08:36 1999
    @@ -68,13 +68,15 @@
    {
    struct autofs_dir_ent *ent = NULL;
    struct autofs_dirhash *dirhash;
    + struct autofs_sb_info *sbi;
    struct inode * inode = filp->f_dentry->d_inode;
    off_t onr, nr;

    if (!inode || !S_ISDIR(inode->i_mode))
    return -ENOTDIR;

    - dirhash = &((struct autofs_sb_info *)inode->i_sb->u.generic_sbp)->dirhash;
    + sbi = autofs_sbi(inode->i_sb);
    + dirhash = &sbi->dirhash;
    nr = filp->f_pos;

    switch(nr)
    @@ -168,12 +170,10 @@
    */
    static int autofs_revalidate(struct dentry * dentry)
    {
    - struct autofs_sb_info *sbi;
    struct inode * dir = dentry->d_parent->d_inode;
    + struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb);
    struct autofs_dir_ent *ent;

    - sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp;
    -
    /* Pending dentry */
    if ( dentry->d_flags & DCACHE_AUTOFS_PENDING ) {
    if (autofs_oz_mode(sbi))
    @@ -220,7 +220,7 @@
    if (!S_ISDIR(dir->i_mode))
    return -ENOTDIR;

    - sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp;
    + sbi = autofs_sbi(dir->i_sb);

    oz_mode = autofs_oz_mode(sbi);
    DPRINTK(("autofs_lookup: pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d\n",
    @@ -267,7 +267,7 @@

    static int autofs_root_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
    {
    - struct autofs_sb_info *sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp;
    + struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb);
    struct autofs_dirhash *dh = &sbi->dirhash;
    struct autofs_dir_ent *ent;
    unsigned int n;
    @@ -338,7 +338,7 @@
    */
    static int autofs_root_unlink(struct inode *dir, struct dentry *dentry)
    {
    - struct autofs_sb_info *sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp;
    + struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb);
    struct autofs_dirhash *dh = &sbi->dirhash;
    struct autofs_dir_ent *ent;
    unsigned int n;
    @@ -365,7 +365,7 @@

    static int autofs_root_rmdir(struct inode *dir, struct dentry *dentry)
    {
    - struct autofs_sb_info *sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp;
    + struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb);
    struct autofs_dirhash *dh = &sbi->dirhash;
    struct autofs_dir_ent *ent;

    @@ -393,7 +393,7 @@

    static int autofs_root_mkdir(struct inode *dir, struct dentry *dentry, int mode)
    {
    - struct autofs_sb_info *sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp;
    + struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb);
    struct autofs_dirhash *dh = &sbi->dirhash;
    struct autofs_dir_ent *ent;
    ino_t ino;
    @@ -492,8 +492,7 @@
    static int autofs_root_ioctl(struct inode *inode, struct file *filp,
    unsigned int cmd, unsigned long arg)
    {
    - struct autofs_sb_info *sbi =
    - (struct autofs_sb_info *)inode->i_sb->u.generic_sbp;
    + struct autofs_sb_info *sbi = autofs_sbi(inode->i_sb);

    DPRINTK(("autofs_ioctl: cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",cmd,arg,sbi,current->pgrp));

    diff -ur stock/linux-2.2.0-pre6/fs/autofs/waitq.c linux-2.2.0-pre6/fs/autofs/waitq.c
    --- stock/linux-2.2.0-pre6/fs/autofs/waitq.c Mon Dec 28 00:47:48 1998
    +++ linux-2.2.0-pre6/fs/autofs/waitq.c Mon Jan 11 11:03:03 1999
    @@ -41,6 +41,7 @@
    wq = nwq;
    }
    fput(sbi->pipe); /* Close the pipe */
    + autofs_hash_dputall(&sbi->dirhash); /* Remove all dentry pointers */
    }

    static int autofs_write(struct file *file, const void *addr, int bytes)
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.rutgers.edu
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 13:49    [W:2.470 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site