Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull vfs fixes from Al Viro:
"Several fixes for bugs caught while looking through f_pos (ab)users"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
aout32 coredump compat fix
splice: don't pass the address of ->f_pos to methods
mconsole: we'd better initialize pos before passing it to vfs_read()...

+43 -25
+1 -1
arch/um/drivers/mconsole_kern.c
··· 147 147 } 148 148 149 149 do { 150 - loff_t pos; 150 + loff_t pos = file->f_pos; 151 151 mm_segment_t old_fs = get_fs(); 152 152 set_fs(KERNEL_DS); 153 153 len = vfs_read(file, buf, PAGE_SIZE - 1, &pos);
+1 -1
arch/x86/ia32/ia32_aout.c
··· 192 192 /* struct user */ 193 193 DUMP_WRITE(&dump, sizeof(dump)); 194 194 /* Now dump all of the user data. Include malloced stuff as well */ 195 - DUMP_SEEK(PAGE_SIZE); 195 + DUMP_SEEK(PAGE_SIZE - sizeof(dump)); 196 196 /* now we start writing out the user space info */ 197 197 set_fs(USER_DS); 198 198 /* Dump the data area */
+6
fs/internal.h
··· 132 132 extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *); 133 133 134 134 /* 135 + * splice.c 136 + */ 137 + extern long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, 138 + loff_t *opos, size_t len, unsigned int flags); 139 + 140 + /* 135 141 * pipe.c 136 142 */ 137 143 extern const struct file_operations pipefifo_fops;
+16 -8
fs/read_write.c
··· 1064 1064 struct fd in, out; 1065 1065 struct inode *in_inode, *out_inode; 1066 1066 loff_t pos; 1067 + loff_t out_pos; 1067 1068 ssize_t retval; 1068 1069 int fl; 1069 1070 ··· 1078 1077 if (!(in.file->f_mode & FMODE_READ)) 1079 1078 goto fput_in; 1080 1079 retval = -ESPIPE; 1081 - if (!ppos) 1082 - ppos = &in.file->f_pos; 1083 - else 1080 + if (!ppos) { 1081 + pos = in.file->f_pos; 1082 + } else { 1083 + pos = *ppos; 1084 1084 if (!(in.file->f_mode & FMODE_PREAD)) 1085 1085 goto fput_in; 1086 - retval = rw_verify_area(READ, in.file, ppos, count); 1086 + } 1087 + retval = rw_verify_area(READ, in.file, &pos, count); 1087 1088 if (retval < 0) 1088 1089 goto fput_in; 1089 1090 count = retval; ··· 1102 1099 retval = -EINVAL; 1103 1100 in_inode = file_inode(in.file); 1104 1101 out_inode = file_inode(out.file); 1105 - retval = rw_verify_area(WRITE, out.file, &out.file->f_pos, count); 1102 + out_pos = out.file->f_pos; 1103 + retval = rw_verify_area(WRITE, out.file, &out_pos, count); 1106 1104 if (retval < 0) 1107 1105 goto fput_out; 1108 1106 count = retval; ··· 1111 1107 if (!max) 1112 1108 max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes); 1113 1109 1114 - pos = *ppos; 1115 1110 if (unlikely(pos + count > max)) { 1116 1111 retval = -EOVERFLOW; 1117 1112 if (pos >= max) ··· 1129 1126 if (in.file->f_flags & O_NONBLOCK) 1130 1127 fl = SPLICE_F_NONBLOCK; 1131 1128 #endif 1132 - retval = do_splice_direct(in.file, ppos, out.file, count, fl); 1129 + retval = do_splice_direct(in.file, &pos, out.file, &out_pos, count, fl); 1133 1130 1134 1131 if (retval > 0) { 1135 1132 add_rchar(current, retval); 1136 1133 add_wchar(current, retval); 1137 1134 fsnotify_access(in.file); 1138 1135 fsnotify_modify(out.file); 1136 + out.file->f_pos = out_pos; 1137 + if (ppos) 1138 + *ppos = pos; 1139 + else 1140 + in.file->f_pos = pos; 1139 1141 } 1140 1142 1141 1143 inc_syscr(current); 1142 1144 inc_syscw(current); 1143 - if (*ppos > max) 1145 + if (pos > max) 1144 1146 retval = -EOVERFLOW; 1145 1147 1146 1148 fput_out:
+18 -13
fs/splice.c
··· 1274 1274 { 1275 1275 struct file *file = sd->u.file; 1276 1276 1277 - return do_splice_from(pipe, file, &file->f_pos, sd->total_len, 1277 + return do_splice_from(pipe, file, sd->opos, sd->total_len, 1278 1278 sd->flags); 1279 1279 } 1280 1280 ··· 1294 1294 * 1295 1295 */ 1296 1296 long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, 1297 - size_t len, unsigned int flags) 1297 + loff_t *opos, size_t len, unsigned int flags) 1298 1298 { 1299 1299 struct splice_desc sd = { 1300 1300 .len = len, ··· 1302 1302 .flags = flags, 1303 1303 .pos = *ppos, 1304 1304 .u.file = out, 1305 + .opos = opos, 1305 1306 }; 1306 1307 long ret; 1307 1308 ··· 1326 1325 { 1327 1326 struct pipe_inode_info *ipipe; 1328 1327 struct pipe_inode_info *opipe; 1329 - loff_t offset, *off; 1328 + loff_t offset; 1330 1329 long ret; 1331 1330 1332 1331 ipipe = get_pipe_info(in); ··· 1357 1356 return -EINVAL; 1358 1357 if (copy_from_user(&offset, off_out, sizeof(loff_t))) 1359 1358 return -EFAULT; 1360 - off = &offset; 1361 - } else 1362 - off = &out->f_pos; 1359 + } else { 1360 + offset = out->f_pos; 1361 + } 1363 1362 1364 - ret = do_splice_from(ipipe, out, off, len, flags); 1363 + ret = do_splice_from(ipipe, out, &offset, len, flags); 1365 1364 1366 - if (off_out && copy_to_user(off_out, off, sizeof(loff_t))) 1365 + if (!off_out) 1366 + out->f_pos = offset; 1367 + else if (copy_to_user(off_out, &offset, sizeof(loff_t))) 1367 1368 ret = -EFAULT; 1368 1369 1369 1370 return ret; ··· 1379 1376 return -EINVAL; 1380 1377 if (copy_from_user(&offset, off_in, sizeof(loff_t))) 1381 1378 return -EFAULT; 1382 - off = &offset; 1383 - } else 1384 - off = &in->f_pos; 1379 + } else { 1380 + offset = in->f_pos; 1381 + } 1385 1382 1386 - ret = do_splice_to(in, off, opipe, len, flags); 1383 + ret = do_splice_to(in, &offset, opipe, len, flags); 1387 1384 1388 - if (off_in && copy_to_user(off_in, off, sizeof(loff_t))) 1385 + if (!off_in) 1386 + in->f_pos = offset; 1387 + else if (copy_to_user(off_in, &offset, sizeof(loff_t))) 1389 1388 ret = -EFAULT; 1390 1389 1391 1390 return ret;
-2
include/linux/fs.h
··· 2414 2414 struct file *, loff_t *, size_t, unsigned int); 2415 2415 extern ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, 2416 2416 struct file *out, loff_t *, size_t len, unsigned int flags); 2417 - extern long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, 2418 - size_t len, unsigned int flags); 2419 2417 2420 2418 extern void 2421 2419 file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping);
+1
include/linux/splice.h
··· 35 35 void *data; /* cookie */ 36 36 } u; 37 37 loff_t pos; /* file position */ 38 + loff_t *opos; /* sendfile: output position */ 38 39 size_t num_spliced; /* number of bytes already spliced */ 39 40 bool need_wakeup; /* need to wake up writer */ 40 41 };