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 tag 'nfs-for-5.3-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs

Pull NFS client bugfixes from Trond Myklebust:
"Highlights include:

Stable fixes:

- Fix a page lock leak in nfs_pageio_resend()

- Ensure O_DIRECT reports an error if the bytes read/written is 0

- Don't handle errors if the bind/connect succeeded

- Revert "NFSv4/flexfiles: Abort I/O early if the layout segment was
invalidat ed"

Bugfixes:

- Don't refresh attributes with mounted-on-file information

- Fix return values for nfs4_file_open() and nfs_finish_open()

- Fix pnfs layoutstats reporting of I/O errors

- Don't use soft RPC calls for pNFS/flexfiles I/O, and don't abort
for soft I/O errors when the user specifies a hard mount.

- Various fixes to the error handling in sunrpc

- Don't report writepage()/writepages() errors twice"

* tag 'nfs-for-5.3-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
NFS: remove set but not used variable 'mapping'
NFSv2: Fix write regression
NFSv2: Fix eof handling
NFS: Fix writepage(s) error handling to not report errors twice
NFS: Fix spurious EIO read errors
pNFS/flexfiles: Don't time out requests on hard mounts
SUNRPC: Handle connection breakages correctly in call_status()
Revert "NFSv4/flexfiles: Abort I/O early if the layout segment was invalidated"
SUNRPC: Handle EADDRINUSE and ENOBUFS correctly
pNFS/flexfiles: Turn off soft RPC calls
SUNRPC: Don't handle errors if the bind/connect succeeded
NFS: On fatal writeback errors, we need to call nfs_inode_remove_request()
NFS: Fix initialisation of I/O result struct in nfs_pgio_rpcsetup
NFS: Ensure O_DIRECT reports an error if the bytes read/written is 0
NFSv4/pnfs: Fix a page lock leak in nfs_pageio_resend()
NFSv4: Fix return value in nfs_finish_open()
NFSv4: Fix return values for nfs4_file_open()
NFS: Don't refresh attributes with mounted-on-file information

