pandora: defconfig: update
[pandora-kernel.git] / fs / fcntl.c
index 22764c7..d90a20b 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/signal.h>
 #include <linux/rcupdate.h>
 #include <linux/pid_namespace.h>
+#include <linux/shmem_fs.h>
 
 #include <asm/poll.h>
 #include <asm/siginfo.h>
@@ -32,20 +33,20 @@ void set_close_on_exec(unsigned int fd, int flag)
        spin_lock(&files->file_lock);
        fdt = files_fdtable(files);
        if (flag)
-               FD_SET(fd, fdt->close_on_exec);
+               __set_close_on_exec(fd, fdt);
        else
-               FD_CLR(fd, fdt->close_on_exec);
+               __clear_close_on_exec(fd, fdt);
        spin_unlock(&files->file_lock);
 }
 
-static int get_close_on_exec(unsigned int fd)
+static bool get_close_on_exec(unsigned int fd)
 {
        struct files_struct *files = current->files;
        struct fdtable *fdt;
-       int res;
+       bool res;
        rcu_read_lock();
        fdt = files_fdtable(files);
-       res = FD_ISSET(fd, fdt->close_on_exec);
+       res = close_on_exec(fd, fdt);
        rcu_read_unlock();
        return res;
 }
@@ -90,15 +91,15 @@ SYSCALL_DEFINE3(dup3, unsigned int, oldfd, unsigned int, newfd, int, flags)
        err = -EBUSY;
        fdt = files_fdtable(files);
        tofree = fdt->fd[newfd];
-       if (!tofree && FD_ISSET(newfd, fdt->open_fds))
+       if (!tofree && fd_is_open(newfd, fdt))
                goto out_unlock;
        get_file(file);
        rcu_assign_pointer(fdt->fd[newfd], file);
-       FD_SET(newfd, fdt->open_fds);
+       __set_open_fd(newfd, fdt);
        if (flags & O_CLOEXEC)
-               FD_SET(newfd, fdt->close_on_exec);
+               __set_close_on_exec(newfd, fdt);
        else
-               FD_CLR(newfd, fdt->close_on_exec);
+               __clear_close_on_exec(newfd, fdt);
        spin_unlock(&files->file_lock);
 
        if (tofree)
@@ -420,6 +421,10 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
        case F_GETPIPE_SZ:
                err = pipe_fcntl(filp, cmd, arg);
                break;
+       case F_ADD_SEALS:
+       case F_GET_SEALS:
+               err = shmem_fcntl(filp, cmd, arg);
+               break;
        default:
                break;
        }
@@ -565,10 +570,21 @@ static void send_sigio_to_task(struct task_struct *p,
                        si.si_signo = signum;
                        si.si_errno = 0;
                        si.si_code  = reason;
+                       /*
+                        * Posix definies POLL_IN and friends to be signal
+                        * specific si_codes for SIG_POLL.  Linux extended
+                        * these si_codes to other signals in a way that is
+                        * ambiguous if other signals also have signal
+                        * specific si_codes.  In that case use SI_SIGIO instead
+                        * to remove the ambiguity.
+                        */
+                       if (sig_specific_sicodes(signum))
+                               si.si_code = SI_SIGIO;
+
                        /* Make sure we are called with one of the POLL_*
                           reasons, otherwise we could leak kernel stack into
                           userspace.  */
-                       BUG_ON((reason & __SI_MASK) != __SI_POLL);
+                       BUG_ON((reason < POLL_IN) || ((reason - POLL_IN) >= NSIGPOLL));
                        if (reason - POLL_IN >= NSIGPOLL)
                                si.si_band  = ~0L;
                        else