int autofs_fill_super(struct super_block *s, void *data, int silent) { struct inode * root_inode; struct dentry * root; struct file * pipe; int pipefd; struct autofs_sb_info *sbi; int minproto, maxproto; pid_t pgid; sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); if (!sbi) goto fail_unlock; DPRINTK(("autofs: starting up, sbi = %p\n",sbi)); s->s_fs_info = sbi; sbi->magic = AUTOFS_SBI_MAGIC; sbi->pipe = NULL; sbi->catatonic = 1; sbi->exp_timeout = 0; autofs_initialize_hash(&sbi->dirhash); sbi->queues = NULL; memset(sbi->symlink_bitmap, 0, sizeof(long)*AUTOFS_SYMLINK_BITMAP_LEN); sbi->next_dir_ino = AUTOFS_FIRST_DIR_INO; s->s_blocksize = 1024; s->s_blocksize_bits = 10; s->s_magic = AUTOFS_SUPER_MAGIC; s->s_op = &autofs_sops; s->s_time_gran = 1; sbi->sb = s; root_inode = iget(s, AUTOFS_ROOT_INO); root = d_alloc_root(root_inode); pipe = NULL; if (!root) goto fail_iput; /* Can this call block? - WTF cares? s is locked. */ if (parse_options(data, &pipefd, &root_inode->i_uid, &root_inode->i_gid, &pgid, &minproto, &maxproto)) { printk("autofs: called with bogus options\n"); goto fail_dput; } /* Couldn't this be tested earlier? */ if (minproto > AUTOFS_PROTO_VERSION || maxproto < AUTOFS_PROTO_VERSION) { printk("autofs: kernel does not match daemon version\n"); goto fail_dput; } DPRINTK(("autofs: pipe fd = %d, pgrp = %u\n", pipefd, pgid)); sbi->oz_pgrp = find_get_pid(pgid); if (!sbi->oz_pgrp) { printk("autofs: could not find process group %d\n", pgid); goto fail_dput; } pipe = fget(pipefd); if (!pipe) { printk("autofs: could not open pipe file descriptor\n"); goto fail_put_pid; } if (!pipe->f_op || !pipe->f_op->write) goto fail_fput; sbi->pipe = pipe; sbi->catatonic = 0; /* * Success! Install the root dentry now to indicate completion. */ s->s_root = root; return 0; fail_fput: printk("autofs: pipe file descriptor does not contain proper ops\n"); fput(pipe); fail_put_pid: put_pid(sbi->oz_pgrp); fail_dput: dput(root); goto fail_free; fail_iput: printk("autofs: get root dentry failed\n"); iput(root_inode); fail_free: kfree(sbi); s->s_fs_info = NULL; fail_unlock: return -EINVAL; }
struct super_block *autofs_read_super(struct super_block *s, void *data, int silent) { int pipefd; struct autofs_sb_info *sbi; int minproto, maxproto; MOD_INC_USE_COUNT; lock_super(s); sbi = (struct autofs_sb_info *) kmalloc(sizeof(struct autofs_sb_info), GFP_KERNEL); if ( !sbi ) { s->s_dev = 0; MOD_DEC_USE_COUNT; return NULL; } DPRINTK(("autofs: starting up, sbi = %p\n",sbi)); s->u.generic_sbp = sbi; sbi->magic = AUTOFS_SBI_MAGIC; sbi->catatonic = 0; sbi->exp_timeout = 0; sbi->oz_pgrp = current->pgrp; autofs_initialize_hash(&sbi->dirhash); sbi->queues = NULL; memset(sbi->symlink_bitmap, 0, sizeof(u32)*AUTOFS_SYMLINK_BITMAP_LEN); sbi->next_dir_ino = AUTOFS_FIRST_DIR_INO; s->s_blocksize = 1024; s->s_blocksize_bits = 10; s->s_magic = AUTOFS_SUPER_MAGIC; s->s_op = &autofs_sops; unlock_super(s); if (!(s->s_mounted = iget(s, AUTOFS_ROOT_INO))) { s->s_dev = 0; kfree(sbi); printk("autofs: get root inode failed\n"); MOD_DEC_USE_COUNT; return NULL; } if ( parse_options(data,&pipefd,&s->s_mounted->i_uid,&s->s_mounted->i_gid,&sbi->oz_pgrp,&minproto,&maxproto) ) { iput(s->s_mounted); s->s_dev = 0; kfree(sbi); printk("autofs: called with bogus options\n"); MOD_DEC_USE_COUNT; return NULL; } if ( minproto > AUTOFS_PROTO_VERSION || maxproto < AUTOFS_PROTO_VERSION ) { iput(s->s_mounted); s->s_dev = 0; kfree(sbi); printk("autofs: kernel does not match daemon version\n"); MOD_DEC_USE_COUNT; return NULL; } DPRINTK(("autofs: pipe fd = %d, pgrp = %u\n", pipefd, sbi->oz_pgrp)); sbi->pipe = fget(pipefd); if ( !sbi->pipe || !sbi->pipe->f_op || !sbi->pipe->f_op->write ) { if ( sbi->pipe ) { fput(sbi->pipe, sbi->pipe->f_inode); printk("autofs: pipe file descriptor does not contain proper ops\n"); } else { printk("autofs: could not open pipe file descriptor\n"); } iput(s->s_mounted); s->s_dev = 0; kfree(sbi); MOD_DEC_USE_COUNT; return NULL; } return s; }