Merge branch 'splice-2.6.23' of git://git.kernel.dk/data/git/linux-2.6-block

* 'splice-2.6.23' of git://git.kernel.dk/data/git/linux-2.6-block:
splice: fix offset mangling with direct splicing (sendfile)
security: revalidate rw permissions for sys_splice and sys_vmsplice
relay: fixup kerneldoc comment
relay: fix bogus cast in subbuf_splice_actor()

+24 -25
+20 -23
fs/splice.c
··· 28 #include <linux/module.h> 29 #include <linux/syscalls.h> 30 #include <linux/uio.h> 31 32 /* 33 * Attempt to steal a page from a pipe buffer. This should perhaps go into ··· 492 493 ret = 0; 494 spliced = 0; 495 - while (len) { 496 ret = __generic_file_splice_read(in, ppos, pipe, len, flags); 497 498 if (ret < 0) ··· 962 if (unlikely(ret < 0)) 963 return ret; 964 965 return out->f_op->splice_write(pipe, out, ppos, len, flags); 966 } 967 ··· 985 return -EBADF; 986 987 ret = rw_verify_area(READ, in, ppos, len); 988 if (unlikely(ret < 0)) 989 return ret; 990 ··· 1060 sd->flags &= ~SPLICE_F_NONBLOCK; 1061 1062 while (len) { 1063 - size_t read_len, max_read_len; 1064 1065 - /* 1066 - * Do at most PIPE_BUFFERS pages worth of transfer: 1067 - */ 1068 - max_read_len = min(len, (size_t)(PIPE_BUFFERS*PAGE_SIZE)); 1069 - 1070 - ret = do_splice_to(in, &sd->pos, pipe, max_read_len, flags); 1071 - if (unlikely(ret < 0)) 1072 goto out_release; 1073 1074 read_len = ret; ··· 1075 * could get stuck data in the internal pipe: 1076 */ 1077 ret = actor(pipe, sd); 1078 - if (unlikely(ret < 0)) 1079 goto out_release; 1080 1081 bytes += ret; 1082 len -= ret; 1083 1084 - /* 1085 - * In nonblocking mode, if we got back a short read then 1086 - * that was due to either an IO error or due to the 1087 - * pagecache entry not being there. In the IO error case 1088 - * the _next_ splice attempt will produce a clean IO error 1089 - * return value (not a short read), so in both cases it's 1090 - * correct to break out of the loop here: 1091 - */ 1092 - if ((flags & SPLICE_F_NONBLOCK) && (read_len < max_read_len)) 1093 - break; 1094 } 1095 1096 pipe->nrbufs = pipe->curbuf = 0; 1097 - 1098 return bytes; 1099 1100 out_release: ··· 1147 .pos = *ppos, 1148 .u.file = out, 1149 }; 1150 - size_t ret; 1151 1152 ret = splice_direct_to_actor(in, &sd, direct_splice_actor); 1153 - *ppos = sd.pos; 1154 return ret; 1155 } 1156
··· 28 #include <linux/module.h> 29 #include <linux/syscalls.h> 30 #include <linux/uio.h> 31 + #include <linux/security.h> 32 33 /* 34 * Attempt to steal a page from a pipe buffer. This should perhaps go into ··· 491 492 ret = 0; 493 spliced = 0; 494 + while (len && !spliced) { 495 ret = __generic_file_splice_read(in, ppos, pipe, len, flags); 496 497 if (ret < 0) ··· 961 if (unlikely(ret < 0)) 962 return ret; 963 964 + ret = security_file_permission(out, MAY_WRITE); 965 + if (unlikely(ret < 0)) 966 + return ret; 967 + 968 return out->f_op->splice_write(pipe, out, ppos, len, flags); 969 } 970 ··· 980 return -EBADF; 981 982 ret = rw_verify_area(READ, in, ppos, len); 983 + if (unlikely(ret < 0)) 984 + return ret; 985 + 986 + ret = security_file_permission(in, MAY_READ); 987 if (unlikely(ret < 0)) 988 return ret; 989 ··· 1051 sd->flags &= ~SPLICE_F_NONBLOCK; 1052 1053 while (len) { 1054 + size_t read_len; 1055 1056 + ret = do_splice_to(in, &sd->pos, pipe, len, flags); 1057 + if (unlikely(ret <= 0)) 1058 goto out_release; 1059 1060 read_len = ret; ··· 1071 * could get stuck data in the internal pipe: 1072 */ 1073 ret = actor(pipe, sd); 1074 + if (unlikely(ret <= 0)) 1075 goto out_release; 1076 1077 bytes += ret; 1078 len -= ret; 1079 1080 + if (ret < read_len) 1081 + goto out_release; 1082 } 1083 1084 pipe->nrbufs = pipe->curbuf = 0; 1085 return bytes; 1086 1087 out_release: ··· 1152 .pos = *ppos, 1153 .u.file = out, 1154 }; 1155 + long ret; 1156 1157 ret = splice_direct_to_actor(in, &sd, direct_splice_actor); 1158 + if (ret > 0) 1159 + *ppos += ret; 1160 + 1161 return ret; 1162 } 1163
+4 -2
kernel/relay.c
··· 1061 .get = generic_pipe_buf_get, 1062 }; 1063 1064 - /** 1065 * subbuf_splice_actor - splice up to one subbuf's worth of data 1066 */ 1067 static int subbuf_splice_actor(struct file *in, ··· 1074 unsigned int pidx, poff, total_len, subbuf_pages, ret; 1075 struct rchan_buf *rbuf = in->private_data; 1076 unsigned int subbuf_size = rbuf->chan->subbuf_size; 1077 - size_t read_start = ((size_t)*ppos) % rbuf->chan->alloc_size; 1078 size_t read_subbuf = read_start / subbuf_size; 1079 size_t padding = rbuf->padding[read_subbuf]; 1080 size_t nonpad_end = read_subbuf * subbuf_size + subbuf_size - padding;
··· 1061 .get = generic_pipe_buf_get, 1062 }; 1063 1064 + /* 1065 * subbuf_splice_actor - splice up to one subbuf's worth of data 1066 */ 1067 static int subbuf_splice_actor(struct file *in, ··· 1074 unsigned int pidx, poff, total_len, subbuf_pages, ret; 1075 struct rchan_buf *rbuf = in->private_data; 1076 unsigned int subbuf_size = rbuf->chan->subbuf_size; 1077 + uint64_t pos = (uint64_t) *ppos; 1078 + uint32_t alloc_size = (uint32_t) rbuf->chan->alloc_size; 1079 + size_t read_start = (size_t) do_div(pos, alloc_size); 1080 size_t read_subbuf = read_start / subbuf_size; 1081 size_t padding = rbuf->padding[read_subbuf]; 1082 size_t nonpad_end = read_subbuf * subbuf_size + subbuf_size - padding;