nfs4state.c 167.5 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
/*
*  Copyright (c) 2001 The Regents of the University of Michigan.
*  All rights reserved.
*
*  Kendrick Smith <kmsmith@umich.edu>
*  Andy Adamson <kandros@umich.edu>
*
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions
*  are met:
*
*  1. Redistributions of source code must retain the above copyright
*     notice, this list of conditions and the following disclaimer.
*  2. Redistributions in binary form must reproduce the above copyright
*     notice, this list of conditions and the following disclaimer in the
*     documentation and/or other materials provided with the distribution.
*  3. Neither the name of the University nor the names of its
*     contributors may be used to endorse or promote products derived
*     from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
*  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
*  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
*  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
*  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
*  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
*  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
*  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
*  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
*  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/

35
#include <linux/file.h>
36
#include <linux/fs.h>
37
#include <linux/slab.h>
38
#include <linux/namei.h>
39
#include <linux/swap.h>
40
#include <linux/pagemap.h>
41
#include <linux/ratelimit.h>
42
#include <linux/sunrpc/svcauth_gss.h>
43
#include <linux/sunrpc/addr.h>
44
#include <linux/jhash.h>
45
#include "xdr4.h"
46
#include "xdr4cb.h"
47
#include "vfs.h"
48
#include "current_stateid.h"
L
Linus Torvalds 已提交
49

50 51
#include "netns.h"

L
Linus Torvalds 已提交
52 53
#define NFSDDBG_FACILITY                NFSDDBG_PROC

54 55 56 57 58 59 60 61
#define all_ones {{~0,~0},~0}
static const stateid_t one_stateid = {
	.si_generation = ~0,
	.si_opaque = all_ones,
};
static const stateid_t zero_stateid = {
	/* all fields zero */
};
62 63 64
static const stateid_t currentstateid = {
	.si_generation = 1,
};
65

A
Andy Adamson 已提交
66
static u64 current_sessionid = 1;
67

68 69
#define ZERO_STATEID(stateid) (!memcmp((stateid), &zero_stateid, sizeof(stateid_t)))
#define ONE_STATEID(stateid)  (!memcmp((stateid), &one_stateid, sizeof(stateid_t)))
70
#define CURRENT_STATEID(stateid) (!memcmp((stateid), &currentstateid, sizeof(stateid_t)))
L
Linus Torvalds 已提交
71 72

/* forward declarations */
73
static bool check_for_locks(struct nfs4_file *fp, struct nfs4_lockowner *lowner);
74
static void nfs4_free_ol_stateid(struct nfs4_stid *stid);
L
Linus Torvalds 已提交
75

76 77 78 79 80 81 82
/* Locking: */

/*
 * Currently used for the del_recall_lru and file hash table.  In an
 * effort to decrease the scope of the client_mutex, this spinlock may
 * eventually cover more:
 */
83
static DEFINE_SPINLOCK(state_lock);
84

85 86 87 88 89 90
/*
 * A waitqueue for all in-progress 4.0 CLOSE operations that are waiting for
 * the refcount on the open stateid to drop.
 */
static DECLARE_WAIT_QUEUE_HEAD(close_wq);

C
Christoph Hellwig 已提交
91 92 93 94 95
static struct kmem_cache *openowner_slab;
static struct kmem_cache *lockowner_slab;
static struct kmem_cache *file_slab;
static struct kmem_cache *stateid_slab;
static struct kmem_cache *deleg_slab;
N
NeilBrown 已提交
96

97
static void free_session(struct nfsd4_session *);
98

99 100
static struct nfsd4_callback_ops nfsd4_cb_recall_ops;

101
static bool is_session_dead(struct nfsd4_session *ses)
102
{
103
	return ses->se_flags & NFS4_SESSION_DEAD;
104 105
}

106
static __be32 mark_session_dead_locked(struct nfsd4_session *ses, int ref_held_by_me)
107
{
108
	if (atomic_read(&ses->se_ref) > ref_held_by_me)
109 110 111
		return nfserr_jukebox;
	ses->se_flags |= NFS4_SESSION_DEAD;
	return nfs_ok;
112 113
}

114 115 116 117 118 119 120
static bool is_client_expired(struct nfs4_client *clp)
{
	return clp->cl_time == 0;
}

static __be32 get_client_locked(struct nfs4_client *clp)
{
121 122 123 124
	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);

	lockdep_assert_held(&nn->client_lock);

125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
	if (is_client_expired(clp))
		return nfserr_expired;
	atomic_inc(&clp->cl_refcount);
	return nfs_ok;
}

/* must be called under the client_lock */
static inline void
renew_client_locked(struct nfs4_client *clp)
{
	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);

	if (is_client_expired(clp)) {
		WARN_ON(1);
		printk("%s: client (clientid %08x/%08x) already expired\n",
			__func__,
			clp->cl_clientid.cl_boot,
			clp->cl_clientid.cl_id);
		return;
	}

	dprintk("renewing client (clientid %08x/%08x)\n",
			clp->cl_clientid.cl_boot,
			clp->cl_clientid.cl_id);
	list_move_tail(&clp->cl_lru, &nn->client_lru);
	clp->cl_time = get_seconds();
}

153
static void put_client_renew_locked(struct nfs4_client *clp)
154
{
155 156 157 158
	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);

	lockdep_assert_held(&nn->client_lock);

159 160 161 162 163 164
	if (!atomic_dec_and_test(&clp->cl_refcount))
		return;
	if (!is_client_expired(clp))
		renew_client_locked(clp);
}

165 166 167 168
static void put_client_renew(struct nfs4_client *clp)
{
	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);

169 170 171 172
	if (!atomic_dec_and_lock(&clp->cl_refcount, &nn->client_lock))
		return;
	if (!is_client_expired(clp))
		renew_client_locked(clp);
173 174 175
	spin_unlock(&nn->client_lock);
}

176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
static __be32 nfsd4_get_session_locked(struct nfsd4_session *ses)
{
	__be32 status;

	if (is_session_dead(ses))
		return nfserr_badsession;
	status = get_client_locked(ses->se_client);
	if (status)
		return status;
	atomic_inc(&ses->se_ref);
	return nfs_ok;
}

static void nfsd4_put_session_locked(struct nfsd4_session *ses)
{
	struct nfs4_client *clp = ses->se_client;
192 193 194
	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);

	lockdep_assert_held(&nn->client_lock);
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210

	if (atomic_dec_and_test(&ses->se_ref) && is_session_dead(ses))
		free_session(ses);
	put_client_renew_locked(clp);
}

static void nfsd4_put_session(struct nfsd4_session *ses)
{
	struct nfs4_client *clp = ses->se_client;
	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);

	spin_lock(&nn->client_lock);
	nfsd4_put_session_locked(ses);
	spin_unlock(&nn->client_lock);
}

211 212 213 214 215 216 217
static inline struct nfs4_stateowner *
nfs4_get_stateowner(struct nfs4_stateowner *sop)
{
	atomic_inc(&sop->so_count);
	return sop;
}

218
static int
219
same_owner_str(struct nfs4_stateowner *sop, struct xdr_netobj *owner)
220 221
{
	return (sop->so_owner.len == owner->len) &&
222
		0 == memcmp(sop->so_owner.data, owner->data, owner->len);
223 224 225 226
}

static struct nfs4_openowner *
find_openstateowner_str_locked(unsigned int hashval, struct nfsd4_open *open,
227
			struct nfs4_client *clp)
228 229 230
{
	struct nfs4_stateowner *so;

231
	lockdep_assert_held(&clp->cl_lock);
232

233 234
	list_for_each_entry(so, &clp->cl_ownerstr_hashtbl[hashval],
			    so_strhash) {
235 236
		if (!so->so_is_open_owner)
			continue;
237 238
		if (same_owner_str(so, &open->op_owner))
			return openowner(nfs4_get_stateowner(so));
239 240 241 242 243 244
	}
	return NULL;
}

static struct nfs4_openowner *
find_openstateowner_str(unsigned int hashval, struct nfsd4_open *open,
245
			struct nfs4_client *clp)
246 247 248
{
	struct nfs4_openowner *oo;

249 250 251
	spin_lock(&clp->cl_lock);
	oo = find_openstateowner_str_locked(hashval, open, clp);
	spin_unlock(&clp->cl_lock);
252 253 254
	return oo;
}

L
Linus Torvalds 已提交
255 256 257 258 259 260 261 262 263 264 265 266 267
static inline u32
opaque_hashval(const void *ptr, int nbytes)
{
	unsigned char *cptr = (unsigned char *) ptr;

	u32 x = 0;
	while (nbytes--) {
		x *= 37;
		x += *cptr++;
	}
	return x;
}

268
static void nfsd4_free_file_rcu(struct rcu_head *rcu)
269
{
270 271 272
	struct nfs4_file *fp = container_of(rcu, struct nfs4_file, fi_rcu);

	kmem_cache_free(file_slab, fp);
273 274
}

275 276 277
static inline void
put_nfs4_file(struct nfs4_file *fi)
{
278 279
	might_lock(&state_lock);

280
	if (atomic_dec_and_lock(&fi->fi_ref, &state_lock)) {
281
		hlist_del_rcu(&fi->fi_hash);
282
		spin_unlock(&state_lock);
283 284
		WARN_ON_ONCE(!list_empty(&fi->fi_delegations));
		call_rcu(&fi->fi_rcu, nfsd4_free_file_rcu);
285
	}
286 287 288 289 290
}

static inline void
get_nfs4_file(struct nfs4_file *fi)
{
291
	atomic_inc(&fi->fi_ref);
292 293
}

294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366
static struct file *
__nfs4_get_fd(struct nfs4_file *f, int oflag)
{
	if (f->fi_fds[oflag])
		return get_file(f->fi_fds[oflag]);
	return NULL;
}

static struct file *
find_writeable_file_locked(struct nfs4_file *f)
{
	struct file *ret;

	lockdep_assert_held(&f->fi_lock);

	ret = __nfs4_get_fd(f, O_WRONLY);
	if (!ret)
		ret = __nfs4_get_fd(f, O_RDWR);
	return ret;
}

static struct file *
find_writeable_file(struct nfs4_file *f)
{
	struct file *ret;

	spin_lock(&f->fi_lock);
	ret = find_writeable_file_locked(f);
	spin_unlock(&f->fi_lock);

	return ret;
}

static struct file *find_readable_file_locked(struct nfs4_file *f)
{
	struct file *ret;

	lockdep_assert_held(&f->fi_lock);

	ret = __nfs4_get_fd(f, O_RDONLY);
	if (!ret)
		ret = __nfs4_get_fd(f, O_RDWR);
	return ret;
}

static struct file *
find_readable_file(struct nfs4_file *f)
{
	struct file *ret;

	spin_lock(&f->fi_lock);
	ret = find_readable_file_locked(f);
	spin_unlock(&f->fi_lock);

	return ret;
}

static struct file *
find_any_file(struct nfs4_file *f)
{
	struct file *ret;

	spin_lock(&f->fi_lock);
	ret = __nfs4_get_fd(f, O_RDWR);
	if (!ret) {
		ret = __nfs4_get_fd(f, O_WRONLY);
		if (!ret)
			ret = __nfs4_get_fd(f, O_RDONLY);
	}
	spin_unlock(&f->fi_lock);
	return ret;
}

367
static atomic_long_t num_delegations;
368
unsigned long max_delegations;
369 370 371 372 373

/*
 * Open owner state (share locks)
 */

374 375 376 377
/* hash tables for lock and open owners */
#define OWNER_HASH_BITS              8
#define OWNER_HASH_SIZE             (1 << OWNER_HASH_BITS)
#define OWNER_HASH_MASK             (OWNER_HASH_SIZE - 1)
378

379
static unsigned int ownerstr_hashval(struct xdr_netobj *ownername)
380 381 382 383
{
	unsigned int ret;

	ret = opaque_hashval(ownername->data, ownername->len);
384
	return ret & OWNER_HASH_MASK;
385
}
386 387 388 389

/* hash table for nfs4_file */
#define FILE_HASH_BITS                   8
#define FILE_HASH_SIZE                  (1 << FILE_HASH_BITS)
S
Shan Wei 已提交
390

391
static unsigned int nfsd_fh_hashval(struct knfsd_fh *fh)
392
{
393 394 395 396 397 398 399 400
	return jhash2(fh->fh_base.fh_pad, XDR_QUADLEN(fh->fh_size), 0);
}

static unsigned int file_hashval(struct knfsd_fh *fh)
{
	return nfsd_fh_hashval(fh) & (FILE_HASH_SIZE - 1);
}

401
static struct hlist_head file_hashtbl[FILE_HASH_SIZE];
402

403 404
static void
__nfs4_file_get_access(struct nfs4_file *fp, u32 access)
405
{
406 407
	lockdep_assert_held(&fp->fi_lock);

408 409 410 411
	if (access & NFS4_SHARE_ACCESS_WRITE)
		atomic_inc(&fp->fi_access[O_WRONLY]);
	if (access & NFS4_SHARE_ACCESS_READ)
		atomic_inc(&fp->fi_access[O_RDONLY]);
412 413
}

414 415
static __be32
nfs4_file_get_access(struct nfs4_file *fp, u32 access)
416
{
417 418
	lockdep_assert_held(&fp->fi_lock);

419 420 421 422
	/* Does this access mode make sense? */
	if (access & ~NFS4_SHARE_ACCESS_BOTH)
		return nfserr_inval;

423 424 425 426
	/* Does it conflict with a deny mode already set? */
	if ((access & fp->fi_share_deny) != 0)
		return nfserr_share_denied;

427 428
	__nfs4_file_get_access(fp, access);
	return nfs_ok;
429 430
}

431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449
static __be32 nfs4_file_check_deny(struct nfs4_file *fp, u32 deny)
{
	/* Common case is that there is no deny mode. */
	if (deny) {
		/* Does this deny mode make sense? */
		if (deny & ~NFS4_SHARE_DENY_BOTH)
			return nfserr_inval;

		if ((deny & NFS4_SHARE_DENY_READ) &&
		    atomic_read(&fp->fi_access[O_RDONLY]))
			return nfserr_share_denied;

		if ((deny & NFS4_SHARE_DENY_WRITE) &&
		    atomic_read(&fp->fi_access[O_WRONLY]))
			return nfserr_share_denied;
	}
	return nfs_ok;
}

450
static void __nfs4_file_put_access(struct nfs4_file *fp, int oflag)
451
{
452 453 454 455 456 457
	might_lock(&fp->fi_lock);

	if (atomic_dec_and_lock(&fp->fi_access[oflag], &fp->fi_lock)) {
		struct file *f1 = NULL;
		struct file *f2 = NULL;

J
Jeff Layton 已提交
458
		swap(f1, fp->fi_fds[oflag]);
459
		if (atomic_read(&fp->fi_access[1 - oflag]) == 0)
J
Jeff Layton 已提交
460
			swap(f2, fp->fi_fds[O_RDWR]);
461 462 463 464 465
		spin_unlock(&fp->fi_lock);
		if (f1)
			fput(f1);
		if (f2)
			fput(f2);
466 467 468
	}
}

469
static void nfs4_file_put_access(struct nfs4_file *fp, u32 access)
470
{
471 472 473
	WARN_ON_ONCE(access & ~NFS4_SHARE_ACCESS_BOTH);

	if (access & NFS4_SHARE_ACCESS_WRITE)
474
		__nfs4_file_put_access(fp, O_WRONLY);
475 476
	if (access & NFS4_SHARE_ACCESS_READ)
		__nfs4_file_put_access(fp, O_RDONLY);
477 478
}

479
struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl,
480
					 struct kmem_cache *slab)
481
{
J
J. Bruce Fields 已提交
482
	struct nfs4_stid *stid;
J
J. Bruce Fields 已提交
483
	int new_id;
484

485
	stid = kmem_cache_zalloc(slab, GFP_KERNEL);
J
J. Bruce Fields 已提交
486 487 488
	if (!stid)
		return NULL;

489 490 491 492 493
	idr_preload(GFP_KERNEL);
	spin_lock(&cl->cl_lock);
	new_id = idr_alloc_cyclic(&cl->cl_stateids, stid, 0, 0, GFP_NOWAIT);
	spin_unlock(&cl->cl_lock);
	idr_preload_end();
T
Tejun Heo 已提交
494
	if (new_id < 0)
J
J. Bruce Fields 已提交
495
		goto out_free;
496
	stid->sc_client = cl;
J
J. Bruce Fields 已提交
497 498
	stid->sc_stateid.si_opaque.so_id = new_id;
	stid->sc_stateid.si_opaque.so_clid = cl->cl_clientid;
499
	/* Will be incremented before return to client: */
500
	atomic_set(&stid->sc_count, 1);
501 502

	/*
J
J. Bruce Fields 已提交
503 504 505 506 507 508 509
	 * It shouldn't be a problem to reuse an opaque stateid value.
	 * I don't think it is for 4.1.  But with 4.0 I worry that, for
	 * example, a stray write retransmission could be accepted by
	 * the server when it should have been rejected.  Therefore,
	 * adopt a trick from the sctp code to attempt to maximize the
	 * amount of time until an id is reused, by ensuring they always
	 * "increase" (mod INT_MAX):
510
	 */
J
J. Bruce Fields 已提交
511 512
	return stid;
out_free:
513
	kmem_cache_free(slab, stid);
J
J. Bruce Fields 已提交
514
	return NULL;
515 516
}

517
static struct nfs4_ol_stateid * nfs4_alloc_open_stateid(struct nfs4_client *clp)
518
{
519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534
	struct nfs4_stid *stid;
	struct nfs4_ol_stateid *stp;

	stid = nfs4_alloc_stid(clp, stateid_slab);
	if (!stid)
		return NULL;

	stp = openlockstateid(stid);
	stp->st_stid.sc_free = nfs4_free_ol_stateid;
	return stp;
}

static void nfs4_free_deleg(struct nfs4_stid *stid)
{
	kmem_cache_free(deleg_slab, stid);
	atomic_long_dec(&num_delegations);
535 536
}

537 538 539 540 541 542 543 544 545 546 547 548 549 550
/*
 * When we recall a delegation, we should be careful not to hand it
 * out again straight away.
 * To ensure this we keep a pair of bloom filters ('new' and 'old')
 * in which the filehandles of recalled delegations are "stored".
 * If a filehandle appear in either filter, a delegation is blocked.
 * When a delegation is recalled, the filehandle is stored in the "new"
 * filter.
 * Every 30 seconds we swap the filters and clear the "new" one,
 * unless both are empty of course.
 *
 * Each filter is 256 bits.  We hash the filehandle to 32bit and use the
 * low 3 bytes as hash-table indices.
 *
551
 * 'blocked_delegations_lock', which is always taken in block_delegations(),
552 553 554
 * is used to manage concurrent access.  Testing does not need the lock
 * except when swapping the two filters.
 */
555
static DEFINE_SPINLOCK(blocked_delegations_lock);
556 557 558 559 560 561 562 563 564 565 566 567 568 569 570
static struct bloom_pair {
	int	entries, old_entries;
	time_t	swap_time;
	int	new; /* index into 'set' */
	DECLARE_BITMAP(set[2], 256);
} blocked_delegations;

static int delegation_blocked(struct knfsd_fh *fh)
{
	u32 hash;
	struct bloom_pair *bd = &blocked_delegations;

	if (bd->entries == 0)
		return 0;
	if (seconds_since_boot() - bd->swap_time > 30) {
571
		spin_lock(&blocked_delegations_lock);
572 573 574 575 576 577 578 579
		if (seconds_since_boot() - bd->swap_time > 30) {
			bd->entries -= bd->old_entries;
			bd->old_entries = bd->entries;
			memset(bd->set[bd->new], 0,
			       sizeof(bd->set[0]));
			bd->new = 1-bd->new;
			bd->swap_time = seconds_since_boot();
		}
580
		spin_unlock(&blocked_delegations_lock);
581
	}
582
	hash = jhash(&fh->fh_base, fh->fh_size, 0);
583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600
	if (test_bit(hash&255, bd->set[0]) &&
	    test_bit((hash>>8)&255, bd->set[0]) &&
	    test_bit((hash>>16)&255, bd->set[0]))
		return 1;

	if (test_bit(hash&255, bd->set[1]) &&
	    test_bit((hash>>8)&255, bd->set[1]) &&
	    test_bit((hash>>16)&255, bd->set[1]))
		return 1;

	return 0;
}

static void block_delegations(struct knfsd_fh *fh)
{
	u32 hash;
	struct bloom_pair *bd = &blocked_delegations;

601
	hash = jhash(&fh->fh_base, fh->fh_size, 0);
602

603
	spin_lock(&blocked_delegations_lock);
604 605 606 607 608 609
	__set_bit(hash&255, bd->set[bd->new]);
	__set_bit((hash>>8)&255, bd->set[bd->new]);
	__set_bit((hash>>16)&255, bd->set[bd->new]);
	if (bd->entries == 0)
		bd->swap_time = seconds_since_boot();
	bd->entries += 1;
610
	spin_unlock(&blocked_delegations_lock);
611 612
}

L
Linus Torvalds 已提交
613
static struct nfs4_delegation *
614
alloc_init_deleg(struct nfs4_client *clp, struct svc_fh *current_fh)
L
Linus Torvalds 已提交
615 616
{
	struct nfs4_delegation *dp;
617
	long n;
L
Linus Torvalds 已提交
618 619

	dprintk("NFSD alloc_init_deleg\n");
620 621 622
	n = atomic_long_inc_return(&num_delegations);
	if (n < 0 || n > max_delegations)
		goto out_dec;
623
	if (delegation_blocked(&current_fh->fh_handle))
624
		goto out_dec;
625
	dp = delegstateid(nfs4_alloc_stid(clp, deleg_slab));
N
NeilBrown 已提交
626
	if (dp == NULL)
627
		goto out_dec;
628 629

	dp->dl_stid.sc_free = nfs4_free_deleg;
630 631
	/*
	 * delegation seqid's are never incremented.  The 4.1 special
J
J. Bruce Fields 已提交
632 633
	 * meaning of seqid 0 isn't meaningful, really, but let's avoid
	 * 0 anyway just for consistency and use 1:
634 635
	 */
	dp->dl_stid.sc_stateid.si_generation = 1;
636 637
	INIT_LIST_HEAD(&dp->dl_perfile);
	INIT_LIST_HEAD(&dp->dl_perclnt);
L
Linus Torvalds 已提交
638
	INIT_LIST_HEAD(&dp->dl_recall_lru);
639
	dp->dl_type = NFS4_OPEN_DELEGATE_READ;
640 641
	dp->dl_retries = 1;
	nfsd4_init_cb(&dp->dl_recall, dp->dl_stid.sc_client,
642
		      &nfsd4_cb_recall_ops, NFSPROC4_CLNT_CB_RECALL);
L
Linus Torvalds 已提交
643
	return dp;
644 645 646
out_dec:
	atomic_long_dec(&num_delegations);
	return NULL;
L
Linus Torvalds 已提交
647 648 649
}

void
650
nfs4_put_stid(struct nfs4_stid *s)
L
Linus Torvalds 已提交
651
{
652
	struct nfs4_file *fp = s->sc_file;
653 654
	struct nfs4_client *clp = s->sc_client;

655 656
	might_lock(&clp->cl_lock);

657 658
	if (!atomic_dec_and_lock(&s->sc_count, &clp->cl_lock)) {
		wake_up_all(&close_wq);
659
		return;
660
	}
661
	idr_remove(&clp->cl_stateids, s->sc_stateid.si_opaque.so_id);
662
	spin_unlock(&clp->cl_lock);
663
	s->sc_free(s);
664 665
	if (fp)
		put_nfs4_file(fp);
L
Linus Torvalds 已提交
666 667
}

668
static void nfs4_put_deleg_lease(struct nfs4_file *fp)
L
Linus Torvalds 已提交
669
{
670
	struct file *filp = NULL;
671

672
	spin_lock(&fp->fi_lock);
673
	if (fp->fi_deleg_file && --fp->fi_delegees == 0)
674 675 676 677
		swap(filp, fp->fi_deleg_file);
	spin_unlock(&fp->fi_lock);

	if (filp) {
678
		vfs_setlease(filp, F_UNLCK, NULL, (void **)&fp);
679
		fput(filp);
680
	}
L
Linus Torvalds 已提交
681 682
}

683
void nfs4_unhash_stid(struct nfs4_stid *s)
J
J. Bruce Fields 已提交
684
{
J
J. Bruce Fields 已提交
685
	s->sc_type = 0;
J
J. Bruce Fields 已提交
686 687
}

688 689 690
static void
hash_delegation_locked(struct nfs4_delegation *dp, struct nfs4_file *fp)
{
691
	lockdep_assert_held(&state_lock);
692
	lockdep_assert_held(&fp->fi_lock);
693

694
	atomic_inc(&dp->dl_stid.sc_count);
695
	dp->dl_stid.sc_type = NFS4_DELEG_STID;
696 697 698 699
	list_add(&dp->dl_perfile, &fp->fi_delegations);
	list_add(&dp->dl_perclnt, &dp->dl_stid.sc_client->cl_delegations);
}

L
Linus Torvalds 已提交
700
static void
701
unhash_delegation_locked(struct nfs4_delegation *dp)
L
Linus Torvalds 已提交
702
{
703
	struct nfs4_file *fp = dp->dl_stid.sc_file;
704

705 706
	lockdep_assert_held(&state_lock);

707
	dp->dl_stid.sc_type = NFS4_CLOSED_DELEG_STID;
708 709
	/* Ensure that deleg break won't try to requeue it */
	++dp->dl_time;
710
	spin_lock(&fp->fi_lock);
711
	list_del_init(&dp->dl_perclnt);
L
Linus Torvalds 已提交
712
	list_del_init(&dp->dl_recall_lru);
713 714
	list_del_init(&dp->dl_perfile);
	spin_unlock(&fp->fi_lock);
715 716 717 718
}

static void destroy_delegation(struct nfs4_delegation *dp)
{
719 720 721
	spin_lock(&state_lock);
	unhash_delegation_locked(dp);
	spin_unlock(&state_lock);
722
	nfs4_put_deleg_lease(dp->dl_stid.sc_file);
723
	nfs4_put_stid(&dp->dl_stid);
724 725 726 727 728 729
}

static void revoke_delegation(struct nfs4_delegation *dp)
{
	struct nfs4_client *clp = dp->dl_stid.sc_client;

730 731
	WARN_ON(!list_empty(&dp->dl_recall_lru));

732 733
	nfs4_put_deleg_lease(dp->dl_stid.sc_file);

734
	if (clp->cl_minorversion == 0)
735
		nfs4_put_stid(&dp->dl_stid);
736 737
	else {
		dp->dl_stid.sc_type = NFS4_REVOKED_DELEG_STID;
738 739 740
		spin_lock(&clp->cl_lock);
		list_add(&dp->dl_recall_lru, &clp->cl_revoked);
		spin_unlock(&clp->cl_lock);
741 742 743
	}
}

L
Linus Torvalds 已提交
744 745 746 747
/* 
 * SETCLIENTID state 
 */

748 749 750 751 752 753 754 755 756 757
static unsigned int clientid_hashval(u32 id)
{
	return id & CLIENT_HASH_MASK;
}

static unsigned int clientstr_hashval(const char *name)
{
	return opaque_hashval(name, 8) & CLIENT_HASH_MASK;
}

758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775
/*
 * We store the NONE, READ, WRITE, and BOTH bits separately in the
 * st_{access,deny}_bmap field of the stateid, in order to track not
 * only what share bits are currently in force, but also what
 * combinations of share bits previous opens have used.  This allows us
 * to enforce the recommendation of rfc 3530 14.2.19 that the server
 * return an error if the client attempt to downgrade to a combination
 * of share bits not explicable by closing some of its previous opens.
 *
 * XXX: This enforcement is actually incomplete, since we don't keep
 * track of access/deny bit combinations; so, e.g., we allow:
 *
 *	OPEN allow read, deny write
 *	OPEN allow both, deny none
 *	DOWNGRADE allow read, deny none
 *
 * which we should reject.
 */
776 777
static unsigned int
bmap_to_share_mode(unsigned long bmap) {
778
	int i;
779
	unsigned int access = 0;
780 781 782

	for (i = 1; i < 4; i++) {
		if (test_bit(i, &bmap))
783
			access |= i;
784
	}
785
	return access;
786 787
}

788 789 790 791
/* set share access for a given stateid */
static inline void
set_access(u32 access, struct nfs4_ol_stateid *stp)
{
792 793 794 795
	unsigned char mask = 1 << access;

	WARN_ON_ONCE(access > NFS4_SHARE_ACCESS_BOTH);
	stp->st_access_bmap |= mask;
796 797 798 799 800 801
}

/* clear share access for a given stateid */
static inline void
clear_access(u32 access, struct nfs4_ol_stateid *stp)
{
802 803 804 805
	unsigned char mask = 1 << access;

	WARN_ON_ONCE(access > NFS4_SHARE_ACCESS_BOTH);
	stp->st_access_bmap &= ~mask;
806 807 808 809 810 811
}

/* test whether a given stateid has access */
static inline bool
test_access(u32 access, struct nfs4_ol_stateid *stp)
{
812 813 814
	unsigned char mask = 1 << access;

	return (bool)(stp->st_access_bmap & mask);
815 816
}

817 818
/* set share deny for a given stateid */
static inline void
819
set_deny(u32 deny, struct nfs4_ol_stateid *stp)
820
{
821 822 823 824
	unsigned char mask = 1 << deny;

	WARN_ON_ONCE(deny > NFS4_SHARE_DENY_BOTH);
	stp->st_deny_bmap |= mask;
825 826 827 828
}

/* clear share deny for a given stateid */
static inline void
829
clear_deny(u32 deny, struct nfs4_ol_stateid *stp)
830
{
831 832 833 834
	unsigned char mask = 1 << deny;

	WARN_ON_ONCE(deny > NFS4_SHARE_DENY_BOTH);
	stp->st_deny_bmap &= ~mask;
835 836 837 838
}

/* test whether a given stateid is denying specific access */
static inline bool
839
test_deny(u32 deny, struct nfs4_ol_stateid *stp)
840
{
841 842 843
	unsigned char mask = 1 << deny;

	return (bool)(stp->st_deny_bmap & mask);
844 845 846 847
}

static int nfs4_access_to_omode(u32 access)
{
848
	switch (access & NFS4_SHARE_ACCESS_BOTH) {
849 850 851 852 853 854 855
	case NFS4_SHARE_ACCESS_READ:
		return O_RDONLY;
	case NFS4_SHARE_ACCESS_WRITE:
		return O_WRONLY;
	case NFS4_SHARE_ACCESS_BOTH:
		return O_RDWR;
	}
856 857
	WARN_ON_ONCE(1);
	return O_RDONLY;
858 859
}

860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890
/*
 * A stateid that had a deny mode associated with it is being released
 * or downgraded. Recalculate the deny mode on the file.
 */
static void
recalculate_deny_mode(struct nfs4_file *fp)
{
	struct nfs4_ol_stateid *stp;

	spin_lock(&fp->fi_lock);
	fp->fi_share_deny = 0;
	list_for_each_entry(stp, &fp->fi_stateids, st_perfile)
		fp->fi_share_deny |= bmap_to_share_mode(stp->st_deny_bmap);
	spin_unlock(&fp->fi_lock);
}

static void
reset_union_bmap_deny(u32 deny, struct nfs4_ol_stateid *stp)
{
	int i;
	bool change = false;

	for (i = 1; i < 4; i++) {
		if ((i & deny) != i) {
			change = true;
			clear_deny(i, stp);
		}
	}

	/* Recalculate per-file deny mode if there was a change */
	if (change)
891
		recalculate_deny_mode(stp->st_stid.sc_file);
892 893
}

894 895 896 897 898
/* release all access and file references for a given stateid */
static void
release_all_access(struct nfs4_ol_stateid *stp)
{
	int i;
899
	struct nfs4_file *fp = stp->st_stid.sc_file;
900 901 902

	if (fp && stp->st_deny_bmap != 0)
		recalculate_deny_mode(fp);
903 904 905

	for (i = 1; i < 4; i++) {
		if (test_access(i, stp))
906
			nfs4_file_put_access(stp->st_stid.sc_file, i);
907 908 909 910
		clear_access(i, stp);
	}
}

911 912
static void nfs4_put_stateowner(struct nfs4_stateowner *sop)
{
913 914 915 916 917
	struct nfs4_client *clp = sop->so_client;

	might_lock(&clp->cl_lock);

	if (!atomic_dec_and_lock(&sop->so_count, &clp->cl_lock))
918
		return;
919
	sop->so_ops->so_unhash(sop);
920
	spin_unlock(&clp->cl_lock);
921 922 923 924
	kfree(sop->so_owner.data);
	sop->so_ops->so_free(sop);
}

925
static void unhash_ol_stateid(struct nfs4_ol_stateid *stp)
926
{
927
	struct nfs4_file *fp = stp->st_stid.sc_file;
928

929 930
	lockdep_assert_held(&stp->st_stateowner->so_client->cl_lock);

931
	spin_lock(&fp->fi_lock);
932
	list_del(&stp->st_perfile);
933
	spin_unlock(&fp->fi_lock);
934 935 936
	list_del(&stp->st_perstateowner);
}

937
static void nfs4_free_ol_stateid(struct nfs4_stid *stid)
938
{
939
	struct nfs4_ol_stateid *stp = openlockstateid(stid);
940

941
	release_all_access(stp);
942 943
	if (stp->st_stateowner)
		nfs4_put_stateowner(stp->st_stateowner);
944
	kmem_cache_free(stateid_slab, stid);
945 946
}

947
static void nfs4_free_lock_stateid(struct nfs4_stid *stid)
948
{
949 950
	struct nfs4_ol_stateid *stp = openlockstateid(stid);
	struct nfs4_lockowner *lo = lockowner(stp->st_stateowner);
951 952
	struct file *file;

953 954 955 956 957 958
	file = find_any_file(stp->st_stid.sc_file);
	if (file)
		filp_close(file, (fl_owner_t)lo);
	nfs4_free_ol_stateid(stid);
}

959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982
/*
 * Put the persistent reference to an already unhashed generic stateid, while
 * holding the cl_lock. If it's the last reference, then put it onto the
 * reaplist for later destruction.
 */
