nfs4state.c 155.1 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/hash.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
/* Locking: */

/* Currently used for almost all code touching nfsv4 state: */
I
Ingo Molnar 已提交
79
static DEFINE_MUTEX(client_mutex);
L
Linus Torvalds 已提交
80

81 82 83 84 85
/*
 * 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:
 */
86
static DEFINE_SPINLOCK(state_lock);
87

88 89 90 91 92 93
/*
 * 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 已提交
94 95 96 97 98
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 已提交
99

L
Linus Torvalds 已提交
100 101 102
void
nfs4_lock_state(void)
{
I
Ingo Molnar 已提交
103
	mutex_lock(&client_mutex);
L
Linus Torvalds 已提交
104 105
}

106
static void free_session(struct nfsd4_session *);
107

108
static bool is_session_dead(struct nfsd4_session *ses)
109
{
110
	return ses->se_flags & NFS4_SESSION_DEAD;
111 112
}

113
static __be32 mark_session_dead_locked(struct nfsd4_session *ses, int ref_held_by_me)
114
{
115
	if (atomic_read(&ses->se_ref) > ref_held_by_me)
116 117 118
		return nfserr_jukebox;
	ses->se_flags |= NFS4_SESSION_DEAD;
	return nfs_ok;
119 120
}

L
Linus Torvalds 已提交
121 122 123
void
nfs4_unlock_state(void)
{
I
Ingo Molnar 已提交
124
	mutex_unlock(&client_mutex);
L
Linus Torvalds 已提交
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 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
static bool is_client_expired(struct nfs4_client *clp)
{
	return clp->cl_time == 0;
}

static __be32 mark_client_expired_locked(struct nfs4_client *clp)
{
	if (atomic_read(&clp->cl_refcount))
		return nfserr_jukebox;
	clp->cl_time = 0;
	return nfs_ok;
}

static __be32 mark_client_expired(struct nfs4_client *clp)
{
	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
	__be32 ret;

	spin_lock(&nn->client_lock);
	ret = mark_client_expired_locked(clp);
	spin_unlock(&nn->client_lock);
	return ret;
}

static __be32 get_client_locked(struct nfs4_client *clp)
{
	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();
}

static inline void
renew_client(struct nfs4_client *clp)
{
	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);

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

191
static void put_client_renew_locked(struct nfs4_client *clp)
192 193 194 195 196 197 198
{
	if (!atomic_dec_and_test(&clp->cl_refcount))
		return;
	if (!is_client_expired(clp))
		renew_client_locked(clp);
}

199 200 201 202
static void put_client_renew(struct nfs4_client *clp)
{
	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);

203 204 205 206
	if (!atomic_dec_and_lock(&clp->cl_refcount, &nn->client_lock))
		return;
	if (!is_client_expired(clp))
		renew_client_locked(clp);
207 208 209
	spin_unlock(&nn->client_lock);
}

210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
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;

	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);
}

242
static int
243
same_owner_str(struct nfs4_stateowner *sop, struct xdr_netobj *owner)
244 245
{
	return (sop->so_owner.len == owner->len) &&
246
		0 == memcmp(sop->so_owner.data, owner->data, owner->len);
247 248 249 250
}

static struct nfs4_openowner *
find_openstateowner_str_locked(unsigned int hashval, struct nfsd4_open *open,
251
			struct nfs4_client *clp)
252 253 254
{
	struct nfs4_stateowner *so;

255
	lockdep_assert_held(&clp->cl_lock);
256

257 258
	list_for_each_entry(so, &clp->cl_ownerstr_hashtbl[hashval],
			    so_strhash) {
259 260
		if (!so->so_is_open_owner)
			continue;
261
		if (same_owner_str(so, &open->op_owner)) {
262
			atomic_inc(&so->so_count);
263
			return openowner(so);
264 265 266 267 268 269 270
		}
	}
	return NULL;
}

static struct nfs4_openowner *
find_openstateowner_str(unsigned int hashval, struct nfsd4_open *open,
271
			struct nfs4_client *clp)
272 273 274
{
	struct nfs4_openowner *oo;

275 276 277
	spin_lock(&clp->cl_lock);
	oo = find_openstateowner_str_locked(hashval, open, clp);
	spin_unlock(&clp->cl_lock);
278 279 280
	return oo;
}

L
Linus Torvalds 已提交
281 282 283 284 285 286 287 288 289 290 291 292 293
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;
}

294 295 296 297 298
static void nfsd4_free_file(struct nfs4_file *f)
{
	kmem_cache_free(file_slab, f);
}

299 300 301
static inline void
put_nfs4_file(struct nfs4_file *fi)
{
302 303
	might_lock(&state_lock);

304
	if (atomic_dec_and_lock(&fi->fi_ref, &state_lock)) {
305
		hlist_del(&fi->fi_hash);
306
		spin_unlock(&state_lock);
307
		nfsd4_free_file(fi);
308
	}
309 310 311 312 313
}

static inline void
get_nfs4_file(struct nfs4_file *fi)
{
314
	atomic_inc(&fi->fi_ref);
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 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389
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;
}

390
static atomic_long_t num_delegations;
391
unsigned long max_delegations;
392 393 394 395 396

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

397 398 399 400
/* 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)
401

402
static unsigned int ownerstr_hashval(struct xdr_netobj *ownername)
403 404 405 406
{
	unsigned int ret;

	ret = opaque_hashval(ownername->data, ownername->len);
407
	return ret & OWNER_HASH_MASK;
408
}
409 410 411 412

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

414
static unsigned int nfsd_fh_hashval(struct knfsd_fh *fh)
415
{
416 417 418 419 420 421 422 423 424 425 426 427 428 429
	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);
}

static bool nfsd_fh_match(struct knfsd_fh *fh1, struct knfsd_fh *fh2)
{
	return fh1->fh_size == fh2->fh_size &&
		!memcmp(fh1->fh_base.fh_pad,
				fh2->fh_base.fh_pad,
				fh1->fh_size);
430 431
}

432
static struct hlist_head file_hashtbl[FILE_HASH_SIZE];
433

434 435
static void
__nfs4_file_get_access(struct nfs4_file *fp, u32 access)
436
{
437 438
	lockdep_assert_held(&fp->fi_lock);

439 440 441 442
	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]);
443 444
}

445 446
static __be32
nfs4_file_get_access(struct nfs4_file *fp, u32 access)
447
{
448 449
	lockdep_assert_held(&fp->fi_lock);

450 451 452 453
	/* Does this access mode make sense? */
	if (access & ~NFS4_SHARE_ACCESS_BOTH)
		return nfserr_inval;

454 455 456 457
	/* Does it conflict with a deny mode already set? */
	if ((access & fp->fi_share_deny) != 0)
		return nfserr_share_denied;

458 459
	__nfs4_file_get_access(fp, access);
	return nfs_ok;
460 461
}

462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480
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;
}

481
static void __nfs4_file_put_access(struct nfs4_file *fp, int oflag)
482
{
483 484 485 486 487 488
	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 已提交
489
		swap(f1, fp->fi_fds[oflag]);
490
		if (atomic_read(&fp->fi_access[1 - oflag]) == 0)
J
Jeff Layton 已提交
491
			swap(f2, fp->fi_fds[O_RDWR]);
492 493 494 495 496
		spin_unlock(&fp->fi_lock);
		if (f1)
			fput(f1);
		if (f2)
			fput(f2);
497 498 499
	}
}

500
static void nfs4_file_put_access(struct nfs4_file *fp, u32 access)
501
{
502 503 504
	WARN_ON_ONCE(access & ~NFS4_SHARE_ACCESS_BOTH);

	if (access & NFS4_SHARE_ACCESS_WRITE)
505
		__nfs4_file_put_access(fp, O_WRONLY);
506 507
	if (access & NFS4_SHARE_ACCESS_READ)
		__nfs4_file_put_access(fp, O_RDONLY);
508 509
}

510 511
static struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl,
					 struct kmem_cache *slab)
512
{
J
J. Bruce Fields 已提交
513
	struct nfs4_stid *stid;
J
J. Bruce Fields 已提交
514
	int new_id;
515

516
	stid = kmem_cache_zalloc(slab, GFP_KERNEL);
J
J. Bruce Fields 已提交
517 518 519
	if (!stid)
		return NULL;

520 521 522 523 524
	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 已提交
525
	if (new_id < 0)
J
J. Bruce Fields 已提交
526
		goto out_free;
527
	stid->sc_client = cl;
J
J. Bruce Fields 已提交
528 529
	stid->sc_stateid.si_opaque.so_id = new_id;
	stid->sc_stateid.si_opaque.so_clid = cl->cl_clientid;
530
	/* Will be incremented before return to client: */
531
	atomic_set(&stid->sc_count, 1);
532 533

	/*
J
J. Bruce Fields 已提交
534 535 536 537 538 539 540
	 * 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):
541
	 */
J
J. Bruce Fields 已提交
542 543
	return stid;
out_free:
544
	kmem_cache_free(slab, stid);
J
J. Bruce Fields 已提交
545
	return NULL;
546 547
}

548
static struct nfs4_ol_stateid * nfs4_alloc_open_stateid(struct nfs4_client *clp)
549
{
550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565
	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);
566 567
}

568 569 570 571 572 573 574 575 576 577 578 579 580 581
/*
 * 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.
 *
582
 * 'blocked_delegations_lock', which is always taken in block_delegations(),
583 584 585
 * is used to manage concurrent access.  Testing does not need the lock
 * except when swapping the two filters.
 */
586
static DEFINE_SPINLOCK(blocked_delegations_lock);
587 588 589 590 591 592 593 594 595 596 597 598 599 600 601
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) {
602
		spin_lock(&blocked_delegations_lock);
603 604 605 606 607 608 609 610
		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();
		}
611
		spin_unlock(&blocked_delegations_lock);
612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633
	}
	hash = arch_fast_hash(&fh->fh_base, fh->fh_size, 0);
	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;

	hash = arch_fast_hash(&fh->fh_base, fh->fh_size, 0);

634
	spin_lock(&blocked_delegations_lock);
635 636 637 638 639 640
	__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;
641
	spin_unlock(&blocked_delegations_lock);
642 643
}

L
Linus Torvalds 已提交
644
static struct nfs4_delegation *
645
alloc_init_deleg(struct nfs4_client *clp, struct svc_fh *current_fh)
L
Linus Torvalds 已提交
646 647
{
	struct nfs4_delegation *dp;
648
	long n;
L
Linus Torvalds 已提交
649 650

	dprintk("NFSD alloc_init_deleg\n");
651 652 653
	n = atomic_long_inc_return(&num_delegations);
	if (n < 0 || n > max_delegations)
		goto out_dec;
654
	if (delegation_blocked(&current_fh->fh_handle))
655
		goto out_dec;
656
	dp = delegstateid(nfs4_alloc_stid(clp, deleg_slab));
N
NeilBrown 已提交
657
	if (dp == NULL)
658
		goto out_dec;
659 660

	dp->dl_stid.sc_free = nfs4_free_deleg;
661 662
	/*
	 * delegation seqid's are never incremented.  The 4.1 special
J
J. Bruce Fields 已提交
663 664
	 * meaning of seqid 0 isn't meaningful, really, but let's avoid
	 * 0 anyway just for consistency and use 1:
665 666
	 */
	dp->dl_stid.sc_stateid.si_generation = 1;
667 668
	INIT_LIST_HEAD(&dp->dl_perfile);
	INIT_LIST_HEAD(&dp->dl_perclnt);
L
Linus Torvalds 已提交
669
	INIT_LIST_HEAD(&dp->dl_recall_lru);
670
	dp->dl_type = NFS4_OPEN_DELEGATE_READ;
671
	INIT_WORK(&dp->dl_recall.cb_work, nfsd4_run_cb_recall);
L
Linus Torvalds 已提交
672
	return dp;
673 674 675
out_dec:
	atomic_long_dec(&num_delegations);
	return NULL;
L
Linus Torvalds 已提交
676 677 678
}

void
679
nfs4_put_stid(struct nfs4_stid *s)
L
Linus Torvalds 已提交
680
{
681
	struct nfs4_file *fp = s->sc_file;
682 683
	struct nfs4_client *clp = s->sc_client;

684 685
	might_lock(&clp->cl_lock);

686 687
	if (!atomic_dec_and_lock(&s->sc_count, &clp->cl_lock)) {
		wake_up_all(&close_wq);
688
		return;
689
	}
690
	idr_remove(&clp->cl_stateids, s->sc_stateid.si_opaque.so_id);
691
	spin_unlock(&clp->cl_lock);
692
	s->sc_free(s);
693 694
	if (fp)
		put_nfs4_file(fp);
L
Linus Torvalds 已提交
695 696
}

697
static void nfs4_put_deleg_lease(struct nfs4_file *fp)
L
Linus Torvalds 已提交
698
{
699 700
	lockdep_assert_held(&state_lock);

701 702
	if (!fp->fi_lease)
		return;
703 704 705
	if (atomic_dec_and_test(&fp->fi_delegees)) {
		vfs_setlease(fp->fi_deleg_file, F_UNLCK, &fp->fi_lease);
		fp->fi_lease = NULL;
706
		fput(fp->fi_deleg_file);
707 708
		fp->fi_deleg_file = NULL;
	}
L
Linus Torvalds 已提交
709 710
}

J
J. Bruce Fields 已提交
711 712
static void unhash_stid(struct nfs4_stid *s)
{
J
J. Bruce Fields 已提交
713
	s->sc_type = 0;
J
J. Bruce Fields 已提交
714 715
}

716 717 718
static void
hash_delegation_locked(struct nfs4_delegation *dp, struct nfs4_file *fp)
{
719
	lockdep_assert_held(&state_lock);
720
	lockdep_assert_held(&fp->fi_lock);
721

722
	atomic_inc(&dp->dl_stid.sc_count);
723
	dp->dl_stid.sc_type = NFS4_DELEG_STID;
724 725 726 727
	list_add(&dp->dl_perfile, &fp->fi_delegations);
	list_add(&dp->dl_perclnt, &dp->dl_stid.sc_client->cl_delegations);
}

L
Linus Torvalds 已提交
728
static void
729
unhash_delegation_locked(struct nfs4_delegation *dp)
L
Linus Torvalds 已提交
730
{
731
	struct nfs4_file *fp = dp->dl_stid.sc_file;
732

733 734
	lockdep_assert_held(&state_lock);

735
	dp->dl_stid.sc_type = NFS4_CLOSED_DELEG_STID;
736 737
	/* Ensure that deleg break won't try to requeue it */
	++dp->dl_time;
738
	spin_lock(&fp->fi_lock);
739
	list_del_init(&dp->dl_perclnt);
L
Linus Torvalds 已提交
740
	list_del_init(&dp->dl_recall_lru);
741 742
	list_del_init(&dp->dl_perfile);
	spin_unlock(&fp->fi_lock);
743
	if (fp)
744
		nfs4_put_deleg_lease(fp);
745 746 747 748
}

static void destroy_delegation(struct nfs4_delegation *dp)
{
749 750 751
	spin_lock(&state_lock);
	unhash_delegation_locked(dp);
	spin_unlock(&state_lock);
752
	nfs4_put_stid(&dp->dl_stid);
753 754 755 756 757 758
}

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

759 760
	WARN_ON(!list_empty(&dp->dl_recall_lru));

761
	if (clp->cl_minorversion == 0)
762
		nfs4_put_stid(&dp->dl_stid);
763 764
	else {
		dp->dl_stid.sc_type = NFS4_REVOKED_DELEG_STID;
765 766 767
		spin_lock(&clp->cl_lock);
		list_add(&dp->dl_recall_lru, &clp->cl_revoked);
		spin_unlock(&clp->cl_lock);
768 769 770
	}
}

L
Linus Torvalds 已提交
771 772 773 774
/* 
 * SETCLIENTID state 
 */

775 776 777 778 779 780 781 782 783 784
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;
}

785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802
/*
 * 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.
 */
803 804
static unsigned int
bmap_to_share_mode(unsigned long bmap) {
805
	int i;
806
	unsigned int access = 0;
807 808 809

	for (i = 1; i < 4; i++) {
		if (test_bit(i, &bmap))
810
			access |= i;
811
	}
812
	return access;
813 814
}

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

	WARN_ON_ONCE(access > NFS4_SHARE_ACCESS_BOTH);
	stp->st_access_bmap |= mask;
823 824 825 826 827 828
}

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

	WARN_ON_ONCE(access > NFS4_SHARE_ACCESS_BOTH);
	stp->st_access_bmap &= ~mask;
833 834 835 836 837 838
}

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

	return (bool)(stp->st_access_bmap & mask);
842 843
}

844 845
/* set share deny for a given stateid */
static inline void
846
set_deny(u32 deny, struct nfs4_ol_stateid *stp)
847
{
848 849 850 851
	unsigned char mask = 1 << deny;

	WARN_ON_ONCE(deny > NFS4_SHARE_DENY_BOTH);
	stp->st_deny_bmap |= mask;
852 853 854 855
}

/* clear share deny for a given stateid */
static inline void
856
clear_deny(u32 deny, struct nfs4_ol_stateid *stp)
857
{
858 859 860 861
	unsigned char mask = 1 << deny;

	WARN_ON_ONCE(deny > NFS4_SHARE_DENY_BOTH);
	stp->st_deny_bmap &= ~mask;
862 863 864 865
}

/* test whether a given stateid is denying specific access */
static inline bool
866
test_deny(u32 deny, struct nfs4_ol_stateid *stp)
867
{
868 869 870
	unsigned char mask = 1 << deny;

	return (bool)(stp->st_deny_bmap & mask);
871 872 873 874
}

static int nfs4_access_to_omode(u32 access)
{
875
	switch (access & NFS4_SHARE_ACCESS_BOTH) {
876 877 878 879 880 881 882
	case NFS4_SHARE_ACCESS_READ:
		return O_RDONLY;
	case NFS4_SHARE_ACCESS_WRITE:
		return O_WRONLY;
	case NFS4_SHARE_ACCESS_BOTH:
		return O_RDWR;
	}
883 884
	WARN_ON_ONCE(1);
	return O_RDONLY;
885 886
}

887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917
/*
 * 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)
918
		recalculate_deny_mode(stp->st_stid.sc_file);
919 920
}

921 922 923 924 925
/* release all access and file references for a given stateid */
static void
release_all_access(struct nfs4_ol_stateid *stp)
{
	int i;
926
	struct nfs4_file *fp = stp->st_stid.sc_file;
927 928 929

	if (fp && stp->st_deny_bmap != 0)
		recalculate_deny_mode(fp);
930 931 932

	for (i = 1; i < 4; i++) {
		if (test_access(i, stp))
933
			nfs4_file_put_access(stp->st_stid.sc_file, i);
934 935 936 937
		clear_access(i, stp);
	}
}

938 939
static void nfs4_put_stateowner(struct nfs4_stateowner *sop)
{
940 941 942 943 944
	struct nfs4_client *clp = sop->so_client;

	might_lock(&clp->cl_lock);

	if (!atomic_dec_and_lock(&sop->so_count, &clp->cl_lock))
945
		return;
946
	sop->so_ops->so_unhash(sop);
947
	spin_unlock(&clp->cl_lock);
948 949 950 951
	kfree(sop->so_owner.data);
	sop->so_ops->so_free(sop);
}

952
static void unhash_generic_stateid(struct nfs4_ol_stateid *stp)
953
{
954
	struct nfs4_file *fp = stp->st_stid.sc_file;
955

956 957
	lockdep_assert_held(&stp->st_stateowner->so_client->cl_lock);

958
	spin_lock(&fp->fi_lock);
959
	list_del(&stp->st_perfile);
960
	spin_unlock(&fp->fi_lock);
961 962 963
	list_del(&stp->st_perstateowner);
}

964
static void nfs4_free_ol_stateid(struct nfs4_stid *stid)
965
{
966
	struct nfs4_ol_stateid *stp = openlockstateid(stid);
967

968
	release_all_access(stp);
969 970
	if (stp->st_stateowner)
		nfs4_put_stateowner(stp->st_stateowner);
971
	kmem_cache_free(stateid_slab, stid);
972 973
}

974
static void nfs4_free_lock_stateid(struct nfs4_stid *stid)
975
{
976 977
	struct nfs4_ol_stateid *stp = openlockstateid(stid);
	struct nfs4_lockowner *lo = lockowner(stp->st_stateowner);
978 979
	struct file *file;

980 981 982 983 984 985
	file = find_any_file(stp->st_stid.sc_file);
	if (file)
		filp_close(file, (fl_owner_t)lo);
	nfs4_free_ol_stateid(stid);
}

986
static void unhash_lock_stateid(struct nfs4_ol_stateid *stp)
987
{
988 989
	struct nfs4_openowner *oo = openowner(stp->st_openstp->st_stateowner);

990 991 992
	lockdep_assert_held(&oo->oo_owner.so_client->cl_lock);

	list_del_init(&stp->st_locks);
993
	unhash_generic_stateid(stp);
J
J. Bruce Fields 已提交
994
	unhash_stid(&stp->st_stid);
995 996 997 998 999 1000 1001 1002
}

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);
1003
	spin_unlock(&oo->oo_owner.so_client->cl_lock);
1004
	nfs4_put_stid(&stp->st_stid);
1005 1006
}

1007
static void unhash_lockowner_locked(struct nfs4_lockowner *lo)
1008
{
1009
	struct nfs4_client *clp = lo->lo_owner.so_client;
1010

1011
	lockdep_assert_held(&clp->cl_lock);
1012

1013 1014 1015
	list_del_init(&lo->lo_owner.so_strhash);
}

1016
static void release_lockowner(struct nfs4_lockowner *lo)
1017
{
1018
	struct nfs4_client *clp = lo->lo_owner.so_client;
1019
	struct nfs4_ol_stateid *stp;
1020
	struct list_head reaplist;
1021

1022
	INIT_LIST_HEAD(&reaplist);
1023

1024 1025
	spin_lock(&clp->cl_lock);
	unhash_lockowner_locked(lo);
1026 1027
	while (!list_empty(&lo->lo_owner.so_stateids)) {
		stp = list_first_entry(&lo->lo_owner.so_stateids,
1028
				struct nfs4_ol_stateid, st_perstateowner);
1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039
		unhash_lock_stateid(stp);
		/*
		 * We now know that no new references can be added to the
		 * stateid. If ours is the last one, finish the unhashing
		 * and put it on the list to be reaped.
		 */
		if (atomic_dec_and_test(&stp->st_stid.sc_count)) {
			idr_remove(&clp->cl_stateids,
				stp->st_stid.sc_stateid.si_opaque.so_id);
			list_add(&stp->st_locks, &reaplist);
		}
1040
	}
1041
	spin_unlock(&clp->cl_lock);
1042 1043 1044 1045 1046 1047
	while (!list_empty(&reaplist)) {
		stp = list_first_entry(&reaplist, struct nfs4_ol_stateid,
					st_locks);
		list_del(&stp->st_locks);
		stp->st_stid.sc_free(&stp->st_stid);
	}
1048
	nfs4_put_stateowner(&lo->lo_owner);
1049 1050
}

1051
static void release_open_stateid_locks(struct nfs4_ol_stateid *open_stp)
1052 1053
	__releases(&open_stp->st_stateowner->so_client->cl_lock)
	__acquires(&open_stp->st_stateowner->so_client->cl_lock)
1054 1055 1056 1057 1058 1059
{
	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);
1060
		spin_unlock(&open_stp->st_stateowner->so_client->cl_lock);
1061
		release_lock_stateid(stp);
1062
		spin_lock(&open_stp->st_stateowner->so_client->cl_lock);
1063 1064 1065
	}
}

1066
static void unhash_open_stateid(struct nfs4_ol_stateid *stp)
1067
{
1068
	spin_lock(&stp->st_stateowner->so_client->cl_lock);
1069
	unhash_generic_stateid(stp);
1070
	release_open_stateid_locks(stp);
1071
	spin_unlock(&stp->st_stateowner->so_client->cl_lock);
1072 1073 1074 1075 1076
}

static void release_open_stateid(struct nfs4_ol_stateid *stp)
{
	unhash_open_stateid(stp);
1077
	nfs4_put_stid(&stp->st_stid);
1078 1079
}

