mm: mm_event: fix compact_scan
[GitHub/MotorolaMobilityLLC/kernel-slsi.git] / fs / pipe.c
index f0f4ab36c444d42d91ffeb0a2cc144387219b62f..8f9628494981c3bf60c19d562896f5724e3c9f19 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -239,6 +239,14 @@ static const struct pipe_buf_operations anon_pipe_buf_ops = {
        .get = generic_pipe_buf_get,
 };
 
+static const struct pipe_buf_operations anon_pipe_buf_nomerge_ops = {
+       .can_merge = 0,
+       .confirm = generic_pipe_buf_confirm,
+       .release = anon_pipe_buf_release,
+       .steal = anon_pipe_buf_steal,
+       .get = generic_pipe_buf_get,
+};
+
 static const struct pipe_buf_operations packet_pipe_buf_ops = {
        .can_merge = 0,
        .confirm = generic_pipe_buf_confirm,
@@ -247,6 +255,12 @@ static const struct pipe_buf_operations packet_pipe_buf_ops = {
        .get = generic_pipe_buf_get,
 };
 
+void pipe_buf_mark_unmergeable(struct pipe_buffer *buf)
+{
+       if (buf->ops == &anon_pipe_buf_ops)
+               buf->ops = &anon_pipe_buf_nomerge_ops;
+}
+
 static ssize_t
 pipe_read(struct kiocb *iocb, struct iov_iter *to)
 {
@@ -610,12 +624,17 @@ static unsigned long account_pipe_buffers(struct user_struct *user,
 
 static bool too_many_pipe_buffers_soft(unsigned long user_bufs)
 {
-       return pipe_user_pages_soft && user_bufs >= pipe_user_pages_soft;
+       return pipe_user_pages_soft && user_bufs > pipe_user_pages_soft;
 }
 
 static bool too_many_pipe_buffers_hard(unsigned long user_bufs)
 {
-       return pipe_user_pages_hard && user_bufs >= pipe_user_pages_hard;
+       return pipe_user_pages_hard && user_bufs > pipe_user_pages_hard;
+}
+
+static bool is_unprivileged_user(void)
+{
+       return !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN);
 }
 
 struct pipe_inode_info *alloc_pipe_info(void)
@@ -634,12 +653,12 @@ struct pipe_inode_info *alloc_pipe_info(void)
 
        user_bufs = account_pipe_buffers(user, 0, pipe_bufs);
 
-       if (too_many_pipe_buffers_soft(user_bufs)) {
+       if (too_many_pipe_buffers_soft(user_bufs) && is_unprivileged_user()) {
                user_bufs = account_pipe_buffers(user, pipe_bufs, 1);
                pipe_bufs = 1;
        }
 
-       if (too_many_pipe_buffers_hard(user_bufs))
+       if (too_many_pipe_buffers_hard(user_bufs) && is_unprivileged_user())
                goto out_revert_acct;
 
        pipe->bufs = kcalloc(pipe_bufs, sizeof(struct pipe_buffer),
@@ -1069,7 +1088,7 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long arg)
        if (nr_pages > pipe->buffers &&
                        (too_many_pipe_buffers_hard(user_bufs) ||
                         too_many_pipe_buffers_soft(user_bufs)) &&
-                       !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN)) {
+                       is_unprivileged_user()) {
                ret = -EPERM;
                goto out_revert_acct;
        }