static void put_ol_stateid_locked(struct nfs4_ol_stateid *stp,
				       struct list_head *reaplist)
{
	struct nfs4_stid *s = &stp->st_stid;
	struct nfs4_client *clp = s->sc_client;

	lockdep_assert_held(&clp->cl_lock);

	WARN_ON_ONCE(!list_empty(&stp->st_locks));

	if (!atomic_dec_and_test(&s->sc_count)) {
		wake_up_all(&close_wq);
		return;
	}

	idr_remove(&clp->cl_stateids, s->sc_stateid.si_opaque.so_id);
	list_add(&stp->st_locks, reaplist);
}

983
static void unhash_lock_stateid(struct nfs4_ol_stateid *stp)
984
{
985 986
	struct nfs4_openowner *oo = openowner(stp->st_openstp->st_stateowner);

987 988 989
	lockdep_assert_held(&oo->oo_owner.so_client->cl_lock);

	list_del_init(&stp->st_locks);
990
	unhash_ol_stateid(stp);
991
	nfs4_unhash_stid(&stp->st_stid);
992 993 994 995 996 997 998 999
}

static void release_lock_stateid(struct nfs4_ol_stateid *stp)
{
	struct nfs4_openowner *oo = openowner(stp->st_openstp->st_stateowner);

	spin_lock(&oo->oo_owner.so_client->cl_lock);
	unhash_lock_stateid(stp);
1000
	spin_unlock(&oo->oo_owner.so_client->cl_lock);
1001
	nfs4_put_stid(&stp->st_stid);
1002 1003
}

1004
static void unhash_lockowner_locked(struct nfs4_lockowner *lo)
1005
{
1006
	struct nfs4_client *clp = lo->lo_owner.so_client;
1007

1008
	lockdep_assert_held(&clp->cl_lock);
1009

1010 1011 1012
	list_del_init(&lo->lo_owner.so_strhash);
}

1013 1014 1015 1016 1017 1018 1019 1020
/*
 * Free a list of generic stateids that were collected earlier after being
 * fully unhashed.
 */
static void
free_ol_stateid_reaplist(struct list_head *reaplist)
{
	struct nfs4_ol_stateid *stp;
1021
	struct nfs4_file *fp;
1022 1023 1024 1025 1026 1027 1028

	might_sleep();

	while (!list_empty(reaplist)) {
		stp = list_first_entry(reaplist, struct nfs4_ol_stateid,
				       st_locks);
		list_del(&stp->st_locks);
1029
		fp = stp->st_stid.sc_file;
1030
		stp->st_stid.sc_free(&stp->st_stid);
1031 1032
		if (fp)
			put_nfs4_file(fp);
1033 1034 1035
	}
}

1036
static void release_lockowner(struct nfs4_lockowner *lo)
1037
{
1038
	struct nfs4_client *clp = lo->lo_owner.so_client;
1039
	struct nfs4_ol_stateid *stp;
1040
	struct list_head reaplist;
1041

1042
	INIT_LIST_HEAD(&reaplist);
1043

1044 1045
	spin_lock(&clp->cl_lock);
	unhash_lockowner_locked(lo);
1046 1047
	while (!list_empty(&lo->lo_owner.so_stateids)) {
		stp = list_first_entry(&lo->lo_owner.so_stateids,
1048
				struct nfs4_ol_stateid, st_perstateowner);
1049
		unhash_lock_stateid(stp);
1050
		put_ol_stateid_locked(stp, &reaplist);
1051
	}
1052
	spin_unlock(&clp->cl_lock);
1053
	free_ol_stateid_reaplist(&reaplist);
1054
	nfs4_put_stateowner(&lo->lo_owner);
1055 1056
}

1057 1058
static void release_open_stateid_locks(struct nfs4_ol_stateid *open_stp,
				       struct list_head *reaplist)
1059 1060 1061 1062 1063 1064
{
	struct nfs4_ol_stateid *stp;

	while (!list_empty(&open_stp->st_locks)) {
		stp = list_entry(open_stp->st_locks.next,
				struct nfs4_ol_stateid, st_locks);
1065 1066
		unhash_lock_stateid(stp);
		put_ol_stateid_locked(stp, reaplist);
1067 1068 1069
	}
}

1070 1071
static void unhash_open_stateid(struct nfs4_ol_stateid *stp,
				struct list_head *reaplist)
1072
{
1073 1074
	lockdep_assert_held(&stp->st_stid.sc_client->cl_lock);

1075
	unhash_ol_stateid(stp);
1076
	release_open_stateid_locks(stp, reaplist);
1077 1078 1079 1080
}

static void release_open_stateid(struct nfs4_ol_stateid *stp)
{
1081 1082 1083
	LIST_HEAD(reaplist);

	spin_lock(&stp->st_stid.sc_client->cl_lock);
1084
	unhash_open_stateid(stp, &reaplist);
1085 1086 1087
	put_ol_stateid_locked(stp, &reaplist);
	spin_unlock(&stp->st_stid.sc_client->cl_lock);
	free_ol_stateid_reaplist(&reaplist);
1088 1089
}

1090
static void unhash_openowner_locked(struct nfs4_openowner *oo)
1091
{
1092
	struct nfs4_client *clp = oo->oo_owner.so_client;
1093

1094
	lockdep_assert_held(&clp->cl_lock);
1095

1096 1097
	list_del_init(&oo->oo_owner.so_strhash);
	list_del_init(&oo->oo_perclient);
1098 1099
}

1100 1101
static void release_last_closed_stateid(struct nfs4_openowner *oo)
{
1102 1103 1104
	struct nfsd_net *nn = net_generic(oo->oo_owner.so_client->net,
					  nfsd_net_id);
	struct nfs4_ol_stateid *s;
1105

1106 1107
	spin_lock(&nn->client_lock);
	s = oo->oo_last_closed_stid;
1108
	if (s) {
1109
		list_del_init(&oo->oo_close_lru);
1110 1111
		oo->oo_last_closed_stid = NULL;
	}
1112 1113 1114
	spin_unlock(&nn->client_lock);
	if (s)
		nfs4_put_stid(&s->st_stid);
1115 1116
}

1117
static void release_openowner(struct nfs4_openowner *oo)
1118 1119
{
	struct nfs4_ol_stateid *stp;
1120
	struct nfs4_client *clp = oo->oo_owner.so_client;
1121
	struct list_head reaplist;
1122

1123
	INIT_LIST_HEAD(&reaplist);
1124

1125 1126
	spin_lock(&clp->cl_lock);
	unhash_openowner_locked(oo);
1127 1128 1129
	while (!list_empty(&oo->oo_owner.so_stateids)) {
		stp = list_first_entry(&oo->oo_owner.so_stateids,
				struct nfs4_ol_stateid, st_perstateowner);
1130
		unhash_open_stateid(stp, &reaplist);
1131
		put_ol_stateid_locked(stp, &reaplist);
1132
	}
1133
	spin_unlock(&clp->cl_lock);
1134
	free_ol_stateid_reaplist(&reaplist);
1135
	release_last_closed_stateid(oo);
1136
	nfs4_put_stateowner(&oo->oo_owner);
1137 1138
}

M
Marc Eshel 已提交
1139 1140 1141 1142 1143 1144 1145 1146
static inline int
hash_sessionid(struct nfs4_sessionid *sessionid)
{
	struct nfsd4_sessionid *sid = (struct nfsd4_sessionid *)sessionid;

	return sid->sequence % SESSION_HASH_SIZE;
}

1147
#ifdef NFSD_DEBUG
M
Marc Eshel 已提交
1148 1149 1150 1151 1152 1153
static inline void
dump_sessionid(const char *fn, struct nfs4_sessionid *sessionid)
{
	u32 *ptr = (u32 *)(&sessionid->data[0]);
	dprintk("%s: %u:%u:%u:%u\n", fn, ptr[0], ptr[1], ptr[2], ptr[3]);
}
1154 1155 1156 1157 1158 1159 1160
#else
static inline void
dump_sessionid(const char *fn, struct nfs4_sessionid *sessionid)
{
}
#endif

1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172
/*
 * Bump the seqid on cstate->replay_owner, and clear replay_owner if it
 * won't be used for replay.
 */
void nfsd4_bump_seqid(struct nfsd4_compound_state *cstate, __be32 nfserr)
{
	struct nfs4_stateowner *so = cstate->replay_owner;

	if (nfserr == nfserr_replay_me)
		return;

	if (!seqid_mutating_err(ntohl(nfserr))) {
1173
		nfsd4_cstate_clear_replay(cstate);
1174 1175 1176 1177 1178 1179 1180 1181 1182
		return;
	}
	if (!so)
		return;
	if (so->so_is_open_owner)
		release_last_closed_stateid(openowner(so));
	so->so_seqid++;
	return;
}
M
Marc Eshel 已提交
1183

A
Andy Adamson 已提交
1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196
static void
gen_sessionid(struct nfsd4_session *ses)
{
	struct nfs4_client *clp = ses->se_client;
	struct nfsd4_sessionid *sid;

	sid = (struct nfsd4_sessionid *)ses->se_sessionid.data;
	sid->clientid = clp->cl_clientid;
	sid->sequence = current_sessionid++;
	sid->reserved = 0;
}

/*
1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209
 * The protocol defines ca_maxresponssize_cached to include the size of
 * the rpc header, but all we need to cache is the data starting after
 * the end of the initial SEQUENCE operation--the rest we regenerate
 * each time.  Therefore we can advertise a ca_maxresponssize_cached
 * value that is the number of bytes in our cache plus a few additional
 * bytes.  In order to stay on the safe side, and not promise more than
 * we can cache, those additional bytes must be the minimum possible: 24
 * bytes of rpc header (xid through accept state, with AUTH_NULL
 * verifier), 12 for the compound header (with zero-length tag), and 44
 * for the SEQUENCE op response:
 */
#define NFSD_MIN_HDR_SEQ_SZ  (24 + 12 + 44)

1210 1211 1212 1213 1214 1215 1216 1217 1218
static void
free_session_slots(struct nfsd4_session *ses)
{
	int i;

	for (i = 0; i < ses->se_fchannel.maxreqs; i++)
		kfree(ses->se_slots[i]);
}

1219
/*
1220 1221 1222
 * We don't actually need to cache the rpc and session headers, so we
 * can allocate a little less for each slot:
 */
1223
static inline u32 slot_bytes(struct nfsd4_channel_attrs *ca)
1224
{
1225
	u32 size;
1226

1227 1228 1229 1230 1231
	if (ca->maxresp_cached < NFSD_MIN_HDR_SEQ_SZ)
		size = 0;
	else
		size = ca->maxresp_cached - NFSD_MIN_HDR_SEQ_SZ;
	return size + sizeof(struct nfsd4_slot);
1232
}
A
Andy Adamson 已提交
1233

1234 1235
/*
 * XXX: If we run out of reserved DRC memory we could (up to a point)
1236
 * re-negotiate active sessions and reduce their slot usage to make
1237
 * room for new connections. For now we just fail the create session.
A
Andy Adamson 已提交
1238
 */
1239
static u32 nfsd4_get_drc_mem(struct nfsd4_channel_attrs *ca)
A
Andy Adamson 已提交
1240
{
1241 1242
	u32 slotsize = slot_bytes(ca);
	u32 num = ca->maxreqs;
1243
	int avail;
A
Andy Adamson 已提交
1244

1245
	spin_lock(&nfsd_drc_lock);
1246 1247
	avail = min((unsigned long)NFSD_MAX_MEM_PER_SESSION,
		    nfsd_drc_max_mem - nfsd_drc_mem_used);
1248 1249 1250
	num = min_t(int, num, avail / slotsize);
	nfsd_drc_mem_used += num * slotsize;
	spin_unlock(&nfsd_drc_lock);
A
Andy Adamson 已提交
1251

1252 1253
	return num;
}
A
Andy Adamson 已提交
1254

1255
static void nfsd4_put_drc_mem(struct nfsd4_channel_attrs *ca)
1256
{
1257 1258
	int slotsize = slot_bytes(ca);

1259
	spin_lock(&nfsd_drc_lock);
1260
	nfsd_drc_mem_used -= slotsize * ca->maxreqs;
1261
	spin_unlock(&nfsd_drc_lock);
1262
}
A
Andy Adamson 已提交
1263

1264 1265
static struct nfsd4_session *alloc_session(struct nfsd4_channel_attrs *fattrs,
					   struct nfsd4_channel_attrs *battrs)
1266
{
1267 1268
	int numslots = fattrs->maxreqs;
	int slotsize = slot_bytes(fattrs);
1269 1270
	struct nfsd4_session *new;
	int mem, i;
1271

1272 1273 1274
	BUILD_BUG_ON(NFSD_MAX_SLOTS_PER_SESSION * sizeof(struct nfsd4_slot *)
			+ sizeof(struct nfsd4_session) > PAGE_SIZE);
	mem = numslots * sizeof(struct nfsd4_slot *);
A
Andy Adamson 已提交
1275

1276 1277 1278
	new = kzalloc(sizeof(*new) + mem, GFP_KERNEL);
	if (!new)
		return NULL;
1279
	/* allocate each struct nfsd4_slot and data cache in one piece */
1280
	for (i = 0; i < numslots; i++) {
1281
		new->se_slots[i] = kzalloc(slotsize, GFP_KERNEL);
1282
		if (!new->se_slots[i])
1283 1284
			goto out_free;
	}
1285 1286 1287 1288

	memcpy(&new->se_fchannel, fattrs, sizeof(struct nfsd4_channel_attrs));
	memcpy(&new->se_bchannel, battrs, sizeof(struct nfsd4_channel_attrs));

1289 1290 1291 1292 1293 1294
	return new;
out_free:
	while (i--)
		kfree(new->se_slots[i]);
	kfree(new);
	return NULL;
A
Andy Adamson 已提交
1295 1296
}

1297 1298 1299 1300 1301
static void free_conn(struct nfsd4_conn *c)
{
	svc_xprt_put(c->cn_xprt);
	kfree(c);
}
A
Andy Adamson 已提交
1302

1303 1304 1305 1306
static void nfsd4_conn_lost(struct svc_xpt_user *u)
{
	struct nfsd4_conn *c = container_of(u, struct nfsd4_conn, cn_xpt_user);
	struct nfs4_client *clp = c->cn_session->se_client;
A
Andy Adamson 已提交
1307

1308 1309 1310 1311 1312
	spin_lock(&clp->cl_lock);
	if (!list_empty(&c->cn_persession)) {
		list_del(&c->cn_persession);
		free_conn(c);
	}
1313
	nfsd4_probe_callback(clp);
1314
	spin_unlock(&clp->cl_lock);
1315
}
A
Andy Adamson 已提交
1316

1317
static struct nfsd4_conn *alloc_conn(struct svc_rqst *rqstp, u32 flags)
1318 1319
{
	struct nfsd4_conn *conn;
A
Andy Adamson 已提交
1320

1321 1322
	conn = kmalloc(sizeof(struct nfsd4_conn), GFP_KERNEL);
	if (!conn)
1323
		return NULL;
1324 1325
	svc_xprt_get(rqstp->rq_xprt);
	conn->cn_xprt = rqstp->rq_xprt;
1326
	conn->cn_flags = flags;
1327 1328 1329
	INIT_LIST_HEAD(&conn->cn_xpt_user.list);
	return conn;
}
1330

1331 1332 1333 1334
static void __nfsd4_hash_conn(struct nfsd4_conn *conn, struct nfsd4_session *ses)
{
	conn->cn_session = ses;
	list_add(&conn->cn_persession, &ses->se_conns);
A
Andy Adamson 已提交
1335 1336
}

1337
static void nfsd4_hash_conn(struct nfsd4_conn *conn, struct nfsd4_session *ses)
1338
{
1339
	struct nfs4_client *clp = ses->se_client;
1340

1341
	spin_lock(&clp->cl_lock);
1342
	__nfsd4_hash_conn(conn, ses);
1343
	spin_unlock(&clp->cl_lock);
1344 1345
}

1346
static int nfsd4_register_conn(struct nfsd4_conn *conn)
1347
{
1348
	conn->cn_xpt_user.callback = nfsd4_conn_lost;
1349
	return register_xpt_user(conn->cn_xprt, &conn->cn_xpt_user);
1350 1351
}

1352
static void nfsd4_init_conn(struct svc_rqst *rqstp, struct nfsd4_conn *conn, struct nfsd4_session *ses)
A
Andy Adamson 已提交
1353
{
1354
	int ret;
A
Andy Adamson 已提交
1355

1356
	nfsd4_hash_conn(conn, ses);
1357 1358 1359 1360
	ret = nfsd4_register_conn(conn);
	if (ret)
		/* oops; xprt is already down: */
		nfsd4_conn_lost(&conn->cn_xpt_user);
1361 1362
	/* We may have gained or lost a callback channel: */
	nfsd4_probe_callback_sync(ses->se_client);
1363
}
A
Andy Adamson 已提交
1364

1365
static struct nfsd4_conn *alloc_conn_from_crses(struct svc_rqst *rqstp, struct nfsd4_create_session *cses)
1366 1367 1368
{
	u32 dir = NFS4_CDFC4_FORE;

1369
	if (cses->flags & SESSION4_BACK_CHAN)
1370
		dir |= NFS4_CDFC4_BACK;
1371
	return alloc_conn(rqstp, dir);
1372 1373 1374
}

/* must be called under client_lock */
1375
static void nfsd4_del_conns(struct nfsd4_session *s)
1376
{
1377 1378
	struct nfs4_client *clp = s->se_client;
	struct nfsd4_conn *c;
A
Andy Adamson 已提交
1379

1380 1381 1382 1383 1384
	spin_lock(&clp->cl_lock);
	while (!list_empty(&s->se_conns)) {
		c = list_first_entry(&s->se_conns, struct nfsd4_conn, cn_persession);
		list_del_init(&c->cn_persession);
		spin_unlock(&clp->cl_lock);
1385

1386 1387
		unregister_xpt_user(c->cn_xprt, &c->cn_xpt_user);
		free_conn(c);
A
Andy Adamson 已提交
1388

1389 1390 1391
		spin_lock(&clp->cl_lock);
	}
	spin_unlock(&clp->cl_lock);
1392
}
A
Andy Adamson 已提交
1393

1394 1395 1396 1397 1398 1399
static void __free_session(struct nfsd4_session *ses)
{
	free_session_slots(ses);
	kfree(ses);
}

1400
static void free_session(struct nfsd4_session *ses)
1401
{
1402
	nfsd4_del_conns(ses);
1403
	nfsd4_put_drc_mem(&ses->se_fchannel);
1404
	__free_session(ses);
1405 1406
}

1407
static void init_session(struct svc_rqst *rqstp, struct nfsd4_session *new, struct nfs4_client *clp, struct nfsd4_create_session *cses)
1408 1409
{
	int idx;
1410
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
1411

A
Andy Adamson 已提交
1412 1413 1414
	new->se_client = clp;
	gen_sessionid(new);

1415 1416
	INIT_LIST_HEAD(&new->se_conns);

1417
	new->se_cb_seq_nr = 1;
A
Andy Adamson 已提交
1418
	new->se_flags = cses->flags;
1419
	new->se_cb_prog = cses->callback_prog;
1420
	new->se_cb_sec = cses->cb_sec;
1421
	atomic_set(&new->se_ref, 0);
1422
	idx = hash_sessionid(&new->se_sessionid);
1423
	list_add(&new->se_hash, &nn->sessionid_hashtbl[idx]);
1424
	spin_lock(&clp->cl_lock);
A
Andy Adamson 已提交
1425
	list_add(&new->se_perclnt, &clp->cl_sessions);
1426
	spin_unlock(&clp->cl_lock);
1427

C
Chuck Lever 已提交
1428
	{
1429
		struct sockaddr *sa = svc_addr(rqstp);
1430 1431 1432 1433 1434 1435 1436
		/*
		 * This is a little silly; with sessions there's no real
		 * use for the callback address.  Use the peer address
		 * as a reasonable default for now, but consider fixing
		 * the rpc client not to require an address in the
		 * future:
		 */
1437 1438 1439
		rpc_copy_addr((struct sockaddr *)&clp->cl_cb_conn.cb_addr, sa);
		clp->cl_cb_conn.cb_addrlen = svc_addr_len(sa);
	}
A
Andy Adamson 已提交
1440 1441
}

1442
/* caller must hold client_lock */
M
Marc Eshel 已提交
1443
static struct nfsd4_session *
1444
__find_in_sessionid_hashtbl(struct nfs4_sessionid *sessionid, struct net *net)
M
Marc Eshel 已提交
1445 1446 1447
{
	struct nfsd4_session *elem;
	int idx;
1448
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
M
Marc Eshel 已提交
1449

1450 1451
	lockdep_assert_held(&nn->client_lock);

M
Marc Eshel 已提交
1452 1453 1454
	dump_sessionid(__func__, sessionid);
	idx = hash_sessionid(sessionid);
	/* Search in the appropriate list */
1455
	list_for_each_entry(elem, &nn->sessionid_hashtbl[idx], se_hash) {
M
Marc Eshel 已提交
1456 1457 1458 1459 1460 1461 1462 1463 1464 1465
		if (!memcmp(elem->se_sessionid.data, sessionid->data,
			    NFS4_MAX_SESSIONID_LEN)) {
			return elem;
		}
	}

	dprintk("%s: session not found\n", __func__);
	return NULL;
}

1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483
static struct nfsd4_session *
find_in_sessionid_hashtbl(struct nfs4_sessionid *sessionid, struct net *net,
		__be32 *ret)
{
	struct nfsd4_session *session;
	__be32 status = nfserr_badsession;

	session = __find_in_sessionid_hashtbl(sessionid, net);
	if (!session)
		goto out;
	status = nfsd4_get_session_locked(session);
	if (status)
		session = NULL;
out:
	*ret = status;
	return session;
}

1484
/* caller must hold client_lock */
A
Andy Adamson 已提交
1485
static void
M
Marc Eshel 已提交
1486
unhash_session(struct nfsd4_session *ses)
A
Andy Adamson 已提交
1487
{
1488 1489 1490 1491 1492
	struct nfs4_client *clp = ses->se_client;
	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);

	lockdep_assert_held(&nn->client_lock);

A
Andy Adamson 已提交
1493
	list_del(&ses->se_hash);
1494
	spin_lock(&ses->se_client->cl_lock);
A
Andy Adamson 已提交
1495
	list_del(&ses->se_perclnt);
1496
	spin_unlock(&ses->se_client->cl_lock);
M
Marc Eshel 已提交
1497 1498
}

L
Linus Torvalds 已提交
1499 1500
/* SETCLIENTID and SETCLIENTID_CONFIRM Helper functions */
static int
1501
STALE_CLIENTID(clientid_t *clid, struct nfsd_net *nn)
L
Linus Torvalds 已提交
1502
{
1503 1504 1505 1506 1507 1508
	/*
	 * We're assuming the clid was not given out from a boot
	 * precisely 2^32 (about 136 years) before this one.  That seems
	 * a safe assumption:
	 */
	if (clid->cl_boot == (u32)nn->boot_time)
L
Linus Torvalds 已提交
1509
		return 0;
A
Andy Adamson 已提交
1510
	dprintk("NFSD stale clientid (%08x/%08x) boot_time %08lx\n",
1511
		clid->cl_boot, clid->cl_id, nn->boot_time);
L
Linus Torvalds 已提交
1512 1513 1514 1515 1516 1517 1518 1519
	return 1;
}

/* 
 * XXX Should we use a slab cache ?
 * This type of memory management is somewhat inefficient, but we use it
 * anyway since SETCLIENTID is not a common operation.
 */
1520
static struct nfs4_client *alloc_client(struct xdr_netobj name)
L
Linus Torvalds 已提交
1521 1522
{
	struct nfs4_client *clp;
1523
	int i;
L
Linus Torvalds 已提交
1524

1525 1526 1527
	clp = kzalloc(sizeof(struct nfs4_client), GFP_KERNEL);
	if (clp == NULL)
		return NULL;
1528
	clp->cl_name.data = kmemdup(name.data, name.len, GFP_KERNEL);
1529 1530 1531 1532 1533 1534 1535 1536
	if (clp->cl_name.data == NULL)
		goto err_no_name;
	clp->cl_ownerstr_hashtbl = kmalloc(sizeof(struct list_head) *
			OWNER_HASH_SIZE, GFP_KERNEL);
	if (!clp->cl_ownerstr_hashtbl)
		goto err_no_hashtbl;
	for (i = 0; i < OWNER_HASH_SIZE; i++)
		INIT_LIST_HEAD(&clp->cl_ownerstr_hashtbl[i]);
1537
	clp->cl_name.len = name.len;
1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549
	INIT_LIST_HEAD(&clp->cl_sessions);
	idr_init(&clp->cl_stateids);
	atomic_set(&clp->cl_refcount, 0);
	clp->cl_cb_state = NFSD4_CB_UNKNOWN;
	INIT_LIST_HEAD(&clp->cl_idhash);
	INIT_LIST_HEAD(&clp->cl_openowners);
	INIT_LIST_HEAD(&clp->cl_delegations);
	INIT_LIST_HEAD(&clp->cl_lru);
	INIT_LIST_HEAD(&clp->cl_callbacks);
	INIT_LIST_HEAD(&clp->cl_revoked);
	spin_lock_init(&clp->cl_lock);
	rpc_init_wait_queue(&clp->cl_cb_waitq, "Backchannel slot table");
L
Linus Torvalds 已提交
1550
	return clp;
1551 1552 1553 1554 1555
err_no_hashtbl:
	kfree(clp->cl_name.data);
err_no_name:
	kfree(clp);
	return NULL;
L
Linus Torvalds 已提交
1556 1557
}

1558
static void
L
Linus Torvalds 已提交
1559 1560
free_client(struct nfs4_client *clp)
{
1561 1562 1563 1564 1565
	while (!list_empty(&clp->cl_sessions)) {
		struct nfsd4_session *ses;
		ses = list_entry(clp->cl_sessions.next, struct nfsd4_session,
				se_perclnt);
		list_del(&ses->se_perclnt);
1566 1567
		WARN_ON_ONCE(atomic_read(&ses->se_ref));
		free_session(ses);
1568
	}
1569
	rpc_destroy_wait_queue(&clp->cl_cb_waitq);
1570
	free_svc_cred(&clp->cl_cred);
1571
	kfree(clp->cl_ownerstr_hashtbl);
L
Linus Torvalds 已提交
1572
	kfree(clp->cl_name.data);
M
majianpeng 已提交
1573
	idr_destroy(&clp->cl_stateids);
L
Linus Torvalds 已提交
1574 1575 1576
	kfree(clp);
}

B
Benny Halevy 已提交
1577
/* must be called under the client_lock */
1578
static void
B
Benny Halevy 已提交
1579 1580
unhash_client_locked(struct nfs4_client *clp)
{
1581
	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
1582 1583
	struct nfsd4_session *ses;

1584 1585
	lockdep_assert_held(&nn->client_lock);

1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596
	/* Mark the client as expired! */
	clp->cl_time = 0;
	/* Make it invisible */
	if (!list_empty(&clp->cl_idhash)) {
		list_del_init(&clp->cl_idhash);
		if (test_bit(NFSD4_CLIENT_CONFIRMED, &clp->cl_flags))
			rb_erase(&clp->cl_namenode, &nn->conf_name_tree);
		else
			rb_erase(&clp->cl_namenode, &nn->unconf_name_tree);
	}
	list_del_init(&clp->cl_lru);
1597
	spin_lock(&clp->cl_lock);
1598 1599
	list_for_each_entry(ses, &clp->cl_sessions, se_perclnt)
		list_del_init(&ses->se_hash);
1600
	spin_unlock(&clp->cl_lock);
B
Benny Halevy 已提交
1601 1602
}

L
Linus Torvalds 已提交
1603
static void
1604 1605 1606 1607 1608 1609 1610 1611 1612
unhash_client(struct nfs4_client *clp)
{
	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);

	spin_lock(&nn->client_lock);
	unhash_client_locked(clp);
	spin_unlock(&nn->client_lock);
}

1613 1614 1615 1616 1617 1618 1619 1620
static __be32 mark_client_expired_locked(struct nfs4_client *clp)
{
	if (atomic_read(&clp->cl_refcount))
		return nfserr_jukebox;
	unhash_client_locked(clp);
	return nfs_ok;
}

1621 1622
static void
__destroy_client(struct nfs4_client *clp)
L
Linus Torvalds 已提交
1623
{
1624
	struct nfs4_openowner *oo;
L
Linus Torvalds 已提交
1625 1626 1627 1628
	struct nfs4_delegation *dp;
	struct list_head reaplist;

	INIT_LIST_HEAD(&reaplist);
1629
	spin_lock(&state_lock);
1630 1631
	while (!list_empty(&clp->cl_delegations)) {
		dp = list_entry(clp->cl_delegations.next, struct nfs4_delegation, dl_perclnt);
1632 1633
		unhash_delegation_locked(dp);
		list_add(&dp->dl_recall_lru, &reaplist);
L
Linus Torvalds 已提交
1634
	}
1635
	spin_unlock(&state_lock);
L
Linus Torvalds 已提交
1636 1637
	while (!list_empty(&reaplist)) {
		dp = list_entry(reaplist.next, struct nfs4_delegation, dl_recall_lru);
1638
		list_del_init(&dp->dl_recall_lru);
1639
		nfs4_put_deleg_lease(dp->dl_stid.sc_file);
1640
		nfs4_put_stid(&dp->dl_stid);
L
Linus Torvalds 已提交
1641
	}
1642
	while (!list_empty(&clp->cl_revoked)) {
1643
		dp = list_entry(reaplist.next, struct nfs4_delegation, dl_recall_lru);
1644
		list_del_init(&dp->dl_recall_lru);
1645
		nfs4_put_stid(&dp->dl_stid);
1646
	}
1647
	while (!list_empty(&clp->cl_openowners)) {
1648
		oo = list_entry(clp->cl_openowners.next, struct nfs4_openowner, oo_perclient);
1649
		nfs4_get_stateowner(&oo->oo_owner);
1650
		release_openowner(oo);
L
Linus Torvalds 已提交
1651
	}
1652
	nfsd4_shutdown_callback(clp);
B
Benny Halevy 已提交
1653 1654
	if (clp->cl_cb_conn.cb_xprt)
		svc_xprt_put(clp->cl_cb_conn.cb_xprt);
1655
	free_client(clp);
L
Linus Torvalds 已提交
1656 1657
}

1658 1659 1660 1661 1662 1663 1664
static void
destroy_client(struct nfs4_client *clp)
{
	unhash_client(clp);
	__destroy_client(clp);
}

1665 1666
static void expire_client(struct nfs4_client *clp)
{
1667
	unhash_client(clp);
1668
	nfsd4_client_record_remove(clp);
1669
	__destroy_client(clp);
1670 1671
}

1672 1673 1674 1675
static void copy_verf(struct nfs4_client *target, nfs4_verifier *source)
{
	memcpy(target->cl_verifier.data, source->data,
			sizeof(target->cl_verifier.data));
L
Linus Torvalds 已提交
1676 1677
}

1678 1679
static void copy_clid(struct nfs4_client *target, struct nfs4_client *source)
{
L
Linus Torvalds 已提交
1680 1681 1682 1683
	target->cl_clientid.cl_boot = source->cl_clientid.cl_boot; 
	target->cl_clientid.cl_id = source->cl_clientid.cl_id; 
}

1684
static int copy_cred(struct svc_cred *target, struct svc_cred *source)
1685
{
1686 1687 1688 1689 1690 1691 1692
	if (source->cr_principal) {
		target->cr_principal =
				kstrdup(source->cr_principal, GFP_KERNEL);
		if (target->cr_principal == NULL)
			return -ENOMEM;
	} else
		target->cr_principal = NULL;
1693
	target->cr_flavor = source->cr_flavor;
L
Linus Torvalds 已提交
1694 1695 1696 1697
	target->cr_uid = source->cr_uid;
	target->cr_gid = source->cr_gid;
	target->cr_group_info = source->cr_group_info;
	get_group_info(target->cr_group_info);
1698 1699 1700
	target->cr_gss_mech = source->cr_gss_mech;
	if (source->cr_gss_mech)
		gss_mech_get(source->cr_gss_mech);
1701
	return 0;
L
Linus Torvalds 已提交
1702 1703
}

1704
static int
1705 1706
compare_blob(const struct xdr_netobj *o1, const struct xdr_netobj *o2)
{
1707 1708 1709 1710 1711
	if (o1->len < o2->len)
		return -1;
	if (o1->len > o2->len)
		return 1;
	return memcmp(o1->data, o2->data, o1->len);
1712 1713
}

1714
static int same_name(const char *n1, const char *n2)
1715
{
N
NeilBrown 已提交
1716
	return 0 == memcmp(n1, n2, HEXDIR_LEN);
L
Linus Torvalds 已提交
1717 1718 1719
}

static int
1720 1721 1722
same_verf(nfs4_verifier *v1, nfs4_verifier *v2)
{
	return 0 == memcmp(v1->data, v2->data, sizeof(v1->data));
L
Linus Torvalds 已提交
1723 1724 1725
}

static int
1726 1727 1728
same_clid(clientid_t *cl1, clientid_t *cl2)
{
	return (cl1->cl_boot == cl2->cl_boot) && (cl1->cl_id == cl2->cl_id);
L
Linus Torvalds 已提交
1729 1730
}

1731 1732 1733 1734 1735 1736 1737
static bool groups_equal(struct group_info *g1, struct group_info *g2)
{
	int i;

	if (g1->ngroups != g2->ngroups)
		return false;
	for (i=0; i<g1->ngroups; i++)
1738
		if (!gid_eq(GROUP_AT(g1, i), GROUP_AT(g2, i)))
1739 1740 1741 1742
			return false;
	return true;
}

1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758
/*
 * RFC 3530 language requires clid_inuse be returned when the
 * "principal" associated with a requests differs from that previously
 * used.  We use uid, gid's, and gss principal string as our best
 * approximation.  We also don't want to allow non-gss use of a client
 * established using gss: in theory cr_principal should catch that
 * change, but in practice cr_principal can be null even in the gss case
 * since gssd doesn't always pass down a principal string.
 */