1080
static void unhash_openowner_locked(struct nfs4_openowner *oo)
1081
{
1082
	struct nfs4_client *clp = oo->oo_owner.so_client;
1083

1084
	lockdep_assert_held(&clp->cl_lock);
1085

1086 1087
	list_del_init(&oo->oo_owner.so_strhash);
	list_del_init(&oo->oo_perclient);
1088 1089
}

1090 1091 1092 1093 1094
static void release_last_closed_stateid(struct nfs4_openowner *oo)
{
	struct nfs4_ol_stateid *s = oo->oo_last_closed_stid;

	if (s) {
1095
		list_del_init(&oo->oo_close_lru);
1096
		oo->oo_last_closed_stid = NULL;
1097
		nfs4_put_stid(&s->st_stid);
1098 1099 1100
	}
}

1101 1102 1103
static void release_openowner_stateids(struct nfs4_openowner *oo)
{
	struct nfs4_ol_stateid *stp;
1104
	struct nfs4_client *clp = oo->oo_owner.so_client;
1105

1106
	lockdep_assert_held(&clp->cl_lock);
1107 1108 1109 1110

	while (!list_empty(&oo->oo_owner.so_stateids)) {
		stp = list_first_entry(&oo->oo_owner.so_stateids,
				struct nfs4_ol_stateid, st_perstateowner);
1111
		spin_unlock(&clp->cl_lock);
1112
		release_open_stateid(stp);
1113
		spin_lock(&clp->cl_lock);
1114 1115 1116
	}
}

1117
static void release_openowner(struct nfs4_openowner *oo)
1118
{
1119
	struct nfs4_client *clp = oo->oo_owner.so_client;
1120

1121
	spin_lock(&clp->cl_lock);
1122
	unhash_openowner_locked(oo);
1123
	release_openowner_stateids(oo);
1124
	spin_unlock(&clp->cl_lock);
1125
	release_last_closed_stateid(oo);
1126
	nfs4_put_stateowner(&oo->oo_owner);
1127 1128
}

M
Marc Eshel 已提交
1129 1130 1131 1132 1133 1134 1135 1136
static inline int
hash_sessionid(struct nfs4_sessionid *sessionid)
{
	struct nfsd4_sessionid *sid = (struct nfsd4_sessionid *)sessionid;

	return sid->sequence % SESSION_HASH_SIZE;
}

1137
#ifdef NFSD_DEBUG
M
Marc Eshel 已提交
1138 1139 1140 1141 1142 1143
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]);
}
1144 1145 1146 1147 1148 1149 1150
#else
static inline void
dump_sessionid(const char *fn, struct nfs4_sessionid *sessionid)
{
}
#endif

1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162
/*
 * 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))) {
1163
		nfsd4_cstate_clear_replay(cstate);
1164 1165 1166 1167 1168 1169 1170 1171 1172
		return;
	}
	if (!so)
		return;
	if (so->so_is_open_owner)
		release_last_closed_stateid(openowner(so));
	so->so_seqid++;
	return;
}
M
Marc Eshel 已提交
1173

A
Andy Adamson 已提交
1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186
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;
}

/*
1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199
 * 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)

1200 1201 1202 1203 1204 1205 1206 1207 1208
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]);
}

1209
/*
1210 1211 1212
 * We don't actually need to cache the rpc and session headers, so we
 * can allocate a little less for each slot:
 */
1213
static inline u32 slot_bytes(struct nfsd4_channel_attrs *ca)
1214
{
1215
	u32 size;
1216

1217 1218 1219 1220 1221
	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);
1222
}
A
Andy Adamson 已提交
1223

1224 1225
/*
 * XXX: If we run out of reserved DRC memory we could (up to a point)
1226
 * re-negotiate active sessions and reduce their slot usage to make
1227
 * room for new connections. For now we just fail the create session.
A
Andy Adamson 已提交
1228
 */
1229
static u32 nfsd4_get_drc_mem(struct nfsd4_channel_attrs *ca)
A
Andy Adamson 已提交
1230
{
1231 1232
	u32 slotsize = slot_bytes(ca);
	u32 num = ca->maxreqs;
1233
	int avail;
A
Andy Adamson 已提交
1234

1235
	spin_lock(&nfsd_drc_lock);
1236 1237
	avail = min((unsigned long)NFSD_MAX_MEM_PER_SESSION,
		    nfsd_drc_max_mem - nfsd_drc_mem_used);
1238 1239 1240
	num = min_t(int, num, avail / slotsize);
	nfsd_drc_mem_used += num * slotsize;
	spin_unlock(&nfsd_drc_lock);
A
Andy Adamson 已提交
1241

1242 1243
	return num;
}
A
Andy Adamson 已提交
1244

1245
static void nfsd4_put_drc_mem(struct nfsd4_channel_attrs *ca)
1246
{
1247 1248
	int slotsize = slot_bytes(ca);

1249
	spin_lock(&nfsd_drc_lock);
1250
	nfsd_drc_mem_used -= slotsize * ca->maxreqs;
1251
	spin_unlock(&nfsd_drc_lock);
1252
}
A
Andy Adamson 已提交
1253

1254 1255
static struct nfsd4_session *alloc_session(struct nfsd4_channel_attrs *fattrs,
					   struct nfsd4_channel_attrs *battrs)
1256
{
1257 1258
	int numslots = fattrs->maxreqs;
	int slotsize = slot_bytes(fattrs);
1259 1260
	struct nfsd4_session *new;
	int mem, i;
1261

1262 1263 1264
	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 已提交
1265

1266 1267 1268
	new = kzalloc(sizeof(*new) + mem, GFP_KERNEL);
	if (!new)
		return NULL;
1269
	/* allocate each struct nfsd4_slot and data cache in one piece */
1270
	for (i = 0; i < numslots; i++) {
1271
		new->se_slots[i] = kzalloc(slotsize, GFP_KERNEL);
1272
		if (!new->se_slots[i])
1273 1274
			goto out_free;
	}
1275 1276 1277 1278

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

1279 1280 1281 1282 1283 1284
	return new;
out_free:
	while (i--)
		kfree(new->se_slots[i]);
	kfree(new);
	return NULL;
A
Andy Adamson 已提交
1285 1286
}

1287 1288 1289 1290 1291
static void free_conn(struct nfsd4_conn *c)
{
	svc_xprt_put(c->cn_xprt);
	kfree(c);
}
A
Andy Adamson 已提交
1292

1293 1294 1295 1296
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 已提交
1297

1298 1299 1300 1301 1302
	spin_lock(&clp->cl_lock);
	if (!list_empty(&c->cn_persession)) {
		list_del(&c->cn_persession);
		free_conn(c);
	}
1303
	nfsd4_probe_callback(clp);
1304
	spin_unlock(&clp->cl_lock);
1305
}
A
Andy Adamson 已提交
1306

1307
static struct nfsd4_conn *alloc_conn(struct svc_rqst *rqstp, u32 flags)
1308 1309
{
	struct nfsd4_conn *conn;
A
Andy Adamson 已提交
1310

1311 1312
	conn = kmalloc(sizeof(struct nfsd4_conn), GFP_KERNEL);
	if (!conn)
1313
		return NULL;
1314 1315
	svc_xprt_get(rqstp->rq_xprt);
	conn->cn_xprt = rqstp->rq_xprt;
1316
	conn->cn_flags = flags;
1317 1318 1319
	INIT_LIST_HEAD(&conn->cn_xpt_user.list);
	return conn;
}
1320

1321 1322 1323 1324
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 已提交
1325 1326
}

1327
static void nfsd4_hash_conn(struct nfsd4_conn *conn, struct nfsd4_session *ses)
1328
{
1329
	struct nfs4_client *clp = ses->se_client;
1330

1331
	spin_lock(&clp->cl_lock);
1332
	__nfsd4_hash_conn(conn, ses);
1333
	spin_unlock(&clp->cl_lock);
1334 1335
}

1336
static int nfsd4_register_conn(struct nfsd4_conn *conn)
1337
{
1338
	conn->cn_xpt_user.callback = nfsd4_conn_lost;
1339
	return register_xpt_user(conn->cn_xprt, &conn->cn_xpt_user);
1340 1341
}

1342
static void nfsd4_init_conn(struct svc_rqst *rqstp, struct nfsd4_conn *conn, struct nfsd4_session *ses)
A
Andy Adamson 已提交
1343
{
1344
	int ret;
A
Andy Adamson 已提交
1345

1346
	nfsd4_hash_conn(conn, ses);
1347 1348 1349 1350
	ret = nfsd4_register_conn(conn);
	if (ret)
		/* oops; xprt is already down: */
		nfsd4_conn_lost(&conn->cn_xpt_user);
1351 1352
	/* We may have gained or lost a callback channel: */
	nfsd4_probe_callback_sync(ses->se_client);
1353
}
A
Andy Adamson 已提交
1354

1355
static struct nfsd4_conn *alloc_conn_from_crses(struct svc_rqst *rqstp, struct nfsd4_create_session *cses)
1356 1357 1358
{
	u32 dir = NFS4_CDFC4_FORE;

1359
	if (cses->flags & SESSION4_BACK_CHAN)
1360
		dir |= NFS4_CDFC4_BACK;
1361
	return alloc_conn(rqstp, dir);
1362 1363 1364
}

/* must be called under client_lock */
1365
static void nfsd4_del_conns(struct nfsd4_session *s)
1366
{
1367 1368
	struct nfs4_client *clp = s->se_client;
	struct nfsd4_conn *c;
A
Andy Adamson 已提交
1369

1370 1371 1372 1373 1374
	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);
1375

1376 1377
		unregister_xpt_user(c->cn_xprt, &c->cn_xpt_user);
		free_conn(c);
A
Andy Adamson 已提交
1378

1379 1380 1381
		spin_lock(&clp->cl_lock);
	}
	spin_unlock(&clp->cl_lock);
1382
}
A
Andy Adamson 已提交
1383

1384 1385 1386 1387 1388 1389
static void __free_session(struct nfsd4_session *ses)
{
	free_session_slots(ses);
	kfree(ses);
}

1390
static void free_session(struct nfsd4_session *ses)
1391
{
1392
	struct nfsd_net *nn = net_generic(ses->se_client->net, nfsd_net_id);
1393 1394

	lockdep_assert_held(&nn->client_lock);
1395
	nfsd4_del_conns(ses);
1396
	nfsd4_put_drc_mem(&ses->se_fchannel);
1397
	__free_session(ses);
1398 1399
}

1400
static void init_session(struct svc_rqst *rqstp, struct nfsd4_session *new, struct nfs4_client *clp, struct nfsd4_create_session *cses)
1401 1402
{
	int idx;
1403
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
1404

A
Andy Adamson 已提交
1405 1406 1407
	new->se_client = clp;
	gen_sessionid(new);

1408 1409
	INIT_LIST_HEAD(&new->se_conns);

1410
	new->se_cb_seq_nr = 1;
A
Andy Adamson 已提交
1411
	new->se_flags = cses->flags;
1412
	new->se_cb_prog = cses->callback_prog;
1413
	new->se_cb_sec = cses->cb_sec;
1414
	atomic_set(&new->se_ref, 0);
1415
	idx = hash_sessionid(&new->se_sessionid);
1416
	spin_lock(&nn->client_lock);
1417
	list_add(&new->se_hash, &nn->sessionid_hashtbl[idx]);
1418
	spin_lock(&clp->cl_lock);
A
Andy Adamson 已提交
1419
	list_add(&new->se_perclnt, &clp->cl_sessions);
1420
	spin_unlock(&clp->cl_lock);
1421
	spin_unlock(&nn->client_lock);
1422

1423
	if (cses->flags & SESSION4_BACK_CHAN) {
1424
		struct sockaddr *sa = svc_addr(rqstp);
1425 1426 1427 1428 1429 1430 1431
		/*
		 * 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:
		 */
1432 1433 1434
		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 已提交
1435 1436
}

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

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

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

1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476
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;
}

1477
/* caller must hold client_lock */
A
Andy Adamson 已提交
1478
static void
M
Marc Eshel 已提交
1479
unhash_session(struct nfsd4_session *ses)
A
Andy Adamson 已提交
1480 1481
{
	list_del(&ses->se_hash);
1482
	spin_lock(&ses->se_client->cl_lock);
A
Andy Adamson 已提交
1483
	list_del(&ses->se_perclnt);
1484
	spin_unlock(&ses->se_client->cl_lock);
M
Marc Eshel 已提交
1485 1486
}

L
Linus Torvalds 已提交
1487 1488
/* SETCLIENTID and SETCLIENTID_CONFIRM Helper functions */
static int
1489
STALE_CLIENTID(clientid_t *clid, struct nfsd_net *nn)
L
Linus Torvalds 已提交
1490
{
1491
	if (clid->cl_boot == nn->boot_time)
L
Linus Torvalds 已提交
1492
		return 0;
A
Andy Adamson 已提交
1493
	dprintk("NFSD stale clientid (%08x/%08x) boot_time %08lx\n",
1494
		clid->cl_boot, clid->cl_id, nn->boot_time);
L
Linus Torvalds 已提交
1495 1496 1497 1498 1499 1500 1501 1502
	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.
 */
1503
static struct nfs4_client *alloc_client(struct xdr_netobj name)
L
Linus Torvalds 已提交
1504 1505
{
	struct nfs4_client *clp;
1506
	int i;
L
Linus Torvalds 已提交
1507

1508 1509 1510
	clp = kzalloc(sizeof(struct nfs4_client), GFP_KERNEL);
	if (clp == NULL)
		return NULL;
1511
	clp->cl_name.data = kmemdup(name.data, name.len, GFP_KERNEL);
1512 1513 1514 1515 1516 1517 1518 1519
	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]);
1520
	clp->cl_name.len = name.len;
1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532
	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 已提交
1533
	return clp;
1534 1535 1536 1537 1538
err_no_hashtbl:
	kfree(clp->cl_name.data);
err_no_name:
	kfree(clp);
	return NULL;
L
Linus Torvalds 已提交
1539 1540
}

1541
static void
L
Linus Torvalds 已提交
1542 1543
free_client(struct nfs4_client *clp)
{
1544
	struct nfsd_net __maybe_unused *nn = net_generic(clp->net, nfsd_net_id);
1545 1546

	lockdep_assert_held(&nn->client_lock);
1547 1548 1549 1550 1551
	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);
1552 1553
		WARN_ON_ONCE(atomic_read(&ses->se_ref));
		free_session(ses);
1554
	}
1555
	rpc_destroy_wait_queue(&clp->cl_cb_waitq);
1556
	free_svc_cred(&clp->cl_cred);
1557
	kfree(clp->cl_ownerstr_hashtbl);
L
Linus Torvalds 已提交
1558
	kfree(clp->cl_name.data);
M
majianpeng 已提交
1559
	idr_destroy(&clp->cl_stateids);
L
Linus Torvalds 已提交
1560 1561 1562
	kfree(clp);
}

B
Benny Halevy 已提交
1563 1564 1565 1566
/* must be called under the client_lock */
static inline void
unhash_client_locked(struct nfs4_client *clp)
{
1567 1568
	struct nfsd4_session *ses;

B
Benny Halevy 已提交
1569
	list_del(&clp->cl_lru);
1570
	spin_lock(&clp->cl_lock);
1571 1572
	list_for_each_entry(ses, &clp->cl_sessions, se_perclnt)
		list_del_init(&ses->se_hash);
1573
	spin_unlock(&clp->cl_lock);
B
Benny Halevy 已提交
1574 1575
}

L
Linus Torvalds 已提交
1576
static void
1577
destroy_client(struct nfs4_client *clp)
L
Linus Torvalds 已提交
1578
{
1579
	struct nfs4_openowner *oo;
L
Linus Torvalds 已提交
1580 1581
	struct nfs4_delegation *dp;
	struct list_head reaplist;
1582
	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
L
Linus Torvalds 已提交
1583 1584

	INIT_LIST_HEAD(&reaplist);
1585
	spin_lock(&state_lock);
1586 1587
	while (!list_empty(&clp->cl_delegations)) {
		dp = list_entry(clp->cl_delegations.next, struct nfs4_delegation, dl_perclnt);
1588 1589
		unhash_delegation_locked(dp);
		list_add(&dp->dl_recall_lru, &reaplist);
L
Linus Torvalds 已提交
1590
	}
1591
	spin_unlock(&state_lock);
L
Linus Torvalds 已提交
1592 1593
	while (!list_empty(&reaplist)) {
		dp = list_entry(reaplist.next, struct nfs4_delegation, dl_recall_lru);
1594
		list_del_init(&dp->dl_recall_lru);
1595
		nfs4_put_stid(&dp->dl_stid);
L
Linus Torvalds 已提交
1596
	}
1597
	while (!list_empty(&clp->cl_revoked)) {
1598
		dp = list_entry(reaplist.next, struct nfs4_delegation, dl_recall_lru);
1599
		list_del_init(&dp->dl_recall_lru);
1600
		nfs4_put_stid(&dp->dl_stid);
1601
	}
1602
	while (!list_empty(&clp->cl_openowners)) {
1603
		oo = list_entry(clp->cl_openowners.next, struct nfs4_openowner, oo_perclient);
1604
		atomic_inc(&oo->oo_owner.so_count);
1605
		release_openowner(oo);
L
Linus Torvalds 已提交
1606
	}
1607
	nfsd4_shutdown_callback(clp);
B
Benny Halevy 已提交
1608 1609
	if (clp->cl_cb_conn.cb_xprt)
		svc_xprt_put(clp->cl_cb_conn.cb_xprt);
1610
	list_del(&clp->cl_idhash);
1611
	if (test_bit(NFSD4_CLIENT_CONFIRMED, &clp->cl_flags))
1612
		rb_erase(&clp->cl_namenode, &nn->conf_name_tree);
1613
	else
1614
		rb_erase(&clp->cl_namenode, &nn->unconf_name_tree);
1615
	spin_lock(&nn->client_lock);
B
Benny Halevy 已提交
1616
	unhash_client_locked(clp);
1617 1618
	WARN_ON_ONCE(atomic_read(&clp->cl_refcount));
	free_client(clp);
1619
	spin_unlock(&nn->client_lock);
L
Linus Torvalds 已提交
1620 1621
}

1622 1623 1624 1625 1626 1627
static void expire_client(struct nfs4_client *clp)
{
	nfsd4_client_record_remove(clp);
	destroy_client(clp);
}

1628 1629 1630 1631
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 已提交
1632 1633
}

1634 1635
static void copy_clid(struct nfs4_client *target, struct nfs4_client *source)
{
L
Linus Torvalds 已提交
1636 1637 1638 1639
	target->cl_clientid.cl_boot = source->cl_clientid.cl_boot; 
	target->cl_clientid.cl_id = source->cl_clientid.cl_id; 
}

1640
static int copy_cred(struct svc_cred *target, struct svc_cred *source)
1641
{
1642 1643 1644 1645 1646 1647 1648
	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;
1649
	target->cr_flavor = source->cr_flavor;
L
Linus Torvalds 已提交
1650 1651 1652 1653
	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);
1654 1655 1656
	target->cr_gss_mech = source->cr_gss_mech;
	if (source->cr_gss_mech)
		gss_mech_get(source->cr_gss_mech);
1657
	return 0;
L
Linus Torvalds 已提交
1658 1659
}

1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670
static long long
compare_blob(const struct xdr_netobj *o1, const struct xdr_netobj *o2)
{
	long long res;

	res = o1->len - o2->len;
	if (res)
		return res;
	return (long long)memcmp(o1->data, o2->data, o1->len);
}

1671
static int same_name(const char *n1, const char *n2)
1672
{
N
NeilBrown 已提交
1673
	return 0 == memcmp(n1, n2, HEXDIR_LEN);
L
Linus Torvalds 已提交
1674 1675 1676
}

static int
1677 1678 1679
same_verf(nfs4_verifier *v1, nfs4_verifier *v2)
{
	return 0 == memcmp(v1->data, v2->data, sizeof(v1->data));
L
Linus Torvalds 已提交
1680 1681 1682
}

static int
1683 1684 1685
same_clid(clientid_t *cl1, clientid_t *cl2)
{
	return (cl1->cl_boot == cl2->cl_boot) && (cl1->cl_id == cl2->cl_id);
L
Linus Torvalds 已提交
1686 1687
}

1688 1689 1690 1691 1692 1693 1694
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++)
1695
		if (!gid_eq(GROUP_AT(g1, i), GROUP_AT(g2, i)))
1696 1697 1698 1699
			return false;
	return true;
}

1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715
/*
 * 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);
}


1716
static bool
1717 1718
same_creds(struct svc_cred *cr1, struct svc_cred *cr2)
{
1719
	if ((is_gss_cred(cr1) != is_gss_cred(cr2))
1720 1721
		|| (!uid_eq(cr1->cr_uid, cr2->cr_uid))
		|| (!gid_eq(cr1->cr_gid, cr2->cr_gid))
1722 1723 1724 1725 1726 1727
		|| !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;
1728
	return 0 == strcmp(cr1->cr_principal, cr2->cr_principal);
L
Linus Torvalds 已提交
1729 1730
}

1731 1732 1733 1734 1735
static bool svc_rqst_integrity_protected(struct svc_rqst *rqstp)
{
	struct svc_cred *cr = &rqstp->rq_cred;
	u32 service;

1736 1737
	if (!cr->cr_gss_mech)
		return false;
1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757
	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);
}

1758
static void gen_clid(struct nfs4_client *clp, struct nfsd_net *nn)
1759 1760 1761
{
	static u32 current_clientid = 1;

1762
	clp->cl_clientid.cl_boot = nn->boot_time;
L
Linus Torvalds 已提交
1763 1764 1765
	clp->cl_clientid.cl_id = current_clientid++; 
}

1766 1767
static void gen_confirm(struct nfs4_client *clp)
{
1768
	__be32 verf[2];
1769
	static u32 i;
L
Linus Torvalds 已提交
1770

1771 1772 1773 1774 1775 1776
	/*
	 * This is opaque to client, so no need to byte-swap. Use
	 * __force to keep sparse happy
	 */
	verf[0] = (__force __be32)get_seconds();
	verf[1] = (__force __be32)i++;
1777
	memcpy(clp->cl_confirm.data, verf, sizeof(clp->cl_confirm.data));
L
Linus Torvalds 已提交
1778 1779
}

1780 1781
static struct nfs4_stid *
find_stateid_locked(struct nfs4_client *cl, stateid_t *t)
1782
{
J
J. Bruce Fields 已提交
1783 1784 1785 1786 1787 1788
	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 已提交
1789 1790
}

1791 1792
static struct nfs4_stid *
find_stateid_by_type(struct nfs4_client *cl, stateid_t *t, char typemask)
1793 1794
{
	struct nfs4_stid *s;
J
J. Bruce Fields 已提交
1795

1796 1797
	spin_lock(&cl->cl_lock);
	s = find_stateid_locked(cl, t);
1798 1799 1800 1801 1802 1803
	if (s != NULL) {
		if (typemask & s->sc_type)
			atomic_inc(&s->sc_count);
		else
			s = NULL;
	}
1804 1805
	spin_unlock(&cl->cl_lock);
	return s;
1806 1807
}

J
Jeff Layton 已提交
1808
static struct nfs4_client *create_client(struct xdr_netobj name,
1809 1810 1811 1812
		struct svc_rqst *rqstp, nfs4_verifier *verf)
{
	struct nfs4_client *clp;
	struct sockaddr *sa = svc_addr(rqstp);
1813
	int ret;
1814
	struct net *net = SVC_NET(rqstp);
1815
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1816 1817 1818 1819 1820

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

1821 1822
	ret = copy_cred(&clp->cl_cred, &rqstp->rq_cred);
	if (ret) {
1823
		spin_lock(&nn->client_lock);
1824
		free_client(clp);
1825
		spin_unlock(&nn->client_lock);
1826
		return NULL;
1827
	}
1828
	INIT_WORK(&clp->cl_cb_null.cb_work, nfsd4_run_cb_null);
B
Benny Halevy 已提交
1829
	clp->cl_time = get_seconds();
1830 1831 1832 1833
	clear_bit(0, &clp->cl_cb_slot_busy);
	copy_verf(clp, verf);
	rpc_copy_addr((struct sockaddr *) &clp->cl_addr, sa);
	gen_confirm(clp);
1834
	clp->cl_cb_session = NULL;
1835
	clp->net = net;
1836 1837 1838
	return clp;
}

