Merge branch 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6

* 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6:
nfs: don't lose MS_SYNCHRONOUS on remount of noac mount
NFS: Return meaningful status from decode_secinfo()
NFSv4: Ensure we request the ordinary fileid when doing readdirplus
NFSv4: Ensure that clientid and session establishment can time out
SUNRPC: Allow RPC calls to return ETIMEDOUT instead of EIO
NFSv4.1: Don't loop forever in nfs4_proc_create_session
NFSv4: Handle NFS4ERR_WRONGSEC outside of nfs4_handle_exception()
NFSv4.1: Don't update sequence number if rpc_task is not sent
NFSv4.1: Ensure state manager thread dies on last umount
SUNRPC: Fix the SUNRPC Kerberos V RPCSEC_GSS module dependencies
NFS: Use correct variable for page bounds checking
NFS: don't negotiate when user specifies sec flavor
NFS: Attempt mount with default sec flavor first
NFS: flav_array honors NFS_MAX_SECFLAVORS
NFS: Fix infinite loop in gss_create_upcall()
Don't mark_inode_dirty_sync() while holding lock
NFS: Get rid of pointless test in nfs_commit_done
NFS: Remove unused argument from nfs_find_best_sec()
NFS: Eliminate duplicate call to nfs_mark_request_dirty
NFS: Remove dead code from nfs_fs_mount()