static bool is_gss_cred(struct svc_cred *cr)
{
	/* Is cr_flavor one of the gss "pseudoflavors"?: */
	return (cr->cr_flavor > RPC_AUTH_MAXFLAVOR);
}


1759
static bool
1760 1761
same_creds(struct svc_cred *cr1, struct svc_cred *cr2)
{
1762
	if ((is_gss_cred(cr1) != is_gss_cred(cr2))
1763 1764
		|| (!uid_eq(cr1->cr_uid, cr2->cr_uid))
		|| (!gid_eq(cr1->cr_gid, cr2->cr_gid))
1765 1766 1767 1768 1769 1770
		|| !groups_equal(cr1->cr_group_info, cr2->cr_group_info))
		return false;
	if (cr1->cr_principal == cr2->cr_principal)
		return true;
	if (!cr1->cr_principal || !cr2->cr_principal)
		return false;
1771
	return 0 == strcmp(cr1->cr_principal, cr2->cr_principal);
L
Linus Torvalds 已提交
1772 1773
}

1774 1775 1776 1777 1778
static bool svc_rqst_integrity_protected(struct svc_rqst *rqstp)
{
	struct svc_cred *cr = &rqstp->rq_cred;
	u32 service;

1779 1780
	if (!cr->cr_gss_mech)
		return false;
1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800
	service = gss_pseudoflavor_to_service(cr->cr_gss_mech, cr->cr_flavor);
	return service == RPC_GSS_SVC_INTEGRITY ||
	       service == RPC_GSS_SVC_PRIVACY;
}

static bool mach_creds_match(struct nfs4_client *cl, struct svc_rqst *rqstp)
{
	struct svc_cred *cr = &rqstp->rq_cred;

	if (!cl->cl_mach_cred)
		return true;
	if (cl->cl_cred.cr_gss_mech != cr->cr_gss_mech)
		return false;
	if (!svc_rqst_integrity_protected(rqstp))
		return false;
	if (!cr->cr_principal)
		return false;
	return 0 == strcmp(cl->cl_cred.cr_principal, cr->cr_principal);
}

1801
static void gen_confirm(struct nfs4_client *clp, struct nfsd_net *nn)
1802
{
1803
	__be32 verf[2];
L
Linus Torvalds 已提交
1804

1805 1806 1807 1808 1809
	/*
	 * This is opaque to client, so no need to byte-swap. Use
	 * __force to keep sparse happy
	 */
	verf[0] = (__force __be32)get_seconds();
1810
	verf[1] = (__force __be32)nn->clientid_counter;
1811
	memcpy(clp->cl_confirm.data, verf, sizeof(clp->cl_confirm.data));
L
Linus Torvalds 已提交
1812 1813
}

1814 1815 1816 1817 1818 1819 1820
static void gen_clid(struct nfs4_client *clp, struct nfsd_net *nn)
{
	clp->cl_clientid.cl_boot = nn->boot_time;
	clp->cl_clientid.cl_id = nn->clientid_counter++;
	gen_confirm(clp, nn);
}

1821 1822
static struct nfs4_stid *
find_stateid_locked(struct nfs4_client *cl, stateid_t *t)
1823
{
J
J. Bruce Fields 已提交
1824 1825 1826 1827 1828 1829
	struct nfs4_stid *ret;

	ret = idr_find(&cl->cl_stateids, t->si_opaque.so_id);
	if (!ret || !ret->sc_type)
		return NULL;
	return ret;
J
J. Bruce Fields 已提交
1830 1831
}

1832 1833
static struct nfs4_stid *
find_stateid_by_type(struct nfs4_client *cl, stateid_t *t, char typemask)
1834 1835
{
	struct nfs4_stid *s;
J
J. Bruce Fields 已提交
1836

1837 1838
	spin_lock(&cl->cl_lock);
	s = find_stateid_locked(cl, t);
1839 1840 1841 1842 1843 1844
	if (s != NULL) {
		if (typemask & s->sc_type)
			atomic_inc(&s->sc_count);
		else
			s = NULL;
	}
1845 1846
	spin_unlock(&cl->cl_lock);
	return s;
1847 1848
}

J
Jeff Layton 已提交
1849
static struct nfs4_client *create_client(struct xdr_netobj name,
1850 1851 1852 1853
		struct svc_rqst *rqstp, nfs4_verifier *verf)
{
	struct nfs4_client *clp;
	struct sockaddr *sa = svc_addr(rqstp);
1854
	int ret;
1855
	struct net *net = SVC_NET(rqstp);
1856 1857 1858 1859 1860

	clp = alloc_client(name);
	if (clp == NULL)
		return NULL;

1861 1862 1863 1864
	ret = copy_cred(&clp->cl_cred, &rqstp->rq_cred);
	if (ret) {
		free_client(clp);
		return NULL;
1865
	}
1866
	nfsd4_init_cb(&clp->cl_cb_null, clp, NULL, NFSPROC4_CLNT_CB_NULL);
B
Benny Halevy 已提交
1867
	clp->cl_time = get_seconds();
1868 1869 1870
	clear_bit(0, &clp->cl_cb_slot_busy);
	copy_verf(clp, verf);
	rpc_copy_addr((struct sockaddr *) &clp->cl_addr, sa);
1871
	clp->cl_cb_session = NULL;
1872
	clp->net = net;
1873 1874 1875
	return clp;
}

1876
static void
1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898
add_clp_to_name_tree(struct nfs4_client *new_clp, struct rb_root *root)
{
	struct rb_node **new = &(root->rb_node), *parent = NULL;
	struct nfs4_client *clp;

	while (*new) {
		clp = rb_entry(*new, struct nfs4_client, cl_namenode);
		parent = *new;

		if (compare_blob(&clp->cl_name, &new_clp->cl_name) > 0)
			new = &((*new)->rb_left);
		else
			new = &((*new)->rb_right);
	}

	rb_link_node(&new_clp->cl_namenode, parent, new);
	rb_insert_color(&new_clp->cl_namenode, root);
}

static struct nfs4_client *
find_clp_in_name_tree(struct xdr_netobj *name, struct rb_root *root)
{
1899
	int cmp;
1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917
	struct rb_node *node = root->rb_node;
	struct nfs4_client *clp;

	while (node) {
		clp = rb_entry(node, struct nfs4_client, cl_namenode);
		cmp = compare_blob(&clp->cl_name, name);
		if (cmp > 0)
			node = node->rb_left;
		else if (cmp < 0)
			node = node->rb_right;
		else
			return clp;
	}
	return NULL;
}

static void
add_to_unconfirmed(struct nfs4_client *clp)
L
Linus Torvalds 已提交
1918 1919
{
	unsigned int idhashval;
1920
	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
L
Linus Torvalds 已提交
1921

1922 1923
	lockdep_assert_held(&nn->client_lock);

1924
	clear_bit(NFSD4_CLIENT_CONFIRMED, &clp->cl_flags);
1925
	add_clp_to_name_tree(clp, &nn->unconf_name_tree);
L
Linus Torvalds 已提交
1926
	idhashval = clientid_hashval(clp->cl_clientid.cl_id);
1927
	list_add(&clp->cl_idhash, &nn->unconf_id_hashtbl[idhashval]);
1928
	renew_client_locked(clp);
L
Linus Torvalds 已提交
1929 1930
}

1931
static void
L
Linus Torvalds 已提交
1932 1933 1934
move_to_confirmed(struct nfs4_client *clp)
{
	unsigned int idhashval = clientid_hashval(clp->cl_clientid.cl_id);
1935
	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
L
Linus Torvalds 已提交
1936

1937 1938
	lockdep_assert_held(&nn->client_lock);

L
Linus Torvalds 已提交
1939
	dprintk("NFSD: move_to_confirm nfs4_client %p\n", clp);
1940
	list_move(&clp->cl_idhash, &nn->conf_id_hashtbl[idhashval]);
1941
	rb_erase(&clp->cl_namenode, &nn->unconf_name_tree);
1942
	add_clp_to_name_tree(clp, &nn->conf_name_tree);
1943
	set_bit(NFSD4_CLIENT_CONFIRMED, &clp->cl_flags);
1944
	renew_client_locked(clp);
L
Linus Torvalds 已提交
1945 1946 1947
}

static struct nfs4_client *
J
J. Bruce Fields 已提交
1948
find_client_in_id_table(struct list_head *tbl, clientid_t *clid, bool sessions)
L
Linus Torvalds 已提交
1949 1950 1951 1952
{
	struct nfs4_client *clp;
	unsigned int idhashval = clientid_hashval(clid->cl_id);

J
J. Bruce Fields 已提交
1953
	list_for_each_entry(clp, &tbl[idhashval], cl_idhash) {
1954
		if (same_clid(&clp->cl_clientid, clid)) {
1955 1956
			if ((bool)clp->cl_minorversion != sessions)
				return NULL;
1957
			renew_client_locked(clp);
L
Linus Torvalds 已提交
1958
			return clp;
1959
		}
L
Linus Torvalds 已提交
1960 1961 1962 1963
	}
	return NULL;
}

J
J. Bruce Fields 已提交
1964 1965 1966 1967 1968
static struct nfs4_client *
find_confirmed_client(clientid_t *clid, bool sessions, struct nfsd_net *nn)
{
	struct list_head *tbl = nn->conf_id_hashtbl;

1969
	lockdep_assert_held(&nn->client_lock);
J
J. Bruce Fields 已提交
1970 1971 1972
	return find_client_in_id_table(tbl, clid, sessions);
}

L
Linus Torvalds 已提交
1973
static struct nfs4_client *
1974
find_unconfirmed_client(clientid_t *clid, bool sessions, struct nfsd_net *nn)
L
Linus Torvalds 已提交
1975
{
J
J. Bruce Fields 已提交
1976
	struct list_head *tbl = nn->unconf_id_hashtbl;
L
Linus Torvalds 已提交
1977

1978
	lockdep_assert_held(&nn->client_lock);
J
J. Bruce Fields 已提交
1979
	return find_client_in_id_table(tbl, clid, sessions);
L
Linus Torvalds 已提交
1980 1981
}

1982
static bool clp_used_exchangeid(struct nfs4_client *clp)
1983
{
1984
	return clp->cl_exchange_flags != 0;
1985
} 
1986

1987
static struct nfs4_client *
1988
find_confirmed_client_by_name(struct xdr_netobj *name, struct nfsd_net *nn)
1989
{
1990
	lockdep_assert_held(&nn->client_lock);
1991
	return find_clp_in_name_tree(name, &nn->conf_name_tree);
1992 1993 1994
}

static struct nfs4_client *
1995
find_unconfirmed_client_by_name(struct xdr_netobj *name, struct nfsd_net *nn)
1996
{
1997
	lockdep_assert_held(&nn->client_lock);
1998
	return find_clp_in_name_tree(name, &nn->unconf_name_tree);
1999 2000
}

2001
static void
2002
gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se, struct svc_rqst *rqstp)
L
Linus Torvalds 已提交
2003
{
2004
	struct nfs4_cb_conn *conn = &clp->cl_cb_conn;
2005 2006
	struct sockaddr	*sa = svc_addr(rqstp);
	u32 scopeid = rpc_get_scope_id(sa);
2007 2008 2009 2010 2011 2012 2013 2014 2015 2016
	unsigned short expected_family;

	/* Currently, we only support tcp and tcp6 for the callback channel */
	if (se->se_callback_netid_len == 3 &&
	    !memcmp(se->se_callback_netid_val, "tcp", 3))
		expected_family = AF_INET;
	else if (se->se_callback_netid_len == 4 &&
		 !memcmp(se->se_callback_netid_val, "tcp6", 4))
		expected_family = AF_INET6;
	else
L
Linus Torvalds 已提交
2017 2018
		goto out_err;

2019
	conn->cb_addrlen = rpc_uaddr2sockaddr(clp->net, se->se_callback_addr_val,
2020
					    se->se_callback_addr_len,
2021 2022
					    (struct sockaddr *)&conn->cb_addr,
					    sizeof(conn->cb_addr));
2023

2024
	if (!conn->cb_addrlen || conn->cb_addr.ss_family != expected_family)
L
Linus Torvalds 已提交
2025
		goto out_err;
2026

2027 2028
	if (conn->cb_addr.ss_family == AF_INET6)
		((struct sockaddr_in6 *)&conn->cb_addr)->sin6_scope_id = scopeid;
2029

2030 2031
	conn->cb_prog = se->se_callback_prog;
	conn->cb_ident = se->se_callback_ident;
2032
	memcpy(&conn->cb_saddr, &rqstp->rq_daddr, rqstp->rq_daddrlen);
L
Linus Torvalds 已提交
2033 2034
	return;
out_err:
2035 2036
	conn->cb_addr.ss_family = AF_UNSPEC;
	conn->cb_addrlen = 0;
N
Neil Brown 已提交
2037
	dprintk(KERN_INFO "NFSD: this client (clientid %08x/%08x) "
L
Linus Torvalds 已提交
2038 2039 2040 2041 2042 2043
		"will not receive delegations\n",
		clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);

	return;
}

2044
/*
2045
 * Cache a reply. nfsd4_check_resp_size() has bounded the cache size.
2046
 */
2047
static void
2048 2049
nfsd4_store_cache_entry(struct nfsd4_compoundres *resp)
{
2050
	struct xdr_buf *buf = resp->xdr.buf;
2051 2052
	struct nfsd4_slot *slot = resp->cstate.slot;
	unsigned int base;
2053

2054
	dprintk("--> %s slot %p\n", __func__, slot);
2055

2056 2057
	slot->sl_opcnt = resp->opcnt;
	slot->sl_status = resp->cstate.status;
2058

2059
	slot->sl_flags |= NFSD4_SLOT_INITIALIZED;
2060
	if (nfsd4_not_cached(resp)) {
2061
		slot->sl_datalen = 0;
2062
		return;
2063
	}
2064 2065 2066
	base = resp->cstate.data_offset;
	slot->sl_datalen = buf->len - base;
	if (read_bytes_from_xdr_buf(buf, base, slot->sl_data, slot->sl_datalen))
2067 2068
		WARN("%s: sessions DRC could not cache compound\n", __func__);
	return;
2069 2070 2071
}

/*
2072 2073 2074 2075
 * Encode the replay sequence operation from the slot values.
 * If cachethis is FALSE encode the uncached rep error on the next
 * operation which sets resp->p and increments resp->opcnt for
 * nfs4svc_encode_compoundres.
2076 2077
 *
 */
2078 2079 2080
static __be32
nfsd4_enc_sequence_replay(struct nfsd4_compoundargs *args,
			  struct nfsd4_compoundres *resp)
2081
{
2082 2083
	struct nfsd4_op *op;
	struct nfsd4_slot *slot = resp->cstate.slot;
2084

2085 2086 2087
	/* Encode the replayed sequence operation */
	op = &args->ops[resp->opcnt - 1];
	nfsd4_encode_operation(resp, op);
2088

2089
	/* Return nfserr_retry_uncached_rep in next operation. */
2090
	if (args->opcnt > 1 && !(slot->sl_flags & NFSD4_SLOT_CACHETHIS)) {
2091 2092 2093
		op = &args->ops[resp->opcnt++];
		op->status = nfserr_retry_uncached_rep;
		nfsd4_encode_operation(resp, op);
2094
	}
2095
	return op->status;
2096 2097 2098
}

/*
2099 2100
 * The sequence operation is not cached because we can use the slot and
 * session values.
2101
 */
2102
static __be32
2103 2104
nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
			 struct nfsd4_sequence *seq)
2105
{
2106
	struct nfsd4_slot *slot = resp->cstate.slot;
2107 2108
	struct xdr_stream *xdr = &resp->xdr;
	__be32 *p;
2109 2110
	__be32 status;

2111
	dprintk("--> %s slot %p\n", __func__, slot);
2112

2113
	status = nfsd4_enc_sequence_replay(resp->rqstp->rq_argp, resp);
2114
	if (status)
2115
		return status;
2116

2117 2118 2119 2120 2121 2122 2123
	p = xdr_reserve_space(xdr, slot->sl_datalen);
	if (!p) {
		WARN_ON_ONCE(1);
		return nfserr_serverfault;
	}
	xdr_encode_opaque_fixed(p, slot->sl_data, slot->sl_datalen);
	xdr_commit_encode(xdr);
2124

2125
	resp->opcnt = slot->sl_opcnt;
2126
	return slot->sl_status;
2127 2128
}

A
Andy Adamson 已提交
2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144
/*
 * Set the exchange_id flags returned by the server.
 */
static void
nfsd4_set_ex_flags(struct nfs4_client *new, struct nfsd4_exchange_id *clid)
{
	/* pNFS is not supported */
	new->cl_exchange_flags |= EXCHGID4_FLAG_USE_NON_PNFS;

	/* Referrals are supported, Migration is not. */
	new->cl_exchange_flags |= EXCHGID4_FLAG_SUPP_MOVED_REFER;

	/* set the wire flags to return to client. */
	clid->flags = new->cl_exchange_flags;
}

2145 2146 2147 2148 2149 2150 2151 2152
static bool client_has_state(struct nfs4_client *clp)
{
	/*
	 * Note clp->cl_openowners check isn't quite right: there's no
	 * need to count owners without stateid's.
	 *
	 * Also note we should probably be using this in 4.0 case too.
	 */
2153 2154 2155
	return !list_empty(&clp->cl_openowners)
		|| !list_empty(&clp->cl_delegations)
		|| !list_empty(&clp->cl_sessions);
2156 2157
}

A
Andy Adamson 已提交
2158 2159 2160 2161 2162
__be32
nfsd4_exchange_id(struct svc_rqst *rqstp,
		  struct nfsd4_compound_state *cstate,
		  struct nfsd4_exchange_id *exid)
{
2163 2164
	struct nfs4_client *conf, *new;
	struct nfs4_client *unconf = NULL;
J
J. Bruce Fields 已提交
2165
	__be32 status;
2166
	char			addr_str[INET6_ADDRSTRLEN];
A
Andy Adamson 已提交
2167
	nfs4_verifier		verf = exid->verifier;
2168
	struct sockaddr		*sa = svc_addr(rqstp);
2169
	bool	update = exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A;
2170
	struct nfsd_net		*nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
A
Andy Adamson 已提交
2171

2172
	rpc_ntop(sa, addr_str, sizeof(addr_str));
A
Andy Adamson 已提交
2173
	dprintk("%s rqstp=%p exid=%p clname.len=%u clname.data=%p "
2174
		"ip_addr=%s flags %x, spa_how %d\n",
A
Andy Adamson 已提交
2175
		__func__, rqstp, exid, exid->clname.len, exid->clname.data,
2176
		addr_str, exid->flags, exid->spa_how);
A
Andy Adamson 已提交
2177

2178
	if (exid->flags & ~EXCHGID4_FLAG_MASK_A)
A
Andy Adamson 已提交
2179 2180 2181
		return nfserr_inval;

	switch (exid->spa_how) {
2182 2183 2184
	case SP4_MACH_CRED:
		if (!svc_rqst_integrity_protected(rqstp))
			return nfserr_inval;
A
Andy Adamson 已提交
2185 2186
	case SP4_NONE:
		break;
2187 2188
	default:				/* checked by xdr code */
		WARN_ON_ONCE(1);
A
Andy Adamson 已提交
2189
	case SP4_SSV:
2190
		return nfserr_encr_alg_unsupp;
A
Andy Adamson 已提交
2191 2192
	}

2193 2194 2195 2196
	new = create_client(exid->clname, rqstp, &verf);
	if (new == NULL)
		return nfserr_jukebox;

2197
	/* Cases below refer to rfc 5661 section 18.35.4: */
2198
	spin_lock(&nn->client_lock);
2199
	conf = find_confirmed_client_by_name(&exid->clname, nn);
A
Andy Adamson 已提交
2200
	if (conf) {
2201 2202 2203
		bool creds_match = same_creds(&conf->cl_cred, &rqstp->rq_cred);
		bool verfs_match = same_verf(&verf, &conf->cl_verifier);

2204 2205
		if (update) {
			if (!clp_used_exchangeid(conf)) { /* buggy client */
2206
				status = nfserr_inval;
2207 2208
				goto out;
			}
2209 2210 2211 2212
			if (!mach_creds_match(conf, rqstp)) {
				status = nfserr_wrong_cred;
				goto out;
			}
2213
			if (!creds_match) { /* case 9 */
2214
				status = nfserr_perm;
2215 2216 2217
				goto out;
			}
			if (!verfs_match) { /* case 8 */
A
Andy Adamson 已提交
2218 2219 2220
				status = nfserr_not_same;
				goto out;
			}
2221 2222 2223
			/* case 6 */
			exid->flags |= EXCHGID4_FLAG_CONFIRMED_R;
			goto out_copy;
A
Andy Adamson 已提交
2224
		}
2225
		if (!creds_match) { /* case 3 */
2226 2227
			if (client_has_state(conf)) {
				status = nfserr_clid_inuse;
A
Andy Adamson 已提交
2228 2229 2230 2231
				goto out;
			}
			goto out_new;
		}
2232
		if (verfs_match) { /* case 2 */
2233
			conf->cl_exchange_flags |= EXCHGID4_FLAG_CONFIRMED_R;
2234 2235 2236
			goto out_copy;
		}
		/* case 5, client reboot */
2237
		conf = NULL;
2238
		goto out_new;
2239 2240
	}

2241
	if (update) { /* case 7 */
2242 2243
		status = nfserr_noent;
		goto out;
A
Andy Adamson 已提交
2244 2245
	}

2246
	unconf  = find_unconfirmed_client_by_name(&exid->clname, nn);
2247
	if (unconf) /* case 4, possible retry or client restart */
2248
		unhash_client_locked(unconf);
A
Andy Adamson 已提交
2249

2250
	/* case 1 (normal case) */
A
Andy Adamson 已提交
2251
out_new:
2252 2253 2254 2255 2256
	if (conf) {
		status = mark_client_expired_locked(conf);
		if (status)
			goto out;
	}
2257
	new->cl_minorversion = cstate->minorversion;
2258
	new->cl_mach_cred = (exid->spa_how == SP4_MACH_CRED);
A
Andy Adamson 已提交
2259

2260
	gen_clid(new, nn);
2261
	add_to_unconfirmed(new);
2262
	swap(new, conf);
A
Andy Adamson 已提交
2263
out_copy:
2264 2265
	exid->clientid.cl_boot = conf->cl_clientid.cl_boot;
	exid->clientid.cl_id = conf->cl_clientid.cl_id;
A
Andy Adamson 已提交
2266

2267 2268
	exid->seqid = conf->cl_cs_slot.sl_seqid + 1;
	nfsd4_set_ex_flags(conf, exid);
A
Andy Adamson 已提交
2269 2270

	dprintk("nfsd4_exchange_id seqid %d flags %x\n",
2271
		conf->cl_cs_slot.sl_seqid, conf->cl_exchange_flags);
A
Andy Adamson 已提交
2272 2273 2274
	status = nfs_ok;

out:
2275
	spin_unlock(&nn->client_lock);
2276
	if (new)
2277 2278 2279
		expire_client(new);
	if (unconf)
		expire_client(unconf);
A
Andy Adamson 已提交
2280
	return status;
A
Andy Adamson 已提交
2281 2282
}

J
J. Bruce Fields 已提交
2283
static __be32
2284
check_slot_seqid(u32 seqid, u32 slot_seqid, int slot_inuse)
B
Benny Halevy 已提交
2285
{
2286 2287
	dprintk("%s enter. seqid %d slot_seqid %d\n", __func__, seqid,
		slot_seqid);
B
Benny Halevy 已提交
2288 2289

	/* The slot is in use, and no response has been sent. */
2290 2291
	if (slot_inuse) {
		if (seqid == slot_seqid)
B
Benny Halevy 已提交
2292 2293 2294 2295
			return nfserr_jukebox;
		else
			return nfserr_seq_misordered;
	}
2296
	/* Note unsigned 32-bit arithmetic handles wraparound: */
2297
	if (likely(seqid == slot_seqid + 1))
B
Benny Halevy 已提交
2298
		return nfs_ok;
2299
	if (seqid == slot_seqid)
B
Benny Halevy 已提交
2300 2301 2302 2303
		return nfserr_replay_cache;
	return nfserr_seq_misordered;
}

2304 2305 2306 2307 2308 2309 2310
/*
 * Cache the create session result into the create session single DRC
 * slot cache by saving the xdr structure. sl_seqid has been set.
 * Do this for solo or embedded create session operations.
 */
static void
nfsd4_cache_create_session(struct nfsd4_create_session *cr_ses,
J
J. Bruce Fields 已提交
2311
			   struct nfsd4_clid_slot *slot, __be32 nfserr)
2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324
{
	slot->sl_status = nfserr;
	memcpy(&slot->sl_cr_ses, cr_ses, sizeof(*cr_ses));
}

static __be32
nfsd4_replay_create_session(struct nfsd4_create_session *cr_ses,
			    struct nfsd4_clid_slot *slot)
{
	memcpy(cr_ses, &slot->sl_cr_ses, sizeof(*cr_ses));
	return slot->sl_status;
}

2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341
#define NFSD_MIN_REQ_HDR_SEQ_SZ	((\
			2 * 2 + /* credential,verifier: AUTH_NULL, length 0 */ \
			1 +	/* MIN tag is length with zero, only length */ \
			3 +	/* version, opcount, opcode */ \
			XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + \
				/* seqid, slotID, slotID, cache */ \
			4 ) * sizeof(__be32))

#define NFSD_MIN_RESP_HDR_SEQ_SZ ((\
			2 +	/* verifier: AUTH_NULL, length 0 */\
			1 +	/* status */ \
			1 +	/* MIN tag is length with zero, only length */ \
			3 +	/* opcount, opcode, opstatus*/ \
			XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + \
				/* seqid, slotID, slotID, slotID, status */ \
			5 ) * sizeof(__be32))

2342
static __be32 check_forechannel_attrs(struct nfsd4_channel_attrs *ca, struct nfsd_net *nn)
2343
{
2344 2345
	u32 maxrpc = nn->nfsd_serv->sv_max_mesg;

2346 2347 2348 2349
	if (ca->maxreq_sz < NFSD_MIN_REQ_HDR_SEQ_SZ)
		return nfserr_toosmall;
	if (ca->maxresp_sz < NFSD_MIN_RESP_HDR_SEQ_SZ)
		return nfserr_toosmall;
2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368
	ca->headerpadsz = 0;
	ca->maxreq_sz = min_t(u32, ca->maxreq_sz, maxrpc);
	ca->maxresp_sz = min_t(u32, ca->maxresp_sz, maxrpc);
	ca->maxops = min_t(u32, ca->maxops, NFSD_MAX_OPS_PER_COMPOUND);
	ca->maxresp_cached = min_t(u32, ca->maxresp_cached,
			NFSD_SLOT_CACHE_SIZE + NFSD_MIN_HDR_SEQ_SZ);
	ca->maxreqs = min_t(u32, ca->maxreqs, NFSD_MAX_SLOTS_PER_SESSION);
	/*
	 * Note decreasing slot size below client's request may make it
	 * difficult for client to function correctly, whereas
	 * decreasing the number of slots will (just?) affect
	 * performance.  When short on memory we therefore prefer to
	 * decrease number of slots instead of their size.  Clients that
	 * request larger slots than they need will get poor results:
	 */
	ca->maxreqs = nfsd4_get_drc_mem(ca);
	if (!ca->maxreqs)
		return nfserr_jukebox;

2369
	return nfs_ok;
2370 2371
}

2372 2373 2374 2375 2376
#define NFSD_CB_MAX_REQ_SZ	((NFS4_enc_cb_recall_sz + \
				 RPC_MAX_HEADER_WITH_AUTH) * sizeof(__be32))
#define NFSD_CB_MAX_RESP_SZ	((NFS4_dec_cb_recall_sz + \
				 RPC_MAX_REPHEADER_WITH_AUTH) * sizeof(__be32))

2377
static __be32 check_backchannel_attrs(struct nfsd4_channel_attrs *ca)
2378
{
2379 2380 2381 2382 2383 2384 2385 2386
	ca->headerpadsz = 0;

	/*
	 * These RPC_MAX_HEADER macros are overkill, especially since we
	 * don't even do gss on the backchannel yet.  But this is still
	 * less than 1k.  Tighten up this estimate in the unlikely event
	 * it turns out to be a problem for some client:
	 */
2387
	if (ca->maxreq_sz < NFSD_CB_MAX_REQ_SZ)
2388
		return nfserr_toosmall;
2389
	if (ca->maxresp_sz < NFSD_CB_MAX_RESP_SZ)
2390 2391 2392 2393 2394 2395
		return nfserr_toosmall;
	ca->maxresp_cached = 0;
	if (ca->maxops < 2)
		return nfserr_toosmall;

	return nfs_ok;
2396 2397
}

2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415
static __be32 nfsd4_check_cb_sec(struct nfsd4_cb_sec *cbs)
{
	switch (cbs->flavor) {
	case RPC_AUTH_NULL:
	case RPC_AUTH_UNIX:
		return nfs_ok;
	default:
		/*
		 * GSS case: the spec doesn't allow us to return this
		 * error.  But it also doesn't allow us not to support
		 * GSS.
		 * I'd rather this fail hard than return some error the
		 * client might think it can already handle:
		 */
		return nfserr_encr_alg_unsupp;
	}
}

A
Andy Adamson 已提交
2416 2417 2418 2419 2420
__be32
nfsd4_create_session(struct svc_rqst *rqstp,
		     struct nfsd4_compound_state *cstate,
		     struct nfsd4_create_session *cr_ses)
{
2421
	struct sockaddr *sa = svc_addr(rqstp);
A
Andy Adamson 已提交
2422
	struct nfs4_client *conf, *unconf;
2423
	struct nfs4_client *old = NULL;
2424
	struct nfsd4_session *new;
2425
	struct nfsd4_conn *conn;
2426
	struct nfsd4_clid_slot *cs_slot = NULL;
J
J. Bruce Fields 已提交
2427
	__be32 status = 0;
2428
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
A
Andy Adamson 已提交
2429

2430 2431
	if (cr_ses->flags & ~SESSION4_FLAG_MASK_A)
		return nfserr_inval;
2432 2433 2434
	status = nfsd4_check_cb_sec(&cr_ses->cb_sec);
	if (status)
		return status;
2435
	status = check_forechannel_attrs(&cr_ses->fore_channel, nn);
2436 2437 2438
	if (status)
		return status;
	status = check_backchannel_attrs(&cr_ses->back_channel);
2439
	if (status)
2440
		goto out_release_drc_mem;
2441
	status = nfserr_jukebox;
2442
	new = alloc_session(&cr_ses->fore_channel, &cr_ses->back_channel);
2443 2444
	if (!new)
		goto out_release_drc_mem;
2445 2446 2447
	conn = alloc_conn_from_crses(rqstp, cr_ses);
	if (!conn)
		goto out_free_session;
2448

2449
	spin_lock(&nn->client_lock);
2450
	unconf = find_unconfirmed_client(&cr_ses->clientid, true, nn);
2451
	conf = find_confirmed_client(&cr_ses->clientid, true, nn);
2452
	WARN_ON_ONCE(conf && unconf);
A
Andy Adamson 已提交
2453 2454

	if (conf) {
2455 2456 2457
		status = nfserr_wrong_cred;
		if (!mach_creds_match(conf, rqstp))
			goto out_free_conn;
2458 2459
		cs_slot = &conf->cl_cs_slot;
		status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0);
2460
		if (status == nfserr_replay_cache) {
2461
			status = nfsd4_replay_create_session(cr_ses, cs_slot);
2462
			goto out_free_conn;
2463
		} else if (cr_ses->seqid != cs_slot->sl_seqid + 1) {
A
Andy Adamson 已提交
2464
			status = nfserr_seq_misordered;
2465
			goto out_free_conn;
A
Andy Adamson 已提交
2466 2467 2468
		}
	} else if (unconf) {
		if (!same_creds(&unconf->cl_cred, &rqstp->rq_cred) ||
2469
		    !rpc_cmp_addr(sa, (struct sockaddr *) &unconf->cl_addr)) {
A
Andy Adamson 已提交
2470
			status = nfserr_clid_inuse;
2471
			goto out_free_conn;
A
Andy Adamson 已提交
2472
		}
2473 2474 2475
		status = nfserr_wrong_cred;
		if (!mach_creds_match(unconf, rqstp))
			goto out_free_conn;
2476 2477
		cs_slot = &unconf->cl_cs_slot;
		status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0);
2478 2479
		if (status) {
			/* an unconfirmed replay returns misordered */
A
Andy Adamson 已提交
2480
			status = nfserr_seq_misordered;
2481
			goto out_free_conn;
A
Andy Adamson 已提交
2482
		}
2483
		old = find_confirmed_client_by_name(&unconf->cl_name, nn);
2484
		if (old) {
2485
			status = mark_client_expired_locked(old);
2486 2487
			if (status) {
				old = NULL;
2488
				goto out_free_conn;
2489
			}
2490
		}
J
J. Bruce Fields 已提交
2491
		move_to_confirmed(unconf);
A
Andy Adamson 已提交
2492 2493 2494
		conf = unconf;
	} else {
		status = nfserr_stale_clientid;
2495
		goto out_free_conn;
A
Andy Adamson 已提交
2496
	}
2497
	status = nfs_ok;
2498 2499 2500 2501 2502 2503
	/*
	 * We do not support RDMA or persistent sessions
	 */
	cr_ses->flags &= ~SESSION4_PERSIST;
	cr_ses->flags &= ~SESSION4_RDMA;

2504
	init_session(rqstp, new, conf, cr_ses);
2505
	nfsd4_get_session_locked(new);
2506

2507
	memcpy(cr_ses->sessionid.data, new->se_sessionid.data,
A
Andy Adamson 已提交
2508
	       NFS4_MAX_SESSIONID_LEN);
2509
	cs_slot->sl_seqid++;
2510
	cr_ses->seqid = cs_slot->sl_seqid;
A
Andy Adamson 已提交
2511

2512
	/* cache solo and embedded create sessions under the client_lock */
2513
	nfsd4_cache_create_session(cr_ses, cs_slot, status);
2514 2515 2516 2517 2518 2519
	spin_unlock(&nn->client_lock);
	/* init connection and backchannel */
	nfsd4_init_conn(rqstp, conn, new);
	nfsd4_put_session(new);
	if (old)
		expire_client(old);
