fs/fcntl.c:kill_fasync_rcu() fa_lock must be IRQ-safe
[sfrench/cifs-2.6.git] / fs / fcntl.c
index f74d270ba1554034b02c7532ece41556ca9040c0..9d175d623aabc5e7c99a83e75e6c970a340465c6 100644 (file)
@@ -274,7 +274,7 @@ static int f_setown_ex(struct file *filp, unsigned long arg)
 
        ret = copy_from_user(&owner, owner_p, sizeof(owner));
        if (ret)
-               return ret;
+               return -EFAULT;
 
        switch (owner.type) {
        case F_OWNER_TID:
@@ -332,8 +332,11 @@ static int f_getown_ex(struct file *filp, unsigned long arg)
        }
        read_unlock(&filp->f_owner.lock);
 
-       if (!ret)
+       if (!ret) {
                ret = copy_to_user(owner_p, &owner, sizeof(owner));
+               if (ret)
+                       ret = -EFAULT;
+       }
        return ret;
 }
 
@@ -730,12 +733,14 @@ static void kill_fasync_rcu(struct fasync_struct *fa, int sig, int band)
 {
        while (fa) {
                struct fown_struct *fown;
+               unsigned long flags;
+
                if (fa->magic != FASYNC_MAGIC) {
                        printk(KERN_ERR "kill_fasync: bad magic number in "
                               "fasync_struct!\n");
                        return;
                }
-               spin_lock(&fa->fa_lock);
+               spin_lock_irqsave(&fa->fa_lock, flags);
                if (fa->fa_file) {
                        fown = &fa->fa_file->f_owner;
                        /* Don't send SIGURG to processes which have not set a
@@ -744,7 +749,7 @@ static void kill_fasync_rcu(struct fasync_struct *fa, int sig, int band)
                        if (!(sig == SIGURG && fown->signum == 0))
                                send_sigio(fown, fa->fa_fd, band);
                }
-               spin_unlock(&fa->fa_lock);
+               spin_unlock_irqrestore(&fa->fa_lock, flags);
                fa = rcu_dereference(fa->fa_next);
        }
 }