1839
static void
1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880
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)
{
	long long cmp;
	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 已提交
1881 1882
{
	unsigned int idhashval;
1883
	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
L
Linus Torvalds 已提交
1884

1885
	clear_bit(NFSD4_CLIENT_CONFIRMED, &clp->cl_flags);
1886
	add_clp_to_name_tree(clp, &nn->unconf_name_tree);
L
Linus Torvalds 已提交
1887
	idhashval = clientid_hashval(clp->cl_clientid.cl_id);
1888
	list_add(&clp->cl_idhash, &nn->unconf_id_hashtbl[idhashval]);
1889
	renew_client(clp);
L
Linus Torvalds 已提交
1890 1891
}

1892
static void
L
Linus Torvalds 已提交
1893 1894 1895
move_to_confirmed(struct nfs4_client *clp)
{
	unsigned int idhashval = clientid_hashval(clp->cl_clientid.cl_id);
1896
	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
L
Linus Torvalds 已提交
1897 1898

	dprintk("NFSD: move_to_confirm nfs4_client %p\n", clp);
1899
	list_move(&clp->cl_idhash, &nn->conf_id_hashtbl[idhashval]);
1900
	rb_erase(&clp->cl_namenode, &nn->unconf_name_tree);
1901
	add_clp_to_name_tree(clp, &nn->conf_name_tree);
1902
	set_bit(NFSD4_CLIENT_CONFIRMED, &clp->cl_flags);
L
Linus Torvalds 已提交
1903 1904 1905 1906
	renew_client(clp);
}

static struct nfs4_client *
J
J. Bruce Fields 已提交
1907
find_client_in_id_table(struct list_head *tbl, clientid_t *clid, bool sessions)
L
Linus Torvalds 已提交
1908 1909 1910 1911
{
	struct nfs4_client *clp;
	unsigned int idhashval = clientid_hashval(clid->cl_id);

J
J. Bruce Fields 已提交
1912
	list_for_each_entry(clp, &tbl[idhashval], cl_idhash) {
1913
		if (same_clid(&clp->cl_clientid, clid)) {
1914 1915
			if ((bool)clp->cl_minorversion != sessions)
				return NULL;
1916
			renew_client(clp);
L
Linus Torvalds 已提交
1917
			return clp;
1918
		}
L
Linus Torvalds 已提交
1919 1920 1921 1922
	}
	return NULL;
}

J
J. Bruce Fields 已提交
1923 1924 1925 1926 1927 1928 1929 1930
static struct nfs4_client *
find_confirmed_client(clientid_t *clid, bool sessions, struct nfsd_net *nn)
{
	struct list_head *tbl = nn->conf_id_hashtbl;

	return find_client_in_id_table(tbl, clid, sessions);
}

L
Linus Torvalds 已提交
1931
static struct nfs4_client *
1932
find_unconfirmed_client(clientid_t *clid, bool sessions, struct nfsd_net *nn)
L
Linus Torvalds 已提交
1933
{
J
J. Bruce Fields 已提交
1934
	struct list_head *tbl = nn->unconf_id_hashtbl;
L
Linus Torvalds 已提交
1935

J
J. Bruce Fields 已提交
1936
	return find_client_in_id_table(tbl, clid, sessions);
L
Linus Torvalds 已提交
1937 1938
}

1939
static bool clp_used_exchangeid(struct nfs4_client *clp)
1940
{
1941
	return clp->cl_exchange_flags != 0;
1942
} 
1943

1944
static struct nfs4_client *
1945
find_confirmed_client_by_name(struct xdr_netobj *name, struct nfsd_net *nn)
1946
{
1947
	return find_clp_in_name_tree(name, &nn->conf_name_tree);
1948 1949 1950
}

static struct nfs4_client *
1951
find_unconfirmed_client_by_name(struct xdr_netobj *name, struct nfsd_net *nn)
1952
{
1953
	return find_clp_in_name_tree(name, &nn->unconf_name_tree);
1954 1955
}

1956
static void
1957
gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se, struct svc_rqst *rqstp)
L
Linus Torvalds 已提交
1958
{
1959
	struct nfs4_cb_conn *conn = &clp->cl_cb_conn;
1960 1961
	struct sockaddr	*sa = svc_addr(rqstp);
	u32 scopeid = rpc_get_scope_id(sa);
1962 1963 1964 1965 1966 1967 1968 1969 1970 1971
	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 已提交
1972 1973
		goto out_err;

1974
	conn->cb_addrlen = rpc_uaddr2sockaddr(clp->net, se->se_callback_addr_val,
1975
					    se->se_callback_addr_len,
1976 1977
					    (struct sockaddr *)&conn->cb_addr,
					    sizeof(conn->cb_addr));
1978

1979
	if (!conn->cb_addrlen || conn->cb_addr.ss_family != expected_family)
L
Linus Torvalds 已提交
1980
		goto out_err;
1981

1982 1983
	if (conn->cb_addr.ss_family == AF_INET6)
		((struct sockaddr_in6 *)&conn->cb_addr)->sin6_scope_id = scopeid;
1984

1985 1986
	conn->cb_prog = se->se_callback_prog;
	conn->cb_ident = se->se_callback_ident;
1987
	memcpy(&conn->cb_saddr, &rqstp->rq_daddr, rqstp->rq_daddrlen);
L
Linus Torvalds 已提交
1988 1989
	return;
out_err:
1990 1991
	conn->cb_addr.ss_family = AF_UNSPEC;
	conn->cb_addrlen = 0;
N
Neil Brown 已提交
1992
	dprintk(KERN_INFO "NFSD: this client (clientid %08x/%08x) "
L
Linus Torvalds 已提交
1993 1994 1995 1996 1997 1998
		"will not receive delegations\n",
		clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);

	return;
}

1999
/*
2000
 * Cache a reply. nfsd4_check_resp_size() has bounded the cache size.
2001
 */
2002
static void
2003 2004
nfsd4_store_cache_entry(struct nfsd4_compoundres *resp)
{
2005
	struct xdr_buf *buf = resp->xdr.buf;
2006 2007
	struct nfsd4_slot *slot = resp->cstate.slot;
	unsigned int base;
2008

2009
	dprintk("--> %s slot %p\n", __func__, slot);
2010

2011 2012
	slot->sl_opcnt = resp->opcnt;
	slot->sl_status = resp->cstate.status;
2013

2014
	slot->sl_flags |= NFSD4_SLOT_INITIALIZED;
2015
	if (nfsd4_not_cached(resp)) {
2016
		slot->sl_datalen = 0;
2017
		return;
2018
	}
2019 2020 2021
	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))
2022 2023
		WARN("%s: sessions DRC could not cache compound\n", __func__);
	return;
2024 2025 2026
}

/*
2027 2028 2029 2030
 * 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.
2031 2032
 *
 */
2033 2034 2035
static __be32
nfsd4_enc_sequence_replay(struct nfsd4_compoundargs *args,
			  struct nfsd4_compoundres *resp)
2036
{
2037 2038
	struct nfsd4_op *op;
	struct nfsd4_slot *slot = resp->cstate.slot;
2039

2040 2041 2042
	/* Encode the replayed sequence operation */
	op = &args->ops[resp->opcnt - 1];
	nfsd4_encode_operation(resp, op);
2043

2044
	/* Return nfserr_retry_uncached_rep in next operation. */
2045
	if (args->opcnt > 1 && !(slot->sl_flags & NFSD4_SLOT_CACHETHIS)) {
2046 2047 2048
		op = &args->ops[resp->opcnt++];
		op->status = nfserr_retry_uncached_rep;
		nfsd4_encode_operation(resp, op);
2049
	}
2050
	return op->status;
2051 2052 2053
}

/*
2054 2055
 * The sequence operation is not cached because we can use the slot and
 * session values.
2056
 */
2057
static __be32
2058 2059
nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
			 struct nfsd4_sequence *seq)
2060
{
2061
	struct nfsd4_slot *slot = resp->cstate.slot;
2062 2063
	struct xdr_stream *xdr = &resp->xdr;
	__be32 *p;
2064 2065
	__be32 status;

2066
	dprintk("--> %s slot %p\n", __func__, slot);
2067

2068
	status = nfsd4_enc_sequence_replay(resp->rqstp->rq_argp, resp);
2069
	if (status)
2070
		return status;
2071

2072 2073 2074 2075 2076 2077 2078
	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);
2079

2080
	resp->opcnt = slot->sl_opcnt;
2081
	return slot->sl_status;
2082 2083
}

A
Andy Adamson 已提交
2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099
/*
 * 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;
}

2100 2101 2102 2103 2104 2105 2106 2107
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.
	 */
2108 2109 2110
	return !list_empty(&clp->cl_openowners)
		|| !list_empty(&clp->cl_delegations)
		|| !list_empty(&clp->cl_sessions);
2111 2112
}

A
Andy Adamson 已提交
2113 2114 2115 2116 2117
__be32
nfsd4_exchange_id(struct svc_rqst *rqstp,
		  struct nfsd4_compound_state *cstate,
		  struct nfsd4_exchange_id *exid)
{
A
Andy Adamson 已提交
2118
	struct nfs4_client *unconf, *conf, *new;
J
J. Bruce Fields 已提交
2119
	__be32 status;
2120
	char			addr_str[INET6_ADDRSTRLEN];
A
Andy Adamson 已提交
2121
	nfs4_verifier		verf = exid->verifier;
2122
	struct sockaddr		*sa = svc_addr(rqstp);
2123
	bool	update = exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A;
2124
	struct nfsd_net		*nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
A
Andy Adamson 已提交
2125

2126
	rpc_ntop(sa, addr_str, sizeof(addr_str));
A
Andy Adamson 已提交
2127
	dprintk("%s rqstp=%p exid=%p clname.len=%u clname.data=%p "
2128
		"ip_addr=%s flags %x, spa_how %d\n",
A
Andy Adamson 已提交
2129
		__func__, rqstp, exid, exid->clname.len, exid->clname.data,
2130
		addr_str, exid->flags, exid->spa_how);
A
Andy Adamson 已提交
2131

2132
	if (exid->flags & ~EXCHGID4_FLAG_MASK_A)
A
Andy Adamson 已提交
2133 2134 2135
		return nfserr_inval;

	switch (exid->spa_how) {
2136 2137 2138
	case SP4_MACH_CRED:
		if (!svc_rqst_integrity_protected(rqstp))
			return nfserr_inval;
A
Andy Adamson 已提交
2139 2140
	case SP4_NONE:
		break;
2141 2142
	default:				/* checked by xdr code */
		WARN_ON_ONCE(1);
A
Andy Adamson 已提交
2143
	case SP4_SSV:
2144
		return nfserr_encr_alg_unsupp;
A
Andy Adamson 已提交
2145 2146
	}

2147
	/* Cases below refer to rfc 5661 section 18.35.4: */
A
Andy Adamson 已提交
2148
	nfs4_lock_state();
2149
	conf = find_confirmed_client_by_name(&exid->clname, nn);
A
Andy Adamson 已提交
2150
	if (conf) {
2151 2152 2153
		bool creds_match = same_creds(&conf->cl_cred, &rqstp->rq_cred);
		bool verfs_match = same_verf(&verf, &conf->cl_verifier);

2154 2155
		if (update) {
			if (!clp_used_exchangeid(conf)) { /* buggy client */
2156
				status = nfserr_inval;
2157 2158
				goto out;
			}
2159 2160 2161 2162
			if (!mach_creds_match(conf, rqstp)) {
				status = nfserr_wrong_cred;
				goto out;
			}
2163
			if (!creds_match) { /* case 9 */
2164
				status = nfserr_perm;
2165 2166 2167
				goto out;
			}
			if (!verfs_match) { /* case 8 */
A
Andy Adamson 已提交
2168 2169 2170
				status = nfserr_not_same;
				goto out;
			}
2171 2172 2173 2174
			/* case 6 */
			exid->flags |= EXCHGID4_FLAG_CONFIRMED_R;
			new = conf;
			goto out_copy;
A
Andy Adamson 已提交
2175
		}
2176
		if (!creds_match) { /* case 3 */
2177 2178
			if (client_has_state(conf)) {
				status = nfserr_clid_inuse;
A
Andy Adamson 已提交
2179 2180 2181 2182 2183
				goto out;
			}
			expire_client(conf);
			goto out_new;
		}
2184
		if (verfs_match) { /* case 2 */
2185
			conf->cl_exchange_flags |= EXCHGID4_FLAG_CONFIRMED_R;
2186 2187 2188 2189 2190
			new = conf;
			goto out_copy;
		}
		/* case 5, client reboot */
		goto out_new;
2191 2192
	}

2193
	if (update) { /* case 7 */
2194 2195
		status = nfserr_noent;
		goto out;
A
Andy Adamson 已提交
2196 2197
	}

2198
	unconf  = find_unconfirmed_client_by_name(&exid->clname, nn);
2199
	if (unconf) /* case 4, possible retry or client restart */
A
Andy Adamson 已提交
2200 2201
		expire_client(unconf);

2202
	/* case 1 (normal case) */
A
Andy Adamson 已提交
2203
out_new:
J
Jeff Layton 已提交
2204
	new = create_client(exid->clname, rqstp, &verf);
A
Andy Adamson 已提交
2205
	if (new == NULL) {
2206
		status = nfserr_jukebox;
A
Andy Adamson 已提交
2207 2208
		goto out;
	}
2209
	new->cl_minorversion = cstate->minorversion;
2210
	new->cl_mach_cred = (exid->spa_how == SP4_MACH_CRED);
A
Andy Adamson 已提交
2211

2212
	gen_clid(new, nn);
2213
	add_to_unconfirmed(new);
A
Andy Adamson 已提交
2214 2215 2216 2217
out_copy:
	exid->clientid.cl_boot = new->cl_clientid.cl_boot;
	exid->clientid.cl_id = new->cl_clientid.cl_id;

2218
	exid->seqid = new->cl_cs_slot.sl_seqid + 1;
A
Andy Adamson 已提交
2219 2220 2221
	nfsd4_set_ex_flags(new, exid);

	dprintk("nfsd4_exchange_id seqid %d flags %x\n",
2222
		new->cl_cs_slot.sl_seqid, new->cl_exchange_flags);
A
Andy Adamson 已提交
2223 2224 2225 2226 2227
	status = nfs_ok;

out:
	nfs4_unlock_state();
	return status;
A
Andy Adamson 已提交
2228 2229
}

J
J. Bruce Fields 已提交
2230
static __be32
2231
check_slot_seqid(u32 seqid, u32 slot_seqid, int slot_inuse)
B
Benny Halevy 已提交
2232
{
2233 2234
	dprintk("%s enter. seqid %d slot_seqid %d\n", __func__, seqid,
		slot_seqid);
B
Benny Halevy 已提交
2235 2236

	/* The slot is in use, and no response has been sent. */
2237 2238
	if (slot_inuse) {
		if (seqid == slot_seqid)
B
Benny Halevy 已提交
2239 2240 2241 2242
			return nfserr_jukebox;
		else
			return nfserr_seq_misordered;
	}
2243
	/* Note unsigned 32-bit arithmetic handles wraparound: */
2244
	if (likely(seqid == slot_seqid + 1))
B
Benny Halevy 已提交
2245
		return nfs_ok;
2246
	if (seqid == slot_seqid)
B
Benny Halevy 已提交
2247 2248 2249 2250
		return nfserr_replay_cache;
	return nfserr_seq_misordered;
}

2251 2252 2253 2254 2255 2256 2257
/*
 * 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 已提交
2258
			   struct nfsd4_clid_slot *slot, __be32 nfserr)
2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271
{
	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;
}

2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288
#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))

2289
static __be32 check_forechannel_attrs(struct nfsd4_channel_attrs *ca, struct nfsd_net *nn)
2290
{
2291 2292
	u32 maxrpc = nn->nfsd_serv->sv_max_mesg;

2293 2294 2295 2296
	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;
2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315
	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;

2316
	return nfs_ok;
2317 2318
}

2319 2320 2321 2322 2323
#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))

2324
static __be32 check_backchannel_attrs(struct nfsd4_channel_attrs *ca)
2325
{
2326 2327 2328 2329 2330 2331 2332 2333
	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:
	 */
2334
	if (ca->maxreq_sz < NFSD_CB_MAX_REQ_SZ)
2335
		return nfserr_toosmall;
2336
	if (ca->maxresp_sz < NFSD_CB_MAX_RESP_SZ)
2337 2338 2339 2340 2341 2342
		return nfserr_toosmall;
	ca->maxresp_cached = 0;
	if (ca->maxops < 2)
		return nfserr_toosmall;

	return nfs_ok;
2343 2344
}

2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362
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 已提交
2363 2364 2365 2366 2367
__be32
nfsd4_create_session(struct svc_rqst *rqstp,
		     struct nfsd4_compound_state *cstate,
		     struct nfsd4_create_session *cr_ses)
{
2368
	struct sockaddr *sa = svc_addr(rqstp);
A
Andy Adamson 已提交
2369
	struct nfs4_client *conf, *unconf;
2370
	struct nfsd4_session *new;
2371
	struct nfsd4_conn *conn;
2372
	struct nfsd4_clid_slot *cs_slot = NULL;
J
J. Bruce Fields 已提交
2373
	__be32 status = 0;
2374
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
A
Andy Adamson 已提交
2375

2376 2377
	if (cr_ses->flags & ~SESSION4_FLAG_MASK_A)
		return nfserr_inval;
2378 2379 2380
	status = nfsd4_check_cb_sec(&cr_ses->cb_sec);
	if (status)
		return status;
2381
	status = check_forechannel_attrs(&cr_ses->fore_channel, nn);
2382 2383 2384
	if (status)
		return status;
	status = check_backchannel_attrs(&cr_ses->back_channel);
2385
	if (status)
2386
		goto out_release_drc_mem;
2387
	status = nfserr_jukebox;
2388
	new = alloc_session(&cr_ses->fore_channel, &cr_ses->back_channel);
2389 2390
	if (!new)
		goto out_release_drc_mem;
2391 2392 2393
	conn = alloc_conn_from_crses(rqstp, cr_ses);
	if (!conn)
		goto out_free_session;
2394

A
Andy Adamson 已提交
2395
	nfs4_lock_state();
2396
	unconf = find_unconfirmed_client(&cr_ses->clientid, true, nn);
2397
	conf = find_confirmed_client(&cr_ses->clientid, true, nn);
2398
	WARN_ON_ONCE(conf && unconf);
A
Andy Adamson 已提交
2399 2400

	if (conf) {
2401 2402 2403
		status = nfserr_wrong_cred;
		if (!mach_creds_match(conf, rqstp))
			goto out_free_conn;
2404 2405
		cs_slot = &conf->cl_cs_slot;
		status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0);
2406
		if (status == nfserr_replay_cache) {
2407
			status = nfsd4_replay_create_session(cr_ses, cs_slot);
2408
			goto out_free_conn;
2409
		} else if (cr_ses->seqid != cs_slot->sl_seqid + 1) {
A
Andy Adamson 已提交
2410
			status = nfserr_seq_misordered;
2411
			goto out_free_conn;
A
Andy Adamson 已提交
2412 2413
		}
	} else if (unconf) {
J
J. Bruce Fields 已提交
2414
		struct nfs4_client *old;
A
Andy Adamson 已提交
2415
		if (!same_creds(&unconf->cl_cred, &rqstp->rq_cred) ||
2416
		    !rpc_cmp_addr(sa, (struct sockaddr *) &unconf->cl_addr)) {
A
Andy Adamson 已提交
2417
			status = nfserr_clid_inuse;
2418
			goto out_free_conn;
A
Andy Adamson 已提交
2419
		}
2420 2421 2422
		status = nfserr_wrong_cred;
		if (!mach_creds_match(unconf, rqstp))
			goto out_free_conn;
2423 2424
		cs_slot = &unconf->cl_cs_slot;
		status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0);
2425 2426
		if (status) {
			/* an unconfirmed replay returns misordered */
A
Andy Adamson 已提交
2427
			status = nfserr_seq_misordered;
2428
			goto out_free_conn;
A
Andy Adamson 已提交
2429
		}
2430
		old = find_confirmed_client_by_name(&unconf->cl_name, nn);
2431 2432 2433 2434
		if (old) {
			status = mark_client_expired(old);
			if (status)
				goto out_free_conn;
J
J. Bruce Fields 已提交
2435
			expire_client(old);
2436
		}
J
J. Bruce Fields 已提交
2437
		move_to_confirmed(unconf);
A
Andy Adamson 已提交
2438 2439 2440
		conf = unconf;
	} else {
		status = nfserr_stale_clientid;
2441
		goto out_free_conn;
A
Andy Adamson 已提交
2442
	}
2443
	status = nfs_ok;
2444 2445 2446 2447 2448 2449
	/*
	 * We do not support RDMA or persistent sessions
	 */
	cr_ses->flags &= ~SESSION4_PERSIST;
	cr_ses->flags &= ~SESSION4_RDMA;

2450 2451 2452
	init_session(rqstp, new, conf, cr_ses);
	nfsd4_init_conn(rqstp, conn, new);

2453
	memcpy(cr_ses->sessionid.data, new->se_sessionid.data,
A
Andy Adamson 已提交
2454
	       NFS4_MAX_SESSIONID_LEN);
2455
	cs_slot->sl_seqid++;
2456
	cr_ses->seqid = cs_slot->sl_seqid;
A
Andy Adamson 已提交
2457

2458 2459
	/* cache solo and embedded create sessions under the state lock */
	nfsd4_cache_create_session(cr_ses, cs_slot, status);
A
Andy Adamson 已提交
2460 2461
	nfs4_unlock_state();
	return status;
2462
out_free_conn:
2463
	nfs4_unlock_state();
2464 2465 2466
	free_conn(conn);
out_free_session:
	__free_session(new);
2467 2468
out_release_drc_mem:
	nfsd4_put_drc_mem(&cr_ses->fore_channel);
J
J. Bruce Fields 已提交
2469
	return status;
A
Andy Adamson 已提交
2470 2471
}

2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485
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;
}

2486 2487 2488
__be32 nfsd4_backchannel_ctl(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_backchannel_ctl *bc)
{
	struct nfsd4_session *session = cstate->session;
2489
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
2490
	__be32 status;
2491

2492 2493 2494
	status = nfsd4_check_cb_sec(&bc->bc_cb_sec);
	if (status)
		return status;
2495
	spin_lock(&nn->client_lock);
2496 2497
	session->se_cb_prog = bc->bc_cb_program;
	session->se_cb_sec = bc->bc_cb_sec;
2498
	spin_unlock(&nn->client_lock);
2499 2500 2501 2502 2503 2504

	nfsd4_probe_callback(session->se_client);

	return nfs_ok;
}

2505 2506 2507 2508 2509
__be32 nfsd4_bind_conn_to_session(struct svc_rqst *rqstp,
		     struct nfsd4_compound_state *cstate,
		     struct nfsd4_bind_conn_to_session *bcts)
{
	__be32 status;
2510
	struct nfsd4_conn *conn;
2511
	struct nfsd4_session *session;
2512 2513
	struct net *net = SVC_NET(rqstp);
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
2514 2515 2516

	if (!nfsd4_last_compound_op(rqstp))
		return nfserr_not_only_op;
2517
	nfs4_lock_state();
2518
	spin_lock(&nn->client_lock);
2519
	session = find_in_sessionid_hashtbl(&bcts->sessionid, net, &status);
2520
	spin_unlock(&nn->client_lock);
2521
	if (!session)
2522
		goto out_no_session;
2523 2524 2525
	status = nfserr_wrong_cred;
	if (!mach_creds_match(session->se_client, rqstp))
		goto out;
2526
	status = nfsd4_map_bcts_dir(&bcts->dir);
2527
	if (status)
2528
		goto out;
2529
	conn = alloc_conn(rqstp, bcts->dir);
2530
	status = nfserr_jukebox;
2531
	if (!conn)
2532 2533 2534 2535
		goto out;
	nfsd4_init_conn(rqstp, conn, session);
	status = nfs_ok;
out:
2536 2537
	nfsd4_put_session(session);
out_no_session:
2538 2539
	nfs4_unlock_state();
	return status;
2540 2541
}

