Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / fs / autofs / root.c
index 74ad37a..9cac08d 100644 (file)
@@ -10,6 +10,7 @@
  *
  * ------------------------------------------------------------------------- */
 
+#include <linux/capability.h>
 #include <linux/errno.h>
 #include <linux/stat.h>
 #include <linux/param.h>
@@ -25,7 +26,7 @@ static int autofs_root_rmdir(struct inode *,struct dentry *);
 static int autofs_root_mkdir(struct inode *,struct dentry *,int);
 static int autofs_root_ioctl(struct inode *, struct file *,unsigned int,unsigned long);
 
-struct file_operations autofs_root_operations = {
+const struct file_operations autofs_root_operations = {
        .read           = generic_read_dir,
        .readdir        = autofs_root_readdir,
        .ioctl          = autofs_root_ioctl,
@@ -229,18 +230,24 @@ static struct dentry *autofs_root_lookup(struct inode *dir, struct dentry *dentr
        dentry->d_flags |= DCACHE_AUTOFS_PENDING;
        d_add(dentry, NULL);
 
-       up(&dir->i_sem);
+       mutex_unlock(&dir->i_mutex);
        autofs_revalidate(dentry, nd);
-       down(&dir->i_sem);
+       mutex_lock(&dir->i_mutex);
 
        /*
         * If we are still pending, check if we had to handle
         * a signal. If so we can force a restart..
         */
        if (dentry->d_flags & DCACHE_AUTOFS_PENDING) {
+               /* See if we were interrupted */
                if (signal_pending(current)) {
-                       unlock_kernel();
-                       return ERR_PTR(-ERESTARTNOINTR);
+                       sigset_t *sigset = &current->pending.signal;
+                       if (sigismember (sigset, SIGKILL) ||
+                           sigismember (sigset, SIGQUIT) ||
+                           sigismember (sigset, SIGINT)) {
+                               unlock_kernel();
+                               return ERR_PTR(-ERESTARTNOINTR);
+                       }
                }
        }
        unlock_kernel();
@@ -468,7 +475,7 @@ static int autofs_root_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 
 /* Get/set timeout ioctl() operation */
 static inline int autofs_get_set_timeout(struct autofs_sb_info *sbi,
-                                        unsigned long *p)
+                                        unsigned long __user *p)
 {
        unsigned long ntimeout;
 
@@ -485,7 +492,7 @@ static inline int autofs_get_set_timeout(struct autofs_sb_info *sbi,
 }
 
 /* Return protocol version */
-static inline int autofs_get_protover(int *p)
+static inline int autofs_get_protover(int __user *p)
 {
        return put_user(AUTOFS_PROTO_VERSION, p);
 }
@@ -494,7 +501,7 @@ static inline int autofs_get_protover(int *p)
 static inline int autofs_expire_run(struct super_block *sb,
                                    struct autofs_sb_info *sbi,
                                    struct vfsmount *mnt,
-                                   struct autofs_packet_expire *pkt_p)
+                                   struct autofs_packet_expire __user *pkt_p)
 {
        struct autofs_dir_ent *ent;
        struct autofs_packet_expire pkt;
@@ -526,6 +533,7 @@ static int autofs_root_ioctl(struct inode *inode, struct file *filp,
                             unsigned int cmd, unsigned long arg)
 {
        struct autofs_sb_info *sbi = autofs_sbi(inode->i_sb);
+       void __user *argp = (void __user *)arg;
 
        DPRINTK(("autofs_ioctl: cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",cmd,arg,sbi,process_group(current)));
 
@@ -545,12 +553,12 @@ static int autofs_root_ioctl(struct inode *inode, struct file *filp,
                autofs_catatonic_mode(sbi);
                return 0;
        case AUTOFS_IOC_PROTOVER: /* Get protocol version */
-               return autofs_get_protover((int *)arg);
+               return autofs_get_protover(argp);
        case AUTOFS_IOC_SETTIMEOUT:
-               return autofs_get_set_timeout(sbi,(unsigned long *)arg);
+               return autofs_get_set_timeout(sbi, argp);
        case AUTOFS_IOC_EXPIRE:
                return autofs_expire_run(inode->i_sb, sbi, filp->f_vfsmnt,
-                                        (struct autofs_packet_expire *)arg);
+                                        argp);
        default:
                return -ENOSYS;
        }