A
Andy Adamson 已提交
2520
	return status;
2521
out_free_conn:
2522
	spin_unlock(&nn->client_lock);
2523
	free_conn(conn);
2524 2525
	if (old)
		expire_client(old);
2526 2527
out_free_session:
	__free_session(new);
2528 2529
out_release_drc_mem:
	nfsd4_put_drc_mem(&cr_ses->fore_channel);
J
J. Bruce Fields 已提交
2530
	return status;
A
Andy Adamson 已提交
2531 2532
}

2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546
static __be32 nfsd4_map_bcts_dir(u32 *dir)
{
	switch (*dir) {
	case NFS4_CDFC4_FORE:
	case NFS4_CDFC4_BACK:
		return nfs_ok;
	case NFS4_CDFC4_FORE_OR_BOTH:
	case NFS4_CDFC4_BACK_OR_BOTH:
		*dir = NFS4_CDFC4_BOTH;
		return nfs_ok;
	};
	return nfserr_inval;
}

2547 2548 2549
__be32 nfsd4_backchannel_ctl(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_backchannel_ctl *bc)
{
	struct nfsd4_session *session = cstate->session;
2550
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
2551
	__be32 status;
2552

2553 2554 2555
	status = nfsd4_check_cb_sec(&bc->bc_cb_sec);
	if (status)
		return status;
2556
	spin_lock(&nn->client_lock);
2557 2558
	session->se_cb_prog = bc->bc_cb_program;
	session->se_cb_sec = bc->bc_cb_sec;
2559
	spin_unlock(&nn->client_lock);
2560 2561 2562 2563 2564 2565

	nfsd4_probe_callback(session->se_client);

	return nfs_ok;
}

2566 2567 2568 2569 2570
__be32 nfsd4_bind_conn_to_session(struct svc_rqst *rqstp,
		     struct nfsd4_compound_state *cstate,
		     struct nfsd4_bind_conn_to_session *bcts)
{
	__be32 status;
2571
	struct nfsd4_conn *conn;
2572
	struct nfsd4_session *session;
2573 2574
	struct net *net = SVC_NET(rqstp);
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
2575 2576 2577

	if (!nfsd4_last_compound_op(rqstp))
		return nfserr_not_only_op;
2578
	spin_lock(&nn->client_lock);
2579
	session = find_in_sessionid_hashtbl(&bcts->sessionid, net, &status);
2580
	spin_unlock(&nn->client_lock);
2581
	if (!session)
2582
		goto out_no_session;
2583 2584 2585
	status = nfserr_wrong_cred;
	if (!mach_creds_match(session->se_client, rqstp))
		goto out;
2586
	status = nfsd4_map_bcts_dir(&bcts->dir);
2587
	if (status)
2588
		goto out;
2589
	conn = alloc_conn(rqstp, bcts->dir);
2590
	status = nfserr_jukebox;
2591
	if (!conn)
2592 2593 2594 2595
		goto out;
	nfsd4_init_conn(rqstp, conn, session);
	status = nfs_ok;
out:
2596 2597
	nfsd4_put_session(session);
out_no_session:
2598
	return status;
2599 2600
}

2601 2602 2603 2604 2605 2606 2607
static bool nfsd4_compound_in_session(struct nfsd4_session *session, struct nfs4_sessionid *sid)
{
	if (!session)
		return 0;
	return !memcmp(sid, &session->se_sessionid, sizeof(*sid));
}

A
Andy Adamson 已提交
2608 2609 2610 2611 2612
__be32
nfsd4_destroy_session(struct svc_rqst *r,
		      struct nfsd4_compound_state *cstate,
		      struct nfsd4_destroy_session *sessionid)
{
B
Benny Halevy 已提交
2613
	struct nfsd4_session *ses;
2614
	__be32 status;
2615
	int ref_held_by_me = 0;
2616 2617
	struct net *net = SVC_NET(r);
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
B
Benny Halevy 已提交
2618

2619
	status = nfserr_not_only_op;
2620
	if (nfsd4_compound_in_session(cstate->session, &sessionid->sessionid)) {
2621
		if (!nfsd4_last_compound_op(r))
2622
			goto out;
2623
		ref_held_by_me++;
2624
	}
B
Benny Halevy 已提交
2625
	dump_sessionid(__func__, &sessionid->sessionid);
2626
	spin_lock(&nn->client_lock);
2627
	ses = find_in_sessionid_hashtbl(&sessionid->sessionid, net, &status);
2628 2629
	if (!ses)
		goto out_client_lock;
2630 2631
	status = nfserr_wrong_cred;
	if (!mach_creds_match(ses->se_client, r))
2632
		goto out_put_session;
2633
	status = mark_session_dead_locked(ses, 1 + ref_held_by_me);
2634
	if (status)
2635
		goto out_put_session;
B
Benny Halevy 已提交
2636
	unhash_session(ses);
2637
	spin_unlock(&nn->client_lock);
B
Benny Halevy 已提交
2638

2639
	nfsd4_probe_callback_sync(ses->se_client);
2640

2641
	spin_lock(&nn->client_lock);
B
Benny Halevy 已提交
2642
	status = nfs_ok;
2643
out_put_session:
2644
	nfsd4_put_session_locked(ses);
2645 2646
out_client_lock:
	spin_unlock(&nn->client_lock);
B
Benny Halevy 已提交
2647 2648
out:
	return status;
A
Andy Adamson 已提交
2649 2650
}

2651
static struct nfsd4_conn *__nfsd4_find_conn(struct svc_xprt *xpt, struct nfsd4_session *s)
2652 2653 2654 2655
{
	struct nfsd4_conn *c;

	list_for_each_entry(c, &s->se_conns, cn_persession) {
2656
		if (c->cn_xprt == xpt) {
2657 2658 2659 2660 2661 2662
			return c;
		}
	}
	return NULL;
}

2663
static __be32 nfsd4_sequence_check_conn(struct nfsd4_conn *new, struct nfsd4_session *ses)
2664 2665
{
	struct nfs4_client *clp = ses->se_client;
2666
	struct nfsd4_conn *c;
2667
	__be32 status = nfs_ok;
2668
	int ret;
2669 2670

	spin_lock(&clp->cl_lock);
2671
	c = __nfsd4_find_conn(new->cn_xprt, ses);
2672 2673 2674 2675 2676
	if (c)
		goto out_free;
	status = nfserr_conn_not_bound_to_session;
	if (clp->cl_mach_cred)
		goto out_free;
2677 2678
	__nfsd4_hash_conn(new, ses);
	spin_unlock(&clp->cl_lock);
2679 2680 2681 2682
	ret = nfsd4_register_conn(new);
	if (ret)
		/* oops; xprt is already down: */
		nfsd4_conn_lost(&new->cn_xpt_user);
2683 2684 2685 2686 2687
	return nfs_ok;
out_free:
	spin_unlock(&clp->cl_lock);
	free_conn(new);
	return status;
2688 2689
}

2690 2691 2692 2693 2694 2695 2696
static bool nfsd4_session_too_many_ops(struct svc_rqst *rqstp, struct nfsd4_session *session)
{
	struct nfsd4_compoundargs *args = rqstp->rq_argp;

	return args->opcnt > session->se_fchannel.maxops;
}

M
Mi Jinlong 已提交
2697 2698 2699 2700 2701 2702 2703 2704
static bool nfsd4_request_too_big(struct svc_rqst *rqstp,
				  struct nfsd4_session *session)
{
	struct xdr_buf *xb = &rqstp->rq_arg;

	return xb->len > session->se_fchannel.maxreq_sz;
}

A
Andy Adamson 已提交
2705
__be32
B
Benny Halevy 已提交
2706
nfsd4_sequence(struct svc_rqst *rqstp,
A
Andy Adamson 已提交
2707 2708 2709
	       struct nfsd4_compound_state *cstate,
	       struct nfsd4_sequence *seq)
{
2710
	struct nfsd4_compoundres *resp = rqstp->rq_resp;
2711
	struct xdr_stream *xdr = &resp->xdr;
B
Benny Halevy 已提交
2712
	struct nfsd4_session *session;
2713
	struct nfs4_client *clp;
B
Benny Halevy 已提交
2714
	struct nfsd4_slot *slot;
2715
	struct nfsd4_conn *conn;
J
J. Bruce Fields 已提交
2716
	__be32 status;
2717
	int buflen;
2718 2719
	struct net *net = SVC_NET(rqstp);
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
B
Benny Halevy 已提交
2720

2721 2722 2723
	if (resp->opcnt != 1)
		return nfserr_sequence_pos;

2724 2725 2726 2727 2728 2729 2730 2731
	/*
	 * Will be either used or freed by nfsd4_sequence_check_conn
	 * below.
	 */
	conn = alloc_conn(rqstp, NFS4_CDFC4_FORE);
	if (!conn)
		return nfserr_jukebox;

2732
	spin_lock(&nn->client_lock);
2733
	session = find_in_sessionid_hashtbl(&seq->sessionid, net, &status);
B
Benny Halevy 已提交
2734
	if (!session)
2735 2736
		goto out_no_session;
	clp = session->se_client;
B
Benny Halevy 已提交
2737

2738 2739
	status = nfserr_too_many_ops;
	if (nfsd4_session_too_many_ops(rqstp, session))
2740
		goto out_put_session;
2741

M
Mi Jinlong 已提交
2742 2743
	status = nfserr_req_too_big;
	if (nfsd4_request_too_big(rqstp, session))
2744
		goto out_put_session;
M
Mi Jinlong 已提交
2745

B
Benny Halevy 已提交
2746
	status = nfserr_badslot;
2747
	if (seq->slotid >= session->se_fchannel.maxreqs)
2748
		goto out_put_session;
B
Benny Halevy 已提交
2749

2750
	slot = session->se_slots[seq->slotid];
B
Benny Halevy 已提交
2751 2752
	dprintk("%s: slotid %d\n", __func__, seq->slotid);

2753 2754 2755 2756 2757
	/* We do not negotiate the number of slots yet, so set the
	 * maxslots to the session maxreqs which is used to encode
	 * sr_highest_slotid and the sr_target_slot id to maxslots */
	seq->maxslots = session->se_fchannel.maxreqs;

2758 2759
	status = check_slot_seqid(seq->seqid, slot->sl_seqid,
					slot->sl_flags & NFSD4_SLOT_INUSE);
B
Benny Halevy 已提交
2760
	if (status == nfserr_replay_cache) {
2761 2762
		status = nfserr_seq_misordered;
		if (!(slot->sl_flags & NFSD4_SLOT_INITIALIZED))
2763
			goto out_put_session;
B
Benny Halevy 已提交
2764 2765
		cstate->slot = slot;
		cstate->session = session;
2766
		cstate->clp = clp;
A
Andy Adamson 已提交
2767
		/* Return the cached reply status and set cstate->status
2768
		 * for nfsd4_proc_compound processing */
2769
		status = nfsd4_replay_cache_entry(resp, seq);
A
Andy Adamson 已提交
2770
		cstate->status = nfserr_replay_cache;
2771
		goto out;
B
Benny Halevy 已提交
2772 2773
	}
	if (status)
2774
		goto out_put_session;
B
Benny Halevy 已提交
2775

2776
	status = nfsd4_sequence_check_conn(conn, session);
2777
	conn = NULL;
2778 2779
	if (status)
		goto out_put_session;
2780

2781 2782 2783 2784 2785
	buflen = (seq->cachethis) ?
			session->se_fchannel.maxresp_cached :
			session->se_fchannel.maxresp_sz;
	status = (seq->cachethis) ? nfserr_rep_too_big_to_cache :
				    nfserr_rep_too_big;
2786
	if (xdr_restrict_buflen(xdr, buflen - rqstp->rq_auth_slack))
2787
		goto out_put_session;
2788
	svc_reserve(rqstp, buflen);
2789 2790

	status = nfs_ok;
B
Benny Halevy 已提交
2791 2792
	/* Success! bump slot seqid */
	slot->sl_seqid = seq->seqid;
2793
	slot->sl_flags |= NFSD4_SLOT_INUSE;
2794 2795
	if (seq->cachethis)
		slot->sl_flags |= NFSD4_SLOT_CACHETHIS;
2796 2797
	else
		slot->sl_flags &= ~NFSD4_SLOT_CACHETHIS;
B
Benny Halevy 已提交
2798 2799 2800

	cstate->slot = slot;
	cstate->session = session;
2801
	cstate->clp = clp;
B
Benny Halevy 已提交
2802 2803

out:
2804 2805 2806 2807 2808 2809 2810 2811 2812
	switch (clp->cl_cb_state) {
	case NFSD4_CB_DOWN:
		seq->status_flags = SEQ4_STATUS_CB_PATH_DOWN;
		break;
	case NFSD4_CB_FAULT:
		seq->status_flags = SEQ4_STATUS_BACKCHANNEL_FAULT;
		break;
	default:
		seq->status_flags = 0;
2813
	}
2814 2815
	if (!list_empty(&clp->cl_revoked))
		seq->status_flags |= SEQ4_STATUS_RECALLABLE_STATE_REVOKED;
2816
out_no_session:
2817 2818
	if (conn)
		free_conn(conn);
2819
	spin_unlock(&nn->client_lock);
B
Benny Halevy 已提交
2820
	return status;
2821
out_put_session:
2822
	nfsd4_put_session_locked(session);
2823
	goto out_no_session;
A
Andy Adamson 已提交
2824 2825
}

2826 2827 2828 2829 2830 2831 2832 2833 2834 2835
void
nfsd4_sequence_done(struct nfsd4_compoundres *resp)
{
	struct nfsd4_compound_state *cs = &resp->cstate;

	if (nfsd4_has_session(cs)) {
		if (cs->status != nfserr_replay_cache) {
			nfsd4_store_cache_entry(resp);
			cs->slot->sl_flags &= ~NFSD4_SLOT_INUSE;
		}
2836
		/* Drop session reference that was taken in nfsd4_sequence() */
2837
		nfsd4_put_session(cs->session);
2838 2839
	} else if (cs->clp)
		put_client_renew(cs->clp);
2840 2841
}

2842 2843 2844
__be32
nfsd4_destroy_clientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_destroy_clientid *dc)
{
2845 2846
	struct nfs4_client *conf, *unconf;
	struct nfs4_client *clp = NULL;
J
J. Bruce Fields 已提交
2847
	__be32 status = 0;
2848
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
2849

2850
	spin_lock(&nn->client_lock);
2851
	unconf = find_unconfirmed_client(&dc->clientid, true, nn);
2852
	conf = find_confirmed_client(&dc->clientid, true, nn);
2853
	WARN_ON_ONCE(conf && unconf);
2854 2855

	if (conf) {
2856
		if (client_has_state(conf)) {
2857 2858 2859
			status = nfserr_clientid_busy;
			goto out;
		}
2860 2861 2862
		status = mark_client_expired_locked(conf);
		if (status)
			goto out;
2863
		clp = conf;
2864 2865 2866 2867 2868 2869
	} else if (unconf)
		clp = unconf;
	else {
		status = nfserr_stale_clientid;
		goto out;
	}
2870
	if (!mach_creds_match(clp, rqstp)) {
2871
		clp = NULL;
2872 2873 2874
		status = nfserr_wrong_cred;
		goto out;
	}
2875
	unhash_client_locked(clp);
2876
out:
2877 2878 2879
	spin_unlock(&nn->client_lock);
	if (clp)
		expire_client(clp);
2880 2881 2882
	return status;
}

2883 2884 2885
__be32
nfsd4_reclaim_complete(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_reclaim_complete *rc)
{
J
J. Bruce Fields 已提交
2886
	__be32 status = 0;
2887

2888 2889 2890 2891 2892 2893 2894 2895 2896
	if (rc->rca_one_fs) {
		if (!cstate->current_fh.fh_dentry)
			return nfserr_nofilehandle;
		/*
		 * We don't take advantage of the rca_one_fs case.
		 * That's OK, it's optional, we can safely ignore it.
		 */
		 return nfs_ok;
	}
2897 2898

	status = nfserr_complete_already;
2899 2900
	if (test_and_set_bit(NFSD4_CLIENT_RECLAIM_COMPLETE,
			     &cstate->session->se_client->cl_flags))
2901 2902 2903 2904
		goto out;

	status = nfserr_stale_clientid;
	if (is_client_expired(cstate->session->se_client))
2905 2906 2907 2908 2909 2910 2911
		/*
		 * The following error isn't really legal.
		 * But we only get here if the client just explicitly
		 * destroyed the client.  Surely it no longer cares what
		 * error it gets back on an operation for the dead
		 * client.
		 */
2912 2913 2914
		goto out;

	status = nfs_ok;
2915
	nfsd4_client_record_create(cstate->session->se_client);
2916 2917
out:
	return status;
2918 2919
}

2920
__be32
2921 2922
nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
		  struct nfsd4_setclientid *setclid)
L
Linus Torvalds 已提交
2923
{
2924
	struct xdr_netobj 	clname = setclid->se_name;
L
Linus Torvalds 已提交
2925
	nfs4_verifier		clverifier = setclid->se_verf;
2926 2927
	struct nfs4_client	*conf, *new;
	struct nfs4_client	*unconf = NULL;
2928
	__be32 			status;
2929 2930
	struct nfsd_net		*nn = net_generic(SVC_NET(rqstp), nfsd_net_id);

2931 2932 2933
	new = create_client(clname, rqstp, &clverifier);
	if (new == NULL)
		return nfserr_jukebox;
2934
	/* Cases below refer to rfc 3530 section 14.2.33: */
2935
	spin_lock(&nn->client_lock);
2936
	conf = find_confirmed_client_by_name(&clname, nn);
2937
	if (conf) {
2938
		/* case 0: */
L
Linus Torvalds 已提交
2939
		status = nfserr_clid_inuse;
2940 2941
		if (clp_used_exchangeid(conf))
			goto out;
2942
		if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)) {
2943 2944 2945 2946 2947
			char addr_str[INET6_ADDRSTRLEN];
			rpc_ntop((struct sockaddr *) &conf->cl_addr, addr_str,
				 sizeof(addr_str));
			dprintk("NFSD: setclientid: string in use by client "
				"at %s\n", addr_str);
L
Linus Torvalds 已提交
2948 2949 2950
			goto out;
		}
	}
2951
	unconf = find_unconfirmed_client_by_name(&clname, nn);
2952
	if (unconf)
2953
		unhash_client_locked(unconf);
2954
	if (conf && same_verf(&conf->cl_verifier, &clverifier))
2955
		/* case 1: probable callback update */
L
Linus Torvalds 已提交
2956
		copy_clid(new, conf);
2957
	else /* case 4 (new client) or cases 2, 3 (client reboot): */
2958
		gen_clid(new, nn);
2959
	new->cl_minorversion = 0;
2960
	gen_callback(new, setclid, rqstp);
2961
	add_to_unconfirmed(new);
L
Linus Torvalds 已提交
2962 2963 2964
	setclid->se_clientid.cl_boot = new->cl_clientid.cl_boot;
	setclid->se_clientid.cl_id = new->cl_clientid.cl_id;
	memcpy(setclid->se_confirm.data, new->cl_confirm.data, sizeof(setclid->se_confirm.data));
2965
	new = NULL;
L
Linus Torvalds 已提交
2966 2967
	status = nfs_ok;
out:
2968
	spin_unlock(&nn->client_lock);
2969 2970
	if (new)
		free_client(new);
2971 2972
	if (unconf)
		expire_client(unconf);
L
Linus Torvalds 已提交
2973 2974 2975 2976
	return status;
}


2977
__be32
2978 2979 2980
nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
			 struct nfsd4_compound_state *cstate,
			 struct nfsd4_setclientid_confirm *setclientid_confirm)
L
Linus Torvalds 已提交
2981
{
2982
	struct nfs4_client *conf, *unconf;
2983
	struct nfs4_client *old = NULL;
L
Linus Torvalds 已提交
2984 2985
	nfs4_verifier confirm = setclientid_confirm->sc_confirm; 
	clientid_t * clid = &setclientid_confirm->sc_clientid;
2986
	__be32 status;
2987
	struct nfsd_net	*nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
L
Linus Torvalds 已提交
2988

2989
	if (STALE_CLIENTID(clid, nn))
L
Linus Torvalds 已提交
2990
		return nfserr_stale_clientid;
2991

2992
	spin_lock(&nn->client_lock);
2993
	conf = find_confirmed_client(clid, false, nn);
2994
	unconf = find_unconfirmed_client(clid, false, nn);
2995
	/*
2996 2997 2998 2999
	 * We try hard to give out unique clientid's, so if we get an
	 * attempt to confirm the same clientid with a different cred,
	 * there's a bug somewhere.  Let's charitably assume it's our
	 * bug.
3000
	 */
3001 3002 3003 3004 3005
	status = nfserr_serverfault;
	if (unconf && !same_creds(&unconf->cl_cred, &rqstp->rq_cred))
		goto out;
	if (conf && !same_creds(&conf->cl_cred, &rqstp->rq_cred))
		goto out;
3006
	/* cases below refer to rfc 3530 section 14.2.34: */
3007 3008
	if (!unconf || !same_verf(&confirm, &unconf->cl_confirm)) {
		if (conf && !unconf) /* case 2: probable retransmit */
L
Linus Torvalds 已提交
3009
			status = nfs_ok;
3010 3011 3012 3013 3014 3015
		else /* case 4: client hasn't noticed we rebooted yet? */
			status = nfserr_stale_clientid;
		goto out;
	}
	status = nfs_ok;
	if (conf) { /* case 1: callback update */
3016 3017
		old = unconf;
		unhash_client_locked(old);
3018
		nfsd4_change_callback(conf, &unconf->cl_cb_conn);
3019
	} else { /* case 3: normal case; new or rebooted client */
3020 3021 3022
		old = find_confirmed_client_by_name(&unconf->cl_name, nn);
		if (old) {
			status = mark_client_expired_locked(old);
3023 3024
			if (status) {
				old = NULL;
3025
				goto out;
3026
			}
3027
		}
3028
		move_to_confirmed(unconf);
3029
		conf = unconf;
3030
	}
3031 3032 3033 3034 3035
	get_client_locked(conf);
	spin_unlock(&nn->client_lock);
	nfsd4_probe_callback(conf);
	spin_lock(&nn->client_lock);
	put_client_renew_locked(conf);
L
Linus Torvalds 已提交
3036
out:
3037 3038 3039
	spin_unlock(&nn->client_lock);
	if (old)
		expire_client(old);
L
Linus Torvalds 已提交
3040 3041 3042
	return status;
}

3043 3044 3045 3046 3047
static struct nfs4_file *nfsd4_alloc_file(void)
{
	return kmem_cache_alloc(file_slab, GFP_KERNEL);
}

L
Linus Torvalds 已提交
3048
/* OPEN Share state helper functions */
3049 3050
static void nfsd4_init_file(struct knfsd_fh *fh, unsigned int hashval,
				struct nfs4_file *fp)
L
Linus Torvalds 已提交
3051
{
3052 3053
	lockdep_assert_held(&state_lock);

3054
	atomic_set(&fp->fi_ref, 1);
3055
	spin_lock_init(&fp->fi_lock);
3056 3057
	INIT_LIST_HEAD(&fp->fi_stateids);
	INIT_LIST_HEAD(&fp->fi_delegations);
3058
	fh_copy_shallow(&fp->fi_fhandle, fh);
3059
	fp->fi_deleg_file = NULL;
3060
	fp->fi_had_conflict = false;
3061
	fp->fi_share_deny = 0;
3062 3063
	memset(fp->fi_fds, 0, sizeof(fp->fi_fds));
	memset(fp->fi_access, 0, sizeof(fp->fi_access));
3064
	hlist_add_head_rcu(&fp->fi_hash, &file_hashtbl[hashval]);
L
Linus Torvalds 已提交
3065 3066
}

3067
void
L
Linus Torvalds 已提交
3068 3069
nfsd4_free_slabs(void)
{
C
Christoph Hellwig 已提交
3070 3071 3072 3073 3074
	kmem_cache_destroy(openowner_slab);
	kmem_cache_destroy(lockowner_slab);
	kmem_cache_destroy(file_slab);
	kmem_cache_destroy(stateid_slab);
	kmem_cache_destroy(deleg_slab);
N
NeilBrown 已提交
3075
}
L
Linus Torvalds 已提交
3076

3077
int
N
NeilBrown 已提交
3078 3079
nfsd4_init_slabs(void)
{
3080 3081 3082
	openowner_slab = kmem_cache_create("nfsd4_openowners",
			sizeof(struct nfs4_openowner), 0, 0, NULL);
	if (openowner_slab == NULL)
C
Christoph Hellwig 已提交
3083
		goto out;
3084
	lockowner_slab = kmem_cache_create("nfsd4_lockowners",
3085
			sizeof(struct nfs4_lockowner), 0, 0, NULL);
3086
	if (lockowner_slab == NULL)
C
Christoph Hellwig 已提交
3087
		goto out_free_openowner_slab;
N
NeilBrown 已提交
3088
	file_slab = kmem_cache_create("nfsd4_files",
3089
			sizeof(struct nfs4_file), 0, 0, NULL);
N
NeilBrown 已提交
3090
	if (file_slab == NULL)
C
Christoph Hellwig 已提交
3091
		goto out_free_lockowner_slab;
N
NeilBrown 已提交
3092
	stateid_slab = kmem_cache_create("nfsd4_stateids",
3093
			sizeof(struct nfs4_ol_stateid), 0, 0, NULL);
N
NeilBrown 已提交
3094
	if (stateid_slab == NULL)
C
Christoph Hellwig 已提交
3095
		goto out_free_file_slab;
N
NeilBrown 已提交
3096
	deleg_slab = kmem_cache_create("nfsd4_delegations",
3097
			sizeof(struct nfs4_delegation), 0, 0, NULL);
N
NeilBrown 已提交
3098
	if (deleg_slab == NULL)
C
Christoph Hellwig 已提交
3099
		goto out_free_stateid_slab;
N
NeilBrown 已提交
3100
	return 0;
C
Christoph Hellwig 已提交
3101 3102 3103 3104 3105 3106 3107 3108 3109 3110

out_free_stateid_slab:
	kmem_cache_destroy(stateid_slab);
out_free_file_slab:
	kmem_cache_destroy(file_slab);
out_free_lockowner_slab:
	kmem_cache_destroy(lockowner_slab);
out_free_openowner_slab:
	kmem_cache_destroy(openowner_slab);
out:
N
NeilBrown 已提交
3111 3112
	dprintk("nfsd4: out of memory while initializing nfsv4\n");
	return -ENOMEM;
L
Linus Torvalds 已提交
3113 3114
}

3115
static void init_nfs4_replay(struct nfs4_replay *rp)
L
Linus Torvalds 已提交
3116
{
3117 3118 3119
	rp->rp_status = nfserr_serverfault;
	rp->rp_buflen = 0;
	rp->rp_buf = rp->rp_ibuf;
3120 3121 3122 3123 3124 3125 3126 3127
	mutex_init(&rp->rp_mutex);
}

static void nfsd4_cstate_assign_replay(struct nfsd4_compound_state *cstate,
		struct nfs4_stateowner *so)
{
	if (!nfsd4_has_session(cstate)) {
		mutex_lock(&so->so_replay.rp_mutex);
3128
		cstate->replay_owner = nfs4_get_stateowner(so);
3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140
	}
}

void nfsd4_cstate_clear_replay(struct nfsd4_compound_state *cstate)
{
	struct nfs4_stateowner *so = cstate->replay_owner;

	if (so != NULL) {
		cstate->replay_owner = NULL;
		mutex_unlock(&so->so_replay.rp_mutex);
		nfs4_put_stateowner(so);
	}
L
Linus Torvalds 已提交
3141 3142
}

3143
static inline void *alloc_stateowner(struct kmem_cache *slab, struct xdr_netobj *owner, struct nfs4_client *clp)
3144
{
L
Linus Torvalds 已提交
3145 3146
	struct nfs4_stateowner *sop;

3147
	sop = kmem_cache_alloc(slab, GFP_KERNEL);
3148 3149 3150 3151 3152
	if (!sop)
		return NULL;

	sop->so_owner.data = kmemdup(owner->data, owner->len, GFP_KERNEL);
	if (!sop->so_owner.data) {
3153
		kmem_cache_free(slab, sop);
L
Linus Torvalds 已提交
3154
		return NULL;
3155 3156 3157
	}
	sop->so_owner.len = owner->len;

3158
	INIT_LIST_HEAD(&sop->so_stateids);
3159 3160
	sop->so_client = clp;
	init_nfs4_replay(&sop->so_replay);
3161
	atomic_set(&sop->so_count, 1);
3162 3163 3164
	return sop;
}

3165
static void hash_openowner(struct nfs4_openowner *oo, struct nfs4_client *clp, unsigned int strhashval)
3166
{
3167
	lockdep_assert_held(&clp->cl_lock);
3168

3169 3170
	list_add(&oo->oo_owner.so_strhash,
		 &clp->cl_ownerstr_hashtbl[strhashval]);
3171
	list_add(&oo->oo_perclient, &clp->cl_openowners);
3172 3173
}

3174 3175
static void nfs4_unhash_openowner(struct nfs4_stateowner *so)
{
3176
	unhash_openowner_locked(openowner(so));
3177 3178
}

3179 3180 3181 3182 3183 3184 3185 3186
static void nfs4_free_openowner(struct nfs4_stateowner *so)
{
	struct nfs4_openowner *oo = openowner(so);

	kmem_cache_free(openowner_slab, oo);
}

static const struct nfs4_stateowner_operations openowner_ops = {
3187 3188
	.so_unhash =	nfs4_unhash_openowner,
	.so_free =	nfs4_free_openowner,
3189 3190
};

3191
static struct nfs4_openowner *
3192
alloc_init_open_stateowner(unsigned int strhashval, struct nfsd4_open *open,
3193 3194
			   struct nfsd4_compound_state *cstate)
{
3195
	struct nfs4_client *clp = cstate->clp;
3196
	struct nfs4_openowner *oo, *ret;
3197

3198 3199
	oo = alloc_stateowner(openowner_slab, &open->op_owner, clp);
	if (!oo)
3200
		return NULL;
3201
	oo->oo_owner.so_ops = &openowner_ops;
3202 3203
	oo->oo_owner.so_is_open_owner = 1;
	oo->oo_owner.so_seqid = open->op_seqid;
3204
	oo->oo_flags = 0;
3205 3206
	if (nfsd4_has_session(cstate))
		oo->oo_flags |= NFS4_OO_CONFIRMED;
3207
	oo->oo_time = 0;
3208
	oo->oo_last_closed_stid = NULL;
3209
	INIT_LIST_HEAD(&oo->oo_close_lru);
3210 3211
	spin_lock(&clp->cl_lock);
	ret = find_openstateowner_str_locked(strhashval, open, clp);
3212 3213 3214 3215 3216
	if (ret == NULL) {
		hash_openowner(oo, clp, strhashval);
		ret = oo;
	} else
		nfs4_free_openowner(&oo->oo_owner);
3217
	spin_unlock(&clp->cl_lock);
3218
	return oo;
L
Linus Torvalds 已提交
3219 3220
}

3221
static void init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp, struct nfsd4_open *open) {
3222
	struct nfs4_openowner *oo = open->op_openowner;
L
Linus Torvalds 已提交
3223

3224
	atomic_inc(&stp->st_stid.sc_count);
J
J. Bruce Fields 已提交
3225
	stp->st_stid.sc_type = NFS4_OPEN_STID;
3226
	INIT_LIST_HEAD(&stp->st_locks);
3227
	stp->st_stateowner = nfs4_get_stateowner(&oo->oo_owner);
3228
	get_nfs4_file(fp);
3229
	stp->st_stid.sc_file = fp;
L
Linus Torvalds 已提交
3230 3231
	stp->st_access_bmap = 0;
	stp->st_deny_bmap = 0;
3232
	stp->st_openstp = NULL;
3233 3234
	spin_lock(&oo->oo_owner.so_client->cl_lock);
	list_add(&stp->st_perstateowner, &oo->oo_owner.so_stateids);
3235 3236 3237
	spin_lock(&fp->fi_lock);
	list_add(&stp->st_perfile, &fp->fi_stateids);
	spin_unlock(&fp->fi_lock);
3238
	spin_unlock(&oo->oo_owner.so_client->cl_lock);
L
Linus Torvalds 已提交
3239 3240
}

3241 3242 3243 3244 3245
/*
 * In the 4.0 case we need to keep the owners around a little while to handle
 * CLOSE replay. We still do need to release any file access that is held by
 * them before returning however.
 */
3246
static void
3247
move_to_close_lru(struct nfs4_ol_stateid *s, struct net *net)
L
Linus Torvalds 已提交
3248
{
3249
	struct nfs4_ol_stateid *last;
3250 3251 3252
	struct nfs4_openowner *oo = openowner(s->st_stateowner);
	struct nfsd_net *nn = net_generic(s->st_stid.sc_client->net,
						nfsd_net_id);
3253

3254
	dprintk("NFSD: move_to_close_lru nfs4_openowner %p\n", oo);
L
Linus Torvalds 已提交
3255

3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266
	/*
	 * We know that we hold one reference via nfsd4_close, and another
	 * "persistent" reference for the client. If the refcount is higher
	 * than 2, then there are still calls in progress that are using this
	 * stateid. We can't put the sc_file reference until they are finished.
	 * Wait for the refcount to drop to 2. Since it has been unhashed,
	 * there should be no danger of the refcount going back up again at
	 * this point.
	 */
	wait_event(close_wq, atomic_read(&s->st_stid.sc_count) == 2);

3267 3268 3269 3270 3271
	release_all_access(s);
	if (s->st_stid.sc_file) {
		put_nfs4_file(s->st_stid.sc_file);
		s->st_stid.sc_file = NULL;
	}
3272 3273 3274

	spin_lock(&nn->client_lock);
	last = oo->oo_last_closed_stid;
3275
	oo->oo_last_closed_stid = s;
3276
	list_move_tail(&oo->oo_close_lru, &nn->close_lru);
3277
	oo->oo_time = get_seconds();
3278 3279 3280
	spin_unlock(&nn->client_lock);
	if (last)
		nfs4_put_stid(&last->st_stid);
L
Linus Torvalds 已提交
3281 3282 3283 3284
}