2542 2543 2544 2545 2546 2547 2548
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 已提交
2549 2550 2551 2552 2553
__be32
nfsd4_destroy_session(struct svc_rqst *r,
		      struct nfsd4_compound_state *cstate,
		      struct nfsd4_destroy_session *sessionid)
{
B
Benny Halevy 已提交
2554
	struct nfsd4_session *ses;
2555
	__be32 status;
2556
	int ref_held_by_me = 0;
2557 2558
	struct net *net = SVC_NET(r);
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
B
Benny Halevy 已提交
2559

2560 2561
	nfs4_lock_state();
	status = nfserr_not_only_op;
2562
	if (nfsd4_compound_in_session(cstate->session, &sessionid->sessionid)) {
2563
		if (!nfsd4_last_compound_op(r))
2564
			goto out;
2565
		ref_held_by_me++;
2566
	}
B
Benny Halevy 已提交
2567
	dump_sessionid(__func__, &sessionid->sessionid);
2568
	spin_lock(&nn->client_lock);
2569
	ses = find_in_sessionid_hashtbl(&sessionid->sessionid, net, &status);
2570 2571
	if (!ses)
		goto out_client_lock;
2572 2573
	status = nfserr_wrong_cred;
	if (!mach_creds_match(ses->se_client, r))
2574
		goto out_put_session;
2575
	status = mark_session_dead_locked(ses, 1 + ref_held_by_me);
2576
	if (status)
2577
		goto out_put_session;
B
Benny Halevy 已提交
2578
	unhash_session(ses);
2579
	spin_unlock(&nn->client_lock);
B
Benny Halevy 已提交
2580

2581
	nfsd4_probe_callback_sync(ses->se_client);
2582

2583
	spin_lock(&nn->client_lock);
B
Benny Halevy 已提交
2584
	status = nfs_ok;
2585
out_put_session:
2586
	nfsd4_put_session_locked(ses);
2587 2588
out_client_lock:
	spin_unlock(&nn->client_lock);
B
Benny Halevy 已提交
2589
out:
2590
	nfs4_unlock_state();
B
Benny Halevy 已提交
2591
	return status;
A
Andy Adamson 已提交
2592 2593
}

2594
static struct nfsd4_conn *__nfsd4_find_conn(struct svc_xprt *xpt, struct nfsd4_session *s)
2595 2596 2597 2598
{
	struct nfsd4_conn *c;

	list_for_each_entry(c, &s->se_conns, cn_persession) {
2599
		if (c->cn_xprt == xpt) {
2600 2601 2602 2603 2604 2605
			return c;
		}
	}
	return NULL;
}

2606
static __be32 nfsd4_sequence_check_conn(struct nfsd4_conn *new, struct nfsd4_session *ses)
2607 2608
{
	struct nfs4_client *clp = ses->se_client;
2609
	struct nfsd4_conn *c;
2610
	__be32 status = nfs_ok;
2611
	int ret;
2612 2613

	spin_lock(&clp->cl_lock);
2614
	c = __nfsd4_find_conn(new->cn_xprt, ses);
2615 2616 2617 2618 2619
	if (c)
		goto out_free;
	status = nfserr_conn_not_bound_to_session;
	if (clp->cl_mach_cred)
		goto out_free;
2620 2621
	__nfsd4_hash_conn(new, ses);
	spin_unlock(&clp->cl_lock);
2622 2623 2624 2625
	ret = nfsd4_register_conn(new);
	if (ret)
		/* oops; xprt is already down: */
		nfsd4_conn_lost(&new->cn_xpt_user);
2626 2627 2628 2629 2630
	return nfs_ok;
out_free:
	spin_unlock(&clp->cl_lock);
	free_conn(new);
	return status;
2631 2632
}

2633 2634 2635 2636 2637 2638 2639
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 已提交
2640 2641 2642 2643 2644 2645 2646 2647
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 已提交
2648
__be32
B
Benny Halevy 已提交
2649
nfsd4_sequence(struct svc_rqst *rqstp,
A
Andy Adamson 已提交
2650 2651 2652
	       struct nfsd4_compound_state *cstate,
	       struct nfsd4_sequence *seq)
{
2653
	struct nfsd4_compoundres *resp = rqstp->rq_resp;
2654
	struct xdr_stream *xdr = &resp->xdr;
B
Benny Halevy 已提交
2655
	struct nfsd4_session *session;
2656
	struct nfs4_client *clp;
B
Benny Halevy 已提交
2657
	struct nfsd4_slot *slot;
2658
	struct nfsd4_conn *conn;
J
J. Bruce Fields 已提交
2659
	__be32 status;
2660
	int buflen;
2661 2662
	struct net *net = SVC_NET(rqstp);
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
B
Benny Halevy 已提交
2663

2664 2665 2666
	if (resp->opcnt != 1)
		return nfserr_sequence_pos;

2667 2668 2669 2670 2671 2672 2673 2674
	/*
	 * Will be either used or freed by nfsd4_sequence_check_conn
	 * below.
	 */
	conn = alloc_conn(rqstp, NFS4_CDFC4_FORE);
	if (!conn)
		return nfserr_jukebox;

2675
	spin_lock(&nn->client_lock);
2676
	session = find_in_sessionid_hashtbl(&seq->sessionid, net, &status);
B
Benny Halevy 已提交
2677
	if (!session)
2678 2679
		goto out_no_session;
	clp = session->se_client;
B
Benny Halevy 已提交
2680

2681 2682
	status = nfserr_too_many_ops;
	if (nfsd4_session_too_many_ops(rqstp, session))
2683
		goto out_put_session;
2684

M
Mi Jinlong 已提交
2685 2686
	status = nfserr_req_too_big;
	if (nfsd4_request_too_big(rqstp, session))
2687
		goto out_put_session;
M
Mi Jinlong 已提交
2688

B
Benny Halevy 已提交
2689
	status = nfserr_badslot;
2690
	if (seq->slotid >= session->se_fchannel.maxreqs)
2691
		goto out_put_session;
B
Benny Halevy 已提交
2692

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

2696 2697 2698 2699 2700
	/* 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;

2701 2702
	status = check_slot_seqid(seq->seqid, slot->sl_seqid,
					slot->sl_flags & NFSD4_SLOT_INUSE);
B
Benny Halevy 已提交
2703
	if (status == nfserr_replay_cache) {
2704 2705
		status = nfserr_seq_misordered;
		if (!(slot->sl_flags & NFSD4_SLOT_INITIALIZED))
2706
			goto out_put_session;
B
Benny Halevy 已提交
2707 2708
		cstate->slot = slot;
		cstate->session = session;
2709
		cstate->clp = clp;
A
Andy Adamson 已提交
2710
		/* Return the cached reply status and set cstate->status
2711
		 * for nfsd4_proc_compound processing */
2712
		status = nfsd4_replay_cache_entry(resp, seq);
A
Andy Adamson 已提交
2713
		cstate->status = nfserr_replay_cache;
2714
		goto out;
B
Benny Halevy 已提交
2715 2716
	}
	if (status)
2717
		goto out_put_session;
B
Benny Halevy 已提交
2718

2719
	status = nfsd4_sequence_check_conn(conn, session);
2720
	conn = NULL;
2721 2722
	if (status)
		goto out_put_session;
2723

2724 2725 2726 2727 2728
	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;
2729
	if (xdr_restrict_buflen(xdr, buflen - rqstp->rq_auth_slack))
2730
		goto out_put_session;
2731
	svc_reserve(rqstp, buflen);
2732 2733

	status = nfs_ok;
B
Benny Halevy 已提交
2734 2735
	/* Success! bump slot seqid */
	slot->sl_seqid = seq->seqid;
2736
	slot->sl_flags |= NFSD4_SLOT_INUSE;
2737 2738
	if (seq->cachethis)
		slot->sl_flags |= NFSD4_SLOT_CACHETHIS;
2739 2740
	else
		slot->sl_flags &= ~NFSD4_SLOT_CACHETHIS;
B
Benny Halevy 已提交
2741 2742 2743

	cstate->slot = slot;
	cstate->session = session;
2744
	cstate->clp = clp;
B
Benny Halevy 已提交
2745 2746

out:
2747 2748 2749 2750 2751 2752 2753 2754 2755
	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;
2756
	}
2757 2758
	if (!list_empty(&clp->cl_revoked))
		seq->status_flags |= SEQ4_STATUS_RECALLABLE_STATE_REVOKED;
2759
out_no_session:
2760 2761
	if (conn)
		free_conn(conn);
2762
	spin_unlock(&nn->client_lock);
B
Benny Halevy 已提交
2763
	return status;
2764
out_put_session:
2765
	nfsd4_put_session_locked(session);
2766
	goto out_no_session;
A
Andy Adamson 已提交
2767 2768
}

2769 2770 2771 2772 2773 2774 2775 2776 2777 2778
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;
		}
2779
		/* Drop session reference that was taken in nfsd4_sequence() */
2780
		nfsd4_put_session(cs->session);
2781 2782
	} else if (cs->clp)
		put_client_renew(cs->clp);
2783 2784
}

2785 2786 2787 2788
__be32
nfsd4_destroy_clientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_destroy_clientid *dc)
{
	struct nfs4_client *conf, *unconf, *clp;
J
J. Bruce Fields 已提交
2789
	__be32 status = 0;
2790
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
2791 2792

	nfs4_lock_state();
2793
	unconf = find_unconfirmed_client(&dc->clientid, true, nn);
2794
	conf = find_confirmed_client(&dc->clientid, true, nn);
2795
	WARN_ON_ONCE(conf && unconf);
2796 2797 2798 2799

	if (conf) {
		clp = conf;

2800
		if (client_has_state(conf)) {
2801 2802 2803 2804 2805 2806 2807 2808 2809
			status = nfserr_clientid_busy;
			goto out;
		}
	} else if (unconf)
		clp = unconf;
	else {
		status = nfserr_stale_clientid;
		goto out;
	}
2810 2811 2812 2813
	if (!mach_creds_match(clp, rqstp)) {
		status = nfserr_wrong_cred;
		goto out;
	}
2814 2815 2816 2817 2818 2819
	expire_client(clp);
out:
	nfs4_unlock_state();
	return status;
}

2820 2821 2822
__be32
nfsd4_reclaim_complete(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_reclaim_complete *rc)
{
J
J. Bruce Fields 已提交
2823
	__be32 status = 0;
2824

2825 2826 2827 2828 2829 2830 2831 2832 2833
	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;
	}
2834

2835
	nfs4_lock_state();
2836
	status = nfserr_complete_already;
2837 2838
	if (test_and_set_bit(NFSD4_CLIENT_RECLAIM_COMPLETE,
			     &cstate->session->se_client->cl_flags))
2839 2840 2841 2842
		goto out;

	status = nfserr_stale_clientid;
	if (is_client_expired(cstate->session->se_client))
2843 2844 2845 2846 2847 2848 2849
		/*
		 * 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.
		 */
2850 2851 2852
		goto out;

	status = nfs_ok;
2853
	nfsd4_client_record_create(cstate->session->se_client);
2854
out:
2855
	nfs4_unlock_state();
2856
	return status;
2857 2858
}

2859
__be32
2860 2861
nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
		  struct nfsd4_setclientid *setclid)
L
Linus Torvalds 已提交
2862
{
2863
	struct xdr_netobj 	clname = setclid->se_name;
L
Linus Torvalds 已提交
2864
	nfs4_verifier		clverifier = setclid->se_verf;
2865
	struct nfs4_client	*conf, *unconf, *new;
2866
	__be32 			status;
2867 2868
	struct nfsd_net		*nn = net_generic(SVC_NET(rqstp), nfsd_net_id);

2869
	/* Cases below refer to rfc 3530 section 14.2.33: */
L
Linus Torvalds 已提交
2870
	nfs4_lock_state();
2871
	conf = find_confirmed_client_by_name(&clname, nn);
2872
	if (conf) {
2873
		/* case 0: */
L
Linus Torvalds 已提交
2874
		status = nfserr_clid_inuse;
2875 2876
		if (clp_used_exchangeid(conf))
			goto out;
2877
		if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)) {
2878 2879 2880 2881 2882
			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 已提交
2883 2884 2885
			goto out;
		}
	}
2886
	unconf = find_unconfirmed_client_by_name(&clname, nn);
2887 2888
	if (unconf)
		expire_client(unconf);
2889
	status = nfserr_jukebox;
J
Jeff Layton 已提交
2890
	new = create_client(clname, rqstp, &clverifier);
2891 2892
	if (new == NULL)
		goto out;
2893
	if (conf && same_verf(&conf->cl_verifier, &clverifier))
2894
		/* case 1: probable callback update */
L
Linus Torvalds 已提交
2895
		copy_clid(new, conf);
2896
	else /* case 4 (new client) or cases 2, 3 (client reboot): */
2897
		gen_clid(new, nn);
2898
	new->cl_minorversion = 0;
2899
	gen_callback(new, setclid, rqstp);
2900
	add_to_unconfirmed(new);
L
Linus Torvalds 已提交
2901 2902 2903 2904 2905 2906 2907 2908 2909 2910
	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));
	status = nfs_ok;
out:
	nfs4_unlock_state();
	return status;
}


2911
__be32
2912 2913 2914
nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
			 struct nfsd4_compound_state *cstate,
			 struct nfsd4_setclientid_confirm *setclientid_confirm)
L
Linus Torvalds 已提交
2915
{
2916
	struct nfs4_client *conf, *unconf;
L
Linus Torvalds 已提交
2917 2918
	nfs4_verifier confirm = setclientid_confirm->sc_confirm; 
	clientid_t * clid = &setclientid_confirm->sc_clientid;
2919
	__be32 status;
2920
	struct nfsd_net	*nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
L
Linus Torvalds 已提交
2921

2922
	if (STALE_CLIENTID(clid, nn))
L
Linus Torvalds 已提交
2923 2924
		return nfserr_stale_clientid;
	nfs4_lock_state();
2925

2926
	conf = find_confirmed_client(clid, false, nn);
2927
	unconf = find_unconfirmed_client(clid, false, nn);
2928
	/*
2929 2930 2931 2932
	 * 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.
2933
	 */
2934 2935 2936 2937 2938
	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;
2939
	/* cases below refer to rfc 3530 section 14.2.34: */
2940 2941
	if (!unconf || !same_verf(&confirm, &unconf->cl_confirm)) {
		if (conf && !unconf) /* case 2: probable retransmit */
L
Linus Torvalds 已提交
2942
			status = nfs_ok;
2943 2944 2945 2946 2947 2948
		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 */
2949 2950 2951
		nfsd4_change_callback(conf, &unconf->cl_cb_conn);
		nfsd4_probe_callback(conf);
		expire_client(unconf);
2952
	} else { /* case 3: normal case; new or rebooted client */
2953
		conf = find_confirmed_client_by_name(&unconf->cl_name, nn);
2954 2955 2956 2957
		if (conf) {
			status = mark_client_expired(conf);
			if (status)
				goto out;
2958
			expire_client(conf);
2959
		}
2960
		move_to_confirmed(unconf);
2961
		nfsd4_probe_callback(unconf);
2962
	}
L
Linus Torvalds 已提交
2963 2964 2965 2966 2967
out:
	nfs4_unlock_state();
	return status;
}

2968 2969 2970 2971 2972
static struct nfs4_file *nfsd4_alloc_file(void)
{
	return kmem_cache_alloc(file_slab, GFP_KERNEL);
}

L
Linus Torvalds 已提交
2973
/* OPEN Share state helper functions */
2974
static void nfsd4_init_file(struct nfs4_file *fp, struct knfsd_fh *fh)
L
Linus Torvalds 已提交
2975
{
2976
	unsigned int hashval = file_hashval(fh);
L
Linus Torvalds 已提交
2977

2978 2979
	lockdep_assert_held(&state_lock);

2980
	atomic_set(&fp->fi_ref, 1);
2981
	spin_lock_init(&fp->fi_lock);
2982 2983
	INIT_LIST_HEAD(&fp->fi_stateids);
	INIT_LIST_HEAD(&fp->fi_delegations);
2984
	fh_copy_shallow(&fp->fi_fhandle, fh);
2985 2986
	fp->fi_had_conflict = false;
	fp->fi_lease = NULL;
2987
	fp->fi_share_deny = 0;
2988 2989
	memset(fp->fi_fds, 0, sizeof(fp->fi_fds));
	memset(fp->fi_access, 0, sizeof(fp->fi_access));
2990
	hlist_add_head(&fp->fi_hash, &file_hashtbl[hashval]);
L
Linus Torvalds 已提交
2991 2992
}

2993
void
L
Linus Torvalds 已提交
2994 2995
nfsd4_free_slabs(void)
{
C
Christoph Hellwig 已提交
2996 2997 2998 2999 3000
	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 已提交
3001
}
L
Linus Torvalds 已提交
3002

3003
int
N
NeilBrown 已提交
3004 3005
nfsd4_init_slabs(void)
{
3006 3007 3008
	openowner_slab = kmem_cache_create("nfsd4_openowners",
			sizeof(struct nfs4_openowner), 0, 0, NULL);
	if (openowner_slab == NULL)
C
Christoph Hellwig 已提交
3009
		goto out;
3010
	lockowner_slab = kmem_cache_create("nfsd4_lockowners",
3011
			sizeof(struct nfs4_lockowner), 0, 0, NULL);
3012
	if (lockowner_slab == NULL)
C
Christoph Hellwig 已提交
3013
		goto out_free_openowner_slab;
N
NeilBrown 已提交
3014
	file_slab = kmem_cache_create("nfsd4_files",
3015
			sizeof(struct nfs4_file), 0, 0, NULL);
N
NeilBrown 已提交
3016
	if (file_slab == NULL)
C
Christoph Hellwig 已提交
3017
		goto out_free_lockowner_slab;
N
NeilBrown 已提交
3018
	stateid_slab = kmem_cache_create("nfsd4_stateids",
3019
			sizeof(struct nfs4_ol_stateid), 0, 0, NULL);
N
NeilBrown 已提交
3020
	if (stateid_slab == NULL)
C
Christoph Hellwig 已提交
3021
		goto out_free_file_slab;
N
NeilBrown 已提交
3022
	deleg_slab = kmem_cache_create("nfsd4_delegations",
3023
			sizeof(struct nfs4_delegation), 0, 0, NULL);
N
NeilBrown 已提交
3024
	if (deleg_slab == NULL)
C
Christoph Hellwig 已提交
3025
		goto out_free_stateid_slab;
N
NeilBrown 已提交
3026
	return 0;
C
Christoph Hellwig 已提交
3027 3028 3029 3030 3031 3032 3033 3034 3035 3036

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 已提交
3037 3038
	dprintk("nfsd4: out of memory while initializing nfsv4\n");
	return -ENOMEM;
L
Linus Torvalds 已提交
3039 3040
}

3041
static void init_nfs4_replay(struct nfs4_replay *rp)
L
Linus Torvalds 已提交
3042
{
3043 3044 3045
	rp->rp_status = nfserr_serverfault;
	rp->rp_buflen = 0;
	rp->rp_buf = rp->rp_ibuf;
3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067
	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);
		cstate->replay_owner = so;
		atomic_inc(&so->so_count);
	}
}

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 已提交
3068 3069
}

3070
static inline void *alloc_stateowner(struct kmem_cache *slab, struct xdr_netobj *owner, struct nfs4_client *clp)
3071
{
L
Linus Torvalds 已提交
3072 3073
	struct nfs4_stateowner *sop;

3074
	sop = kmem_cache_alloc(slab, GFP_KERNEL);
3075 3076 3077 3078 3079
	if (!sop)
		return NULL;

	sop->so_owner.data = kmemdup(owner->data, owner->len, GFP_KERNEL);
	if (!sop->so_owner.data) {
3080
		kmem_cache_free(slab, sop);
L
Linus Torvalds 已提交
3081
		return NULL;
3082 3083 3084
	}
	sop->so_owner.len = owner->len;

3085
	INIT_LIST_HEAD(&sop->so_stateids);
3086 3087
	sop->so_client = clp;
	init_nfs4_replay(&sop->so_replay);
3088
	atomic_set(&sop->so_count, 1);
3089 3090 3091
	return sop;
}

3092
static void hash_openowner(struct nfs4_openowner *oo, struct nfs4_client *clp, unsigned int strhashval)
3093
{
3094
	lockdep_assert_held(&clp->cl_lock);
3095

3096 3097
	list_add(&oo->oo_owner.so_strhash,
		 &clp->cl_ownerstr_hashtbl[strhashval]);
3098
	list_add(&oo->oo_perclient, &clp->cl_openowners);
3099 3100
}

3101 3102
static void nfs4_unhash_openowner(struct nfs4_stateowner *so)
{
3103
	unhash_openowner_locked(openowner(so));
3104 3105
}

3106 3107 3108 3109 3110 3111 3112 3113
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 = {
3114 3115
	.so_unhash =	nfs4_unhash_openowner,
	.so_free =	nfs4_free_openowner,
3116 3117
};

3118
static struct nfs4_openowner *
3119
alloc_init_open_stateowner(unsigned int strhashval, struct nfsd4_open *open,
3120 3121
			   struct nfsd4_compound_state *cstate)
{
3122
	struct nfs4_client *clp = cstate->clp;
3123
	struct nfs4_openowner *oo, *ret;
3124

3125 3126
	oo = alloc_stateowner(openowner_slab, &open->op_owner, clp);
	if (!oo)
3127
		return NULL;
3128
	oo->oo_owner.so_ops = &openowner_ops;
3129 3130
	oo->oo_owner.so_is_open_owner = 1;
	oo->oo_owner.so_seqid = open->op_seqid;
3131
	oo->oo_flags = 0;
3132 3133
	if (nfsd4_has_session(cstate))
		oo->oo_flags |= NFS4_OO_CONFIRMED;
3134
	oo->oo_time = 0;
3135
	oo->oo_last_closed_stid = NULL;
3136
	INIT_LIST_HEAD(&oo->oo_close_lru);
3137 3138
	spin_lock(&clp->cl_lock);
	ret = find_openstateowner_str_locked(strhashval, open, clp);
3139 3140 3141 3142 3143
	if (ret == NULL) {
		hash_openowner(oo, clp, strhashval);
		ret = oo;
	} else
		nfs4_free_openowner(&oo->oo_owner);
3144
	spin_unlock(&clp->cl_lock);
3145
	return oo;
L
Linus Torvalds 已提交
3146 3147
}

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

3151
	atomic_inc(&stp->st_stid.sc_count);
J
J. Bruce Fields 已提交
3152
	stp->st_stid.sc_type = NFS4_OPEN_STID;
3153
	INIT_LIST_HEAD(&stp->st_locks);
3154
	stp->st_stateowner = &oo->oo_owner;
3155
	atomic_inc(&stp->st_stateowner->so_count);
3156
	get_nfs4_file(fp);
3157
	stp->st_stid.sc_file = fp;
L
Linus Torvalds 已提交
3158 3159
	stp->st_access_bmap = 0;
	stp->st_deny_bmap = 0;
3160
	stp->st_openstp = NULL;
3161 3162
	spin_lock(&oo->oo_owner.so_client->cl_lock);
	list_add(&stp->st_perstateowner, &oo->oo_owner.so_stateids);
3163 3164 3165
	spin_lock(&fp->fi_lock);
	list_add(&stp->st_perfile, &fp->fi_stateids);
	spin_unlock(&fp->fi_lock);
3166
	spin_unlock(&oo->oo_owner.so_client->cl_lock);
L
Linus Torvalds 已提交
3167 3168
}

3169 3170 3171 3172 3173
/*
 * 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.
 */
