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.c44
1 files changed, 19 insertions, 25 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 56347e0ac88d..116cab970e0f 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -673,16 +673,17 @@ static void nfsd4_hash_conn(struct nfsd4_conn *conn, struct nfsd4_session *ses)
673 spin_unlock(&clp->cl_lock); 673 spin_unlock(&clp->cl_lock);
674} 674}
675 675
676static void nfsd4_register_conn(struct nfsd4_conn *conn) 676static int nfsd4_register_conn(struct nfsd4_conn *conn)
677{ 677{
678 conn->cn_xpt_user.callback = nfsd4_conn_lost; 678 conn->cn_xpt_user.callback = nfsd4_conn_lost;
679 register_xpt_user(conn->cn_xprt, &conn->cn_xpt_user); 679 return register_xpt_user(conn->cn_xprt, &conn->cn_xpt_user);
680} 680}
681 681
682static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses) 682static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses)
683{ 683{
684 struct nfsd4_conn *conn; 684 struct nfsd4_conn *conn;
685 u32 flags = NFS4_CDFC4_FORE; 685 u32 flags = NFS4_CDFC4_FORE;
686 int ret;
686 687
687 if (ses->se_flags & SESSION4_BACK_CHAN) 688 if (ses->se_flags & SESSION4_BACK_CHAN)
688 flags |= NFS4_CDFC4_BACK; 689 flags |= NFS4_CDFC4_BACK;
@@ -690,7 +691,10 @@ static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses)
690 if (!conn) 691 if (!conn)
691 return nfserr_jukebox; 692 return nfserr_jukebox;
692 nfsd4_hash_conn(conn, ses); 693 nfsd4_hash_conn(conn, ses);
693 nfsd4_register_conn(conn); 694 ret = nfsd4_register_conn(conn);
695 if (ret)
696 /* oops; xprt is already down: */
697 nfsd4_conn_lost(&conn->cn_xpt_user);
694 return nfs_ok; 698 return nfs_ok;
695} 699}
696 700
@@ -1644,6 +1648,7 @@ static void nfsd4_sequence_check_conn(struct nfsd4_conn *new, struct nfsd4_sessi
1644{ 1648{
1645 struct nfs4_client *clp = ses->se_client; 1649 struct nfs4_client *clp = ses->se_client;
1646 struct nfsd4_conn *c; 1650 struct nfsd4_conn *c;
1651 int ret;
1647 1652
1648 spin_lock(&clp->cl_lock); 1653 spin_lock(&clp->cl_lock);
1649 c = __nfsd4_find_conn(new->cn_xprt, ses); 1654 c = __nfsd4_find_conn(new->cn_xprt, ses);
@@ -1654,7 +1659,10 @@ static void nfsd4_sequence_check_conn(struct nfsd4_conn *new, struct nfsd4_sessi
1654 } 1659 }
1655 __nfsd4_hash_conn(new, ses); 1660 __nfsd4_hash_conn(new, ses);
1656 spin_unlock(&clp->cl_lock); 1661 spin_unlock(&clp->cl_lock);
1657 nfsd4_register_conn(new); 1662 ret = nfsd4_register_conn(new);
1663 if (ret)
1664 /* oops; xprt is already down: */
1665 nfsd4_conn_lost(&new->cn_xpt_user);
1658 return; 1666 return;
1659} 1667}
1660 1668
@@ -2254,7 +2262,7 @@ nfs4_file_downgrade(struct nfs4_file *fp, unsigned int share_access)
2254 * Spawn a thread to perform a recall on the delegation represented 2262 * Spawn a thread to perform a recall on the delegation represented
2255 * by the lease (file_lock) 2263 * by the lease (file_lock)
2256 * 2264 *
2257 * Called from break_lease() with lock_kernel() held. 2265 * Called from break_lease() with lock_flocks() held.
2258 * Note: we assume break_lease will only call this *once* for any given 2266 * Note: we assume break_lease will only call this *once* for any given
2259 * lease. 2267 * lease.
2260 */ 2268 */
@@ -2278,7 +2286,7 @@ void nfsd_break_deleg_cb(struct file_lock *fl)
2278 list_add_tail(&dp->dl_recall_lru, &del_recall_lru); 2286 list_add_tail(&dp->dl_recall_lru, &del_recall_lru);
2279 spin_unlock(&recall_lock); 2287 spin_unlock(&recall_lock);
2280 2288
2281 /* only place dl_time is set. protected by lock_kernel*/ 2289 /* only place dl_time is set. protected by lock_flocks*/
2282 dp->dl_time = get_seconds(); 2290 dp->dl_time = get_seconds();
2283 2291
2284 /* 2292 /*
@@ -2295,7 +2303,7 @@ void nfsd_break_deleg_cb(struct file_lock *fl)
2295/* 2303/*
2296 * The file_lock is being reapd. 2304 * The file_lock is being reapd.
2297 * 2305 *
2298 * Called by locks_free_lock() with lock_kernel() held. 2306 * Called by locks_free_lock() with lock_flocks() held.
2299 */ 2307 */
2300static 2308static
2301void nfsd_release_deleg_cb(struct file_lock *fl) 2309void nfsd_release_deleg_cb(struct file_lock *fl)
@@ -2310,23 +2318,7 @@ void nfsd_release_deleg_cb(struct file_lock *fl)
2310} 2318}
2311 2319
2312/* 2320/*
2313 * Set the delegation file_lock back pointer. 2321 * Called from setlease() with lock_flocks() held
2314 *
2315 * Called from setlease() with lock_kernel() held.
2316 */
2317static
2318void nfsd_copy_lock_deleg_cb(struct file_lock *new, struct file_lock *fl)
2319{
2320 struct nfs4_delegation *dp = (struct nfs4_delegation *)new->fl_owner;
2321
2322 dprintk("NFSD: nfsd_copy_lock_deleg_cb: new fl %p dp %p\n", new, dp);
2323 if (!dp)
2324 return;
2325 dp->dl_flock = new;
2326}
2327
2328/*
2329 * Called from setlease() with lock_kernel() held
2330 */ 2322 */
2331static 2323static
2332int nfsd_same_client_deleg_cb(struct file_lock *onlist, struct file_lock *try) 2324int nfsd_same_client_deleg_cb(struct file_lock *onlist, struct file_lock *try)
@@ -2355,7 +2347,6 @@ int nfsd_change_deleg_cb(struct file_lock **onlist, int arg)
2355static const struct lock_manager_operations nfsd_lease_mng_ops = { 2347static const struct lock_manager_operations nfsd_lease_mng_ops = {
2356 .fl_break = nfsd_break_deleg_cb, 2348 .fl_break = nfsd_break_deleg_cb,
2357 .fl_release_private = nfsd_release_deleg_cb, 2349 .fl_release_private = nfsd_release_deleg_cb,
2358 .fl_copy_lock = nfsd_copy_lock_deleg_cb,
2359 .fl_mylease = nfsd_same_client_deleg_cb, 2350 .fl_mylease = nfsd_same_client_deleg_cb,
2360 .fl_change = nfsd_change_deleg_cb, 2351 .fl_change = nfsd_change_deleg_cb,
2361}; 2352};
@@ -2661,12 +2652,15 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
2661 fl->fl_file = find_readable_file(stp->st_file); 2652 fl->fl_file = find_readable_file(stp->st_file);
2662 BUG_ON(!fl->fl_file); 2653 BUG_ON(!fl->fl_file);
2663 fl->fl_pid = current->tgid; 2654 fl->fl_pid = current->tgid;
2655 dp->dl_flock = fl;
2664 2656
2665 /* vfs_setlease checks to see if delegation should be handed out. 2657 /* vfs_setlease checks to see if delegation should be handed out.
2666 * the lock_manager callbacks fl_mylease and fl_change are used 2658 * the lock_manager callbacks fl_mylease and fl_change are used
2667 */ 2659 */
2668 if ((status = vfs_setlease(fl->fl_file, fl->fl_type, &fl))) { 2660 if ((status = vfs_setlease(fl->fl_file, fl->fl_type, &fl))) {
2669 dprintk("NFSD: setlease failed [%d], no delegation\n", status); 2661 dprintk("NFSD: setlease failed [%d], no delegation\n", status);
2662 dp->dl_flock = NULL;
2663 locks_free_lock(fl);
2670 unhash_delegation(dp); 2664 unhash_delegation(dp);
2671 flag = NFS4_OPEN_DELEGATE_NONE; 2665 flag = NFS4_OPEN_DELEGATE_NONE;
2672 goto out; 2666 goto out;