2005-04-17 02:20:36 +04:00
/* -*- c -*- ------------------------------------------------------------- *
*
* linux / fs / autofs / autofs_i . h
*
* Copyright 1997 - 1998 Transmeta Corporation - All Rights Reserved
2006-03-27 13:14:54 +04:00
* Copyright 2005 - 2006 Ian Kent < raven @ themaw . net >
2005-04-17 02:20:36 +04:00
*
* This file is part of the Linux kernel and is made available under
* the terms of the GNU General Public License , version 2 , or at your
* option , any later version , incorporated herein by reference .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Internal header file for autofs */
# include <linux/auto_fs4.h>
2008-10-16 09:02:54 +04:00
# include <linux/auto_dev-ioctl.h>
2006-03-23 14:00:41 +03:00
# include <linux/mutex.h>
2011-01-07 09:49:38 +03:00
# include <linux/spinlock.h>
2005-04-17 02:20:36 +04:00
# include <linux/list.h>
/* This is the range of ioctl() numbers we claim as ours */
# define AUTOFS_IOC_FIRST AUTOFS_IOC_READY
# define AUTOFS_IOC_COUNT 32
2008-10-16 09:02:54 +04:00
# define AUTOFS_DEV_IOCTL_IOC_FIRST (AUTOFS_DEV_IOCTL_VERSION)
# define AUTOFS_DEV_IOCTL_IOC_COUNT (AUTOFS_IOC_COUNT - 11)
2005-04-17 02:20:36 +04:00
# include <linux/kernel.h>
# include <linux/slab.h>
# include <linux/time.h>
# include <linux/string.h>
# include <linux/wait.h>
# include <linux/sched.h>
# include <linux/mount.h>
# include <linux/namei.h>
# include <asm/current.h>
# include <asm/uaccess.h>
/* #define DEBUG */
# ifdef DEBUG
2008-10-16 09:02:54 +04:00
# define DPRINTK(fmt, args...) \
do { \
printk ( KERN_DEBUG " pid %d: %s: " fmt " \n " , \
current - > pid , __func__ , # # args ) ; \
} while ( 0 )
2005-04-17 02:20:36 +04:00
# else
2008-10-16 09:02:54 +04:00
# define DPRINTK(fmt, args...) do {} while (0)
2005-04-17 02:20:36 +04:00
# endif
2008-10-16 09:02:54 +04:00
# define AUTOFS_WARN(fmt, args...) \
do { \
printk ( KERN_WARNING " pid %d: %s: " fmt " \n " , \
current - > pid , __func__ , # # args ) ; \
} while ( 0 )
# define AUTOFS_ERROR(fmt, args...) \
do { \
printk ( KERN_ERR " pid %d: %s: " fmt " \n " , \
current - > pid , __func__ , # # args ) ; \
} while ( 0 )
2011-01-07 09:49:38 +03:00
extern spinlock_t autofs4_lock ;
2005-04-17 02:20:36 +04:00
/* Unified info structure. This is pointed to by both the dentry and
inode structures . Each file in the filesystem has an instance of this
structure . It holds a reference to the dentry , so dentries are never
flushed while the file exists . All name lookups are dealt with at the
dentry level , although the filesystem can interfere in the validation
process . Readdir is implemented by traversing the dentry lists . */
struct autofs_info {
struct dentry * dentry ;
struct inode * inode ;
int flags ;
2008-07-24 08:30:27 +04:00
struct completion expire_complete ;
2008-07-24 08:30:12 +04:00
struct list_head active ;
2009-12-16 03:45:42 +03:00
int active_count ;
2008-07-24 08:30:09 +04:00
struct list_head expiring ;
2007-02-21 00:58:10 +03:00
2005-04-17 02:20:36 +04:00
struct autofs_sb_info * sbi ;
unsigned long last_used ;
2006-03-27 13:14:46 +04:00
atomic_t count ;
2005-04-17 02:20:36 +04:00
2008-10-16 09:02:52 +04:00
uid_t uid ;
gid_t gid ;
2005-04-17 02:20:36 +04:00
mode_t mode ;
size_t size ;
void ( * free ) ( struct autofs_info * ) ;
union {
const char * symlink ;
} u ;
} ;
# define AUTOFS_INF_EXPIRING (1<<0) /* dentry is in the process of expiring */
2008-07-24 08:30:27 +04:00
# define AUTOFS_INF_MOUNTPOINT (1<<1) /* mountpoint status for direct expire */
2009-12-16 03:45:45 +03:00
# define AUTOFS_INF_PENDING (1<<2) /* dentry pending mount */
2005-04-17 02:20:36 +04:00
struct autofs_wait_queue {
wait_queue_head_t queue ;
struct autofs_wait_queue * next ;
autofs_wqt_t wait_queue_token ;
/* We use the following to see what we are waiting for */
2008-07-24 08:30:16 +04:00
struct qstr name ;
2006-03-27 13:14:55 +04:00
u32 dev ;
u64 ino ;
uid_t uid ;
gid_t gid ;
pid_t pid ;
pid_t tgid ;
2005-04-17 02:20:36 +04:00
/* This is for status reporting upon return */
int status ;
2008-07-24 08:30:21 +04:00
unsigned int wait_ctr ;
2005-04-17 02:20:36 +04:00
} ;
# define AUTOFS_SBI_MAGIC 0x6d4a556d
struct autofs_sb_info {
u32 magic ;
2006-03-27 13:14:49 +04:00
int pipefd ;
2005-04-17 02:20:36 +04:00
struct file * pipe ;
pid_t oz_pgrp ;
int catatonic ;
int version ;
int sub_version ;
2006-03-27 13:14:49 +04:00
int min_proto ;
int max_proto ;
2005-04-17 02:20:36 +04:00
unsigned long exp_timeout ;
2006-03-27 13:14:54 +04:00
unsigned int type ;
2005-04-17 02:20:36 +04:00
int reghost_enabled ;
int needs_reghost ;
struct super_block * sb ;
2006-03-23 14:00:41 +03:00
struct mutex wq_mutex ;
2005-05-01 19:59:17 +04:00
spinlock_t fs_lock ;
2005-04-17 02:20:36 +04:00
struct autofs_wait_queue * queues ; /* Wait queue pointer */
2008-07-24 08:30:09 +04:00
spinlock_t lookup_lock ;
2008-07-24 08:30:12 +04:00
struct list_head active_list ;
2008-07-24 08:30:09 +04:00
struct list_head expiring_list ;
2005-04-17 02:20:36 +04:00
} ;
static inline struct autofs_sb_info * autofs4_sbi ( struct super_block * sb )
{
return ( struct autofs_sb_info * ) ( sb - > s_fs_info ) ;
}
static inline struct autofs_info * autofs4_dentry_ino ( struct dentry * dentry )
{
return ( struct autofs_info * ) ( dentry - > d_fsdata ) ;
}
/* autofs4_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 " . ) */
static inline int autofs4_oz_mode ( struct autofs_sb_info * sbi ) {
2007-10-19 10:39:46 +04:00
return sbi - > catatonic | | task_pgrp_nr ( current ) = = sbi - > oz_pgrp ;
2005-04-17 02:20:36 +04:00
}
/* Does a dentry have some pending activity? */
static inline int autofs4_ispending ( struct dentry * dentry )
{
struct autofs_info * inf = autofs4_dentry_ino ( dentry ) ;
2009-12-16 03:45:45 +03:00
if ( inf - > flags & AUTOFS_INF_PENDING )
2005-05-01 19:59:17 +04:00
return 1 ;
2008-07-24 08:30:26 +04:00
if ( inf - > flags & AUTOFS_INF_EXPIRING )
return 1 ;
2005-05-01 19:59:17 +04:00
2008-07-24 08:30:26 +04:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
static inline void autofs4_copy_atime ( struct file * src , struct file * dst )
{
2006-12-08 13:36:46 +03:00
dst - > f_path . dentry - > d_inode - > i_atime =
src - > f_path . dentry - > d_inode - > i_atime ;
2005-04-17 02:20:36 +04:00
return ;
}
struct inode * autofs4_get_inode ( struct super_block * , struct autofs_info * ) ;
void autofs4_free_ino ( struct autofs_info * ) ;
/* Expiration */
int is_autofs4_dentry ( struct dentry * ) ;
2008-07-24 08:30:28 +04:00
int autofs4_expire_wait ( struct dentry * dentry ) ;
2005-04-17 02:20:36 +04:00
int autofs4_expire_run ( struct super_block * , struct vfsmount * ,
struct autofs_sb_info * ,
struct autofs_packet_expire __user * ) ;
2009-04-01 02:24:43 +04:00
int autofs4_do_expire_multi ( struct super_block * sb , struct vfsmount * mnt ,
struct autofs_sb_info * sbi , int when ) ;
2005-04-17 02:20:36 +04:00
int autofs4_expire_multi ( struct super_block * , struct vfsmount * ,
struct autofs_sb_info * , int __user * ) ;
2008-10-16 09:02:54 +04:00
struct dentry * autofs4_expire_direct ( struct super_block * sb ,
struct vfsmount * mnt ,
struct autofs_sb_info * sbi , int how ) ;
struct dentry * autofs4_expire_indirect ( struct super_block * sb ,
struct vfsmount * mnt ,
struct autofs_sb_info * sbi , int how ) ;
/* Device node initialization */
int autofs_dev_ioctl_init ( void ) ;
void autofs_dev_ioctl_exit ( void ) ;
2005-04-17 02:20:36 +04:00
/* Operations structures */
2007-02-12 11:55:38 +03:00
extern const struct inode_operations autofs4_symlink_inode_operations ;
extern const struct inode_operations autofs4_dir_inode_operations ;
extern const struct inode_operations autofs4_root_inode_operations ;
extern const struct inode_operations autofs4_indirect_root_inode_operations ;
extern const struct inode_operations autofs4_direct_root_inode_operations ;
2006-03-28 13:56:42 +04:00
extern const struct file_operations autofs4_dir_operations ;
extern const struct file_operations autofs4_root_operations ;
2005-04-17 02:20:36 +04:00
2011-01-14 21:45:58 +03:00
/* Operations methods */
struct vfsmount * autofs4_d_automount ( struct path * ) ;
/* VFS automount flags management functions */
static inline void __managed_dentry_set_automount ( struct dentry * dentry )
{
dentry - > d_flags | = DCACHE_NEED_AUTOMOUNT ;
}
static inline void managed_dentry_set_automount ( struct dentry * dentry )
{
spin_lock ( & dentry - > d_lock ) ;
__managed_dentry_set_automount ( dentry ) ;
spin_unlock ( & dentry - > d_lock ) ;
}
static inline void __managed_dentry_clear_automount ( struct dentry * dentry )
{
dentry - > d_flags & = ~ DCACHE_NEED_AUTOMOUNT ;
}
static inline void managed_dentry_clear_automount ( struct dentry * dentry )
{
spin_lock ( & dentry - > d_lock ) ;
__managed_dentry_clear_automount ( dentry ) ;
spin_unlock ( & dentry - > d_lock ) ;
}
2005-04-17 02:20:36 +04:00
/* Initializing function */
int autofs4_fill_super ( struct super_block * , void * , int ) ;
struct autofs_info * autofs4_init_ino ( struct autofs_info * , struct autofs_sb_info * sbi , mode_t mode ) ;
/* Queue management functions */
int autofs4_wait ( struct autofs_sb_info * , struct dentry * , enum autofs_notify ) ;
int autofs4_wait_release ( struct autofs_sb_info * , autofs_wqt_t , int ) ;
void autofs4_catatonic_mode ( struct autofs_sb_info * ) ;
2006-03-27 13:14:55 +04:00
static inline u32 autofs4_get_dev ( struct autofs_sb_info * sbi )
{
return new_encode_dev ( sbi - > sb - > s_dev ) ;
}
static inline u64 autofs4_get_ino ( struct autofs_sb_info * sbi )
{
return sbi - > sb - > s_root - > d_inode - > i_ino ;
}
2005-04-17 02:20:36 +04:00
static inline int simple_positive ( struct dentry * dentry )
{
return dentry - > d_inode & & ! d_unhashed ( dentry ) ;
}
2011-01-07 09:49:34 +03:00
static inline void __autofs4_add_expiring ( struct dentry * dentry )
{
struct autofs_sb_info * sbi = autofs4_sbi ( dentry - > d_sb ) ;
struct autofs_info * ino = autofs4_dentry_ino ( dentry ) ;
if ( ino ) {
if ( list_empty ( & ino - > expiring ) )
list_add ( & ino - > expiring , & sbi - > expiring_list ) ;
}
return ;
}
2009-12-16 03:45:43 +03:00
static inline void autofs4_add_expiring ( struct dentry * dentry )
{
struct autofs_sb_info * sbi = autofs4_sbi ( dentry - > d_sb ) ;
struct autofs_info * ino = autofs4_dentry_ino ( dentry ) ;
if ( ino ) {
spin_lock ( & sbi - > lookup_lock ) ;
if ( list_empty ( & ino - > expiring ) )
list_add ( & ino - > expiring , & sbi - > expiring_list ) ;
spin_unlock ( & sbi - > lookup_lock ) ;
}
return ;
}
static inline void autofs4_del_expiring ( struct dentry * dentry )
{
struct autofs_sb_info * sbi = autofs4_sbi ( dentry - > d_sb ) ;
struct autofs_info * ino = autofs4_dentry_ino ( dentry ) ;
if ( ino ) {
spin_lock ( & sbi - > lookup_lock ) ;
if ( ! list_empty ( & ino - > expiring ) )
list_del_init ( & ino - > expiring ) ;
spin_unlock ( & sbi - > lookup_lock ) ;
}
return ;
}
2006-03-28 13:56:29 +04:00
void autofs4_dentry_release ( struct dentry * ) ;
2006-10-11 12:22:15 +04:00
extern void autofs4_kill_sb ( struct super_block * ) ;