3174
static void
3175
move_to_close_lru(struct nfs4_ol_stateid *s, struct net *net)
L
Linus Torvalds 已提交
3176
{
3177 3178 3179
	struct nfs4_openowner *oo = openowner(s->st_stateowner);
	struct nfsd_net *nn = net_generic(s->st_stid.sc_client->net,
						nfsd_net_id);
3180

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

3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193
	/*
	 * 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);

3194 3195 3196 3197 3198 3199 3200
	release_all_access(s);
	if (s->st_stid.sc_file) {
		put_nfs4_file(s->st_stid.sc_file);
		s->st_stid.sc_file = NULL;
	}
	release_last_closed_stateid(oo);
	oo->oo_last_closed_stid = s;
3201
	list_move_tail(&oo->oo_close_lru, &nn->close_lru);
3202
	oo->oo_time = get_seconds();
L
Linus Torvalds 已提交
3203 3204 3205 3206
}

/* search file_hashtbl[] for file */
static struct nfs4_file *
3207
find_file_locked(struct knfsd_fh *fh)
L
Linus Torvalds 已提交
3208
{
3209
	unsigned int hashval = file_hashval(fh);
L
Linus Torvalds 已提交
3210 3211
	struct nfs4_file *fp;

3212 3213
	lockdep_assert_held(&state_lock);

3214
	hlist_for_each_entry(fp, &file_hashtbl[hashval], fi_hash) {
3215
		if (nfsd_fh_match(&fp->fi_fhandle, fh)) {
3216
			get_nfs4_file(fp);
L
Linus Torvalds 已提交
3217
			return fp;
3218
		}
L
Linus Torvalds 已提交
3219 3220 3221 3222
	}
	return NULL;
}

3223
static struct nfs4_file *
3224
find_file(struct knfsd_fh *fh)
3225 3226 3227 3228
{
	struct nfs4_file *fp;

	spin_lock(&state_lock);
3229
	fp = find_file_locked(fh);
3230 3231 3232 3233 3234
	spin_unlock(&state_lock);
	return fp;
}

static struct nfs4_file *
3235
find_or_add_file(struct nfs4_file *new, struct knfsd_fh *fh)
3236 3237 3238 3239
{
	struct nfs4_file *fp;

	spin_lock(&state_lock);
3240
	fp = find_file_locked(fh);
3241
	if (fp == NULL) {
3242
		nfsd4_init_file(new, fh);
3243 3244 3245 3246 3247 3248 3249
		fp = new;
	}
	spin_unlock(&state_lock);

	return fp;
}

L
Linus Torvalds 已提交
3250 3251 3252 3253
/*
 * Called to check deny when READ with all zero stateid or
 * WRITE with all zero or all one stateid
 */
3254
static __be32
L
Linus Torvalds 已提交
3255 3256 3257
nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type)
{
	struct nfs4_file *fp;
3258
	__be32 ret = nfs_ok;
L
Linus Torvalds 已提交
3259

3260
	fp = find_file(&current_fh->fh_handle);
3261
	if (!fp)
3262 3263
		return ret;
	/* Check for conflicting share reservations */
3264
	spin_lock(&fp->fi_lock);
3265 3266
	if (fp->fi_share_deny & deny_type)
		ret = nfserr_locked;
3267
	spin_unlock(&fp->fi_lock);
3268 3269
	put_nfs4_file(fp);
	return ret;
L
Linus Torvalds 已提交
3270 3271
}

3272
void nfsd4_prepare_cb_recall(struct nfs4_delegation *dp)
L
Linus Torvalds 已提交
3273
{
3274 3275
	struct nfsd_net *nn = net_generic(dp->dl_stid.sc_client->net,
					  nfsd_net_id);
3276

3277
	block_delegations(&dp->dl_stid.sc_file->fi_fhandle);
3278

3279
	/*
3280 3281 3282
	 * We can't do this in nfsd_break_deleg_cb because it is
	 * already holding inode->i_lock.
	 *
3283 3284 3285
	 * If the dl_time != 0, then we know that it has already been
	 * queued for a lease break. Don't queue it again.
	 */
3286
	spin_lock(&state_lock);
3287 3288
	if (dp->dl_time == 0) {
		dp->dl_time = get_seconds();
3289
		list_add_tail(&dp->dl_recall_lru, &nn->del_recall_lru);
3290
	}
3291 3292
	spin_unlock(&state_lock);
}
L
Linus Torvalds 已提交
3293

3294 3295 3296 3297 3298 3299 3300 3301 3302
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.
	 */
3303
	atomic_inc(&dp->dl_stid.sc_count);
3304 3305 3306
	nfsd4_cb_recall(dp);
}

3307
/* Called from break_lease() with i_lock held. */
3308 3309
static void nfsd_break_deleg_cb(struct file_lock *fl)
{
3310 3311
	struct nfs4_file *fp = (struct nfs4_file *)fl->fl_owner;
	struct nfs4_delegation *dp;
3312

3313 3314 3315 3316 3317 3318 3319 3320
	if (!fp) {
		WARN(1, "(%p)->fl_owner NULL\n", fl);
		return;
	}
	if (fp->fi_had_conflict) {
		WARN(1, "duplicate break on %p\n", fp);
		return;
	}
3321 3322
	/*
	 * We don't want the locks code to timeout the lease for us;
3323
	 * we'll remove it ourself if a delegation isn't returned
3324
	 * in time:
3325 3326
	 */
	fl->fl_break_time = 0;
L
Linus Torvalds 已提交
3327

3328
	spin_lock(&fp->fi_lock);
3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340
	fp->fi_had_conflict = true;
	/*
	 * If there are no delegations on the list, then we can't count on this
	 * lease ever being cleaned up. Set the fl_break_time to jiffies so that
	 * time_out_leases will do it ASAP. The fact that fi_had_conflict is now
	 * true should keep any new delegations from being hashed.
	 */
	if (list_empty(&fp->fi_delegations))
		fl->fl_break_time = jiffies;
	else
		list_for_each_entry(dp, &fp->fi_delegations, dl_perfile)
			nfsd_break_one_deleg(dp);
3341
	spin_unlock(&fp->fi_lock);
L
Linus Torvalds 已提交
3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352
}

static
int nfsd_change_deleg_cb(struct file_lock **onlist, int arg)
{
	if (arg & F_UNLCK)
		return lease_modify(onlist, arg);
	else
		return -EAGAIN;
}

3353
static const struct lock_manager_operations nfsd_lease_mng_ops = {
J
J. Bruce Fields 已提交
3354 3355
	.lm_break = nfsd_break_deleg_cb,
	.lm_change = nfsd_change_deleg_cb,
L
Linus Torvalds 已提交
3356 3357
};

3358 3359 3360 3361 3362 3363 3364 3365 3366 3367
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 已提交
3368

3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400
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);
	found = find_confirmed_client(clid, false, nn);
	if (!found)
		return nfserr_expired;

	/* Cache the nfs4_client in cstate! */
	cstate->clp = found;
	atomic_inc(&found->cl_refcount);
	return nfs_ok;
}

3401
__be32
A
Andy Adamson 已提交
3402
nfsd4_process_open1(struct nfsd4_compound_state *cstate,
3403
		    struct nfsd4_open *open, struct nfsd_net *nn)
L
Linus Torvalds 已提交
3404 3405 3406 3407
{
	clientid_t *clientid = &open->op_clientid;
	struct nfs4_client *clp = NULL;
	unsigned int strhashval;
3408
	struct nfs4_openowner *oo = NULL;
3409
	__be32 status;
L
Linus Torvalds 已提交
3410

3411
	if (STALE_CLIENTID(&open->op_clientid, nn))
L
Linus Torvalds 已提交
3412
		return nfserr_stale_clientid;
3413 3414 3415 3416 3417 3418 3419
	/*
	 * 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 已提交
3420

3421 3422 3423 3424 3425
	status = lookup_clientid(clientid, cstate, nn);
	if (status)
		return status;
	clp = cstate->clp;

3426 3427
	strhashval = ownerstr_hashval(&open->op_owner);
	oo = find_openstateowner_str(strhashval, open, clp);
3428 3429
	open->op_openowner = oo;
	if (!oo) {
3430
		goto new_owner;
L
Linus Torvalds 已提交
3431
	}
3432
	if (!(oo->oo_flags & NFS4_OO_CONFIRMED)) {
3433
		/* Replace unconfirmed owners without checking for replay. */
3434 3435
		release_openowner(oo);
		open->op_openowner = NULL;
3436
		goto new_owner;
3437
	}
3438 3439 3440 3441
	status = nfsd4_check_seqid(cstate, &oo->oo_owner, open->op_seqid);
	if (status)
		return status;
	goto alloc_stateid;
3442
new_owner:
3443
	oo = alloc_init_open_stateowner(strhashval, open, cstate);
3444 3445 3446
	if (oo == NULL)
		return nfserr_jukebox;
	open->op_openowner = oo;
3447
alloc_stateid:
3448
	open->op_stp = nfs4_alloc_open_stateid(clp);
3449 3450
	if (!open->op_stp)
		return nfserr_jukebox;
3451
	return nfs_ok;
L
Linus Torvalds 已提交
3452 3453
}

3454
static inline __be32
N
NeilBrown 已提交
3455 3456 3457 3458 3459 3460 3461 3462
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;
}

3463
static int share_access_to_flags(u32 share_access)
3464
{
3465
	return share_access == NFS4_SHARE_ACCESS_READ ? RD_STATE : WR_STATE;
3466 3467
}

3468
static struct nfs4_delegation *find_deleg_stateid(struct nfs4_client *cl, stateid_t *s)
3469
{
3470
	struct nfs4_stid *ret;
3471

3472
	ret = find_stateid_by_type(cl, s, NFS4_DELEG_STID);
3473 3474 3475
	if (!ret)
		return NULL;
	return delegstateid(ret);
3476 3477
}

3478 3479 3480 3481 3482 3483
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;
}

3484
static __be32
3485
nfs4_check_deleg(struct nfs4_client *cl, struct nfsd4_open *open,
3486 3487 3488
		struct nfs4_delegation **dp)
{
	int flags;
3489
	__be32 status = nfserr_bad_stateid;
3490
	struct nfs4_delegation *deleg;
3491

3492 3493
	deleg = find_deleg_stateid(cl, &open->op_delegate_stateid);
	if (deleg == NULL)
3494
		goto out;
3495
	flags = share_access_to_flags(open->op_share_access);
3496 3497 3498 3499 3500 3501
	status = nfs4_check_delegmode(deleg, flags);
	if (status) {
		nfs4_put_stid(&deleg->dl_stid);
		goto out;
	}
	*dp = deleg;
3502
out:
3503
	if (!nfsd4_is_deleg_cur(open))
3504 3505 3506
		return nfs_ok;
	if (status)
		return status;
3507
	open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
3508
	return nfs_ok;
3509 3510
}

3511 3512
static struct nfs4_ol_stateid *
nfsd4_find_existing_open(struct nfs4_file *fp, struct nfsd4_open *open)
L
Linus Torvalds 已提交
3513
{
3514
	struct nfs4_ol_stateid *local, *ret = NULL;
3515
	struct nfs4_openowner *oo = open->op_openowner;
L
Linus Torvalds 已提交
3516

3517
	spin_lock(&fp->fi_lock);
3518
	list_for_each_entry(local, &fp->fi_stateids, st_perfile) {
L
Linus Torvalds 已提交
3519 3520 3521
		/* ignore lock owners */
		if (local->st_stateowner->so_is_open_owner == 0)
			continue;
3522
		if (local->st_stateowner == &oo->oo_owner) {
3523
			ret = local;
3524
			atomic_inc(&ret->st_stid.sc_count);
3525
			break;
3526
		}
L
Linus Torvalds 已提交
3527
	}
3528
	spin_unlock(&fp->fi_lock);
3529
	return ret;
L
Linus Torvalds 已提交
3530 3531
}

3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542
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;
}

3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557
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);
}

3558
static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file *fp,
3559 3560
		struct svc_fh *cur_fh, struct nfs4_ol_stateid *stp,
		struct nfsd4_open *open)
3561
{
3562
	struct file *filp = NULL;
3563
	__be32 status;
3564 3565
	int oflag = nfs4_access_to_omode(open->op_share_access);
	int access = nfs4_access_to_access(open->op_share_access);
3566
	unsigned char old_access_bmap, old_deny_bmap;
3567

3568
	spin_lock(&fp->fi_lock);
3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595

	/*
	 * 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);

3596
	if (!fp->fi_fds[oflag]) {
3597 3598
		spin_unlock(&fp->fi_lock);
		status = nfsd_open(rqstp, cur_fh, S_IFREG, access, &filp);
3599
		if (status)
3600
			goto out_put_access;
3601 3602 3603 3604 3605
		spin_lock(&fp->fi_lock);
		if (!fp->fi_fds[oflag]) {
			fp->fi_fds[oflag] = filp;
			filp = NULL;
		}
3606
	}
3607 3608 3609
	spin_unlock(&fp->fi_lock);
	if (filp)
		fput(filp);
3610

3611 3612 3613 3614 3615
	status = nfsd4_truncate(rqstp, cur_fh, open);
	if (status)
		goto out_put_access;
out:
	return status;
3616 3617 3618 3619 3620
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 已提交
3621 3622
}

3623
static __be32
3624
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 已提交
3625
{
3626
	__be32 status;
3627
	unsigned char old_deny_bmap;
L
Linus Torvalds 已提交
3628

3629
	if (!test_access(open->op_share_access, stp))
3630
		return nfs4_get_vfs_file(rqstp, fp, cur_fh, stp, open);
3631

3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643
	/* 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 已提交
3644 3645
		return status;

3646 3647 3648 3649 3650
	status = nfsd4_truncate(rqstp, cur_fh, open);
	if (status != nfs_ok)
		reset_union_bmap_deny(old_deny_bmap, stp);
	return status;
}
L
Linus Torvalds 已提交
3651 3652

static void
3653
nfs4_set_claim_prev(struct nfsd4_open *open, bool has_session)
L
Linus Torvalds 已提交
3654
{
3655
	open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
L
Linus Torvalds 已提交
3656 3657
}

3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670
/* 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;
}

3671
static struct file_lock *nfs4_alloc_init_lease(struct nfs4_file *fp, int flag)
3672 3673 3674 3675 3676 3677 3678 3679
{
	struct file_lock *fl;

	fl = locks_alloc_lock();
	if (!fl)
		return NULL;
	locks_init_lock(fl);
	fl->fl_lmops = &nfsd_lease_mng_ops;
3680
	fl->fl_flags = FL_DELEG;
3681 3682
	fl->fl_type = flag == NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_WRLCK;
	fl->fl_end = OFFSET_MAX;
3683
	fl->fl_owner = (fl_owner_t)fp;
3684 3685 3686 3687
	fl->fl_pid = current->tgid;
	return fl;
}

3688
static int nfs4_setlease(struct nfs4_delegation *dp)
3689
{
3690
	struct nfs4_file *fp = dp->dl_stid.sc_file;
3691
	struct file_lock *fl;
3692 3693
	struct file *filp;
	int status = 0;
3694

3695
	fl = nfs4_alloc_init_lease(fp, NFS4_OPEN_DELEGATE_READ);
3696 3697
	if (!fl)
		return -ENOMEM;
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
	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;
	status = vfs_setlease(filp, fl->fl_type, &fl);
	if (status) {
		locks_free_lock(fl);
		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 */
	if (fp->fi_lease) {
		status = 0;
		atomic_inc(&fp->fi_delegees);
		hash_delegation_locked(dp, fp);
		goto out_unlock;
	}
3723
	fp->fi_lease = fl;
3724
	fp->fi_deleg_file = filp;
3725
	atomic_set(&fp->fi_delegees, 1);
3726
	hash_delegation_locked(dp, fp);
3727
	spin_unlock(&fp->fi_lock);
3728
	spin_unlock(&state_lock);
3729
	return 0;
3730 3731 3732 3733 3734
out_unlock:
	spin_unlock(&fp->fi_lock);
	spin_unlock(&state_lock);
out_fput:
	fput(filp);
3735
	return status;
3736 3737
}

J
Jeff Layton 已提交
3738 3739 3740
static struct nfs4_delegation *
nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh,
		    struct nfs4_file *fp)
3741
{
J
Jeff Layton 已提交
3742 3743
	int status;
	struct nfs4_delegation *dp;
3744

3745
	if (fp->fi_had_conflict)
J
Jeff Layton 已提交
3746 3747 3748 3749 3750 3751
		return ERR_PTR(-EAGAIN);

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

3752
	get_nfs4_file(fp);
3753 3754
	spin_lock(&state_lock);
	spin_lock(&fp->fi_lock);
3755
	dp->dl_stid.sc_file = fp;
3756 3757 3758
	if (!fp->fi_lease) {
		spin_unlock(&fp->fi_lock);
		spin_unlock(&state_lock);
J
Jeff Layton 已提交
3759 3760
		status = nfs4_setlease(dp);
		goto out;
3761
	}
3762
	atomic_inc(&fp->fi_delegees);
3763
	if (fp->fi_had_conflict) {
3764 3765
		status = -EAGAIN;
		goto out_unlock;
3766
	}
3767
	hash_delegation_locked(dp, fp);
J
Jeff Layton 已提交
3768
	status = 0;
3769 3770
out_unlock:
	spin_unlock(&fp->fi_lock);
3771
	spin_unlock(&state_lock);
J
Jeff Layton 已提交
3772 3773
out:
	if (status) {
3774
		nfs4_put_stid(&dp->dl_stid);
J
Jeff Layton 已提交
3775 3776 3777
		return ERR_PTR(status);
	}
	return dp;
3778 3779
}

3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795
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:
3796
			WARN_ON_ONCE(1);
3797 3798 3799 3800
		}
	}
}

L
Linus Torvalds 已提交
3801 3802
/*
 * Attempt to hand out a delegation.
3803 3804 3805
 *
 * Note we don't support write delegations, and won't until the vfs has
 * proper support for them.
L
Linus Torvalds 已提交
3806 3807
 */
static void
3808 3809
nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open,
			struct nfs4_ol_stateid *stp)
L
Linus Torvalds 已提交
3810 3811
{
	struct nfs4_delegation *dp;
3812 3813
	struct nfs4_openowner *oo = openowner(stp->st_stateowner);
	struct nfs4_client *clp = stp->st_stid.sc_client;
3814
	int cb_up;
3815
	int status = 0;
L
Linus Torvalds 已提交
3816

3817
	cb_up = nfsd4_cb_channel_good(oo->oo_owner.so_client);
3818 3819 3820
	open->op_recall = 0;
	switch (open->op_claim_type) {
		case NFS4_OPEN_CLAIM_PREVIOUS:
3821
			if (!cb_up)
3822
				open->op_recall = 1;
3823 3824
			if (open->op_delegate_type != NFS4_OPEN_DELEGATE_READ)
				goto out_no_deleg;
3825 3826
			break;
		case NFS4_OPEN_CLAIM_NULL:
3827
		case NFS4_OPEN_CLAIM_FH:
3828 3829 3830 3831
			/*
			 * Let's not give out any delegations till everyone's
			 * had the chance to reclaim theirs....
			 */
3832
			if (locks_in_grace(clp->net))
3833
				goto out_no_deleg;
3834
			if (!cb_up || !(oo->oo_flags & NFS4_OO_CONFIRMED))
3835
				goto out_no_deleg;
3836 3837 3838 3839 3840 3841 3842
			/*
			 * 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):
			 */
3843
			if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
3844 3845 3846
				goto out_no_deleg;
			if (open->op_create == NFS4_OPEN_CREATE)
				goto out_no_deleg;
3847 3848
			break;
		default:
3849
			goto out_no_deleg;
3850
	}
3851
	dp = nfs4_set_delegation(clp, fh, stp->st_stid.sc_file);
J
Jeff Layton 已提交
3852
	if (IS_ERR(dp))
3853
		goto out_no_deleg;
L
Linus Torvalds 已提交
3854

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

3857
	dprintk("NFSD: delegation stateid=" STATEID_FMT "\n",
3858
		STATEID_VAL(&dp->dl_stid.sc_stateid));
3859
	open->op_delegate_type = NFS4_OPEN_DELEGATE_READ;
3860
	nfs4_put_stid(&dp->dl_stid);
3861 3862
	return;
out_no_deleg:
3863 3864
	open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE;
	if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS &&
3865
	    open->op_delegate_type != NFS4_OPEN_DELEGATE_NONE) {
3866
		dprintk("NFSD: WARNING: refusing delegation reclaim\n");
3867 3868
		open->op_recall = 1;
	}
3869 3870 3871 3872 3873

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

3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893
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.
	 */
}

L
Linus Torvalds 已提交
3894 3895 3896
/*
 * called with nfs4_lock_state() held.
 */
