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 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull vfs fixes from Al Viro:
"Assorted fixes all over the place.

The iov_iter one is this cycle regression (splice from UDP triggering
WARN_ON()), the rest is older"

* 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
afs: Use d_instantiate() rather than d_add() and don't d_drop()
afs: Fix missing net error handling
afs: Fix validation/callback interaction
iov_iter: teach csum_and_copy_to_iter() to handle pipe-backed ones
exportfs: do not read dentry after free
exportfs: fix 'passing zero to ERR_PTR()' warning
aio: fix failure to put the file pointer
sysv: return 'err' instead of 0 in __sysv_write_inode

+189 -125
+1 -3
fs/afs/dir.c
··· 1075 1075 if (fc->ac.error < 0) 1076 1076 return; 1077 1077 1078 - d_drop(new_dentry); 1079 - 1080 1078 inode = afs_iget(fc->vnode->vfs_inode.i_sb, fc->key, 1081 1079 newfid, newstatus, newcb, fc->cbi); 1082 1080 if (IS_ERR(inode)) { ··· 1088 1090 vnode = AFS_FS_I(inode); 1089 1091 set_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags); 1090 1092 afs_vnode_commit_status(fc, vnode, 0); 1091 - d_add(new_dentry, inode); 1093 + d_instantiate(new_dentry, inode); 1092 1094 } 1093 1095 1094 1096 /*
+24 -15
fs/afs/fs_probe.c
··· 61 61 afs_io_error(call, afs_io_error_fs_probe_fail); 62 62 goto out; 63 63 case -ECONNRESET: /* Responded, but call expired. */ 64 + case -ERFKILL: 65 + case -EADDRNOTAVAIL: 64 66 case -ENETUNREACH: 65 67 case -EHOSTUNREACH: 68 + case -EHOSTDOWN: 66 69 case -ECONNREFUSED: 67 70 case -ETIMEDOUT: 68 71 case -ETIME: ··· 135 132 static int afs_do_probe_fileserver(struct afs_net *net, 136 133 struct afs_server *server, 137 134 struct key *key, 138 - unsigned int server_index) 135 + unsigned int server_index, 136 + struct afs_error *_e) 139 137 { 140 138 struct afs_addr_cursor ac = { 141 139 .index = 0, 142 140 }; 143 - int ret; 141 + bool in_progress = false; 142 + int err; 144 143 145 144 _enter("%pU", &server->uuid); 146 145 ··· 156 151 server->probe.rtt = UINT_MAX; 157 152 158 153 for (ac.index = 0; ac.index < ac.alist->nr_addrs; ac.index++) { 159 - ret = afs_fs_get_capabilities(net, server, &ac, key, server_index, 154 + err = afs_fs_get_capabilities(net, server, &ac, key, server_index, 160 155 true); 161 - if (ret != -EINPROGRESS) { 162 - afs_fs_probe_done(server); 163 - return ret; 164 - } 156 + if (err == -EINPROGRESS) 157 + in_progress = true; 158 + else 159 + afs_prioritise_error(_e, err, ac.abort_code); 165 160 } 166 161 167 - return 0; 162 + if (!in_progress) 163 + afs_fs_probe_done(server); 164 + return in_progress; 168 165 } 169 166 170 167 /* ··· 176 169 struct afs_server_list *list) 177 170 { 178 171 struct afs_server *server; 179 - int i, ret; 172 + struct afs_error e; 173 + bool in_progress = false; 174 + int i; 180 175 176 + e.error = 0; 177 + e.responded = false; 181 178 for (i = 0; i < list->nr_servers; i++) { 182 179 server = list->servers[i].server; 183 180 if (test_bit(AFS_SERVER_FL_PROBED, &server->flags)) 184 181 continue; 185 182 186 - if (!test_and_set_bit_lock(AFS_SERVER_FL_PROBING, &server->flags)) { 187 - ret = afs_do_probe_fileserver(net, server, key, i); 188 - if (ret) 189 - return ret; 190 - } 183 + if (!test_and_set_bit_lock(AFS_SERVER_FL_PROBING, &server->flags) && 184 + afs_do_probe_fileserver(net, server, key, i, &e)) 185 + in_progress = true; 191 186 } 192 187 193 - return 0; 188 + return in_progress ? 0 : e.error; 194 189 } 195 190 196 191 /*
+12 -6
fs/afs/inode.c
··· 382 382 int afs_validate(struct afs_vnode *vnode, struct key *key) 383 383 { 384 384 time64_t now = ktime_get_real_seconds(); 385 - bool valid = false; 385 + bool valid; 386 386 int ret; 387 387 388 388 _enter("{v={%llx:%llu} fl=%lx},%x", ··· 402 402 vnode->cb_v_break = vnode->volume->cb_v_break; 403 403 valid = false; 404 404 } else if (vnode->status.type == AFS_FTYPE_DIR && 405 - test_bit(AFS_VNODE_DIR_VALID, &vnode->flags) && 406 - vnode->cb_expires_at - 10 > now) { 407 - valid = true; 408 - } else if (!test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags) && 409 - vnode->cb_expires_at - 10 > now) { 405 + (!test_bit(AFS_VNODE_DIR_VALID, &vnode->flags) || 406 + vnode->cb_expires_at - 10 <= now)) { 407 + valid = false; 408 + } else if (test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags) || 409 + vnode->cb_expires_at - 10 <= now) { 410 + valid = false; 411 + } else { 410 412 valid = true; 411 413 } 412 414 } else if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) { 413 415 valid = true; 416 + } else { 417 + vnode->cb_s_break = vnode->cb_interest->server->cb_s_break; 418 + vnode->cb_v_break = vnode->volume->cb_v_break; 419 + valid = false; 414 420 } 415 421 416 422 read_sequnlock_excl(&vnode->cb_lock);
+9
fs/afs/internal.h
··· 696 696 }; 697 697 698 698 /* 699 + * Error prioritisation and accumulation. 700 + */ 701 + struct afs_error { 702 + short error; /* Accumulated error */ 703 + bool responded; /* T if server responded */ 704 + }; 705 + 706 + /* 699 707 * Cursor for iterating over a server's address list. 700 708 */ 701 709 struct afs_addr_cursor { ··· 1023 1015 * misc.c 1024 1016 */ 1025 1017 extern int afs_abort_to_error(u32); 1018 + extern void afs_prioritise_error(struct afs_error *, int, u32); 1026 1019 1027 1020 /* 1028 1021 * mntpt.c
+52
fs/afs/misc.c
··· 118 118 default: return -EREMOTEIO; 119 119 } 120 120 } 121 + 122 + /* 123 + * Select the error to report from a set of errors. 124 + */ 125 + void afs_prioritise_error(struct afs_error *e, int error, u32 abort_code) 126 + { 127 + switch (error) { 128 + case 0: 129 + return; 130 + default: 131 + if (e->error == -ETIMEDOUT || 132 + e->error == -ETIME) 133 + return; 134 + case -ETIMEDOUT: 135 + case -ETIME: 136 + if (e->error == -ENOMEM || 137 + e->error == -ENONET) 138 + return; 139 + case -ENOMEM: 140 + case -ENONET: 141 + if (e->error == -ERFKILL) 142 + return; 143 + case -ERFKILL: 144 + if (e->error == -EADDRNOTAVAIL) 145 + return; 146 + case -EADDRNOTAVAIL: 147 + if (e->error == -ENETUNREACH) 148 + return; 149 + case -ENETUNREACH: 150 + if (e->error == -EHOSTUNREACH) 151 + return; 152 + case -EHOSTUNREACH: 153 + if (e->error == -EHOSTDOWN) 154 + return; 155 + case -EHOSTDOWN: 156 + if (e->error == -ECONNREFUSED) 157 + return; 158 + case -ECONNREFUSED: 159 + if (e->error == -ECONNRESET) 160 + return; 161 + case -ECONNRESET: /* Responded, but call expired. */ 162 + if (e->responded) 163 + return; 164 + e->error = error; 165 + return; 166 + 167 + case -ECONNABORTED: 168 + e->responded = true; 169 + e->error = afs_abort_to_error(abort_code); 170 + return; 171 + } 172 + }
+13 -40
fs/afs/rotate.c
··· 136 136 struct afs_addr_list *alist; 137 137 struct afs_server *server; 138 138 struct afs_vnode *vnode = fc->vnode; 139 - u32 rtt, abort_code; 139 + struct afs_error e; 140 + u32 rtt; 140 141 int error = fc->ac.error, i; 141 142 142 143 _enter("%lx[%d],%lx[%d],%d,%d", ··· 307 306 if (fc->error != -EDESTADDRREQ) 308 307 goto iterate_address; 309 308 /* Fall through */ 309 + case -ERFKILL: 310 + case -EADDRNOTAVAIL: 310 311 case -ENETUNREACH: 311 312 case -EHOSTUNREACH: 313 + case -EHOSTDOWN: 312 314 case -ECONNREFUSED: 313 315 _debug("no conn"); 314 316 fc->error = error; ··· 450 446 if (fc->flags & AFS_FS_CURSOR_VBUSY) 451 447 goto restart_from_beginning; 452 448 453 - abort_code = 0; 454 - error = -EDESTADDRREQ; 449 + e.error = -EDESTADDRREQ; 450 + e.responded = false; 455 451 for (i = 0; i < fc->server_list->nr_servers; i++) { 456 452 struct afs_server *s = fc->server_list->servers[i].server; 457 - int probe_error = READ_ONCE(s->probe.error); 458 453 459 - switch (probe_error) { 460 - case 0: 461 - continue; 462 - default: 463 - if (error == -ETIMEDOUT || 464 - error == -ETIME) 465 - continue; 466 - case -ETIMEDOUT: 467 - case -ETIME: 468 - if (error == -ENOMEM || 469 - error == -ENONET) 470 - continue; 471 - case -ENOMEM: 472 - case -ENONET: 473 - if (error == -ENETUNREACH) 474 - continue; 475 - case -ENETUNREACH: 476 - if (error == -EHOSTUNREACH) 477 - continue; 478 - case -EHOSTUNREACH: 479 - if (error == -ECONNREFUSED) 480 - continue; 481 - case -ECONNREFUSED: 482 - if (error == -ECONNRESET) 483 - continue; 484 - case -ECONNRESET: /* Responded, but call expired. */ 485 - if (error == -ECONNABORTED) 486 - continue; 487 - case -ECONNABORTED: 488 - abort_code = s->probe.abort_code; 489 - error = probe_error; 490 - continue; 491 - } 454 + afs_prioritise_error(&e, READ_ONCE(s->probe.error), 455 + s->probe.abort_code); 492 456 } 493 - 494 - if (error == -ECONNABORTED) 495 - error = afs_abort_to_error(abort_code); 496 457 497 458 failed_set_error: 498 459 fc->error = error; ··· 522 553 _leave(" = f [abort]"); 523 554 return false; 524 555 556 + case -ERFKILL: 557 + case -EADDRNOTAVAIL: 525 558 case -ENETUNREACH: 526 559 case -EHOSTUNREACH: 560 + case -EHOSTDOWN: 527 561 case -ECONNREFUSED: 528 562 case -ETIMEDOUT: 529 563 case -ETIME: ··· 605 633 struct afs_net *net = afs_v2net(fc->vnode); 606 634 607 635 if (fc->error == -EDESTADDRREQ || 636 + fc->error == -EADDRNOTAVAIL || 608 637 fc->error == -ENETUNREACH || 609 638 fc->error == -EHOSTUNREACH) 610 639 afs_dump_edestaddrreq(fc);
+27 -18
fs/afs/vl_probe.c
··· 61 61 afs_io_error(call, afs_io_error_vl_probe_fail); 62 62 goto out; 63 63 case -ECONNRESET: /* Responded, but call expired. */ 64 + case -ERFKILL: 65 + case -EADDRNOTAVAIL: 64 66 case -ENETUNREACH: 65 67 case -EHOSTUNREACH: 68 + case -EHOSTDOWN: 66 69 case -ECONNREFUSED: 67 70 case -ETIMEDOUT: 68 71 case -ETIME: ··· 132 129 * Probe all of a vlserver's addresses to find out the best route and to 133 130 * query its capabilities. 134 131 */ 135 - static int afs_do_probe_vlserver(struct afs_net *net, 136 - struct afs_vlserver *server, 137 - struct key *key, 138 - unsigned int server_index) 132 + static bool afs_do_probe_vlserver(struct afs_net *net, 133 + struct afs_vlserver *server, 134 + struct key *key, 135 + unsigned int server_index, 136 + struct afs_error *_e) 139 137 { 140 138 struct afs_addr_cursor ac = { 141 139 .index = 0, 142 140 }; 143 - int ret; 141 + bool in_progress = false; 142 + int err; 144 143 145 144 _enter("%s", server->name); 146 145 ··· 156 151 server->probe.rtt = UINT_MAX; 157 152 158 153 for (ac.index = 0; ac.index < ac.alist->nr_addrs; ac.index++) { 159 - ret = afs_vl_get_capabilities(net, &ac, key, server, 154 + err = afs_vl_get_capabilities(net, &ac, key, server, 160 155 server_index, true); 161 - if (ret != -EINPROGRESS) { 162 - afs_vl_probe_done(server); 163 - return ret; 164 - } 156 + if (err == -EINPROGRESS) 157 + in_progress = true; 158 + else 159 + afs_prioritise_error(_e, err, ac.abort_code); 165 160 } 166 161 167 - return 0; 162 + if (!in_progress) 163 + afs_vl_probe_done(server); 164 + return in_progress; 168 165 } 169 166 170 167 /* ··· 176 169 struct afs_vlserver_list *vllist) 177 170 { 178 171 struct afs_vlserver *server; 179 - int i, ret; 172 + struct afs_error e; 173 + bool in_progress = false; 174 + int i; 180 175 176 + e.error = 0; 177 + e.responded = false; 181 178 for (i = 0; i < vllist->nr_servers; i++) { 182 179 server = vllist->servers[i].server; 183 180 if (test_bit(AFS_VLSERVER_FL_PROBED, &server->flags)) 184 181 continue; 185 182 186 - if (!test_and_set_bit_lock(AFS_VLSERVER_FL_PROBING, &server->flags)) { 187 - ret = afs_do_probe_vlserver(net, server, key, i); 188 - if (ret) 189 - return ret; 190 - } 183 + if (!test_and_set_bit_lock(AFS_VLSERVER_FL_PROBING, &server->flags) && 184 + afs_do_probe_vlserver(net, server, key, i, &e)) 185 + in_progress = true; 191 186 } 192 187 193 - return 0; 188 + return in_progress ? 0 : e.error; 194 189 } 195 190 196 191 /*
+10 -40
fs/afs/vl_rotate.c
··· 71 71 { 72 72 struct afs_addr_list *alist; 73 73 struct afs_vlserver *vlserver; 74 + struct afs_error e; 74 75 u32 rtt; 75 - int error = vc->ac.error, abort_code, i; 76 + int error = vc->ac.error, i; 76 77 77 78 _enter("%lx[%d],%lx[%d],%d,%d", 78 79 vc->untried, vc->index, ··· 120 119 goto failed; 121 120 } 122 121 122 + case -ERFKILL: 123 + case -EADDRNOTAVAIL: 123 124 case -ENETUNREACH: 124 125 case -EHOSTUNREACH: 126 + case -EHOSTDOWN: 125 127 case -ECONNREFUSED: 126 128 case -ETIMEDOUT: 127 129 case -ETIME: ··· 239 235 if (vc->flags & AFS_VL_CURSOR_RETRY) 240 236 goto restart_from_beginning; 241 237 242 - abort_code = 0; 243 - error = -EDESTADDRREQ; 238 + e.error = -EDESTADDRREQ; 239 + e.responded = false; 244 240 for (i = 0; i < vc->server_list->nr_servers; i++) { 245 241 struct afs_vlserver *s = vc->server_list->servers[i].server; 246 - int probe_error = READ_ONCE(s->probe.error); 247 242 248 - switch (probe_error) { 249 - case 0: 250 - continue; 251 - default: 252 - if (error == -ETIMEDOUT || 253 - error == -ETIME) 254 - continue; 255 - case -ETIMEDOUT: 256 - case -ETIME: 257 - if (error == -ENOMEM || 258 - error == -ENONET) 259 - continue; 260 - case -ENOMEM: 261 - case -ENONET: 262 - if (error == -ENETUNREACH) 263 - continue; 264 - case -ENETUNREACH: 265 - if (error == -EHOSTUNREACH) 266 - continue; 267 - case -EHOSTUNREACH: 268 - if (error == -ECONNREFUSED) 269 - continue; 270 - case -ECONNREFUSED: 271 - if (error == -ECONNRESET) 272 - continue; 273 - case -ECONNRESET: /* Responded, but call expired. */ 274 - if (error == -ECONNABORTED) 275 - continue; 276 - case -ECONNABORTED: 277 - abort_code = s->probe.abort_code; 278 - error = probe_error; 279 - continue; 280 - } 243 + afs_prioritise_error(&e, READ_ONCE(s->probe.error), 244 + s->probe.abort_code); 281 245 } 282 - 283 - if (error == -ECONNABORTED) 284 - error = afs_abort_to_error(abort_code); 285 246 286 247 failed_set_error: 287 248 vc->error = error; ··· 310 341 struct afs_net *net = vc->cell->net; 311 342 312 343 if (vc->error == -EDESTADDRREQ || 344 + vc->error == -EADDRNOTAVAIL || 313 345 vc->error == -ENETUNREACH || 314 346 vc->error == -EHOSTUNREACH) 315 347 afs_vl_dump_edestaddrreq(vc);
+1
fs/aio.c
··· 1436 1436 ret = ioprio_check_cap(iocb->aio_reqprio); 1437 1437 if (ret) { 1438 1438 pr_debug("aio ioprio check cap error: %d\n", ret); 1439 + fput(req->ki_filp); 1439 1440 return ret; 1440 1441 } 1441 1442
+2 -1
fs/exportfs/expfs.c
··· 77 77 struct dentry *parent = dget_parent(dentry); 78 78 79 79 dput(dentry); 80 - if (IS_ROOT(dentry)) { 80 + if (dentry == parent) { 81 81 dput(parent); 82 82 return false; 83 83 } ··· 147 147 tmp = lookup_one_len_unlocked(nbuf, parent, strlen(nbuf)); 148 148 if (IS_ERR(tmp)) { 149 149 dprintk("%s: lookup failed: %d\n", __func__, PTR_ERR(tmp)); 150 + err = PTR_ERR(tmp); 150 151 goto out_err; 151 152 } 152 153 if (tmp != dentry) {
+1 -1
fs/sysv/inode.c
··· 275 275 } 276 276 } 277 277 brelse(bh); 278 - return 0; 278 + return err; 279 279 } 280 280 281 281 int sysv_write_inode(struct inode *inode, struct writeback_control *wbc)
+37 -1
lib/iov_iter.c
··· 560 560 return bytes; 561 561 } 562 562 563 + static size_t csum_and_copy_to_pipe_iter(const void *addr, size_t bytes, 564 + __wsum *csum, struct iov_iter *i) 565 + { 566 + struct pipe_inode_info *pipe = i->pipe; 567 + size_t n, r; 568 + size_t off = 0; 569 + __wsum sum = *csum, next; 570 + int idx; 571 + 572 + if (!sanity(i)) 573 + return 0; 574 + 575 + bytes = n = push_pipe(i, bytes, &idx, &r); 576 + if (unlikely(!n)) 577 + return 0; 578 + for ( ; n; idx = next_idx(idx, pipe), r = 0) { 579 + size_t chunk = min_t(size_t, n, PAGE_SIZE - r); 580 + char *p = kmap_atomic(pipe->bufs[idx].page); 581 + next = csum_partial_copy_nocheck(addr, p + r, chunk, 0); 582 + sum = csum_block_add(sum, next, off); 583 + kunmap_atomic(p); 584 + i->idx = idx; 585 + i->iov_offset = r + chunk; 586 + n -= chunk; 587 + off += chunk; 588 + addr += chunk; 589 + } 590 + i->count -= bytes; 591 + *csum = sum; 592 + return bytes; 593 + } 594 + 563 595 size_t _copy_to_iter(const void *addr, size_t bytes, struct iov_iter *i) 564 596 { 565 597 const char *from = addr; ··· 1470 1438 const char *from = addr; 1471 1439 __wsum sum, next; 1472 1440 size_t off = 0; 1441 + 1442 + if (unlikely(iov_iter_is_pipe(i))) 1443 + return csum_and_copy_to_pipe_iter(addr, bytes, csum, i); 1444 + 1473 1445 sum = *csum; 1474 - if (unlikely(iov_iter_is_pipe(i) || iov_iter_is_discard(i))) { 1446 + if (unlikely(iov_iter_is_discard(i))) { 1475 1447 WARN_ON(1); /* for now */ 1476 1448 return 0; 1477 1449 }