/* search file_hashtbl[] for file */
static struct nfs4_file *
3285
find_file_locked(struct knfsd_fh *fh, unsigned int hashval)
L
Linus Torvalds 已提交
3286 3287 3288
{
	struct nfs4_file *fp;

3289
	hlist_for_each_entry_rcu(fp, &file_hashtbl[hashval], fi_hash) {
3290
		if (fh_match(&fp->fi_fhandle, fh)) {
3291 3292
			if (atomic_inc_not_zero(&fp->fi_ref))
				return fp;
3293
		}
L
Linus Torvalds 已提交
3294 3295 3296 3297
	}
	return NULL;
}

3298
static struct nfs4_file *
3299
find_file(struct knfsd_fh *fh)
3300 3301
{
	struct nfs4_file *fp;
3302
	unsigned int hashval = file_hashval(fh);
3303

3304 3305 3306
	rcu_read_lock();
	fp = find_file_locked(fh, hashval);
	rcu_read_unlock();
3307 3308 3309 3310
	return fp;
}

static struct nfs4_file *
3311
find_or_add_file(struct nfs4_file *new, struct knfsd_fh *fh)
3312 3313
{
	struct nfs4_file *fp;
3314 3315 3316 3317 3318 3319 3320
	unsigned int hashval = file_hashval(fh);

	rcu_read_lock();
	fp = find_file_locked(fh, hashval);
	rcu_read_unlock();
	if (fp)
		return fp;
3321 3322

	spin_lock(&state_lock);
3323 3324 3325
	fp = find_file_locked(fh, hashval);
	if (likely(fp == NULL)) {
		nfsd4_init_file(fh, hashval, new);
3326 3327 3328 3329 3330 3331 3332
		fp = new;
	}
	spin_unlock(&state_lock);

	return fp;
}

L
Linus Torvalds 已提交
3333 3334 3335 3336
/*
 * Called to check deny when READ with all zero stateid or
 * WRITE with all zero or all one stateid
 */
3337
static __be32
L
Linus Torvalds 已提交
3338 3339 3340
nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type)
{
	struct nfs4_file *fp;
3341
	__be32 ret = nfs_ok;
L
Linus Torvalds 已提交
3342

3343
	fp = find_file(&current_fh->fh_handle);
3344
	if (!fp)
3345 3346
		return ret;
	/* Check for conflicting share reservations */
3347
	spin_lock(&fp->fi_lock);
3348 3349
	if (fp->fi_share_deny & deny_type)
		ret = nfserr_locked;
3350
	spin_unlock(&fp->fi_lock);
3351 3352
	put_nfs4_file(fp);
	return ret;
L
Linus Torvalds 已提交
3353 3354
}

3355
static void nfsd4_cb_recall_prepare(struct nfsd4_callback *cb)
L
Linus Torvalds 已提交
3356
{
3357
	struct nfs4_delegation *dp = cb_to_delegation(cb);
3358 3359
	struct nfsd_net *nn = net_generic(dp->dl_stid.sc_client->net,
					  nfsd_net_id);
3360

3361
	block_delegations(&dp->dl_stid.sc_file->fi_fhandle);
3362

3363
	/*
3364 3365 3366
	 * We can't do this in nfsd_break_deleg_cb because it is
	 * already holding inode->i_lock.
	 *
3367 3368 3369
	 * If the dl_time != 0, then we know that it has already been
	 * queued for a lease break. Don't queue it again.
	 */
3370
	spin_lock(&state_lock);
3371 3372
	if (dp->dl_time == 0) {
		dp->dl_time = get_seconds();
3373
		list_add_tail(&dp->dl_recall_lru, &nn->del_recall_lru);
3374
	}
3375 3376
	spin_unlock(&state_lock);
}
L
Linus Torvalds 已提交
3377

3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414
static int nfsd4_cb_recall_done(struct nfsd4_callback *cb,
		struct rpc_task *task)
{
	struct nfs4_delegation *dp = cb_to_delegation(cb);

	switch (task->tk_status) {
	case 0:
		return 1;
	case -EBADHANDLE:
	case -NFS4ERR_BAD_STATEID:
		/*
		 * Race: client probably got cb_recall before open reply
		 * granting delegation.
		 */
		if (dp->dl_retries--) {
			rpc_delay(task, 2 * HZ);
			return 0;
		}
		/*FALLTHRU*/
	default:
		return -1;
	}
}

static void nfsd4_cb_recall_release(struct nfsd4_callback *cb)
{
	struct nfs4_delegation *dp = cb_to_delegation(cb);

	nfs4_put_stid(&dp->dl_stid);
}

static struct nfsd4_callback_ops nfsd4_cb_recall_ops = {
	.prepare	= nfsd4_cb_recall_prepare,
	.done		= nfsd4_cb_recall_done,
	.release	= nfsd4_cb_recall_release,
};

3415 3416 3417 3418 3419 3420 3421 3422 3423
static void nfsd_break_one_deleg(struct nfs4_delegation *dp)
{
	/*
	 * We're assuming the state code never drops its reference
	 * without first removing the lease.  Since we're in this lease
	 * callback (and since the lease code is serialized by the kernel
	 * lock) we know the server hasn't removed the lease yet, we know
	 * it's safe to take a reference.
	 */
3424
	atomic_inc(&dp->dl_stid.sc_count);
3425
	nfsd4_run_cb(&dp->dl_recall);
3426 3427
}

3428
/* Called from break_lease() with i_lock held. */
J
Jeff Layton 已提交
3429 3430
static bool
nfsd_break_deleg_cb(struct file_lock *fl)
3431
{
J
Jeff Layton 已提交
3432
	bool ret = false;
3433 3434
	struct nfs4_file *fp = (struct nfs4_file *)fl->fl_owner;
	struct nfs4_delegation *dp;
3435

3436 3437
	if (!fp) {
		WARN(1, "(%p)->fl_owner NULL\n", fl);
J
Jeff Layton 已提交
3438
		return ret;
3439 3440 3441
	}
	if (fp->fi_had_conflict) {
		WARN(1, "duplicate break on %p\n", fp);
J
Jeff Layton 已提交
3442
		return ret;
3443
	}
3444 3445
	/*
	 * We don't want the locks code to timeout the lease for us;
3446
	 * we'll remove it ourself if a delegation isn't returned
3447
	 * in time:
3448 3449
	 */
	fl->fl_break_time = 0;
L
Linus Torvalds 已提交
3450

3451
	spin_lock(&fp->fi_lock);
3452 3453
	fp->fi_had_conflict = true;
	/*
J
Jeff Layton 已提交
3454 3455
	 * If there are no delegations on the list, then return true
	 * so that the lease code will go ahead and delete it.
3456 3457
	 */
	if (list_empty(&fp->fi_delegations))
J
Jeff Layton 已提交
3458
		ret = true;
3459 3460 3461
	else
		list_for_each_entry(dp, &fp->fi_delegations, dl_perfile)
			nfsd_break_one_deleg(dp);
3462
	spin_unlock(&fp->fi_lock);
J
Jeff Layton 已提交
3463
	return ret;
L
Linus Torvalds 已提交
3464 3465
}

3466
static int
3467 3468
nfsd_change_deleg_cb(struct file_lock *onlist, int arg,
		     struct list_head *dispose)
L
Linus Torvalds 已提交
3469 3470
{
	if (arg & F_UNLCK)
3471
		return lease_modify(onlist, arg, dispose);
L
Linus Torvalds 已提交
3472 3473 3474 3475
	else
		return -EAGAIN;
}

3476
static const struct lock_manager_operations nfsd_lease_mng_ops = {
J
J. Bruce Fields 已提交
3477 3478
	.lm_break = nfsd_break_deleg_cb,
	.lm_change = nfsd_change_deleg_cb,
L
Linus Torvalds 已提交
3479 3480
};

3481 3482 3483 3484 3485 3486 3487 3488 3489 3490
static __be32 nfsd4_check_seqid(struct nfsd4_compound_state *cstate, struct nfs4_stateowner *so, u32 seqid)
{
	if (nfsd4_has_session(cstate))
		return nfs_ok;
	if (seqid == so->so_seqid - 1)
		return nfserr_replay_me;
	if (seqid == so->so_seqid)
		return nfs_ok;
	return nfserr_bad_seqid;
}
L
Linus Torvalds 已提交
3491

3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513
static __be32 lookup_clientid(clientid_t *clid,
		struct nfsd4_compound_state *cstate,
		struct nfsd_net *nn)
{
	struct nfs4_client *found;

	if (cstate->clp) {
		found = cstate->clp;
		if (!same_clid(&found->cl_clientid, clid))
			return nfserr_stale_clientid;
		return nfs_ok;
	}

	if (STALE_CLIENTID(clid, nn))
		return nfserr_stale_clientid;

	/*
	 * For v4.1+ we get the client in the SEQUENCE op. If we don't have one
	 * cached already then we know this is for is for v4.0 and "sessions"
	 * will be false.
	 */
	WARN_ON_ONCE(cstate->session);
3514
	spin_lock(&nn->client_lock);
3515
	found = find_confirmed_client(clid, false, nn);
3516 3517
	if (!found) {
		spin_unlock(&nn->client_lock);
3518
		return nfserr_expired;
3519 3520 3521
	}
	atomic_inc(&found->cl_refcount);
	spin_unlock(&nn->client_lock);
3522 3523 3524 3525 3526 3527

	/* Cache the nfs4_client in cstate! */
	cstate->clp = found;
	return nfs_ok;
}

3528
__be32
A
Andy Adamson 已提交
3529
nfsd4_process_open1(struct nfsd4_compound_state *cstate,
3530
		    struct nfsd4_open *open, struct nfsd_net *nn)
L
Linus Torvalds 已提交
3531 3532 3533 3534
{
	clientid_t *clientid = &open->op_clientid;
	struct nfs4_client *clp = NULL;
	unsigned int strhashval;
3535
	struct nfs4_openowner *oo = NULL;
3536
	__be32 status;
L
Linus Torvalds 已提交
3537

3538
	if (STALE_CLIENTID(&open->op_clientid, nn))
L
Linus Torvalds 已提交
3539
		return nfserr_stale_clientid;
3540 3541 3542 3543 3544 3545 3546
	/*
	 * In case we need it later, after we've already created the
	 * file and don't want to risk a further failure:
	 */
	open->op_file = nfsd4_alloc_file();
	if (open->op_file == NULL)
		return nfserr_jukebox;
L
Linus Torvalds 已提交
3547

3548 3549 3550 3551 3552
	status = lookup_clientid(clientid, cstate, nn);
	if (status)
		return status;
	clp = cstate->clp;

3553 3554
	strhashval = ownerstr_hashval(&open->op_owner);
	oo = find_openstateowner_str(strhashval, open, clp);
3555 3556
	open->op_openowner = oo;
	if (!oo) {
3557
		goto new_owner;
L
Linus Torvalds 已提交
3558
	}
3559
	if (!(oo->oo_flags & NFS4_OO_CONFIRMED)) {
3560
		/* Replace unconfirmed owners without checking for replay. */
3561 3562
		release_openowner(oo);
		open->op_openowner = NULL;
3563
		goto new_owner;
3564
	}
3565 3566 3567 3568
	status = nfsd4_check_seqid(cstate, &oo->oo_owner, open->op_seqid);
	if (status)
		return status;
	goto alloc_stateid;
3569
new_owner:
3570
	oo = alloc_init_open_stateowner(strhashval, open, cstate);
3571 3572 3573
	if (oo == NULL)
		return nfserr_jukebox;
	open->op_openowner = oo;
3574
alloc_stateid:
3575
	open->op_stp = nfs4_alloc_open_stateid(clp);
3576 3577
	if (!open->op_stp)
		return nfserr_jukebox;
3578
	return nfs_ok;
L
Linus Torvalds 已提交
3579 3580
}

3581
static inline __be32
N
NeilBrown 已提交
3582 3583 3584 3585 3586 3587 3588 3589
nfs4_check_delegmode(struct nfs4_delegation *dp, int flags)
{
	if ((flags & WR_STATE) && (dp->dl_type == NFS4_OPEN_DELEGATE_READ))
		return nfserr_openmode;
	else
		return nfs_ok;
}

3590
static int share_access_to_flags(u32 share_access)
3591
{
3592
	return share_access == NFS4_SHARE_ACCESS_READ ? RD_STATE : WR_STATE;
3593 3594
}

3595
static struct nfs4_delegation *find_deleg_stateid(struct nfs4_client *cl, stateid_t *s)
3596
{
3597
	struct nfs4_stid *ret;
3598

3599
	ret = find_stateid_by_type(cl, s, NFS4_DELEG_STID);
3600 3601 3602
	if (!ret)
		return NULL;
	return delegstateid(ret);
3603 3604
}

3605 3606 3607 3608 3609 3610
static bool nfsd4_is_deleg_cur(struct nfsd4_open *open)
{
	return open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR ||
	       open->op_claim_type == NFS4_OPEN_CLAIM_DELEG_CUR_FH;
}

3611
static __be32
3612
nfs4_check_deleg(struct nfs4_client *cl, struct nfsd4_open *open,
3613 3614 3615
		struct nfs4_delegation **dp)
{
	int flags;
3616
	__be32 status = nfserr_bad_stateid;
3617
	struct nfs4_delegation *deleg;
3618

3619 3620
	deleg = find_deleg_stateid(cl, &open->op_delegate_stateid);
	if (deleg == NULL)
3621
		goto out;
3622
	flags = share_access_to_flags(open->op_share_access);
3623 3624 3625 3626 3627 3628
	status = nfs4_check_delegmode(deleg, flags);
	if (status) {
		nfs4_put_stid(&deleg->dl_stid);
		goto out;
	}
	*dp = deleg;
3629
out:
3630
	if (!nfsd4_is_deleg_cur(open))
3631 3632 3633
		return nfs_ok;
	if (status)
		return status;
3634
	open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
3635
	return nfs_ok;
3636 3637
}

3638 3639
static struct nfs4_ol_stateid *
nfsd4_find_existing_open(struct nfs4_file *fp, struct nfsd4_open *open)
L
Linus Torvalds 已提交
3640
{
3641
	struct nfs4_ol_stateid *local, *ret = NULL;
3642
	struct nfs4_openowner *oo = open->op_openowner;
L
Linus Torvalds 已提交
3643

3644
	spin_lock(&fp->fi_lock);
3645
	list_for_each_entry(local, &fp->fi_stateids, st_perfile) {
L
Linus Torvalds 已提交
3646 3647 3648
		/* ignore lock owners */
		if (local->st_stateowner->so_is_open_owner == 0)
			continue;
3649
		if (local->st_stateowner == &oo->oo_owner) {
3650
			ret = local;
3651
			atomic_inc(&ret->st_stid.sc_count);
3652
			break;
3653
		}
L
Linus Torvalds 已提交
3654
	}
3655
	spin_unlock(&fp->fi_lock);
3656
	return ret;
L
Linus Torvalds 已提交
3657 3658
}

3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669
static inline int nfs4_access_to_access(u32 nfs4_access)
{
	int flags = 0;

	if (nfs4_access & NFS4_SHARE_ACCESS_READ)
		flags |= NFSD_MAY_READ;
	if (nfs4_access & NFS4_SHARE_ACCESS_WRITE)
		flags |= NFSD_MAY_WRITE;
	return flags;
}

3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684
static inline __be32
nfsd4_truncate(struct svc_rqst *rqstp, struct svc_fh *fh,
		struct nfsd4_open *open)
{
	struct iattr iattr = {
		.ia_valid = ATTR_SIZE,
		.ia_size = 0,
	};
	if (!open->op_truncate)
		return 0;
	if (!(open->op_share_access & NFS4_SHARE_ACCESS_WRITE))
		return nfserr_inval;
	return nfsd_setattr(rqstp, fh, &iattr, 0, (time_t)0);
}

3685
static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file *fp,
3686 3687
		struct svc_fh *cur_fh, struct nfs4_ol_stateid *stp,
		struct nfsd4_open *open)
3688
{
3689
	struct file *filp = NULL;
3690
	__be32 status;
3691 3692
	int oflag = nfs4_access_to_omode(open->op_share_access);
	int access = nfs4_access_to_access(open->op_share_access);
3693
	unsigned char old_access_bmap, old_deny_bmap;
3694

3695
	spin_lock(&fp->fi_lock);
3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722

	/*
	 * Are we trying to set a deny mode that would conflict with
	 * current access?
	 */
	status = nfs4_file_check_deny(fp, open->op_share_deny);
	if (status != nfs_ok) {
		spin_unlock(&fp->fi_lock);
		goto out;
	}

	/* set access to the file */
	status = nfs4_file_get_access(fp, open->op_share_access);
	if (status != nfs_ok) {
		spin_unlock(&fp->fi_lock);
		goto out;
	}

	/* Set access bits in stateid */
	old_access_bmap = stp->st_access_bmap;
	set_access(open->op_share_access, stp);

	/* Set new deny mask */
	old_deny_bmap = stp->st_deny_bmap;
	set_deny(open->op_share_deny, stp);
	fp->fi_share_deny |= (open->op_share_deny & NFS4_SHARE_DENY_BOTH);

3723
	if (!fp->fi_fds[oflag]) {
3724 3725
		spin_unlock(&fp->fi_lock);
		status = nfsd_open(rqstp, cur_fh, S_IFREG, access, &filp);
3726
		if (status)
3727
			goto out_put_access;
3728 3729 3730 3731 3732
		spin_lock(&fp->fi_lock);
		if (!fp->fi_fds[oflag]) {
			fp->fi_fds[oflag] = filp;
			filp = NULL;
		}
3733
	}
3734 3735 3736
	spin_unlock(&fp->fi_lock);
	if (filp)
		fput(filp);
3737

3738 3739 3740 3741 3742
	status = nfsd4_truncate(rqstp, cur_fh, open);
	if (status)
		goto out_put_access;
out:
	return status;
3743 3744 3745 3746 3747
out_put_access:
	stp->st_access_bmap = old_access_bmap;
	nfs4_file_put_access(fp, open->op_share_access);
	reset_union_bmap_deny(bmap_to_share_mode(old_deny_bmap), stp);
	goto out;
L
Linus Torvalds 已提交
3748 3749
}

3750
static __be32
3751
nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *cur_fh, struct nfs4_ol_stateid *stp, struct nfsd4_open *open)
L
Linus Torvalds 已提交
3752
{
3753
	__be32 status;
3754
	unsigned char old_deny_bmap;
L
Linus Torvalds 已提交
3755

3756
	if (!test_access(open->op_share_access, stp))
3757
		return nfs4_get_vfs_file(rqstp, fp, cur_fh, stp, open);
3758

3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770
	/* test and set deny mode */
	spin_lock(&fp->fi_lock);
	status = nfs4_file_check_deny(fp, open->op_share_deny);
	if (status == nfs_ok) {
		old_deny_bmap = stp->st_deny_bmap;
		set_deny(open->op_share_deny, stp);
		fp->fi_share_deny |=
				(open->op_share_deny & NFS4_SHARE_DENY_BOTH);
	}
	spin_unlock(&fp->fi_lock);

	if (status != nfs_ok)
L
Linus Torvalds 已提交
3771 3772
		return status;

3773 3774 3775 3776 3777
	status = nfsd4_truncate(rqstp, cur_fh, open);
	if (status != nfs_ok)
		reset_union_bmap_deny(old_deny_bmap, stp);
	return status;
}
L
Linus Torvalds 已提交
3778 3779

static void
3780
nfs4_set_claim_prev(struct nfsd4_open *open, bool has_session)
L
Linus Torvalds 已提交
3781
{
3782
	open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
L
Linus Torvalds 已提交
3783 3784
}

3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797
/* Should we give out recallable state?: */
static bool nfsd4_cb_channel_good(struct nfs4_client *clp)
{
	if (clp->cl_cb_state == NFSD4_CB_UP)
		return true;
	/*
	 * In the sessions case, since we don't have to establish a
	 * separate connection for callbacks, we assume it's OK
	 * until we hear otherwise:
	 */
	return clp->cl_minorversion && clp->cl_cb_state == NFSD4_CB_UNKNOWN;
}

3798
static struct file_lock *nfs4_alloc_init_lease(struct nfs4_file *fp, int flag)
3799 3800 3801 3802 3803 3804 3805
{
	struct file_lock *fl;

	fl = locks_alloc_lock();
	if (!fl)
		return NULL;
	fl->fl_lmops = &nfsd_lease_mng_ops;
3806
	fl->fl_flags = FL_DELEG;
3807 3808
	fl->fl_type = flag == NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_WRLCK;
	fl->fl_end = OFFSET_MAX;
3809
	fl->fl_owner = (fl_owner_t)fp;
3810 3811 3812 3813
	fl->fl_pid = current->tgid;
	return fl;
}

3814
static int nfs4_setlease(struct nfs4_delegation *dp)
3815
{
3816
	struct nfs4_file *fp = dp->dl_stid.sc_file;
3817
	struct file_lock *fl, *ret;
3818 3819
	struct file *filp;
	int status = 0;
3820

3821
	fl = nfs4_alloc_init_lease(fp, NFS4_OPEN_DELEGATE_READ);
3822 3823
	if (!fl)
		return -ENOMEM;
3824 3825 3826 3827 3828 3829 3830
	filp = find_readable_file(fp);
	if (!filp) {
		/* We should always have a readable file here */
		WARN_ON_ONCE(1);
		return -EBADF;
	}
	fl->fl_file = filp;
3831
	ret = fl;
3832
	status = vfs_setlease(filp, fl->fl_type, &fl, NULL);
3833
	if (fl)
3834
		locks_free_lock(fl);
3835
	if (status)
3836 3837 3838 3839 3840 3841 3842 3843
		goto out_fput;
	spin_lock(&state_lock);
	spin_lock(&fp->fi_lock);
	/* Did the lease get broken before we took the lock? */
	status = -EAGAIN;
	if (fp->fi_had_conflict)
		goto out_unlock;
	/* Race breaker */
3844
	if (fp->fi_deleg_file) {
3845
		status = 0;
3846
		++fp->fi_delegees;
3847 3848 3849 3850
		hash_delegation_locked(dp, fp);
		goto out_unlock;
	}
	fp->fi_deleg_file = filp;
3851
	fp->fi_delegees = 1;
3852
	hash_delegation_locked(dp, fp);
3853
	spin_unlock(&fp->fi_lock);
3854
	spin_unlock(&state_lock);
3855
	return 0;
3856 3857 3858 3859 3860
out_unlock:
	spin_unlock(&fp->fi_lock);
	spin_unlock(&state_lock);
out_fput:
	fput(filp);
3861
	return status;
3862 3863
}

J
Jeff Layton 已提交
3864 3865 3866
static struct nfs4_delegation *
nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh,
		    struct nfs4_file *fp)
3867
{
J
Jeff Layton 已提交
3868 3869
	int status;
	struct nfs4_delegation *dp;
3870

3871
	if (fp->fi_had_conflict)
J
Jeff Layton 已提交
3872 3873 3874 3875 3876 3877
		return ERR_PTR(-EAGAIN);

	dp = alloc_init_deleg(clp, fh);
	if (!dp)
		return ERR_PTR(-ENOMEM);

3878
	get_nfs4_file(fp);
3879 3880
	spin_lock(&state_lock);
	spin_lock(&fp->fi_lock);
3881
	dp->dl_stid.sc_file = fp;
3882
	if (!fp->fi_deleg_file) {
3883 3884
		spin_unlock(&fp->fi_lock);
		spin_unlock(&state_lock);
J
Jeff Layton 已提交
3885 3886
		status = nfs4_setlease(dp);
		goto out;
3887
	}
3888
	if (fp->fi_had_conflict) {
3889 3890
		status = -EAGAIN;
		goto out_unlock;
3891
	}
3892
	++fp->fi_delegees;
3893
	hash_delegation_locked(dp, fp);
J
Jeff Layton 已提交
3894
	status = 0;
3895 3896
out_unlock:
	spin_unlock(&fp->fi_lock);
3897
	spin_unlock(&state_lock);
J
Jeff Layton 已提交
3898 3899
out:
	if (status) {
3900
		nfs4_put_stid(&dp->dl_stid);
J
Jeff Layton 已提交
3901 3902 3903
		return ERR_PTR(status);
	}
	return dp;
3904 3905
}

3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921
static void nfsd4_open_deleg_none_ext(struct nfsd4_open *open, int status)
{
	open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE_EXT;
	if (status == -EAGAIN)
		open->op_why_no_deleg = WND4_CONTENTION;
	else {
		open->op_why_no_deleg = WND4_RESOURCE;
		switch (open->op_deleg_want) {
		case NFS4_SHARE_WANT_READ_DELEG:
		case NFS4_SHARE_WANT_WRITE_DELEG:
		case NFS4_SHARE_WANT_ANY_DELEG:
			break;
		case NFS4_SHARE_WANT_CANCEL:
			open->op_why_no_deleg = WND4_CANCELLED;
			break;
		case NFS4_SHARE_WANT_NO_DELEG:
3922
			WARN_ON_ONCE(1);
3923 3924 3925 3926
		}
	}
}

L
Linus Torvalds 已提交
3927 3928
/*
 * Attempt to hand out a delegation.
3929 3930 3931
 *
 * Note we don't support write delegations, and won't until the vfs has
 * proper support for them.
L
Linus Torvalds 已提交
3932 3933
 */
static void
3934 3935
nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open,
			struct nfs4_ol_stateid *stp)
L
Linus Torvalds 已提交
3936 3937
{
	struct nfs4_delegation *dp;
3938 3939
	struct nfs4_openowner *oo = openowner(stp->st_stateowner);
	struct nfs4_client *clp = stp->st_stid.sc_client;
3940
	int cb_up;
3941
	int status = 0;
L
Linus Torvalds 已提交
3942

3943
	cb_up = nfsd4_cb_channel_good(oo->oo_owner.so_client);
3944 3945 3946
	open->op_recall = 0;
	switch (open->op_claim_type) {
		case NFS4_OPEN_CLAIM_PREVIOUS:
3947
			if (!cb_up)
3948
				open->op_recall = 1;
3949 3950
			if (open->op_delegate_type != NFS4_OPEN_DELEGATE_READ)
				goto out_no_deleg;
3951 3952
			break;
		case NFS4_OPEN_CLAIM_NULL:
3953
		case NFS4_OPEN_CLAIM_FH:
3954 3955 3956 3957
			/*
			 * Let's not give out any delegations till everyone's
			 * had the chance to reclaim theirs....
			 */
3958
			if (locks_in_grace(clp->net))
3959
				goto out_no_deleg;
3960
			if (!cb_up || !(oo->oo_flags & NFS4_OO_CONFIRMED))
3961
				goto out_no_deleg;
3962 3963 3964 3965 3966 3967 3968
			/*
			 * Also, if the file was opened for write or
			 * create, there's a good chance the client's
			 * about to write to it, resulting in an
			 * immediate recall (since we don't support
			 * write delegations):
			 */
3969
			if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
3970 3971 3972
				goto out_no_deleg;
			if (open->op_create == NFS4_OPEN_CREATE)
				goto out_no_deleg;
3973 3974
			break;
		default:
3975
			goto out_no_deleg;
3976
	}
3977
	dp = nfs4_set_delegation(clp, fh, stp->st_stid.sc_file);
J
Jeff Layton 已提交
3978
	if (IS_ERR(dp))
3979
		goto out_no_deleg;
L
Linus Torvalds 已提交
3980

3981
	memcpy(&open->op_delegate_stateid, &dp->dl_stid.sc_stateid, sizeof(dp->dl_stid.sc_stateid));
L
Linus Torvalds 已提交
3982

3983
	dprintk("NFSD: delegation stateid=" STATEID_FMT "\n",
3984
		STATEID_VAL(&dp->dl_stid.sc_stateid));
3985
	open->op_delegate_type = NFS4_OPEN_DELEGATE_READ;
3986
	nfs4_put_stid(&dp->dl_stid);
3987 3988
	return;
out_no_deleg:
3989 3990
	open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE;
	if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS &&
3991
	    open->op_delegate_type != NFS4_OPEN_DELEGATE_NONE) {
3992
		dprintk("NFSD: WARNING: refusing delegation reclaim\n");
3993 3994
		open->op_recall = 1;
	}
3995 3996 3997 3998 3999

	/* 4.1 client asking for a delegation? */
	if (open->op_deleg_want)
		nfsd4_open_deleg_none_ext(open, status);
	return;
L
Linus Torvalds 已提交
4000 4001
}

4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019
static void nfsd4_deleg_xgrade_none_ext(struct nfsd4_open *open,
					struct nfs4_delegation *dp)
{
	if (open->op_deleg_want == NFS4_SHARE_WANT_READ_DELEG &&
	    dp->dl_type == NFS4_OPEN_DELEGATE_WRITE) {
		open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE_EXT;
		open->op_why_no_deleg = WND4_NOT_SUPP_DOWNGRADE;
	} else if (open->op_deleg_want == NFS4_SHARE_WANT_WRITE_DELEG &&
		   dp->dl_type == NFS4_OPEN_DELEGATE_WRITE) {
		open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE_EXT;
		open->op_why_no_deleg = WND4_NOT_SUPP_UPGRADE;
	}
	/* Otherwise the client must be confused wanting a delegation
	 * it already has, therefore we don't return
	 * NFS4_OPEN_DELEGATE_NONE_EXT and reason.
	 */
}

