btrfs: fix race between quota disable and quota assign ioctls
[platform/kernel/linux-rpi.git] / fs / pipe.c
index 8e6ef62..e08f0fe 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -252,7 +252,8 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to)
         */
        was_full = pipe_full(pipe->head, pipe->tail, pipe->max_usage);
        for (;;) {
-               unsigned int head = pipe->head;
+               /* Read ->head with a barrier vs post_one_notification() */
+               unsigned int head = smp_load_acquire(&pipe->head);
                unsigned int tail = pipe->tail;
                unsigned int mask = pipe->ring_size - 1;
 
@@ -363,10 +364,9 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to)
                 * _very_ unlikely case that the pipe was full, but we got
                 * no data.
                 */
-               if (unlikely(was_full)) {
+               if (unlikely(was_full))
                        wake_up_interruptible_sync_poll(&pipe->wr_wait, EPOLLOUT | EPOLLWRNORM);
-                       kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
-               }
+               kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
 
                /*
                 * But because we didn't read anything, at this point we can
@@ -385,12 +385,11 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to)
                wake_next_reader = false;
        __pipe_unlock(pipe);
 
-       if (was_full) {
+       if (was_full)
                wake_up_interruptible_sync_poll(&pipe->wr_wait, EPOLLOUT | EPOLLWRNORM);
-               kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
-       }
        if (wake_next_reader)
                wake_up_interruptible_sync_poll(&pipe->rd_wait, EPOLLIN | EPOLLRDNORM);
+       kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
        if (ret > 0)
                file_accessed(filp);
        return ret;
@@ -444,9 +443,6 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from)
 #endif
 
        /*
-        * Epoll nonsensically wants a wakeup whether the pipe
-        * was already empty or not.
-        *
         * If it wasn't empty we try to merge new data into
         * the last buffer.
         *
@@ -455,9 +451,9 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from)
         * spanning multiple pages.
         */
        head = pipe->head;
-       was_empty = true;
+       was_empty = pipe_empty(head, pipe->tail);
        chars = total_len & (PAGE_SIZE-1);
-       if (chars && !pipe_empty(head, pipe->tail)) {
+       if (chars && !was_empty) {
                unsigned int mask = pipe->ring_size - 1;
                struct pipe_buffer *buf = &pipe->bufs[(head - 1) & mask];
                int offset = buf->offset + buf->len;
@@ -568,10 +564,9 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from)
                 * become empty while we dropped the lock.
                 */
                __pipe_unlock(pipe);
-               if (was_empty) {
+               if (was_empty)
                        wake_up_interruptible_sync_poll(&pipe->rd_wait, EPOLLIN | EPOLLRDNORM);
-                       kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
-               }
+               kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
                wait_event_interruptible_exclusive(pipe->wr_wait, pipe_writable(pipe));
                __pipe_lock(pipe);
                was_empty = pipe_empty(pipe->head, pipe->tail);
@@ -590,11 +585,13 @@ out:
         * This is particularly important for small writes, because of
         * how (for example) the GNU make jobserver uses small writes to
         * wake up pending jobs
+        *
+        * Epoll nonsensically wants a wakeup whether the pipe
+        * was already empty or not.
         */
-       if (was_empty) {
+       if (was_empty || pipe->poll_usage)
                wake_up_interruptible_sync_poll(&pipe->rd_wait, EPOLLIN | EPOLLRDNORM);
-               kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
-       }
+       kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
        if (wake_next_writer)
                wake_up_interruptible_sync_poll(&pipe->wr_wait, EPOLLOUT | EPOLLWRNORM);
        if (ret > 0 && sb_start_write_trylock(file_inode(filp)->i_sb)) {
@@ -654,6 +651,9 @@ pipe_poll(struct file *filp, poll_table *wait)
        struct pipe_inode_info *pipe = filp->private_data;
        unsigned int head, tail;
 
+       /* Epoll has some historical nasty semantics, this enables them */
+       WRITE_ONCE(pipe->poll_usage, true);
+
        /*
         * Reading pipe state only -- no need for acquiring the semaphore.
         *
@@ -831,10 +831,8 @@ void free_pipe_info(struct pipe_inode_info *pipe)
        int i;
 
 #ifdef CONFIG_WATCH_QUEUE
-       if (pipe->watch_queue) {
+       if (pipe->watch_queue)
                watch_queue_clear(pipe->watch_queue);
-               put_watch_queue(pipe->watch_queue);
-       }
 #endif
 
        (void) account_pipe_buffers(pipe->user, pipe->nr_accounted, 0);
@@ -844,6 +842,10 @@ void free_pipe_info(struct pipe_inode_info *pipe)
                if (buf->ops)
                        pipe_buf_release(pipe, buf);
        }
+#ifdef CONFIG_WATCH_QUEUE
+       if (pipe->watch_queue)
+               put_watch_queue(pipe->watch_queue);
+#endif
        if (pipe->tmp_page)
                __free_page(pipe->tmp_page);
        kfree(pipe->bufs);
@@ -1242,30 +1244,33 @@ unsigned int round_pipe_size(unsigned long size)
 
 /*
  * Resize the pipe ring to a number of slots.
+ *
+ * Note the pipe can be reduced in capacity, but only if the current
+ * occupancy doesn't exceed nr_slots; if it does, EBUSY will be
+ * returned instead.
  */
 int pipe_resize_ring(struct pipe_inode_info *pipe, unsigned int nr_slots)
 {
        struct pipe_buffer *bufs;
        unsigned int head, tail, mask, n;
 
-       /*
-        * We can shrink the pipe, if arg is greater than the ring occupancy.
-        * Since we don't expect a lot of shrink+grow operations, just free and
-        * allocate again like we would do for growing.  If the pipe currently
-        * contains more buffers than arg, then return busy.
-        */
-       mask = pipe->ring_size - 1;
-       head = pipe->head;
-       tail = pipe->tail;
-       n = pipe_occupancy(pipe->head, pipe->tail);
-       if (nr_slots < n)
-               return -EBUSY;
-
        bufs = kcalloc(nr_slots, sizeof(*bufs),
                       GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
        if (unlikely(!bufs))
                return -ENOMEM;
 
+       spin_lock_irq(&pipe->rd_wait.lock);
+       mask = pipe->ring_size - 1;
+       head = pipe->head;
+       tail = pipe->tail;
+
+       n = pipe_occupancy(head, tail);
+       if (nr_slots < n) {
+               spin_unlock_irq(&pipe->rd_wait.lock);
+               kfree(bufs);
+               return -EBUSY;
+       }
+
        /*
         * The pipe array wraps around, so just start the new one at zero
         * and adjust the indices.
@@ -1297,6 +1302,8 @@ int pipe_resize_ring(struct pipe_inode_info *pipe, unsigned int nr_slots)
        pipe->tail = tail;
        pipe->head = head;
 
+       spin_unlock_irq(&pipe->rd_wait.lock);
+
        /* This might have made more room for writers */
        wake_up_interruptible(&pipe->wr_wait);
        return 0;