+165 -122
+2 -2
fs/nfs/namespace.c
··· 119 119 } 120 120 121 121 #ifdef CONFIG_NFS_V4 122 - static rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *flavors, struct inode *inode) 122 + static rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *flavors) 123 123 { 124 124 struct gss_api_mech *mech; 125 125 struct xdr_netobj oid; ··· 166 166 } 167 167 flavors = page_address(page); 168 168 ret = secinfo(parent->d_inode, &dentry->d_name, flavors); 169 - *flavor = nfs_find_best_sec(flavors, dentry->d_inode); 169 + *flavor = nfs_find_best_sec(flavors); 170 170 put_page(page); 171 171 } 172 172
+1
fs/nfs/nfs4_fs.h
··· 47 47 NFS4CLNT_LAYOUTRECALL, 48 48 NFS4CLNT_SESSION_RESET, 49 49 NFS4CLNT_RECALL_SLOT, 50 + NFS4CLNT_LEASE_CONFIRM, 50 51 }; 51 52 52 53 enum nfs4_session_state {
+60 -62
fs/nfs/nfs4proc.c
··· 46 46 #include <linux/nfs4.h> 47 47 #include <linux/nfs_fs.h> 48 48 #include <linux/nfs_page.h> 49 + #include <linux/nfs_mount.h> 49 50 #include <linux/namei.h> 50 51 #include <linux/mount.h> 51 52 #include <linux/module.h> ··· 444 443 if (res->sr_status == 1) 445 444 res->sr_status = NFS_OK; 446 445 447 - /* -ERESTARTSYS can result in skipping nfs41_sequence_setup */ 448 - if (!res->sr_slot) 446 + /* don't increment the sequence number if the task wasn't sent */ 447 + if (!RPC_WAS_SENT(task)) 449 448 goto out; 450 449 451 450 /* Check the SEQUENCE operation status */ ··· 2186 2185 struct nfs4_exception exception = { }; 2187 2186 int err; 2188 2187 do { 2189 - err = nfs4_handle_exception(server, 2190 - _nfs4_lookup_root(server, fhandle, info), 2191 - &exception); 2188 + err = _nfs4_lookup_root(server, fhandle, info); 2189 + switch (err) { 2190 + case 0: 2191 + case -NFS4ERR_WRONGSEC: 2192 + break; 2193 + default: 2194 + err = nfs4_handle_exception(server, err, &exception); 2195 + } 2192 2196 } while (exception.retry); 2193 2197 return err; 2194 2198 } ··· 2214 2208 return ret; 2215 2209 } 2216 2210 2211 + static int nfs4_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle, 2212 + struct nfs_fsinfo *info) 2213 + { 2214 + int i, len, status = 0; 2215 + rpc_authflavor_t flav_array[NFS_MAX_SECFLAVORS]; 2216 + 2217 + len = gss_mech_list_pseudoflavors(&flav_array[0]); 2218 + flav_array[len] = RPC_AUTH_NULL; 2219 + len += 1; 2220 + 2221 + for (i = 0; i < len; i++) { 2222 + status = nfs4_lookup_root_sec(server, fhandle, info, flav_array[i]); 2223 + if (status == -NFS4ERR_WRONGSEC || status == -EACCES) 2224 + continue; 2225 + break; 2226 + } 2227 + /* 2228 + * -EACCESS could mean that the user doesn't have correct permissions 2229 + * to access the mount. It could also mean that we tried to mount 2230 + * with a gss auth flavor, but rpc.gssd isn't running. Either way, 2231 + * existing mount programs don't handle -EACCES very well so it should 2232 + * be mapped to -EPERM instead. 2233 + */ 2234 + if (status == -EACCES) 2235 + status = -EPERM; 2236 + return status; 2237 + } 2238 + 2217 2239 /* 2218 2240 * get the file handle for the "/" directory on the server 2219 2241 */ 2220 2242 static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, 2221 2243 struct nfs_fsinfo *info) 2222 2244 { 2223 - int i, len, status = 0; 2224 - rpc_authflavor_t flav_array[NFS_MAX_SECFLAVORS + 2]; 2225 - 2226 - flav_array[0] = RPC_AUTH_UNIX; 2227 - len = gss_mech_list_pseudoflavors(&flav_array[1]); 2228 - flav_array[1+len] = RPC_AUTH_NULL; 2229 - len += 2; 2230 - 2231 - for (i = 0; i < len; i++) { 2232 - status = nfs4_lookup_root_sec(server, fhandle, info, flav_array[i]); 2233 - if (status != -EPERM) 2234 - break; 2235 - } 2245 + int status = nfs4_lookup_root(server, fhandle, info); 2246 + if ((status == -NFS4ERR_WRONGSEC) && !(server->flags & NFS_MOUNT_SECFLAVOUR)) 2247 + /* 2248 + * A status of -NFS4ERR_WRONGSEC will be mapped to -EPERM 2249 + * by nfs4_map_errors() as this function exits. 2250 + */ 2251 + status = nfs4_find_root_sec(server, fhandle, info); 2236 2252 if (status == 0) 2237 2253 status = nfs4_server_capabilities(server, fhandle); 2238 2254 if (status == 0) ··· 3751 3723 sizeof(setclientid.sc_uaddr), "%s.%u.%u", 3752 3724 clp->cl_ipaddr, port >> 8, port & 255); 3753 3725 3754 - status = rpc_call_sync(clp->cl_rpcclient, &msg, 0); 3726 + status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 3755 3727 if (status != -NFS4ERR_CLID_INUSE) 3756 3728 break; 3757 - if (signalled()) 3729 + if (loop != 0) { 3730 + ++clp->cl_id_uniquifier; 3758 3731 break; 3759 - if (loop++ & 1) 3760 - ssleep(clp->cl_lease_time / HZ + 1); 3761 - else 3762 - if (++clp->cl_id_uniquifier == 0) 3763 - break; 3732 + } 3733 + ++loop; 3734 + ssleep(clp->cl_lease_time / HZ + 1); 3764 3735 } 3765 3736 return status; 3766 3737 } 3767 3738 3768 - static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, 3739 + int nfs4_proc_setclientid_confirm(struct nfs_client *clp, 3769 3740 struct nfs4_setclientid_res *arg, 3770 3741 struct rpc_cred *cred) 3771 3742 { ··· 3779 3752 int status; 3780 3753 3781 3754 now = jiffies; 3782 - status = rpc_call_sync(clp->cl_rpcclient, &msg, 0); 3755 + status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 3783 3756 if (status == 0) { 3784 3757 spin_lock(&clp->cl_lock); 3785 3758 clp->cl_lease_time = fsinfo.lease_time * HZ; ··· 3787 3760 spin_unlock(&clp->cl_lock); 3788 3761 } 3789 3762 return status; 3790 - } 3791 - 3792 - int nfs4_proc_setclientid_confirm(struct nfs_client *clp, 3793 - struct nfs4_setclientid_res *arg, 3794 - struct rpc_cred *cred) 3795 - { 3796 - long timeout = 0; 3797 - int err; 3798 - do { 3799 - err = _nfs4_proc_setclientid_confirm(clp, arg, cred); 3800 - switch (err) { 3801 - case 0: 3802 - return err; 3803 - case -NFS4ERR_RESOURCE: 3804 - /* The IBM lawyers misread another document! */ 3805 - case -NFS4ERR_DELAY: 3806 - err = nfs4_delay(clp->cl_rpcclient, &timeout); 3807 - } 3808 - } while (err == 0); 3809 - return err; 3810 3763 } 3811 3764 3812 3765 struct nfs4_delegreturndata { ··· 4793 4786 init_utsname()->domainname, 4794 4787 clp->cl_rpcclient->cl_auth->au_flavor); 4795 4788 4796 - status = rpc_call_sync(clp->cl_rpcclient, &msg, 0); 4789 + status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 4797 4790 if (!status) 4798 4791 status = nfs4_check_cl_exchange_flags(clp->cl_exchange_flags); 4799 4792 dprintk("<-- %s status= %d\n", __func__, status); ··· 4876 4869 .rpc_client = clp->cl_rpcclient, 4877 4870 .rpc_message = &msg, 4878 4871 .callback_ops = &nfs4_get_lease_time_ops, 4879 - .callback_data = &data 4872 + .callback_data = &data, 4873 + .flags = RPC_TASK_TIMEOUT, 4880 4874 }; 4881 4875 int status; 4882 4876 ··· 5179 5171 nfs4_init_channel_attrs(&args); 5180 5172 args.flags = (SESSION4_PERSIST | SESSION4_BACK_CHAN); 5181 5173 5182 - status = rpc_call_sync(session->clp->cl_rpcclient, &msg, 0); 5174 + status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 5183 5175 5184 5176 if (!status) 5185 5177 /* Verify the session's negotiated channel_attrs values */ ··· 5202 5194 int status; 5203 5195 unsigned *ptr; 5204 5196 struct nfs4_session *session = clp->cl_session; 5205 - long timeout = 0; 5206 - int err; 5207 5197 5208 5198 dprintk("--> %s clp=%p session=%p\n", __func__, clp, session); 5209 5199 5210 - do { 5211 - status = _nfs4_proc_create_session(clp); 5212 - if (status == -NFS4ERR_DELAY) { 5213 - err = nfs4_delay(clp->cl_rpcclient, &timeout); 5214 - if (err) 5215 - status = err; 5216 - } 5217 - } while (status == -NFS4ERR_DELAY); 5218 - 5200 + status = _nfs4_proc_create_session(clp); 5219 5201 if (status) 5220 5202 goto out; 5221 5203 ··· 5246 5248 msg.rpc_argp = session; 5247 5249 msg.rpc_resp = NULL; 5248 5250 msg.rpc_cred = NULL; 5249 - status = rpc_call_sync(session->clp->cl_rpcclient, &msg, 0); 5251 + status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 5250 5252 5251 5253 if (status) 5252 5254 printk(KERN_WARNING
+34 -17
fs/nfs/nfs4state.c
··· 64 64 65 65 int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred) 66 66 { 67 - struct nfs4_setclientid_res clid; 67 + struct nfs4_setclientid_res clid = { 68 + .clientid = clp->cl_clientid, 69 + .confirm = clp->cl_confirm, 70 + }; 68 71 unsigned short port; 69 72 int status; 70 73 74 + if (test_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state)) 75 + goto do_confirm; 71 76 port = nfs_callback_tcpport; 72 77 if (clp->cl_addr.ss_family == AF_INET6) 73 78 port = nfs_callback_tcpport6; ··· 80 75 status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, port, cred, &clid); 81 76 if (status != 0) 82 77 goto out; 78 + clp->cl_clientid = clid.clientid; 79 + clp->cl_confirm = clid.confirm; 80 + set_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); 81 + do_confirm: 83 82 status = nfs4_proc_setclientid_confirm(clp, &clid, cred); 84 83 if (status != 0) 85 84 goto out; 86 - clp->cl_clientid = clid.clientid; 85 + clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); 87 86 nfs4_schedule_state_renewal(clp); 88 87 out: 89 88 return status; ··· 239 230 { 240 231 int status; 241 232 233 + if (test_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state)) 234 + goto do_confirm; 242 235 nfs4_begin_drain_session(clp); 243 236 status = nfs4_proc_exchange_id(clp, cred); 244 237 if (status != 0) 245 238 goto out; 239 + set_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); 240 + do_confirm: 246 241 status = nfs4_proc_create_session(clp); 247 242 if (status != 0) 248 243 goto out; 244 + clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); 249 245 nfs41_setup_state_renewal(clp); 250 246 nfs_mark_client_ready(clp, NFS_CS_READY); 251 247 out: ··· 1598 1584 */ 1599 1585 static void nfs4_set_lease_expired(struct nfs_client *clp, int status) 1600 1586 { 1601 - if (nfs4_has_session(clp)) { 1602 - switch (status) { 1603 - case -NFS4ERR_DELAY: 1604 - case -NFS4ERR_CLID_INUSE: 1605 - case -EAGAIN: 1606 - break; 1587 + switch (status) { 1588 + case -NFS4ERR_CLID_INUSE: 1589 + case -NFS4ERR_STALE_CLIENTID: 1590 + clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); 1591 + break; 1592 + case -NFS4ERR_DELAY: 1593 + case -ETIMEDOUT: 1594 + case -EAGAIN: 1595 + ssleep(1); 1596 + break; 1607 1597 1608 - case -EKEYEXPIRED: 1609 - nfs4_warn_keyexpired(clp->cl_hostname); 1610 - case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery 1611 - * in nfs4_exchange_id */ 1612 - default: 1613 - return; 1614 - } 1598 + case -EKEYEXPIRED: 1599 + nfs4_warn_keyexpired(clp->cl_hostname); 1600 + case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery 1601 + * in nfs4_exchange_id */ 1602 + default: 1603 + return; 1615 1604 } 1616 1605 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); 1617 1606 } ··· 1624 1607 int status = 0; 1625 1608 1626 1609 /* Ensure exclusive access to NFSv4 state */ 1627 - for(;;) { 1610 + do { 1628 1611 if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) { 1629 1612 /* We're going to have to re-establish a clientid */ 1630 1613 status = nfs4_reclaim_lease(clp); ··· 1708 1691 break; 1709 1692 if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0) 1710 1693 break; 1711 - } 1694 + } while (atomic_read(&clp->cl_count) > 1); 1712 1695 return; 1713 1696 out_error: 1714 1697 printk(KERN_WARNING "Error: state manager failed on NFSv4 server %s"
+28 -25
fs/nfs/nfs4xdr.c
··· 1452 1452 1453 1453 static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req, struct compound_hdr *hdr) 1454 1454 { 1455 - uint32_t attrs[2] = {0, 0}; 1455 + uint32_t attrs[2] = { 1456 + FATTR4_WORD0_RDATTR_ERROR, 1457 + FATTR4_WORD1_MOUNTED_ON_FILEID, 1458 + }; 1456 1459 uint32_t dircount = readdir->count >> 1; 1457 1460 __be32 *p; 1458 1461 1459 1462 if (readdir->plus) { 1460 1463 attrs[0] |= FATTR4_WORD0_TYPE|FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE| 1461 - FATTR4_WORD0_FSID|FATTR4_WORD0_FILEHANDLE; 1464 + FATTR4_WORD0_FSID|FATTR4_WORD0_FILEHANDLE|FATTR4_WORD0_FILEID; 1462 1465 attrs[1] |= FATTR4_WORD1_MODE|FATTR4_WORD1_NUMLINKS|FATTR4_WORD1_OWNER| 1463 1466 FATTR4_WORD1_OWNER_GROUP|FATTR4_WORD1_RAWDEV| 1464 1467 FATTR4_WORD1_SPACE_USED|FATTR4_WORD1_TIME_ACCESS| 1465 1468 FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY; 1466 1469 dircount >>= 1; 1467 1470 } 1468 - attrs[0] |= FATTR4_WORD0_RDATTR_ERROR|FATTR4_WORD0_FILEID; 1469 - attrs[1] |= FATTR4_WORD1_MOUNTED_ON_FILEID; 1470 - /* Switch to mounted_on_fileid if the server supports it */ 1471 - if (readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID) 1472 - attrs[0] &= ~FATTR4_WORD0_FILEID; 1473 - else 1474 - attrs[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID; 1471 + /* Use mounted_on_fileid only if the server supports it */ 1472 + if (!(readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)) 1473 + attrs[0] |= FATTR4_WORD0_FILEID; 1475 1474 1476 1475 p = reserve_space(xdr, 12+NFS4_VERIFIER_SIZE+20); 1477 1476 *p++ = cpu_to_be32(OP_READDIR); ··· 3139 3140 goto out_overflow; 3140 3141 xdr_decode_hyper(p, fileid); 3141 3142 bitmap[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID; 3142 - ret = NFS_ATTR_FATTR_FILEID; 3143 + ret = NFS_ATTR_FATTR_MOUNTED_ON_FILEID; 3143 3144 } 3144 3145 dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid); 3145 3146 return ret; ··· 4001 4002 { 4002 4003 int status; 4003 4004 umode_t fmode = 0; 4004 - uint64_t fileid; 4005 4005 uint32_t type; 4006 4006 4007 4007 status = decode_attr_type(xdr, bitmap, &type); ··· 4099 4101 goto xdr_error; 4100 4102 fattr->valid |= status; 4101 4103 4102 - status = decode_attr_mounted_on_fileid(xdr, bitmap, &fileid); 4104 + status = decode_attr_mounted_on_fileid(xdr, bitmap, &fattr->mounted_on_fileid); 4103 4105 if (status < 0) 4104 4106 goto xdr_error; 4105 - if (status != 0 && !(fattr->valid & status)) { 4106 - fattr->fileid = fileid; 4107 - fattr->valid |= status; 4108 - } 4107 + fattr->valid |= status; 4109 4108 4110 4109 xdr_error: 4111 4110 dprintk("%s: xdr returned %d\n", __func__, -status); ··· 4833 4838 struct nfs4_secinfo_flavor *sec_flavor; 4834 4839 int status; 4835 4840 __be32 *p; 4836 - int i; 4841 + int i, num_flavors; 4837 4842 4838 4843 status = decode_op_hdr(xdr, OP_SECINFO); 4844 + if (status) 4845 + goto out; 4839 4846 p = xdr_inline_decode(xdr, 4); 4840 4847 if (unlikely(!p)) 4841 4848 goto out_overflow; 4842 - res->flavors->num_flavors = be32_to_cpup(p); 4843 4849 4844 - for (i = 0; i < res->flavors->num_flavors; i++) { 4850 + res->flavors->num_flavors = 0; 4851 + num_flavors = be32_to_cpup(p); 4852 + 4853 + for (i = 0; i < num_flavors; i++) { 4845 4854 sec_flavor = &res->flavors->flavors[i]; 4846 - if ((char *)&sec_flavor[1] - (char *)res > PAGE_SIZE) 4855 + if ((char *)&sec_flavor[1] - (char *)res->flavors > PAGE_SIZE) 4847 4856 break; 4848 4857 4849 4858 p = xdr_inline_decode(xdr, 4); ··· 4856 4857 sec_flavor->flavor = be32_to_cpup(p); 4857 4858 4858 4859 if (sec_flavor->flavor == RPC_AUTH_GSS) { 4859 - if (decode_secinfo_gss(xdr, sec_flavor)) 4860 - break; 4860 + status = decode_secinfo_gss(xdr, sec_flavor); 4861 + if (status) 4862 + goto out; 4861 4863 } 4864 + res->flavors->num_flavors++; 4862 4865 } 4863 4866 4864 - return 0; 4865 - 4867 + out: 4868 + return status; 4866 4869 out_overflow: 4867 4870 print_overflow_msg(__func__, xdr); 4868 4871 return -EIO; ··· 6409 6408 if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh, 6410 6409 entry->server, 1) < 0) 6411 6410 goto out_overflow; 6412 - if (entry->fattr->valid & NFS_ATTR_FATTR_FILEID) 6411 + if (entry->fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) 6412 + entry->ino = entry->fattr->mounted_on_fileid; 6413 + else if (entry->fattr->valid & NFS_ATTR_FATTR_FILEID) 6413 6414 entry->ino = entry->fattr->fileid; 6414 6415 6415 6416 entry->d_type = DT_UNKNOWN;
+7 -1
fs/nfs/pnfs.c
··· 1004 1004 { 1005 1005 struct nfs_inode *nfsi = NFS_I(wdata->inode); 1006 1006 loff_t end_pos = wdata->args.offset + wdata->res.count; 1007 + bool mark_as_dirty = false; 1007 1008 1008 1009 spin_lock(&nfsi->vfs_inode.i_lock); 1009 1010 if (!test_and_set_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) { ··· 1012 1011 get_lseg(wdata->lseg); 1013 1012 wdata->lseg->pls_lc_cred = 1014 1013 get_rpccred(wdata->args.context->state->owner->so_cred); 1015 - mark_inode_dirty_sync(wdata->inode); 1014 + mark_as_dirty = true; 1016 1015 dprintk("%s: Set layoutcommit for inode %lu ", 1017 1016 __func__, wdata->inode->i_ino); 1018 1017 } 1019 1018 if (end_pos > wdata->lseg->pls_end_pos) 1020 1019 wdata->lseg->pls_end_pos = end_pos; 1021 1020 spin_unlock(&nfsi->vfs_inode.i_lock); 1021 + 1022 + /* if pnfs_layoutcommit_inode() runs between inode locks, the next one 1023 + * will be a noop because NFS_INO_LAYOUTCOMMIT will not be set */ 1024 + if (mark_as_dirty) 1025 + mark_inode_dirty_sync(wdata->inode); 1022 1026 } 1023 1027 EXPORT_SYMBOL_GPL(pnfs_set_layoutcommit); 1024 1028
+11 -2
fs/nfs/super.c
··· 1004 1004 return 0; 1005 1005 } 1006 1006 1007 + mnt->flags |= NFS_MOUNT_SECFLAVOUR; 1007 1008 mnt->auth_flavor_len = 1; 1008 1009 return 1; 1009 1010 } ··· 1977 1976 if (error < 0) 1978 1977 goto out; 1979 1978 1979 + /* 1980 + * noac is a special case. It implies -o sync, but that's not 1981 + * necessarily reflected in the mtab options. do_remount_sb 1982 + * will clear MS_SYNCHRONOUS if -o sync wasn't specified in the 1983 + * remount options, so we have to explicitly reset it. 1984 + */ 1985 + if (data->flags & NFS_MOUNT_NOAC) 1986 + *flags |= MS_SYNCHRONOUS; 1987 + 1980 1988 /* compare new mount options with old ones */ 1981 1989 error = nfs_compare_remount_data(nfss, data); 1982 1990 out: ··· 2245 2235 if (!s->s_root) { 2246 2236 /* initial superblock/root creation */ 2247 2237 nfs_fill_super(s, data); 2248 - nfs_fscache_get_super_cookie( 2249 - s, data ? data->fscache_uniq : NULL, NULL); 2238 + nfs_fscache_get_super_cookie(s, data->fscache_uniq, NULL); 2250 2239 } 2251 2240 2252 2241 mntroot = nfs_get_root(s, mntfh, dev_name);
+1 -3
fs/nfs/write.c
··· 680 680 req = nfs_setup_write_request(ctx, page, offset, count); 681 681 if (IS_ERR(req)) 682 682 return PTR_ERR(req); 683 - nfs_mark_request_dirty(req); 684 683 /* Update file length */ 685 684 nfs_grow_file(page, offset, count); 686 685 nfs_mark_uptodate(page, req->wb_pgbase, req->wb_bytes); ··· 1417 1418 task->tk_pid, task->tk_status); 1418 1419 1419 1420 /* Call the NFS version-specific code */ 1420 - if (NFS_PROTO(data->inode)->commit_done(task, data) != 0) 1421 - return; 1421 + NFS_PROTO(data->inode)->commit_done(task, data); 1422 1422 } 1423 1423 1424 1424 void nfs_commit_release_pages(struct nfs_write_data *data)
+1
include/linux/nfs_fs_sb.h
··· 47 47 48 48 #ifdef CONFIG_NFS_V4 49 49 u64 cl_clientid; /* constant */ 50 + nfs4_verifier cl_confirm; /* Clientid verifier */ 50 51 unsigned long cl_state; 51 52 52 53 spinlock_t cl_lock;
+2
include/linux/nfs_xdr.h
··· 50 50 } du; 51 51 struct nfs_fsid fsid; 52 52 __u64 fileid; 53 + __u64 mounted_on_fileid; 53 54 struct timespec atime; 54 55 struct timespec mtime; 55 56 struct timespec ctime; ··· 84 83 #define NFS_ATTR_FATTR_PRECHANGE (1U << 18) 85 84 #define NFS_ATTR_FATTR_V4_REFERRAL (1U << 19) /* NFSv4 referral */ 86 85 #define NFS_ATTR_FATTR_MOUNTPOINT (1U << 20) /* Treat as mountpoint */ 86 + #define NFS_ATTR_FATTR_MOUNTED_ON_FILEID (1U << 21) 87 87 88 88 #define NFS_ATTR_FATTR (NFS_ATTR_FATTR_TYPE \ 89 89 | NFS_ATTR_FATTR_MODE \
+4 -1
include/linux/sunrpc/sched.h
··· 127 127 #define RPC_TASK_KILLED 0x0100 /* task was killed */ 128 128 #define RPC_TASK_SOFT 0x0200 /* Use soft timeouts */ 129 129 #define RPC_TASK_SOFTCONN 0x0400 /* Fail if can't connect */ 130 + #define RPC_TASK_SENT 0x0800 /* message was sent */ 131 + #define RPC_TASK_TIMEOUT 0x1000 /* fail with ETIMEDOUT on timeout */ 130 132 131 133 #define RPC_IS_ASYNC(t) ((t)->tk_flags & RPC_TASK_ASYNC) 132 134 #define RPC_IS_SWAPPER(t) ((t)->tk_flags & RPC_TASK_SWAPPER) 133 135 #define RPC_DO_ROOTOVERRIDE(t) ((t)->tk_flags & RPC_TASK_ROOTCREDS) 134 136 #define RPC_ASSASSINATED(t) ((t)->tk_flags & RPC_TASK_KILLED) 135 - #define RPC_IS_SOFT(t) ((t)->tk_flags & RPC_TASK_SOFT) 137 + #define RPC_IS_SOFT(t) ((t)->tk_flags & (RPC_TASK_SOFT|RPC_TASK_TIMEOUT)) 136 138 #define RPC_IS_SOFTCONN(t) ((t)->tk_flags & RPC_TASK_SOFTCONN) 139 + #define RPC_WAS_SENT(t) ((t)->tk_flags & RPC_TASK_SENT) 137 140 138 141 #define RPC_TASK_RUNNING 0 139 142 #define RPC_TASK_QUEUED 1
+4 -5
net/sunrpc/Kconfig
··· 18 18 If unsure, say N. 19 19 20 20 config RPCSEC_GSS_KRB5 21 - tristate 21 + tristate "Secure RPC: Kerberos V mechanism" 22 22 depends on SUNRPC && CRYPTO 23 - prompt "Secure RPC: Kerberos V mechanism" if !(NFS_V4 || NFSD_V4) 23 + depends on CRYPTO_MD5 && CRYPTO_DES && CRYPTO_CBC && CRYPTO_CTS 24 + depends on CRYPTO_ECB && CRYPTO_HMAC && CRYPTO_SHA1 && CRYPTO_AES 25 + depends on CRYPTO_ARC4 24 26 default y 25 27 select SUNRPC_GSS 26 - select CRYPTO_MD5 27 - select CRYPTO_DES 28 - select CRYPTO_CBC 29 28 help 30 29 Choose Y here to enable Secure RPC using the Kerberos version 5 31 30 GSS-API mechanism (RFC 1964).
+5 -3
net/sunrpc/auth_gss/auth_gss.c
··· 520 520 warn_gssd(); 521 521 task->tk_timeout = 15*HZ; 522 522 rpc_sleep_on(&pipe_version_rpc_waitqueue, task, NULL); 523 - return 0; 523 + return -EAGAIN; 524 524 } 525 525 if (IS_ERR(gss_msg)) { 526 526 err = PTR_ERR(gss_msg); ··· 563 563 if (PTR_ERR(gss_msg) == -EAGAIN) { 564 564 err = wait_event_interruptible_timeout(pipe_version_waitqueue, 565 565 pipe_version >= 0, 15*HZ); 566 + if (pipe_version < 0) { 567 + warn_gssd(); 568 + err = -EACCES; 569 + } 566 570 if (err) 567 571 goto out; 568 - if (pipe_version < 0) 569 - warn_gssd(); 570 572 goto retry; 571 573 } 572 574 if (IS_ERR(gss_msg)) {
+4 -1
net/sunrpc/clnt.c
··· 1508 1508 if (clnt->cl_chatty) 1509 1509 printk(KERN_NOTICE "%s: server %s not responding, timed out\n", 1510 1510 clnt->cl_protname, clnt->cl_server); 1511 - rpc_exit(task, -EIO); 1511 + if (task->tk_flags & RPC_TASK_TIMEOUT) 1512 + rpc_exit(task, -ETIMEDOUT); 1513 + else 1514 + rpc_exit(task, -EIO); 1512 1515 return; 1513 1516 } 1514 1517
+1
net/sunrpc/xprt.c
··· 906 906 } 907 907 908 908 dprintk("RPC: %5u xmit complete\n", task->tk_pid); 909 + task->tk_flags |= RPC_TASK_SENT; 909 910 spin_lock_bh(&xprt->transport_lock); 910 911 911 912 xprt->ops->set_retrans_timeout(task);