4020
__be32
L
Linus Torvalds 已提交
4021 4022
nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
{
A
Andy Adamson 已提交
4023
	struct nfsd4_compoundres *resp = rqstp->rq_resp;
4024
	struct nfs4_client *cl = open->op_openowner->oo_owner.so_client;
L
Linus Torvalds 已提交
4025
	struct nfs4_file *fp = NULL;
4026
	struct nfs4_ol_stateid *stp = NULL;
4027
	struct nfs4_delegation *dp = NULL;
4028
	__be32 status;
L
Linus Torvalds 已提交
4029 4030 4031 4032 4033 4034

	/*
	 * Lookup file; if found, lookup stateid and check open request,
	 * and check for delegations in the process of being recalled.
	 * If not found, create the nfs4_file struct
	 */
4035
	fp = find_or_add_file(open->op_file, &current_fh->fh_handle);
4036
	if (fp != open->op_file) {
4037
		status = nfs4_check_deleg(cl, open, &dp);
4038 4039
		if (status)
			goto out;
4040
		stp = nfsd4_find_existing_open(fp, open);
L
Linus Torvalds 已提交
4041
	} else {
4042
		open->op_file = NULL;
4043
		status = nfserr_bad_stateid;
4044
		if (nfsd4_is_deleg_cur(open))
4045
			goto out;
4046
		status = nfserr_jukebox;
L
Linus Torvalds 已提交
4047 4048 4049 4050 4051 4052 4053 4054
	}

	/*
	 * OPEN the file, or upgrade an existing OPEN.
	 * If truncate fails, the OPEN fails.
	 */
	if (stp) {
		/* Stateid was found, this is an OPEN upgrade */
4055
		status = nfs4_upgrade_open(rqstp, fp, current_fh, stp, open);
L
Linus Torvalds 已提交
4056 4057 4058
		if (status)
			goto out;
	} else {
4059 4060
		stp = open->op_stp;
		open->op_stp = NULL;
4061
		init_open_stateid(stp, fp, open);
4062 4063 4064 4065 4066
		status = nfs4_get_vfs_file(rqstp, fp, current_fh, stp, open);
		if (status) {
			release_open_stateid(stp);
			goto out;
		}
L
Linus Torvalds 已提交
4067
	}
4068 4069
	update_stateid(&stp->st_stid.sc_stateid);
	memcpy(&open->op_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
L
Linus Torvalds 已提交
4070

4071 4072 4073 4074 4075 4076 4077 4078
	if (nfsd4_has_session(&resp->cstate)) {
		if (open->op_deleg_want & NFS4_SHARE_WANT_NO_DELEG) {
			open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE_EXT;
			open->op_why_no_deleg = WND4_NOT_WANTED;
			goto nodeleg;
		}
	}

L
Linus Torvalds 已提交
4079 4080 4081 4082
	/*
	* Attempt to hand out a delegation. No error return, because the
	* OPEN succeeds even if we fail.
	*/
4083
	nfs4_open_delegation(current_fh, open, stp);
4084
nodeleg:
L
Linus Torvalds 已提交
4085 4086
	status = nfs_ok;

4087
	dprintk("%s: stateid=" STATEID_FMT "\n", __func__,
4088
		STATEID_VAL(&stp->st_stid.sc_stateid));
L
Linus Torvalds 已提交
4089
out:
4090 4091
	/* 4.1 client trying to upgrade/downgrade delegation? */
	if (open->op_delegate_type == NFS4_OPEN_DELEGATE_NONE && dp &&
4092 4093
	    open->op_deleg_want)
		nfsd4_deleg_xgrade_none_ext(open, dp);
4094

4095 4096
	if (fp)
		put_nfs4_file(fp);
4097
	if (status == 0 && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
4098
		nfs4_set_claim_prev(open, nfsd4_has_session(&resp->cstate));
L
Linus Torvalds 已提交
4099 4100 4101 4102
	/*
	* To finish the open response, we just need to set the rflags.
	*/
	open->op_rflags = NFS4_OPEN_RESULT_LOCKTYPE_POSIX;
4103
	if (!(open->op_openowner->oo_flags & NFS4_OO_CONFIRMED) &&
A
Andy Adamson 已提交
4104
	    !nfsd4_has_session(&resp->cstate))
L
Linus Torvalds 已提交
4105
		open->op_rflags |= NFS4_OPEN_RESULT_CONFIRM;
4106 4107
	if (dp)
		nfs4_put_stid(&dp->dl_stid);
4108 4109
	if (stp)
		nfs4_put_stid(&stp->st_stid);
L
Linus Torvalds 已提交
4110 4111 4112 4113

	return status;
}

4114 4115
void nfsd4_cleanup_open_state(struct nfsd4_compound_state *cstate,
			      struct nfsd4_open *open, __be32 status)
4116 4117
{
	if (open->op_openowner) {
4118 4119 4120 4121
		struct nfs4_stateowner *so = &open->op_openowner->oo_owner;

		nfsd4_cstate_assign_replay(cstate, so);
		nfs4_put_stateowner(so);
4122
	}
4123
	if (open->op_file)
4124
		kmem_cache_free(file_slab, open->op_file);
4125
	if (open->op_stp)
4126
		nfs4_put_stid(&open->op_stp->st_stid);
4127 4128
}

4129
__be32
4130 4131
nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	    clientid_t *clid)
L
Linus Torvalds 已提交
4132 4133
{
	struct nfs4_client *clp;
4134
	__be32 status;
4135
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
L
Linus Torvalds 已提交
4136 4137 4138

	dprintk("process_renew(%08x/%08x): starting\n", 
			clid->cl_boot, clid->cl_id);
4139
	status = lookup_clientid(clid, cstate, nn);
4140
	if (status)
L
Linus Torvalds 已提交
4141
		goto out;
4142
	clp = cstate->clp;
L
Linus Torvalds 已提交
4143
	status = nfserr_cb_path_down;
4144
	if (!list_empty(&clp->cl_delegations)
4145
			&& clp->cl_cb_state != NFSD4_CB_UP)
L
Linus Torvalds 已提交
4146 4147 4148 4149 4150 4151
		goto out;
	status = nfs_ok;
out:
	return status;
}

4152
void
4153
nfsd4_end_grace(struct nfsd_net *nn)
4154
{
4155
	/* do nothing if grace period already ended */
4156
	if (nn->grace_ended)
4157 4158
		return;

4159
	dprintk("NFSD: end of grace period\n");
4160
	nn->grace_ended = true;
4161 4162 4163 4164 4165 4166
	/*
	 * If the server goes down again right now, an NFSv4
	 * client will still be allowed to reclaim after it comes back up,
	 * even if it hasn't yet had a chance to reclaim state this time.
	 *
	 */
4167
	nfsd4_record_grace_done(nn);
4168 4169 4170 4171 4172 4173 4174 4175 4176
	/*
	 * At this point, NFSv4 clients can still reclaim.  But if the
	 * server crashes, any that have not yet reclaimed will be out
	 * of luck on the next boot.
	 *
	 * (NFSv4.1+ clients are considered to have reclaimed once they
	 * call RECLAIM_COMPLETE.  NFSv4.0 clients are considered to
	 * have reclaimed after their first OPEN.)
	 */
4177
	locks_end_grace(&nn->nfsd4_manager);
4178 4179 4180 4181 4182
	/*
	 * At this point, and once lockd and/or any other containers
	 * exit their grace period, further reclaims will fail and
	 * regular locking can resume.
	 */
4183 4184
}

4185
static time_t
4186
nfs4_laundromat(struct nfsd_net *nn)
L
Linus Torvalds 已提交
4187 4188
{
	struct nfs4_client *clp;
4189
	struct nfs4_openowner *oo;
L
Linus Torvalds 已提交
4190
	struct nfs4_delegation *dp;
4191
	struct nfs4_ol_stateid *stp;
L
Linus Torvalds 已提交
4192
	struct list_head *pos, *next, reaplist;
4193
	time_t cutoff = get_seconds() - nn->nfsd4_lease;
4194
	time_t t, new_timeo = nn->nfsd4_lease;
L
Linus Torvalds 已提交
4195 4196

	dprintk("NFSD: laundromat service - starting\n");
4197
	nfsd4_end_grace(nn);
4198
	INIT_LIST_HEAD(&reaplist);
4199
	spin_lock(&nn->client_lock);
4200
	list_for_each_safe(pos, next, &nn->client_lru) {
L
Linus Torvalds 已提交
4201 4202 4203
		clp = list_entry(pos, struct nfs4_client, cl_lru);
		if (time_after((unsigned long)clp->cl_time, (unsigned long)cutoff)) {
			t = clp->cl_time - cutoff;
4204
			new_timeo = min(new_timeo, t);
L
Linus Torvalds 已提交
4205 4206
			break;
		}
4207
		if (mark_client_expired_locked(clp)) {
4208 4209 4210 4211
			dprintk("NFSD: client in use (clientid %08x)\n",
				clp->cl_clientid.cl_id);
			continue;
		}
4212
		list_add(&clp->cl_lru, &reaplist);
4213
	}
4214
	spin_unlock(&nn->client_lock);
4215 4216
	list_for_each_safe(pos, next, &reaplist) {
		clp = list_entry(pos, struct nfs4_client, cl_lru);
L
Linus Torvalds 已提交
4217 4218
		dprintk("NFSD: purging unused client (clientid %08x)\n",
			clp->cl_clientid.cl_id);
4219
		list_del_init(&clp->cl_lru);
L
Linus Torvalds 已提交
4220 4221
		expire_client(clp);
	}
4222
	spin_lock(&state_lock);
4223
	list_for_each_safe(pos, next, &nn->del_recall_lru) {
L
Linus Torvalds 已提交
4224
		dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
4225 4226
		if (net_generic(dp->dl_stid.sc_client->net, nfsd_net_id) != nn)
			continue;
L
Linus Torvalds 已提交
4227
		if (time_after((unsigned long)dp->dl_time, (unsigned long)cutoff)) {
4228 4229
			t = dp->dl_time - cutoff;
			new_timeo = min(new_timeo, t);
L
Linus Torvalds 已提交
4230 4231
			break;
		}
4232 4233
		unhash_delegation_locked(dp);
		list_add(&dp->dl_recall_lru, &reaplist);
L
Linus Torvalds 已提交
4234
	}
4235
	spin_unlock(&state_lock);
4236 4237 4238 4239
	while (!list_empty(&reaplist)) {
		dp = list_first_entry(&reaplist, struct nfs4_delegation,
					dl_recall_lru);
		list_del_init(&dp->dl_recall_lru);
4240
		revoke_delegation(dp);
L
Linus Torvalds 已提交
4241
	}
4242 4243 4244 4245 4246 4247 4248

	spin_lock(&nn->client_lock);
	while (!list_empty(&nn->close_lru)) {
		oo = list_first_entry(&nn->close_lru, struct nfs4_openowner,
					oo_close_lru);
		if (time_after((unsigned long)oo->oo_time,
			       (unsigned long)cutoff)) {
4249 4250
			t = oo->oo_time - cutoff;
			new_timeo = min(new_timeo, t);
L
Linus Torvalds 已提交
4251 4252
			break;
		}
4253 4254 4255 4256 4257 4258
		list_del_init(&oo->oo_close_lru);
		stp = oo->oo_last_closed_stid;
		oo->oo_last_closed_stid = NULL;
		spin_unlock(&nn->client_lock);
		nfs4_put_stid(&stp->st_stid);
		spin_lock(&nn->client_lock);
L
Linus Torvalds 已提交
4259
	}
4260 4261
	spin_unlock(&nn->client_lock);

4262 4263
	new_timeo = max_t(time_t, new_timeo, NFSD_LAUNDROMAT_MINTIMEOUT);
	return new_timeo;
L
Linus Torvalds 已提交
4264 4265
}

H
Harvey Harrison 已提交
4266 4267 4268 4269
static struct workqueue_struct *laundry_wq;
static void laundromat_main(struct work_struct *);

static void
4270
laundromat_main(struct work_struct *laundry)
L
Linus Torvalds 已提交
4271 4272
{
	time_t t;
4273 4274 4275 4276
	struct delayed_work *dwork = container_of(laundry, struct delayed_work,
						  work);
	struct nfsd_net *nn = container_of(dwork, struct nfsd_net,
					   laundromat_work);
L
Linus Torvalds 已提交
4277

4278
	t = nfs4_laundromat(nn);
L
Linus Torvalds 已提交
4279
	dprintk("NFSD: laundromat_main - sleeping for %ld seconds\n", t);
4280
	queue_delayed_work(laundry_wq, &nn->laundromat_work, t*HZ);
L
Linus Torvalds 已提交
4281 4282
}

4283
static inline __be32 nfs4_check_fh(struct svc_fh *fhp, struct nfs4_ol_stateid *stp)
L
Linus Torvalds 已提交
4284
{
4285
	if (!fh_match(&fhp->fh_handle, &stp->st_stid.sc_file->fi_fhandle))
4286 4287
		return nfserr_bad_stateid;
	return nfs_ok;
L
Linus Torvalds 已提交
4288 4289 4290
}

static inline int
4291
access_permit_read(struct nfs4_ol_stateid *stp)
L
Linus Torvalds 已提交
4292
{
4293 4294 4295
	return test_access(NFS4_SHARE_ACCESS_READ, stp) ||
		test_access(NFS4_SHARE_ACCESS_BOTH, stp) ||
		test_access(NFS4_SHARE_ACCESS_WRITE, stp);
L
Linus Torvalds 已提交
4296 4297 4298
}

static inline int
4299
access_permit_write(struct nfs4_ol_stateid *stp)
L
Linus Torvalds 已提交
4300
{
4301 4302
	return test_access(NFS4_SHARE_ACCESS_WRITE, stp) ||
		test_access(NFS4_SHARE_ACCESS_BOTH, stp);
L
Linus Torvalds 已提交
4303 4304 4305
}

static
4306
__be32 nfs4_check_openmode(struct nfs4_ol_stateid *stp, int flags)
L
Linus Torvalds 已提交
4307
{
4308
        __be32 status = nfserr_openmode;
L
Linus Torvalds 已提交
4309

4310 4311 4312
	/* For lock stateid's, we test the parent open, not the lock: */
	if (stp->st_openstp)
		stp = stp->st_openstp;
4313
	if ((flags & WR_STATE) && !access_permit_write(stp))
L
Linus Torvalds 已提交
4314
                goto out;
4315
	if ((flags & RD_STATE) && !access_permit_read(stp))
L
Linus Torvalds 已提交
4316 4317 4318 4319 4320 4321
                goto out;
	status = nfs_ok;
out:
	return status;
}

4322
static inline __be32
4323
check_special_stateids(struct net *net, svc_fh *current_fh, stateid_t *stateid, int flags)
L
Linus Torvalds 已提交
4324
{
4325
	if (ONE_STATEID(stateid) && (flags & RD_STATE))
L
Linus Torvalds 已提交
4326
		return nfs_ok;
4327
	else if (locks_in_grace(net)) {
L
Lucas De Marchi 已提交
4328
		/* Answer in remaining cases depends on existence of
L
Linus Torvalds 已提交
4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343
		 * conflicting state; so we must wait out the grace period. */
		return nfserr_grace;
	} else if (flags & WR_STATE)
		return nfs4_share_conflict(current_fh,
				NFS4_SHARE_DENY_WRITE);
	else /* (flags & RD_STATE) && ZERO_STATEID(stateid) */
		return nfs4_share_conflict(current_fh,
				NFS4_SHARE_DENY_READ);
}

/*
 * Allow READ/WRITE during grace period on recovered state only for files
 * that are not able to provide mandatory locking.
 */
static inline int
4344
grace_disallows_io(struct net *net, struct inode *inode)
L
Linus Torvalds 已提交
4345
{
4346
	return locks_in_grace(net) && mandatory_lock(inode);
L
Linus Torvalds 已提交
4347 4348
}

4349 4350 4351
/* Returns true iff a is later than b: */
static bool stateid_generation_after(stateid_t *a, stateid_t *b)
{
J
Jim Rees 已提交
4352
	return (s32)(a->si_generation - b->si_generation) > 0;
4353 4354
}

J
J. Bruce Fields 已提交
4355
static __be32 check_stateid_generation(stateid_t *in, stateid_t *ref, bool has_session)
4356
{
A
Andy Adamson 已提交
4357 4358 4359 4360
	/*
	 * When sessions are used the stateid generation number is ignored
	 * when it is zero.
	 */
J
J. Bruce Fields 已提交
4361
	if (has_session && in->si_generation == 0)
4362 4363 4364 4365
		return nfs_ok;

	if (in->si_generation == ref->si_generation)
		return nfs_ok;
A
Andy Adamson 已提交
4366

4367
	/* If the client sends us a stateid from the future, it's buggy: */
4368
	if (stateid_generation_after(in, ref))
4369 4370
		return nfserr_bad_stateid;
	/*
4371 4372 4373 4374 4375 4376 4377 4378
	 * However, we could see a stateid from the past, even from a
	 * non-buggy client.  For example, if the client sends a lock
	 * while some IO is outstanding, the lock may bump si_generation
	 * while the IO is still in flight.  The client could avoid that
	 * situation by waiting for responses on all the IO requests,
	 * but better performance may result in retrying IO that
	 * receives an old_stateid error if requests are rarely
	 * reordered in flight:
4379
	 */
4380
	return nfserr_old_stateid;
4381 4382
}

4383
static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid)
4384
{
4385 4386
	struct nfs4_stid *s;
	struct nfs4_ol_stateid *ols;
4387
	__be32 status = nfserr_bad_stateid;
4388

4389
	if (ZERO_STATEID(stateid) || ONE_STATEID(stateid))
4390
		return status;
4391 4392 4393 4394 4395 4396 4397
	/* Client debugging aid. */
	if (!same_clid(&stateid->si_opaque.so_clid, &cl->cl_clientid)) {
		char addr_str[INET6_ADDRSTRLEN];
		rpc_ntop((struct sockaddr *)&cl->cl_addr, addr_str,
				 sizeof(addr_str));
		pr_warn_ratelimited("NFSD: client %s testing state ID "
					"with incorrect client ID\n", addr_str);
4398
		return status;
4399
	}
4400 4401
	spin_lock(&cl->cl_lock);
	s = find_stateid_locked(cl, stateid);
4402
	if (!s)
4403
		goto out_unlock;
4404
	status = check_stateid_generation(stateid, &s->sc_stateid, 1);
4405
	if (status)
4406
		goto out_unlock;
4407 4408
	switch (s->sc_type) {
	case NFS4_DELEG_STID:
4409 4410
		status = nfs_ok;
		break;
4411
	case NFS4_REVOKED_DELEG_STID:
4412 4413
		status = nfserr_deleg_revoked;
		break;
4414 4415 4416 4417 4418 4419
	case NFS4_OPEN_STID:
	case NFS4_LOCK_STID:
		ols = openlockstateid(s);
		if (ols->st_stateowner->so_is_open_owner
	    			&& !(openowner(ols->st_stateowner)->oo_flags
						& NFS4_OO_CONFIRMED))
4420 4421 4422 4423
			status = nfserr_bad_stateid;
		else
			status = nfs_ok;
		break;
4424 4425
	default:
		printk("unknown stateid type %x\n", s->sc_type);
4426
		/* Fallthrough */
4427
	case NFS4_CLOSED_STID:
4428
	case NFS4_CLOSED_DELEG_STID:
4429
		status = nfserr_bad_stateid;
4430
	}
4431 4432 4433
out_unlock:
	spin_unlock(&cl->cl_lock);
	return status;
4434 4435
}

4436
__be32
4437 4438 4439
nfsd4_lookup_stateid(struct nfsd4_compound_state *cstate,
		     stateid_t *stateid, unsigned char typemask,
		     struct nfs4_stid **s, struct nfsd_net *nn)
4440
{
J
J. Bruce Fields 已提交
4441
	__be32 status;
4442 4443 4444

	if (ZERO_STATEID(stateid) || ONE_STATEID(stateid))
		return nfserr_bad_stateid;
4445
	status = lookup_clientid(&stateid->si_opaque.so_clid, cstate, nn);
4446
	if (status == nfserr_stale_clientid) {
4447
		if (cstate->session)
4448
			return nfserr_bad_stateid;
4449
		return nfserr_stale_stateid;
4450
	}
J
J. Bruce Fields 已提交
4451 4452
	if (status)
		return status;
4453
	*s = find_stateid_by_type(cstate->clp, stateid, typemask);
4454 4455 4456 4457 4458
	if (!*s)
		return nfserr_bad_stateid;
	return nfs_ok;
}

L
Linus Torvalds 已提交
4459 4460 4461
/*
* Checks for stateid operations
*/
4462
__be32
4463
nfs4_preprocess_stateid_op(struct net *net, struct nfsd4_compound_state *cstate,
4464
			   stateid_t *stateid, int flags, struct file **filpp)
L
Linus Torvalds 已提交
4465
{
4466
	struct nfs4_stid *s;
4467
	struct nfs4_ol_stateid *stp = NULL;
L
Linus Torvalds 已提交
4468
	struct nfs4_delegation *dp = NULL;
4469
	struct svc_fh *current_fh = &cstate->current_fh;
L
Linus Torvalds 已提交
4470
	struct inode *ino = current_fh->fh_dentry->d_inode;
4471
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
4472
	struct file *file = NULL;
4473
	__be32 status;
L
Linus Torvalds 已提交
4474 4475 4476 4477

	if (filpp)
		*filpp = NULL;

4478
	if (grace_disallows_io(net, ino))
L
Linus Torvalds 已提交
4479 4480 4481
		return nfserr_grace;

	if (ZERO_STATEID(stateid) || ONE_STATEID(stateid))
4482
		return check_special_stateids(net, current_fh, stateid, flags);
L
Linus Torvalds 已提交
4483

4484
	status = nfsd4_lookup_stateid(cstate, stateid,
4485
				NFS4_DELEG_STID|NFS4_OPEN_STID|NFS4_LOCK_STID,
4486
				&s, nn);
4487
	if (status)
4488
		return status;
4489 4490 4491
	status = check_stateid_generation(stateid, &s->sc_stateid, nfsd4_has_session(cstate));
	if (status)
		goto out;
4492 4493
	switch (s->sc_type) {
	case NFS4_DELEG_STID:
4494
		dp = delegstateid(s);
4495 4496 4497
		status = nfs4_check_delegmode(dp, flags);
		if (status)
			goto out;
4498
		if (filpp) {
4499
			file = dp->dl_stid.sc_file->fi_deleg_file;
4500
			if (!file) {
4501 4502 4503 4504
				WARN_ON_ONCE(1);
				status = nfserr_serverfault;
				goto out;
			}
4505
			get_file(file);
4506
		}
4507 4508 4509
		break;
	case NFS4_OPEN_STID:
	case NFS4_LOCK_STID:
4510
		stp = openlockstateid(s);
4511 4512
		status = nfs4_check_fh(current_fh, stp);
		if (status)
L
Linus Torvalds 已提交
4513
			goto out;
4514
		if (stp->st_stateowner->so_is_open_owner
4515
		    && !(openowner(stp->st_stateowner)->oo_flags & NFS4_OO_CONFIRMED))
L
Linus Torvalds 已提交
4516
			goto out;
4517 4518
		status = nfs4_check_openmode(stp, flags);
		if (status)
L
Linus Torvalds 已提交
4519
			goto out;
4520
		if (filpp) {
4521 4522
			struct nfs4_file *fp = stp->st_stid.sc_file;

4523
			if (flags & RD_STATE)
4524
				file = find_readable_file(fp);
4525
			else
4526
				file = find_writeable_file(fp);
4527
		}
4528 4529
		break;
	default:
4530 4531
		status = nfserr_bad_stateid;
		goto out;
L
Linus Torvalds 已提交
4532 4533
	}
	status = nfs_ok;
4534
	if (file)
4535
		*filpp = file;
L
Linus Torvalds 已提交
4536
out:
4537
	nfs4_put_stid(s);
L
Linus Torvalds 已提交
4538 4539 4540
	return status;
}

4541 4542 4543 4544 4545 4546 4547
/*
 * Test if the stateid is valid
 */
__be32
nfsd4_test_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
		   struct nfsd4_test_stateid *test_stateid)
{
4548 4549 4550 4551
	struct nfsd4_test_stateid_id *stateid;
	struct nfs4_client *cl = cstate->session->se_client;

	list_for_each_entry(stateid, &test_stateid->ts_stateid_list, ts_id_list)
4552 4553
		stateid->ts_id_status =
			nfsd4_validate_stateid(cl, &stateid->ts_id_stateid);
4554

4555 4556 4557
	return nfs_ok;
}

4558 4559 4560 4561 4562
__be32
nfsd4_free_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
		   struct nfsd4_free_stateid *free_stateid)
{
	stateid_t *stateid = &free_stateid->fr_stateid;
J
J. Bruce Fields 已提交
4563
	struct nfs4_stid *s;
4564
	struct nfs4_delegation *dp;
4565
	struct nfs4_ol_stateid *stp;
4566
	struct nfs4_client *cl = cstate->session->se_client;
J
J. Bruce Fields 已提交
4567
	__be32 ret = nfserr_bad_stateid;
4568

4569 4570
	spin_lock(&cl->cl_lock);
	s = find_stateid_locked(cl, stateid);
J
J. Bruce Fields 已提交
4571
	if (!s)
4572
		goto out_unlock;
J
J. Bruce Fields 已提交
4573 4574
	switch (s->sc_type) {
	case NFS4_DELEG_STID:
4575
		ret = nfserr_locks_held;
4576
		break;
J
J. Bruce Fields 已提交
4577 4578 4579
	case NFS4_OPEN_STID:
		ret = check_stateid_generation(stateid, &s->sc_stateid, 1);
		if (ret)
4580 4581
			break;
		ret = nfserr_locks_held;
4582
		break;
4583 4584 4585 4586
	case NFS4_LOCK_STID:
		ret = check_stateid_generation(stateid, &s->sc_stateid, 1);
		if (ret)
			break;
4587 4588 4589 4590 4591 4592
		stp = openlockstateid(s);
		ret = nfserr_locks_held;
		if (check_for_locks(stp->st_stid.sc_file,
				    lockowner(stp->st_stateowner)))
			break;
		unhash_lock_stateid(stp);
4593
		spin_unlock(&cl->cl_lock);
4594 4595
		nfs4_put_stid(s);
		ret = nfs_ok;
4596
		goto out;
4597 4598
	case NFS4_REVOKED_DELEG_STID:
		dp = delegstateid(s);
4599 4600
		list_del_init(&dp->dl_recall_lru);
		spin_unlock(&cl->cl_lock);
4601
		nfs4_put_stid(s);
4602
		ret = nfs_ok;
4603 4604
		goto out;
	/* Default falls through and returns nfserr_bad_stateid */
4605
	}
4606 4607
out_unlock:
	spin_unlock(&cl->cl_lock);
4608 4609 4610 4611
out:
	return ret;
}

4612 4613 4614 4615 4616 4617
static inline int
setlkflg (int type)
{
	return (type == NFS4_READW_LT || type == NFS4_READ_LT) ?
		RD_STATE : WR_STATE;
}
L
Linus Torvalds 已提交
4618

4619
static __be32 nfs4_seqid_op_checks(struct nfsd4_compound_state *cstate, stateid_t *stateid, u32 seqid, struct nfs4_ol_stateid *stp)
4620 4621 4622 4623 4624 4625 4626 4627
{
	struct svc_fh *current_fh = &cstate->current_fh;
	struct nfs4_stateowner *sop = stp->st_stateowner;
	__be32 status;

	status = nfsd4_check_seqid(cstate, sop, seqid);
	if (status)
		return status;
4628 4629
	if (stp->st_stid.sc_type == NFS4_CLOSED_STID
		|| stp->st_stid.sc_type == NFS4_REVOKED_DELEG_STID)
4630 4631
		/*
		 * "Closed" stateid's exist *only* to return
4632 4633
		 * nfserr_replay_me from the previous step, and
		 * revoked delegations are kept only for free_stateid.
4634 4635 4636 4637 4638 4639
		 */
		return nfserr_bad_stateid;
	status = check_stateid_generation(stateid, &stp->st_stid.sc_stateid, nfsd4_has_session(cstate));
	if (status)
		return status;
	return nfs4_check_fh(current_fh, stp);
4640 4641
}

L
Linus Torvalds 已提交
4642 4643 4644
/* 
 * Checks for sequence id mutating operations. 
 */
4645
static __be32
4646
nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid,
4647
			 stateid_t *stateid, char typemask,
4648 4649
			 struct nfs4_ol_stateid **stpp,
			 struct nfsd_net *nn)
L
Linus Torvalds 已提交
4650
{
4651
	__be32 status;
4652
	struct nfs4_stid *s;
4653
	struct nfs4_ol_stateid *stp = NULL;
L
Linus Torvalds 已提交
4654

4655 4656
	dprintk("NFSD: %s: seqid=%d stateid = " STATEID_FMT "\n", __func__,
		seqid, STATEID_VAL(stateid));
4657

L
Linus Torvalds 已提交
4658
	*stpp = NULL;
4659
	status = nfsd4_lookup_stateid(cstate, stateid, typemask, &s, nn);
4660 4661
	if (status)
		return status;
4662
	stp = openlockstateid(s);
4663
	nfsd4_cstate_assign_replay(cstate, stp->st_stateowner);
L
Linus Torvalds 已提交
4664

4665
	status = nfs4_seqid_op_checks(cstate, stateid, seqid, stp);
4666
	if (!status)
4667
		*stpp = stp;
4668 4669
	else
		nfs4_put_stid(&stp->st_stid);
4670
	return status;
4671
}
4672

4673 4674
static __be32 nfs4_preprocess_confirmed_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid,
						 stateid_t *stateid, struct nfs4_ol_stateid **stpp, struct nfsd_net *nn)
4675 4676 4677
{
	__be32 status;
	struct nfs4_openowner *oo;
4678
	struct nfs4_ol_stateid *stp;
L
Linus Torvalds 已提交
4679

4680
	status = nfs4_preprocess_seqid_op(cstate, seqid, stateid,
4681
						NFS4_OPEN_STID, &stp, nn);
4682 4683
	if (status)
		return status;
4684 4685 4686
	oo = openowner(stp->st_stateowner);
	if (!(oo->oo_flags & NFS4_OO_CONFIRMED)) {
		nfs4_put_stid(&stp->st_stid);
4687
		return nfserr_bad_stateid;
4688 4689
	}
	*stpp = stp;
4690
	return nfs_ok;
L
Linus Torvalds 已提交
4691 4692
}

4693
__be32
4694
nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4695
		   struct nfsd4_open_confirm *oc)
L
Linus Torvalds 已提交
4696
{
4697
	__be32 status;
4698
	struct nfs4_openowner *oo;
4699
	struct nfs4_ol_stateid *stp;
4700
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
L
Linus Torvalds 已提交
4701

A
Al Viro 已提交
4702 4703
	dprintk("NFSD: nfsd4_open_confirm on file %pd\n",
			cstate->current_fh.fh_dentry);
L
Linus Torvalds 已提交
4704

4705
	status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0);
4706 4707
	if (status)
		return status;
L
Linus Torvalds 已提交
4708

4709
	status = nfs4_preprocess_seqid_op(cstate,
4710
					oc->oc_seqid, &oc->oc_req_stateid,
4711
					NFS4_OPEN_STID, &stp, nn);
4712
	if (status)
4713
		goto out;
4714
	oo = openowner(stp->st_stateowner);
4715
	status = nfserr_bad_stateid;
4716
	if (oo->oo_flags & NFS4_OO_CONFIRMED)
4717
		goto put_stateid;
4718
	oo->oo_flags |= NFS4_OO_CONFIRMED;
4719 4720
	update_stateid(&stp->st_stid.sc_stateid);
	memcpy(&oc->oc_resp_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
4721
	dprintk("NFSD: %s: success, seqid=%d stateid=" STATEID_FMT "\n",
4722
		__func__, oc->oc_seqid, STATEID_VAL(&stp->st_stid.sc_stateid));
4723

4724
	nfsd4_client_record_create(oo->oo_owner.so_client);
4725
	status = nfs_ok;
4726 4727
put_stateid:
	nfs4_put_stid(&stp->st_stid);
L
Linus Torvalds 已提交
4728
out:
4729
	nfsd4_bump_seqid(cstate, status);
L
Linus Torvalds 已提交
4730 4731 4732
	return status;
}

J
J. Bruce Fields 已提交
4733
static inline void nfs4_stateid_downgrade_bit(struct nfs4_ol_stateid *stp, u32 access)
L
Linus Torvalds 已提交
4734
{
4735
	if (!test_access(access, stp))
J
J. Bruce Fields 已提交
4736
		return;
4737
	nfs4_file_put_access(stp->st_stid.sc_file, access);
4738
	clear_access(access, stp);
J
J. Bruce Fields 已提交
4739
}
4740

J
J. Bruce Fields 已提交
4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754
static inline void nfs4_stateid_downgrade(struct nfs4_ol_stateid *stp, u32 to_access)
{
	switch (to_access) {
	case NFS4_SHARE_ACCESS_READ:
		nfs4_stateid_downgrade_bit(stp, NFS4_SHARE_ACCESS_WRITE);
		nfs4_stateid_downgrade_bit(stp, NFS4_SHARE_ACCESS_BOTH);
		break;
	case NFS4_SHARE_ACCESS_WRITE:
		nfs4_stateid_downgrade_bit(stp, NFS4_SHARE_ACCESS_READ);
		nfs4_stateid_downgrade_bit(stp, NFS4_SHARE_ACCESS_BOTH);
		break;
	case NFS4_SHARE_ACCESS_BOTH:
		break;
	default:
4755
		WARN_ON_ONCE(1);
L
Linus Torvalds 已提交
4756 4757 4758
	}
}

4759
__be32
4760 4761
nfsd4_open_downgrade(struct svc_rqst *rqstp,
		     struct nfsd4_compound_state *cstate,
4762
		     struct nfsd4_open_downgrade *od)
L
Linus Torvalds 已提交
4763
{
4764
	__be32 status;
4765
	struct nfs4_ol_stateid *stp;
4766
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
L
Linus Torvalds 已提交
4767

A
Al Viro 已提交
4768 4769
	dprintk("NFSD: nfsd4_open_downgrade on file %pd\n", 
			cstate->current_fh.fh_dentry);
L
Linus Torvalds 已提交
4770

4771
	/* We don't yet support WANT bits: */
4772 4773 4774
	if (od->od_deleg_want)
		dprintk("NFSD: %s: od_deleg_want=0x%x ignored\n", __func__,
			od->od_deleg_want);
L
Linus Torvalds 已提交
4775

4776
	status = nfs4_preprocess_confirmed_seqid_op(cstate, od->od_seqid,
4777
					&od->od_stateid, &stp, nn);
4778
	if (status)
L
Linus Torvalds 已提交
4779 4780
		goto out; 
	status = nfserr_inval;
4781
	if (!test_access(od->od_share_access, stp)) {
4782
		dprintk("NFSD: access not a subset of current bitmap: 0x%hhx, input access=%08x\n",
L
Linus Torvalds 已提交
4783
			stp->st_access_bmap, od->od_share_access);
4784
		goto put_stateid;
L
Linus Torvalds 已提交
4785
	}
4786
	if (!test_deny(od->od_share_deny, stp)) {
4787
		dprintk("NFSD: deny not a subset of current bitmap: 0x%hhx, input deny=%08x\n",
L
Linus Torvalds 已提交
4788
			stp->st_deny_bmap, od->od_share_deny);
4789
		goto put_stateid;
L
Linus Torvalds 已提交
4790
	}
J
J. Bruce Fields 已提交
4791
	nfs4_stateid_downgrade(stp, od->od_share_access);
L
Linus Torvalds 已提交
4792

4793
	reset_union_bmap_deny(od->od_share_deny, stp);
L
Linus Torvalds 已提交
4794

4795 4796
	update_stateid(&stp->st_stid.sc_stateid);
	memcpy(&od->od_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
L
Linus Torvalds 已提交
4797
	status = nfs_ok;
4798 4799
put_stateid:
	nfs4_put_stid(&stp->st_stid);
L
Linus Torvalds 已提交
4800
out:
4801
	nfsd4_bump_seqid(cstate, status);
L
Linus Torvalds 已提交
4802 4803 4804
	return status;
}

4805 4806
static void nfsd4_close_open_stateid(struct nfs4_ol_stateid *s)
{
4807
	struct nfs4_client *clp = s->st_stid.sc_client;
4808
	LIST_HEAD(reaplist);
4809

4810
	s->st_stid.sc_type = NFS4_CLOSED_STID;
4811
	spin_lock(&clp->cl_lock);
4812
	unhash_open_stateid(s, &reaplist);
4813

4814 4815 4816 4817 4818 4819 4820
	if (clp->cl_minorversion) {
		put_ol_stateid_locked(s, &reaplist);
		spin_unlock(&clp->cl_lock);
		free_ol_stateid_reaplist(&reaplist);
	} else {
		spin_unlock(&clp->cl_lock);
		free_ol_stateid_reaplist(&reaplist);
4821
		move_to_close_lru(s, clp->net);
4822
	}
4823 4824
}

L
Linus Torvalds 已提交
4825 4826 4827
/*
 * nfs4_unlock_state() called after encode
 */
4828
__be32
4829
nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4830
	    struct nfsd4_close *close)
L
Linus Torvalds 已提交
4831
{
4832
	__be32 status;
4833
	struct nfs4_ol_stateid *stp;
4834 4835
	struct net *net = SVC_NET(rqstp);
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
L
Linus Torvalds 已提交
4836

A
Al Viro 已提交
4837 4838
	dprintk("NFSD: nfsd4_close on file %pd\n", 
			cstate->current_fh.fh_dentry);
L
Linus Torvalds 已提交
4839

4840 4841 4842
	status = nfs4_preprocess_seqid_op(cstate, close->cl_seqid,
					&close->cl_stateid,
					NFS4_OPEN_STID|NFS4_CLOSED_STID,
4843
					&stp, nn);
4844
	nfsd4_bump_seqid(cstate, status);
4845
	if (status)
L
Linus Torvalds 已提交
4846
		goto out; 
4847 4848
	update_stateid(&stp->st_stid.sc_stateid);
	memcpy(&close->cl_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
L
Linus Torvalds 已提交
4849

4850
	nfsd4_close_open_stateid(stp);
4851 4852 4853

	/* put reference from nfs4_preprocess_seqid_op */
	nfs4_put_stid(&stp->st_stid);
L
Linus Torvalds 已提交
4854 4855 4856 4857
out:
	return status;
}

4858
__be32
4859 4860
nfsd4_delegreturn(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
		  struct nfsd4_delegreturn *dr)
L
Linus Torvalds 已提交
4861
{
4862 4863
	struct nfs4_delegation *dp;
	stateid_t *stateid = &dr->dr_stateid;
4864
	struct nfs4_stid *s;
4865
	__be32 status;
4866
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
L
Linus Torvalds 已提交
4867

4868
	if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0)))
4869
		return status;
L
Linus Torvalds 已提交
4870