+163 -118
+1 -1
fs/nfs/dir.c
··· 1487 1487 if (S_ISREG(file->f_path.dentry->d_inode->i_mode)) 1488 1488 nfs_file_set_open_context(file, ctx); 1489 1489 else 1490 - err = -ESTALE; 1490 + err = -EOPENSTALE; 1491 1491 out: 1492 1492 return err; 1493 1493 }
+18 -9
fs/nfs/direct.c
··· 401 401 unsigned long bytes = 0; 402 402 struct nfs_direct_req *dreq = hdr->dreq; 403 403 404 - if (test_bit(NFS_IOHDR_REDO, &hdr->flags)) 405 - goto out_put; 406 - 407 404 spin_lock(&dreq->lock); 408 - if (test_bit(NFS_IOHDR_ERROR, &hdr->flags) && (hdr->good_bytes == 0)) 405 + if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) 409 406 dreq->error = hdr->error; 410 - else 407 + 408 + if (test_bit(NFS_IOHDR_REDO, &hdr->flags)) { 409 + spin_unlock(&dreq->lock); 410 + goto out_put; 411 + } 412 + 413 + if (hdr->good_bytes != 0) 411 414 nfs_direct_good_bytes(dreq, hdr); 415 + 416 + if (test_bit(NFS_IOHDR_EOF, &hdr->flags)) 417 + dreq->error = 0; 412 418 413 419 spin_unlock(&dreq->lock); 414 420 ··· 788 782 bool request_commit = false; 789 783 struct nfs_page *req = nfs_list_entry(hdr->pages.next); 790 784 791 - if (test_bit(NFS_IOHDR_REDO, &hdr->flags)) 792 - goto out_put; 793 - 794 785 nfs_init_cinfo_from_dreq(&cinfo, dreq); 795 786 796 787 spin_lock(&dreq->lock); 797 788 798 789 if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) 799 790 dreq->error = hdr->error; 800 - if (dreq->error == 0) { 791 + 792 + if (test_bit(NFS_IOHDR_REDO, &hdr->flags)) { 793 + spin_unlock(&dreq->lock); 794 + goto out_put; 795 + } 796 + 797 + if (hdr->good_bytes != 0) { 801 798 nfs_direct_good_bytes(dreq, hdr); 802 799 if (nfs_write_need_commit(hdr)) { 803 800 if (dreq->flags == NFS_ODIRECT_RESCHED_WRITES)
+9 -19
fs/nfs/flexfilelayout/flexfilelayout.c
··· 8 8 */ 9 9 10 10 #include <linux/nfs_fs.h> 11 + #include <linux/nfs_mount.h> 11 12 #include <linux/nfs_page.h> 12 13 #include <linux/module.h> 13 14 #include <linux/sched/mm.h> ··· 929 928 pgm = &pgio->pg_mirrors[0]; 930 929 pgm->pg_bsize = mirror->mirror_ds->ds_versions[0].rsize; 931 930 932 - pgio->pg_maxretrans = io_maxretrans; 931 + if (NFS_SERVER(pgio->pg_inode)->flags & 932 + (NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR)) 933 + pgio->pg_maxretrans = io_maxretrans; 933 934 return; 934 935 out_nolseg: 935 936 if (pgio->pg_error < 0) ··· 943 940 pgio->pg_lseg); 944 941 pnfs_put_lseg(pgio->pg_lseg); 945 942 pgio->pg_lseg = NULL; 943 + pgio->pg_maxretrans = 0; 946 944 nfs_pageio_reset_read_mds(pgio); 947 945 } 948 946 ··· 1004 1000 pgm->pg_bsize = mirror->mirror_ds->ds_versions[0].wsize; 1005 1001 } 1006 1002 1007 - pgio->pg_maxretrans = io_maxretrans; 1003 + if (NFS_SERVER(pgio->pg_inode)->flags & 1004 + (NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR)) 1005 + pgio->pg_maxretrans = io_maxretrans; 1008 1006 return; 1009 1007 1010 1008 out_mds: ··· 1016 1010 pgio->pg_lseg); 1017 1011 pnfs_put_lseg(pgio->pg_lseg); 1018 1012 pgio->pg_lseg = NULL; 1013 + pgio->pg_maxretrans = 0; 1019 1014 nfs_pageio_reset_write_mds(pgio); 1020 1015 } 1021 1016 ··· 1155 1148 break; 1156 1149 case -NFS4ERR_RETRY_UNCACHED_REP: 1157 1150 break; 1158 - case -EAGAIN: 1159 - return -NFS4ERR_RESET_TO_PNFS; 1160 1151 /* Invalidate Layout errors */ 1161 1152 case -NFS4ERR_PNFS_NO_LAYOUT: 1162 1153 case -ESTALE: /* mapped NFS4ERR_STALE */ ··· 1215 1210 case -EBADHANDLE: 1216 1211 case -ELOOP: 1217 1212 case -ENOSPC: 1218 - case -EAGAIN: 1219 1213 break; 1220 1214 case -EJUKEBOX: 1221 1215 nfs_inc_stats(lseg->pls_layout->plh_inode, NFSIOS_DELAY); ··· 1447 1443 return; 1448 1444 1449 1445 ff_layout_read_prepare_common(task, hdr); 1450 - } 1451 - 1452 - static void 1453 - ff_layout_io_prepare_transmit(struct rpc_task *task, 1454 - void *data) 1455 - { 1456 - struct nfs_pgio_header *hdr = data; 1457 - 1458 - if (!pnfs_is_valid_lseg(hdr->lseg)) 1459 - rpc_exit(task, -EAGAIN); 1460 1446 } 1461 1447 1462 1448 static void ff_layout_read_call_done(struct rpc_task *task, void *data) ··· 1734 1740 1735 1741 static const struct rpc_call_ops ff_layout_read_call_ops_v3 = { 1736 1742 .rpc_call_prepare = ff_layout_read_prepare_v3, 1737 - .rpc_call_prepare_transmit = ff_layout_io_prepare_transmit, 1738 1743 .rpc_call_done = ff_layout_read_call_done, 1739 1744 .rpc_count_stats = ff_layout_read_count_stats, 1740 1745 .rpc_release = ff_layout_read_release, ··· 1741 1748 1742 1749 static const struct rpc_call_ops ff_layout_read_call_ops_v4 = { 1743 1750 .rpc_call_prepare = ff_layout_read_prepare_v4, 1744 - .rpc_call_prepare_transmit = ff_layout_io_prepare_transmit, 1745 1751 .rpc_call_done = ff_layout_read_call_done, 1746 1752 .rpc_count_stats = ff_layout_read_count_stats, 1747 1753 .rpc_release = ff_layout_read_release, ··· 1748 1756 1749 1757 static const struct rpc_call_ops ff_layout_write_call_ops_v3 = { 1750 1758 .rpc_call_prepare = ff_layout_write_prepare_v3, 1751 - .rpc_call_prepare_transmit = ff_layout_io_prepare_transmit, 1752 1759 .rpc_call_done = ff_layout_write_call_done, 1753 1760 .rpc_count_stats = ff_layout_write_count_stats, 1754 1761 .rpc_release = ff_layout_write_release, ··· 1755 1764 1756 1765 static const struct rpc_call_ops ff_layout_write_call_ops_v4 = { 1757 1766 .rpc_call_prepare = ff_layout_write_prepare_v4, 1758 - .rpc_call_prepare_transmit = ff_layout_io_prepare_transmit, 1759 1767 .rpc_call_done = ff_layout_write_call_done, 1760 1768 .rpc_count_stats = ff_layout_write_count_stats, 1761 1769 .rpc_release = ff_layout_write_release,
+19 -14
fs/nfs/inode.c
··· 1403 1403 if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ)) 1404 1404 return 0; 1405 1405 1406 + /* No fileid? Just exit */ 1407 + if (!(fattr->valid & NFS_ATTR_FATTR_FILEID)) 1408 + return 0; 1406 1409 /* Has the inode gone and changed behind our back? */ 1407 - if ((fattr->valid & NFS_ATTR_FATTR_FILEID) && nfsi->fileid != fattr->fileid) 1410 + if (nfsi->fileid != fattr->fileid) { 1411 + /* Is this perhaps the mounted-on fileid? */ 1412 + if ((fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) && 1413 + nfsi->fileid == fattr->mounted_on_fileid) 1414 + return 0; 1408 1415 return -ESTALE; 1416 + } 1409 1417 if ((fattr->valid & NFS_ATTR_FATTR_TYPE) && (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) 1410 1418 return -ESTALE; 1419 + 1411 1420 1412 1421 if (!nfs_file_has_buffered_writers(nfsi)) { 1413 1422 /* Verify a few of the more important attributes */ ··· 1777 1768 EXPORT_SYMBOL_GPL(nfs_post_op_update_inode_force_wcc); 1778 1769 1779 1770 1780 - static inline bool nfs_fileid_valid(struct nfs_inode *nfsi, 1781 - struct nfs_fattr *fattr) 1782 - { 1783 - bool ret1 = true, ret2 = true; 1784 - 1785 - if (fattr->valid & NFS_ATTR_FATTR_FILEID) 1786 - ret1 = (nfsi->fileid == fattr->fileid); 1787 - if (fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) 1788 - ret2 = (nfsi->fileid == fattr->mounted_on_fileid); 1789 - return ret1 || ret2; 1790 - } 1791 - 1792 1771 /* 1793 1772 * Many nfs protocol calls return the new file attributes after 1794 1773 * an operation. Here we update the inode to reflect the state ··· 1807 1810 nfs_display_fhandle_hash(NFS_FH(inode)), 1808 1811 atomic_read(&inode->i_count), fattr->valid); 1809 1812 1810 - if (!nfs_fileid_valid(nfsi, fattr)) { 1813 + /* No fileid? Just exit */ 1814 + if (!(fattr->valid & NFS_ATTR_FATTR_FILEID)) 1815 + return 0; 1816 + /* Has the inode gone and changed behind our back? */ 1817 + if (nfsi->fileid != fattr->fileid) { 1818 + /* Is this perhaps the mounted-on fileid? */ 1819 + if ((fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) && 1820 + nfsi->fileid == fattr->mounted_on_fileid) 1821 + return 0; 1811 1822 printk(KERN_ERR "NFS: server %s error: fileid changed\n" 1812 1823 "fsid %s: expected fileid 0x%Lx, got 0x%Lx\n", 1813 1824 NFS_SERVER(inode)->nfs_client->cl_hostname,
+10
fs/nfs/internal.h
··· 775 775 } 776 776 } 777 777 778 + static inline bool nfs_error_is_fatal_on_server(int err) 779 + { 780 + switch (err) { 781 + case 0: 782 + case -ERESTARTSYS: 783 + case -EINTR: 784 + return false; 785 + } 786 + return nfs_error_is_fatal(err); 787 + }
+6 -6
fs/nfs/nfs4file.c
··· 73 73 if (IS_ERR(inode)) { 74 74 err = PTR_ERR(inode); 75 75 switch (err) { 76 - case -EPERM: 77 - case -EACCES: 78 - case -EDQUOT: 79 - case -ENOSPC: 80 - case -EROFS: 81 - goto out_put_ctx; 82 76 default: 77 + goto out_put_ctx; 78 + case -ENOENT: 79 + case -ESTALE: 80 + case -EISDIR: 81 + case -ENOTDIR: 82 + case -ELOOP: 83 83 goto out_drop; 84 84 } 85 85 }
+11 -8
fs/nfs/pagelist.c
··· 590 590 } 591 591 592 592 hdr->res.fattr = &hdr->fattr; 593 - hdr->res.count = count; 593 + hdr->res.count = 0; 594 594 hdr->res.eof = 0; 595 595 hdr->res.verf = &hdr->verf; 596 596 nfs_fattr_init(&hdr->fattr); ··· 1251 1251 int nfs_pageio_resend(struct nfs_pageio_descriptor *desc, 1252 1252 struct nfs_pgio_header *hdr) 1253 1253 { 1254 - LIST_HEAD(failed); 1254 + LIST_HEAD(pages); 1255 1255 1256 1256 desc->pg_io_completion = hdr->io_completion; 1257 1257 desc->pg_dreq = hdr->dreq; 1258 - while (!list_empty(&hdr->pages)) { 1259 - struct nfs_page *req = nfs_list_entry(hdr->pages.next); 1258 + list_splice_init(&hdr->pages, &pages); 1259 + while (!list_empty(&pages)) { 1260 + struct nfs_page *req = nfs_list_entry(pages.next); 1260 1261 1261 1262 if (!nfs_pageio_add_request(desc, req)) 1262 - nfs_list_move_request(req, &failed); 1263 + break; 1263 1264 } 1264 1265 nfs_pageio_complete(desc); 1265 - if (!list_empty(&failed)) { 1266 - list_move(&failed, &hdr->pages); 1267 - return desc->pg_error < 0 ? desc->pg_error : -EIO; 1266 + if (!list_empty(&pages)) { 1267 + int err = desc->pg_error < 0 ? desc->pg_error : -EIO; 1268 + hdr->completion_ops->error_cleanup(&pages, err); 1269 + nfs_set_pgio_error(hdr, err, hdr->io_start); 1270 + return err; 1268 1271 } 1269 1272 return 0; 1270 1273 }
+10 -5
fs/nfs/pnfs_nfs.c
··· 627 627 /* Add this address as an alias */ 628 628 rpc_clnt_add_xprt(clp->cl_rpcclient, &xprt_args, 629 629 rpc_clnt_test_and_add_xprt, NULL); 630 - } else 631 - clp = get_v3_ds_connect(mds_srv, 632 - (struct sockaddr *)&da->da_addr, 633 - da->da_addrlen, IPPROTO_TCP, 634 - timeo, retrans); 630 + continue; 631 + } 632 + clp = get_v3_ds_connect(mds_srv, 633 + (struct sockaddr *)&da->da_addr, 634 + da->da_addrlen, IPPROTO_TCP, 635 + timeo, retrans); 636 + if (IS_ERR(clp)) 637 + continue; 638 + clp->cl_rpcclient->cl_softerr = 0; 639 + clp->cl_rpcclient->cl_softrtry = 0; 635 640 } 636 641 637 642 if (IS_ERR(clp)) {
+5 -2
fs/nfs/proc.c
··· 594 594 /* Emulate the eof flag, which isn't normally needed in NFSv2 595 595 * as it is guaranteed to always return the file attributes 596 596 */ 597 - if (hdr->args.offset + hdr->res.count >= hdr->res.fattr->size) 597 + if ((hdr->res.count == 0 && hdr->args.count > 0) || 598 + hdr->args.offset + hdr->res.count >= hdr->res.fattr->size) 598 599 hdr->res.eof = 1; 599 600 } 600 601 return 0; ··· 616 615 617 616 static int nfs_write_done(struct rpc_task *task, struct nfs_pgio_header *hdr) 618 617 { 619 - if (task->tk_status >= 0) 618 + if (task->tk_status >= 0) { 619 + hdr->res.count = hdr->args.count; 620 620 nfs_writeback_update_inode(hdr); 621 + } 621 622 return 0; 622 623 } 623 624
+26 -9
fs/nfs/read.c
··· 91 91 } 92 92 EXPORT_SYMBOL_GPL(nfs_pageio_reset_read_mds); 93 93 94 - static void nfs_readpage_release(struct nfs_page *req) 94 + static void nfs_readpage_release(struct nfs_page *req, int error) 95 95 { 96 96 struct inode *inode = d_inode(nfs_req_openctx(req)->dentry); 97 + struct page *page = req->wb_page; 97 98 98 99 dprintk("NFS: read done (%s/%llu %d@%lld)\n", inode->i_sb->s_id, 99 100 (unsigned long long)NFS_FILEID(inode), req->wb_bytes, 100 101 (long long)req_offset(req)); 101 102 103 + if (nfs_error_is_fatal_on_server(error) && error != -ETIMEDOUT) 104 + SetPageError(page); 102 105 if (nfs_page_group_sync_on_bit(req, PG_UNLOCKPAGE)) { 103 - if (PageUptodate(req->wb_page)) 104 - nfs_readpage_to_fscache(inode, req->wb_page, 0); 106 + struct address_space *mapping = page_file_mapping(page); 105 107 106 - unlock_page(req->wb_page); 108 + if (PageUptodate(page)) 109 + nfs_readpage_to_fscache(inode, page, 0); 110 + else if (!PageError(page) && !PagePrivate(page)) 111 + generic_error_remove_page(mapping, page); 112 + unlock_page(page); 107 113 } 108 114 nfs_release_request(req); 109 115 } ··· 137 131 &nfs_async_read_completion_ops); 138 132 if (!nfs_pageio_add_request(&pgio, new)) { 139 133 nfs_list_remove_request(new); 140 - nfs_readpage_release(new); 134 + nfs_readpage_release(new, pgio.pg_error); 141 135 } 142 136 nfs_pageio_complete(&pgio); 143 137 ··· 159 153 static void nfs_read_completion(struct nfs_pgio_header *hdr) 160 154 { 161 155 unsigned long bytes = 0; 156 + int error; 162 157 163 158 if (test_bit(NFS_IOHDR_REDO, &hdr->flags)) 164 159 goto out; ··· 186 179 zero_user_segment(page, start, end); 187 180 } 188 181 } 182 + error = 0; 189 183 bytes += req->wb_bytes; 190 184 if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) { 191 185 if (bytes <= hdr->good_bytes) 192 186 nfs_page_group_set_uptodate(req); 187 + else { 188 + error = hdr->error; 189 + xchg(&nfs_req_openctx(req)->error, error); 190 + } 193 191 } else 194 192 nfs_page_group_set_uptodate(req); 195 193 nfs_list_remove_request(req); 196 - nfs_readpage_release(req); 194 + nfs_readpage_release(req, error); 197 195 } 198 196 out: 199 197 hdr->release(hdr); ··· 225 213 while (!list_empty(head)) { 226 214 req = nfs_list_entry(head->next); 227 215 nfs_list_remove_request(req); 228 - nfs_readpage_release(req); 216 + nfs_readpage_release(req, error); 229 217 } 230 218 } 231 219 ··· 349 337 goto out; 350 338 } 351 339 340 + xchg(&ctx->error, 0); 352 341 error = nfs_readpage_async(ctx, inode, page); 353 - 342 + if (!error) { 343 + error = wait_on_page_locked_killable(page); 344 + if (!PageUptodate(page) && !error) 345 + error = xchg(&ctx->error, 0); 346 + } 354 347 out: 355 348 put_nfs_open_context(ctx); 356 349 return error; ··· 389 372 zero_user_segment(page, len, PAGE_SIZE); 390 373 if (!nfs_pageio_add_request(desc->pgio, new)) { 391 374 nfs_list_remove_request(new); 392 - nfs_readpage_release(new); 393 375 error = desc->pgio->pg_error; 376 + nfs_readpage_release(new, error); 394 377 goto out; 395 378 } 396 379 return 0;
+16 -22
fs/nfs/write.c
··· 57 57 static const struct nfs_pgio_completion_ops nfs_async_write_completion_ops; 58 58 static const struct nfs_commit_completion_ops nfs_commit_completion_ops; 59 59 static const struct nfs_rw_ops nfs_rw_write_ops; 60 + static void nfs_inode_remove_request(struct nfs_page *req); 60 61 static void nfs_clear_request_commit(struct nfs_page *req); 61 62 static void nfs_init_cinfo_from_inode(struct nfs_commit_info *cinfo, 62 63 struct inode *inode); ··· 592 591 593 592 static void nfs_write_error(struct nfs_page *req, int error) 594 593 { 594 + nfs_set_pageerror(page_file_mapping(req->wb_page)); 595 595 nfs_mapping_set_error(req->wb_page, error); 596 + nfs_inode_remove_request(req); 596 597 nfs_end_page_writeback(req); 597 598 nfs_release_request(req); 598 - } 599 - 600 - static bool 601 - nfs_error_is_fatal_on_server(int err) 602 - { 603 - switch (err) { 604 - case 0: 605 - case -ERESTARTSYS: 606 - case -EINTR: 607 - return false; 608 - } 609 - return nfs_error_is_fatal(err); 610 599 } 611 600 612 601 /* ··· 606 615 static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio, 607 616 struct page *page) 608 617 { 609 - struct address_space *mapping; 610 618 struct nfs_page *req; 611 619 int ret = 0; 612 620 ··· 620 630 WARN_ON_ONCE(test_bit(PG_CLEAN, &req->wb_flags)); 621 631 622 632 /* If there is a fatal error that covers this write, just exit */ 623 - ret = 0; 624 - mapping = page_file_mapping(page); 625 - if (test_bit(AS_ENOSPC, &mapping->flags) || 626 - test_bit(AS_EIO, &mapping->flags)) 633 + ret = pgio->pg_error; 634 + if (nfs_error_is_fatal_on_server(ret)) 627 635 goto out_launder; 628 636 637 + ret = 0; 629 638 if (!nfs_pageio_add_request(pgio, req)) { 630 639 ret = pgio->pg_error; 631 640 /* ··· 636 647 } else 637 648 ret = -EAGAIN; 638 649 nfs_redirty_request(req); 650 + pgio->pg_error = 0; 639 651 } else 640 652 nfs_add_stats(page_file_mapping(page)->host, 641 653 NFSIOS_WRITEPAGES, 1); ··· 656 666 ret = nfs_page_async_flush(pgio, page); 657 667 if (ret == -EAGAIN) { 658 668 redirty_page_for_writepage(wbc, page); 659 - ret = 0; 669 + ret = AOP_WRITEPAGE_ACTIVATE; 660 670 } 661 671 return ret; 662 672 } ··· 675 685 nfs_pageio_init_write(&pgio, inode, 0, 676 686 false, &nfs_async_write_completion_ops); 677 687 err = nfs_do_writepage(page, wbc, &pgio); 688 + pgio.pg_error = 0; 678 689 nfs_pageio_complete(&pgio); 679 690 if (err < 0) 680 691 return err; 681 - if (pgio.pg_error < 0) 692 + if (nfs_error_is_fatal(pgio.pg_error)) 682 693 return pgio.pg_error; 683 694 return 0; 684 695 } ··· 689 698 int ret; 690 699 691 700 ret = nfs_writepage_locked(page, wbc); 692 - unlock_page(page); 701 + if (ret != AOP_WRITEPAGE_ACTIVATE) 702 + unlock_page(page); 693 703 return ret; 694 704 } 695 705 ··· 699 707 int ret; 700 708 701 709 ret = nfs_do_writepage(page, wbc, data); 702 - unlock_page(page); 710 + if (ret != AOP_WRITEPAGE_ACTIVATE) 711 + unlock_page(page); 703 712 return ret; 704 713 } 705 714 ··· 726 733 &nfs_async_write_completion_ops); 727 734 pgio.pg_io_completion = ioc; 728 735 err = write_cache_pages(mapping, wbc, nfs_writepages_callback, &pgio); 736 + pgio.pg_error = 0; 729 737 nfs_pageio_complete(&pgio); 730 738 nfs_io_completion_put(ioc); 731 739 732 740 if (err < 0) 733 741 goto out_err; 734 742 err = pgio.pg_error; 735 - if (err < 0) 743 + if (nfs_error_is_fatal(err)) 736 744 goto out_err; 737 745 return 0; 738 746 out_err:
-1
include/linux/sunrpc/sched.h
··· 98 98 99 99 struct rpc_call_ops { 100 100 void (*rpc_call_prepare)(struct rpc_task *, void *); 101 - void (*rpc_call_prepare_transmit)(struct rpc_task *, void *); 102 101 void (*rpc_call_done)(struct rpc_task *, void *); 103 102 void (*rpc_count_stats)(struct rpc_task *, void *); 104 103 void (*rpc_release)(void *);
+32 -15
net/sunrpc/clnt.c
··· 1970 1970 static void 1971 1971 call_bind_status(struct rpc_task *task) 1972 1972 { 1973 + struct rpc_xprt *xprt = task->tk_rqstp->rq_xprt; 1973 1974 int status = -EIO; 1974 1975 1975 1976 if (rpc_task_transmitted(task)) { ··· 1978 1977 return; 1979 1978 } 1980 1979 1981 - if (task->tk_status >= 0) { 1982 - dprint_status(task); 1980 + dprint_status(task); 1981 + trace_rpc_bind_status(task); 1982 + if (task->tk_status >= 0) 1983 + goto out_next; 1984 + if (xprt_bound(xprt)) { 1983 1985 task->tk_status = 0; 1984 - task->tk_action = call_connect; 1985 - return; 1986 + goto out_next; 1986 1987 } 1987 1988 1988 - trace_rpc_bind_status(task); 1989 1989 switch (task->tk_status) { 1990 1990 case -ENOMEM: 1991 1991 dprintk("RPC: %5u rpcbind out of memory\n", task->tk_pid); ··· 2004 2002 break; 2005 2003 task->tk_rebind_retry--; 2006 2004 rpc_delay(task, 3*HZ); 2005 + goto retry_timeout; 2006 + case -ENOBUFS: 2007 + rpc_delay(task, HZ >> 2); 2007 2008 goto retry_timeout; 2008 2009 case -EAGAIN: 2009 2010 goto retry_timeout; ··· 2031 2026 case -ENETDOWN: 2032 2027 case -EHOSTUNREACH: 2033 2028 case -ENETUNREACH: 2034 - case -ENOBUFS: 2035 2029 case -EPIPE: 2036 2030 dprintk("RPC: %5u remote rpcbind unreachable: %d\n", 2037 2031 task->tk_pid, task->tk_status); ··· 2047 2043 2048 2044 rpc_call_rpcerror(task, status); 2049 2045 return; 2050 - 2046 + out_next: 2047 + task->tk_action = call_connect; 2048 + return; 2051 2049 retry_timeout: 2052 2050 task->tk_status = 0; 2053 2051 task->tk_action = call_bind; ··· 2096 2090 static void 2097 2091 call_connect_status(struct rpc_task *task) 2098 2092 { 2093 + struct rpc_xprt *xprt = task->tk_rqstp->rq_xprt; 2099 2094 struct rpc_clnt *clnt = task->tk_client; 2100 2095 int status = task->tk_status; 2101 2096 ··· 2106 2099 } 2107 2100 2108 2101 dprint_status(task); 2109 - 2110 2102 trace_rpc_connect_status(task); 2103 + 2104 + if (task->tk_status == 0) { 2105 + clnt->cl_stats->netreconn++; 2106 + goto out_next; 2107 + } 2108 + if (xprt_connected(xprt)) { 2109 + task->tk_status = 0; 2110 + goto out_next; 2111 + } 2112 + 2111 2113 task->tk_status = 0; 2112 2114 switch (status) { 2113 2115 case -ECONNREFUSED: ··· 2133 2117 case -ENETDOWN: 2134 2118 case -ENETUNREACH: 2135 2119 case -EHOSTUNREACH: 2136 - case -EADDRINUSE: 2137 - case -ENOBUFS: 2138 2120 case -EPIPE: 2139 2121 xprt_conditional_disconnect(task->tk_rqstp->rq_xprt, 2140 2122 task->tk_rqstp->rq_connect_cookie); ··· 2141 2127 /* retry with existing socket, after a delay */ 2142 2128 rpc_delay(task, 3*HZ); 2143 2129 /* fall through */ 2130 + case -EADDRINUSE: 2144 2131 case -ENOTCONN: 2145 2132 case -EAGAIN: 2146 2133 case -ETIMEDOUT: 2147 2134 goto out_retry; 2148 - case 0: 2149 - clnt->cl_stats->netreconn++; 2150 - task->tk_action = call_transmit; 2151 - return; 2135 + case -ENOBUFS: 2136 + rpc_delay(task, HZ >> 2); 2137 + goto out_retry; 2152 2138 } 2153 2139 rpc_call_rpcerror(task, status); 2140 + return; 2141 + out_next: 2142 + task->tk_action = call_transmit; 2154 2143 return; 2155 2144 out_retry: 2156 2145 /* Check for timeouts before looping back to call_bind */ ··· 2382 2365 case -ECONNABORTED: 2383 2366 case -ENOTCONN: 2384 2367 rpc_force_rebind(clnt); 2385 - /* fall through */ 2368 + break; 2386 2369 case -EADDRINUSE: 2387 2370 rpc_delay(task, 3*HZ); 2388 2371 /* fall through */
-7
net/sunrpc/xprt.c
··· 1408 1408 status = -EBADMSG; 1409 1409 goto out_dequeue; 1410 1410 } 1411 - if (task->tk_ops->rpc_call_prepare_transmit) { 1412 - task->tk_ops->rpc_call_prepare_transmit(task, 1413 - task->tk_calldata); 1414 - status = task->tk_status; 1415 - if (status < 0) 1416 - goto out_dequeue; 1417 - } 1418 1411 if (RPC_SIGNALLED(task)) { 1419 1412 status = -ERESTARTSYS; 1420 1413 goto out_dequeue;