3897
__be32
L
Linus Torvalds 已提交
3898 3899
nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
{
A
Andy Adamson 已提交
3900
	struct nfsd4_compoundres *resp = rqstp->rq_resp;
3901
	struct nfs4_client *cl = open->op_openowner->oo_owner.so_client;
L
Linus Torvalds 已提交
3902
	struct nfs4_file *fp = NULL;
3903
	struct nfs4_ol_stateid *stp = NULL;
3904
	struct nfs4_delegation *dp = NULL;
3905
	__be32 status;
L
Linus Torvalds 已提交
3906 3907 3908 3909 3910 3911

	/*
	 * 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
	 */
3912
	fp = find_or_add_file(open->op_file, &current_fh->fh_handle);
3913
	if (fp != open->op_file) {
3914
		status = nfs4_check_deleg(cl, open, &dp);
3915 3916
		if (status)
			goto out;
3917
		stp = nfsd4_find_existing_open(fp, open);
L
Linus Torvalds 已提交
3918
	} else {
3919
		open->op_file = NULL;
3920
		status = nfserr_bad_stateid;
3921
		if (nfsd4_is_deleg_cur(open))
3922
			goto out;
3923
		status = nfserr_jukebox;
L
Linus Torvalds 已提交
3924 3925 3926 3927 3928 3929 3930 3931
	}

	/*
	 * OPEN the file, or upgrade an existing OPEN.
	 * If truncate fails, the OPEN fails.
	 */
	if (stp) {
		/* Stateid was found, this is an OPEN upgrade */
3932
		status = nfs4_upgrade_open(rqstp, fp, current_fh, stp, open);
L
Linus Torvalds 已提交
3933 3934 3935
		if (status)
			goto out;
	} else {
3936 3937
		stp = open->op_stp;
		open->op_stp = NULL;
3938
		init_open_stateid(stp, fp, open);
3939 3940 3941 3942 3943
		status = nfs4_get_vfs_file(rqstp, fp, current_fh, stp, open);
		if (status) {
			release_open_stateid(stp);
			goto out;
		}
L
Linus Torvalds 已提交
3944
	}
3945 3946
	update_stateid(&stp->st_stid.sc_stateid);
	memcpy(&open->op_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
L
Linus Torvalds 已提交
3947

3948 3949 3950 3951 3952 3953 3954 3955
	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 已提交
3956 3957 3958 3959
	/*
	* Attempt to hand out a delegation. No error return, because the
	* OPEN succeeds even if we fail.
	*/
3960
	nfs4_open_delegation(current_fh, open, stp);
3961
nodeleg:
L
Linus Torvalds 已提交
3962 3963
	status = nfs_ok;

3964
	dprintk("%s: stateid=" STATEID_FMT "\n", __func__,
3965
		STATEID_VAL(&stp->st_stid.sc_stateid));
L
Linus Torvalds 已提交
3966
out:
3967 3968
	/* 4.1 client trying to upgrade/downgrade delegation? */
	if (open->op_delegate_type == NFS4_OPEN_DELEGATE_NONE && dp &&
3969 3970
	    open->op_deleg_want)
		nfsd4_deleg_xgrade_none_ext(open, dp);
3971

3972 3973
	if (fp)
		put_nfs4_file(fp);
3974
	if (status == 0 && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
3975
		nfs4_set_claim_prev(open, nfsd4_has_session(&resp->cstate));
L
Linus Torvalds 已提交
3976 3977 3978 3979
	/*
	* To finish the open response, we just need to set the rflags.
	*/
	open->op_rflags = NFS4_OPEN_RESULT_LOCKTYPE_POSIX;
3980
	if (!(open->op_openowner->oo_flags & NFS4_OO_CONFIRMED) &&
A
Andy Adamson 已提交
3981
	    !nfsd4_has_session(&resp->cstate))
L
Linus Torvalds 已提交
3982
		open->op_rflags |= NFS4_OPEN_RESULT_CONFIRM;
3983 3984
	if (dp)
		nfs4_put_stid(&dp->dl_stid);
3985 3986
	if (stp)
		nfs4_put_stid(&stp->st_stid);
L
Linus Torvalds 已提交
3987 3988 3989 3990

	return status;
}

3991 3992
void nfsd4_cleanup_open_state(struct nfsd4_compound_state *cstate,
			      struct nfsd4_open *open, __be32 status)
3993 3994
{
	if (open->op_openowner) {
3995 3996 3997 3998
		struct nfs4_stateowner *so = &open->op_openowner->oo_owner;

		nfsd4_cstate_assign_replay(cstate, so);
		nfs4_put_stateowner(so);
3999
	}
4000 4001
	if (open->op_file)
		nfsd4_free_file(open->op_file);
4002
	if (open->op_stp)
4003
		nfs4_put_stid(&open->op_stp->st_stid);
4004 4005
}

4006
__be32
4007 4008
nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	    clientid_t *clid)
L
Linus Torvalds 已提交
4009 4010
{
	struct nfs4_client *clp;
4011
	__be32 status;
4012
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
L
Linus Torvalds 已提交
4013 4014 4015 4016

	nfs4_lock_state();
	dprintk("process_renew(%08x/%08x): starting\n", 
			clid->cl_boot, clid->cl_id);
4017
	status = lookup_clientid(clid, cstate, nn);
4018
	if (status)
L
Linus Torvalds 已提交
4019
		goto out;
4020
	clp = cstate->clp;
L
Linus Torvalds 已提交
4021
	status = nfserr_cb_path_down;
4022
	if (!list_empty(&clp->cl_delegations)
4023
			&& clp->cl_cb_state != NFSD4_CB_UP)
L
Linus Torvalds 已提交
4024 4025 4026 4027 4028 4029 4030
		goto out;
	status = nfs_ok;
out:
	nfs4_unlock_state();
	return status;
}

4031
static void
4032
nfsd4_end_grace(struct nfsd_net *nn)
4033
{
4034
	/* do nothing if grace period already ended */
4035
	if (nn->grace_ended)
4036 4037
		return;

4038
	dprintk("NFSD: end of grace period\n");
4039
	nn->grace_ended = true;
4040
	nfsd4_record_grace_done(nn, nn->boot_time);
4041
	locks_end_grace(&nn->nfsd4_manager);
4042 4043 4044 4045 4046
	/*
	 * Now that every NFSv4 client has had the chance to recover and
	 * to see the (possibly new, possibly shorter) lease time, we
	 * can safely set the next grace time to the current lease time:
	 */
4047
	nn->nfsd4_grace = nn->nfsd4_lease;
4048 4049
}

4050
static time_t
4051
nfs4_laundromat(struct nfsd_net *nn)
L
Linus Torvalds 已提交
4052 4053
{
	struct nfs4_client *clp;
4054
	struct nfs4_openowner *oo;
L
Linus Torvalds 已提交
4055 4056
	struct nfs4_delegation *dp;
	struct list_head *pos, *next, reaplist;
4057
	time_t cutoff = get_seconds() - nn->nfsd4_lease;
4058
	time_t t, new_timeo = nn->nfsd4_lease;
L
Linus Torvalds 已提交
4059 4060 4061 4062

	nfs4_lock_state();

	dprintk("NFSD: laundromat service - starting\n");
4063
	nfsd4_end_grace(nn);
4064
	INIT_LIST_HEAD(&reaplist);
4065
	spin_lock(&nn->client_lock);
4066
	list_for_each_safe(pos, next, &nn->client_lru) {
L
Linus Torvalds 已提交
4067 4068 4069
		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;
4070
			new_timeo = min(new_timeo, t);
L
Linus Torvalds 已提交
4071 4072
			break;
		}
4073
		if (mark_client_expired_locked(clp)) {
4074 4075 4076 4077
			dprintk("NFSD: client in use (clientid %08x)\n",
				clp->cl_clientid.cl_id);
			continue;
		}
4078
		list_move(&clp->cl_lru, &reaplist);
4079
	}
4080
	spin_unlock(&nn->client_lock);
4081 4082
	list_for_each_safe(pos, next, &reaplist) {
		clp = list_entry(pos, struct nfs4_client, cl_lru);
L
Linus Torvalds 已提交
4083 4084 4085 4086
		dprintk("NFSD: purging unused client (clientid %08x)\n",
			clp->cl_clientid.cl_id);
		expire_client(clp);
	}
4087
	spin_lock(&state_lock);
4088
	list_for_each_safe(pos, next, &nn->del_recall_lru) {
L
Linus Torvalds 已提交
4089
		dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
4090 4091
		if (net_generic(dp->dl_stid.sc_client->net, nfsd_net_id) != nn)
			continue;
L
Linus Torvalds 已提交
4092
		if (time_after((unsigned long)dp->dl_time, (unsigned long)cutoff)) {
4093 4094
			t = dp->dl_time - cutoff;
			new_timeo = min(new_timeo, t);
L
Linus Torvalds 已提交
4095 4096
			break;
		}
4097 4098
		unhash_delegation_locked(dp);
		list_add(&dp->dl_recall_lru, &reaplist);
L
Linus Torvalds 已提交
4099
	}
4100
	spin_unlock(&state_lock);
4101 4102 4103 4104
	while (!list_empty(&reaplist)) {
		dp = list_first_entry(&reaplist, struct nfs4_delegation,
					dl_recall_lru);
		list_del_init(&dp->dl_recall_lru);
4105
		revoke_delegation(dp);
L
Linus Torvalds 已提交
4106
	}
4107
	list_for_each_safe(pos, next, &nn->close_lru) {
4108 4109
		oo = container_of(pos, struct nfs4_openowner, oo_close_lru);
		if (time_after((unsigned long)oo->oo_time, (unsigned long)cutoff)) {
4110 4111
			t = oo->oo_time - cutoff;
			new_timeo = min(new_timeo, t);
L
Linus Torvalds 已提交
4112 4113
			break;
		}
4114
		release_last_closed_stateid(oo);
L
Linus Torvalds 已提交
4115
	}
4116
	new_timeo = max_t(time_t, new_timeo, NFSD_LAUNDROMAT_MINTIMEOUT);
L
Linus Torvalds 已提交
4117
	nfs4_unlock_state();
4118
	return new_timeo;
L
Linus Torvalds 已提交
4119 4120
}

H
Harvey Harrison 已提交
4121 4122 4123 4124
static struct workqueue_struct *laundry_wq;
static void laundromat_main(struct work_struct *);

static void
4125
laundromat_main(struct work_struct *laundry)
L
Linus Torvalds 已提交
4126 4127
{
	time_t t;
4128 4129 4130 4131
	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 已提交
4132

4133
	t = nfs4_laundromat(nn);
L
Linus Torvalds 已提交
4134
	dprintk("NFSD: laundromat_main - sleeping for %ld seconds\n", t);
4135
	queue_delayed_work(laundry_wq, &nn->laundromat_work, t*HZ);
L
Linus Torvalds 已提交
4136 4137
}

4138
static inline __be32 nfs4_check_fh(struct svc_fh *fhp, struct nfs4_ol_stateid *stp)
L
Linus Torvalds 已提交
4139
{
4140
	if (!nfsd_fh_match(&fhp->fh_handle, &stp->st_stid.sc_file->fi_fhandle))
4141 4142
		return nfserr_bad_stateid;
	return nfs_ok;
L
Linus Torvalds 已提交
4143 4144 4145
}

static inline int
4146
access_permit_read(struct nfs4_ol_stateid *stp)
L
Linus Torvalds 已提交
4147
{
4148 4149 4150
	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 已提交
4151 4152 4153
}

static inline int
4154
access_permit_write(struct nfs4_ol_stateid *stp)
L
Linus Torvalds 已提交
4155
{
4156 4157
	return test_access(NFS4_SHARE_ACCESS_WRITE, stp) ||
		test_access(NFS4_SHARE_ACCESS_BOTH, stp);
L
Linus Torvalds 已提交
4158 4159 4160
}

static
4161
__be32 nfs4_check_openmode(struct nfs4_ol_stateid *stp, int flags)
L
Linus Torvalds 已提交
4162
{
4163
        __be32 status = nfserr_openmode;
L
Linus Torvalds 已提交
4164

4165 4166 4167
	/* For lock stateid's, we test the parent open, not the lock: */
	if (stp->st_openstp)
		stp = stp->st_openstp;
4168
	if ((flags & WR_STATE) && !access_permit_write(stp))
L
Linus Torvalds 已提交
4169
                goto out;
4170
	if ((flags & RD_STATE) && !access_permit_read(stp))
L
Linus Torvalds 已提交
4171 4172 4173 4174 4175 4176
                goto out;
	status = nfs_ok;
out:
	return status;
}

4177
static inline __be32
4178
check_special_stateids(struct net *net, svc_fh *current_fh, stateid_t *stateid, int flags)
L
Linus Torvalds 已提交
4179
{
4180
	if (ONE_STATEID(stateid) && (flags & RD_STATE))
L
Linus Torvalds 已提交
4181
		return nfs_ok;
4182
	else if (locks_in_grace(net)) {
L
Lucas De Marchi 已提交
4183
		/* Answer in remaining cases depends on existence of
L
Linus Torvalds 已提交
4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198
		 * 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
4199
grace_disallows_io(struct net *net, struct inode *inode)
L
Linus Torvalds 已提交
4200
{
4201
	return locks_in_grace(net) && mandatory_lock(inode);
L
Linus Torvalds 已提交
4202 4203
}

4204 4205 4206
/* Returns true iff a is later than b: */
static bool stateid_generation_after(stateid_t *a, stateid_t *b)
{
J
Jim Rees 已提交
4207
	return (s32)(a->si_generation - b->si_generation) > 0;
4208 4209
}

J
J. Bruce Fields 已提交
4210
static __be32 check_stateid_generation(stateid_t *in, stateid_t *ref, bool has_session)
4211
{
A
Andy Adamson 已提交
4212 4213 4214 4215
	/*
	 * When sessions are used the stateid generation number is ignored
	 * when it is zero.
	 */
J
J. Bruce Fields 已提交
4216
	if (has_session && in->si_generation == 0)
4217 4218 4219 4220
		return nfs_ok;

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

4222
	/* If the client sends us a stateid from the future, it's buggy: */
4223
	if (stateid_generation_after(in, ref))
4224 4225
		return nfserr_bad_stateid;
	/*
4226 4227 4228 4229 4230 4231 4232 4233
	 * 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:
4234
	 */
4235
	return nfserr_old_stateid;
4236 4237
}

4238
static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid)
4239
{
4240 4241
	struct nfs4_stid *s;
	struct nfs4_ol_stateid *ols;
4242
	__be32 status = nfserr_bad_stateid;
4243

4244
	if (ZERO_STATEID(stateid) || ONE_STATEID(stateid))
4245
		return status;
4246 4247 4248 4249 4250 4251 4252
	/* 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);
4253
		return status;
4254
	}
4255 4256
	spin_lock(&cl->cl_lock);
	s = find_stateid_locked(cl, stateid);
4257
	if (!s)
4258
		goto out_unlock;
4259
	status = check_stateid_generation(stateid, &s->sc_stateid, 1);
4260
	if (status)
4261
		goto out_unlock;
4262 4263
	switch (s->sc_type) {
	case NFS4_DELEG_STID:
4264 4265
		status = nfs_ok;
		break;
4266
	case NFS4_REVOKED_DELEG_STID:
4267 4268
		status = nfserr_deleg_revoked;
		break;
4269 4270 4271 4272 4273 4274
	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))
4275 4276 4277 4278
			status = nfserr_bad_stateid;
		else
			status = nfs_ok;
		break;
4279 4280
	default:
		printk("unknown stateid type %x\n", s->sc_type);
4281
		/* Fallthrough */
4282
	case NFS4_CLOSED_STID:
4283
	case NFS4_CLOSED_DELEG_STID:
4284
		status = nfserr_bad_stateid;
4285
	}
4286 4287 4288
out_unlock:
	spin_unlock(&cl->cl_lock);
	return status;
4289 4290
}

4291 4292 4293 4294
static __be32
nfsd4_lookup_stateid(struct nfsd4_compound_state *cstate,
		     stateid_t *stateid, unsigned char typemask,
		     struct nfs4_stid **s, struct nfsd_net *nn)
4295
{
J
J. Bruce Fields 已提交
4296
	__be32 status;
4297 4298 4299

	if (ZERO_STATEID(stateid) || ONE_STATEID(stateid))
		return nfserr_bad_stateid;
4300
	status = lookup_clientid(&stateid->si_opaque.so_clid, cstate, nn);
4301
	if (status == nfserr_stale_clientid) {
4302
		if (cstate->session)
4303
			return nfserr_bad_stateid;
4304
		return nfserr_stale_stateid;
4305
	}
J
J. Bruce Fields 已提交
4306 4307
	if (status)
		return status;
4308
	*s = find_stateid_by_type(cstate->clp, stateid, typemask);
4309 4310 4311 4312 4313
	if (!*s)
		return nfserr_bad_stateid;
	return nfs_ok;
}

L
Linus Torvalds 已提交
4314 4315 4316
/*
* Checks for stateid operations
*/
4317
__be32
4318
nfs4_preprocess_stateid_op(struct net *net, struct nfsd4_compound_state *cstate,
4319
			   stateid_t *stateid, int flags, struct file **filpp)
L
Linus Torvalds 已提交
4320
{
4321
	struct nfs4_stid *s;
4322
	struct nfs4_ol_stateid *stp = NULL;
L
Linus Torvalds 已提交
4323
	struct nfs4_delegation *dp = NULL;
4324
	struct svc_fh *current_fh = &cstate->current_fh;
L
Linus Torvalds 已提交
4325
	struct inode *ino = current_fh->fh_dentry->d_inode;
4326
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
4327
	struct file *file = NULL;
4328
	__be32 status;
L
Linus Torvalds 已提交
4329 4330 4331 4332

	if (filpp)
		*filpp = NULL;

4333
	if (grace_disallows_io(net, ino))
L
Linus Torvalds 已提交
4334 4335 4336
		return nfserr_grace;

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

4339 4340
	nfs4_lock_state();

4341
	status = nfsd4_lookup_stateid(cstate, stateid,
4342
				NFS4_DELEG_STID|NFS4_OPEN_STID|NFS4_LOCK_STID,
4343
				&s, nn);
4344
	if (status)
4345
		goto unlock_state;
4346 4347 4348
	status = check_stateid_generation(stateid, &s->sc_stateid, nfsd4_has_session(cstate));
	if (status)
		goto out;
4349 4350
	switch (s->sc_type) {
	case NFS4_DELEG_STID:
4351
		dp = delegstateid(s);
4352 4353 4354
		status = nfs4_check_delegmode(dp, flags);
		if (status)
			goto out;
4355
		if (filpp) {
4356
			file = dp->dl_stid.sc_file->fi_deleg_file;
4357
			if (!file) {
4358 4359 4360 4361
				WARN_ON_ONCE(1);
				status = nfserr_serverfault;
				goto out;
			}
4362
			get_file(file);
4363
		}
4364 4365 4366
		break;
	case NFS4_OPEN_STID:
	case NFS4_LOCK_STID:
4367
		stp = openlockstateid(s);
4368 4369
		status = nfs4_check_fh(current_fh, stp);
		if (status)
L
Linus Torvalds 已提交
4370
			goto out;
4371
		if (stp->st_stateowner->so_is_open_owner
4372
		    && !(openowner(stp->st_stateowner)->oo_flags & NFS4_OO_CONFIRMED))
L
Linus Torvalds 已提交
4373
			goto out;
4374 4375
		status = nfs4_check_openmode(stp, flags);
		if (status)
L
Linus Torvalds 已提交
4376
			goto out;
4377
		if (filpp) {
4378 4379
			struct nfs4_file *fp = stp->st_stid.sc_file;

4380
			if (flags & RD_STATE)
4381
				file = find_readable_file(fp);
4382
			else
4383
				file = find_writeable_file(fp);
4384
		}
4385 4386
		break;
	default:
4387 4388
		status = nfserr_bad_stateid;
		goto out;
L
Linus Torvalds 已提交
4389 4390
	}
	status = nfs_ok;
4391
	if (file)
4392
		*filpp = file;
L
Linus Torvalds 已提交
4393
out:
4394 4395
	nfs4_put_stid(s);
unlock_state:
4396
	nfs4_unlock_state();
L
Linus Torvalds 已提交
4397 4398 4399
	return status;
}

4400
static __be32
4401
nfsd4_free_lock_stateid(struct nfs4_ol_stateid *stp)
4402
{
4403 4404
	struct nfs4_lockowner *lo = lockowner(stp->st_stateowner);

4405
	if (check_for_locks(stp->st_stid.sc_file, lo))
4406
		return nfserr_locks_held;
4407
	release_lock_stateid(stp);
4408 4409 4410
	return nfs_ok;
}

4411 4412 4413 4414 4415 4416 4417
/*
 * 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)
{
4418 4419 4420 4421 4422
	struct nfsd4_test_stateid_id *stateid;
	struct nfs4_client *cl = cstate->session->se_client;

	nfs4_lock_state();
	list_for_each_entry(stateid, &test_stateid->ts_stateid_list, ts_id_list)
4423 4424
		stateid->ts_id_status =
			nfsd4_validate_stateid(cl, &stateid->ts_id_stateid);
4425 4426
	nfs4_unlock_state();

4427 4428 4429
	return nfs_ok;
}

4430 4431 4432 4433 4434
__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 已提交
4435
	struct nfs4_stid *s;
4436
	struct nfs4_delegation *dp;
4437
	struct nfs4_client *cl = cstate->session->se_client;
J
J. Bruce Fields 已提交
4438
	__be32 ret = nfserr_bad_stateid;
4439 4440

	nfs4_lock_state();
4441 4442
	spin_lock(&cl->cl_lock);
	s = find_stateid_locked(cl, stateid);
J
J. Bruce Fields 已提交
4443
	if (!s)
4444
		goto out_unlock;
J
J. Bruce Fields 已提交
4445 4446
	switch (s->sc_type) {
	case NFS4_DELEG_STID:
4447
		ret = nfserr_locks_held;
4448
		break;
J
J. Bruce Fields 已提交
4449 4450 4451
	case NFS4_OPEN_STID:
		ret = check_stateid_generation(stateid, &s->sc_stateid, 1);
		if (ret)
4452 4453
			break;
		ret = nfserr_locks_held;
4454
		break;
4455 4456 4457 4458 4459 4460 4461
	case NFS4_LOCK_STID:
		ret = check_stateid_generation(stateid, &s->sc_stateid, 1);
		if (ret)
			break;
		spin_unlock(&cl->cl_lock);
		ret = nfsd4_free_lock_stateid(openlockstateid(s));
		goto out;
4462 4463
	case NFS4_REVOKED_DELEG_STID:
		dp = delegstateid(s);
4464 4465
		list_del_init(&dp->dl_recall_lru);
		spin_unlock(&cl->cl_lock);
4466
		nfs4_put_stid(s);
4467
		ret = nfs_ok;
4468 4469
		goto out;
	/* Default falls through and returns nfserr_bad_stateid */
4470
	}
4471 4472
out_unlock:
	spin_unlock(&cl->cl_lock);
4473 4474 4475 4476 4477
out:
	nfs4_unlock_state();
	return ret;
}

4478 4479 4480 4481 4482 4483
static inline int
setlkflg (int type)
{
	return (type == NFS4_READW_LT || type == NFS4_READ_LT) ?
		RD_STATE : WR_STATE;
}
L
Linus Torvalds 已提交
4484

4485
static __be32 nfs4_seqid_op_checks(struct nfsd4_compound_state *cstate, stateid_t *stateid, u32 seqid, struct nfs4_ol_stateid *stp)
4486 4487 4488 4489 4490 4491 4492 4493
{
	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;
4494 4495
	if (stp->st_stid.sc_type == NFS4_CLOSED_STID
		|| stp->st_stid.sc_type == NFS4_REVOKED_DELEG_STID)
4496 4497
		/*
		 * "Closed" stateid's exist *only* to return
4498 4499
		 * nfserr_replay_me from the previous step, and
		 * revoked delegations are kept only for free_stateid.
4500 4501 4502 4503 4504 4505
		 */
		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);
4506 4507
}

L
Linus Torvalds 已提交
4508 4509 4510
/* 
 * Checks for sequence id mutating operations. 
 */
4511
static __be32
4512
nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid,
4513
			 stateid_t *stateid, char typemask,
4514 4515
			 struct nfs4_ol_stateid **stpp,
			 struct nfsd_net *nn)
L
Linus Torvalds 已提交
4516
{
4517
	__be32 status;
4518
	struct nfs4_stid *s;
4519
	struct nfs4_ol_stateid *stp = NULL;
L
Linus Torvalds 已提交
4520

4521 4522
	dprintk("NFSD: %s: seqid=%d stateid = " STATEID_FMT "\n", __func__,
		seqid, STATEID_VAL(stateid));
4523

L
Linus Torvalds 已提交
4524
	*stpp = NULL;
4525
	status = nfsd4_lookup_stateid(cstate, stateid, typemask, &s, nn);
4526 4527
	if (status)
		return status;
4528
	stp = openlockstateid(s);
4529
	nfsd4_cstate_assign_replay(cstate, stp->st_stateowner);
L
Linus Torvalds 已提交
4530

4531
	status = nfs4_seqid_op_checks(cstate, stateid, seqid, stp);
4532
	if (!status)
4533
		*stpp = stp;
4534 4535
	else
		nfs4_put_stid(&stp->st_stid);
4536
	return status;
4537
}
4538

4539 4540
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)
4541 4542 4543
{
	__be32 status;
	struct nfs4_openowner *oo;
4544
	struct nfs4_ol_stateid *stp;
L
Linus Torvalds 已提交
4545

4546
	status = nfs4_preprocess_seqid_op(cstate, seqid, stateid,
4547
						NFS4_OPEN_STID, &stp, nn);
4548 4549
	if (status)
		return status;
4550 4551 4552
	oo = openowner(stp->st_stateowner);
	if (!(oo->oo_flags & NFS4_OO_CONFIRMED)) {
		nfs4_put_stid(&stp->st_stid);
4553
		return nfserr_bad_stateid;
4554 4555
	}
	*stpp = stp;
4556
	return nfs_ok;
L
Linus Torvalds 已提交
4557 4558
}

4559
__be32
4560
nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4561
		   struct nfsd4_open_confirm *oc)
L
Linus Torvalds 已提交
4562
{
4563
	__be32 status;
4564
	struct nfs4_openowner *oo;
4565
	struct nfs4_ol_stateid *stp;
4566
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
L
Linus Torvalds 已提交
4567

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

4571
	status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0);
4572 4573
	if (status)
		return status;
L
Linus Torvalds 已提交
4574 4575 4576

	nfs4_lock_state();

4577
	status = nfs4_preprocess_seqid_op(cstate,
4578
					oc->oc_seqid, &oc->oc_req_stateid,
4579
					NFS4_OPEN_STID, &stp, nn);
4580
	if (status)
4581
		goto out;
4582
	oo = openowner(stp->st_stateowner);
4583
	status = nfserr_bad_stateid;
4584
	if (oo->oo_flags & NFS4_OO_CONFIRMED)
4585
		goto put_stateid;
4586
	oo->oo_flags |= NFS4_OO_CONFIRMED;
4587 4588
	update_stateid(&stp->st_stid.sc_stateid);
	memcpy(&oc->oc_resp_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
4589
	dprintk("NFSD: %s: success, seqid=%d stateid=" STATEID_FMT "\n",
4590
		__func__, oc->oc_seqid, STATEID_VAL(&stp->st_stid.sc_stateid));
4591

4592
	nfsd4_client_record_create(oo->oo_owner.so_client);
4593
	status = nfs_ok;
4594 4595
put_stateid:
	nfs4_put_stid(&stp->st_stid);
L
Linus Torvalds 已提交
4596
out:
4597
	nfsd4_bump_seqid(cstate, status);
4598
	nfs4_unlock_state();
L
Linus Torvalds 已提交
4599 4600 4601
	return status;
}

J
J. Bruce Fields 已提交
4602
static inline void nfs4_stateid_downgrade_bit(struct nfs4_ol_stateid *stp, u32 access)
L
Linus Torvalds 已提交
4603
{
4604
	if (!test_access(access, stp))
J
J. Bruce Fields 已提交
4605
		return;
4606
	nfs4_file_put_access(stp->st_stid.sc_file, access);
4607
	clear_access(access, stp);
J
J. Bruce Fields 已提交
4608
}
4609

J
J. Bruce Fields 已提交
4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623
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:
4624
		WARN_ON_ONCE(1);
L
Linus Torvalds 已提交
4625 4626 4627
	}
}

4628
__be32
4629 4630
nfsd4_open_downgrade(struct svc_rqst *rqstp,
		     struct nfsd4_compound_state *cstate,
4631
		     struct nfsd4_open_downgrade *od)