4871
	status = nfsd4_lookup_stateid(cstate, stateid, NFS4_DELEG_STID, &s, nn);
4872
	if (status)
4873
		goto out;
4874
	dp = delegstateid(s);
4875
	status = check_stateid_generation(stateid, &dp->dl_stid.sc_stateid, nfsd4_has_session(cstate));
4876
	if (status)
4877
		goto put_stateid;
4878

4879
	destroy_delegation(dp);
4880 4881
put_stateid:
	nfs4_put_stid(&dp->dl_stid);
L
Linus Torvalds 已提交
4882 4883 4884 4885 4886 4887 4888
out:
	return status;
}


#define LOFF_OVERFLOW(start, len)      ((u64)(len) > ~(u64)(start))

B
Benny Halevy 已提交
4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903
static inline u64
end_offset(u64 start, u64 len)
{
	u64 end;

	end = start + len;
	return end >= start ? end: NFS4_MAX_UINT64;
}

/* last octet in a range */
static inline u64
last_byte_offset(u64 start, u64 len)
{
	u64 end;

4904
	WARN_ON_ONCE(!len);
B
Benny Halevy 已提交
4905 4906 4907 4908
	end = start + len;
	return end > start ? end - 1: NFS4_MAX_UINT64;
}

L
Linus Torvalds 已提交
4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925
/*
 * TODO: Linux file offsets are _signed_ 64-bit quantities, which means that
 * we can't properly handle lock requests that go beyond the (2^63 - 1)-th
 * byte, because of sign extension problems.  Since NFSv4 calls for 64-bit
 * locking, this prevents us from being completely protocol-compliant.  The
 * real solution to this problem is to start using unsigned file offsets in
 * the VFS, but this is a very deep change!
 */
static inline void
nfs4_transform_lock_offset(struct file_lock *lock)
{
	if (lock->fl_start < 0)
		lock->fl_start = OFFSET_MAX;
	if (lock->fl_end < 0)
		lock->fl_end = OFFSET_MAX;
}

4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941
static void nfsd4_fl_get_owner(struct file_lock *dst, struct file_lock *src)
{
	struct nfs4_lockowner *lo = (struct nfs4_lockowner *)src->fl_owner;
	dst->fl_owner = (fl_owner_t)lockowner(nfs4_get_stateowner(&lo->lo_owner));
}

static void nfsd4_fl_put_owner(struct file_lock *fl)
{
	struct nfs4_lockowner *lo = (struct nfs4_lockowner *)fl->fl_owner;

	if (lo) {
		nfs4_put_stateowner(&lo->lo_owner);
		fl->fl_owner = NULL;
	}
}

4942
static const struct lock_manager_operations nfsd_posix_mng_ops  = {
4943 4944
	.lm_get_owner = nfsd4_fl_get_owner,
	.lm_put_owner = nfsd4_fl_put_owner,
4945
};
L
Linus Torvalds 已提交
4946 4947 4948 4949

static inline void
nfs4_set_lock_denied(struct file_lock *fl, struct nfsd4_lock_denied *deny)
{
4950
	struct nfs4_lockowner *lo;
L
Linus Torvalds 已提交
4951

4952
	if (fl->fl_lmops == &nfsd_posix_mng_ops) {
4953 4954 4955
		lo = (struct nfs4_lockowner *) fl->fl_owner;
		deny->ld_owner.data = kmemdup(lo->lo_owner.so_owner.data,
					lo->lo_owner.so_owner.len, GFP_KERNEL);
4956 4957 4958
		if (!deny->ld_owner.data)
			/* We just don't care that much */
			goto nevermind;
4959 4960
		deny->ld_owner.len = lo->lo_owner.so_owner.len;
		deny->ld_clientid = lo->lo_owner.so_client->cl_clientid;
4961
	} else {
4962 4963 4964
nevermind:
		deny->ld_owner.len = 0;
		deny->ld_owner.data = NULL;
4965 4966
		deny->ld_clientid.cl_boot = 0;
		deny->ld_clientid.cl_id = 0;
L
Linus Torvalds 已提交
4967 4968
	}
	deny->ld_start = fl->fl_start;
B
Benny Halevy 已提交
4969 4970
	deny->ld_length = NFS4_MAX_UINT64;
	if (fl->fl_end != NFS4_MAX_UINT64)
L
Linus Torvalds 已提交
4971 4972 4973 4974 4975 4976
		deny->ld_length = fl->fl_end - fl->fl_start + 1;        
	deny->ld_type = NFS4_READ_LT;
	if (fl->fl_type != F_RDLCK)
		deny->ld_type = NFS4_WRITE_LT;
}

4977
static struct nfs4_lockowner *
4978
find_lockowner_str_locked(clientid_t *clid, struct xdr_netobj *owner,
4979
		struct nfs4_client *clp)
L
Linus Torvalds 已提交
4980
{
4981
	unsigned int strhashval = ownerstr_hashval(owner);
4982
	struct nfs4_stateowner *so;
L
Linus Torvalds 已提交
4983

4984 4985
	lockdep_assert_held(&clp->cl_lock);

4986 4987
	list_for_each_entry(so, &clp->cl_ownerstr_hashtbl[strhashval],
			    so_strhash) {
4988 4989
		if (so->so_is_open_owner)
			continue;
4990 4991
		if (same_owner_str(so, owner))
			return lockowner(nfs4_get_stateowner(so));
L
Linus Torvalds 已提交
4992 4993 4994 4995
	}
	return NULL;
}

4996 4997
static struct nfs4_lockowner *
find_lockowner_str(clientid_t *clid, struct xdr_netobj *owner,
4998
		struct nfs4_client *clp)
4999 5000 5001
{
	struct nfs4_lockowner *lo;

5002 5003 5004
	spin_lock(&clp->cl_lock);
	lo = find_lockowner_str_locked(clid, owner, clp);
	spin_unlock(&clp->cl_lock);
5005 5006 5007
	return lo;
}

5008 5009
static void nfs4_unhash_lockowner(struct nfs4_stateowner *sop)
{
5010
	unhash_lockowner_locked(lockowner(sop));
5011 5012
}

5013 5014 5015 5016 5017 5018 5019 5020
static void nfs4_free_lockowner(struct nfs4_stateowner *sop)
{
	struct nfs4_lockowner *lo = lockowner(sop);

	kmem_cache_free(lockowner_slab, lo);
}

static const struct nfs4_stateowner_operations lockowner_ops = {
5021 5022
	.so_unhash =	nfs4_unhash_lockowner,
	.so_free =	nfs4_free_lockowner,
5023 5024
};

L
Linus Torvalds 已提交
5025 5026 5027
/*
 * Alloc a lock owner structure.
 * Called in nfsd4_lock - therefore, OPEN and OPEN_CONFIRM (if needed) has 
L
Lucas De Marchi 已提交
5028
 * occurred. 
L
Linus Torvalds 已提交
5029
 *
5030
 * strhashval = ownerstr_hashval
L
Linus Torvalds 已提交
5031
 */
5032
static struct nfs4_lockowner *
5033 5034 5035 5036 5037
alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp,
			   struct nfs4_ol_stateid *open_stp,
			   struct nfsd4_lock *lock)
{
	struct nfs4_lockowner *lo, *ret;
L
Linus Torvalds 已提交
5038

5039 5040
	lo = alloc_stateowner(lockowner_slab, &lock->lk_new_owner, clp);
	if (!lo)
L
Linus Torvalds 已提交
5041
		return NULL;
5042 5043
	INIT_LIST_HEAD(&lo->lo_owner.so_stateids);
	lo->lo_owner.so_is_open_owner = 0;
5044
	lo->lo_owner.so_seqid = lock->lk_new_lock_seqid;
5045
	lo->lo_owner.so_ops = &lockowner_ops;
5046
	spin_lock(&clp->cl_lock);
5047
	ret = find_lockowner_str_locked(&clp->cl_clientid,
5048
			&lock->lk_new_owner, clp);
5049 5050
	if (ret == NULL) {
		list_add(&lo->lo_owner.so_strhash,
5051
			 &clp->cl_ownerstr_hashtbl[strhashval]);
5052 5053 5054
		ret = lo;
	} else
		nfs4_free_lockowner(&lo->lo_owner);
5055
	spin_unlock(&clp->cl_lock);
5056
	return lo;
L
Linus Torvalds 已提交
5057 5058
}

5059 5060 5061 5062
static void
init_lock_stateid(struct nfs4_ol_stateid *stp, struct nfs4_lockowner *lo,
		  struct nfs4_file *fp, struct inode *inode,
		  struct nfs4_ol_stateid *open_stp)
L
Linus Torvalds 已提交
5063
{
5064
	struct nfs4_client *clp = lo->lo_owner.so_client;
L
Linus Torvalds 已提交
5065

5066 5067
	lockdep_assert_held(&clp->cl_lock);

5068
	atomic_inc(&stp->st_stid.sc_count);
J
J. Bruce Fields 已提交
5069
	stp->st_stid.sc_type = NFS4_LOCK_STID;
5070
	stp->st_stateowner = nfs4_get_stateowner(&lo->lo_owner);
5071
	get_nfs4_file(fp);
5072
	stp->st_stid.sc_file = fp;
5073
	stp->st_stid.sc_free = nfs4_free_lock_stateid;
J
J. Bruce Fields 已提交
5074
	stp->st_access_bmap = 0;
L
Linus Torvalds 已提交
5075
	stp->st_deny_bmap = open_stp->st_deny_bmap;
5076
	stp->st_openstp = open_stp;
5077
	list_add(&stp->st_locks, &open_stp->st_locks);
5078
	list_add(&stp->st_perstateowner, &lo->lo_owner.so_stateids);
5079 5080 5081
	spin_lock(&fp->fi_lock);
	list_add(&stp->st_perfile, &fp->fi_stateids);
	spin_unlock(&fp->fi_lock);
L
Linus Torvalds 已提交
5082 5083
}

5084 5085 5086 5087
static struct nfs4_ol_stateid *
find_lock_stateid(struct nfs4_lockowner *lo, struct nfs4_file *fp)
{
	struct nfs4_ol_stateid *lst;
5088 5089 5090
	struct nfs4_client *clp = lo->lo_owner.so_client;

	lockdep_assert_held(&clp->cl_lock);
5091 5092

	list_for_each_entry(lst, &lo->lo_owner.so_stateids, st_perstateowner) {
5093 5094
		if (lst->st_stid.sc_file == fp) {
			atomic_inc(&lst->st_stid.sc_count);
5095
			return lst;
5096
		}
5097 5098 5099 5100
	}
	return NULL;
}

5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132
static struct nfs4_ol_stateid *
find_or_create_lock_stateid(struct nfs4_lockowner *lo, struct nfs4_file *fi,
			    struct inode *inode, struct nfs4_ol_stateid *ost,
			    bool *new)
{
	struct nfs4_stid *ns = NULL;
	struct nfs4_ol_stateid *lst;
	struct nfs4_openowner *oo = openowner(ost->st_stateowner);
	struct nfs4_client *clp = oo->oo_owner.so_client;

	spin_lock(&clp->cl_lock);
	lst = find_lock_stateid(lo, fi);
	if (lst == NULL) {
		spin_unlock(&clp->cl_lock);
		ns = nfs4_alloc_stid(clp, stateid_slab);
		if (ns == NULL)
			return NULL;

		spin_lock(&clp->cl_lock);
		lst = find_lock_stateid(lo, fi);
		if (likely(!lst)) {
			lst = openlockstateid(ns);
			init_lock_stateid(lst, lo, fi, inode, ost);
			ns = NULL;
			*new = true;
		}
	}
	spin_unlock(&clp->cl_lock);
	if (ns)
		nfs4_put_stid(ns);
	return lst;
}
5133

5134
static int
L
Linus Torvalds 已提交
5135 5136
check_lock_length(u64 offset, u64 length)
{
B
Benny Halevy 已提交
5137
	return ((length == 0)  || ((length != NFS4_MAX_UINT64) &&
L
Linus Torvalds 已提交
5138 5139 5140
	     LOFF_OVERFLOW(offset, length)));
}

5141
static void get_lock_access(struct nfs4_ol_stateid *lock_stp, u32 access)
J
J. Bruce Fields 已提交
5142
{
5143
	struct nfs4_file *fp = lock_stp->st_stid.sc_file;
J
J. Bruce Fields 已提交
5144

5145 5146
	lockdep_assert_held(&fp->fi_lock);

5147
	if (test_access(access, lock_stp))
J
J. Bruce Fields 已提交
5148
		return;
5149
	__nfs4_file_get_access(fp, access);
5150
	set_access(access, lock_stp);
J
J. Bruce Fields 已提交
5151 5152
}

5153 5154 5155 5156 5157
static __be32
lookup_or_create_lock_state(struct nfsd4_compound_state *cstate,
			    struct nfs4_ol_stateid *ost,
			    struct nfsd4_lock *lock,
			    struct nfs4_ol_stateid **lst, bool *new)
5158
{
5159
	__be32 status;
5160
	struct nfs4_file *fi = ost->st_stid.sc_file;
5161 5162
	struct nfs4_openowner *oo = openowner(ost->st_stateowner);
	struct nfs4_client *cl = oo->oo_owner.so_client;
5163
	struct inode *inode = cstate->current_fh.fh_dentry->d_inode;
5164 5165 5166
	struct nfs4_lockowner *lo;
	unsigned int strhashval;

5167
	lo = find_lockowner_str(&cl->cl_clientid, &lock->v.new.owner, cl);
5168
	if (!lo) {
5169
		strhashval = ownerstr_hashval(&lock->v.new.owner);
5170 5171 5172 5173 5174
		lo = alloc_init_lock_stateowner(strhashval, cl, ost, lock);
		if (lo == NULL)
			return nfserr_jukebox;
	} else {
		/* with an existing lockowner, seqids must be the same */
5175
		status = nfserr_bad_seqid;
5176 5177
		if (!cstate->minorversion &&
		    lock->lk_new_lock_seqid != lo->lo_owner.so_seqid)
5178
			goto out;
5179
	}
5180

5181
	*lst = find_or_create_lock_stateid(lo, fi, inode, ost, new);
5182
	if (*lst == NULL) {
5183 5184
		status = nfserr_jukebox;
		goto out;
5185
	}
5186 5187 5188 5189
	status = nfs_ok;
out:
	nfs4_put_stateowner(&lo->lo_owner);
	return status;
5190 5191
}

L
Linus Torvalds 已提交
5192 5193 5194
/*
 *  LOCK operation 
 */
5195
__be32
5196
nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
5197
	   struct nfsd4_lock *lock)
L
Linus Torvalds 已提交
5198
{
5199 5200
	struct nfs4_openowner *open_sop = NULL;
	struct nfs4_lockowner *lock_sop = NULL;
5201
	struct nfs4_ol_stateid *lock_stp = NULL;
5202
	struct nfs4_ol_stateid *open_stp = NULL;
5203
	struct nfs4_file *fp;
5204
	struct file *filp = NULL;
5205 5206
	struct file_lock *file_lock = NULL;
	struct file_lock *conflock = NULL;
5207
	__be32 status = 0;
5208
	int lkflg;
5209
	int err;
5210
	bool new = false;
5211 5212
	struct net *net = SVC_NET(rqstp);
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
L
Linus Torvalds 已提交
5213 5214 5215 5216 5217 5218 5219 5220

	dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n",
		(long long) lock->lk_offset,
		(long long) lock->lk_length);

	if (check_lock_length(lock->lk_offset, lock->lk_length))
		 return nfserr_inval;

5221
	if ((status = fh_verify(rqstp, &cstate->current_fh,
M
Miklos Szeredi 已提交
5222
				S_IFREG, NFSD_MAY_LOCK))) {
A
Andy Adamson 已提交
5223 5224 5225 5226
		dprintk("NFSD: nfsd4_lock: permission denied!\n");
		return status;
	}

L
Linus Torvalds 已提交
5227
	if (lock->lk_is_new) {
5228 5229 5230 5231 5232 5233
		if (nfsd4_has_session(cstate))
			/* See rfc 5661 18.10.3: given clientid is ignored: */
			memcpy(&lock->v.new.clientid,
				&cstate->session->se_client->cl_clientid,
				sizeof(clientid_t));

L
Linus Torvalds 已提交
5234
		status = nfserr_stale_clientid;
5235
		if (STALE_CLIENTID(&lock->lk_new_clientid, nn))
L
Linus Torvalds 已提交
5236 5237 5238
			goto out;

		/* validate and update open stateid and open seqid */
5239
		status = nfs4_preprocess_confirmed_seqid_op(cstate,
L
Linus Torvalds 已提交
5240 5241
				        lock->lk_new_open_seqid,
		                        &lock->lk_new_open_stateid,
5242
					&open_stp, nn);
5243
		if (status)
L
Linus Torvalds 已提交
5244
			goto out;
5245
		open_sop = openowner(open_stp->st_stateowner);
5246
		status = nfserr_bad_stateid;
5247
		if (!same_clid(&open_sop->oo_owner.so_client->cl_clientid,
5248 5249
						&lock->v.new.clientid))
			goto out;
5250
		status = lookup_or_create_lock_state(cstate, open_stp, lock,
5251
							&lock_stp, &new);
5252
	} else {
5253
		status = nfs4_preprocess_seqid_op(cstate,
5254 5255
				       lock->lk_old_lock_seqid,
				       &lock->lk_old_lock_stateid,
5256
				       NFS4_LOCK_STID, &lock_stp, nn);
5257
	}
J
J. Bruce Fields 已提交
5258 5259
	if (status)
		goto out;
5260
	lock_sop = lockowner(lock_stp->st_stateowner);
L
Linus Torvalds 已提交
5261

5262 5263 5264 5265 5266
	lkflg = setlkflg(lock->lk_type);
	status = nfs4_check_openmode(lock_stp, lkflg);
	if (status)
		goto out;

5267
	status = nfserr_grace;
5268
	if (locks_in_grace(net) && !lock->lk_reclaim)
5269 5270
		goto out;
	status = nfserr_no_grace;
5271
	if (!locks_in_grace(net) && lock->lk_reclaim)
5272 5273
		goto out;

5274 5275 5276 5277 5278 5279 5280
	file_lock = locks_alloc_lock();
	if (!file_lock) {
		dprintk("NFSD: %s: unable to allocate lock!\n", __func__);
		status = nfserr_jukebox;
		goto out;
	}

5281
	fp = lock_stp->st_stid.sc_file;
L
Linus Torvalds 已提交
5282 5283 5284
	switch (lock->lk_type) {
		case NFS4_READ_LT:
		case NFS4_READW_LT:
5285 5286
			spin_lock(&fp->fi_lock);
			filp = find_readable_file_locked(fp);
J
J. Bruce Fields 已提交
5287 5288
			if (filp)
				get_lock_access(lock_stp, NFS4_SHARE_ACCESS_READ);
5289
			spin_unlock(&fp->fi_lock);
5290
			file_lock->fl_type = F_RDLCK;
5291
			break;
L
Linus Torvalds 已提交
5292 5293
		case NFS4_WRITE_LT:
		case NFS4_WRITEW_LT:
5294 5295
			spin_lock(&fp->fi_lock);
			filp = find_writeable_file_locked(fp);
J
J. Bruce Fields 已提交
5296 5297
			if (filp)
				get_lock_access(lock_stp, NFS4_SHARE_ACCESS_WRITE);
5298
			spin_unlock(&fp->fi_lock);
5299
			file_lock->fl_type = F_WRLCK;
5300
			break;
L
Linus Torvalds 已提交
5301 5302 5303 5304
		default:
			status = nfserr_inval;
		goto out;
	}
5305 5306 5307 5308
	if (!filp) {
		status = nfserr_openmode;
		goto out;
	}
5309 5310

	file_lock->fl_owner = (fl_owner_t)lockowner(nfs4_get_stateowner(&lock_sop->lo_owner));
5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324
	file_lock->fl_pid = current->tgid;
	file_lock->fl_file = filp;
	file_lock->fl_flags = FL_POSIX;
	file_lock->fl_lmops = &nfsd_posix_mng_ops;
	file_lock->fl_start = lock->lk_offset;
	file_lock->fl_end = last_byte_offset(lock->lk_offset, lock->lk_length);
	nfs4_transform_lock_offset(file_lock);

	conflock = locks_alloc_lock();
	if (!conflock) {
		dprintk("NFSD: %s: unable to allocate lock!\n", __func__);
		status = nfserr_jukebox;
		goto out;
	}
L
Linus Torvalds 已提交
5325

5326
	err = vfs_lock_file(filp, F_SETLK, file_lock, conflock);
5327
	switch (-err) {
L
Linus Torvalds 已提交
5328
	case 0: /* success! */
5329 5330
		update_stateid(&lock_stp->st_stid.sc_stateid);
		memcpy(&lock->lk_resp_stateid, &lock_stp->st_stid.sc_stateid, 
L
Linus Torvalds 已提交
5331
				sizeof(stateid_t));
5332
		status = 0;
5333 5334 5335 5336
		break;
	case (EAGAIN):		/* conflock holds conflicting lock */
		status = nfserr_denied;
		dprintk("NFSD: nfsd4_lock: conflicting lock found!\n");
5337
		nfs4_set_lock_denied(conflock, &lock->lk_denied);
5338
		break;
L
Linus Torvalds 已提交
5339 5340
	case (EDEADLK):
		status = nfserr_deadlock;
5341
		break;
5342
	default:
5343
		dprintk("NFSD: nfsd4_lock: vfs_lock_file() failed! status %d\n",err);
5344
		status = nfserrno(err);
5345
		break;
L
Linus Torvalds 已提交
5346 5347
	}
out:
5348 5349
	if (filp)
		fput(filp);
5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363
	if (lock_stp) {
		/* Bump seqid manually if the 4.0 replay owner is openowner */
		if (cstate->replay_owner &&
		    cstate->replay_owner != &lock_sop->lo_owner &&
		    seqid_mutating_err(ntohl(status)))
			lock_sop->lo_owner.so_seqid++;

		/*
		 * If this is a new, never-before-used stateid, and we are
		 * returning an error, then just go ahead and release it.
		 */
		if (status && new)
			release_lock_stateid(lock_stp);

5364
		nfs4_put_stid(&lock_stp->st_stid);
5365
	}
5366 5367
	if (open_stp)
		nfs4_put_stid(&open_stp->st_stid);
5368
	nfsd4_bump_seqid(cstate, status);
5369 5370 5371 5372
	if (file_lock)
		locks_free_lock(file_lock);
	if (conflock)
		locks_free_lock(conflock);
L
Linus Torvalds 已提交
5373 5374 5375
	return status;
}

5376 5377 5378 5379 5380 5381
/*
 * The NFSv4 spec allows a client to do a LOCKT without holding an OPEN,
 * so we do a temporary open here just to get an open file to pass to
 * vfs_test_lock.  (Arguably perhaps test_lock should be done with an
 * inode operation.)
 */
5382
static __be32 nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file_lock *lock)
5383 5384
{
	struct file *file;
5385 5386 5387 5388 5389
	__be32 err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file);
	if (!err) {
		err = nfserrno(vfs_test_lock(file, lock));
		nfsd_close(file);
	}
5390 5391 5392
	return err;
}

L
Linus Torvalds 已提交
5393 5394 5395
/*
 * LOCKT operation
 */
5396
__be32
5397 5398
nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	    struct nfsd4_lockt *lockt)
L
Linus Torvalds 已提交
5399
{
5400
	struct file_lock *file_lock = NULL;
5401
	struct nfs4_lockowner *lo = NULL;
5402
	__be32 status;
5403
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
L
Linus Torvalds 已提交
5404

5405
	if (locks_in_grace(SVC_NET(rqstp)))
L
Linus Torvalds 已提交
5406 5407 5408 5409 5410
		return nfserr_grace;

	if (check_lock_length(lockt->lt_offset, lockt->lt_length))
		 return nfserr_inval;

5411
	if (!nfsd4_has_session(cstate)) {
5412
		status = lookup_clientid(&lockt->lt_clientid, cstate, nn);
5413 5414 5415
		if (status)
			goto out;
	}
L
Linus Torvalds 已提交
5416

5417
	if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0)))
L
Linus Torvalds 已提交
5418 5419
		goto out;

5420 5421 5422 5423 5424 5425
	file_lock = locks_alloc_lock();
	if (!file_lock) {
		dprintk("NFSD: %s: unable to allocate lock!\n", __func__);
		status = nfserr_jukebox;
		goto out;
	}
5426

L
Linus Torvalds 已提交
5427 5428 5429
	switch (lockt->lt_type) {
		case NFS4_READ_LT:
		case NFS4_READW_LT:
5430
			file_lock->fl_type = F_RDLCK;
L
Linus Torvalds 已提交
5431 5432 5433
		break;
		case NFS4_WRITE_LT:
		case NFS4_WRITEW_LT:
5434
			file_lock->fl_type = F_WRLCK;
L
Linus Torvalds 已提交
5435 5436
		break;
		default:
5437
			dprintk("NFSD: nfs4_lockt: bad lock type!\n");
L
Linus Torvalds 已提交
5438 5439 5440 5441
			status = nfserr_inval;
		goto out;
	}

5442 5443
	lo = find_lockowner_str(&lockt->lt_clientid, &lockt->lt_owner,
				cstate->clp);
5444
	if (lo)
5445 5446 5447
		file_lock->fl_owner = (fl_owner_t)lo;
	file_lock->fl_pid = current->tgid;
	file_lock->fl_flags = FL_POSIX;
L
Linus Torvalds 已提交
5448

5449 5450
	file_lock->fl_start = lockt->lt_offset;
	file_lock->fl_end = last_byte_offset(lockt->lt_offset, lockt->lt_length);
L
Linus Torvalds 已提交
5451

5452
	nfs4_transform_lock_offset(file_lock);
L
Linus Torvalds 已提交
5453

5454
	status = nfsd_test_lock(rqstp, &cstate->current_fh, file_lock);
5455
	if (status)
5456
		goto out;
5457

5458
	if (file_lock->fl_type != F_UNLCK) {
L
Linus Torvalds 已提交
5459
		status = nfserr_denied;
5460
		nfs4_set_lock_denied(file_lock, &lockt->lt_denied);
L
Linus Torvalds 已提交
5461 5462
	}
out:
5463 5464
	if (lo)
		nfs4_put_stateowner(&lo->lo_owner);
5465 5466
	if (file_lock)
		locks_free_lock(file_lock);
L
Linus Torvalds 已提交
5467 5468 5469
	return status;
}

5470
__be32
5471
nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
5472
	    struct nfsd4_locku *locku)
L
Linus Torvalds 已提交
5473
{
5474
	struct nfs4_ol_stateid *stp;
L
Linus Torvalds 已提交
5475
	struct file *filp = NULL;
5476
	struct file_lock *file_lock = NULL;
5477
	__be32 status;
5478
	int err;
5479 5480
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);

L
Linus Torvalds 已提交
5481 5482 5483 5484 5485 5486 5487
	dprintk("NFSD: nfsd4_locku: start=%Ld length=%Ld\n",
		(long long) locku->lu_offset,
		(long long) locku->lu_length);

	if (check_lock_length(locku->lu_offset, locku->lu_length))
		 return nfserr_inval;

5488
	status = nfs4_preprocess_seqid_op(cstate, locku->lu_seqid,
5489 5490
					&locku->lu_stateid, NFS4_LOCK_STID,
					&stp, nn);
5491
	if (status)
L
Linus Torvalds 已提交
5492
		goto out;
5493
	filp = find_any_file(stp->st_stid.sc_file);
5494 5495
	if (!filp) {
		status = nfserr_lock_range;
5496
		goto put_stateid;
5497
	}
5498 5499 5500 5501
	file_lock = locks_alloc_lock();
	if (!file_lock) {
		dprintk("NFSD: %s: unable to allocate lock!\n", __func__);
		status = nfserr_jukebox;
5502
		goto fput;
5503
	}
5504

5505
	file_lock->fl_type = F_UNLCK;
5506
	file_lock->fl_owner = (fl_owner_t)lockowner(nfs4_get_stateowner(stp->st_stateowner));
5507 5508 5509 5510 5511 5512 5513 5514 5515
	file_lock->fl_pid = current->tgid;
	file_lock->fl_file = filp;
	file_lock->fl_flags = FL_POSIX;
	file_lock->fl_lmops = &nfsd_posix_mng_ops;
	file_lock->fl_start = locku->lu_offset;

	file_lock->fl_end = last_byte_offset(locku->lu_offset,
						locku->lu_length);
	nfs4_transform_lock_offset(file_lock);
L
Linus Torvalds 已提交
5516

5517
	err = vfs_lock_file(filp, F_SETLK, file_lock, NULL);
5518
	if (err) {
5519
		dprintk("NFSD: nfs4_locku: vfs_lock_file failed!\n");
L
Linus Torvalds 已提交
5520 5521
		goto out_nfserr;
	}
5522 5523
	update_stateid(&stp->st_stid.sc_stateid);
	memcpy(&locku->lu_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
5524 5525
fput:
	fput(filp);
5526 5527
put_stateid:
	nfs4_put_stid(&stp->st_stid);
L
Linus Torvalds 已提交
5528
out:
5529
	nfsd4_bump_seqid(cstate, status);
5530 5531
	if (file_lock)
		locks_free_lock(file_lock);
L
Linus Torvalds 已提交
5532 5533 5534
	return status;

out_nfserr:
5535
	status = nfserrno(err);
5536
	goto fput;
L
Linus Torvalds 已提交
5537 5538 5539 5540
}

/*
 * returns
5541 5542
 * 	true:  locks held by lockowner
 * 	false: no locks held by lockowner
L
Linus Torvalds 已提交
5543
 */
5544 5545
static bool
check_for_locks(struct nfs4_file *fp, struct nfs4_lockowner *lowner)
L
Linus Torvalds 已提交
5546
{
5547
	struct file_lock *fl;
5548 5549 5550
	int status = false;
	struct file *filp = find_any_file(fp);
	struct inode *inode;
5551
	struct file_lock_context *flctx;
5552 5553 5554 5555 5556 5557 5558 5559

	if (!filp) {
		/* Any valid lock stateid should have some sort of access */
		WARN_ON_ONCE(1);
		return status;
	}

	inode = file_inode(filp);
5560 5561 5562
	flctx = inode->i_flctx;

	if (flctx && !list_empty_careful(&flctx->flc_posix)) {
5563
		spin_lock(&flctx->flc_lock);
5564 5565 5566 5567 5568
		list_for_each_entry(fl, &flctx->flc_posix, fl_list) {
			if (fl->fl_owner == (fl_owner_t)lowner) {
				status = true;
				break;
			}
5569
		}
5570
		spin_unlock(&flctx->flc_lock);
L
Linus Torvalds 已提交
5571
	}
5572
	fput(filp);
L
Linus Torvalds 已提交
5573 5574 5575
	return status;
}

5576
__be32
5577 5578 5579
nfsd4_release_lockowner(struct svc_rqst *rqstp,
			struct nfsd4_compound_state *cstate,
			struct nfsd4_release_lockowner *rlockowner)
L
Linus Torvalds 已提交
5580 5581
{
	clientid_t *clid = &rlockowner->rl_clientid;
5582 5583
	struct nfs4_stateowner *sop;
	struct nfs4_lockowner *lo = NULL;
5584
	struct nfs4_ol_stateid *stp;
L
Linus Torvalds 已提交
5585
	struct xdr_netobj *owner = &rlockowner->rl_owner;
5586
	unsigned int hashval = ownerstr_hashval(owner);
5587
	__be32 status;
5588
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
5589
	struct nfs4_client *clp;
L
Linus Torvalds 已提交
5590 5591 5592 5593

	dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n",
		clid->cl_boot, clid->cl_id);

5594
	status = lookup_clientid(clid, cstate, nn);
5595
	if (status)
5596
		return status;
5597

5598
	clp = cstate->clp;
5599
	/* Find the matching lock stateowner */
5600
	spin_lock(&clp->cl_lock);
5601
	list_for_each_entry(sop, &clp->cl_ownerstr_hashtbl[hashval],
5602
			    so_strhash) {
5603

5604 5605
		if (sop->so_is_open_owner || !same_owner_str(sop, owner))
			continue;
5606

5607 5608 5609 5610 5611 5612
		/* see if there are still any locks associated with it */
		lo = lockowner(sop);
		list_for_each_entry(stp, &sop->so_stateids, st_perstateowner) {
			if (check_for_locks(stp->st_stid.sc_file, lo)) {
				status = nfserr_locks_held;
				spin_unlock(&clp->cl_lock);
5613
				return status;
5614
			}
5615
		}
5616

5617
		nfs4_get_stateowner(sop);
5618
		break;
L
Linus Torvalds 已提交
5619
	}
5620
	spin_unlock(&clp->cl_lock);
5621 5622
	if (lo)
		release_lockowner(lo);
L
Linus Torvalds 已提交
5623 5624 5625 5626
	return status;
}

static inline struct nfs4_client_reclaim *
N
NeilBrown 已提交
5627
alloc_reclaim(void)
L
Linus Torvalds 已提交
5628
{
N
NeilBrown 已提交
5629
	return kmalloc(sizeof(struct nfs4_client_reclaim), GFP_KERNEL);
L
Linus Torvalds 已提交
5630 5631
}

5632
bool
5633
nfs4_has_reclaimed_state(const char *name, struct nfsd_net *nn)
5634
{
5635
	struct nfs4_client_reclaim *crp;
5636

5637
	crp = nfsd4_find_reclaim_client(name, nn);
5638
	return (crp && crp->cr_clp);
5639 5640
}

L
Linus Torvalds 已提交
5641 5642 5643
/*
 * failure => all reset bets are off, nfserr_no_grace...
 */
5644
struct nfs4_client_reclaim *
5645
nfs4_client_to_reclaim(const char *name, struct nfsd_net *nn)
L
Linus Torvalds 已提交
5646 5647
{
	unsigned int strhashval;
5648
	struct nfs4_client_reclaim *crp;
L
Linus Torvalds 已提交
5649

N
NeilBrown 已提交
5650 5651
	dprintk("NFSD nfs4_client_to_reclaim NAME: %.*s\n", HEXDIR_LEN, name);
	crp = alloc_reclaim();
5652 5653 5654
	if (crp) {
		strhashval = clientstr_hashval(name);
		INIT_LIST_HEAD(&crp->cr_strhash);
5655
		list_add(&crp->cr_strhash, &nn->reclaim_str_hashtbl[strhashval]);
5656
		memcpy(crp->cr_recdir, name, HEXDIR_LEN);
5657
		crp->cr_clp = NULL;
5658
		nn->reclaim_str_hashtbl_size++;
5659 5660
	}
	return crp;
L
Linus Torvalds 已提交
5661 5662
}

