OSDN Git Service

f2fs: enhance f2fs_is_checkpoint_ready()'s readability
[sagit-ice-cold/kernel_xiaomi_msm8998.git] / fs / pipe.c
index ab8dad3..1e7263b 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -616,6 +616,9 @@ struct pipe_inode_info *alloc_pipe_info(void)
                unsigned long pipe_bufs = PIPE_DEF_BUFFERS;
                struct user_struct *user = get_current_user();
 
+               if (pipe_bufs * PAGE_SIZE > pipe_max_size && !capable(CAP_SYS_RESOURCE))
+                       pipe_bufs = pipe_max_size >> PAGE_SHIFT;
+
                if (!too_many_pipe_buffers_hard(user)) {
                        if (too_many_pipe_buffers_soft(user))
                                pipe_bufs = 1;
@@ -1001,6 +1004,9 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long nr_pages)
 {
        struct pipe_buffer *bufs;
 
+       if (!nr_pages)
+               return -EINVAL;
+
        /*
         * We can shrink the pipe, if arg >= pipe->nrbufs. Since we don't
         * expect a lot of shrink+grow operations, just free and allocate
@@ -1045,13 +1051,19 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long nr_pages)
 
 /*
  * Currently we rely on the pipe array holding a power-of-2 number
- * of pages.
+ * of pages. Returns 0 on error.
  */
 static inline unsigned int round_pipe_size(unsigned int size)
 {
        unsigned long nr_pages;
 
+       if (size < pipe_min_size)
+               size = pipe_min_size;
+
        nr_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+       if (nr_pages == 0)
+               return 0;
+
        return roundup_pow_of_two(nr_pages) << PAGE_SHIFT;
 }
 
@@ -1062,13 +1074,18 @@ static inline unsigned int round_pipe_size(unsigned int size)
 int pipe_proc_fn(struct ctl_table *table, int write, void __user *buf,
                 size_t *lenp, loff_t *ppos)
 {
+       unsigned int rounded_pipe_max_size;
        int ret;
 
        ret = proc_dointvec_minmax(table, write, buf, lenp, ppos);
        if (ret < 0 || !write)
                return ret;
 
-       pipe_max_size = round_pipe_size(pipe_max_size);
+       rounded_pipe_max_size = round_pipe_size(pipe_max_size);
+       if (rounded_pipe_max_size == 0)
+               return -EINVAL;
+
+       pipe_max_size = rounded_pipe_max_size;
        return ret;
 }