L
Linus Torvalds 已提交
4632
{
4633
	__be32 status;
4634
	struct nfs4_ol_stateid *stp;
4635
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
L
Linus Torvalds 已提交
4636

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

4640
	/* We don't yet support WANT bits: */
4641 4642 4643
	if (od->od_deleg_want)
		dprintk("NFSD: %s: od_deleg_want=0x%x ignored\n", __func__,
			od->od_deleg_want);
L
Linus Torvalds 已提交
4644 4645

	nfs4_lock_state();
4646
	status = nfs4_preprocess_confirmed_seqid_op(cstate, od->od_seqid,
4647
					&od->od_stateid, &stp, nn);
4648
	if (status)
L
Linus Torvalds 已提交
4649 4650
		goto out; 
	status = nfserr_inval;
4651
	if (!test_access(od->od_share_access, stp)) {
4652
		dprintk("NFSD: access not a subset of current bitmap: 0x%hhx, input access=%08x\n",
L
Linus Torvalds 已提交
4653
			stp->st_access_bmap, od->od_share_access);
4654
		goto put_stateid;
L
Linus Torvalds 已提交
4655
	}
4656
	if (!test_deny(od->od_share_deny, stp)) {
4657
		dprintk("NFSD: deny not a subset of current bitmap: 0x%hhx, input deny=%08x\n",
L
Linus Torvalds 已提交
4658
			stp->st_deny_bmap, od->od_share_deny);
4659
		goto put_stateid;
L
Linus Torvalds 已提交
4660
	}
J
J. Bruce Fields 已提交
4661
	nfs4_stateid_downgrade(stp, od->od_share_access);
L
Linus Torvalds 已提交
4662

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

4665 4666
	update_stateid(&stp->st_stid.sc_stateid);
	memcpy(&od->od_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
L
Linus Torvalds 已提交
4667
	status = nfs_ok;
4668 4669
put_stateid:
	nfs4_put_stid(&stp->st_stid);
L
Linus Torvalds 已提交
4670
out:
4671
	nfsd4_bump_seqid(cstate, status);
4672
	nfs4_unlock_state();
L
Linus Torvalds 已提交
4673 4674 4675
	return status;
}

4676 4677
static void nfsd4_close_open_stateid(struct nfs4_ol_stateid *s)
{
4678 4679
	struct nfs4_client *clp = s->st_stid.sc_client;

4680
	s->st_stid.sc_type = NFS4_CLOSED_STID;
4681 4682
	unhash_open_stateid(s);

4683
	if (clp->cl_minorversion)
4684
		nfs4_put_stid(&s->st_stid);
4685 4686
	else
		move_to_close_lru(s, clp->net);
4687 4688
}

L
Linus Torvalds 已提交
4689 4690 4691
/*
 * nfs4_unlock_state() called after encode
 */
4692
__be32
4693
nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4694
	    struct nfsd4_close *close)
L
Linus Torvalds 已提交
4695
{
4696
	__be32 status;
4697
	struct nfs4_ol_stateid *stp;
4698 4699
	struct net *net = SVC_NET(rqstp);
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
L
Linus Torvalds 已提交
4700

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

	nfs4_lock_state();
4705 4706 4707
	status = nfs4_preprocess_seqid_op(cstate, close->cl_seqid,
					&close->cl_stateid,
					NFS4_OPEN_STID|NFS4_CLOSED_STID,
4708
					&stp, nn);
4709
	nfsd4_bump_seqid(cstate, status);
4710
	if (status)
L
Linus Torvalds 已提交
4711
		goto out; 
4712 4713
	update_stateid(&stp->st_stid.sc_stateid);
	memcpy(&close->cl_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
L
Linus Torvalds 已提交
4714

4715
	nfsd4_close_open_stateid(stp);
4716 4717 4718

	/* put reference from nfs4_preprocess_seqid_op */
	nfs4_put_stid(&stp->st_stid);
L
Linus Torvalds 已提交
4719
out:
4720
	nfs4_unlock_state();
L
Linus Torvalds 已提交
4721 4722 4723
	return status;
}

4724
__be32
4725 4726
nfsd4_delegreturn(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
		  struct nfsd4_delegreturn *dr)
L
Linus Torvalds 已提交
4727
{
4728 4729
	struct nfs4_delegation *dp;
	stateid_t *stateid = &dr->dr_stateid;
4730
	struct nfs4_stid *s;
4731
	__be32 status;
4732
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
L
Linus Torvalds 已提交
4733

4734
	if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0)))
4735
		return status;
L
Linus Torvalds 已提交
4736 4737

	nfs4_lock_state();
4738
	status = nfsd4_lookup_stateid(cstate, stateid, NFS4_DELEG_STID, &s, nn);
4739
	if (status)
4740
		goto out;
4741
	dp = delegstateid(s);
4742
	status = check_stateid_generation(stateid, &dp->dl_stid.sc_stateid, nfsd4_has_session(cstate));
4743
	if (status)
4744
		goto put_stateid;
4745

4746
	destroy_delegation(dp);
4747 4748
put_stateid:
	nfs4_put_stid(&dp->dl_stid);
L
Linus Torvalds 已提交
4749
out:
4750 4751
	nfs4_unlock_state();

L
Linus Torvalds 已提交
4752 4753 4754 4755 4756 4757
	return status;
}


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

B
Benny Halevy 已提交
4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772
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;

4773
	WARN_ON_ONCE(!len);
B
Benny Halevy 已提交
4774 4775 4776 4777
	end = start + len;
	return end > start ? end - 1: NFS4_MAX_UINT64;
}

L
Linus Torvalds 已提交
4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794
/*
 * 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;
}

4795 4796
/* Hack!: For now, we're defining this just so we can use a pointer to it
 * as a unique cookie to identify our (NFSv4's) posix locks. */
4797
static const struct lock_manager_operations nfsd_posix_mng_ops  = {
4798
};
L
Linus Torvalds 已提交
4799 4800 4801 4802

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

4805
	if (fl->fl_lmops == &nfsd_posix_mng_ops) {
4806 4807 4808
		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);
4809 4810 4811
		if (!deny->ld_owner.data)
			/* We just don't care that much */
			goto nevermind;
4812 4813
		deny->ld_owner.len = lo->lo_owner.so_owner.len;
		deny->ld_clientid = lo->lo_owner.so_client->cl_clientid;
4814
	} else {
4815 4816 4817
nevermind:
		deny->ld_owner.len = 0;
		deny->ld_owner.data = NULL;
4818 4819
		deny->ld_clientid.cl_boot = 0;
		deny->ld_clientid.cl_id = 0;
L
Linus Torvalds 已提交
4820 4821
	}
	deny->ld_start = fl->fl_start;
B
Benny Halevy 已提交
4822 4823
	deny->ld_length = NFS4_MAX_UINT64;
	if (fl->fl_end != NFS4_MAX_UINT64)
L
Linus Torvalds 已提交
4824 4825 4826 4827 4828 4829
		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;
}

4830
static struct nfs4_lockowner *
4831
find_lockowner_str_locked(clientid_t *clid, struct xdr_netobj *owner,
4832
		struct nfs4_client *clp)
L
Linus Torvalds 已提交
4833
{
4834
	unsigned int strhashval = ownerstr_hashval(owner);
4835
	struct nfs4_stateowner *so;
L
Linus Torvalds 已提交
4836

4837 4838
	list_for_each_entry(so, &clp->cl_ownerstr_hashtbl[strhashval],
			    so_strhash) {
4839 4840
		if (so->so_is_open_owner)
			continue;
4841
		if (!same_owner_str(so, owner))
4842
			continue;
4843
		atomic_inc(&so->so_count);
4844
		return lockowner(so);
L
Linus Torvalds 已提交
4845 4846 4847 4848
	}
	return NULL;
}

4849 4850
static struct nfs4_lockowner *
find_lockowner_str(clientid_t *clid, struct xdr_netobj *owner,
4851
		struct nfs4_client *clp)
4852 4853 4854
{
	struct nfs4_lockowner *lo;

4855 4856 4857
	spin_lock(&clp->cl_lock);
	lo = find_lockowner_str_locked(clid, owner, clp);
	spin_unlock(&clp->cl_lock);
4858 4859 4860
	return lo;
}

4861 4862
static void nfs4_unhash_lockowner(struct nfs4_stateowner *sop)
{
4863
	unhash_lockowner_locked(lockowner(sop));
4864 4865
}

4866 4867 4868 4869 4870 4871 4872 4873
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 = {
4874 4875
	.so_unhash =	nfs4_unhash_lockowner,
	.so_free =	nfs4_free_lockowner,
4876 4877
};

L
Linus Torvalds 已提交
4878 4879 4880
/*
 * Alloc a lock owner structure.
 * Called in nfsd4_lock - therefore, OPEN and OPEN_CONFIRM (if needed) has 
L
Lucas De Marchi 已提交
4881
 * occurred. 
L
Linus Torvalds 已提交
4882
 *
4883
 * strhashval = ownerstr_hashval
L
Linus Torvalds 已提交
4884
 */
4885
static struct nfs4_lockowner *
4886 4887 4888 4889 4890
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 已提交
4891

4892 4893
	lo = alloc_stateowner(lockowner_slab, &lock->lk_new_owner, clp);
	if (!lo)
L
Linus Torvalds 已提交
4894
		return NULL;
4895 4896
	INIT_LIST_HEAD(&lo->lo_owner.so_stateids);
	lo->lo_owner.so_is_open_owner = 0;
4897
	lo->lo_owner.so_seqid = lock->lk_new_lock_seqid;
4898
	lo->lo_owner.so_ops = &lockowner_ops;
4899
	spin_lock(&clp->cl_lock);
4900
	ret = find_lockowner_str_locked(&clp->cl_clientid,
4901
			&lock->lk_new_owner, clp);
4902 4903
	if (ret == NULL) {
		list_add(&lo->lo_owner.so_strhash,
4904
			 &clp->cl_ownerstr_hashtbl[strhashval]);
4905 4906 4907
		ret = lo;
	} else
		nfs4_free_lockowner(&lo->lo_owner);
4908
	spin_unlock(&clp->cl_lock);
4909
	return lo;
L
Linus Torvalds 已提交
4910 4911
}

4912 4913 4914 4915
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 已提交
4916
{
4917
	struct nfs4_client *clp = lo->lo_owner.so_client;
L
Linus Torvalds 已提交
4918

4919 4920
	lockdep_assert_held(&clp->cl_lock);

4921
	atomic_inc(&stp->st_stid.sc_count);
J
J. Bruce Fields 已提交
4922
	stp->st_stid.sc_type = NFS4_LOCK_STID;
4923
	stp->st_stateowner = &lo->lo_owner;
4924
	atomic_inc(&lo->lo_owner.so_count);
4925
	get_nfs4_file(fp);
4926
	stp->st_stid.sc_file = fp;
4927
	stp->st_stid.sc_free = nfs4_free_lock_stateid;
J
J. Bruce Fields 已提交
4928
	stp->st_access_bmap = 0;
L
Linus Torvalds 已提交
4929
	stp->st_deny_bmap = open_stp->st_deny_bmap;
4930
	stp->st_openstp = open_stp;
4931
	list_add(&stp->st_locks, &open_stp->st_locks);
4932
	list_add(&stp->st_perstateowner, &lo->lo_owner.so_stateids);
4933 4934 4935
	spin_lock(&fp->fi_lock);
	list_add(&stp->st_perfile, &fp->fi_stateids);
	spin_unlock(&fp->fi_lock);
L
Linus Torvalds 已提交
4936 4937
}

4938 4939 4940 4941
static struct nfs4_ol_stateid *
find_lock_stateid(struct nfs4_lockowner *lo, struct nfs4_file *fp)
{
	struct nfs4_ol_stateid *lst;
4942 4943 4944
	struct nfs4_client *clp = lo->lo_owner.so_client;

	lockdep_assert_held(&clp->cl_lock);
4945 4946

	list_for_each_entry(lst, &lo->lo_owner.so_stateids, st_perstateowner) {
4947 4948
		if (lst->st_stid.sc_file == fp) {
			atomic_inc(&lst->st_stid.sc_count);
4949
			return lst;
4950
		}
4951 4952 4953 4954
	}
	return NULL;
}

4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986
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;
}
4987

4988
static int
L
Linus Torvalds 已提交
4989 4990
check_lock_length(u64 offset, u64 length)
{
B
Benny Halevy 已提交
4991
	return ((length == 0)  || ((length != NFS4_MAX_UINT64) &&
L
Linus Torvalds 已提交
4992 4993 4994
	     LOFF_OVERFLOW(offset, length)));
}

4995
static void get_lock_access(struct nfs4_ol_stateid *lock_stp, u32 access)
J
J. Bruce Fields 已提交
4996
{
4997
	struct nfs4_file *fp = lock_stp->st_stid.sc_file;
J
J. Bruce Fields 已提交
4998

4999 5000
	lockdep_assert_held(&fp->fi_lock);

5001
	if (test_access(access, lock_stp))
J
J. Bruce Fields 已提交
5002
		return;
5003
	__nfs4_file_get_access(fp, access);
5004
	set_access(access, lock_stp);
J
J. Bruce Fields 已提交
5005 5006
}

5007 5008 5009 5010 5011
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)
5012
{
5013
	__be32 status;
5014
	struct nfs4_file *fi = ost->st_stid.sc_file;
5015 5016
	struct nfs4_openowner *oo = openowner(ost->st_stateowner);
	struct nfs4_client *cl = oo->oo_owner.so_client;
5017
	struct inode *inode = cstate->current_fh.fh_dentry->d_inode;
5018 5019 5020
	struct nfs4_lockowner *lo;
	unsigned int strhashval;

5021
	lo = find_lockowner_str(&cl->cl_clientid, &lock->v.new.owner, cl);
5022
	if (!lo) {
5023
		strhashval = ownerstr_hashval(&lock->v.new.owner);
5024 5025 5026 5027 5028
		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 */
5029
		status = nfserr_bad_seqid;
5030 5031
		if (!cstate->minorversion &&
		    lock->lk_new_lock_seqid != lo->lo_owner.so_seqid)
5032
			goto out;
5033
	}
5034

5035
	*lst = find_or_create_lock_stateid(lo, fi, inode, ost, new);
5036
	if (*lst == NULL) {
5037 5038
		status = nfserr_jukebox;
		goto out;
5039
	}
5040 5041 5042 5043
	status = nfs_ok;
out:
	nfs4_put_stateowner(&lo->lo_owner);
	return status;
5044 5045
}

L
Linus Torvalds 已提交
5046 5047 5048
/*
 *  LOCK operation 
 */
5049
__be32
5050
nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
5051
	   struct nfsd4_lock *lock)
L
Linus Torvalds 已提交
5052
{
5053 5054
	struct nfs4_openowner *open_sop = NULL;
	struct nfs4_lockowner *lock_sop = NULL;
5055
	struct nfs4_ol_stateid *lock_stp = NULL;
5056
	struct nfs4_ol_stateid *open_stp = NULL;
5057
	struct nfs4_file *fp;
5058
	struct file *filp = NULL;
5059 5060
	struct file_lock *file_lock = NULL;
	struct file_lock *conflock = NULL;
5061
	__be32 status = 0;
5062
	int lkflg;
5063
	int err;
5064
	bool new = false;
5065 5066
	struct net *net = SVC_NET(rqstp);
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
L
Linus Torvalds 已提交
5067 5068 5069 5070 5071 5072 5073 5074

	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;

5075
	if ((status = fh_verify(rqstp, &cstate->current_fh,
M
Miklos Szeredi 已提交
5076
				S_IFREG, NFSD_MAY_LOCK))) {
A
Andy Adamson 已提交
5077 5078 5079 5080
		dprintk("NFSD: nfsd4_lock: permission denied!\n");
		return status;
	}

L
Linus Torvalds 已提交
5081 5082 5083
	nfs4_lock_state();

	if (lock->lk_is_new) {
5084 5085 5086 5087 5088 5089
		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 已提交
5090
		status = nfserr_stale_clientid;
5091
		if (STALE_CLIENTID(&lock->lk_new_clientid, nn))
L
Linus Torvalds 已提交
5092 5093 5094
			goto out;

		/* validate and update open stateid and open seqid */
5095
		status = nfs4_preprocess_confirmed_seqid_op(cstate,
L
Linus Torvalds 已提交
5096 5097
				        lock->lk_new_open_seqid,
		                        &lock->lk_new_open_stateid,
5098
					&open_stp, nn);
5099
		if (status)
L
Linus Torvalds 已提交
5100
			goto out;
5101
		open_sop = openowner(open_stp->st_stateowner);
5102
		status = nfserr_bad_stateid;
5103
		if (!same_clid(&open_sop->oo_owner.so_client->cl_clientid,
5104 5105
						&lock->v.new.clientid))
			goto out;
5106
		status = lookup_or_create_lock_state(cstate, open_stp, lock,
5107
							&lock_stp, &new);
5108
	} else {
5109
		status = nfs4_preprocess_seqid_op(cstate,
5110 5111
				       lock->lk_old_lock_seqid,
				       &lock->lk_old_lock_stateid,
5112
				       NFS4_LOCK_STID, &lock_stp, nn);
5113
	}
J
J. Bruce Fields 已提交
5114 5115
	if (status)
		goto out;
5116
	lock_sop = lockowner(lock_stp->st_stateowner);
L
Linus Torvalds 已提交
5117

5118 5119 5120 5121 5122
	lkflg = setlkflg(lock->lk_type);
	status = nfs4_check_openmode(lock_stp, lkflg);
	if (status)
		goto out;

5123
	status = nfserr_grace;
5124
	if (locks_in_grace(net) && !lock->lk_reclaim)
5125 5126
		goto out;
	status = nfserr_no_grace;
5127
	if (!locks_in_grace(net) && lock->lk_reclaim)
5128 5129
		goto out;

5130 5131 5132 5133 5134 5135 5136
	file_lock = locks_alloc_lock();
	if (!file_lock) {
		dprintk("NFSD: %s: unable to allocate lock!\n", __func__);
		status = nfserr_jukebox;
		goto out;
	}

5137
	fp = lock_stp->st_stid.sc_file;
5138
	locks_init_lock(file_lock);
L
Linus Torvalds 已提交
5139 5140 5141
	switch (lock->lk_type) {
		case NFS4_READ_LT:
		case NFS4_READW_LT:
5142 5143
			spin_lock(&fp->fi_lock);
			filp = find_readable_file_locked(fp);
J
J. Bruce Fields 已提交
5144 5145
			if (filp)
				get_lock_access(lock_stp, NFS4_SHARE_ACCESS_READ);
5146
			spin_unlock(&fp->fi_lock);
5147
			file_lock->fl_type = F_RDLCK;
5148
			break;
L
Linus Torvalds 已提交
5149 5150
		case NFS4_WRITE_LT:
		case NFS4_WRITEW_LT:
5151 5152
			spin_lock(&fp->fi_lock);
			filp = find_writeable_file_locked(fp);
J
J. Bruce Fields 已提交
5153 5154
			if (filp)
				get_lock_access(lock_stp, NFS4_SHARE_ACCESS_WRITE);
5155
			spin_unlock(&fp->fi_lock);
5156
			file_lock->fl_type = F_WRLCK;
5157
			break;
L
Linus Torvalds 已提交
5158 5159 5160 5161
		default:
			status = nfserr_inval;
		goto out;
	}
5162 5163 5164 5165
	if (!filp) {
		status = nfserr_openmode;
		goto out;
	}
5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180
	file_lock->fl_owner = (fl_owner_t)lock_sop;
	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 已提交
5181

5182
	err = vfs_lock_file(filp, F_SETLK, file_lock, conflock);
5183
	switch (-err) {
L
Linus Torvalds 已提交
5184
	case 0: /* success! */
5185 5186
		update_stateid(&lock_stp->st_stid.sc_stateid);
		memcpy(&lock->lk_resp_stateid, &lock_stp->st_stid.sc_stateid, 
L
Linus Torvalds 已提交
5187
				sizeof(stateid_t));
5188
		status = 0;
5189 5190 5191 5192
		break;
	case (EAGAIN):		/* conflock holds conflicting lock */
		status = nfserr_denied;
		dprintk("NFSD: nfsd4_lock: conflicting lock found!\n");
5193
		nfs4_set_lock_denied(conflock, &lock->lk_denied);
5194
		break;
L
Linus Torvalds 已提交
5195 5196
	case (EDEADLK):
		status = nfserr_deadlock;
5197
		break;
5198
	default:
5199
		dprintk("NFSD: nfsd4_lock: vfs_lock_file() failed! status %d\n",err);
5200
		status = nfserrno(err);
5201
		break;
L
Linus Torvalds 已提交
5202 5203
	}
out:
5204 5205
	if (filp)
		fput(filp);
5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219
	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);

5220
		nfs4_put_stid(&lock_stp->st_stid);
5221
	}
5222 5223
	if (open_stp)
		nfs4_put_stid(&open_stp->st_stid);
5224
	nfsd4_bump_seqid(cstate, status);
5225
	nfs4_unlock_state();
5226 5227 5228 5229
	if (file_lock)
		locks_free_lock(file_lock);
	if (conflock)
		locks_free_lock(conflock);
L
Linus Torvalds 已提交
5230 5231 5232
	return status;
}

5233 5234 5235 5236 5237 5238
/*
 * 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.)
 */
5239
static __be32 nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file_lock *lock)
5240 5241
{
	struct file *file;
5242 5243 5244 5245 5246
	__be32 err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file);
	if (!err) {
		err = nfserrno(vfs_test_lock(file, lock));
		nfsd_close(file);
	}
5247 5248 5249
	return err;
}

L
Linus Torvalds 已提交
5250 5251 5252
/*
 * LOCKT operation
 */
5253
__be32
5254 5255
nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	    struct nfsd4_lockt *lockt)
L
Linus Torvalds 已提交
5256
{
5257
	struct file_lock *file_lock = NULL;
5258
	struct nfs4_lockowner *lo = NULL;
5259
	__be32 status;
5260
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
L
Linus Torvalds 已提交
5261

5262
	if (locks_in_grace(SVC_NET(rqstp)))
L
Linus Torvalds 已提交
5263 5264 5265 5266 5267 5268 5269
		return nfserr_grace;

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

	nfs4_lock_state();

5270
	if (!nfsd4_has_session(cstate)) {
5271
		status = lookup_clientid(&lockt->lt_clientid, cstate, nn);
5272 5273 5274
		if (status)
			goto out;
	}
L
Linus Torvalds 已提交
5275

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

5279 5280 5281 5282 5283 5284 5285
	file_lock = locks_alloc_lock();
	if (!file_lock) {
		dprintk("NFSD: %s: unable to allocate lock!\n", __func__);
		status = nfserr_jukebox;
		goto out;
	}
	locks_init_lock(file_lock);
L
Linus Torvalds 已提交
5286 5287 5288
	switch (lockt->lt_type) {
		case NFS4_READ_LT:
		case NFS4_READW_LT:
5289
			file_lock->fl_type = F_RDLCK;
L
Linus Torvalds 已提交
5290 5291 5292
		break;
		case NFS4_WRITE_LT:
		case NFS4_WRITEW_LT:
5293
			file_lock->fl_type = F_WRLCK;
L
Linus Torvalds 已提交
5294 5295
		break;
		default:
5296
			dprintk("NFSD: nfs4_lockt: bad lock type!\n");
L
Linus Torvalds 已提交
5297 5298 5299 5300
			status = nfserr_inval;
		goto out;
	}

5301 5302
	lo = find_lockowner_str(&lockt->lt_clientid, &lockt->lt_owner,
				cstate->clp);
5303
	if (lo)
5304 5305 5306
		file_lock->fl_owner = (fl_owner_t)lo;
	file_lock->fl_pid = current->tgid;
	file_lock->fl_flags = FL_POSIX;
L
Linus Torvalds 已提交
5307

5308 5309
	file_lock->fl_start = lockt->lt_offset;
	file_lock->fl_end = last_byte_offset(lockt->lt_offset, lockt->lt_length);
L
Linus Torvalds 已提交
5310

5311
	nfs4_transform_lock_offset(file_lock);
L
Linus Torvalds 已提交
5312

5313
	status = nfsd_test_lock(rqstp, &cstate->current_fh, file_lock);
5314
	if (status)
5315
		goto out;
5316

5317
	if (file_lock->fl_type != F_UNLCK) {
L
Linus Torvalds 已提交
5318
		status = nfserr_denied;
5319
		nfs4_set_lock_denied(file_lock, &lockt->lt_denied);
L
Linus Torvalds 已提交
5320 5321
	}
out:
5322 5323
	if (lo)
		nfs4_put_stateowner(&lo->lo_owner);
L
Linus Torvalds 已提交
5324
	nfs4_unlock_state();
5325 5326
	if (file_lock)
		locks_free_lock(file_lock);
L
Linus Torvalds 已提交
5327 5328 5329
	return status;
}