5663
void
5664
nfs4_remove_reclaim_record(struct nfs4_client_reclaim *crp, struct nfsd_net *nn)
5665 5666 5667
{
	list_del(&crp->cr_strhash);
	kfree(crp);
5668
	nn->reclaim_str_hashtbl_size--;
5669 5670
}

5671
void
5672
nfs4_release_reclaim(struct nfsd_net *nn)
L
Linus Torvalds 已提交
5673 5674 5675 5676 5677
{
	struct nfs4_client_reclaim *crp = NULL;
	int i;

	for (i = 0; i < CLIENT_HASH_SIZE; i++) {
5678 5679
		while (!list_empty(&nn->reclaim_str_hashtbl[i])) {
			crp = list_entry(nn->reclaim_str_hashtbl[i].next,
L
Linus Torvalds 已提交
5680
			                struct nfs4_client_reclaim, cr_strhash);
5681
			nfs4_remove_reclaim_record(crp, nn);
L
Linus Torvalds 已提交
5682 5683
		}
	}
5684
	WARN_ON_ONCE(nn->reclaim_str_hashtbl_size);
L
Linus Torvalds 已提交
5685 5686 5687 5688
}

/*
 * called from OPEN, CLAIM_PREVIOUS with a new clientid. */
5689
struct nfs4_client_reclaim *
5690
nfsd4_find_reclaim_client(const char *recdir, struct nfsd_net *nn)
L
Linus Torvalds 已提交
5691 5692 5693 5694
{
	unsigned int strhashval;
	struct nfs4_client_reclaim *crp = NULL;

5695
	dprintk("NFSD: nfs4_find_reclaim_client for recdir %s\n", recdir);
L
Linus Torvalds 已提交
5696

5697
	strhashval = clientstr_hashval(recdir);
5698
	list_for_each_entry(crp, &nn->reclaim_str_hashtbl[strhashval], cr_strhash) {
5699
		if (same_name(crp->cr_recdir, recdir)) {
L
Linus Torvalds 已提交
5700 5701 5702 5703 5704 5705 5706 5707 5708
			return crp;
		}
	}
	return NULL;
}

/*
* Called from OPEN. Look for clientid in reclaim list.
*/
5709
__be32
5710 5711 5712
nfs4_check_open_reclaim(clientid_t *clid,
		struct nfsd4_compound_state *cstate,
		struct nfsd_net *nn)
L
Linus Torvalds 已提交
5713
{
5714
	__be32 status;
5715 5716

	/* find clientid in conf_id_hashtbl */
5717 5718
	status = lookup_clientid(clid, cstate, nn);
	if (status)
5719 5720
		return nfserr_reclaim_bad;

5721 5722 5723
	if (test_bit(NFSD4_CLIENT_RECLAIM_COMPLETE, &cstate->clp->cl_flags))
		return nfserr_no_grace;

5724 5725 5726 5727
	if (nfsd4_client_record_check(cstate->clp))
		return nfserr_reclaim_bad;

	return nfs_ok;
L
Linus Torvalds 已提交
5728 5729
}

B
Bryan Schumaker 已提交
5730
#ifdef CONFIG_NFSD_FAULT_INJECTION
5731 5732 5733 5734 5735 5736
static inline void
put_client(struct nfs4_client *clp)
{
	atomic_dec(&clp->cl_refcount);
}

5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753
static struct nfs4_client *
nfsd_find_client(struct sockaddr_storage *addr, size_t addr_size)
{
	struct nfs4_client *clp;
	struct nfsd_net *nn = net_generic(current->nsproxy->net_ns,
					  nfsd_net_id);

	if (!nfsd_netns_ready(nn))
		return NULL;

	list_for_each_entry(clp, &nn->client_lru, cl_lru) {
		if (memcmp(&clp->cl_addr, addr, addr_size) == 0)
			return clp;
	}
	return NULL;
}

5754
u64
5755
nfsd_inject_print_clients(void)
5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775
{
	struct nfs4_client *clp;
	u64 count = 0;
	struct nfsd_net *nn = net_generic(current->nsproxy->net_ns,
					  nfsd_net_id);
	char buf[INET6_ADDRSTRLEN];

	if (!nfsd_netns_ready(nn))
		return 0;

	spin_lock(&nn->client_lock);
	list_for_each_entry(clp, &nn->client_lru, cl_lru) {
		rpc_ntop((struct sockaddr *)&clp->cl_addr, buf, sizeof(buf));
		pr_info("NFS Client: %s\n", buf);
		++count;
	}
	spin_unlock(&nn->client_lock);

	return count;
}
B
Bryan Schumaker 已提交
5776

5777
u64
5778
nfsd_inject_forget_client(struct sockaddr_storage *addr, size_t addr_size)
5779 5780 5781 5782 5783 5784 5785 5786 5787 5788 5789 5790 5791 5792 5793 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803
{
	u64 count = 0;
	struct nfs4_client *clp;
	struct nfsd_net *nn = net_generic(current->nsproxy->net_ns,
					  nfsd_net_id);

	if (!nfsd_netns_ready(nn))
		return count;

	spin_lock(&nn->client_lock);
	clp = nfsd_find_client(addr, addr_size);
	if (clp) {
		if (mark_client_expired_locked(clp) == nfs_ok)
			++count;
		else
			clp = NULL;
	}
	spin_unlock(&nn->client_lock);

	if (clp)
		expire_client(clp);

	return count;
}

5804
u64
5805
nfsd_inject_forget_clients(u64 max)
5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831
{
	u64 count = 0;
	struct nfs4_client *clp, *next;
	struct nfsd_net *nn = net_generic(current->nsproxy->net_ns,
						nfsd_net_id);
	LIST_HEAD(reaplist);

	if (!nfsd_netns_ready(nn))
		return count;

	spin_lock(&nn->client_lock);
	list_for_each_entry_safe(clp, next, &nn->client_lru, cl_lru) {
		if (mark_client_expired_locked(clp) == nfs_ok) {
			list_add(&clp->cl_lru, &reaplist);
			if (max != 0 && ++count >= max)
				break;
		}
	}
	spin_unlock(&nn->client_lock);

	list_for_each_entry_safe(clp, next, &reaplist, cl_lru)
		expire_client(clp);

	return count;
}

5832 5833 5834 5835
static void nfsd_print_count(struct nfs4_client *clp, unsigned int count,
			     const char *type)
{
	char buf[INET6_ADDRSTRLEN];
5836
	rpc_ntop((struct sockaddr *)&clp->cl_addr, buf, sizeof(buf));
5837 5838 5839
	printk(KERN_INFO "NFS Client: %s has %u %s\n", buf, count, type);
}

5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855
static void
nfsd_inject_add_lock_to_list(struct nfs4_ol_stateid *lst,
			     struct list_head *collect)
{
	struct nfs4_client *clp = lst->st_stid.sc_client;
	struct nfsd_net *nn = net_generic(current->nsproxy->net_ns,
					  nfsd_net_id);

	if (!collect)
		return;

	lockdep_assert_held(&nn->client_lock);
	atomic_inc(&clp->cl_refcount);
	list_add(&lst->st_locks, collect);
}

5856
static u64 nfsd_foreach_client_lock(struct nfs4_client *clp, u64 max,
5857
				    struct list_head *collect,
5858
				    void (*func)(struct nfs4_ol_stateid *))
B
Bryan Schumaker 已提交
5859 5860 5861
{
	struct nfs4_openowner *oop;
	struct nfs4_ol_stateid *stp, *st_next;
5862
	struct nfs4_ol_stateid *lst, *lst_next;
B
Bryan Schumaker 已提交
5863 5864
	u64 count = 0;

5865
	spin_lock(&clp->cl_lock);
B
Bryan Schumaker 已提交
5866
	list_for_each_entry(oop, &clp->cl_openowners, oo_perclient) {
5867 5868 5869 5870
		list_for_each_entry_safe(stp, st_next,
				&oop->oo_owner.so_stateids, st_perstateowner) {
			list_for_each_entry_safe(lst, lst_next,
					&stp->st_locks, st_locks) {
5871
				if (func) {
5872
					func(lst);
5873 5874
					nfsd_inject_add_lock_to_list(lst,
								collect);
5875
				}
5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886
				++count;
				/*
				 * Despite the fact that these functions deal
				 * with 64-bit integers for "count", we must
				 * ensure that it doesn't blow up the
				 * clp->cl_refcount. Throw a warning if we
				 * start to approach INT_MAX here.
				 */
				WARN_ON_ONCE(count == (INT_MAX / 2));
				if (count == max)
					goto out;
B
Bryan Schumaker 已提交
5887 5888 5889
			}
		}
	}
5890 5891
out:
	spin_unlock(&clp->cl_lock);
B
Bryan Schumaker 已提交
5892 5893 5894 5895

	return count;
}

5896 5897 5898
static u64
nfsd_collect_client_locks(struct nfs4_client *clp, struct list_head *collect,
			  u64 max)
B
Bryan Schumaker 已提交
5899
{
5900
	return nfsd_foreach_client_lock(clp, max, collect, unhash_lock_stateid);
B
Bryan Schumaker 已提交
5901 5902
}

5903 5904
static u64
nfsd_print_client_locks(struct nfs4_client *clp)
5905
{
5906
	u64 count = nfsd_foreach_client_lock(clp, 0, NULL, NULL);
5907 5908 5909 5910
	nfsd_print_count(clp, count, "locked files");
	return count;
}

5911
u64
5912
nfsd_inject_print_locks(void)
5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944
{
	struct nfs4_client *clp;
	u64 count = 0;
	struct nfsd_net *nn = net_generic(current->nsproxy->net_ns,
						nfsd_net_id);

	if (!nfsd_netns_ready(nn))
		return 0;

	spin_lock(&nn->client_lock);
	list_for_each_entry(clp, &nn->client_lru, cl_lru)
		count += nfsd_print_client_locks(clp);
	spin_unlock(&nn->client_lock);

	return count;
}

static void
nfsd_reap_locks(struct list_head *reaplist)
{
	struct nfs4_client *clp;
	struct nfs4_ol_stateid *stp, *next;

	list_for_each_entry_safe(stp, next, reaplist, st_locks) {
		list_del_init(&stp->st_locks);
		clp = stp->st_stid.sc_client;
		nfs4_put_stid(&stp->st_stid);
		put_client(clp);
	}
}

u64
5945
nfsd_inject_forget_client_locks(struct sockaddr_storage *addr, size_t addr_size)
5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965
{
	unsigned int count = 0;
	struct nfs4_client *clp;
	struct nfsd_net *nn = net_generic(current->nsproxy->net_ns,
						nfsd_net_id);
	LIST_HEAD(reaplist);

	if (!nfsd_netns_ready(nn))
		return count;

	spin_lock(&nn->client_lock);
	clp = nfsd_find_client(addr, addr_size);
	if (clp)
		count = nfsd_collect_client_locks(clp, &reaplist, 0);
	spin_unlock(&nn->client_lock);
	nfsd_reap_locks(&reaplist);
	return count;
}

u64
5966
nfsd_inject_forget_locks(u64 max)
5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987
{
	u64 count = 0;
	struct nfs4_client *clp;
	struct nfsd_net *nn = net_generic(current->nsproxy->net_ns,
						nfsd_net_id);
	LIST_HEAD(reaplist);

	if (!nfsd_netns_ready(nn))
		return count;

	spin_lock(&nn->client_lock);
	list_for_each_entry(clp, &nn->client_lru, cl_lru) {
		count += nfsd_collect_client_locks(clp, &reaplist, max - count);
		if (max != 0 && count >= max)
			break;
	}
	spin_unlock(&nn->client_lock);
	nfsd_reap_locks(&reaplist);
	return count;
}

5988 5989 5990 5991
static u64
nfsd_foreach_client_openowner(struct nfs4_client *clp, u64 max,
			      struct list_head *collect,
			      void (*func)(struct nfs4_openowner *))
5992 5993
{
	struct nfs4_openowner *oop, *next;
5994 5995
	struct nfsd_net *nn = net_generic(current->nsproxy->net_ns,
						nfsd_net_id);
5996 5997
	u64 count = 0;

5998 5999 6000
	lockdep_assert_held(&nn->client_lock);

	spin_lock(&clp->cl_lock);
6001
	list_for_each_entry_safe(oop, next, &clp->cl_openowners, oo_perclient) {
6002
		if (func) {
6003
			func(oop);
6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017
			if (collect) {
				atomic_inc(&clp->cl_refcount);
				list_add(&oop->oo_perclient, collect);
			}
		}
		++count;
		/*
		 * Despite the fact that these functions deal with
		 * 64-bit integers for "count", we must ensure that
		 * it doesn't blow up the clp->cl_refcount. Throw a
		 * warning if we start to approach INT_MAX here.
		 */
		WARN_ON_ONCE(count == (INT_MAX / 2));
		if (count == max)
6018 6019
			break;
	}
6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042
	spin_unlock(&clp->cl_lock);

	return count;
}

static u64
nfsd_print_client_openowners(struct nfs4_client *clp)
{
	u64 count = nfsd_foreach_client_openowner(clp, 0, NULL, NULL);

	nfsd_print_count(clp, count, "openowners");
	return count;
}

static u64
nfsd_collect_client_openowners(struct nfs4_client *clp,
			       struct list_head *collect, u64 max)
{
	return nfsd_foreach_client_openowner(clp, max, collect,
						unhash_openowner_locked);
}

u64
6043
nfsd_inject_print_openowners(void)
6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056
{
	struct nfs4_client *clp;
	u64 count = 0;
	struct nfsd_net *nn = net_generic(current->nsproxy->net_ns,
						nfsd_net_id);

	if (!nfsd_netns_ready(nn))
		return 0;

	spin_lock(&nn->client_lock);
	list_for_each_entry(clp, &nn->client_lru, cl_lru)
		count += nfsd_print_client_openowners(clp);
	spin_unlock(&nn->client_lock);
6057 6058 6059 6060

	return count;
}

6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075
static void
nfsd_reap_openowners(struct list_head *reaplist)
{
	struct nfs4_client *clp;
	struct nfs4_openowner *oop, *next;

	list_for_each_entry_safe(oop, next, reaplist, oo_perclient) {
		list_del_init(&oop->oo_perclient);
		clp = oop->oo_owner.so_client;
		release_openowner(oop);
		put_client(clp);
	}
}

u64
6076 6077
nfsd_inject_forget_client_openowners(struct sockaddr_storage *addr,
				     size_t addr_size)
6078
{
6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094
	unsigned int count = 0;
	struct nfs4_client *clp;
	struct nfsd_net *nn = net_generic(current->nsproxy->net_ns,
						nfsd_net_id);
	LIST_HEAD(reaplist);

	if (!nfsd_netns_ready(nn))
		return count;

	spin_lock(&nn->client_lock);
	clp = nfsd_find_client(addr, addr_size);
	if (clp)
		count = nfsd_collect_client_openowners(clp, &reaplist, 0);
	spin_unlock(&nn->client_lock);
	nfsd_reap_openowners(&reaplist);
	return count;
6095 6096
}

6097
u64
6098
nfsd_inject_forget_openowners(u64 max)
6099
{
6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117
	u64 count = 0;
	struct nfs4_client *clp;
	struct nfsd_net *nn = net_generic(current->nsproxy->net_ns,
						nfsd_net_id);
	LIST_HEAD(reaplist);

	if (!nfsd_netns_ready(nn))
		return count;

	spin_lock(&nn->client_lock);
	list_for_each_entry(clp, &nn->client_lru, cl_lru) {
		count += nfsd_collect_client_openowners(clp, &reaplist,
							max - count);
		if (max != 0 && count >= max)
			break;
	}
	spin_unlock(&nn->client_lock);
	nfsd_reap_openowners(&reaplist);
6118 6119 6120
	return count;
}

6121 6122 6123 6124
static u64 nfsd_find_all_delegations(struct nfs4_client *clp, u64 max,
				     struct list_head *victims)
{
	struct nfs4_delegation *dp, *next;
6125 6126
	struct nfsd_net *nn = net_generic(current->nsproxy->net_ns,
						nfsd_net_id);
6127 6128
	u64 count = 0;

6129 6130 6131
	lockdep_assert_held(&nn->client_lock);

	spin_lock(&state_lock);
6132
	list_for_each_entry_safe(dp, next, &clp->cl_delegations, dl_perclnt) {
6133 6134 6135 6136 6137 6138 6139 6140 6141 6142
		if (victims) {
			/*
			 * It's not safe to mess with delegations that have a
			 * non-zero dl_time. They might have already been broken
			 * and could be processed by the laundromat outside of
			 * the state_lock. Just leave them be.
			 */
			if (dp->dl_time != 0)
				continue;

6143
			atomic_inc(&clp->cl_refcount);
6144 6145
			unhash_delegation_locked(dp);
			list_add(&dp->dl_recall_lru, victims);
6146
		}
6147 6148 6149 6150 6151 6152 6153 6154 6155
		++count;
		/*
		 * Despite the fact that these functions deal with
		 * 64-bit integers for "count", we must ensure that
		 * it doesn't blow up the clp->cl_refcount. Throw a
		 * warning if we start to approach INT_MAX here.
		 */
		WARN_ON_ONCE(count == (INT_MAX / 2));
		if (count == max)
6156 6157
			break;
	}
6158
	spin_unlock(&state_lock);
6159 6160 6161
	return count;
}

6162 6163
static u64
nfsd_print_client_delegations(struct nfs4_client *clp)
6164
{
6165
	u64 count = nfsd_find_all_delegations(clp, 0, NULL);
6166

6167 6168 6169 6170 6171
	nfsd_print_count(clp, count, "delegations");
	return count;
}

u64
6172
nfsd_inject_print_delegations(void)
6173 6174 6175 6176 6177 6178 6179 6180
{
	struct nfs4_client *clp;
	u64 count = 0;
	struct nfsd_net *nn = net_generic(current->nsproxy->net_ns,
						nfsd_net_id);

	if (!nfsd_netns_ready(nn))
		return 0;
6181

6182 6183 6184 6185 6186 6187 6188 6189 6190 6191 6192 6193 6194 6195 6196
	spin_lock(&nn->client_lock);
	list_for_each_entry(clp, &nn->client_lru, cl_lru)
		count += nfsd_print_client_delegations(clp);
	spin_unlock(&nn->client_lock);

	return count;
}

static void
nfsd_forget_delegations(struct list_head *reaplist)
{
	struct nfs4_client *clp;
	struct nfs4_delegation *dp, *next;

	list_for_each_entry_safe(dp, next, reaplist, dl_recall_lru) {
6197
		list_del_init(&dp->dl_recall_lru);
6198
		clp = dp->dl_stid.sc_client;
6199
		revoke_delegation(dp);
6200
		put_client(clp);
6201
	}
6202 6203 6204
}

u64
6205 6206
nfsd_inject_forget_client_delegations(struct sockaddr_storage *addr,
				      size_t addr_size)
6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222 6223 6224 6225
{
	u64 count = 0;
	struct nfs4_client *clp;
	struct nfsd_net *nn = net_generic(current->nsproxy->net_ns,
						nfsd_net_id);
	LIST_HEAD(reaplist);

	if (!nfsd_netns_ready(nn))
		return count;

	spin_lock(&nn->client_lock);
	clp = nfsd_find_client(addr, addr_size);
	if (clp)
		count = nfsd_find_all_delegations(clp, 0, &reaplist);
	spin_unlock(&nn->client_lock);

	nfsd_forget_delegations(&reaplist);
	return count;
}
6226

6227
u64
6228
nfsd_inject_forget_delegations(u64 max)
6229 6230 6231 6232 6233 6234 6235 6236 6237 6238 6239 6240 6241 6242 6243 6244 6245 6246
{
	u64 count = 0;
	struct nfs4_client *clp;
	struct nfsd_net *nn = net_generic(current->nsproxy->net_ns,
						nfsd_net_id);
	LIST_HEAD(reaplist);

	if (!nfsd_netns_ready(nn))
		return count;

	spin_lock(&nn->client_lock);
	list_for_each_entry(clp, &nn->client_lru, cl_lru) {
		count += nfsd_find_all_delegations(clp, max - count, &reaplist);
		if (max != 0 && count >= max)
			break;
	}
	spin_unlock(&nn->client_lock);
	nfsd_forget_delegations(&reaplist);
6247 6248 6249
	return count;
}

6250 6251
static void
nfsd_recall_delegations(struct list_head *reaplist)
6252
{
6253 6254
	struct nfs4_client *clp;
	struct nfs4_delegation *dp, *next;
6255

6256
	list_for_each_entry_safe(dp, next, reaplist, dl_recall_lru) {
6257
		list_del_init(&dp->dl_recall_lru);
6258 6259 6260 6261 6262 6263 6264 6265
		clp = dp->dl_stid.sc_client;
		/*
		 * We skipped all entries that had a zero dl_time before,
		 * so we can now reset the dl_time back to 0. If a delegation
		 * break comes in now, then it won't make any difference since
		 * we're recalling it either way.
		 */
		spin_lock(&state_lock);
6266
		dp->dl_time = 0;
6267
		spin_unlock(&state_lock);
6268
		nfsd_break_one_deleg(dp);
6269
		put_client(clp);
6270
	}
6271
}
6272

6273
u64
6274
nfsd_inject_recall_client_delegations(struct sockaddr_storage *addr,
6275 6276 6277 6278 6279 6280 6281 6282 6283 6284 6285 6286 6287 6288 6289 6290 6291 6292
				      size_t addr_size)
{
	u64 count = 0;
	struct nfs4_client *clp;
	struct nfsd_net *nn = net_generic(current->nsproxy->net_ns,
						nfsd_net_id);
	LIST_HEAD(reaplist);

	if (!nfsd_netns_ready(nn))
		return count;

	spin_lock(&nn->client_lock);
	clp = nfsd_find_client(addr, addr_size);
	if (clp)
		count = nfsd_find_all_delegations(clp, 0, &reaplist);
	spin_unlock(&nn->client_lock);

	nfsd_recall_delegations(&reaplist);
6293 6294 6295
	return count;
}

6296
u64
6297
nfsd_inject_recall_delegations(u64 max)
6298 6299
{
	u64 count = 0;
6300 6301 6302 6303
	struct nfs4_client *clp, *next;
	struct nfsd_net *nn = net_generic(current->nsproxy->net_ns,
						nfsd_net_id);
	LIST_HEAD(reaplist);
6304

6305 6306
	if (!nfsd_netns_ready(nn))
		return count;
6307

6308 6309 6310 6311 6312 6313 6314 6315
	spin_lock(&nn->client_lock);
	list_for_each_entry_safe(clp, next, &nn->client_lru, cl_lru) {
		count += nfsd_find_all_delegations(clp, max - count, &reaplist);
		if (max != 0 && ++count >= max)
			break;
	}
	spin_unlock(&nn->client_lock);
	nfsd_recall_delegations(&reaplist);
6316 6317
	return count;
}
B
Bryan Schumaker 已提交
6318 6319
#endif /* CONFIG_NFSD_FAULT_INJECTION */

6320 6321 6322 6323 6324 6325 6326 6327 6328 6329 6330 6331 6332 6333 6334 6335 6336 6337 6338 6339 6340
/*
 * Since the lifetime of a delegation isn't limited to that of an open, a
 * client may quite reasonably hang on to a delegation as long as it has
 * the inode cached.  This becomes an obvious problem the first time a
 * client's inode cache approaches the size of the server's total memory.
 *
 * For now we avoid this problem by imposing a hard limit on the number
 * of delegations, which varies according to the server's memory size.
 */
static void
set_max_delegations(void)
{
	/*
	 * Allow at most 4 delegations per megabyte of RAM.  Quick
	 * estimates suggest that in the worst case (where every delegation
	 * is for a different inode), a delegation could take about 1.5K,
	 * giving a worst case usage of about 6% of memory.
	 */
	max_delegations = nr_free_buffer_pages() >> (20 - 2 - PAGE_SHIFT);
}

6341
static int nfs4_state_create_net(struct net *net)
6342 6343 6344 6345 6346 6347 6348
{
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
	int i;

	nn->conf_id_hashtbl = kmalloc(sizeof(struct list_head) *
			CLIENT_HASH_SIZE, GFP_KERNEL);
	if (!nn->conf_id_hashtbl)
6349
		goto err;
6350 6351 6352 6353
	nn->unconf_id_hashtbl = kmalloc(sizeof(struct list_head) *
			CLIENT_HASH_SIZE, GFP_KERNEL);
	if (!nn->unconf_id_hashtbl)
		goto err_unconf_id;
6354 6355 6356 6357
	nn->sessionid_hashtbl = kmalloc(sizeof(struct list_head) *
			SESSION_HASH_SIZE, GFP_KERNEL);
	if (!nn->sessionid_hashtbl)
		goto err_sessionid;
6358

6359
	for (i = 0; i < CLIENT_HASH_SIZE; i++) {
6360
		INIT_LIST_HEAD(&nn->conf_id_hashtbl[i]);
6361
		INIT_LIST_HEAD(&nn->unconf_id_hashtbl[i]);
6362
	}
6363 6364
	for (i = 0; i < SESSION_HASH_SIZE; i++)
		INIT_LIST_HEAD(&nn->sessionid_hashtbl[i]);
6365
	nn->conf_name_tree = RB_ROOT;
6366
	nn->unconf_name_tree = RB_ROOT;
6367
	INIT_LIST_HEAD(&nn->client_lru);
6368
	INIT_LIST_HEAD(&nn->close_lru);
6369
	INIT_LIST_HEAD(&nn->del_recall_lru);
6370
	spin_lock_init(&nn->client_lock);
6371

6372
	INIT_DELAYED_WORK(&nn->laundromat_work, laundromat_main);
6373
	get_net(net);
6374

6375
	return 0;
6376

6377
err_sessionid:
6378
	kfree(nn->unconf_id_hashtbl);
6379 6380
err_unconf_id:
	kfree(nn->conf_id_hashtbl);
6381 6382
err:
	return -ENOMEM;
6383 6384 6385
}

static void
6386
nfs4_state_destroy_net(struct net *net)
6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397
{
	int i;
	struct nfs4_client *clp = NULL;
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);

	for (i = 0; i < CLIENT_HASH_SIZE; i++) {
		while (!list_empty(&nn->conf_id_hashtbl[i])) {
			clp = list_entry(nn->conf_id_hashtbl[i].next, struct nfs4_client, cl_idhash);
			destroy_client(clp);
		}
	}
6398

6399 6400 6401 6402 6403
	for (i = 0; i < CLIENT_HASH_SIZE; i++) {
		while (!list_empty(&nn->unconf_id_hashtbl[i])) {
			clp = list_entry(nn->unconf_id_hashtbl[i].next, struct nfs4_client, cl_idhash);
			destroy_client(clp);
		}
6404 6405
	}

6406
	kfree(nn->sessionid_hashtbl);
6407
	kfree(nn->unconf_id_hashtbl);
6408
	kfree(nn->conf_id_hashtbl);
6409
	put_net(net);
6410 6411
}

6412
int
6413
nfs4_state_start_net(struct net *net)
6414
{
6415
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
6416 6417
	int ret;

6418
	ret = nfs4_state_create_net(net);
6419 6420
	if (ret)
		return ret;
6421
	nn->boot_time = get_seconds();
6422
	nn->grace_ended = false;
6423 6424
	locks_start_grace(net, &nn->nfsd4_manager);
	nfsd4_client_tracking_init(net);
6425
	printk(KERN_INFO "NFSD: starting %ld-second grace period (net %p)\n",
6426 6427
	       nn->nfsd4_grace, net);
	queue_delayed_work(laundry_wq, &nn->laundromat_work, nn->nfsd4_grace * HZ);
6428 6429 6430 6431 6432 6433 6434 6435 6436 6437
	return 0;
}

/* initialization to perform when the nfsd service is started: */

int
nfs4_state_start(void)
{
	int ret;

6438
	ret = set_callback_cred();
6439 6440
	if (ret)
		return -ENOMEM;
6441
	laundry_wq = create_singlethread_workqueue("nfsd4");
6442 6443 6444 6445
	if (laundry_wq == NULL) {
		ret = -ENOMEM;
		goto out_recovery;
	}
6446 6447 6448
	ret = nfsd4_create_callback_queue();
	if (ret)
		goto out_free_laundry;
6449

6450
	set_max_delegations();
6451

6452
	return 0;
6453

6454 6455
out_free_laundry:
	destroy_workqueue(laundry_wq);
6456
out_recovery:
6457
	return ret;
L
Linus Torvalds 已提交
6458 6459
}

6460
void
6461
nfs4_state_shutdown_net(struct net *net)
L
Linus Torvalds 已提交
6462 6463 6464
{
	struct nfs4_delegation *dp = NULL;
	struct list_head *pos, *next, reaplist;
6465
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
L
Linus Torvalds 已提交
6466

6467 6468
	cancel_delayed_work_sync(&nn->laundromat_work);
	locks_end_grace(&nn->nfsd4_manager);
6469

L
Linus Torvalds 已提交
6470
	INIT_LIST_HEAD(&reaplist);
6471
	spin_lock(&state_lock);
6472
	list_for_each_safe(pos, next, &nn->del_recall_lru) {
L
Linus Torvalds 已提交
6473
		dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
6474 6475
		unhash_delegation_locked(dp);
		list_add(&dp->dl_recall_lru, &reaplist);
L
Linus Torvalds 已提交
6476
	}
6477
	spin_unlock(&state_lock);
L
Linus Torvalds 已提交
6478 6479
	list_for_each_safe(pos, next, &reaplist) {
		dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
6480
		list_del_init(&dp->dl_recall_lru);
6481
		nfs4_put_deleg_lease(dp->dl_stid.sc_file);
6482
		nfs4_put_stid(&dp->dl_stid);
L
Linus Torvalds 已提交
6483 6484
	}

6485
	nfsd4_client_tracking_exit(net);
6486
	nfs4_state_destroy_net(net);
L
Linus Torvalds 已提交
6487 6488 6489 6490 6491
}

void
nfs4_state_shutdown(void)
{
6492
	destroy_workqueue(laundry_wq);
6493
	nfsd4_destroy_callback_queue();
L
Linus Torvalds 已提交
6494
}
6495 6496 6497 6498

static void
get_stateid(struct nfsd4_compound_state *cstate, stateid_t *stateid)
{
6499 6500
	if (HAS_STATE_ID(cstate, CURRENT_STATE_ID_FLAG) && CURRENT_STATEID(stateid))
		memcpy(stateid, &cstate->current_stateid, sizeof(stateid_t));
6501 6502 6503 6504 6505
}

static void
put_stateid(struct nfsd4_compound_state *cstate, stateid_t *stateid)
{
6506 6507 6508 6509 6510 6511 6512 6513 6514 6515
	if (cstate->minorversion) {
		memcpy(&cstate->current_stateid, stateid, sizeof(stateid_t));
		SET_STATE_ID(cstate, CURRENT_STATE_ID_FLAG);
	}
}

void
clear_current_stateid(struct nfsd4_compound_state *cstate)
{
	CLEAR_STATE_ID(cstate, CURRENT_STATE_ID_FLAG);
6516 6517
}

6518 6519 6520
/*
 * functions to set current state id
 */
6521 6522 6523 6524 6525 6526
void
nfsd4_set_opendowngradestateid(struct nfsd4_compound_state *cstate, struct nfsd4_open_downgrade *odp)
{
	put_stateid(cstate, &odp->od_stateid);
}

6527 6528 6529 6530 6531 6532
void
nfsd4_set_openstateid(struct nfsd4_compound_state *cstate, struct nfsd4_open *open)
{
	put_stateid(cstate, &open->op_stateid);
}

6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547
void
nfsd4_set_closestateid(struct nfsd4_compound_state *cstate, struct nfsd4_close *close)
{
	put_stateid(cstate, &close->cl_stateid);
}

void
nfsd4_set_lockstateid(struct nfsd4_compound_state *cstate, struct nfsd4_lock *lock)
{
	put_stateid(cstate, &lock->lk_resp_stateid);
}

/*
 * functions to consume current state id
 */
6548

6549 6550 6551 6552 6553 6554 6555 6556 6557 6558 6559 6560
void
nfsd4_get_opendowngradestateid(struct nfsd4_compound_state *cstate, struct nfsd4_open_downgrade *odp)
{
	get_stateid(cstate, &odp->od_stateid);
}

void
nfsd4_get_delegreturnstateid(struct nfsd4_compound_state *cstate, struct nfsd4_delegreturn *drp)
{
	get_stateid(cstate, &drp->dr_stateid);
}

6561 6562 6563 6564 6565 6566 6567 6568 6569 6570 6571 6572
void
nfsd4_get_freestateid(struct nfsd4_compound_state *cstate, struct nfsd4_free_stateid *fsp)
{
	get_stateid(cstate, &fsp->fr_stateid);
}

void
nfsd4_get_setattrstateid(struct nfsd4_compound_state *cstate, struct nfsd4_setattr *setattr)
{
	get_stateid(cstate, &setattr->sa_stateid);
}

6573 6574 6575 6576 6577 6578 6579
void
nfsd4_get_closestateid(struct nfsd4_compound_state *cstate, struct nfsd4_close *close)
{
	get_stateid(cstate, &close->cl_stateid);
}

void
6580
nfsd4_get_lockustateid(struct nfsd4_compound_state *cstate, struct nfsd4_locku *locku)
6581
{
6582
	get_stateid(cstate, &locku->lu_stateid);
6583
}
6584 6585 6586 6587 6588 6589 6590 6591 6592 6593 6594 6595

void
nfsd4_get_readstateid(struct nfsd4_compound_state *cstate, struct nfsd4_read *read)
{
	get_stateid(cstate, &read->rd_stateid);
}

void
nfsd4_get_writestateid(struct nfsd4_compound_state *cstate, struct nfsd4_write *write)
{
	get_stateid(cstate, &write->wr_stateid);
}