aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4state.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r--fs/nfsd/nfs4state.c235
1 files changed, 158 insertions, 77 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 316ec843dec2..43f42290e5df 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -97,19 +97,20 @@ nfs4_lock_state(void)
97 97
98static void free_session(struct nfsd4_session *); 98static void free_session(struct nfsd4_session *);
99 99
100void nfsd4_put_session(struct nfsd4_session *ses) 100static bool is_session_dead(struct nfsd4_session *ses)
101{ 101{
102 atomic_dec(&ses->se_ref); 102 return ses->se_flags & NFS4_SESSION_DEAD;
103} 103}
104 104
105static bool is_session_dead(struct nfsd4_session *ses) 105void nfsd4_put_session(struct nfsd4_session *ses)
106{ 106{
107 return ses->se_flags & NFS4_SESSION_DEAD; 107 if (atomic_dec_and_test(&ses->se_ref) && is_session_dead(ses))
108 free_session(ses);
108} 109}
109 110
110static __be32 mark_session_dead_locked(struct nfsd4_session *ses) 111static __be32 mark_session_dead_locked(struct nfsd4_session *ses, int ref_held_by_me)
111{ 112{
112 if (atomic_read(&ses->se_ref)) 113 if (atomic_read(&ses->se_ref) > ref_held_by_me)
113 return nfserr_jukebox; 114 return nfserr_jukebox;
114 ses->se_flags |= NFS4_SESSION_DEAD; 115 ses->se_flags |= NFS4_SESSION_DEAD;
115 return nfs_ok; 116 return nfs_ok;
@@ -364,19 +365,12 @@ static struct nfs4_ol_stateid * nfs4_alloc_stateid(struct nfs4_client *clp)
364} 365}
365 366
366static struct nfs4_delegation * 367static struct nfs4_delegation *
367alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct svc_fh *current_fh, u32 type) 368alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct svc_fh *current_fh)
368{ 369{
369 struct nfs4_delegation *dp; 370 struct nfs4_delegation *dp;
370 struct nfs4_file *fp = stp->st_file; 371 struct nfs4_file *fp = stp->st_file;
371 372
372 dprintk("NFSD alloc_init_deleg\n"); 373 dprintk("NFSD alloc_init_deleg\n");
373 /*
374 * Major work on the lease subsystem (for example, to support
375 * calbacks on stat) will be required before we can support
376 * write delegations properly.
377 */
378 if (type != NFS4_OPEN_DELEGATE_READ)
379 return NULL;
380 if (fp->fi_had_conflict) 374 if (fp->fi_had_conflict)
381 return NULL; 375 return NULL;
382 if (num_delegations > max_delegations) 376 if (num_delegations > max_delegations)
@@ -397,7 +391,7 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct sv
397 INIT_LIST_HEAD(&dp->dl_recall_lru); 391 INIT_LIST_HEAD(&dp->dl_recall_lru);
398 get_nfs4_file(fp); 392 get_nfs4_file(fp);
399 dp->dl_file = fp; 393 dp->dl_file = fp;
400 dp->dl_type = type; 394 dp->dl_type = NFS4_OPEN_DELEGATE_READ;
401 fh_copy_shallow(&dp->dl_fh, &current_fh->fh_handle); 395 fh_copy_shallow(&dp->dl_fh, &current_fh->fh_handle);
402 dp->dl_time = 0; 396 dp->dl_time = 0;
403 atomic_set(&dp->dl_count, 1); 397 atomic_set(&dp->dl_count, 1);
@@ -1188,6 +1182,9 @@ static int copy_cred(struct svc_cred *target, struct svc_cred *source)
1188 target->cr_gid = source->cr_gid; 1182 target->cr_gid = source->cr_gid;
1189 target->cr_group_info = source->cr_group_info; 1183 target->cr_group_info = source->cr_group_info;
1190 get_group_info(target->cr_group_info); 1184 get_group_info(target->cr_group_info);
1185 target->cr_gss_mech = source->cr_gss_mech;
1186 if (source->cr_gss_mech)
1187 gss_mech_get(source->cr_gss_mech);
1191 return 0; 1188 return 0;
1192} 1189}
1193 1190
@@ -1262,6 +1259,33 @@ same_creds(struct svc_cred *cr1, struct svc_cred *cr2)
1262 return 0 == strcmp(cr1->cr_principal, cr2->cr_principal); 1259 return 0 == strcmp(cr1->cr_principal, cr2->cr_principal);
1263} 1260}
1264 1261
1262static bool svc_rqst_integrity_protected(struct svc_rqst *rqstp)
1263{
1264 struct svc_cred *cr = &rqstp->rq_cred;
1265 u32 service;
1266
1267 if (!cr->cr_gss_mech)
1268 return false;
1269 service = gss_pseudoflavor_to_service(cr->cr_gss_mech, cr->cr_flavor);
1270 return service == RPC_GSS_SVC_INTEGRITY ||
1271 service == RPC_GSS_SVC_PRIVACY;
1272}
1273
1274static bool mach_creds_match(struct nfs4_client *cl, struct svc_rqst *rqstp)
1275{
1276 struct svc_cred *cr = &rqstp->rq_cred;
1277
1278 if (!cl->cl_mach_cred)
1279 return true;
1280 if (cl->cl_cred.cr_gss_mech != cr->cr_gss_mech)
1281 return false;
1282 if (!svc_rqst_integrity_protected(rqstp))
1283 return false;
1284 if (!cr->cr_principal)
1285 return false;
1286 return 0 == strcmp(cl->cl_cred.cr_principal, cr->cr_principal);
1287}
1288
1265static void gen_clid(struct nfs4_client *clp, struct nfsd_net *nn) 1289static void gen_clid(struct nfs4_client *clp, struct nfsd_net *nn)
1266{ 1290{
1267 static u32 current_clientid = 1; 1291 static u32 current_clientid = 1;
@@ -1639,16 +1663,16 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
1639 if (exid->flags & ~EXCHGID4_FLAG_MASK_A) 1663 if (exid->flags & ~EXCHGID4_FLAG_MASK_A)
1640 return nfserr_inval; 1664 return nfserr_inval;
1641 1665
1642 /* Currently only support SP4_NONE */
1643 switch (exid->spa_how) { 1666 switch (exid->spa_how) {
1667 case SP4_MACH_CRED:
1668 if (!svc_rqst_integrity_protected(rqstp))
1669 return nfserr_inval;
1644 case SP4_NONE: 1670 case SP4_NONE:
1645 break; 1671 break;
1646 default: /* checked by xdr code */ 1672 default: /* checked by xdr code */
1647 WARN_ON_ONCE(1); 1673 WARN_ON_ONCE(1);
1648 case SP4_SSV: 1674 case SP4_SSV:
1649 return nfserr_encr_alg_unsupp; 1675 return nfserr_encr_alg_unsupp;
1650 case SP4_MACH_CRED:
1651 return nfserr_serverfault; /* no excuse :-/ */
1652 } 1676 }
1653 1677
1654 /* Cases below refer to rfc 5661 section 18.35.4: */ 1678 /* Cases below refer to rfc 5661 section 18.35.4: */
@@ -1663,6 +1687,10 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
1663 status = nfserr_inval; 1687 status = nfserr_inval;
1664 goto out; 1688 goto out;
1665 } 1689 }
1690 if (!mach_creds_match(conf, rqstp)) {
1691 status = nfserr_wrong_cred;
1692 goto out;
1693 }
1666 if (!creds_match) { /* case 9 */ 1694 if (!creds_match) { /* case 9 */
1667 status = nfserr_perm; 1695 status = nfserr_perm;
1668 goto out; 1696 goto out;
@@ -1709,7 +1737,8 @@ out_new:
1709 status = nfserr_jukebox; 1737 status = nfserr_jukebox;
1710 goto out; 1738 goto out;
1711 } 1739 }
1712 new->cl_minorversion = 1; 1740 new->cl_minorversion = cstate->minorversion;
1741 new->cl_mach_cred = (exid->spa_how == SP4_MACH_CRED);
1713 1742
1714 gen_clid(new, nn); 1743 gen_clid(new, nn);
1715 add_to_unconfirmed(new); 1744 add_to_unconfirmed(new);
@@ -1839,6 +1868,24 @@ static __be32 check_backchannel_attrs(struct nfsd4_channel_attrs *ca)
1839 return nfs_ok; 1868 return nfs_ok;
1840} 1869}
1841 1870
1871static __be32 nfsd4_check_cb_sec(struct nfsd4_cb_sec *cbs)
1872{
1873 switch (cbs->flavor) {
1874 case RPC_AUTH_NULL:
1875 case RPC_AUTH_UNIX:
1876 return nfs_ok;
1877 default:
1878 /*
1879 * GSS case: the spec doesn't allow us to return this
1880 * error. But it also doesn't allow us not to support
1881 * GSS.
1882 * I'd rather this fail hard than return some error the
1883 * client might think it can already handle:
1884 */
1885 return nfserr_encr_alg_unsupp;
1886 }
1887}
1888
1842__be32 1889__be32
1843nfsd4_create_session(struct svc_rqst *rqstp, 1890nfsd4_create_session(struct svc_rqst *rqstp,
1844 struct nfsd4_compound_state *cstate, 1891 struct nfsd4_compound_state *cstate,
@@ -1854,6 +1901,9 @@ nfsd4_create_session(struct svc_rqst *rqstp,
1854 1901
1855 if (cr_ses->flags & ~SESSION4_FLAG_MASK_A) 1902 if (cr_ses->flags & ~SESSION4_FLAG_MASK_A)
1856 return nfserr_inval; 1903 return nfserr_inval;
1904 status = nfsd4_check_cb_sec(&cr_ses->cb_sec);
1905 if (status)
1906 return status;
1857 status = check_forechannel_attrs(&cr_ses->fore_channel, nn); 1907 status = check_forechannel_attrs(&cr_ses->fore_channel, nn);
1858 if (status) 1908 if (status)
1859 return status; 1909 return status;
@@ -1874,6 +1924,9 @@ nfsd4_create_session(struct svc_rqst *rqstp,
1874 WARN_ON_ONCE(conf && unconf); 1924 WARN_ON_ONCE(conf && unconf);
1875 1925
1876 if (conf) { 1926 if (conf) {
1927 status = nfserr_wrong_cred;
1928 if (!mach_creds_match(conf, rqstp))
1929 goto out_free_conn;
1877 cs_slot = &conf->cl_cs_slot; 1930 cs_slot = &conf->cl_cs_slot;
1878 status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0); 1931 status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0);
1879 if (status == nfserr_replay_cache) { 1932 if (status == nfserr_replay_cache) {
@@ -1890,6 +1943,9 @@ nfsd4_create_session(struct svc_rqst *rqstp,
1890 status = nfserr_clid_inuse; 1943 status = nfserr_clid_inuse;
1891 goto out_free_conn; 1944 goto out_free_conn;
1892 } 1945 }
1946 status = nfserr_wrong_cred;
1947 if (!mach_creds_match(unconf, rqstp))
1948 goto out_free_conn;
1893 cs_slot = &unconf->cl_cs_slot; 1949 cs_slot = &unconf->cl_cs_slot;
1894 status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0); 1950 status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0);
1895 if (status) { 1951 if (status) {
@@ -1957,7 +2013,11 @@ __be32 nfsd4_backchannel_ctl(struct svc_rqst *rqstp, struct nfsd4_compound_state
1957{ 2013{
1958 struct nfsd4_session *session = cstate->session; 2014 struct nfsd4_session *session = cstate->session;
1959 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); 2015 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
2016 __be32 status;
1960 2017
2018 status = nfsd4_check_cb_sec(&bc->bc_cb_sec);
2019 if (status)
2020 return status;
1961 spin_lock(&nn->client_lock); 2021 spin_lock(&nn->client_lock);
1962 session->se_cb_prog = bc->bc_cb_program; 2022 session->se_cb_prog = bc->bc_cb_program;
1963 session->se_cb_sec = bc->bc_cb_sec; 2023 session->se_cb_sec = bc->bc_cb_sec;
@@ -1986,6 +2046,9 @@ __be32 nfsd4_bind_conn_to_session(struct svc_rqst *rqstp,
1986 status = nfserr_badsession; 2046 status = nfserr_badsession;
1987 if (!session) 2047 if (!session)
1988 goto out; 2048 goto out;
2049 status = nfserr_wrong_cred;
2050 if (!mach_creds_match(session->se_client, rqstp))
2051 goto out;
1989 status = nfsd4_map_bcts_dir(&bcts->dir); 2052 status = nfsd4_map_bcts_dir(&bcts->dir);
1990 if (status) 2053 if (status)
1991 goto out; 2054 goto out;
@@ -2014,6 +2077,7 @@ nfsd4_destroy_session(struct svc_rqst *r,
2014{ 2077{
2015 struct nfsd4_session *ses; 2078 struct nfsd4_session *ses;
2016 __be32 status; 2079 __be32 status;
2080 int ref_held_by_me = 0;
2017 struct nfsd_net *nn = net_generic(SVC_NET(r), nfsd_net_id); 2081 struct nfsd_net *nn = net_generic(SVC_NET(r), nfsd_net_id);
2018 2082
2019 nfs4_lock_state(); 2083 nfs4_lock_state();
@@ -2021,6 +2085,7 @@ nfsd4_destroy_session(struct svc_rqst *r,
2021 if (nfsd4_compound_in_session(cstate->session, &sessionid->sessionid)) { 2085 if (nfsd4_compound_in_session(cstate->session, &sessionid->sessionid)) {
2022 if (!nfsd4_last_compound_op(r)) 2086 if (!nfsd4_last_compound_op(r))
2023 goto out; 2087 goto out;
2088 ref_held_by_me++;
2024 } 2089 }
2025 dump_sessionid(__func__, &sessionid->sessionid); 2090 dump_sessionid(__func__, &sessionid->sessionid);
2026 spin_lock(&nn->client_lock); 2091 spin_lock(&nn->client_lock);
@@ -2028,17 +2093,22 @@ nfsd4_destroy_session(struct svc_rqst *r,
2028 status = nfserr_badsession; 2093 status = nfserr_badsession;
2029 if (!ses) 2094 if (!ses)
2030 goto out_client_lock; 2095 goto out_client_lock;
2031 status = mark_session_dead_locked(ses); 2096 status = nfserr_wrong_cred;
2032 if (status) 2097 if (!mach_creds_match(ses->se_client, r))
2033 goto out_client_lock; 2098 goto out_client_lock;
2099 nfsd4_get_session_locked(ses);
2100 status = mark_session_dead_locked(ses, 1 + ref_held_by_me);
2101 if (status)
2102 goto out_put_session;
2034 unhash_session(ses); 2103 unhash_session(ses);
2035 spin_unlock(&nn->client_lock); 2104 spin_unlock(&nn->client_lock);
2036 2105
2037 nfsd4_probe_callback_sync(ses->se_client); 2106 nfsd4_probe_callback_sync(ses->se_client);
2038 2107
2039 spin_lock(&nn->client_lock); 2108 spin_lock(&nn->client_lock);
2040 free_session(ses);
2041 status = nfs_ok; 2109 status = nfs_ok;
2110out_put_session:
2111 nfsd4_put_session(ses);
2042out_client_lock: 2112out_client_lock:
2043 spin_unlock(&nn->client_lock); 2113 spin_unlock(&nn->client_lock);
2044out: 2114out:
@@ -2058,26 +2128,31 @@ static struct nfsd4_conn *__nfsd4_find_conn(struct svc_xprt *xpt, struct nfsd4_s
2058 return NULL; 2128 return NULL;
2059} 2129}
2060 2130
2061static void nfsd4_sequence_check_conn(struct nfsd4_conn *new, struct nfsd4_session *ses) 2131static __be32 nfsd4_sequence_check_conn(struct nfsd4_conn *new, struct nfsd4_session *ses)
2062{ 2132{
2063 struct nfs4_client *clp = ses->se_client; 2133 struct nfs4_client *clp = ses->se_client;
2064 struct nfsd4_conn *c; 2134 struct nfsd4_conn *c;
2135 __be32 status = nfs_ok;
2065 int ret; 2136 int ret;
2066 2137
2067 spin_lock(&clp->cl_lock); 2138 spin_lock(&clp->cl_lock);
2068 c = __nfsd4_find_conn(new->cn_xprt, ses); 2139 c = __nfsd4_find_conn(new->cn_xprt, ses);
2069 if (c) { 2140 if (c)
2070 spin_unlock(&clp->cl_lock); 2141 goto out_free;
2071 free_conn(new); 2142 status = nfserr_conn_not_bound_to_session;
2072 return; 2143 if (clp->cl_mach_cred)
2073 } 2144 goto out_free;
2074 __nfsd4_hash_conn(new, ses); 2145 __nfsd4_hash_conn(new, ses);
2075 spin_unlock(&clp->cl_lock); 2146 spin_unlock(&clp->cl_lock);
2076 ret = nfsd4_register_conn(new); 2147 ret = nfsd4_register_conn(new);
2077 if (ret) 2148 if (ret)
2078 /* oops; xprt is already down: */ 2149 /* oops; xprt is already down: */
2079 nfsd4_conn_lost(&new->cn_xpt_user); 2150 nfsd4_conn_lost(&new->cn_xpt_user);
2080 return; 2151 return nfs_ok;
2152out_free:
2153 spin_unlock(&clp->cl_lock);
2154 free_conn(new);
2155 return status;
2081} 2156}
2082 2157
2083static bool nfsd4_session_too_many_ops(struct svc_rqst *rqstp, struct nfsd4_session *session) 2158static bool nfsd4_session_too_many_ops(struct svc_rqst *rqstp, struct nfsd4_session *session)
@@ -2169,8 +2244,10 @@ nfsd4_sequence(struct svc_rqst *rqstp,
2169 if (status) 2244 if (status)
2170 goto out_put_session; 2245 goto out_put_session;
2171 2246
2172 nfsd4_sequence_check_conn(conn, session); 2247 status = nfsd4_sequence_check_conn(conn, session);
2173 conn = NULL; 2248 conn = NULL;
2249 if (status)
2250 goto out_put_session;
2174 2251
2175 /* Success! bump slot seqid */ 2252 /* Success! bump slot seqid */
2176 slot->sl_seqid = seq->seqid; 2253 slot->sl_seqid = seq->seqid;
@@ -2232,7 +2309,10 @@ nfsd4_destroy_clientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *csta
2232 status = nfserr_stale_clientid; 2309 status = nfserr_stale_clientid;
2233 goto out; 2310 goto out;
2234 } 2311 }
2235 2312 if (!mach_creds_match(clp, rqstp)) {
2313 status = nfserr_wrong_cred;
2314 goto out;
2315 }
2236 expire_client(clp); 2316 expire_client(clp);
2237out: 2317out:
2238 nfs4_unlock_state(); 2318 nfs4_unlock_state();
@@ -2645,13 +2725,13 @@ static void nfsd_break_one_deleg(struct nfs4_delegation *dp)
2645 2725
2646 list_add_tail(&dp->dl_recall_lru, &nn->del_recall_lru); 2726 list_add_tail(&dp->dl_recall_lru, &nn->del_recall_lru);
2647 2727
2648 /* only place dl_time is set. protected by lock_flocks*/ 2728 /* Only place dl_time is set; protected by i_lock: */
2649 dp->dl_time = get_seconds(); 2729 dp->dl_time = get_seconds();
2650 2730
2651 nfsd4_cb_recall(dp); 2731 nfsd4_cb_recall(dp);
2652} 2732}
2653 2733
2654/* Called from break_lease() with lock_flocks() held. */ 2734/* Called from break_lease() with i_lock held. */
2655static void nfsd_break_deleg_cb(struct file_lock *fl) 2735static void nfsd_break_deleg_cb(struct file_lock *fl)
2656{ 2736{
2657 struct nfs4_file *fp = (struct nfs4_file *)fl->fl_owner; 2737 struct nfs4_file *fp = (struct nfs4_file *)fl->fl_owner;
@@ -2940,13 +3020,13 @@ static struct file_lock *nfs4_alloc_init_lease(struct nfs4_delegation *dp, int f
2940 return fl; 3020 return fl;
2941} 3021}
2942 3022
2943static int nfs4_setlease(struct nfs4_delegation *dp, int flag) 3023static int nfs4_setlease(struct nfs4_delegation *dp)
2944{ 3024{
2945 struct nfs4_file *fp = dp->dl_file; 3025 struct nfs4_file *fp = dp->dl_file;
2946 struct file_lock *fl; 3026 struct file_lock *fl;
2947 int status; 3027 int status;
2948 3028
2949 fl = nfs4_alloc_init_lease(dp, flag); 3029 fl = nfs4_alloc_init_lease(dp, NFS4_OPEN_DELEGATE_READ);
2950 if (!fl) 3030 if (!fl)
2951 return -ENOMEM; 3031 return -ENOMEM;
2952 fl->fl_file = find_readable_file(fp); 3032 fl->fl_file = find_readable_file(fp);
@@ -2964,12 +3044,12 @@ static int nfs4_setlease(struct nfs4_delegation *dp, int flag)
2964 return 0; 3044 return 0;
2965} 3045}
2966 3046
2967static int nfs4_set_delegation(struct nfs4_delegation *dp, int flag) 3047static int nfs4_set_delegation(struct nfs4_delegation *dp)
2968{ 3048{
2969 struct nfs4_file *fp = dp->dl_file; 3049 struct nfs4_file *fp = dp->dl_file;
2970 3050
2971 if (!fp->fi_lease) 3051 if (!fp->fi_lease)
2972 return nfs4_setlease(dp, flag); 3052 return nfs4_setlease(dp);
2973 spin_lock(&recall_lock); 3053 spin_lock(&recall_lock);
2974 if (fp->fi_had_conflict) { 3054 if (fp->fi_had_conflict) {
2975 spin_unlock(&recall_lock); 3055 spin_unlock(&recall_lock);
@@ -3005,6 +3085,9 @@ static void nfsd4_open_deleg_none_ext(struct nfsd4_open *open, int status)
3005 3085
3006/* 3086/*
3007 * Attempt to hand out a delegation. 3087 * Attempt to hand out a delegation.
3088 *
3089 * Note we don't support write delegations, and won't until the vfs has
3090 * proper support for them.
3008 */ 3091 */
3009static void 3092static void
3010nfs4_open_delegation(struct net *net, struct svc_fh *fh, 3093nfs4_open_delegation(struct net *net, struct svc_fh *fh,
@@ -3013,39 +3096,45 @@ nfs4_open_delegation(struct net *net, struct svc_fh *fh,
3013 struct nfs4_delegation *dp; 3096 struct nfs4_delegation *dp;
3014 struct nfs4_openowner *oo = container_of(stp->st_stateowner, struct nfs4_openowner, oo_owner); 3097 struct nfs4_openowner *oo = container_of(stp->st_stateowner, struct nfs4_openowner, oo_owner);
3015 int cb_up; 3098 int cb_up;
3016 int status = 0, flag = 0; 3099 int status = 0;
3017 3100
3018 cb_up = nfsd4_cb_channel_good(oo->oo_owner.so_client); 3101 cb_up = nfsd4_cb_channel_good(oo->oo_owner.so_client);
3019 flag = NFS4_OPEN_DELEGATE_NONE;
3020 open->op_recall = 0; 3102 open->op_recall = 0;
3021 switch (open->op_claim_type) { 3103 switch (open->op_claim_type) {
3022 case NFS4_OPEN_CLAIM_PREVIOUS: 3104 case NFS4_OPEN_CLAIM_PREVIOUS:
3023 if (!cb_up) 3105 if (!cb_up)
3024 open->op_recall = 1; 3106 open->op_recall = 1;
3025 flag = open->op_delegate_type; 3107 if (open->op_delegate_type != NFS4_OPEN_DELEGATE_READ)
3026 if (flag == NFS4_OPEN_DELEGATE_NONE) 3108 goto out_no_deleg;
3027 goto out;
3028 break; 3109 break;
3029 case NFS4_OPEN_CLAIM_NULL: 3110 case NFS4_OPEN_CLAIM_NULL:
3030 /* Let's not give out any delegations till everyone's 3111 /*
3031 * had the chance to reclaim theirs.... */ 3112 * Let's not give out any delegations till everyone's
3113 * had the chance to reclaim theirs....
3114 */
3032 if (locks_in_grace(net)) 3115 if (locks_in_grace(net))
3033 goto out; 3116 goto out_no_deleg;
3034 if (!cb_up || !(oo->oo_flags & NFS4_OO_CONFIRMED)) 3117 if (!cb_up || !(oo->oo_flags & NFS4_OO_CONFIRMED))
3035 goto out; 3118 goto out_no_deleg;
3119 /*
3120 * Also, if the file was opened for write or
3121 * create, there's a good chance the client's
3122 * about to write to it, resulting in an
3123 * immediate recall (since we don't support
3124 * write delegations):
3125 */
3036 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) 3126 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
3037 flag = NFS4_OPEN_DELEGATE_WRITE; 3127 goto out_no_deleg;
3038 else 3128 if (open->op_create == NFS4_OPEN_CREATE)
3039 flag = NFS4_OPEN_DELEGATE_READ; 3129 goto out_no_deleg;
3040 break; 3130 break;
3041 default: 3131 default:
3042 goto out; 3132 goto out_no_deleg;
3043 } 3133 }
3044 3134 dp = alloc_init_deleg(oo->oo_owner.so_client, stp, fh);
3045 dp = alloc_init_deleg(oo->oo_owner.so_client, stp, fh, flag);
3046 if (dp == NULL) 3135 if (dp == NULL)
3047 goto out_no_deleg; 3136 goto out_no_deleg;
3048 status = nfs4_set_delegation(dp, flag); 3137 status = nfs4_set_delegation(dp);
3049 if (status) 3138 if (status)
3050 goto out_free; 3139 goto out_free;
3051 3140
@@ -3053,24 +3142,23 @@ nfs4_open_delegation(struct net *net, struct svc_fh *fh,
3053 3142
3054 dprintk("NFSD: delegation stateid=" STATEID_FMT "\n", 3143 dprintk("NFSD: delegation stateid=" STATEID_FMT "\n",
3055 STATEID_VAL(&dp->dl_stid.sc_stateid)); 3144 STATEID_VAL(&dp->dl_stid.sc_stateid));
3056out: 3145 open->op_delegate_type = NFS4_OPEN_DELEGATE_READ;
3057 open->op_delegate_type = flag;
3058 if (flag == NFS4_OPEN_DELEGATE_NONE) {
3059 if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS &&
3060 open->op_delegate_type != NFS4_OPEN_DELEGATE_NONE)
3061 dprintk("NFSD: WARNING: refusing delegation reclaim\n");
3062
3063 /* 4.1 client asking for a delegation? */
3064 if (open->op_deleg_want)
3065 nfsd4_open_deleg_none_ext(open, status);
3066 }
3067 return; 3146 return;
3068out_free: 3147out_free:
3069 unhash_stid(&dp->dl_stid); 3148 unhash_stid(&dp->dl_stid);
3070 nfs4_put_delegation(dp); 3149 nfs4_put_delegation(dp);
3071out_no_deleg: 3150out_no_deleg:
3072 flag = NFS4_OPEN_DELEGATE_NONE; 3151 open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE;
3073 goto out; 3152 if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS &&
3153 open->op_delegate_type != NFS4_OPEN_DELEGATE_NONE) {
3154 dprintk("NFSD: WARNING: refusing delegation reclaim\n");
3155 open->op_recall = 1;
3156 }
3157
3158 /* 4.1 client asking for a delegation? */
3159 if (open->op_deleg_want)
3160 nfsd4_open_deleg_none_ext(open, status);
3161 return;
3074} 3162}
3075 3163
3076static void nfsd4_deleg_xgrade_none_ext(struct nfsd4_open *open, 3164static void nfsd4_deleg_xgrade_none_ext(struct nfsd4_open *open,
@@ -3427,7 +3515,7 @@ grace_disallows_io(struct net *net, struct inode *inode)
3427/* Returns true iff a is later than b: */ 3515/* Returns true iff a is later than b: */
3428static bool stateid_generation_after(stateid_t *a, stateid_t *b) 3516static bool stateid_generation_after(stateid_t *a, stateid_t *b)
3429{ 3517{
3430 return (s32)a->si_generation - (s32)b->si_generation > 0; 3518 return (s32)(a->si_generation - b->si_generation) > 0;
3431} 3519}
3432 3520
3433static __be32 check_stateid_generation(stateid_t *in, stateid_t *ref, bool has_session) 3521static __be32 check_stateid_generation(stateid_t *in, stateid_t *ref, bool has_session)
@@ -4435,7 +4523,6 @@ __be32
4435nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 4523nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4436 struct nfsd4_locku *locku) 4524 struct nfsd4_locku *locku)
4437{ 4525{
4438 struct nfs4_lockowner *lo;
4439 struct nfs4_ol_stateid *stp; 4526 struct nfs4_ol_stateid *stp;
4440 struct file *filp = NULL; 4527 struct file *filp = NULL;
4441 struct file_lock *file_lock = NULL; 4528 struct file_lock *file_lock = NULL;
@@ -4468,10 +4555,9 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4468 status = nfserr_jukebox; 4555 status = nfserr_jukebox;
4469 goto out; 4556 goto out;
4470 } 4557 }
4471 lo = lockowner(stp->st_stateowner);
4472 locks_init_lock(file_lock); 4558 locks_init_lock(file_lock);
4473 file_lock->fl_type = F_UNLCK; 4559 file_lock->fl_type = F_UNLCK;
4474 file_lock->fl_owner = (fl_owner_t)lo; 4560 file_lock->fl_owner = (fl_owner_t)lockowner(stp->st_stateowner);
4475 file_lock->fl_pid = current->tgid; 4561 file_lock->fl_pid = current->tgid;
4476 file_lock->fl_file = filp; 4562 file_lock->fl_file = filp;
4477 file_lock->fl_flags = FL_POSIX; 4563 file_lock->fl_flags = FL_POSIX;
@@ -4490,11 +4576,6 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4490 update_stateid(&stp->st_stid.sc_stateid); 4576 update_stateid(&stp->st_stid.sc_stateid);
4491 memcpy(&locku->lu_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); 4577 memcpy(&locku->lu_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
4492 4578
4493 if (nfsd4_has_session(cstate) && !check_for_locks(stp->st_file, lo)) {
4494 WARN_ON_ONCE(cstate->replay_owner);
4495 release_lockowner(lo);
4496 }
4497
4498out: 4579out:
4499 nfsd4_bump_seqid(cstate, status); 4580 nfsd4_bump_seqid(cstate, status);
4500 if (!cstate->replay_owner) 4581 if (!cstate->replay_owner)
@@ -4520,7 +4601,7 @@ check_for_locks(struct nfs4_file *filp, struct nfs4_lockowner *lowner)
4520 struct inode *inode = filp->fi_inode; 4601 struct inode *inode = filp->fi_inode;
4521 int status = 0; 4602 int status = 0;
4522 4603
4523 lock_flocks(); 4604 spin_lock(&inode->i_lock);
4524 for (flpp = &inode->i_flock; *flpp != NULL; flpp = &(*flpp)->fl_next) { 4605 for (flpp = &inode->i_flock; *flpp != NULL; flpp = &(*flpp)->fl_next) {
4525 if ((*flpp)->fl_owner == (fl_owner_t)lowner) { 4606 if ((*flpp)->fl_owner == (fl_owner_t)lowner) {
4526 status = 1; 4607 status = 1;
@@ -4528,7 +4609,7 @@ check_for_locks(struct nfs4_file *filp, struct nfs4_lockowner *lowner)
4528 } 4609 }
4529 } 4610 }
4530out: 4611out:
4531 unlock_flocks(); 4612 spin_unlock(&inode->i_lock);
4532 return status; 4613 return status;
4533} 4614}
4534 4615