5330
__be32
5331
nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
5332
	    struct nfsd4_locku *locku)
L
Linus Torvalds 已提交
5333
{
5334
	struct nfs4_ol_stateid *stp;
L
Linus Torvalds 已提交
5335
	struct file *filp = NULL;
5336
	struct file_lock *file_lock = NULL;
5337
	__be32 status;
5338
	int err;
5339 5340
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);

L
Linus Torvalds 已提交
5341 5342 5343 5344 5345 5346 5347 5348 5349
	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;

	nfs4_lock_state();
									        
5350
	status = nfs4_preprocess_seqid_op(cstate, locku->lu_seqid,
5351 5352
					&locku->lu_stateid, NFS4_LOCK_STID,
					&stp, nn);
5353
	if (status)
L
Linus Torvalds 已提交
5354
		goto out;
5355
	filp = find_any_file(stp->st_stid.sc_file);
5356 5357
	if (!filp) {
		status = nfserr_lock_range;
5358
		goto put_stateid;
5359
	}
5360 5361 5362 5363
	file_lock = locks_alloc_lock();
	if (!file_lock) {
		dprintk("NFSD: %s: unable to allocate lock!\n", __func__);
		status = nfserr_jukebox;
5364
		goto fput;
5365 5366 5367
	}
	locks_init_lock(file_lock);
	file_lock->fl_type = F_UNLCK;
5368
	file_lock->fl_owner = (fl_owner_t)lockowner(stp->st_stateowner);
5369 5370 5371 5372 5373 5374 5375 5376 5377
	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 已提交
5378

5379
	err = vfs_lock_file(filp, F_SETLK, file_lock, NULL);
5380
	if (err) {
5381
		dprintk("NFSD: nfs4_locku: vfs_lock_file failed!\n");
L
Linus Torvalds 已提交
5382 5383
		goto out_nfserr;
	}
5384 5385
	update_stateid(&stp->st_stid.sc_stateid);
	memcpy(&locku->lu_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
5386 5387
fput:
	fput(filp);
5388 5389
put_stateid:
	nfs4_put_stid(&stp->st_stid);
L
Linus Torvalds 已提交
5390
out:
5391
	nfsd4_bump_seqid(cstate, status);
5392
	nfs4_unlock_state();
5393 5394
	if (file_lock)
		locks_free_lock(file_lock);
L
Linus Torvalds 已提交
5395 5396 5397
	return status;

out_nfserr:
5398
	status = nfserrno(err);
5399
	goto fput;
L
Linus Torvalds 已提交
5400 5401 5402 5403
}

/*
 * returns
5404 5405
 * 	true:  locks held by lockowner
 * 	false: no locks held by lockowner
L
Linus Torvalds 已提交
5406
 */
5407 5408
static bool
check_for_locks(struct nfs4_file *fp, struct nfs4_lockowner *lowner)
L
Linus Torvalds 已提交
5409 5410
{
	struct file_lock **flpp;
5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421
	int status = false;
	struct file *filp = find_any_file(fp);
	struct inode *inode;

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

	inode = file_inode(filp);
L
Linus Torvalds 已提交
5422

5423
	spin_lock(&inode->i_lock);
L
Linus Torvalds 已提交
5424
	for (flpp = &inode->i_flock; *flpp != NULL; flpp = &(*flpp)->fl_next) {
5425
		if ((*flpp)->fl_owner == (fl_owner_t)lowner) {
5426 5427
			status = true;
			break;
5428
		}
L
Linus Torvalds 已提交
5429
	}
5430
	spin_unlock(&inode->i_lock);
5431
	fput(filp);
L
Linus Torvalds 已提交
5432 5433 5434
	return status;
}

5435
__be32
5436 5437 5438
nfsd4_release_lockowner(struct svc_rqst *rqstp,
			struct nfsd4_compound_state *cstate,
			struct nfsd4_release_lockowner *rlockowner)
L
Linus Torvalds 已提交
5439 5440
{
	clientid_t *clid = &rlockowner->rl_clientid;
5441 5442
	struct nfs4_stateowner *sop;
	struct nfs4_lockowner *lo = NULL;
5443
	struct nfs4_ol_stateid *stp;
L
Linus Torvalds 已提交
5444
	struct xdr_netobj *owner = &rlockowner->rl_owner;
5445
	unsigned int hashval = ownerstr_hashval(owner);
5446
	__be32 status;
5447
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
5448
	struct nfs4_client *clp;
L
Linus Torvalds 已提交
5449 5450 5451 5452 5453 5454

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

	nfs4_lock_state();

5455
	status = lookup_clientid(clid, cstate, nn);
5456 5457 5458
	if (status)
		goto out;

5459
	clp = cstate->clp;
5460
	/* Find the matching lock stateowner */
5461
	spin_lock(&clp->cl_lock);
5462
	list_for_each_entry(sop, &clp->cl_ownerstr_hashtbl[hashval],
5463
			    so_strhash) {
5464

5465 5466
		if (sop->so_is_open_owner || !same_owner_str(sop, owner))
			continue;
5467

5468 5469 5470 5471 5472 5473 5474 5475
		/* 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);
				goto out;
			}
5476
		}
5477 5478 5479

		atomic_inc(&sop->so_count);
		break;
L
Linus Torvalds 已提交
5480
	}
5481
	spin_unlock(&clp->cl_lock);
5482 5483
	if (lo)
		release_lockowner(lo);
L
Linus Torvalds 已提交
5484 5485 5486 5487 5488 5489
out:
	nfs4_unlock_state();
	return status;
}

static inline struct nfs4_client_reclaim *
N
NeilBrown 已提交
5490
alloc_reclaim(void)
L
Linus Torvalds 已提交
5491
{
N
NeilBrown 已提交
5492
	return kmalloc(sizeof(struct nfs4_client_reclaim), GFP_KERNEL);
L
Linus Torvalds 已提交
5493 5494
}

5495
bool
5496
nfs4_has_reclaimed_state(const char *name, struct nfsd_net *nn)
5497
{
5498
	struct nfs4_client_reclaim *crp;
5499

5500
	crp = nfsd4_find_reclaim_client(name, nn);
5501
	return (crp && crp->cr_clp);
5502 5503
}

L
Linus Torvalds 已提交
5504 5505 5506
/*
 * failure => all reset bets are off, nfserr_no_grace...
 */
5507
struct nfs4_client_reclaim *
5508
nfs4_client_to_reclaim(const char *name, struct nfsd_net *nn)
L
Linus Torvalds 已提交
5509 5510
{
	unsigned int strhashval;
5511
	struct nfs4_client_reclaim *crp;
L
Linus Torvalds 已提交
5512

N
NeilBrown 已提交
5513 5514
	dprintk("NFSD nfs4_client_to_reclaim NAME: %.*s\n", HEXDIR_LEN, name);
	crp = alloc_reclaim();
5515 5516 5517
	if (crp) {
		strhashval = clientstr_hashval(name);
		INIT_LIST_HEAD(&crp->cr_strhash);
5518
		list_add(&crp->cr_strhash, &nn->reclaim_str_hashtbl[strhashval]);
5519
		memcpy(crp->cr_recdir, name, HEXDIR_LEN);
5520
		crp->cr_clp = NULL;
5521
		nn->reclaim_str_hashtbl_size++;
5522 5523
	}
	return crp;
L
Linus Torvalds 已提交
5524 5525
}

5526
void
5527
nfs4_remove_reclaim_record(struct nfs4_client_reclaim *crp, struct nfsd_net *nn)
5528 5529 5530
{
	list_del(&crp->cr_strhash);
	kfree(crp);
5531
	nn->reclaim_str_hashtbl_size--;
5532 5533
}

5534
void
5535
nfs4_release_reclaim(struct nfsd_net *nn)
L
Linus Torvalds 已提交
5536 5537 5538 5539 5540
{
	struct nfs4_client_reclaim *crp = NULL;
	int i;

	for (i = 0; i < CLIENT_HASH_SIZE; i++) {
5541 5542
		while (!list_empty(&nn->reclaim_str_hashtbl[i])) {
			crp = list_entry(nn->reclaim_str_hashtbl[i].next,
L
Linus Torvalds 已提交
5543
			                struct nfs4_client_reclaim, cr_strhash);
5544
			nfs4_remove_reclaim_record(crp, nn);
L
Linus Torvalds 已提交
5545 5546
		}
	}
5547
	WARN_ON_ONCE(nn->reclaim_str_hashtbl_size);
L
Linus Torvalds 已提交
5548 5549 5550 5551
}

/*
 * called from OPEN, CLAIM_PREVIOUS with a new clientid. */
5552
struct nfs4_client_reclaim *
5553
nfsd4_find_reclaim_client(const char *recdir, struct nfsd_net *nn)
L
Linus Torvalds 已提交
5554 5555 5556 5557
{
	unsigned int strhashval;
	struct nfs4_client_reclaim *crp = NULL;

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

5560
	strhashval = clientstr_hashval(recdir);
5561
	list_for_each_entry(crp, &nn->reclaim_str_hashtbl[strhashval], cr_strhash) {
5562
		if (same_name(crp->cr_recdir, recdir)) {
L
Linus Torvalds 已提交
5563 5564 5565 5566 5567 5568 5569 5570 5571
			return crp;
		}
	}
	return NULL;
}

/*
* Called from OPEN. Look for clientid in reclaim list.
*/
5572
__be32
5573 5574 5575
nfs4_check_open_reclaim(clientid_t *clid,
		struct nfsd4_compound_state *cstate,
		struct nfsd_net *nn)
L
Linus Torvalds 已提交
5576
{
5577
	__be32 status;
5578 5579

	/* find clientid in conf_id_hashtbl */
5580 5581
	status = lookup_clientid(clid, cstate, nn);
	if (status)
5582 5583
		return nfserr_reclaim_bad;

5584 5585 5586 5587
	if (nfsd4_client_record_check(cstate->clp))
		return nfserr_reclaim_bad;

	return nfs_ok;
L
Linus Torvalds 已提交
5588 5589
}

B
Bryan Schumaker 已提交
5590 5591
#ifdef CONFIG_NFSD_FAULT_INJECTION

5592 5593
u64 nfsd_forget_client(struct nfs4_client *clp, u64 max)
{
5594 5595
	if (mark_client_expired(clp))
		return 0;
5596 5597 5598 5599
	expire_client(clp);
	return 1;
}

5600 5601 5602
u64 nfsd_print_client(struct nfs4_client *clp, u64 num)
{
	char buf[INET6_ADDRSTRLEN];
5603
	rpc_ntop((struct sockaddr *)&clp->cl_addr, buf, sizeof(buf));
5604 5605 5606 5607 5608 5609 5610 5611
	printk(KERN_INFO "NFS Client: %s\n", buf);
	return 1;
}

static void nfsd_print_count(struct nfs4_client *clp, unsigned int count,
			     const char *type)
{
	char buf[INET6_ADDRSTRLEN];
5612
	rpc_ntop((struct sockaddr *)&clp->cl_addr, buf, sizeof(buf));
5613 5614 5615
	printk(KERN_INFO "NFS Client: %s has %u %s\n", buf, count, type);
}

5616 5617
static u64 nfsd_foreach_client_lock(struct nfs4_client *clp, u64 max,
				    void (*func)(struct nfs4_ol_stateid *))
B
Bryan Schumaker 已提交
5618 5619 5620
{
	struct nfs4_openowner *oop;
	struct nfs4_ol_stateid *stp, *st_next;
5621
	struct nfs4_ol_stateid *lst, *lst_next;
B
Bryan Schumaker 已提交
5622 5623 5624
	u64 count = 0;

	list_for_each_entry(oop, &clp->cl_openowners, oo_perclient) {
5625 5626 5627 5628
		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) {
B
Bryan Schumaker 已提交
5629
				if (func)
5630
					func(lst);
B
Bryan Schumaker 已提交
5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641
				if (++count == max)
					return count;
			}
		}
	}

	return count;
}

u64 nfsd_forget_client_locks(struct nfs4_client *clp, u64 max)
{
5642
	return nfsd_foreach_client_lock(clp, max, release_lock_stateid);
B
Bryan Schumaker 已提交
5643 5644
}

5645 5646 5647 5648 5649 5650 5651
u64 nfsd_print_client_locks(struct nfs4_client *clp, u64 max)
{
	u64 count = nfsd_foreach_client_lock(clp, max, NULL);
	nfsd_print_count(clp, count, "locked files");
	return count;
}

5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671
static u64 nfsd_foreach_client_open(struct nfs4_client *clp, u64 max, void (*func)(struct nfs4_openowner *))
{
	struct nfs4_openowner *oop, *next;
	u64 count = 0;

	list_for_each_entry_safe(oop, next, &clp->cl_openowners, oo_perclient) {
		if (func)
			func(oop);
		if (++count == max)
			break;
	}

	return count;
}

u64 nfsd_forget_client_openowners(struct nfs4_client *clp, u64 max)
{
	return nfsd_foreach_client_open(clp, max, release_openowner);
}

5672 5673 5674 5675 5676 5677 5678
u64 nfsd_print_client_openowners(struct nfs4_client *clp, u64 max)
{
	u64 count = nfsd_foreach_client_open(clp, max, NULL);
	nfsd_print_count(clp, count, "open files");
	return count;
}

5679 5680 5681 5682 5683 5684
static u64 nfsd_find_all_delegations(struct nfs4_client *clp, u64 max,
				     struct list_head *victims)
{
	struct nfs4_delegation *dp, *next;
	u64 count = 0;

5685
	lockdep_assert_held(&state_lock);
5686
	list_for_each_entry_safe(dp, next, &clp->cl_delegations, dl_perclnt) {
5687 5688 5689 5690 5691 5692 5693 5694 5695 5696
		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;

5697 5698
			unhash_delegation_locked(dp);
			list_add(&dp->dl_recall_lru, victims);
5699
		}
5700 5701 5702 5703 5704 5705 5706 5707 5708 5709 5710 5711
		if (++count == max)
			break;
	}
	return count;
}

u64 nfsd_forget_client_delegations(struct nfs4_client *clp, u64 max)
{
	struct nfs4_delegation *dp, *next;
	LIST_HEAD(victims);
	u64 count;

5712
	spin_lock(&state_lock);
5713
	count = nfsd_find_all_delegations(clp, max, &victims);
5714
	spin_unlock(&state_lock);
5715

5716 5717
	list_for_each_entry_safe(dp, next, &victims, dl_recall_lru) {
		list_del_init(&dp->dl_recall_lru);
5718
		revoke_delegation(dp);
5719
	}
5720 5721 5722 5723 5724 5725

	return count;
}

u64 nfsd_recall_client_delegations(struct nfs4_client *clp, u64 max)
{
5726
	struct nfs4_delegation *dp;
5727 5728 5729
	LIST_HEAD(victims);
	u64 count;

5730
	spin_lock(&state_lock);
5731
	count = nfsd_find_all_delegations(clp, max, &victims);
5732 5733 5734 5735 5736
	while (!list_empty(&victims)) {
		dp = list_first_entry(&victims, struct nfs4_delegation,
					dl_recall_lru);
		list_del_init(&dp->dl_recall_lru);
		dp->dl_time = 0;
5737
		nfsd_break_one_deleg(dp);
5738
	}
5739
	spin_unlock(&state_lock);
5740 5741 5742 5743

	return count;
}

5744 5745 5746 5747
u64 nfsd_print_client_delegations(struct nfs4_client *clp, u64 max)
{
	u64 count = 0;

5748
	spin_lock(&state_lock);
5749
	count = nfsd_find_all_delegations(clp, max, NULL);
5750
	spin_unlock(&state_lock);
5751 5752 5753 5754 5755

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

5756
u64 nfsd_for_n_state(u64 max, u64 (*func)(struct nfs4_client *, u64))
B
Bryan Schumaker 已提交
5757 5758
{
	struct nfs4_client *clp, *next;
5759
	u64 count = 0;
5760
	struct nfsd_net *nn = net_generic(current->nsproxy->net_ns, nfsd_net_id);
B
Bryan Schumaker 已提交
5761

5762 5763 5764
	if (!nfsd_netns_ready(nn))
		return 0;

5765
	list_for_each_entry_safe(clp, next, &nn->client_lru, cl_lru) {
5766 5767
		count += func(clp, max - count);
		if ((max != 0) && (count >= max))
B
Bryan Schumaker 已提交
5768 5769 5770
			break;
	}

5771 5772 5773
	return count;
}

5774 5775 5776 5777 5778 5779 5780 5781 5782 5783 5784 5785 5786 5787 5788
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;
}

B
Bryan Schumaker 已提交
5789 5790
#endif /* CONFIG_NFSD_FAULT_INJECTION */

5791 5792 5793 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811
/*
 * 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);
}

5812
static int nfs4_state_create_net(struct net *net)
5813 5814 5815 5816 5817 5818 5819
{
	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)
5820
		goto err;
5821 5822 5823 5824
	nn->unconf_id_hashtbl = kmalloc(sizeof(struct list_head) *
			CLIENT_HASH_SIZE, GFP_KERNEL);
	if (!nn->unconf_id_hashtbl)
		goto err_unconf_id;
5825 5826 5827 5828
	nn->sessionid_hashtbl = kmalloc(sizeof(struct list_head) *
			SESSION_HASH_SIZE, GFP_KERNEL);
	if (!nn->sessionid_hashtbl)
		goto err_sessionid;
5829

5830
	for (i = 0; i < CLIENT_HASH_SIZE; i++) {
5831
		INIT_LIST_HEAD(&nn->conf_id_hashtbl[i]);
5832
		INIT_LIST_HEAD(&nn->unconf_id_hashtbl[i]);
5833
	}
5834 5835
	for (i = 0; i < SESSION_HASH_SIZE; i++)
		INIT_LIST_HEAD(&nn->sessionid_hashtbl[i]);
5836
	nn->conf_name_tree = RB_ROOT;
5837
	nn->unconf_name_tree = RB_ROOT;
5838
	INIT_LIST_HEAD(&nn->client_lru);
5839
	INIT_LIST_HEAD(&nn->close_lru);
5840
	INIT_LIST_HEAD(&nn->del_recall_lru);
5841
	spin_lock_init(&nn->client_lock);
5842

5843
	INIT_DELAYED_WORK(&nn->laundromat_work, laundromat_main);
5844
	get_net(net);
5845

5846
	return 0;
5847

5848
err_sessionid:
5849
	kfree(nn->unconf_id_hashtbl);
5850 5851
err_unconf_id:
	kfree(nn->conf_id_hashtbl);
5852 5853
err:
	return -ENOMEM;
5854 5855 5856
}

static void
5857
nfs4_state_destroy_net(struct net *net)
5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868
{
	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);
		}
	}
5869

5870 5871 5872 5873 5874
	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);
		}
5875 5876
	}

5877
	kfree(nn->sessionid_hashtbl);
5878
	kfree(nn->unconf_id_hashtbl);
5879
	kfree(nn->conf_id_hashtbl);
5880
	put_net(net);
5881 5882
}

5883
int
5884
nfs4_state_start_net(struct net *net)
5885
{
5886
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
5887 5888
	int ret;

5889
	ret = nfs4_state_create_net(net);
5890 5891
	if (ret)
		return ret;
5892
	nfsd4_client_tracking_init(net);
5893
	nn->boot_time = get_seconds();
5894
	locks_start_grace(net, &nn->nfsd4_manager);
5895
	nn->grace_ended = false;
5896
	printk(KERN_INFO "NFSD: starting %ld-second grace period (net %p)\n",
5897 5898
	       nn->nfsd4_grace, net);
	queue_delayed_work(laundry_wq, &nn->laundromat_work, nn->nfsd4_grace * HZ);
5899 5900 5901 5902 5903 5904 5905 5906 5907 5908
	return 0;
}

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

int
nfs4_state_start(void)
{
	int ret;

5909
	ret = set_callback_cred();
5910 5911
	if (ret)
		return -ENOMEM;
5912
	laundry_wq = create_singlethread_workqueue("nfsd4");
5913 5914 5915 5916
	if (laundry_wq == NULL) {
		ret = -ENOMEM;
		goto out_recovery;
	}
5917 5918 5919
	ret = nfsd4_create_callback_queue();
	if (ret)
		goto out_free_laundry;
5920

5921
	set_max_delegations();
5922

5923
	return 0;
5924

5925 5926
out_free_laundry:
	destroy_workqueue(laundry_wq);
5927
out_recovery:
5928
	return ret;
L
Linus Torvalds 已提交
5929 5930
}

5931
void
5932
nfs4_state_shutdown_net(struct net *net)
L
Linus Torvalds 已提交
5933 5934 5935
{
	struct nfs4_delegation *dp = NULL;
	struct list_head *pos, *next, reaplist;
5936
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
L
Linus Torvalds 已提交
5937

5938 5939
	cancel_delayed_work_sync(&nn->laundromat_work);
	locks_end_grace(&nn->nfsd4_manager);
5940

5941
	nfs4_lock_state();
L
Linus Torvalds 已提交
5942
	INIT_LIST_HEAD(&reaplist);
5943
	spin_lock(&state_lock);
5944
	list_for_each_safe(pos, next, &nn->del_recall_lru) {
L
Linus Torvalds 已提交
5945
		dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
5946 5947
		unhash_delegation_locked(dp);
		list_add(&dp->dl_recall_lru, &reaplist);
L
Linus Torvalds 已提交
5948
	}
5949
	spin_unlock(&state_lock);
L
Linus Torvalds 已提交
5950 5951
	list_for_each_safe(pos, next, &reaplist) {
		dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
5952
		list_del_init(&dp->dl_recall_lru);
5953
		nfs4_put_stid(&dp->dl_stid);
L
Linus Torvalds 已提交
5954 5955
	}

5956
	nfsd4_client_tracking_exit(net);
5957
	nfs4_state_destroy_net(net);
5958
	nfs4_unlock_state();
L
Linus Torvalds 已提交
5959 5960 5961 5962 5963
}

void
nfs4_state_shutdown(void)
{
5964
	destroy_workqueue(laundry_wq);
5965
	nfsd4_destroy_callback_queue();
L
Linus Torvalds 已提交
5966
}
5967 5968 5969 5970

static void
get_stateid(struct nfsd4_compound_state *cstate, stateid_t *stateid)
{
5971 5972
	if (HAS_STATE_ID(cstate, CURRENT_STATE_ID_FLAG) && CURRENT_STATEID(stateid))
		memcpy(stateid, &cstate->current_stateid, sizeof(stateid_t));
5973 5974 5975 5976 5977
}

static void
put_stateid(struct nfsd4_compound_state *cstate, stateid_t *stateid)
{
5978 5979 5980 5981 5982 5983 5984 5985 5986 5987
	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);
5988 5989
}

5990 5991 5992
/*
 * functions to set current state id
 */
5993 5994 5995 5996 5997 5998
void
nfsd4_set_opendowngradestateid(struct nfsd4_compound_state *cstate, struct nfsd4_open_downgrade *odp)
{
	put_stateid(cstate, &odp->od_stateid);
}

5999 6000 6001 6002 6003 6004
void
nfsd4_set_openstateid(struct nfsd4_compound_state *cstate, struct nfsd4_open *open)
{
	put_stateid(cstate, &open->op_stateid);
}

6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019
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
 */
6020

6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032
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);
}

6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044
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);
}

6045 6046 6047 6048 6049 6050 6051
void
nfsd4_get_closestateid(struct nfsd4_compound_state *cstate, struct nfsd4_close *close)
{
	get_stateid(cstate, &close->cl_stateid);
}

void
6052
nfsd4_get_lockustateid(struct nfsd4_compound_state *cstate, struct nfsd4_locku *locku)
6053
{
6054
	get_stateid(cstate, &locku->lu_stateid);
6055
}
6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067

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);
}