nfs4state.c 151.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

C
Christoph Hellwig 已提交
88 89 90 91 92
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 已提交
93

L
Linus Torvalds 已提交
94 95 96
void
nfs4_lock_state(void)
{
I
Ingo Molnar 已提交
97
	mutex_lock(&client_mutex);
L
Linus Torvalds 已提交
98 99
}

100
static void free_session(struct nfsd4_session *);
101

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

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

L
Linus Torvalds 已提交
115 116 117
void
nfs4_unlock_state(void)
{
I
Ingo Molnar 已提交
118
	mutex_unlock(&client_mutex);
L
Linus Torvalds 已提交
119 120
}

121 122 123 124 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
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);
}

185
static void put_client_renew_locked(struct nfs4_client *clp)
186 187 188 189 190 191 192
{
	if (!atomic_dec_and_test(&clp->cl_refcount))
		return;
	if (!is_client_expired(clp))
		renew_client_locked(clp);
}

193 194 195 196
static void put_client_renew(struct nfs4_client *clp)
{
	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);

197 198 199 200
	if (!atomic_dec_and_lock(&clp->cl_refcount, &nn->client_lock))
		return;
	if (!is_client_expired(clp))
		renew_client_locked(clp);
201 202 203
	spin_unlock(&nn->client_lock);
}

204 205 206 207 208 209 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
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);
}


L
Linus Torvalds 已提交
237 238 239 240 241 242 243 244 245 246 247 248 249
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;
}

250 251 252 253 254
static void nfsd4_free_file(struct nfs4_file *f)
{
	kmem_cache_free(file_slab, f);
}

255 256 257
static inline void
put_nfs4_file(struct nfs4_file *fi)
{
258 259
	might_lock(&state_lock);

260
	if (atomic_dec_and_lock(&fi->fi_ref, &state_lock)) {
261
		hlist_del(&fi->fi_hash);
262
		spin_unlock(&state_lock);
263
		nfsd4_free_file(fi);
264
	}
265 266 267 268 269
}

static inline void
get_nfs4_file(struct nfs4_file *fi)
{
270
	atomic_inc(&fi->fi_ref);
271 272
}

273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345
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;
}

346
static atomic_long_t num_delegations;
347
unsigned long max_delegations;
348 349 350 351 352

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

353 354 355 356
/* 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)
357

358
static unsigned int ownerstr_hashval(u32 clientid, struct xdr_netobj *ownername)
359 360 361 362 363
{
	unsigned int ret;

	ret = opaque_hashval(ownername->data, ownername->len);
	ret += clientid;
364
	return ret & OWNER_HASH_MASK;
365
}
366 367 368 369

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

371
static unsigned int nfsd_fh_hashval(struct knfsd_fh *fh)
372
{
373 374 375 376 377 378 379 380 381 382 383 384 385 386
	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);
387 388
}

389
static struct hlist_head file_hashtbl[FILE_HASH_SIZE];
390

391 392
static void
__nfs4_file_get_access(struct nfs4_file *fp, u32 access)
393
{
394 395
	lockdep_assert_held(&fp->fi_lock);

396 397 398 399
	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]);
400 401
}

402 403
static __be32
nfs4_file_get_access(struct nfs4_file *fp, u32 access)
404
{
405 406
	lockdep_assert_held(&fp->fi_lock);

407 408 409 410
	/* Does this access mode make sense? */
	if (access & ~NFS4_SHARE_ACCESS_BOTH)
		return nfserr_inval;

411 412 413 414
	/* Does it conflict with a deny mode already set? */
	if ((access & fp->fi_share_deny) != 0)
		return nfserr_share_denied;

415 416
	__nfs4_file_get_access(fp, access);
	return nfs_ok;
417 418
}

419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437
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;
}

438
static void __nfs4_file_put_access(struct nfs4_file *fp, int oflag)
439
{
440 441 442 443 444 445
	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 已提交
446
		swap(f1, fp->fi_fds[oflag]);
447
		if (atomic_read(&fp->fi_access[1 - oflag]) == 0)
J
Jeff Layton 已提交
448
			swap(f2, fp->fi_fds[O_RDWR]);
449 450 451 452 453
		spin_unlock(&fp->fi_lock);
		if (f1)
			fput(f1);
		if (f2)
			fput(f2);
454 455 456
	}
}

457
static void nfs4_file_put_access(struct nfs4_file *fp, u32 access)
458
{
459 460 461
	WARN_ON_ONCE(access & ~NFS4_SHARE_ACCESS_BOTH);

	if (access & NFS4_SHARE_ACCESS_WRITE)
462
		__nfs4_file_put_access(fp, O_WRONLY);
463 464
	if (access & NFS4_SHARE_ACCESS_READ)
		__nfs4_file_put_access(fp, O_RDONLY);
465 466
}

467 468
static struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl,
					 struct kmem_cache *slab)
469
{
J
J. Bruce Fields 已提交
470
	struct nfs4_stid *stid;
J
J. Bruce Fields 已提交
471
	int new_id;
472

473
	stid = kmem_cache_zalloc(slab, GFP_KERNEL);
J
J. Bruce Fields 已提交
474 475 476
	if (!stid)
		return NULL;

477 478 479 480 481
	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 已提交
482
	if (new_id < 0)
J
J. Bruce Fields 已提交
483
		goto out_free;
484
	stid->sc_client = cl;
J
J. Bruce Fields 已提交
485 486
	stid->sc_stateid.si_opaque.so_id = new_id;
	stid->sc_stateid.si_opaque.so_clid = cl->cl_clientid;
487
	/* Will be incremented before return to client: */
488
	atomic_set(&stid->sc_count, 1);
489 490

	/*
J
J. Bruce Fields 已提交
491 492 493 494 495 496 497
	 * 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):
498
	 */
J
J. Bruce Fields 已提交
499 500
	return stid;
out_free:
501
	kmem_cache_free(slab, stid);
J
J. Bruce Fields 已提交
502
	return NULL;
503 504
}

505
static struct nfs4_ol_stateid * nfs4_alloc_open_stateid(struct nfs4_client *clp)
506
{
507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522
	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);
523 524
}

525 526 527 528 529 530 531 532 533 534 535 536 537 538
/*
 * 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.
 *
539
 * 'blocked_delegations_lock', which is always taken in block_delegations(),
540 541 542
 * is used to manage concurrent access.  Testing does not need the lock
 * except when swapping the two filters.
 */
543
static DEFINE_SPINLOCK(blocked_delegations_lock);
544 545 546 547 548 549 550 551 552 553 554 555 556 557 558
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) {
559
		spin_lock(&blocked_delegations_lock);
560 561 562 563 564 565 566 567
		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();
		}
568
		spin_unlock(&blocked_delegations_lock);
569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590
	}
	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);

591
	spin_lock(&blocked_delegations_lock);
592 593 594 595 596 597
	__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;
598
	spin_unlock(&blocked_delegations_lock);
599 600
}

L
Linus Torvalds 已提交
601
static struct nfs4_delegation *
602
alloc_init_deleg(struct nfs4_client *clp, struct svc_fh *current_fh)
L
Linus Torvalds 已提交
603 604
{
	struct nfs4_delegation *dp;
605
	long n;
L
Linus Torvalds 已提交
606 607

	dprintk("NFSD alloc_init_deleg\n");
608 609 610
	n = atomic_long_inc_return(&num_delegations);
	if (n < 0 || n > max_delegations)
		goto out_dec;
611
	if (delegation_blocked(&current_fh->fh_handle))
612
		goto out_dec;
613
	dp = delegstateid(nfs4_alloc_stid(clp, deleg_slab));
N
NeilBrown 已提交
614
	if (dp == NULL)
615
		goto out_dec;
616 617

	dp->dl_stid.sc_free = nfs4_free_deleg;
618 619
	/*
	 * delegation seqid's are never incremented.  The 4.1 special
J
J. Bruce Fields 已提交
620 621
	 * meaning of seqid 0 isn't meaningful, really, but let's avoid
	 * 0 anyway just for consistency and use 1:
622 623
	 */
	dp->dl_stid.sc_stateid.si_generation = 1;
624 625
	INIT_LIST_HEAD(&dp->dl_perfile);
	INIT_LIST_HEAD(&dp->dl_perclnt);
L
Linus Torvalds 已提交
626
	INIT_LIST_HEAD(&dp->dl_recall_lru);
627
	dp->dl_type = NFS4_OPEN_DELEGATE_READ;
628
	INIT_WORK(&dp->dl_recall.cb_work, nfsd4_run_cb_recall);
L
Linus Torvalds 已提交
629
	return dp;
630 631 632
out_dec:
	atomic_long_dec(&num_delegations);
	return NULL;
L
Linus Torvalds 已提交
633 634 635
}

void
636
nfs4_put_stid(struct nfs4_stid *s)
L
Linus Torvalds 已提交
637
{
638
	struct nfs4_file *fp = s->sc_file;
639 640
	struct nfs4_client *clp = s->sc_client;

641 642 643
	might_lock(&clp->cl_lock);

	if (!atomic_dec_and_lock(&s->sc_count, &clp->cl_lock))
644 645
		return;
	idr_remove(&clp->cl_stateids, s->sc_stateid.si_opaque.so_id);
646
	spin_unlock(&clp->cl_lock);
647
	s->sc_free(s);
648 649
	if (fp)
		put_nfs4_file(fp);
L
Linus Torvalds 已提交
650 651
}

652
static void nfs4_put_deleg_lease(struct nfs4_file *fp)
L
Linus Torvalds 已提交
653
{
654 655
	lockdep_assert_held(&state_lock);

656 657
	if (!fp->fi_lease)
		return;
658 659 660
	if (atomic_dec_and_test(&fp->fi_delegees)) {
		vfs_setlease(fp->fi_deleg_file, F_UNLCK, &fp->fi_lease);
		fp->fi_lease = NULL;
661
		fput(fp->fi_deleg_file);
662 663
		fp->fi_deleg_file = NULL;
	}
L
Linus Torvalds 已提交
664 665
}

J
J. Bruce Fields 已提交
666 667
static void unhash_stid(struct nfs4_stid *s)
{
J
J. Bruce Fields 已提交
668
	s->sc_type = 0;
J
J. Bruce Fields 已提交
669 670
}

671 672 673
static void
hash_delegation_locked(struct nfs4_delegation *dp, struct nfs4_file *fp)
{
674
	lockdep_assert_held(&state_lock);
675
	lockdep_assert_held(&fp->fi_lock);
676

677
	atomic_inc(&dp->dl_stid.sc_count);
678
	dp->dl_stid.sc_type = NFS4_DELEG_STID;
679 680 681 682
	list_add(&dp->dl_perfile, &fp->fi_delegations);
	list_add(&dp->dl_perclnt, &dp->dl_stid.sc_client->cl_delegations);
}

L
Linus Torvalds 已提交
683
static void
684
unhash_delegation_locked(struct nfs4_delegation *dp)
L
Linus Torvalds 已提交
685
{
686
	struct nfs4_file *fp = dp->dl_stid.sc_file;
687

688 689
	lockdep_assert_held(&state_lock);

690
	dp->dl_stid.sc_type = NFS4_CLOSED_DELEG_STID;
691 692
	/* Ensure that deleg break won't try to requeue it */
	++dp->dl_time;
693
	spin_lock(&fp->fi_lock);
694
	list_del_init(&dp->dl_perclnt);
L
Linus Torvalds 已提交
695
	list_del_init(&dp->dl_recall_lru);
696 697
	list_del_init(&dp->dl_perfile);
	spin_unlock(&fp->fi_lock);
698
	if (fp)
699
		nfs4_put_deleg_lease(fp);
700 701 702 703
}

static void destroy_delegation(struct nfs4_delegation *dp)
{
704 705 706
	spin_lock(&state_lock);
	unhash_delegation_locked(dp);
	spin_unlock(&state_lock);
707
	nfs4_put_stid(&dp->dl_stid);
708 709 710 711 712 713
}

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

714 715
	WARN_ON(!list_empty(&dp->dl_recall_lru));

716
	if (clp->cl_minorversion == 0)
717
		nfs4_put_stid(&dp->dl_stid);
718 719
	else {
		dp->dl_stid.sc_type = NFS4_REVOKED_DELEG_STID;
720 721 722
		spin_lock(&clp->cl_lock);
		list_add(&dp->dl_recall_lru, &clp->cl_revoked);
		spin_unlock(&clp->cl_lock);
723 724 725
	}
}

L
Linus Torvalds 已提交
726 727 728 729
/* 
 * SETCLIENTID state 
 */

730 731 732 733 734 735 736 737 738 739
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;
}

740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757
/*
 * 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.
 */
758 759
static unsigned int
bmap_to_share_mode(unsigned long bmap) {
760
	int i;
761
	unsigned int access = 0;
762 763 764

	for (i = 1; i < 4; i++) {
		if (test_bit(i, &bmap))
765
			access |= i;
766
	}
767
	return access;
768 769
}

770 771 772 773
/* set share access for a given stateid */
static inline void
set_access(u32 access, struct nfs4_ol_stateid *stp)
{
774 775 776 777
	unsigned char mask = 1 << access;

	WARN_ON_ONCE(access > NFS4_SHARE_ACCESS_BOTH);
	stp->st_access_bmap |= mask;
778 779 780 781 782 783
}

/* clear share access for a given stateid */
static inline void
clear_access(u32 access, struct nfs4_ol_stateid *stp)
{
784 785 786 787
	unsigned char mask = 1 << access;

	WARN_ON_ONCE(access > NFS4_SHARE_ACCESS_BOTH);
	stp->st_access_bmap &= ~mask;
788 789 790 791 792 793
}

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

	return (bool)(stp->st_access_bmap & mask);
797 798
}

799 800
/* set share deny for a given stateid */
static inline void
801
set_deny(u32 deny, struct nfs4_ol_stateid *stp)
802
{
803 804 805 806
	unsigned char mask = 1 << deny;

	WARN_ON_ONCE(deny > NFS4_SHARE_DENY_BOTH);
	stp->st_deny_bmap |= mask;
807 808 809 810
}

/* clear share deny for a given stateid */
static inline void
811
clear_deny(u32 deny, struct nfs4_ol_stateid *stp)
812
{
813 814 815 816
	unsigned char mask = 1 << deny;

	WARN_ON_ONCE(deny > NFS4_SHARE_DENY_BOTH);
	stp->st_deny_bmap &= ~mask;
817 818 819 820
}

/* test whether a given stateid is denying specific access */
static inline bool
821
test_deny(u32 deny, struct nfs4_ol_stateid *stp)
822
{
823 824 825
	unsigned char mask = 1 << deny;

	return (bool)(stp->st_deny_bmap & mask);
826 827 828 829
}

static int nfs4_access_to_omode(u32 access)
{
830
	switch (access & NFS4_SHARE_ACCESS_BOTH) {
831 832 833 834 835 836 837
	case NFS4_SHARE_ACCESS_READ:
		return O_RDONLY;
	case NFS4_SHARE_ACCESS_WRITE:
		return O_WRONLY;
	case NFS4_SHARE_ACCESS_BOTH:
		return O_RDWR;
	}
838 839
	WARN_ON_ONCE(1);
	return O_RDONLY;
840 841
}

842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872
/*
 * 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)
873
		recalculate_deny_mode(stp->st_stid.sc_file);
874 875
}

876 877 878 879 880
/* release all access and file references for a given stateid */
static void
release_all_access(struct nfs4_ol_stateid *stp)
{
	int i;
881
	struct nfs4_file *fp = stp->st_stid.sc_file;
882 883 884

	if (fp && stp->st_deny_bmap != 0)
		recalculate_deny_mode(fp);
885 886 887

	for (i = 1; i < 4; i++) {
		if (test_access(i, stp))
888
			nfs4_file_put_access(stp->st_stid.sc_file, i);
889 890 891 892
		clear_access(i, stp);
	}
}

893
static void unhash_generic_stateid(struct nfs4_ol_stateid *stp)
894
{
895
	struct nfs4_file *fp = stp->st_stid.sc_file;
896

897 898
	lockdep_assert_held(&stp->st_stateowner->so_client->cl_lock);

899
	spin_lock(&fp->fi_lock);
900
	list_del(&stp->st_perfile);
901
	spin_unlock(&fp->fi_lock);
902 903 904
	list_del(&stp->st_perstateowner);
}

905
static void nfs4_free_ol_stateid(struct nfs4_stid *stid)
906
{
907
	struct nfs4_ol_stateid *stp = openlockstateid(stid);
908

909 910
	release_all_access(stp);
	kmem_cache_free(stateid_slab, stid);
911 912
}

913
static void nfs4_free_lock_stateid(struct nfs4_stid *stid)
914
{
915 916
	struct nfs4_ol_stateid *stp = openlockstateid(stid);
	struct nfs4_lockowner *lo = lockowner(stp->st_stateowner);
917 918
	struct file *file;

919 920 921 922 923 924 925 926
	file = find_any_file(stp->st_stid.sc_file);
	if (file)
		filp_close(file, (fl_owner_t)lo);
	nfs4_free_ol_stateid(stid);
}

static void __release_lock_stateid(struct nfs4_ol_stateid *stp)
{
927 928 929
	struct nfs4_openowner *oo = openowner(stp->st_openstp->st_stateowner);

	spin_lock(&oo->oo_owner.so_client->cl_lock);
930
	list_del(&stp->st_locks);
931
	unhash_generic_stateid(stp);
J
J. Bruce Fields 已提交
932
	unhash_stid(&stp->st_stid);
933
	spin_unlock(&oo->oo_owner.so_client->cl_lock);
934
	nfs4_put_stid(&stp->st_stid);
935 936
}

937
static void unhash_lockowner(struct nfs4_lockowner *lo)
938
{
939
	struct nfs4_ol_stateid *stp;
940

941 942 943
	list_del(&lo->lo_owner.so_strhash);
	while (!list_empty(&lo->lo_owner.so_stateids)) {
		stp = list_first_entry(&lo->lo_owner.so_stateids,
944
				struct nfs4_ol_stateid, st_perstateowner);
945
		__release_lock_stateid(stp);
946 947 948
	}
}

949 950 951 952 953 954
static void nfs4_free_lockowner(struct nfs4_lockowner *lo)
{
	kfree(lo->lo_owner.so_owner.data);
	kmem_cache_free(lockowner_slab, lo);
}

955
static void release_lockowner(struct nfs4_lockowner *lo)
956
{
957 958
	unhash_lockowner(lo);
	nfs4_free_lockowner(lo);
959 960
}

961 962 963 964 965 966 967
static void release_lockowner_if_empty(struct nfs4_lockowner *lo)
{
	if (list_empty(&lo->lo_owner.so_stateids))
		release_lockowner(lo);
}

static void release_lock_stateid(struct nfs4_ol_stateid *stp)
968
{
969
	struct nfs4_lockowner *lo;
970

971 972 973 974 975 976
	lo = lockowner(stp->st_stateowner);
	__release_lock_stateid(stp);
	release_lockowner_if_empty(lo);
}

static void release_open_stateid_locks(struct nfs4_ol_stateid *open_stp)
977 978
	__releases(&open_stp->st_stateowner->so_client->cl_lock)
	__acquires(&open_stp->st_stateowner->so_client->cl_lock)
979 980 981 982 983 984
{
	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);
985
		spin_unlock(&open_stp->st_stateowner->so_client->cl_lock);
986
		release_lock_stateid(stp);
987
		spin_lock(&open_stp->st_stateowner->so_client->cl_lock);
988 989 990
	}
}

991
static void unhash_open_stateid(struct nfs4_ol_stateid *stp)
992
{
993
	spin_lock(&stp->st_stateowner->so_client->cl_lock);
994
	unhash_generic_stateid(stp);
995
	release_open_stateid_locks(stp);
996
	spin_unlock(&stp->st_stateowner->so_client->cl_lock);
997 998 999 1000 1001
}

static void release_open_stateid(struct nfs4_ol_stateid *stp)
{
	unhash_open_stateid(stp);
1002
	nfs4_put_stid(&stp->st_stid);
1003 1004
}

1005
static void unhash_openowner(struct nfs4_openowner *oo)
1006
{
1007
	struct nfs4_ol_stateid *stp;
1008

1009 1010 1011 1012
	list_del(&oo->oo_owner.so_strhash);
	list_del(&oo->oo_perclient);
	while (!list_empty(&oo->oo_owner.so_stateids)) {
		stp = list_first_entry(&oo->oo_owner.so_stateids,
1013
				struct nfs4_ol_stateid, st_perstateowner);
1014
		release_open_stateid(stp);
1015 1016 1017
	}
}

1018 1019 1020 1021 1022
static void release_last_closed_stateid(struct nfs4_openowner *oo)
{
	struct nfs4_ol_stateid *s = oo->oo_last_closed_stid;

	if (s) {
1023
		nfs4_put_stid(&s->st_stid);
1024 1025 1026 1027
		oo->oo_last_closed_stid = NULL;
	}
}

1028 1029 1030 1031 1032 1033
static void nfs4_free_openowner(struct nfs4_openowner *oo)
{
	kfree(oo->oo_owner.so_owner.data);
	kmem_cache_free(openowner_slab, oo);
}

1034
static void release_openowner(struct nfs4_openowner *oo)
1035
{
1036 1037
	unhash_openowner(oo);
	list_del(&oo->oo_close_lru);
1038
	release_last_closed_stateid(oo);
1039
	nfs4_free_openowner(oo);
1040 1041
}

M
Marc Eshel 已提交
1042 1043 1044 1045 1046 1047 1048 1049
static inline int
hash_sessionid(struct nfs4_sessionid *sessionid)
{
	struct nfsd4_sessionid *sid = (struct nfsd4_sessionid *)sessionid;

	return sid->sequence % SESSION_HASH_SIZE;
}

1050
#ifdef NFSD_DEBUG
M
Marc Eshel 已提交
1051 1052 1053 1054 1055 1056
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]);
}
1057 1058 1059 1060 1061 1062 1063
#else
static inline void
dump_sessionid(const char *fn, struct nfs4_sessionid *sessionid)
{
}
#endif

1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085
/*
 * 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))) {
		cstate->replay_owner = NULL;
		return;
	}
	if (!so)
		return;
	if (so->so_is_open_owner)
		release_last_closed_stateid(openowner(so));
	so->so_seqid++;
	return;
}
M
Marc Eshel 已提交
1086

A
Andy Adamson 已提交
1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099
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;
}

/*
1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112
 * 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)

1113 1114 1115 1116 1117 1118 1119 1120 1121
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]);
}

1122
/*
1123 1124 1125
 * We don't actually need to cache the rpc and session headers, so we
 * can allocate a little less for each slot:
 */
1126
static inline u32 slot_bytes(struct nfsd4_channel_attrs *ca)
1127
{
1128
	u32 size;
1129

1130 1131 1132 1133 1134
	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);
1135
}
A
Andy Adamson 已提交
1136

1137 1138
/*
 * XXX: If we run out of reserved DRC memory we could (up to a point)
1139
 * re-negotiate active sessions and reduce their slot usage to make
1140
 * room for new connections. For now we just fail the create session.
A
Andy Adamson 已提交
1141
 */
1142
static u32 nfsd4_get_drc_mem(struct nfsd4_channel_attrs *ca)
A
Andy Adamson 已提交
1143
{
1144 1145
	u32 slotsize = slot_bytes(ca);
	u32 num = ca->maxreqs;
1146
	int avail;
A
Andy Adamson 已提交
1147

1148
	spin_lock(&nfsd_drc_lock);
1149 1150
	avail = min((unsigned long)NFSD_MAX_MEM_PER_SESSION,
		    nfsd_drc_max_mem - nfsd_drc_mem_used);
1151 1152 1153
	num = min_t(int, num, avail / slotsize);
	nfsd_drc_mem_used += num * slotsize;
	spin_unlock(&nfsd_drc_lock);
A
Andy Adamson 已提交
1154

1155 1156
	return num;
}
A
Andy Adamson 已提交
1157

1158
static void nfsd4_put_drc_mem(struct nfsd4_channel_attrs *ca)
1159
{
1160 1161
	int slotsize = slot_bytes(ca);

1162
	spin_lock(&nfsd_drc_lock);
1163
	nfsd_drc_mem_used -= slotsize * ca->maxreqs;
1164
	spin_unlock(&nfsd_drc_lock);
1165
}
A
Andy Adamson 已提交
1166

1167 1168
static struct nfsd4_session *alloc_session(struct nfsd4_channel_attrs *fattrs,
					   struct nfsd4_channel_attrs *battrs)
1169
{
1170 1171
	int numslots = fattrs->maxreqs;
	int slotsize = slot_bytes(fattrs);
1172 1173
	struct nfsd4_session *new;
	int mem, i;
1174

1175 1176 1177
	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 已提交
1178

1179 1180 1181
	new = kzalloc(sizeof(*new) + mem, GFP_KERNEL);
	if (!new)
		return NULL;
1182
	/* allocate each struct nfsd4_slot and data cache in one piece */
1183
	for (i = 0; i < numslots; i++) {
1184
		new->se_slots[i] = kzalloc(slotsize, GFP_KERNEL);
1185
		if (!new->se_slots[i])
1186 1187
			goto out_free;
	}
1188 1189 1190 1191

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

1192 1193 1194 1195 1196 1197
	return new;
out_free:
	while (i--)
		kfree(new->se_slots[i]);
	kfree(new);
	return NULL;
A
Andy Adamson 已提交
1198 1199
}

1200 1201 1202 1203 1204
static void free_conn(struct nfsd4_conn *c)
{
	svc_xprt_put(c->cn_xprt);
	kfree(c);
}
A
Andy Adamson 已提交
1205

1206 1207 1208 1209
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 已提交
1210

1211 1212 1213 1214 1215
	spin_lock(&clp->cl_lock);
	if (!list_empty(&c->cn_persession)) {
		list_del(&c->cn_persession);
		free_conn(c);
	}
1216
	nfsd4_probe_callback(clp);
1217
	spin_unlock(&clp->cl_lock);
1218
}
A
Andy Adamson 已提交
1219

1220
static struct nfsd4_conn *alloc_conn(struct svc_rqst *rqstp, u32 flags)
1221 1222
{
	struct nfsd4_conn *conn;
A
Andy Adamson 已提交
1223

1224 1225
	conn = kmalloc(sizeof(struct nfsd4_conn), GFP_KERNEL);
	if (!conn)
1226
		return NULL;
1227 1228
	svc_xprt_get(rqstp->rq_xprt);
	conn->cn_xprt = rqstp->rq_xprt;
1229
	conn->cn_flags = flags;
1230 1231 1232
	INIT_LIST_HEAD(&conn->cn_xpt_user.list);
	return conn;
}
1233

1234 1235 1236 1237
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 已提交
1238 1239
}

1240
static void nfsd4_hash_conn(struct nfsd4_conn *conn, struct nfsd4_session *ses)
1241
{
1242
	struct nfs4_client *clp = ses->se_client;
1243

1244
	spin_lock(&clp->cl_lock);
1245
	__nfsd4_hash_conn(conn, ses);
1246
	spin_unlock(&clp->cl_lock);
1247 1248
}

1249
static int nfsd4_register_conn(struct nfsd4_conn *conn)
1250
{
1251
	conn->cn_xpt_user.callback = nfsd4_conn_lost;
1252
	return register_xpt_user(conn->cn_xprt, &conn->cn_xpt_user);
1253 1254
}

1255
static void nfsd4_init_conn(struct svc_rqst *rqstp, struct nfsd4_conn *conn, struct nfsd4_session *ses)
A
Andy Adamson 已提交
1256
{
1257
	int ret;
A
Andy Adamson 已提交
1258

1259
	nfsd4_hash_conn(conn, ses);
1260 1261 1262 1263
	ret = nfsd4_register_conn(conn);
	if (ret)
		/* oops; xprt is already down: */
		nfsd4_conn_lost(&conn->cn_xpt_user);
1264 1265
	/* We may have gained or lost a callback channel: */
	nfsd4_probe_callback_sync(ses->se_client);
1266
}
A
Andy Adamson 已提交
1267

1268
static struct nfsd4_conn *alloc_conn_from_crses(struct svc_rqst *rqstp, struct nfsd4_create_session *cses)
1269 1270 1271
{
	u32 dir = NFS4_CDFC4_FORE;

1272
	if (cses->flags & SESSION4_BACK_CHAN)
1273
		dir |= NFS4_CDFC4_BACK;
1274
	return alloc_conn(rqstp, dir);
1275 1276 1277
}

/* must be called under client_lock */
1278
static void nfsd4_del_conns(struct nfsd4_session *s)
1279
{
1280 1281
	struct nfs4_client *clp = s->se_client;
	struct nfsd4_conn *c;
A
Andy Adamson 已提交
1282

1283 1284 1285 1286 1287
	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);
1288

1289 1290
		unregister_xpt_user(c->cn_xprt, &c->cn_xpt_user);
		free_conn(c);
A
Andy Adamson 已提交
1291

1292 1293 1294
		spin_lock(&clp->cl_lock);
	}
	spin_unlock(&clp->cl_lock);
1295
}
A
Andy Adamson 已提交
1296

1297 1298 1299 1300 1301 1302
static void __free_session(struct nfsd4_session *ses)
{
	free_session_slots(ses);
	kfree(ses);
}

1303
static void free_session(struct nfsd4_session *ses)
1304
{
1305
	struct nfsd_net *nn = net_generic(ses->se_client->net, nfsd_net_id);
1306 1307

	lockdep_assert_held(&nn->client_lock);
1308
	nfsd4_del_conns(ses);
1309
	nfsd4_put_drc_mem(&ses->se_fchannel);
1310
	__free_session(ses);
1311 1312
}

1313
static void init_session(struct svc_rqst *rqstp, struct nfsd4_session *new, struct nfs4_client *clp, struct nfsd4_create_session *cses)
1314 1315
{
	int idx;
1316
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
1317

A
Andy Adamson 已提交
1318 1319 1320
	new->se_client = clp;
	gen_sessionid(new);

1321 1322
	INIT_LIST_HEAD(&new->se_conns);

1323
	new->se_cb_seq_nr = 1;
A
Andy Adamson 已提交
1324
	new->se_flags = cses->flags;
1325
	new->se_cb_prog = cses->callback_prog;
1326
	new->se_cb_sec = cses->cb_sec;
1327
	atomic_set(&new->se_ref, 0);
1328
	idx = hash_sessionid(&new->se_sessionid);
1329
	spin_lock(&nn->client_lock);
1330
	list_add(&new->se_hash, &nn->sessionid_hashtbl[idx]);
1331
	spin_lock(&clp->cl_lock);
A
Andy Adamson 已提交
1332
	list_add(&new->se_perclnt, &clp->cl_sessions);
1333
	spin_unlock(&clp->cl_lock);
1334
	spin_unlock(&nn->client_lock);
1335

1336
	if (cses->flags & SESSION4_BACK_CHAN) {
1337
		struct sockaddr *sa = svc_addr(rqstp);
1338 1339 1340 1341 1342 1343 1344
		/*
		 * 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:
		 */
1345 1346 1347
		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 已提交
1348 1349
}

1350
/* caller must hold client_lock */
M
Marc Eshel 已提交
1351
static struct nfsd4_session *
1352
__find_in_sessionid_hashtbl(struct nfs4_sessionid *sessionid, struct net *net)
M
Marc Eshel 已提交
1353 1354 1355
{
	struct nfsd4_session *elem;
	int idx;
1356
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
M
Marc Eshel 已提交
1357 1358 1359 1360

	dump_sessionid(__func__, sessionid);
	idx = hash_sessionid(sessionid);
	/* Search in the appropriate list */
1361
	list_for_each_entry(elem, &nn->sessionid_hashtbl[idx], se_hash) {
M
Marc Eshel 已提交
1362 1363 1364 1365 1366 1367 1368 1369 1370 1371
		if (!memcmp(elem->se_sessionid.data, sessionid->data,
			    NFS4_MAX_SESSIONID_LEN)) {
			return elem;
		}
	}

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

1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389
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;
}

1390
/* caller must hold client_lock */
A
Andy Adamson 已提交
1391
static void
M
Marc Eshel 已提交
1392
unhash_session(struct nfsd4_session *ses)
A
Andy Adamson 已提交
1393 1394
{
	list_del(&ses->se_hash);
1395
	spin_lock(&ses->se_client->cl_lock);
A
Andy Adamson 已提交
1396
	list_del(&ses->se_perclnt);
1397
	spin_unlock(&ses->se_client->cl_lock);
M
Marc Eshel 已提交
1398 1399
}

L
Linus Torvalds 已提交
1400 1401
/* SETCLIENTID and SETCLIENTID_CONFIRM Helper functions */
static int
1402
STALE_CLIENTID(clientid_t *clid, struct nfsd_net *nn)
L
Linus Torvalds 已提交
1403
{
1404
	if (clid->cl_boot == nn->boot_time)
L
Linus Torvalds 已提交
1405
		return 0;
A
Andy Adamson 已提交
1406
	dprintk("NFSD stale clientid (%08x/%08x) boot_time %08lx\n",
1407
		clid->cl_boot, clid->cl_id, nn->boot_time);
L
Linus Torvalds 已提交
1408 1409 1410 1411 1412 1413 1414 1415
	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.
 */
1416
static struct nfs4_client *alloc_client(struct xdr_netobj name)
L
Linus Torvalds 已提交
1417 1418 1419
{
	struct nfs4_client *clp;

1420 1421 1422
	clp = kzalloc(sizeof(struct nfs4_client), GFP_KERNEL);
	if (clp == NULL)
		return NULL;
1423
	clp->cl_name.data = kmemdup(name.data, name.len, GFP_KERNEL);
1424 1425 1426
	if (clp->cl_name.data == NULL) {
		kfree(clp);
		return NULL;
L
Linus Torvalds 已提交
1427
	}
1428
	clp->cl_name.len = name.len;
1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440
	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 已提交
1441 1442 1443
	return clp;
}

1444
static void
L
Linus Torvalds 已提交
1445 1446
free_client(struct nfs4_client *clp)
{
1447
	struct nfsd_net __maybe_unused *nn = net_generic(clp->net, nfsd_net_id);
1448 1449

	lockdep_assert_held(&nn->client_lock);
1450 1451 1452 1453 1454
	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);
1455 1456
		WARN_ON_ONCE(atomic_read(&ses->se_ref));
		free_session(ses);
1457
	}
1458
	rpc_destroy_wait_queue(&clp->cl_cb_waitq);
1459
	free_svc_cred(&clp->cl_cred);
L
Linus Torvalds 已提交
1460
	kfree(clp->cl_name.data);
M
majianpeng 已提交
1461
	idr_destroy(&clp->cl_stateids);
L
Linus Torvalds 已提交
1462 1463 1464
	kfree(clp);
}

B
Benny Halevy 已提交
1465 1466 1467 1468
/* must be called under the client_lock */
static inline void
unhash_client_locked(struct nfs4_client *clp)
{
1469 1470
	struct nfsd4_session *ses;

B
Benny Halevy 已提交
1471
	list_del(&clp->cl_lru);
1472
	spin_lock(&clp->cl_lock);
1473 1474
	list_for_each_entry(ses, &clp->cl_sessions, se_perclnt)
		list_del_init(&ses->se_hash);
1475
	spin_unlock(&clp->cl_lock);
B
Benny Halevy 已提交
1476 1477
}

L
Linus Torvalds 已提交
1478
static void
1479
destroy_client(struct nfs4_client *clp)
L
Linus Torvalds 已提交
1480
{
1481
	struct nfs4_openowner *oo;
L
Linus Torvalds 已提交
1482 1483
	struct nfs4_delegation *dp;
	struct list_head reaplist;
1484
	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
L
Linus Torvalds 已提交
1485 1486

	INIT_LIST_HEAD(&reaplist);
1487
	spin_lock(&state_lock);
1488 1489
	while (!list_empty(&clp->cl_delegations)) {
		dp = list_entry(clp->cl_delegations.next, struct nfs4_delegation, dl_perclnt);
1490 1491
		unhash_delegation_locked(dp);
		list_add(&dp->dl_recall_lru, &reaplist);
L
Linus Torvalds 已提交
1492
	}
1493
	spin_unlock(&state_lock);
L
Linus Torvalds 已提交
1494 1495
	while (!list_empty(&reaplist)) {
		dp = list_entry(reaplist.next, struct nfs4_delegation, dl_recall_lru);
1496
		list_del_init(&dp->dl_recall_lru);
1497
		nfs4_put_stid(&dp->dl_stid);
L
Linus Torvalds 已提交
1498
	}
1499
	while (!list_empty(&clp->cl_revoked)) {
1500
		dp = list_entry(reaplist.next, struct nfs4_delegation, dl_recall_lru);
1501
		list_del_init(&dp->dl_recall_lru);
1502
		nfs4_put_stid(&dp->dl_stid);
1503
	}
1504
	while (!list_empty(&clp->cl_openowners)) {
1505 1506
		oo = list_entry(clp->cl_openowners.next, struct nfs4_openowner, oo_perclient);
		release_openowner(oo);
L
Linus Torvalds 已提交
1507
	}
1508
	nfsd4_shutdown_callback(clp);
B
Benny Halevy 已提交
1509 1510
	if (clp->cl_cb_conn.cb_xprt)
		svc_xprt_put(clp->cl_cb_conn.cb_xprt);
1511
	list_del(&clp->cl_idhash);
1512
	if (test_bit(NFSD4_CLIENT_CONFIRMED, &clp->cl_flags))
1513
		rb_erase(&clp->cl_namenode, &nn->conf_name_tree);
1514
	else
1515
		rb_erase(&clp->cl_namenode, &nn->unconf_name_tree);
1516
	spin_lock(&nn->client_lock);
B
Benny Halevy 已提交
1517
	unhash_client_locked(clp);
1518 1519
	WARN_ON_ONCE(atomic_read(&clp->cl_refcount));
	free_client(clp);
1520
	spin_unlock(&nn->client_lock);
L
Linus Torvalds 已提交
1521 1522
}

1523 1524 1525 1526 1527 1528
static void expire_client(struct nfs4_client *clp)
{
	nfsd4_client_record_remove(clp);
	destroy_client(clp);
}

1529 1530 1531 1532
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 已提交
1533 1534
}

1535 1536
static void copy_clid(struct nfs4_client *target, struct nfs4_client *source)
{
L
Linus Torvalds 已提交
1537 1538 1539 1540
	target->cl_clientid.cl_boot = source->cl_clientid.cl_boot; 
	target->cl_clientid.cl_id = source->cl_clientid.cl_id; 
}

1541
static int copy_cred(struct svc_cred *target, struct svc_cred *source)
1542
{
1543 1544 1545 1546 1547 1548 1549
	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;
1550
	target->cr_flavor = source->cr_flavor;
L
Linus Torvalds 已提交
1551 1552 1553 1554
	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);
1555 1556 1557
	target->cr_gss_mech = source->cr_gss_mech;
	if (source->cr_gss_mech)
		gss_mech_get(source->cr_gss_mech);
1558
	return 0;
L
Linus Torvalds 已提交
1559 1560
}

1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571
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);
}

1572
static int same_name(const char *n1, const char *n2)
1573
{
N
NeilBrown 已提交
1574
	return 0 == memcmp(n1, n2, HEXDIR_LEN);
L
Linus Torvalds 已提交
1575 1576 1577
}

static int
1578 1579 1580
same_verf(nfs4_verifier *v1, nfs4_verifier *v2)
{
	return 0 == memcmp(v1->data, v2->data, sizeof(v1->data));
L
Linus Torvalds 已提交
1581 1582 1583
}

static int
1584 1585 1586
same_clid(clientid_t *cl1, clientid_t *cl2)
{
	return (cl1->cl_boot == cl2->cl_boot) && (cl1->cl_id == cl2->cl_id);
L
Linus Torvalds 已提交
1587 1588
}

1589 1590 1591 1592 1593 1594 1595
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++)
1596
		if (!gid_eq(GROUP_AT(g1, i), GROUP_AT(g2, i)))
1597 1598 1599 1600
			return false;
	return true;
}

1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616
/*
 * 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);
}


1617
static bool
1618 1619
same_creds(struct svc_cred *cr1, struct svc_cred *cr2)
{
1620
	if ((is_gss_cred(cr1) != is_gss_cred(cr2))
1621 1622
		|| (!uid_eq(cr1->cr_uid, cr2->cr_uid))
		|| (!gid_eq(cr1->cr_gid, cr2->cr_gid))
1623 1624 1625 1626 1627 1628
		|| !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;
1629
	return 0 == strcmp(cr1->cr_principal, cr2->cr_principal);
L
Linus Torvalds 已提交
1630 1631
}

1632 1633 1634 1635 1636
static bool svc_rqst_integrity_protected(struct svc_rqst *rqstp)
{
	struct svc_cred *cr = &rqstp->rq_cred;
	u32 service;

1637 1638
	if (!cr->cr_gss_mech)
		return false;
1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658
	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);
}

1659
static void gen_clid(struct nfs4_client *clp, struct nfsd_net *nn)
1660 1661 1662
{
	static u32 current_clientid = 1;

1663
	clp->cl_clientid.cl_boot = nn->boot_time;
L
Linus Torvalds 已提交
1664 1665 1666
	clp->cl_clientid.cl_id = current_clientid++; 
}

1667 1668
static void gen_confirm(struct nfs4_client *clp)
{
1669
	__be32 verf[2];
1670
	static u32 i;
L
Linus Torvalds 已提交
1671

1672 1673 1674 1675 1676 1677
	/*
	 * 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++;
1678
	memcpy(clp->cl_confirm.data, verf, sizeof(clp->cl_confirm.data));
L
Linus Torvalds 已提交
1679 1680
}

1681 1682
static struct nfs4_stid *
find_stateid_locked(struct nfs4_client *cl, stateid_t *t)
1683
{
J
J. Bruce Fields 已提交
1684 1685 1686 1687 1688 1689
	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 已提交
1690 1691
}

1692 1693
static struct nfs4_stid *
find_stateid_by_type(struct nfs4_client *cl, stateid_t *t, char typemask)
1694 1695
{
	struct nfs4_stid *s;
J
J. Bruce Fields 已提交
1696

1697 1698 1699 1700 1701 1702
	spin_lock(&cl->cl_lock);
	s = find_stateid_locked(cl, t);
	if (s != NULL && !(typemask & s->sc_type))
		s = NULL;
	spin_unlock(&cl->cl_lock);
	return s;
1703 1704
}

J
Jeff Layton 已提交
1705
static struct nfs4_client *create_client(struct xdr_netobj name,
1706 1707 1708 1709
		struct svc_rqst *rqstp, nfs4_verifier *verf)
{
	struct nfs4_client *clp;
	struct sockaddr *sa = svc_addr(rqstp);
1710
	int ret;
1711
	struct net *net = SVC_NET(rqstp);
1712
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1713 1714 1715 1716 1717

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

1718 1719
	ret = copy_cred(&clp->cl_cred, &rqstp->rq_cred);
	if (ret) {
1720
		spin_lock(&nn->client_lock);
1721
		free_client(clp);
1722
		spin_unlock(&nn->client_lock);
1723
		return NULL;
1724
	}
1725
	INIT_WORK(&clp->cl_cb_null.cb_work, nfsd4_run_cb_null);
B
Benny Halevy 已提交
1726
	clp->cl_time = get_seconds();
1727 1728 1729 1730
	clear_bit(0, &clp->cl_cb_slot_busy);
	copy_verf(clp, verf);
	rpc_copy_addr((struct sockaddr *) &clp->cl_addr, sa);
	gen_confirm(clp);
1731
	clp->cl_cb_session = NULL;
1732
	clp->net = net;
1733 1734 1735
	return clp;
}

1736
static void
1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777
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 已提交
1778 1779
{
	unsigned int idhashval;
1780
	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
L
Linus Torvalds 已提交
1781

1782
	clear_bit(NFSD4_CLIENT_CONFIRMED, &clp->cl_flags);
1783
	add_clp_to_name_tree(clp, &nn->unconf_name_tree);
L
Linus Torvalds 已提交
1784
	idhashval = clientid_hashval(clp->cl_clientid.cl_id);
1785
	list_add(&clp->cl_idhash, &nn->unconf_id_hashtbl[idhashval]);
1786
	renew_client(clp);
L
Linus Torvalds 已提交
1787 1788
}

1789
static void
L
Linus Torvalds 已提交
1790 1791 1792
move_to_confirmed(struct nfs4_client *clp)
{
	unsigned int idhashval = clientid_hashval(clp->cl_clientid.cl_id);
1793
	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
L
Linus Torvalds 已提交
1794 1795

	dprintk("NFSD: move_to_confirm nfs4_client %p\n", clp);
1796
	list_move(&clp->cl_idhash, &nn->conf_id_hashtbl[idhashval]);
1797
	rb_erase(&clp->cl_namenode, &nn->unconf_name_tree);
1798
	add_clp_to_name_tree(clp, &nn->conf_name_tree);
1799
	set_bit(NFSD4_CLIENT_CONFIRMED, &clp->cl_flags);
L
Linus Torvalds 已提交
1800 1801 1802 1803
	renew_client(clp);
}

static struct nfs4_client *
J
J. Bruce Fields 已提交
1804
find_client_in_id_table(struct list_head *tbl, clientid_t *clid, bool sessions)
L
Linus Torvalds 已提交
1805 1806 1807 1808
{
	struct nfs4_client *clp;
	unsigned int idhashval = clientid_hashval(clid->cl_id);

J
J. Bruce Fields 已提交
1809
	list_for_each_entry(clp, &tbl[idhashval], cl_idhash) {
1810
		if (same_clid(&clp->cl_clientid, clid)) {
1811 1812
			if ((bool)clp->cl_minorversion != sessions)
				return NULL;
1813
			renew_client(clp);
L
Linus Torvalds 已提交
1814
			return clp;
1815
		}
L
Linus Torvalds 已提交
1816 1817 1818 1819
	}
	return NULL;
}

J
J. Bruce Fields 已提交
1820 1821 1822 1823 1824 1825 1826 1827
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 已提交
1828
static struct nfs4_client *
1829
find_unconfirmed_client(clientid_t *clid, bool sessions, struct nfsd_net *nn)
L
Linus Torvalds 已提交
1830
{
J
J. Bruce Fields 已提交
1831
	struct list_head *tbl = nn->unconf_id_hashtbl;
L
Linus Torvalds 已提交
1832

J
J. Bruce Fields 已提交
1833
	return find_client_in_id_table(tbl, clid, sessions);
L
Linus Torvalds 已提交
1834 1835
}

1836
static bool clp_used_exchangeid(struct nfs4_client *clp)
1837
{
1838
	return clp->cl_exchange_flags != 0;
1839
} 
1840

1841
static struct nfs4_client *
1842
find_confirmed_client_by_name(struct xdr_netobj *name, struct nfsd_net *nn)
1843
{
1844
	return find_clp_in_name_tree(name, &nn->conf_name_tree);
1845 1846 1847
}

static struct nfs4_client *
1848
find_unconfirmed_client_by_name(struct xdr_netobj *name, struct nfsd_net *nn)
1849
{
1850
	return find_clp_in_name_tree(name, &nn->unconf_name_tree);
1851 1852
}

1853
static void
1854
gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se, struct svc_rqst *rqstp)
L
Linus Torvalds 已提交
1855
{
1856
	struct nfs4_cb_conn *conn = &clp->cl_cb_conn;
1857 1858
	struct sockaddr	*sa = svc_addr(rqstp);
	u32 scopeid = rpc_get_scope_id(sa);
1859 1860 1861 1862 1863 1864 1865 1866 1867 1868
	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 已提交
1869 1870
		goto out_err;

1871
	conn->cb_addrlen = rpc_uaddr2sockaddr(clp->net, se->se_callback_addr_val,
1872
					    se->se_callback_addr_len,
1873 1874
					    (struct sockaddr *)&conn->cb_addr,
					    sizeof(conn->cb_addr));
1875

1876
	if (!conn->cb_addrlen || conn->cb_addr.ss_family != expected_family)
L
Linus Torvalds 已提交
1877
		goto out_err;
1878

1879 1880
	if (conn->cb_addr.ss_family == AF_INET6)
		((struct sockaddr_in6 *)&conn->cb_addr)->sin6_scope_id = scopeid;
1881

1882 1883
	conn->cb_prog = se->se_callback_prog;
	conn->cb_ident = se->se_callback_ident;
1884
	memcpy(&conn->cb_saddr, &rqstp->rq_daddr, rqstp->rq_daddrlen);
L
Linus Torvalds 已提交
1885 1886
	return;
out_err:
1887 1888
	conn->cb_addr.ss_family = AF_UNSPEC;
	conn->cb_addrlen = 0;
N
Neil Brown 已提交
1889
	dprintk(KERN_INFO "NFSD: this client (clientid %08x/%08x) "
L
Linus Torvalds 已提交
1890 1891 1892 1893 1894 1895
		"will not receive delegations\n",
		clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);

	return;
}

1896
/*
1897
 * Cache a reply. nfsd4_check_resp_size() has bounded the cache size.
1898
 */
1899
static void
1900 1901
nfsd4_store_cache_entry(struct nfsd4_compoundres *resp)
{
1902
	struct xdr_buf *buf = resp->xdr.buf;
1903 1904
	struct nfsd4_slot *slot = resp->cstate.slot;
	unsigned int base;
1905

1906
	dprintk("--> %s slot %p\n", __func__, slot);
1907

1908 1909
	slot->sl_opcnt = resp->opcnt;
	slot->sl_status = resp->cstate.status;
1910

1911
	slot->sl_flags |= NFSD4_SLOT_INITIALIZED;
1912
	if (nfsd4_not_cached(resp)) {
1913
		slot->sl_datalen = 0;
1914
		return;
1915
	}
1916 1917 1918
	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))
1919 1920
		WARN("%s: sessions DRC could not cache compound\n", __func__);
	return;
1921 1922 1923
}

/*
1924 1925 1926 1927
 * 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.
1928 1929
 *
 */
1930 1931 1932
static __be32
nfsd4_enc_sequence_replay(struct nfsd4_compoundargs *args,
			  struct nfsd4_compoundres *resp)
1933
{
1934 1935
	struct nfsd4_op *op;
	struct nfsd4_slot *slot = resp->cstate.slot;
1936

1937 1938 1939
	/* Encode the replayed sequence operation */
	op = &args->ops[resp->opcnt - 1];
	nfsd4_encode_operation(resp, op);
1940

1941
	/* Return nfserr_retry_uncached_rep in next operation. */
1942
	if (args->opcnt > 1 && !(slot->sl_flags & NFSD4_SLOT_CACHETHIS)) {
1943 1944 1945
		op = &args->ops[resp->opcnt++];
		op->status = nfserr_retry_uncached_rep;
		nfsd4_encode_operation(resp, op);
1946
	}
1947
	return op->status;
1948 1949 1950
}

/*
1951 1952
 * The sequence operation is not cached because we can use the slot and
 * session values.
1953
 */
1954
static __be32
1955 1956
nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
			 struct nfsd4_sequence *seq)
1957
{
1958
	struct nfsd4_slot *slot = resp->cstate.slot;
1959 1960
	struct xdr_stream *xdr = &resp->xdr;
	__be32 *p;
1961 1962
	__be32 status;

1963
	dprintk("--> %s slot %p\n", __func__, slot);
1964

1965
	status = nfsd4_enc_sequence_replay(resp->rqstp->rq_argp, resp);
1966
	if (status)
1967
		return status;
1968

1969 1970 1971 1972 1973 1974 1975
	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);
1976

1977
	resp->opcnt = slot->sl_opcnt;
1978
	return slot->sl_status;
1979 1980
}

A
Andy Adamson 已提交
1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996
/*
 * 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;
}

1997 1998 1999 2000 2001 2002 2003 2004
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.
	 */
2005 2006 2007
	return !list_empty(&clp->cl_openowners)
		|| !list_empty(&clp->cl_delegations)
		|| !list_empty(&clp->cl_sessions);
2008 2009
}

A
Andy Adamson 已提交
2010 2011 2012 2013 2014
__be32
nfsd4_exchange_id(struct svc_rqst *rqstp,
		  struct nfsd4_compound_state *cstate,
		  struct nfsd4_exchange_id *exid)
{
A
Andy Adamson 已提交
2015
	struct nfs4_client *unconf, *conf, *new;
J
J. Bruce Fields 已提交
2016
	__be32 status;
2017
	char			addr_str[INET6_ADDRSTRLEN];
A
Andy Adamson 已提交
2018
	nfs4_verifier		verf = exid->verifier;
2019
	struct sockaddr		*sa = svc_addr(rqstp);
2020
	bool	update = exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A;
2021
	struct nfsd_net		*nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
A
Andy Adamson 已提交
2022

2023
	rpc_ntop(sa, addr_str, sizeof(addr_str));
A
Andy Adamson 已提交
2024
	dprintk("%s rqstp=%p exid=%p clname.len=%u clname.data=%p "
2025
		"ip_addr=%s flags %x, spa_how %d\n",
A
Andy Adamson 已提交
2026
		__func__, rqstp, exid, exid->clname.len, exid->clname.data,
2027
		addr_str, exid->flags, exid->spa_how);
A
Andy Adamson 已提交
2028

2029
	if (exid->flags & ~EXCHGID4_FLAG_MASK_A)
A
Andy Adamson 已提交
2030 2031 2032
		return nfserr_inval;

	switch (exid->spa_how) {
2033 2034 2035
	case SP4_MACH_CRED:
		if (!svc_rqst_integrity_protected(rqstp))
			return nfserr_inval;
A
Andy Adamson 已提交
2036 2037
	case SP4_NONE:
		break;
2038 2039
	default:				/* checked by xdr code */
		WARN_ON_ONCE(1);
A
Andy Adamson 已提交
2040
	case SP4_SSV:
2041
		return nfserr_encr_alg_unsupp;
A
Andy Adamson 已提交
2042 2043
	}

2044
	/* Cases below refer to rfc 5661 section 18.35.4: */
A
Andy Adamson 已提交
2045
	nfs4_lock_state();
2046
	conf = find_confirmed_client_by_name(&exid->clname, nn);
A
Andy Adamson 已提交
2047
	if (conf) {
2048 2049 2050
		bool creds_match = same_creds(&conf->cl_cred, &rqstp->rq_cred);
		bool verfs_match = same_verf(&verf, &conf->cl_verifier);

2051 2052
		if (update) {
			if (!clp_used_exchangeid(conf)) { /* buggy client */
2053
				status = nfserr_inval;
2054 2055
				goto out;
			}
2056 2057 2058 2059
			if (!mach_creds_match(conf, rqstp)) {
				status = nfserr_wrong_cred;
				goto out;
			}
2060
			if (!creds_match) { /* case 9 */
2061
				status = nfserr_perm;
2062 2063 2064
				goto out;
			}
			if (!verfs_match) { /* case 8 */
A
Andy Adamson 已提交
2065 2066 2067
				status = nfserr_not_same;
				goto out;
			}
2068 2069 2070 2071
			/* case 6 */
			exid->flags |= EXCHGID4_FLAG_CONFIRMED_R;
			new = conf;
			goto out_copy;
A
Andy Adamson 已提交
2072
		}
2073
		if (!creds_match) { /* case 3 */
2074 2075
			if (client_has_state(conf)) {
				status = nfserr_clid_inuse;
A
Andy Adamson 已提交
2076 2077 2078 2079 2080
				goto out;
			}
			expire_client(conf);
			goto out_new;
		}
2081
		if (verfs_match) { /* case 2 */
2082
			conf->cl_exchange_flags |= EXCHGID4_FLAG_CONFIRMED_R;
2083 2084 2085 2086 2087
			new = conf;
			goto out_copy;
		}
		/* case 5, client reboot */
		goto out_new;
2088 2089
	}

2090
	if (update) { /* case 7 */
2091 2092
		status = nfserr_noent;
		goto out;
A
Andy Adamson 已提交
2093 2094
	}

2095
	unconf  = find_unconfirmed_client_by_name(&exid->clname, nn);
2096
	if (unconf) /* case 4, possible retry or client restart */
A
Andy Adamson 已提交
2097 2098
		expire_client(unconf);

2099
	/* case 1 (normal case) */
A
Andy Adamson 已提交
2100
out_new:
J
Jeff Layton 已提交
2101
	new = create_client(exid->clname, rqstp, &verf);
A
Andy Adamson 已提交
2102
	if (new == NULL) {
2103
		status = nfserr_jukebox;
A
Andy Adamson 已提交
2104 2105
		goto out;
	}
2106
	new->cl_minorversion = cstate->minorversion;
2107
	new->cl_mach_cred = (exid->spa_how == SP4_MACH_CRED);
A
Andy Adamson 已提交
2108

2109
	gen_clid(new, nn);
2110
	add_to_unconfirmed(new);
A
Andy Adamson 已提交
2111 2112 2113 2114
out_copy:
	exid->clientid.cl_boot = new->cl_clientid.cl_boot;
	exid->clientid.cl_id = new->cl_clientid.cl_id;

2115
	exid->seqid = new->cl_cs_slot.sl_seqid + 1;
A
Andy Adamson 已提交
2116 2117 2118
	nfsd4_set_ex_flags(new, exid);

	dprintk("nfsd4_exchange_id seqid %d flags %x\n",
2119
		new->cl_cs_slot.sl_seqid, new->cl_exchange_flags);
A
Andy Adamson 已提交
2120 2121 2122 2123 2124
	status = nfs_ok;

out:
	nfs4_unlock_state();
	return status;
A
Andy Adamson 已提交
2125 2126
}

J
J. Bruce Fields 已提交
2127
static __be32
2128
check_slot_seqid(u32 seqid, u32 slot_seqid, int slot_inuse)
B
Benny Halevy 已提交
2129
{
2130 2131
	dprintk("%s enter. seqid %d slot_seqid %d\n", __func__, seqid,
		slot_seqid);
B
Benny Halevy 已提交
2132 2133

	/* The slot is in use, and no response has been sent. */
2134 2135
	if (slot_inuse) {
		if (seqid == slot_seqid)
B
Benny Halevy 已提交
2136 2137 2138 2139
			return nfserr_jukebox;
		else
			return nfserr_seq_misordered;
	}
2140
	/* Note unsigned 32-bit arithmetic handles wraparound: */
2141
	if (likely(seqid == slot_seqid + 1))
B
Benny Halevy 已提交
2142
		return nfs_ok;
2143
	if (seqid == slot_seqid)
B
Benny Halevy 已提交
2144 2145 2146 2147
		return nfserr_replay_cache;
	return nfserr_seq_misordered;
}

2148 2149 2150 2151 2152 2153 2154
/*
 * 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 已提交
2155
			   struct nfsd4_clid_slot *slot, __be32 nfserr)
2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168
{
	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;
}

2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185
#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))

2186
static __be32 check_forechannel_attrs(struct nfsd4_channel_attrs *ca, struct nfsd_net *nn)
2187
{
2188 2189
	u32 maxrpc = nn->nfsd_serv->sv_max_mesg;

2190 2191 2192 2193
	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;
2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212
	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;

2213
	return nfs_ok;
2214 2215
}

2216 2217 2218 2219 2220
#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))

2221
static __be32 check_backchannel_attrs(struct nfsd4_channel_attrs *ca)
2222
{
2223 2224 2225 2226 2227 2228 2229 2230
	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:
	 */
2231
	if (ca->maxreq_sz < NFSD_CB_MAX_REQ_SZ)
2232
		return nfserr_toosmall;
2233
	if (ca->maxresp_sz < NFSD_CB_MAX_RESP_SZ)
2234 2235 2236 2237 2238 2239
		return nfserr_toosmall;
	ca->maxresp_cached = 0;
	if (ca->maxops < 2)
		return nfserr_toosmall;

	return nfs_ok;
2240 2241
}

2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259
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 已提交
2260 2261 2262 2263 2264
__be32
nfsd4_create_session(struct svc_rqst *rqstp,
		     struct nfsd4_compound_state *cstate,
		     struct nfsd4_create_session *cr_ses)
{
2265
	struct sockaddr *sa = svc_addr(rqstp);
A
Andy Adamson 已提交
2266
	struct nfs4_client *conf, *unconf;
2267
	struct nfsd4_session *new;
2268
	struct nfsd4_conn *conn;
2269
	struct nfsd4_clid_slot *cs_slot = NULL;
J
J. Bruce Fields 已提交
2270
	__be32 status = 0;
2271
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
A
Andy Adamson 已提交
2272

2273 2274
	if (cr_ses->flags & ~SESSION4_FLAG_MASK_A)
		return nfserr_inval;
2275 2276 2277
	status = nfsd4_check_cb_sec(&cr_ses->cb_sec);
	if (status)
		return status;
2278
	status = check_forechannel_attrs(&cr_ses->fore_channel, nn);
2279 2280 2281
	if (status)
		return status;
	status = check_backchannel_attrs(&cr_ses->back_channel);
2282
	if (status)
2283
		goto out_release_drc_mem;
2284
	status = nfserr_jukebox;
2285
	new = alloc_session(&cr_ses->fore_channel, &cr_ses->back_channel);
2286 2287
	if (!new)
		goto out_release_drc_mem;
2288 2289 2290
	conn = alloc_conn_from_crses(rqstp, cr_ses);
	if (!conn)
		goto out_free_session;
2291

A
Andy Adamson 已提交
2292
	nfs4_lock_state();
2293
	unconf = find_unconfirmed_client(&cr_ses->clientid, true, nn);
2294
	conf = find_confirmed_client(&cr_ses->clientid, true, nn);
2295
	WARN_ON_ONCE(conf && unconf);
A
Andy Adamson 已提交
2296 2297

	if (conf) {
2298 2299 2300
		status = nfserr_wrong_cred;
		if (!mach_creds_match(conf, rqstp))
			goto out_free_conn;
2301 2302
		cs_slot = &conf->cl_cs_slot;
		status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0);
2303
		if (status == nfserr_replay_cache) {
2304
			status = nfsd4_replay_create_session(cr_ses, cs_slot);
2305
			goto out_free_conn;
2306
		} else if (cr_ses->seqid != cs_slot->sl_seqid + 1) {
A
Andy Adamson 已提交
2307
			status = nfserr_seq_misordered;
2308
			goto out_free_conn;
A
Andy Adamson 已提交
2309 2310
		}
	} else if (unconf) {
J
J. Bruce Fields 已提交
2311
		struct nfs4_client *old;
A
Andy Adamson 已提交
2312
		if (!same_creds(&unconf->cl_cred, &rqstp->rq_cred) ||
2313
		    !rpc_cmp_addr(sa, (struct sockaddr *) &unconf->cl_addr)) {
A
Andy Adamson 已提交
2314
			status = nfserr_clid_inuse;
2315
			goto out_free_conn;
A
Andy Adamson 已提交
2316
		}
2317 2318 2319
		status = nfserr_wrong_cred;
		if (!mach_creds_match(unconf, rqstp))
			goto out_free_conn;
2320 2321
		cs_slot = &unconf->cl_cs_slot;
		status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0);
2322 2323
		if (status) {
			/* an unconfirmed replay returns misordered */
A
Andy Adamson 已提交
2324
			status = nfserr_seq_misordered;
2325
			goto out_free_conn;
A
Andy Adamson 已提交
2326
		}
2327
		old = find_confirmed_client_by_name(&unconf->cl_name, nn);
2328 2329 2330 2331
		if (old) {
			status = mark_client_expired(old);
			if (status)
				goto out_free_conn;
J
J. Bruce Fields 已提交
2332
			expire_client(old);
2333
		}
J
J. Bruce Fields 已提交
2334
		move_to_confirmed(unconf);
A
Andy Adamson 已提交
2335 2336 2337
		conf = unconf;
	} else {
		status = nfserr_stale_clientid;
2338
		goto out_free_conn;
A
Andy Adamson 已提交
2339
	}
2340
	status = nfs_ok;
2341 2342 2343 2344 2345 2346
	/*
	 * We do not support RDMA or persistent sessions
	 */
	cr_ses->flags &= ~SESSION4_PERSIST;
	cr_ses->flags &= ~SESSION4_RDMA;

2347 2348 2349
	init_session(rqstp, new, conf, cr_ses);
	nfsd4_init_conn(rqstp, conn, new);

2350
	memcpy(cr_ses->sessionid.data, new->se_sessionid.data,
A
Andy Adamson 已提交
2351
	       NFS4_MAX_SESSIONID_LEN);
2352
	cs_slot->sl_seqid++;
2353
	cr_ses->seqid = cs_slot->sl_seqid;
A
Andy Adamson 已提交
2354

2355 2356
	/* cache solo and embedded create sessions under the state lock */
	nfsd4_cache_create_session(cr_ses, cs_slot, status);
A
Andy Adamson 已提交
2357 2358
	nfs4_unlock_state();
	return status;
2359
out_free_conn:
2360
	nfs4_unlock_state();
2361 2362 2363
	free_conn(conn);
out_free_session:
	__free_session(new);
2364 2365
out_release_drc_mem:
	nfsd4_put_drc_mem(&cr_ses->fore_channel);
J
J. Bruce Fields 已提交
2366
	return status;
A
Andy Adamson 已提交
2367 2368
}

2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382
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;
}

2383 2384 2385
__be32 nfsd4_backchannel_ctl(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_backchannel_ctl *bc)
{
	struct nfsd4_session *session = cstate->session;
2386
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
2387
	__be32 status;
2388

2389 2390 2391
	status = nfsd4_check_cb_sec(&bc->bc_cb_sec);
	if (status)
		return status;
2392
	spin_lock(&nn->client_lock);
2393 2394
	session->se_cb_prog = bc->bc_cb_program;
	session->se_cb_sec = bc->bc_cb_sec;
2395
	spin_unlock(&nn->client_lock);
2396 2397 2398 2399 2400 2401

	nfsd4_probe_callback(session->se_client);

	return nfs_ok;
}

2402 2403 2404 2405 2406
__be32 nfsd4_bind_conn_to_session(struct svc_rqst *rqstp,
		     struct nfsd4_compound_state *cstate,
		     struct nfsd4_bind_conn_to_session *bcts)
{
	__be32 status;
2407
	struct nfsd4_conn *conn;
2408
	struct nfsd4_session *session;
2409 2410
	struct net *net = SVC_NET(rqstp);
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
2411 2412 2413

	if (!nfsd4_last_compound_op(rqstp))
		return nfserr_not_only_op;
2414
	nfs4_lock_state();
2415
	spin_lock(&nn->client_lock);
2416
	session = find_in_sessionid_hashtbl(&bcts->sessionid, net, &status);
2417
	spin_unlock(&nn->client_lock);
2418
	if (!session)
2419
		goto out_no_session;
2420 2421 2422
	status = nfserr_wrong_cred;
	if (!mach_creds_match(session->se_client, rqstp))
		goto out;
2423
	status = nfsd4_map_bcts_dir(&bcts->dir);
2424
	if (status)
2425
		goto out;
2426
	conn = alloc_conn(rqstp, bcts->dir);
2427
	status = nfserr_jukebox;
2428
	if (!conn)
2429 2430 2431 2432
		goto out;
	nfsd4_init_conn(rqstp, conn, session);
	status = nfs_ok;
out:
2433 2434
	nfsd4_put_session(session);
out_no_session:
2435 2436
	nfs4_unlock_state();
	return status;
2437 2438
}

2439 2440 2441 2442 2443 2444 2445
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 已提交
2446 2447 2448 2449 2450
__be32
nfsd4_destroy_session(struct svc_rqst *r,
		      struct nfsd4_compound_state *cstate,
		      struct nfsd4_destroy_session *sessionid)
{
B
Benny Halevy 已提交
2451
	struct nfsd4_session *ses;
2452
	__be32 status;
2453
	int ref_held_by_me = 0;
2454 2455
	struct net *net = SVC_NET(r);
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
B
Benny Halevy 已提交
2456

2457 2458
	nfs4_lock_state();
	status = nfserr_not_only_op;
2459
	if (nfsd4_compound_in_session(cstate->session, &sessionid->sessionid)) {
2460
		if (!nfsd4_last_compound_op(r))
2461
			goto out;
2462
		ref_held_by_me++;
2463
	}
B
Benny Halevy 已提交
2464
	dump_sessionid(__func__, &sessionid->sessionid);
2465
	spin_lock(&nn->client_lock);
2466
	ses = find_in_sessionid_hashtbl(&sessionid->sessionid, net, &status);
2467 2468
	if (!ses)
		goto out_client_lock;
2469 2470
	status = nfserr_wrong_cred;
	if (!mach_creds_match(ses->se_client, r))
2471
		goto out_put_session;
2472
	status = mark_session_dead_locked(ses, 1 + ref_held_by_me);
2473
	if (status)
2474
		goto out_put_session;
B
Benny Halevy 已提交
2475
	unhash_session(ses);
2476
	spin_unlock(&nn->client_lock);
B
Benny Halevy 已提交
2477

2478
	nfsd4_probe_callback_sync(ses->se_client);
2479

2480
	spin_lock(&nn->client_lock);
B
Benny Halevy 已提交
2481
	status = nfs_ok;
2482
out_put_session:
2483
	nfsd4_put_session_locked(ses);
2484 2485
out_client_lock:
	spin_unlock(&nn->client_lock);
B
Benny Halevy 已提交
2486
out:
2487
	nfs4_unlock_state();
B
Benny Halevy 已提交
2488
	return status;
A
Andy Adamson 已提交
2489 2490
}

2491
static struct nfsd4_conn *__nfsd4_find_conn(struct svc_xprt *xpt, struct nfsd4_session *s)
2492 2493 2494 2495
{
	struct nfsd4_conn *c;

	list_for_each_entry(c, &s->se_conns, cn_persession) {
2496
		if (c->cn_xprt == xpt) {
2497 2498 2499 2500 2501 2502
			return c;
		}
	}
	return NULL;
}

2503
static __be32 nfsd4_sequence_check_conn(struct nfsd4_conn *new, struct nfsd4_session *ses)
2504 2505
{
	struct nfs4_client *clp = ses->se_client;
2506
	struct nfsd4_conn *c;
2507
	__be32 status = nfs_ok;
2508
	int ret;
2509 2510

	spin_lock(&clp->cl_lock);
2511
	c = __nfsd4_find_conn(new->cn_xprt, ses);
2512 2513 2514 2515 2516
	if (c)
		goto out_free;
	status = nfserr_conn_not_bound_to_session;
	if (clp->cl_mach_cred)
		goto out_free;
2517 2518
	__nfsd4_hash_conn(new, ses);
	spin_unlock(&clp->cl_lock);
2519 2520 2521 2522
	ret = nfsd4_register_conn(new);
	if (ret)
		/* oops; xprt is already down: */
		nfsd4_conn_lost(&new->cn_xpt_user);
2523 2524 2525 2526 2527
	return nfs_ok;
out_free:
	spin_unlock(&clp->cl_lock);
	free_conn(new);
	return status;
2528 2529
}

2530 2531 2532 2533 2534 2535 2536
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 已提交
2537 2538 2539 2540 2541 2542 2543 2544
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 已提交
2545
__be32
B
Benny Halevy 已提交
2546
nfsd4_sequence(struct svc_rqst *rqstp,
A
Andy Adamson 已提交
2547 2548 2549
	       struct nfsd4_compound_state *cstate,
	       struct nfsd4_sequence *seq)
{
2550
	struct nfsd4_compoundres *resp = rqstp->rq_resp;
2551
	struct xdr_stream *xdr = &resp->xdr;
B
Benny Halevy 已提交
2552
	struct nfsd4_session *session;
2553
	struct nfs4_client *clp;
B
Benny Halevy 已提交
2554
	struct nfsd4_slot *slot;
2555
	struct nfsd4_conn *conn;
J
J. Bruce Fields 已提交
2556
	__be32 status;
2557
	int buflen;
2558 2559
	struct net *net = SVC_NET(rqstp);
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
B
Benny Halevy 已提交
2560

2561 2562 2563
	if (resp->opcnt != 1)
		return nfserr_sequence_pos;

2564 2565 2566 2567 2568 2569 2570 2571
	/*
	 * Will be either used or freed by nfsd4_sequence_check_conn
	 * below.
	 */
	conn = alloc_conn(rqstp, NFS4_CDFC4_FORE);
	if (!conn)
		return nfserr_jukebox;

2572
	spin_lock(&nn->client_lock);
2573
	session = find_in_sessionid_hashtbl(&seq->sessionid, net, &status);
B
Benny Halevy 已提交
2574
	if (!session)
2575 2576
		goto out_no_session;
	clp = session->se_client;
B
Benny Halevy 已提交
2577

2578 2579
	status = nfserr_too_many_ops;
	if (nfsd4_session_too_many_ops(rqstp, session))
2580
		goto out_put_session;
2581

M
Mi Jinlong 已提交
2582 2583
	status = nfserr_req_too_big;
	if (nfsd4_request_too_big(rqstp, session))
2584
		goto out_put_session;
M
Mi Jinlong 已提交
2585

B
Benny Halevy 已提交
2586
	status = nfserr_badslot;
2587
	if (seq->slotid >= session->se_fchannel.maxreqs)
2588
		goto out_put_session;
B
Benny Halevy 已提交
2589

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

2593 2594 2595 2596 2597
	/* 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;

2598 2599
	status = check_slot_seqid(seq->seqid, slot->sl_seqid,
					slot->sl_flags & NFSD4_SLOT_INUSE);
B
Benny Halevy 已提交
2600
	if (status == nfserr_replay_cache) {
2601 2602
		status = nfserr_seq_misordered;
		if (!(slot->sl_flags & NFSD4_SLOT_INITIALIZED))
2603
			goto out_put_session;
B
Benny Halevy 已提交
2604 2605
		cstate->slot = slot;
		cstate->session = session;
2606
		cstate->clp = clp;
A
Andy Adamson 已提交
2607
		/* Return the cached reply status and set cstate->status
2608
		 * for nfsd4_proc_compound processing */
2609
		status = nfsd4_replay_cache_entry(resp, seq);
A
Andy Adamson 已提交
2610
		cstate->status = nfserr_replay_cache;
2611
		goto out;
B
Benny Halevy 已提交
2612 2613
	}
	if (status)
2614
		goto out_put_session;
B
Benny Halevy 已提交
2615

2616
	status = nfsd4_sequence_check_conn(conn, session);
2617
	conn = NULL;
2618 2619
	if (status)
		goto out_put_session;
2620

2621 2622 2623 2624 2625
	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;
2626
	if (xdr_restrict_buflen(xdr, buflen - rqstp->rq_auth_slack))
2627
		goto out_put_session;
2628
	svc_reserve(rqstp, buflen);
2629 2630

	status = nfs_ok;
B
Benny Halevy 已提交
2631 2632
	/* Success! bump slot seqid */
	slot->sl_seqid = seq->seqid;
2633
	slot->sl_flags |= NFSD4_SLOT_INUSE;
2634 2635
	if (seq->cachethis)
		slot->sl_flags |= NFSD4_SLOT_CACHETHIS;
2636 2637
	else
		slot->sl_flags &= ~NFSD4_SLOT_CACHETHIS;
B
Benny Halevy 已提交
2638 2639 2640

	cstate->slot = slot;
	cstate->session = session;
2641
	cstate->clp = clp;
B
Benny Halevy 已提交
2642 2643

out:
2644 2645 2646 2647 2648 2649 2650 2651 2652
	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;
2653
	}
2654 2655
	if (!list_empty(&clp->cl_revoked))
		seq->status_flags |= SEQ4_STATUS_RECALLABLE_STATE_REVOKED;
2656
out_no_session:
2657 2658
	if (conn)
		free_conn(conn);
2659
	spin_unlock(&nn->client_lock);
B
Benny Halevy 已提交
2660
	return status;
2661
out_put_session:
2662
	nfsd4_put_session_locked(session);
2663
	goto out_no_session;
A
Andy Adamson 已提交
2664 2665
}

2666 2667 2668 2669 2670 2671 2672 2673 2674 2675
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;
		}
2676
		/* Drop session reference that was taken in nfsd4_sequence() */
2677
		nfsd4_put_session(cs->session);
2678 2679
	} else if (cs->clp)
		put_client_renew(cs->clp);
2680 2681
}

2682 2683 2684 2685
__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 已提交
2686
	__be32 status = 0;
2687
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
2688 2689

	nfs4_lock_state();
2690
	unconf = find_unconfirmed_client(&dc->clientid, true, nn);
2691
	conf = find_confirmed_client(&dc->clientid, true, nn);
2692
	WARN_ON_ONCE(conf && unconf);
2693 2694 2695 2696

	if (conf) {
		clp = conf;

2697
		if (client_has_state(conf)) {
2698 2699 2700 2701 2702 2703 2704 2705 2706
			status = nfserr_clientid_busy;
			goto out;
		}
	} else if (unconf)
		clp = unconf;
	else {
		status = nfserr_stale_clientid;
		goto out;
	}
2707 2708 2709 2710
	if (!mach_creds_match(clp, rqstp)) {
		status = nfserr_wrong_cred;
		goto out;
	}
2711 2712 2713 2714 2715 2716
	expire_client(clp);
out:
	nfs4_unlock_state();
	return status;
}

2717 2718 2719
__be32
nfsd4_reclaim_complete(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_reclaim_complete *rc)
{
J
J. Bruce Fields 已提交
2720
	__be32 status = 0;
2721

2722 2723 2724 2725 2726 2727 2728 2729 2730
	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;
	}
2731

2732
	nfs4_lock_state();
2733
	status = nfserr_complete_already;
2734 2735
	if (test_and_set_bit(NFSD4_CLIENT_RECLAIM_COMPLETE,
			     &cstate->session->se_client->cl_flags))
2736 2737 2738 2739
		goto out;

	status = nfserr_stale_clientid;
	if (is_client_expired(cstate->session->se_client))
2740 2741 2742 2743 2744 2745 2746
		/*
		 * 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.
		 */
2747 2748 2749
		goto out;

	status = nfs_ok;
2750
	nfsd4_client_record_create(cstate->session->se_client);
2751
out:
2752
	nfs4_unlock_state();
2753
	return status;
2754 2755
}

2756
__be32
2757 2758
nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
		  struct nfsd4_setclientid *setclid)
L
Linus Torvalds 已提交
2759
{
2760
	struct xdr_netobj 	clname = setclid->se_name;
L
Linus Torvalds 已提交
2761
	nfs4_verifier		clverifier = setclid->se_verf;
2762
	struct nfs4_client	*conf, *unconf, *new;
2763
	__be32 			status;
2764 2765
	struct nfsd_net		*nn = net_generic(SVC_NET(rqstp), nfsd_net_id);

2766
	/* Cases below refer to rfc 3530 section 14.2.33: */
L
Linus Torvalds 已提交
2767
	nfs4_lock_state();
2768
	conf = find_confirmed_client_by_name(&clname, nn);
2769
	if (conf) {
2770
		/* case 0: */
L
Linus Torvalds 已提交
2771
		status = nfserr_clid_inuse;
2772 2773
		if (clp_used_exchangeid(conf))
			goto out;
2774
		if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)) {
2775 2776 2777 2778 2779
			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 已提交
2780 2781 2782
			goto out;
		}
	}
2783
	unconf = find_unconfirmed_client_by_name(&clname, nn);
2784 2785
	if (unconf)
		expire_client(unconf);
2786
	status = nfserr_jukebox;
J
Jeff Layton 已提交
2787
	new = create_client(clname, rqstp, &clverifier);
2788 2789
	if (new == NULL)
		goto out;
2790
	if (conf && same_verf(&conf->cl_verifier, &clverifier))
2791
		/* case 1: probable callback update */
L
Linus Torvalds 已提交
2792
		copy_clid(new, conf);
2793
	else /* case 4 (new client) or cases 2, 3 (client reboot): */
2794
		gen_clid(new, nn);
2795
	new->cl_minorversion = 0;
2796
	gen_callback(new, setclid, rqstp);
2797
	add_to_unconfirmed(new);
L
Linus Torvalds 已提交
2798 2799 2800 2801 2802 2803 2804 2805 2806 2807
	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;
}


2808
__be32
2809 2810 2811
nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
			 struct nfsd4_compound_state *cstate,
			 struct nfsd4_setclientid_confirm *setclientid_confirm)
L
Linus Torvalds 已提交
2812
{
2813
	struct nfs4_client *conf, *unconf;
L
Linus Torvalds 已提交
2814 2815
	nfs4_verifier confirm = setclientid_confirm->sc_confirm; 
	clientid_t * clid = &setclientid_confirm->sc_clientid;
2816
	__be32 status;
2817
	struct nfsd_net	*nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
L
Linus Torvalds 已提交
2818

2819
	if (STALE_CLIENTID(clid, nn))
L
Linus Torvalds 已提交
2820 2821
		return nfserr_stale_clientid;
	nfs4_lock_state();
2822

2823
	conf = find_confirmed_client(clid, false, nn);
2824
	unconf = find_unconfirmed_client(clid, false, nn);
2825
	/*
2826 2827 2828 2829
	 * 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.
2830
	 */
2831 2832 2833 2834 2835
	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;
2836
	/* cases below refer to rfc 3530 section 14.2.34: */
2837 2838
	if (!unconf || !same_verf(&confirm, &unconf->cl_confirm)) {
		if (conf && !unconf) /* case 2: probable retransmit */
L
Linus Torvalds 已提交
2839
			status = nfs_ok;
2840 2841 2842 2843 2844 2845
		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 */
2846 2847 2848
		nfsd4_change_callback(conf, &unconf->cl_cb_conn);
		nfsd4_probe_callback(conf);
		expire_client(unconf);
2849
	} else { /* case 3: normal case; new or rebooted client */
2850
		conf = find_confirmed_client_by_name(&unconf->cl_name, nn);
2851 2852 2853 2854
		if (conf) {
			status = mark_client_expired(conf);
			if (status)
				goto out;
2855
			expire_client(conf);
2856
		}
2857
		move_to_confirmed(unconf);
2858
		nfsd4_probe_callback(unconf);
2859
	}
L
Linus Torvalds 已提交
2860 2861 2862 2863 2864
out:
	nfs4_unlock_state();
	return status;
}

2865 2866 2867 2868 2869
static struct nfs4_file *nfsd4_alloc_file(void)
{
	return kmem_cache_alloc(file_slab, GFP_KERNEL);
}

L
Linus Torvalds 已提交
2870
/* OPEN Share state helper functions */
2871
static void nfsd4_init_file(struct nfs4_file *fp, struct knfsd_fh *fh)
L
Linus Torvalds 已提交
2872
{
2873
	unsigned int hashval = file_hashval(fh);
L
Linus Torvalds 已提交
2874

2875 2876
	lockdep_assert_held(&state_lock);

2877
	atomic_set(&fp->fi_ref, 1);
2878
	spin_lock_init(&fp->fi_lock);
2879 2880
	INIT_LIST_HEAD(&fp->fi_stateids);
	INIT_LIST_HEAD(&fp->fi_delegations);
2881
	fh_copy_shallow(&fp->fi_fhandle, fh);
2882 2883
	fp->fi_had_conflict = false;
	fp->fi_lease = NULL;
2884
	fp->fi_share_deny = 0;
2885 2886
	memset(fp->fi_fds, 0, sizeof(fp->fi_fds));
	memset(fp->fi_access, 0, sizeof(fp->fi_access));
2887
	hlist_add_head(&fp->fi_hash, &file_hashtbl[hashval]);
L
Linus Torvalds 已提交
2888 2889
}

2890
void
L
Linus Torvalds 已提交
2891 2892
nfsd4_free_slabs(void)
{
C
Christoph Hellwig 已提交
2893 2894 2895 2896 2897
	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 已提交
2898
}
L
Linus Torvalds 已提交
2899

2900
int
N
NeilBrown 已提交
2901 2902
nfsd4_init_slabs(void)
{
2903 2904 2905
	openowner_slab = kmem_cache_create("nfsd4_openowners",
			sizeof(struct nfs4_openowner), 0, 0, NULL);
	if (openowner_slab == NULL)
C
Christoph Hellwig 已提交
2906
		goto out;
2907
	lockowner_slab = kmem_cache_create("nfsd4_lockowners",
2908
			sizeof(struct nfs4_lockowner), 0, 0, NULL);
2909
	if (lockowner_slab == NULL)
C
Christoph Hellwig 已提交
2910
		goto out_free_openowner_slab;
N
NeilBrown 已提交
2911
	file_slab = kmem_cache_create("nfsd4_files",
2912
			sizeof(struct nfs4_file), 0, 0, NULL);
N
NeilBrown 已提交
2913
	if (file_slab == NULL)
C
Christoph Hellwig 已提交
2914
		goto out_free_lockowner_slab;
N
NeilBrown 已提交
2915
	stateid_slab = kmem_cache_create("nfsd4_stateids",
2916
			sizeof(struct nfs4_ol_stateid), 0, 0, NULL);
N
NeilBrown 已提交
2917
	if (stateid_slab == NULL)
C
Christoph Hellwig 已提交
2918
		goto out_free_file_slab;
N
NeilBrown 已提交
2919
	deleg_slab = kmem_cache_create("nfsd4_delegations",
2920
			sizeof(struct nfs4_delegation), 0, 0, NULL);
N
NeilBrown 已提交
2921
	if (deleg_slab == NULL)
C
Christoph Hellwig 已提交
2922
		goto out_free_stateid_slab;
N
NeilBrown 已提交
2923
	return 0;
C
Christoph Hellwig 已提交
2924 2925 2926 2927 2928 2929 2930 2931 2932 2933

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

2938
static void init_nfs4_replay(struct nfs4_replay *rp)
L
Linus Torvalds 已提交
2939
{
2940 2941 2942
	rp->rp_status = nfserr_serverfault;
	rp->rp_buflen = 0;
	rp->rp_buf = rp->rp_ibuf;
L
Linus Torvalds 已提交
2943 2944
}

2945
static inline void *alloc_stateowner(struct kmem_cache *slab, struct xdr_netobj *owner, struct nfs4_client *clp)
2946
{
L
Linus Torvalds 已提交
2947 2948
	struct nfs4_stateowner *sop;

2949
	sop = kmem_cache_alloc(slab, GFP_KERNEL);
2950 2951 2952 2953 2954
	if (!sop)
		return NULL;

	sop->so_owner.data = kmemdup(owner->data, owner->len, GFP_KERNEL);
	if (!sop->so_owner.data) {
2955
		kmem_cache_free(slab, sop);
L
Linus Torvalds 已提交
2956
		return NULL;
2957 2958 2959
	}
	sop->so_owner.len = owner->len;

2960
	INIT_LIST_HEAD(&sop->so_stateids);
2961 2962 2963 2964 2965
	sop->so_client = clp;
	init_nfs4_replay(&sop->so_replay);
	return sop;
}

2966
static void hash_openowner(struct nfs4_openowner *oo, struct nfs4_client *clp, unsigned int strhashval)
2967
{
2968 2969 2970
	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);

	list_add(&oo->oo_owner.so_strhash, &nn->ownerstr_hashtbl[strhashval]);
2971
	list_add(&oo->oo_perclient, &clp->cl_openowners);
2972 2973
}

2974
static struct nfs4_openowner *
2975
alloc_init_open_stateowner(unsigned int strhashval, struct nfsd4_open *open,
2976 2977
			   struct nfsd4_compound_state *cstate)
{
2978
	struct nfs4_client *clp = cstate->clp;
2979
	struct nfs4_openowner *oo;
2980

2981 2982
	oo = alloc_stateowner(openowner_slab, &open->op_owner, clp);
	if (!oo)
2983
		return NULL;
2984 2985
	oo->oo_owner.so_is_open_owner = 1;
	oo->oo_owner.so_seqid = open->op_seqid;
2986
	oo->oo_flags = NFS4_OO_NEW;
2987 2988
	if (nfsd4_has_session(cstate))
		oo->oo_flags |= NFS4_OO_CONFIRMED;
2989
	oo->oo_time = 0;
2990
	oo->oo_last_closed_stid = NULL;
2991 2992 2993
	INIT_LIST_HEAD(&oo->oo_close_lru);
	hash_openowner(oo, clp, strhashval);
	return oo;
L
Linus Torvalds 已提交
2994 2995
}

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

2999
	atomic_inc(&stp->st_stid.sc_count);
J
J. Bruce Fields 已提交
3000
	stp->st_stid.sc_type = NFS4_OPEN_STID;
3001
	INIT_LIST_HEAD(&stp->st_locks);
3002
	stp->st_stateowner = &oo->oo_owner;
3003
	get_nfs4_file(fp);
3004
	stp->st_stid.sc_file = fp;
L
Linus Torvalds 已提交
3005 3006
	stp->st_access_bmap = 0;
	stp->st_deny_bmap = 0;
3007
	stp->st_openstp = NULL;
3008 3009
	spin_lock(&oo->oo_owner.so_client->cl_lock);
	list_add(&stp->st_perstateowner, &oo->oo_owner.so_stateids);
3010 3011 3012
	spin_lock(&fp->fi_lock);
	list_add(&stp->st_perfile, &fp->fi_stateids);
	spin_unlock(&fp->fi_lock);
3013
	spin_unlock(&oo->oo_owner.so_client->cl_lock);
L
Linus Torvalds 已提交
3014 3015
}

3016
static void
3017
move_to_close_lru(struct nfs4_openowner *oo, struct net *net)
L
Linus Torvalds 已提交
3018
{
3019 3020
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);

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

3023
	list_move_tail(&oo->oo_close_lru, &nn->close_lru);
3024
	oo->oo_time = get_seconds();
L
Linus Torvalds 已提交
3025 3026 3027
}

static int
3028 3029 3030 3031 3032 3033
same_owner_str(struct nfs4_stateowner *sop, struct xdr_netobj *owner,
							clientid_t *clid)
{
	return (sop->so_owner.len == owner->len) &&
		0 == memcmp(sop->so_owner.data, owner->data, owner->len) &&
		(sop->so_client->cl_clientid.cl_id == clid->cl_id);
L
Linus Torvalds 已提交
3034 3035
}

3036
static struct nfs4_openowner *
3037 3038
find_openstateowner_str(unsigned int hashval, struct nfsd4_open *open,
			bool sessions, struct nfsd_net *nn)
L
Linus Torvalds 已提交
3039
{
3040 3041
	struct nfs4_stateowner *so;
	struct nfs4_openowner *oo;
3042
	struct nfs4_client *clp;
L
Linus Torvalds 已提交
3043

3044
	list_for_each_entry(so, &nn->ownerstr_hashtbl[hashval], so_strhash) {
3045 3046
		if (!so->so_is_open_owner)
			continue;
3047 3048
		if (same_owner_str(so, &open->op_owner, &open->op_clientid)) {
			oo = openowner(so);
3049 3050 3051
			clp = oo->oo_owner.so_client;
			if ((bool)clp->cl_minorversion != sessions)
				return NULL;
3052 3053 3054
			renew_client(oo->oo_owner.so_client);
			return oo;
		}
L
Linus Torvalds 已提交
3055 3056 3057 3058 3059 3060
	}
	return NULL;
}

/* search file_hashtbl[] for file */
static struct nfs4_file *
3061
find_file_locked(struct knfsd_fh *fh)
L
Linus Torvalds 已提交
3062
{
3063
	unsigned int hashval = file_hashval(fh);
L
Linus Torvalds 已提交
3064 3065
	struct nfs4_file *fp;

3066 3067
	lockdep_assert_held(&state_lock);

3068
	hlist_for_each_entry(fp, &file_hashtbl[hashval], fi_hash) {
3069
		if (nfsd_fh_match(&fp->fi_fhandle, fh)) {
3070
			get_nfs4_file(fp);
L
Linus Torvalds 已提交
3071
			return fp;
3072
		}
L
Linus Torvalds 已提交
3073 3074 3075 3076
	}
	return NULL;
}

3077
static struct nfs4_file *
3078
find_file(struct knfsd_fh *fh)
3079 3080 3081 3082
{
	struct nfs4_file *fp;

	spin_lock(&state_lock);
3083
	fp = find_file_locked(fh);
3084 3085 3086 3087 3088
	spin_unlock(&state_lock);
	return fp;
}

static struct nfs4_file *
3089
find_or_add_file(struct nfs4_file *new, struct knfsd_fh *fh)
3090 3091 3092 3093
{
	struct nfs4_file *fp;

	spin_lock(&state_lock);
3094
	fp = find_file_locked(fh);
3095
	if (fp == NULL) {
3096
		nfsd4_init_file(new, fh);
3097 3098 3099 3100 3101 3102 3103
		fp = new;
	}
	spin_unlock(&state_lock);

	return fp;
}

L
Linus Torvalds 已提交
3104 3105 3106 3107
/*
 * Called to check deny when READ with all zero stateid or
 * WRITE with all zero or all one stateid
 */
3108
static __be32
L
Linus Torvalds 已提交
3109 3110 3111
nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type)
{
	struct nfs4_file *fp;
3112
	__be32 ret = nfs_ok;
L
Linus Torvalds 已提交
3113

3114
	fp = find_file(&current_fh->fh_handle);
3115
	if (!fp)
3116 3117
		return ret;
	/* Check for conflicting share reservations */
3118
	spin_lock(&fp->fi_lock);
3119 3120
	if (fp->fi_share_deny & deny_type)
		ret = nfserr_locked;
3121
	spin_unlock(&fp->fi_lock);
3122 3123
	put_nfs4_file(fp);
	return ret;
L
Linus Torvalds 已提交
3124 3125
}

3126
void nfsd4_prepare_cb_recall(struct nfs4_delegation *dp)
L
Linus Torvalds 已提交
3127
{
3128 3129
	struct nfsd_net *nn = net_generic(dp->dl_stid.sc_client->net,
					  nfsd_net_id);
3130

3131
	block_delegations(&dp->dl_stid.sc_file->fi_fhandle);
3132

3133
	/*
3134 3135 3136
	 * We can't do this in nfsd_break_deleg_cb because it is
	 * already holding inode->i_lock.
	 *
3137 3138 3139
	 * If the dl_time != 0, then we know that it has already been
	 * queued for a lease break. Don't queue it again.
	 */
3140
	spin_lock(&state_lock);
3141 3142
	if (dp->dl_time == 0) {
		dp->dl_time = get_seconds();
3143
		list_add_tail(&dp->dl_recall_lru, &nn->del_recall_lru);
3144
	}
3145 3146
	spin_unlock(&state_lock);
}
L
Linus Torvalds 已提交
3147

3148 3149 3150 3151 3152 3153 3154 3155 3156
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.
	 */
3157
	atomic_inc(&dp->dl_stid.sc_count);
3158 3159 3160
	nfsd4_cb_recall(dp);
}

3161
/* Called from break_lease() with i_lock held. */
3162 3163
static void nfsd_break_deleg_cb(struct file_lock *fl)
{
3164 3165
	struct nfs4_file *fp = (struct nfs4_file *)fl->fl_owner;
	struct nfs4_delegation *dp;
3166

3167 3168 3169 3170 3171 3172 3173 3174
	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;
	}
3175 3176
	/*
	 * We don't want the locks code to timeout the lease for us;
3177
	 * we'll remove it ourself if a delegation isn't returned
3178
	 * in time:
3179 3180
	 */
	fl->fl_break_time = 0;
L
Linus Torvalds 已提交
3181

3182
	spin_lock(&fp->fi_lock);
3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194
	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);
3195
	spin_unlock(&fp->fi_lock);
L
Linus Torvalds 已提交
3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206
}

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

3207
static const struct lock_manager_operations nfsd_lease_mng_ops = {
J
J. Bruce Fields 已提交
3208 3209
	.lm_break = nfsd_break_deleg_cb,
	.lm_change = nfsd_change_deleg_cb,
L
Linus Torvalds 已提交
3210 3211
};

3212 3213 3214 3215 3216 3217 3218 3219 3220 3221
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 已提交
3222

3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254
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;
}

3255
__be32
A
Andy Adamson 已提交
3256
nfsd4_process_open1(struct nfsd4_compound_state *cstate,
3257
		    struct nfsd4_open *open, struct nfsd_net *nn)
L
Linus Torvalds 已提交
3258 3259 3260 3261
{
	clientid_t *clientid = &open->op_clientid;
	struct nfs4_client *clp = NULL;
	unsigned int strhashval;
3262
	struct nfs4_openowner *oo = NULL;
3263
	__be32 status;
L
Linus Torvalds 已提交
3264

3265
	if (STALE_CLIENTID(&open->op_clientid, nn))
L
Linus Torvalds 已提交
3266
		return nfserr_stale_clientid;
3267 3268 3269 3270 3271 3272 3273
	/*
	 * 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 已提交
3274

3275 3276 3277 3278 3279
	status = lookup_clientid(clientid, cstate, nn);
	if (status)
		return status;
	clp = cstate->clp;

3280
	strhashval = ownerstr_hashval(clientid->cl_id, &open->op_owner);
3281
	oo = find_openstateowner_str(strhashval, open, cstate->minorversion, nn);
3282 3283
	open->op_openowner = oo;
	if (!oo) {
3284
		goto new_owner;
L
Linus Torvalds 已提交
3285
	}
3286
	if (!(oo->oo_flags & NFS4_OO_CONFIRMED)) {
3287
		/* Replace unconfirmed owners without checking for replay. */
3288 3289
		release_openowner(oo);
		open->op_openowner = NULL;
3290
		goto new_owner;
3291
	}
3292 3293 3294 3295
	status = nfsd4_check_seqid(cstate, &oo->oo_owner, open->op_seqid);
	if (status)
		return status;
	goto alloc_stateid;
3296
new_owner:
3297
	oo = alloc_init_open_stateowner(strhashval, open, cstate);
3298 3299 3300
	if (oo == NULL)
		return nfserr_jukebox;
	open->op_openowner = oo;
3301
alloc_stateid:
3302
	open->op_stp = nfs4_alloc_open_stateid(clp);
3303 3304
	if (!open->op_stp)
		return nfserr_jukebox;
3305
	return nfs_ok;
L
Linus Torvalds 已提交
3306 3307
}

3308
static inline __be32
N
NeilBrown 已提交
3309 3310 3311 3312 3313 3314 3315 3316
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;
}

3317
static int share_access_to_flags(u32 share_access)
3318
{
3319
	return share_access == NFS4_SHARE_ACCESS_READ ? RD_STATE : WR_STATE;
3320 3321
}

3322
static struct nfs4_delegation *find_deleg_stateid(struct nfs4_client *cl, stateid_t *s)
3323
{
3324
	struct nfs4_stid *ret;
3325

3326
	ret = find_stateid_by_type(cl, s, NFS4_DELEG_STID);
3327 3328
	if (!ret)
		return NULL;
3329 3330
	/* FIXME: move into find_stateid_by_type */
	atomic_inc(&ret->sc_count);
3331
	return delegstateid(ret);
3332 3333
}

3334 3335 3336 3337 3338 3339
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;
}

3340
static __be32
3341
nfs4_check_deleg(struct nfs4_client *cl, struct nfsd4_open *open,
3342 3343 3344
		struct nfs4_delegation **dp)
{
	int flags;
3345
	__be32 status = nfserr_bad_stateid;
3346
	struct nfs4_delegation *deleg;
3347

3348 3349
	deleg = find_deleg_stateid(cl, &open->op_delegate_stateid);
	if (deleg == NULL)
3350
		goto out;
3351
	flags = share_access_to_flags(open->op_share_access);
3352 3353 3354 3355 3356 3357
	status = nfs4_check_delegmode(deleg, flags);
	if (status) {
		nfs4_put_stid(&deleg->dl_stid);
		goto out;
	}
	*dp = deleg;
3358
out:
3359
	if (!nfsd4_is_deleg_cur(open))
3360 3361 3362
		return nfs_ok;
	if (status)
		return status;
3363
	open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
3364
	return nfs_ok;
3365 3366
}

3367 3368
static struct nfs4_ol_stateid *
nfsd4_find_existing_open(struct nfs4_file *fp, struct nfsd4_open *open)
L
Linus Torvalds 已提交
3369
{
3370
	struct nfs4_ol_stateid *local, *ret = NULL;
3371
	struct nfs4_openowner *oo = open->op_openowner;
L
Linus Torvalds 已提交
3372

3373
	spin_lock(&fp->fi_lock);
3374
	list_for_each_entry(local, &fp->fi_stateids, st_perfile) {
L
Linus Torvalds 已提交
3375 3376 3377
		/* ignore lock owners */
		if (local->st_stateowner->so_is_open_owner == 0)
			continue;
3378
		if (local->st_stateowner == &oo->oo_owner) {
3379
			ret = local;
3380
			atomic_inc(&ret->st_stid.sc_count);
3381
			break;
3382
		}
L
Linus Torvalds 已提交
3383
	}
3384
	spin_unlock(&fp->fi_lock);
3385
	return ret;
L
Linus Torvalds 已提交
3386 3387
}

3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398
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;
}

3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413
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);
}

3414
static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file *fp,
3415 3416
		struct svc_fh *cur_fh, struct nfs4_ol_stateid *stp,
		struct nfsd4_open *open)
3417
{
3418
	struct file *filp = NULL;
3419
	__be32 status;
3420 3421
	int oflag = nfs4_access_to_omode(open->op_share_access);
	int access = nfs4_access_to_access(open->op_share_access);
3422
	unsigned char old_access_bmap, old_deny_bmap;
3423

3424
	spin_lock(&fp->fi_lock);
3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451

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

3452
	if (!fp->fi_fds[oflag]) {
3453 3454
		spin_unlock(&fp->fi_lock);
		status = nfsd_open(rqstp, cur_fh, S_IFREG, access, &filp);
3455
		if (status)
3456
			goto out_put_access;
3457 3458 3459 3460 3461
		spin_lock(&fp->fi_lock);
		if (!fp->fi_fds[oflag]) {
			fp->fi_fds[oflag] = filp;
			filp = NULL;
		}
3462
	}
3463 3464 3465
	spin_unlock(&fp->fi_lock);
	if (filp)
		fput(filp);
3466

3467 3468 3469 3470 3471
	status = nfsd4_truncate(rqstp, cur_fh, open);
	if (status)
		goto out_put_access;
out:
	return status;
3472 3473 3474 3475 3476
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 已提交
3477 3478
}

3479
static __be32
3480
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 已提交
3481
{
3482
	__be32 status;
3483
	unsigned char old_deny_bmap;
L
Linus Torvalds 已提交
3484

3485
	if (!test_access(open->op_share_access, stp))
3486
		return nfs4_get_vfs_file(rqstp, fp, cur_fh, stp, open);
3487

3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499
	/* 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 已提交
3500 3501
		return status;

3502 3503 3504 3505 3506
	status = nfsd4_truncate(rqstp, cur_fh, open);
	if (status != nfs_ok)
		reset_union_bmap_deny(old_deny_bmap, stp);
	return status;
}
L
Linus Torvalds 已提交
3507 3508

static void
3509
nfs4_set_claim_prev(struct nfsd4_open *open, bool has_session)
L
Linus Torvalds 已提交
3510
{
3511
	open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
L
Linus Torvalds 已提交
3512 3513
}

3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526
/* 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;
}

3527
static struct file_lock *nfs4_alloc_init_lease(struct nfs4_file *fp, int flag)
3528 3529 3530 3531 3532 3533 3534 3535
{
	struct file_lock *fl;

	fl = locks_alloc_lock();
	if (!fl)
		return NULL;
	locks_init_lock(fl);
	fl->fl_lmops = &nfsd_lease_mng_ops;
3536
	fl->fl_flags = FL_DELEG;
3537 3538
	fl->fl_type = flag == NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_WRLCK;
	fl->fl_end = OFFSET_MAX;
3539
	fl->fl_owner = (fl_owner_t)fp;
3540 3541 3542 3543
	fl->fl_pid = current->tgid;
	return fl;
}

3544
static int nfs4_setlease(struct nfs4_delegation *dp)
3545
{
3546
	struct nfs4_file *fp = dp->dl_stid.sc_file;
3547
	struct file_lock *fl;
3548 3549
	struct file *filp;
	int status = 0;
3550

3551
	fl = nfs4_alloc_init_lease(fp, NFS4_OPEN_DELEGATE_READ);
3552 3553
	if (!fl)
		return -ENOMEM;
3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578
	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;
	}
3579
	fp->fi_lease = fl;
3580
	fp->fi_deleg_file = filp;
3581
	atomic_set(&fp->fi_delegees, 1);
3582
	hash_delegation_locked(dp, fp);
3583
	spin_unlock(&fp->fi_lock);
3584
	spin_unlock(&state_lock);
3585
	return 0;
3586 3587 3588 3589 3590
out_unlock:
	spin_unlock(&fp->fi_lock);
	spin_unlock(&state_lock);
out_fput:
	fput(filp);
3591
	return status;
3592 3593
}

J
Jeff Layton 已提交
3594 3595 3596
static struct nfs4_delegation *
nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh,
		    struct nfs4_file *fp)
3597
{
J
Jeff Layton 已提交
3598 3599
	int status;
	struct nfs4_delegation *dp;
3600

3601
	if (fp->fi_had_conflict)
J
Jeff Layton 已提交
3602 3603 3604 3605 3606 3607
		return ERR_PTR(-EAGAIN);

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

3608
	get_nfs4_file(fp);
3609 3610
	spin_lock(&state_lock);
	spin_lock(&fp->fi_lock);
3611
	dp->dl_stid.sc_file = fp;
3612 3613 3614
	if (!fp->fi_lease) {
		spin_unlock(&fp->fi_lock);
		spin_unlock(&state_lock);
J
Jeff Layton 已提交
3615 3616
		status = nfs4_setlease(dp);
		goto out;
3617
	}
3618
	atomic_inc(&fp->fi_delegees);
3619
	if (fp->fi_had_conflict) {
3620 3621
		status = -EAGAIN;
		goto out_unlock;
3622
	}
3623
	hash_delegation_locked(dp, fp);
J
Jeff Layton 已提交
3624
	status = 0;
3625 3626
out_unlock:
	spin_unlock(&fp->fi_lock);
3627
	spin_unlock(&state_lock);
J
Jeff Layton 已提交
3628 3629
out:
	if (status) {
3630
		nfs4_put_stid(&dp->dl_stid);
J
Jeff Layton 已提交
3631 3632 3633
		return ERR_PTR(status);
	}
	return dp;
3634 3635
}

3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651
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:
3652
			WARN_ON_ONCE(1);
3653 3654 3655 3656
		}
	}
}

L
Linus Torvalds 已提交
3657 3658
/*
 * Attempt to hand out a delegation.
3659 3660 3661
 *
 * Note we don't support write delegations, and won't until the vfs has
 * proper support for them.
L
Linus Torvalds 已提交
3662 3663
 */
static void
3664 3665
nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open,
			struct nfs4_ol_stateid *stp)
L
Linus Torvalds 已提交
3666 3667
{
	struct nfs4_delegation *dp;
3668 3669
	struct nfs4_openowner *oo = openowner(stp->st_stateowner);
	struct nfs4_client *clp = stp->st_stid.sc_client;
3670
	int cb_up;
3671
	int status = 0;
L
Linus Torvalds 已提交
3672

3673
	cb_up = nfsd4_cb_channel_good(oo->oo_owner.so_client);
3674 3675 3676
	open->op_recall = 0;
	switch (open->op_claim_type) {
		case NFS4_OPEN_CLAIM_PREVIOUS:
3677
			if (!cb_up)
3678
				open->op_recall = 1;
3679 3680
			if (open->op_delegate_type != NFS4_OPEN_DELEGATE_READ)
				goto out_no_deleg;
3681 3682
			break;
		case NFS4_OPEN_CLAIM_NULL:
3683
		case NFS4_OPEN_CLAIM_FH:
3684 3685 3686 3687
			/*
			 * Let's not give out any delegations till everyone's
			 * had the chance to reclaim theirs....
			 */
3688
			if (locks_in_grace(clp->net))
3689
				goto out_no_deleg;
3690
			if (!cb_up || !(oo->oo_flags & NFS4_OO_CONFIRMED))
3691
				goto out_no_deleg;
3692 3693 3694 3695 3696 3697 3698
			/*
			 * 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):
			 */
3699
			if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
3700 3701 3702
				goto out_no_deleg;
			if (open->op_create == NFS4_OPEN_CREATE)
				goto out_no_deleg;
3703 3704
			break;
		default:
3705
			goto out_no_deleg;
3706
	}
3707
	dp = nfs4_set_delegation(clp, fh, stp->st_stid.sc_file);
J
Jeff Layton 已提交
3708
	if (IS_ERR(dp))
3709
		goto out_no_deleg;
L
Linus Torvalds 已提交
3710

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

3713
	dprintk("NFSD: delegation stateid=" STATEID_FMT "\n",
3714
		STATEID_VAL(&dp->dl_stid.sc_stateid));
3715
	open->op_delegate_type = NFS4_OPEN_DELEGATE_READ;
3716
	nfs4_put_stid(&dp->dl_stid);
3717 3718
	return;
out_no_deleg:
3719 3720
	open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE;
	if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS &&
3721
	    open->op_delegate_type != NFS4_OPEN_DELEGATE_NONE) {
3722
		dprintk("NFSD: WARNING: refusing delegation reclaim\n");
3723 3724
		open->op_recall = 1;
	}
3725 3726 3727 3728 3729

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

3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749
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 已提交
3750 3751 3752
/*
 * called with nfs4_lock_state() held.
 */
3753
__be32
L
Linus Torvalds 已提交
3754 3755
nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
{
A
Andy Adamson 已提交
3756
	struct nfsd4_compoundres *resp = rqstp->rq_resp;
3757
	struct nfs4_client *cl = open->op_openowner->oo_owner.so_client;
L
Linus Torvalds 已提交
3758
	struct nfs4_file *fp = NULL;
3759
	struct nfs4_ol_stateid *stp = NULL;
3760
	struct nfs4_delegation *dp = NULL;
3761
	__be32 status;
L
Linus Torvalds 已提交
3762 3763 3764 3765 3766 3767

	/*
	 * 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
	 */
3768
	fp = find_or_add_file(open->op_file, &current_fh->fh_handle);
3769
	if (fp != open->op_file) {
3770
		status = nfs4_check_deleg(cl, open, &dp);
3771 3772
		if (status)
			goto out;
3773
		stp = nfsd4_find_existing_open(fp, open);
L
Linus Torvalds 已提交
3774
	} else {
3775
		open->op_file = NULL;
3776
		status = nfserr_bad_stateid;
3777
		if (nfsd4_is_deleg_cur(open))
3778
			goto out;
3779
		status = nfserr_jukebox;
L
Linus Torvalds 已提交
3780 3781 3782 3783 3784 3785 3786 3787
	}

	/*
	 * OPEN the file, or upgrade an existing OPEN.
	 * If truncate fails, the OPEN fails.
	 */
	if (stp) {
		/* Stateid was found, this is an OPEN upgrade */
3788
		status = nfs4_upgrade_open(rqstp, fp, current_fh, stp, open);
L
Linus Torvalds 已提交
3789 3790 3791
		if (status)
			goto out;
	} else {
3792 3793
		stp = open->op_stp;
		open->op_stp = NULL;
3794
		init_open_stateid(stp, fp, open);
3795 3796 3797 3798 3799
		status = nfs4_get_vfs_file(rqstp, fp, current_fh, stp, open);
		if (status) {
			release_open_stateid(stp);
			goto out;
		}
L
Linus Torvalds 已提交
3800
	}
3801 3802
	update_stateid(&stp->st_stid.sc_stateid);
	memcpy(&open->op_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
L
Linus Torvalds 已提交
3803

3804 3805 3806 3807 3808 3809 3810 3811
	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 已提交
3812 3813 3814 3815
	/*
	* Attempt to hand out a delegation. No error return, because the
	* OPEN succeeds even if we fail.
	*/
3816
	nfs4_open_delegation(current_fh, open, stp);
3817
nodeleg:
L
Linus Torvalds 已提交
3818 3819
	status = nfs_ok;

3820
	dprintk("%s: stateid=" STATEID_FMT "\n", __func__,
3821
		STATEID_VAL(&stp->st_stid.sc_stateid));
L
Linus Torvalds 已提交
3822
out:
3823 3824
	/* 4.1 client trying to upgrade/downgrade delegation? */
	if (open->op_delegate_type == NFS4_OPEN_DELEGATE_NONE && dp &&
3825 3826
	    open->op_deleg_want)
		nfsd4_deleg_xgrade_none_ext(open, dp);
3827

3828 3829
	if (fp)
		put_nfs4_file(fp);
3830
	if (status == 0 && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
3831
		nfs4_set_claim_prev(open, nfsd4_has_session(&resp->cstate));
L
Linus Torvalds 已提交
3832 3833 3834 3835
	/*
	* To finish the open response, we just need to set the rflags.
	*/
	open->op_rflags = NFS4_OPEN_RESULT_LOCKTYPE_POSIX;
3836
	if (!(open->op_openowner->oo_flags & NFS4_OO_CONFIRMED) &&
A
Andy Adamson 已提交
3837
	    !nfsd4_has_session(&resp->cstate))
L
Linus Torvalds 已提交
3838
		open->op_rflags |= NFS4_OPEN_RESULT_CONFIRM;
3839 3840
	if (dp)
		nfs4_put_stid(&dp->dl_stid);
3841 3842
	if (stp)
		nfs4_put_stid(&stp->st_stid);
L
Linus Torvalds 已提交
3843 3844 3845 3846

	return status;
}

3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861
void nfsd4_cleanup_open_state(struct nfsd4_open *open, __be32 status)
{
	if (open->op_openowner) {
		struct nfs4_openowner *oo = open->op_openowner;

		if (!list_empty(&oo->oo_owner.so_stateids))
			list_del_init(&oo->oo_close_lru);
		if (oo->oo_flags & NFS4_OO_NEW) {
			if (status) {
				release_openowner(oo);
				open->op_openowner = NULL;
			} else
				oo->oo_flags &= ~NFS4_OO_NEW;
		}
	}
3862 3863
	if (open->op_file)
		nfsd4_free_file(open->op_file);
3864
	if (open->op_stp)
3865
		nfs4_put_stid(&open->op_stp->st_stid);
3866 3867
}

3868
__be32
3869 3870
nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	    clientid_t *clid)
L
Linus Torvalds 已提交
3871 3872
{
	struct nfs4_client *clp;
3873
	__be32 status;
3874
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
L
Linus Torvalds 已提交
3875 3876 3877 3878

	nfs4_lock_state();
	dprintk("process_renew(%08x/%08x): starting\n", 
			clid->cl_boot, clid->cl_id);
3879
	status = lookup_clientid(clid, cstate, nn);
3880
	if (status)
L
Linus Torvalds 已提交
3881
		goto out;
3882
	clp = cstate->clp;
L
Linus Torvalds 已提交
3883
	status = nfserr_cb_path_down;
3884
	if (!list_empty(&clp->cl_delegations)
3885
			&& clp->cl_cb_state != NFSD4_CB_UP)
L
Linus Torvalds 已提交
3886 3887 3888 3889 3890 3891 3892
		goto out;
	status = nfs_ok;
out:
	nfs4_unlock_state();
	return status;
}

3893
static void
3894
nfsd4_end_grace(struct nfsd_net *nn)
3895
{
3896
	/* do nothing if grace period already ended */
3897
	if (nn->grace_ended)
3898 3899
		return;

3900
	dprintk("NFSD: end of grace period\n");
3901
	nn->grace_ended = true;
3902
	nfsd4_record_grace_done(nn, nn->boot_time);
3903
	locks_end_grace(&nn->nfsd4_manager);
3904 3905 3906 3907 3908
	/*
	 * 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:
	 */
3909
	nn->nfsd4_grace = nn->nfsd4_lease;
3910 3911
}

3912
static time_t
3913
nfs4_laundromat(struct nfsd_net *nn)
L
Linus Torvalds 已提交
3914 3915
{
	struct nfs4_client *clp;
3916
	struct nfs4_openowner *oo;
L
Linus Torvalds 已提交
3917 3918
	struct nfs4_delegation *dp;
	struct list_head *pos, *next, reaplist;
3919
	time_t cutoff = get_seconds() - nn->nfsd4_lease;
3920
	time_t t, new_timeo = nn->nfsd4_lease;
L
Linus Torvalds 已提交
3921 3922 3923 3924

	nfs4_lock_state();

	dprintk("NFSD: laundromat service - starting\n");
3925
	nfsd4_end_grace(nn);
3926
	INIT_LIST_HEAD(&reaplist);
3927
	spin_lock(&nn->client_lock);
3928
	list_for_each_safe(pos, next, &nn->client_lru) {
L
Linus Torvalds 已提交
3929 3930 3931
		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;
3932
			new_timeo = min(new_timeo, t);
L
Linus Torvalds 已提交
3933 3934
			break;
		}
3935
		if (mark_client_expired_locked(clp)) {
3936 3937 3938 3939
			dprintk("NFSD: client in use (clientid %08x)\n",
				clp->cl_clientid.cl_id);
			continue;
		}
3940
		list_move(&clp->cl_lru, &reaplist);
3941
	}
3942
	spin_unlock(&nn->client_lock);
3943 3944
	list_for_each_safe(pos, next, &reaplist) {
		clp = list_entry(pos, struct nfs4_client, cl_lru);
L
Linus Torvalds 已提交
3945 3946 3947 3948
		dprintk("NFSD: purging unused client (clientid %08x)\n",
			clp->cl_clientid.cl_id);
		expire_client(clp);
	}
3949
	spin_lock(&state_lock);
3950
	list_for_each_safe(pos, next, &nn->del_recall_lru) {
L
Linus Torvalds 已提交
3951
		dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
3952 3953
		if (net_generic(dp->dl_stid.sc_client->net, nfsd_net_id) != nn)
			continue;
L
Linus Torvalds 已提交
3954
		if (time_after((unsigned long)dp->dl_time, (unsigned long)cutoff)) {
3955 3956
			t = dp->dl_time - cutoff;
			new_timeo = min(new_timeo, t);
L
Linus Torvalds 已提交
3957 3958
			break;
		}
3959 3960
		unhash_delegation_locked(dp);
		list_add(&dp->dl_recall_lru, &reaplist);
L
Linus Torvalds 已提交
3961
	}
3962
	spin_unlock(&state_lock);
3963 3964 3965 3966
	while (!list_empty(&reaplist)) {
		dp = list_first_entry(&reaplist, struct nfs4_delegation,
					dl_recall_lru);
		list_del_init(&dp->dl_recall_lru);
3967
		revoke_delegation(dp);
L
Linus Torvalds 已提交
3968
	}
3969
	list_for_each_safe(pos, next, &nn->close_lru) {
3970 3971
		oo = container_of(pos, struct nfs4_openowner, oo_close_lru);
		if (time_after((unsigned long)oo->oo_time, (unsigned long)cutoff)) {
3972 3973
			t = oo->oo_time - cutoff;
			new_timeo = min(new_timeo, t);
L
Linus Torvalds 已提交
3974 3975
			break;
		}
3976
		release_openowner(oo);
L
Linus Torvalds 已提交
3977
	}
3978
	new_timeo = max_t(time_t, new_timeo, NFSD_LAUNDROMAT_MINTIMEOUT);
L
Linus Torvalds 已提交
3979
	nfs4_unlock_state();
3980
	return new_timeo;
L
Linus Torvalds 已提交
3981 3982
}

H
Harvey Harrison 已提交
3983 3984 3985 3986
static struct workqueue_struct *laundry_wq;
static void laundromat_main(struct work_struct *);

static void
3987
laundromat_main(struct work_struct *laundry)
L
Linus Torvalds 已提交
3988 3989
{
	time_t t;
3990 3991 3992 3993
	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 已提交
3994

3995
	t = nfs4_laundromat(nn);
L
Linus Torvalds 已提交
3996
	dprintk("NFSD: laundromat_main - sleeping for %ld seconds\n", t);
3997
	queue_delayed_work(laundry_wq, &nn->laundromat_work, t*HZ);
L
Linus Torvalds 已提交
3998 3999
}

4000
static inline __be32 nfs4_check_fh(struct svc_fh *fhp, struct nfs4_ol_stateid *stp)
L
Linus Torvalds 已提交
4001
{
4002
	if (!nfsd_fh_match(&fhp->fh_handle, &stp->st_stid.sc_file->fi_fhandle))
4003 4004
		return nfserr_bad_stateid;
	return nfs_ok;
L
Linus Torvalds 已提交
4005 4006 4007
}

static inline int
4008
access_permit_read(struct nfs4_ol_stateid *stp)
L
Linus Torvalds 已提交
4009
{
4010 4011 4012
	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 已提交
4013 4014 4015
}

static inline int
4016
access_permit_write(struct nfs4_ol_stateid *stp)
L
Linus Torvalds 已提交
4017
{
4018 4019
	return test_access(NFS4_SHARE_ACCESS_WRITE, stp) ||
		test_access(NFS4_SHARE_ACCESS_BOTH, stp);
L
Linus Torvalds 已提交
4020 4021 4022
}

static
4023
__be32 nfs4_check_openmode(struct nfs4_ol_stateid *stp, int flags)
L
Linus Torvalds 已提交
4024
{
4025
        __be32 status = nfserr_openmode;
L
Linus Torvalds 已提交
4026

4027 4028 4029
	/* For lock stateid's, we test the parent open, not the lock: */
	if (stp->st_openstp)
		stp = stp->st_openstp;
4030
	if ((flags & WR_STATE) && !access_permit_write(stp))
L
Linus Torvalds 已提交
4031
                goto out;
4032
	if ((flags & RD_STATE) && !access_permit_read(stp))
L
Linus Torvalds 已提交
4033 4034 4035 4036 4037 4038
                goto out;
	status = nfs_ok;
out:
	return status;
}

4039
static inline __be32
4040
check_special_stateids(struct net *net, svc_fh *current_fh, stateid_t *stateid, int flags)
L
Linus Torvalds 已提交
4041
{
4042
	if (ONE_STATEID(stateid) && (flags & RD_STATE))
L
Linus Torvalds 已提交
4043
		return nfs_ok;
4044
	else if (locks_in_grace(net)) {
L
Lucas De Marchi 已提交
4045
		/* Answer in remaining cases depends on existence of
L
Linus Torvalds 已提交
4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060
		 * 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
4061
grace_disallows_io(struct net *net, struct inode *inode)
L
Linus Torvalds 已提交
4062
{
4063
	return locks_in_grace(net) && mandatory_lock(inode);
L
Linus Torvalds 已提交
4064 4065
}

4066 4067 4068
/* Returns true iff a is later than b: */
static bool stateid_generation_after(stateid_t *a, stateid_t *b)
{
J
Jim Rees 已提交
4069
	return (s32)(a->si_generation - b->si_generation) > 0;
4070 4071
}

J
J. Bruce Fields 已提交
4072
static __be32 check_stateid_generation(stateid_t *in, stateid_t *ref, bool has_session)
4073
{
A
Andy Adamson 已提交
4074 4075 4076 4077
	/*
	 * When sessions are used the stateid generation number is ignored
	 * when it is zero.
	 */
J
J. Bruce Fields 已提交
4078
	if (has_session && in->si_generation == 0)
4079 4080 4081 4082
		return nfs_ok;

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

4084
	/* If the client sends us a stateid from the future, it's buggy: */
4085
	if (stateid_generation_after(in, ref))
4086 4087
		return nfserr_bad_stateid;
	/*
4088 4089 4090 4091 4092 4093 4094 4095
	 * 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:
4096
	 */
4097
	return nfserr_old_stateid;
4098 4099
}

4100
static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid)
4101
{
4102 4103
	struct nfs4_stid *s;
	struct nfs4_ol_stateid *ols;
4104
	__be32 status = nfserr_bad_stateid;
4105

4106
	if (ZERO_STATEID(stateid) || ONE_STATEID(stateid))
4107
		return status;
4108 4109 4110 4111 4112 4113 4114
	/* 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);
4115
		return status;
4116
	}
4117 4118
	spin_lock(&cl->cl_lock);
	s = find_stateid_locked(cl, stateid);
4119
	if (!s)
4120
		goto out_unlock;
4121
	status = check_stateid_generation(stateid, &s->sc_stateid, 1);
4122
	if (status)
4123
		goto out_unlock;
4124 4125
	switch (s->sc_type) {
	case NFS4_DELEG_STID:
4126 4127
		status = nfs_ok;
		break;
4128
	case NFS4_REVOKED_DELEG_STID:
4129 4130
		status = nfserr_deleg_revoked;
		break;
4131 4132 4133 4134 4135 4136
	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))
4137 4138 4139 4140
			status = nfserr_bad_stateid;
		else
			status = nfs_ok;
		break;
4141 4142
	default:
		printk("unknown stateid type %x\n", s->sc_type);
4143
		/* Fallthrough */
4144
	case NFS4_CLOSED_STID:
4145
	case NFS4_CLOSED_DELEG_STID:
4146
		status = nfserr_bad_stateid;
4147
	}
4148 4149 4150
out_unlock:
	spin_unlock(&cl->cl_lock);
	return status;
4151 4152
}

4153 4154 4155 4156
static __be32
nfsd4_lookup_stateid(struct nfsd4_compound_state *cstate,
		     stateid_t *stateid, unsigned char typemask,
		     struct nfs4_stid **s, struct nfsd_net *nn)
4157
{
J
J. Bruce Fields 已提交
4158
	__be32 status;
4159 4160 4161

	if (ZERO_STATEID(stateid) || ONE_STATEID(stateid))
		return nfserr_bad_stateid;
4162
	status = lookup_clientid(&stateid->si_opaque.so_clid, cstate, nn);
4163
	if (status == nfserr_stale_clientid) {
4164
		if (cstate->session)
4165
			return nfserr_bad_stateid;
4166
		return nfserr_stale_stateid;
4167
	}
J
J. Bruce Fields 已提交
4168 4169
	if (status)
		return status;
4170
	*s = find_stateid_by_type(cstate->clp, stateid, typemask);
4171 4172
	if (!*s)
		return nfserr_bad_stateid;
4173 4174
	/* FIXME: move into find_stateid_by_type */
	atomic_inc(&(*s)->sc_count);
4175 4176 4177
	return nfs_ok;
}

L
Linus Torvalds 已提交
4178 4179 4180
/*
* Checks for stateid operations
*/
4181
__be32
4182
nfs4_preprocess_stateid_op(struct net *net, struct nfsd4_compound_state *cstate,
4183
			   stateid_t *stateid, int flags, struct file **filpp)
L
Linus Torvalds 已提交
4184
{
4185
	struct nfs4_stid *s;
4186
	struct nfs4_ol_stateid *stp = NULL;
L
Linus Torvalds 已提交
4187
	struct nfs4_delegation *dp = NULL;
4188
	struct svc_fh *current_fh = &cstate->current_fh;
L
Linus Torvalds 已提交
4189
	struct inode *ino = current_fh->fh_dentry->d_inode;
4190
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
4191
	struct file *file = NULL;
4192
	__be32 status;
L
Linus Torvalds 已提交
4193 4194 4195 4196

	if (filpp)
		*filpp = NULL;

4197
	if (grace_disallows_io(net, ino))
L
Linus Torvalds 已提交
4198 4199 4200
		return nfserr_grace;

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

4203 4204
	nfs4_lock_state();

4205
	status = nfsd4_lookup_stateid(cstate, stateid,
4206
				NFS4_DELEG_STID|NFS4_OPEN_STID|NFS4_LOCK_STID,
4207
				&s, nn);
4208
	if (status)
4209
		goto unlock_state;
4210 4211 4212
	status = check_stateid_generation(stateid, &s->sc_stateid, nfsd4_has_session(cstate));
	if (status)
		goto out;
4213 4214
	switch (s->sc_type) {
	case NFS4_DELEG_STID:
4215
		dp = delegstateid(s);
4216 4217 4218
		status = nfs4_check_delegmode(dp, flags);
		if (status)
			goto out;
4219
		if (filpp) {
4220
			file = dp->dl_stid.sc_file->fi_deleg_file;
4221
			if (!file) {
4222 4223 4224 4225
				WARN_ON_ONCE(1);
				status = nfserr_serverfault;
				goto out;
			}
4226
			get_file(file);
4227
		}
4228 4229 4230
		break;
	case NFS4_OPEN_STID:
	case NFS4_LOCK_STID:
4231
		stp = openlockstateid(s);
4232 4233
		status = nfs4_check_fh(current_fh, stp);
		if (status)
L
Linus Torvalds 已提交
4234
			goto out;
4235
		if (stp->st_stateowner->so_is_open_owner
4236
		    && !(openowner(stp->st_stateowner)->oo_flags & NFS4_OO_CONFIRMED))
L
Linus Torvalds 已提交
4237
			goto out;
4238 4239
		status = nfs4_check_openmode(stp, flags);
		if (status)
L
Linus Torvalds 已提交
4240
			goto out;
4241
		if (filpp) {
4242 4243
			struct nfs4_file *fp = stp->st_stid.sc_file;

4244
			if (flags & RD_STATE)
4245
				file = find_readable_file(fp);
4246
			else
4247
				file = find_writeable_file(fp);
4248
		}
4249 4250
		break;
	default:
4251 4252
		status = nfserr_bad_stateid;
		goto out;
L
Linus Torvalds 已提交
4253 4254
	}
	status = nfs_ok;
4255
	if (file)
4256
		*filpp = file;
L
Linus Torvalds 已提交
4257
out:
4258 4259
	nfs4_put_stid(s);
unlock_state:
4260
	nfs4_unlock_state();
L
Linus Torvalds 已提交
4261 4262 4263
	return status;
}

4264
static __be32
4265
nfsd4_free_lock_stateid(struct nfs4_ol_stateid *stp)
4266
{
4267 4268
	struct nfs4_lockowner *lo = lockowner(stp->st_stateowner);

4269
	if (check_for_locks(stp->st_stid.sc_file, lo))
4270
		return nfserr_locks_held;
4271
	release_lockowner_if_empty(lo);
4272 4273 4274
	return nfs_ok;
}

4275 4276 4277 4278 4279 4280 4281
/*
 * 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)
{
4282 4283 4284 4285 4286
	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)
4287 4288
		stateid->ts_id_status =
			nfsd4_validate_stateid(cl, &stateid->ts_id_stateid);
4289 4290
	nfs4_unlock_state();

4291 4292 4293
	return nfs_ok;
}

4294 4295 4296 4297 4298
__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 已提交
4299
	struct nfs4_stid *s;
4300
	struct nfs4_delegation *dp;
4301
	struct nfs4_client *cl = cstate->session->se_client;
J
J. Bruce Fields 已提交
4302
	__be32 ret = nfserr_bad_stateid;
4303 4304

	nfs4_lock_state();
4305 4306
	spin_lock(&cl->cl_lock);
	s = find_stateid_locked(cl, stateid);
J
J. Bruce Fields 已提交
4307
	if (!s)
4308
		goto out_unlock;
J
J. Bruce Fields 已提交
4309 4310
	switch (s->sc_type) {
	case NFS4_DELEG_STID:
4311
		ret = nfserr_locks_held;
4312
		break;
J
J. Bruce Fields 已提交
4313 4314 4315
	case NFS4_OPEN_STID:
		ret = check_stateid_generation(stateid, &s->sc_stateid, 1);
		if (ret)
4316 4317
			break;
		ret = nfserr_locks_held;
4318
		break;
4319 4320 4321 4322 4323 4324 4325
	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;
4326 4327
	case NFS4_REVOKED_DELEG_STID:
		dp = delegstateid(s);
4328 4329
		list_del_init(&dp->dl_recall_lru);
		spin_unlock(&cl->cl_lock);
4330
		nfs4_put_stid(s);
4331
		ret = nfs_ok;
4332 4333
		goto out;
	/* Default falls through and returns nfserr_bad_stateid */
4334
	}
4335 4336
out_unlock:
	spin_unlock(&cl->cl_lock);
4337 4338 4339 4340 4341
out:
	nfs4_unlock_state();
	return ret;
}

4342 4343 4344 4345 4346 4347
static inline int
setlkflg (int type)
{
	return (type == NFS4_READW_LT || type == NFS4_READ_LT) ?
		RD_STATE : WR_STATE;
}
L
Linus Torvalds 已提交
4348

4349
static __be32 nfs4_seqid_op_checks(struct nfsd4_compound_state *cstate, stateid_t *stateid, u32 seqid, struct nfs4_ol_stateid *stp)
4350 4351 4352 4353 4354 4355 4356 4357
{
	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;
4358 4359
	if (stp->st_stid.sc_type == NFS4_CLOSED_STID
		|| stp->st_stid.sc_type == NFS4_REVOKED_DELEG_STID)
4360 4361
		/*
		 * "Closed" stateid's exist *only* to return
4362 4363
		 * nfserr_replay_me from the previous step, and
		 * revoked delegations are kept only for free_stateid.
4364 4365 4366 4367 4368 4369
		 */
		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);
4370 4371
}

L
Linus Torvalds 已提交
4372 4373 4374
/* 
 * Checks for sequence id mutating operations. 
 */
4375
static __be32
4376
nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid,
4377
			 stateid_t *stateid, char typemask,
4378 4379
			 struct nfs4_ol_stateid **stpp,
			 struct nfsd_net *nn)
L
Linus Torvalds 已提交
4380
{
4381
	__be32 status;
4382
	struct nfs4_stid *s;
4383
	struct nfs4_ol_stateid *stp = NULL;
L
Linus Torvalds 已提交
4384

4385 4386
	dprintk("NFSD: %s: seqid=%d stateid = " STATEID_FMT "\n", __func__,
		seqid, STATEID_VAL(stateid));
4387

L
Linus Torvalds 已提交
4388
	*stpp = NULL;
4389
	status = nfsd4_lookup_stateid(cstate, stateid, typemask, &s, nn);
4390 4391
	if (status)
		return status;
4392
	stp = openlockstateid(s);
4393
	if (!nfsd4_has_session(cstate))
4394
		cstate->replay_owner = stp->st_stateowner;
L
Linus Torvalds 已提交
4395

4396
	status = nfs4_seqid_op_checks(cstate, stateid, seqid, stp);
4397
	if (!status)
4398
		*stpp = stp;
4399 4400
	else
		nfs4_put_stid(&stp->st_stid);
4401
	return status;
4402
}
4403

4404 4405
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)
4406 4407 4408
{
	__be32 status;
	struct nfs4_openowner *oo;
4409
	struct nfs4_ol_stateid *stp;
L
Linus Torvalds 已提交
4410

4411
	status = nfs4_preprocess_seqid_op(cstate, seqid, stateid,
4412
						NFS4_OPEN_STID, &stp, nn);
4413 4414
	if (status)
		return status;
4415 4416 4417
	oo = openowner(stp->st_stateowner);
	if (!(oo->oo_flags & NFS4_OO_CONFIRMED)) {
		nfs4_put_stid(&stp->st_stid);
4418
		return nfserr_bad_stateid;
4419 4420
	}
	*stpp = stp;
4421
	return nfs_ok;
L
Linus Torvalds 已提交
4422 4423
}

4424
__be32
4425
nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4426
		   struct nfsd4_open_confirm *oc)
L
Linus Torvalds 已提交
4427
{
4428
	__be32 status;
4429
	struct nfs4_openowner *oo;
4430
	struct nfs4_ol_stateid *stp;
4431
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
L
Linus Torvalds 已提交
4432

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

4436
	status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0);
4437 4438
	if (status)
		return status;
L
Linus Torvalds 已提交
4439 4440 4441

	nfs4_lock_state();

4442
	status = nfs4_preprocess_seqid_op(cstate,
4443
					oc->oc_seqid, &oc->oc_req_stateid,
4444
					NFS4_OPEN_STID, &stp, nn);
4445
	if (status)
4446
		goto out;
4447
	oo = openowner(stp->st_stateowner);
4448
	status = nfserr_bad_stateid;
4449
	if (oo->oo_flags & NFS4_OO_CONFIRMED)
4450
		goto put_stateid;
4451
	oo->oo_flags |= NFS4_OO_CONFIRMED;
4452 4453
	update_stateid(&stp->st_stid.sc_stateid);
	memcpy(&oc->oc_resp_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
4454
	dprintk("NFSD: %s: success, seqid=%d stateid=" STATEID_FMT "\n",
4455
		__func__, oc->oc_seqid, STATEID_VAL(&stp->st_stid.sc_stateid));
4456

4457
	nfsd4_client_record_create(oo->oo_owner.so_client);
4458
	status = nfs_ok;
4459 4460
put_stateid:
	nfs4_put_stid(&stp->st_stid);
L
Linus Torvalds 已提交
4461
out:
4462
	nfsd4_bump_seqid(cstate, status);
4463 4464
	if (!cstate->replay_owner)
		nfs4_unlock_state();
L
Linus Torvalds 已提交
4465 4466 4467
	return status;
}

J
J. Bruce Fields 已提交
4468
static inline void nfs4_stateid_downgrade_bit(struct nfs4_ol_stateid *stp, u32 access)
L
Linus Torvalds 已提交
4469
{
4470
	if (!test_access(access, stp))
J
J. Bruce Fields 已提交
4471
		return;
4472
	nfs4_file_put_access(stp->st_stid.sc_file, access);
4473
	clear_access(access, stp);
J
J. Bruce Fields 已提交
4474
}
4475

J
J. Bruce Fields 已提交
4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489
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:
4490
		WARN_ON_ONCE(1);
L
Linus Torvalds 已提交
4491 4492 4493
	}
}

4494
__be32
4495 4496
nfsd4_open_downgrade(struct svc_rqst *rqstp,
		     struct nfsd4_compound_state *cstate,
4497
		     struct nfsd4_open_downgrade *od)
L
Linus Torvalds 已提交
4498
{
4499
	__be32 status;
4500
	struct nfs4_ol_stateid *stp;
4501
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
L
Linus Torvalds 已提交
4502

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

4506
	/* We don't yet support WANT bits: */
4507 4508 4509
	if (od->od_deleg_want)
		dprintk("NFSD: %s: od_deleg_want=0x%x ignored\n", __func__,
			od->od_deleg_want);
L
Linus Torvalds 已提交
4510 4511

	nfs4_lock_state();
4512
	status = nfs4_preprocess_confirmed_seqid_op(cstate, od->od_seqid,
4513
					&od->od_stateid, &stp, nn);
4514
	if (status)
L
Linus Torvalds 已提交
4515 4516
		goto out; 
	status = nfserr_inval;
4517
	if (!test_access(od->od_share_access, stp)) {
4518
		dprintk("NFSD: access not a subset of current bitmap: 0x%hhx, input access=%08x\n",
L
Linus Torvalds 已提交
4519
			stp->st_access_bmap, od->od_share_access);
4520
		goto put_stateid;
L
Linus Torvalds 已提交
4521
	}
4522
	if (!test_deny(od->od_share_deny, stp)) {
4523
		dprintk("NFSD: deny not a subset of current bitmap: 0x%hhx, input deny=%08x\n",
L
Linus Torvalds 已提交
4524
			stp->st_deny_bmap, od->od_share_deny);
4525
		goto put_stateid;
L
Linus Torvalds 已提交
4526
	}
J
J. Bruce Fields 已提交
4527
	nfs4_stateid_downgrade(stp, od->od_share_access);
L
Linus Torvalds 已提交
4528

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

4531 4532
	update_stateid(&stp->st_stid.sc_stateid);
	memcpy(&od->od_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
L
Linus Torvalds 已提交
4533
	status = nfs_ok;
4534 4535
put_stateid:
	nfs4_put_stid(&stp->st_stid);
L
Linus Torvalds 已提交
4536
out:
4537
	nfsd4_bump_seqid(cstate, status);
4538 4539
	if (!cstate->replay_owner)
		nfs4_unlock_state();
L
Linus Torvalds 已提交
4540 4541 4542
	return status;
}

4543 4544
static void nfsd4_close_open_stateid(struct nfs4_ol_stateid *s)
{
4545 4546 4547
	struct nfs4_client *clp = s->st_stid.sc_client;
	struct nfs4_openowner *oo = openowner(s->st_stateowner);

4548
	s->st_stid.sc_type = NFS4_CLOSED_STID;
4549 4550 4551 4552 4553
	unhash_open_stateid(s);

	if (clp->cl_minorversion) {
		if (list_empty(&oo->oo_owner.so_stateids))
			release_openowner(oo);
4554
		nfs4_put_stid(&s->st_stid);
4555
	} else {
4556 4557 4558 4559 4560 4561 4562
		/*
		 * 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.
		 */
		release_all_access(s);
4563 4564 4565
		if (s->st_stid.sc_file) {
			put_nfs4_file(s->st_stid.sc_file);
			s->st_stid.sc_file = NULL;
4566
		}
4567 4568 4569 4570
		oo->oo_last_closed_stid = s;
		if (list_empty(&oo->oo_owner.so_stateids))
			move_to_close_lru(oo, clp->net);
	}
4571 4572
}

L
Linus Torvalds 已提交
4573 4574 4575
/*
 * nfs4_unlock_state() called after encode
 */
4576
__be32
4577
nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4578
	    struct nfsd4_close *close)
L
Linus Torvalds 已提交
4579
{
4580
	__be32 status;
4581
	struct nfs4_ol_stateid *stp;
4582 4583
	struct net *net = SVC_NET(rqstp);
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
L
Linus Torvalds 已提交
4584

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

	nfs4_lock_state();
4589 4590 4591
	status = nfs4_preprocess_seqid_op(cstate, close->cl_seqid,
					&close->cl_stateid,
					NFS4_OPEN_STID|NFS4_CLOSED_STID,
4592
					&stp, nn);
4593
	nfsd4_bump_seqid(cstate, status);
4594
	if (status)
L
Linus Torvalds 已提交
4595
		goto out; 
4596 4597
	update_stateid(&stp->st_stid.sc_stateid);
	memcpy(&close->cl_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
L
Linus Torvalds 已提交
4598

4599
	nfsd4_close_open_stateid(stp);
4600 4601 4602

	/* put reference from nfs4_preprocess_seqid_op */
	nfs4_put_stid(&stp->st_stid);
L
Linus Torvalds 已提交
4603
out:
4604 4605
	if (!cstate->replay_owner)
		nfs4_unlock_state();
L
Linus Torvalds 已提交
4606 4607 4608
	return status;
}

4609
__be32
4610 4611
nfsd4_delegreturn(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
		  struct nfsd4_delegreturn *dr)
L
Linus Torvalds 已提交
4612
{
4613 4614
	struct nfs4_delegation *dp;
	stateid_t *stateid = &dr->dr_stateid;
4615
	struct nfs4_stid *s;
4616
	__be32 status;
4617
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
L
Linus Torvalds 已提交
4618

4619
	if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0)))
4620
		return status;
L
Linus Torvalds 已提交
4621 4622

	nfs4_lock_state();
4623
	status = nfsd4_lookup_stateid(cstate, stateid, NFS4_DELEG_STID, &s, nn);
4624
	if (status)
4625
		goto out;
4626
	dp = delegstateid(s);
4627
	status = check_stateid_generation(stateid, &dp->dl_stid.sc_stateid, nfsd4_has_session(cstate));
4628
	if (status)
4629
		goto put_stateid;
4630

4631
	destroy_delegation(dp);
4632 4633
put_stateid:
	nfs4_put_stid(&dp->dl_stid);
L
Linus Torvalds 已提交
4634
out:
4635 4636
	nfs4_unlock_state();

L
Linus Torvalds 已提交
4637 4638 4639 4640 4641 4642
	return status;
}


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

B
Benny Halevy 已提交
4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657
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;

4658
	WARN_ON_ONCE(!len);
B
Benny Halevy 已提交
4659 4660 4661 4662
	end = start + len;
	return end > start ? end - 1: NFS4_MAX_UINT64;
}

L
Linus Torvalds 已提交
4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679
/*
 * 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;
}

4680 4681
/* 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. */
4682
static const struct lock_manager_operations nfsd_posix_mng_ops  = {
4683
};
L
Linus Torvalds 已提交
4684 4685 4686 4687

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

4690
	if (fl->fl_lmops == &nfsd_posix_mng_ops) {
4691 4692 4693
		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);
4694 4695 4696
		if (!deny->ld_owner.data)
			/* We just don't care that much */
			goto nevermind;
4697 4698
		deny->ld_owner.len = lo->lo_owner.so_owner.len;
		deny->ld_clientid = lo->lo_owner.so_client->cl_clientid;
4699
	} else {
4700 4701 4702
nevermind:
		deny->ld_owner.len = 0;
		deny->ld_owner.data = NULL;
4703 4704
		deny->ld_clientid.cl_boot = 0;
		deny->ld_clientid.cl_id = 0;
L
Linus Torvalds 已提交
4705 4706
	}
	deny->ld_start = fl->fl_start;
B
Benny Halevy 已提交
4707 4708
	deny->ld_length = NFS4_MAX_UINT64;
	if (fl->fl_end != NFS4_MAX_UINT64)
L
Linus Torvalds 已提交
4709 4710 4711 4712 4713 4714
		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;
}

4715
static struct nfs4_lockowner *
4716 4717
find_lockowner_str(clientid_t *clid, struct xdr_netobj *owner,
		struct nfsd_net *nn)
L
Linus Torvalds 已提交
4718
{
4719 4720
	unsigned int strhashval = ownerstr_hashval(clid->cl_id, owner);
	struct nfs4_stateowner *so;
L
Linus Torvalds 已提交
4721

4722 4723 4724 4725 4726 4727
	list_for_each_entry(so, &nn->ownerstr_hashtbl[strhashval], so_strhash) {
		if (so->so_is_open_owner)
			continue;
		if (!same_owner_str(so, owner, clid))
			continue;
		return lockowner(so);
L
Linus Torvalds 已提交
4728 4729 4730 4731 4732 4733 4734
	}
	return NULL;
}

/*
 * Alloc a lock owner structure.
 * Called in nfsd4_lock - therefore, OPEN and OPEN_CONFIRM (if needed) has 
L
Lucas De Marchi 已提交
4735
 * occurred. 
L
Linus Torvalds 已提交
4736
 *
4737
 * strhashval = ownerstr_hashval
L
Linus Torvalds 已提交
4738
 */
4739
static struct nfs4_lockowner *
4740
alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct nfs4_ol_stateid *open_stp, struct nfsd4_lock *lock) {
4741
	struct nfs4_lockowner *lo;
4742
	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
L
Linus Torvalds 已提交
4743

4744 4745
	lo = alloc_stateowner(lockowner_slab, &lock->lk_new_owner, clp);
	if (!lo)
L
Linus Torvalds 已提交
4746
		return NULL;
4747 4748
	INIT_LIST_HEAD(&lo->lo_owner.so_stateids);
	lo->lo_owner.so_is_open_owner = 0;
4749 4750
	/* It is the openowner seqid that will be incremented in encode in the
	 * case of new lockowners; so increment the lock seqid manually: */
4751
	lo->lo_owner.so_seqid = lock->lk_new_lock_seqid + 1;
4752
	list_add(&lo->lo_owner.so_strhash, &nn->ownerstr_hashtbl[strhashval]);
4753
	return lo;
L
Linus Torvalds 已提交
4754 4755
}

4756 4757 4758 4759
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 已提交
4760
{
4761
	struct nfs4_client *clp = lo->lo_owner.so_client;
L
Linus Torvalds 已提交
4762

4763 4764
	lockdep_assert_held(&clp->cl_lock);

4765
	atomic_inc(&stp->st_stid.sc_count);
J
J. Bruce Fields 已提交
4766
	stp->st_stid.sc_type = NFS4_LOCK_STID;
4767
	stp->st_stateowner = &lo->lo_owner;
4768
	get_nfs4_file(fp);
4769
	stp->st_stid.sc_file = fp;
4770
	stp->st_stid.sc_free = nfs4_free_lock_stateid;
J
J. Bruce Fields 已提交
4771
	stp->st_access_bmap = 0;
L
Linus Torvalds 已提交
4772
	stp->st_deny_bmap = open_stp->st_deny_bmap;
4773
	stp->st_openstp = open_stp;
4774
	list_add(&stp->st_locks, &open_stp->st_locks);
4775
	list_add(&stp->st_perstateowner, &lo->lo_owner.so_stateids);
4776 4777 4778
	spin_lock(&fp->fi_lock);
	list_add(&stp->st_perfile, &fp->fi_stateids);
	spin_unlock(&fp->fi_lock);
L
Linus Torvalds 已提交
4779 4780
}

4781 4782 4783 4784
static struct nfs4_ol_stateid *
find_lock_stateid(struct nfs4_lockowner *lo, struct nfs4_file *fp)
{
	struct nfs4_ol_stateid *lst;
4785 4786 4787
	struct nfs4_client *clp = lo->lo_owner.so_client;

	lockdep_assert_held(&clp->cl_lock);
4788 4789

	list_for_each_entry(lst, &lo->lo_owner.so_stateids, st_perstateowner) {
4790 4791
		if (lst->st_stid.sc_file == fp) {
			atomic_inc(&lst->st_stid.sc_count);
4792
			return lst;
4793
		}
4794 4795 4796 4797
	}
	return NULL;
}

4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829
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;
}
4830

4831
static int
L
Linus Torvalds 已提交
4832 4833
check_lock_length(u64 offset, u64 length)
{
B
Benny Halevy 已提交
4834
	return ((length == 0)  || ((length != NFS4_MAX_UINT64) &&
L
Linus Torvalds 已提交
4835 4836 4837
	     LOFF_OVERFLOW(offset, length)));
}

4838
static void get_lock_access(struct nfs4_ol_stateid *lock_stp, u32 access)
J
J. Bruce Fields 已提交
4839
{
4840
	struct nfs4_file *fp = lock_stp->st_stid.sc_file;
J
J. Bruce Fields 已提交
4841

4842 4843
	lockdep_assert_held(&fp->fi_lock);

4844
	if (test_access(access, lock_stp))
J
J. Bruce Fields 已提交
4845
		return;
4846
	__nfs4_file_get_access(fp, access);
4847
	set_access(access, lock_stp);
J
J. Bruce Fields 已提交
4848 4849
}

4850 4851 4852 4853 4854
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)
4855
{
4856
	struct nfs4_file *fi = ost->st_stid.sc_file;
4857 4858
	struct nfs4_openowner *oo = openowner(ost->st_stateowner);
	struct nfs4_client *cl = oo->oo_owner.so_client;
4859
	struct inode *inode = cstate->current_fh.fh_dentry->d_inode;
4860 4861
	struct nfs4_lockowner *lo;
	unsigned int strhashval;
4862
	struct nfsd_net *nn = net_generic(cl->net, nfsd_net_id);
4863

4864
	lo = find_lockowner_str(&cl->cl_clientid, &lock->v.new.owner, nn);
4865 4866 4867 4868 4869 4870 4871 4872 4873 4874
	if (!lo) {
		strhashval = ownerstr_hashval(cl->cl_clientid.cl_id,
				&lock->v.new.owner);
		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 */
		if (!cstate->minorversion &&
		    lock->lk_new_lock_seqid != lo->lo_owner.so_seqid)
4875 4876
			return nfserr_bad_seqid;
	}
4877

4878
	*lst = find_or_create_lock_stateid(lo, fi, inode, ost, new);
4879
	if (*lst == NULL) {
4880 4881
		release_lockowner_if_empty(lo);
		return nfserr_jukebox;
4882 4883 4884 4885
	}
	return nfs_ok;
}

L
Linus Torvalds 已提交
4886 4887 4888
/*
 *  LOCK operation 
 */
4889
__be32
4890
nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4891
	   struct nfsd4_lock *lock)
L
Linus Torvalds 已提交
4892
{
4893 4894
	struct nfs4_openowner *open_sop = NULL;
	struct nfs4_lockowner *lock_sop = NULL;
4895
	struct nfs4_ol_stateid *lock_stp = NULL;
4896
	struct nfs4_ol_stateid *open_stp = NULL;
4897
	struct nfs4_file *fp;
4898
	struct file *filp = NULL;
4899 4900
	struct file_lock *file_lock = NULL;
	struct file_lock *conflock = NULL;
4901
	__be32 status = 0;
4902
	bool new_state = false;
4903
	int lkflg;
4904
	int err;
4905 4906
	struct net *net = SVC_NET(rqstp);
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
L
Linus Torvalds 已提交
4907 4908 4909 4910 4911 4912 4913 4914

	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;

4915
	if ((status = fh_verify(rqstp, &cstate->current_fh,
M
Miklos Szeredi 已提交
4916
				S_IFREG, NFSD_MAY_LOCK))) {
A
Andy Adamson 已提交
4917 4918 4919 4920
		dprintk("NFSD: nfsd4_lock: permission denied!\n");
		return status;
	}

L
Linus Torvalds 已提交
4921 4922 4923
	nfs4_lock_state();

	if (lock->lk_is_new) {
4924 4925 4926 4927 4928 4929
		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 已提交
4930
		status = nfserr_stale_clientid;
4931
		if (STALE_CLIENTID(&lock->lk_new_clientid, nn))
L
Linus Torvalds 已提交
4932 4933 4934
			goto out;

		/* validate and update open stateid and open seqid */
4935
		status = nfs4_preprocess_confirmed_seqid_op(cstate,
L
Linus Torvalds 已提交
4936 4937
				        lock->lk_new_open_seqid,
		                        &lock->lk_new_open_stateid,
4938
					&open_stp, nn);
4939
		if (status)
L
Linus Torvalds 已提交
4940
			goto out;
4941
		open_sop = openowner(open_stp->st_stateowner);
4942
		status = nfserr_bad_stateid;
4943
		if (!same_clid(&open_sop->oo_owner.so_client->cl_clientid,
4944 4945
						&lock->v.new.clientid))
			goto out;
4946 4947
		status = lookup_or_create_lock_state(cstate, open_stp, lock,
							&lock_stp, &new_state);
4948
	} else {
4949
		status = nfs4_preprocess_seqid_op(cstate,
4950 4951
				       lock->lk_old_lock_seqid,
				       &lock->lk_old_lock_stateid,
4952
				       NFS4_LOCK_STID, &lock_stp, nn);
4953
	}
J
J. Bruce Fields 已提交
4954 4955
	if (status)
		goto out;
4956
	lock_sop = lockowner(lock_stp->st_stateowner);
L
Linus Torvalds 已提交
4957

4958 4959 4960 4961 4962
	lkflg = setlkflg(lock->lk_type);
	status = nfs4_check_openmode(lock_stp, lkflg);
	if (status)
		goto out;

4963
	status = nfserr_grace;
4964
	if (locks_in_grace(net) && !lock->lk_reclaim)
4965 4966
		goto out;
	status = nfserr_no_grace;
4967
	if (!locks_in_grace(net) && lock->lk_reclaim)
4968 4969
		goto out;

4970 4971 4972 4973 4974 4975 4976
	file_lock = locks_alloc_lock();
	if (!file_lock) {
		dprintk("NFSD: %s: unable to allocate lock!\n", __func__);
		status = nfserr_jukebox;
		goto out;
	}

4977
	fp = lock_stp->st_stid.sc_file;
4978
	locks_init_lock(file_lock);
L
Linus Torvalds 已提交
4979 4980 4981
	switch (lock->lk_type) {
		case NFS4_READ_LT:
		case NFS4_READW_LT:
4982 4983
			spin_lock(&fp->fi_lock);
			filp = find_readable_file_locked(fp);
J
J. Bruce Fields 已提交
4984 4985
			if (filp)
				get_lock_access(lock_stp, NFS4_SHARE_ACCESS_READ);
4986
			spin_unlock(&fp->fi_lock);
4987
			file_lock->fl_type = F_RDLCK;
4988
			break;
L
Linus Torvalds 已提交
4989 4990
		case NFS4_WRITE_LT:
		case NFS4_WRITEW_LT:
4991 4992
			spin_lock(&fp->fi_lock);
			filp = find_writeable_file_locked(fp);
J
J. Bruce Fields 已提交
4993 4994
			if (filp)
				get_lock_access(lock_stp, NFS4_SHARE_ACCESS_WRITE);
4995
			spin_unlock(&fp->fi_lock);
4996
			file_lock->fl_type = F_WRLCK;
4997
			break;
L
Linus Torvalds 已提交
4998 4999 5000 5001
		default:
			status = nfserr_inval;
		goto out;
	}
5002 5003 5004 5005
	if (!filp) {
		status = nfserr_openmode;
		goto out;
	}
5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020
	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 已提交
5021

5022
	err = vfs_lock_file(filp, F_SETLK, file_lock, conflock);
5023
	switch (-err) {
L
Linus Torvalds 已提交
5024
	case 0: /* success! */
5025 5026
		update_stateid(&lock_stp->st_stid.sc_stateid);
		memcpy(&lock->lk_resp_stateid, &lock_stp->st_stid.sc_stateid, 
L
Linus Torvalds 已提交
5027
				sizeof(stateid_t));
5028
		status = 0;
5029 5030 5031 5032
		break;
	case (EAGAIN):		/* conflock holds conflicting lock */
		status = nfserr_denied;
		dprintk("NFSD: nfsd4_lock: conflicting lock found!\n");
5033
		nfs4_set_lock_denied(conflock, &lock->lk_denied);
5034
		break;
L
Linus Torvalds 已提交
5035 5036
	case (EDEADLK):
		status = nfserr_deadlock;
5037
		break;
5038
	default:
5039
		dprintk("NFSD: nfsd4_lock: vfs_lock_file() failed! status %d\n",err);
5040
		status = nfserrno(err);
5041
		break;
L
Linus Torvalds 已提交
5042 5043
	}
out:
5044 5045
	if (filp)
		fput(filp);
5046 5047
	if (lock_stp)
		nfs4_put_stid(&lock_stp->st_stid);
5048 5049
	if (open_stp)
		nfs4_put_stid(&open_stp->st_stid);
5050
	if (status && new_state)
5051
		release_lock_stateid(lock_stp);
5052
	nfsd4_bump_seqid(cstate, status);
5053 5054
	if (!cstate->replay_owner)
		nfs4_unlock_state();
5055 5056 5057 5058
	if (file_lock)
		locks_free_lock(file_lock);
	if (conflock)
		locks_free_lock(conflock);
L
Linus Torvalds 已提交
5059 5060 5061
	return status;
}

5062 5063 5064 5065 5066 5067
/*
 * 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.)
 */
5068
static __be32 nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file_lock *lock)
5069 5070
{
	struct file *file;
5071 5072 5073 5074 5075
	__be32 err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file);
	if (!err) {
		err = nfserrno(vfs_test_lock(file, lock));
		nfsd_close(file);
	}
5076 5077 5078
	return err;
}

L
Linus Torvalds 已提交
5079 5080 5081
/*
 * LOCKT operation
 */
5082
__be32
5083 5084
nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	    struct nfsd4_lockt *lockt)
L
Linus Torvalds 已提交
5085
{
5086
	struct file_lock *file_lock = NULL;
5087
	struct nfs4_lockowner *lo;
5088
	__be32 status;
5089
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
L
Linus Torvalds 已提交
5090

5091
	if (locks_in_grace(SVC_NET(rqstp)))
L
Linus Torvalds 已提交
5092 5093 5094 5095 5096 5097 5098
		return nfserr_grace;

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

	nfs4_lock_state();

5099
	if (!nfsd4_has_session(cstate)) {
5100
		status = lookup_clientid(&lockt->lt_clientid, cstate, nn);
5101 5102 5103
		if (status)
			goto out;
	}
L
Linus Torvalds 已提交
5104

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

5108 5109 5110 5111 5112 5113 5114
	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 已提交
5115 5116 5117
	switch (lockt->lt_type) {
		case NFS4_READ_LT:
		case NFS4_READW_LT:
5118
			file_lock->fl_type = F_RDLCK;
L
Linus Torvalds 已提交
5119 5120 5121
		break;
		case NFS4_WRITE_LT:
		case NFS4_WRITEW_LT:
5122
			file_lock->fl_type = F_WRLCK;
L
Linus Torvalds 已提交
5123 5124
		break;
		default:
5125
			dprintk("NFSD: nfs4_lockt: bad lock type!\n");
L
Linus Torvalds 已提交
5126 5127 5128 5129
			status = nfserr_inval;
		goto out;
	}

5130
	lo = find_lockowner_str(&lockt->lt_clientid, &lockt->lt_owner, nn);
5131
	if (lo)
5132 5133 5134
		file_lock->fl_owner = (fl_owner_t)lo;
	file_lock->fl_pid = current->tgid;
	file_lock->fl_flags = FL_POSIX;
L
Linus Torvalds 已提交
5135

5136 5137
	file_lock->fl_start = lockt->lt_offset;
	file_lock->fl_end = last_byte_offset(lockt->lt_offset, lockt->lt_length);
L
Linus Torvalds 已提交
5138

5139
	nfs4_transform_lock_offset(file_lock);
L
Linus Torvalds 已提交
5140

5141
	status = nfsd_test_lock(rqstp, &cstate->current_fh, file_lock);
5142
	if (status)
5143
		goto out;
5144

5145
	if (file_lock->fl_type != F_UNLCK) {
L
Linus Torvalds 已提交
5146
		status = nfserr_denied;
5147
		nfs4_set_lock_denied(file_lock, &lockt->lt_denied);
L
Linus Torvalds 已提交
5148 5149 5150
	}
out:
	nfs4_unlock_state();
5151 5152
	if (file_lock)
		locks_free_lock(file_lock);
L
Linus Torvalds 已提交
5153 5154 5155
	return status;
}

5156
__be32
5157
nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
5158
	    struct nfsd4_locku *locku)
L
Linus Torvalds 已提交
5159
{
5160
	struct nfs4_ol_stateid *stp;
L
Linus Torvalds 已提交
5161
	struct file *filp = NULL;
5162
	struct file_lock *file_lock = NULL;
5163
	__be32 status;
5164
	int err;
5165 5166
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);

L
Linus Torvalds 已提交
5167 5168 5169 5170 5171 5172 5173 5174 5175
	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();
									        
5176
	status = nfs4_preprocess_seqid_op(cstate, locku->lu_seqid,
5177 5178
					&locku->lu_stateid, NFS4_LOCK_STID,
					&stp, nn);
5179
	if (status)
L
Linus Torvalds 已提交
5180
		goto out;
5181
	filp = find_any_file(stp->st_stid.sc_file);
5182 5183
	if (!filp) {
		status = nfserr_lock_range;
5184
		goto put_stateid;
5185
	}
5186 5187 5188 5189
	file_lock = locks_alloc_lock();
	if (!file_lock) {
		dprintk("NFSD: %s: unable to allocate lock!\n", __func__);
		status = nfserr_jukebox;
5190
		goto fput;
5191 5192 5193
	}
	locks_init_lock(file_lock);
	file_lock->fl_type = F_UNLCK;
5194
	file_lock->fl_owner = (fl_owner_t)lockowner(stp->st_stateowner);
5195 5196 5197 5198 5199 5200 5201 5202 5203
	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 已提交
5204

5205
	err = vfs_lock_file(filp, F_SETLK, file_lock, NULL);
5206
	if (err) {
5207
		dprintk("NFSD: nfs4_locku: vfs_lock_file failed!\n");
L
Linus Torvalds 已提交
5208 5209
		goto out_nfserr;
	}
5210 5211
	update_stateid(&stp->st_stid.sc_stateid);
	memcpy(&locku->lu_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
5212 5213
fput:
	fput(filp);
5214 5215
put_stateid:
	nfs4_put_stid(&stp->st_stid);
L
Linus Torvalds 已提交
5216
out:
5217
	nfsd4_bump_seqid(cstate, status);
5218 5219
	if (!cstate->replay_owner)
		nfs4_unlock_state();
5220 5221
	if (file_lock)
		locks_free_lock(file_lock);
L
Linus Torvalds 已提交
5222 5223 5224
	return status;

out_nfserr:
5225
	status = nfserrno(err);
5226
	goto fput;
L
Linus Torvalds 已提交
5227 5228 5229 5230
}

/*
 * returns
5231 5232
 * 	true:  locks held by lockowner
 * 	false: no locks held by lockowner
L
Linus Torvalds 已提交
5233
 */
5234 5235
static bool
check_for_locks(struct nfs4_file *fp, struct nfs4_lockowner *lowner)
L
Linus Torvalds 已提交
5236 5237
{
	struct file_lock **flpp;
5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248
	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 已提交
5249

5250
	spin_lock(&inode->i_lock);
L
Linus Torvalds 已提交
5251
	for (flpp = &inode->i_flock; *flpp != NULL; flpp = &(*flpp)->fl_next) {
5252
		if ((*flpp)->fl_owner == (fl_owner_t)lowner) {
5253 5254
			status = true;
			break;
5255
		}
L
Linus Torvalds 已提交
5256
	}
5257
	spin_unlock(&inode->i_lock);
5258
	fput(filp);
L
Linus Torvalds 已提交
5259 5260 5261
	return status;
}

5262
__be32
5263 5264 5265
nfsd4_release_lockowner(struct svc_rqst *rqstp,
			struct nfsd4_compound_state *cstate,
			struct nfsd4_release_lockowner *rlockowner)
L
Linus Torvalds 已提交
5266 5267
{
	clientid_t *clid = &rlockowner->rl_clientid;
5268
	struct nfs4_stateowner *sop = NULL, *tmp;
5269
	struct nfs4_lockowner *lo;
5270
	struct nfs4_ol_stateid *stp;
L
Linus Torvalds 已提交
5271
	struct xdr_netobj *owner = &rlockowner->rl_owner;
5272
	unsigned int hashval = ownerstr_hashval(clid->cl_id, owner);
5273
	__be32 status;
5274
	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
L
Linus Torvalds 已提交
5275 5276 5277 5278 5279 5280

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

	nfs4_lock_state();

5281
	status = lookup_clientid(clid, cstate, nn);
5282 5283 5284
	if (status)
		goto out;

5285
	status = nfserr_locks_held;
5286

5287 5288 5289
	/* Find the matching lock stateowner */
	list_for_each_entry(tmp, &nn->ownerstr_hashtbl[hashval], so_strhash) {
		if (tmp->so_is_open_owner)
5290
			continue;
5291 5292 5293
		if (same_owner_str(tmp, owner, clid)) {
			sop = tmp;
			break;
L
Linus Torvalds 已提交
5294
		}
5295
	}
5296 5297 5298 5299 5300 5301 5302 5303 5304 5305

	/* No matching owner found, maybe a replay? Just declare victory... */
	if (!sop) {
		status = nfs_ok;
		goto out;
	}

	lo = lockowner(sop);
	/* see if there are still any locks associated with it */
	list_for_each_entry(stp, &sop->so_stateids, st_perstateowner) {
5306
		if (check_for_locks(stp->st_stid.sc_file, lo))
5307
			goto out;
L
Linus Torvalds 已提交
5308
	}
5309 5310 5311

	status = nfs_ok;
	release_lockowner(lo);
L
Linus Torvalds 已提交
5312 5313 5314 5315 5316 5317
out:
	nfs4_unlock_state();
	return status;
}

static inline struct nfs4_client_reclaim *
N
NeilBrown 已提交
5318
alloc_reclaim(void)
L
Linus Torvalds 已提交
5319
{
N
NeilBrown 已提交
5320
	return kmalloc(sizeof(struct nfs4_client_reclaim), GFP_KERNEL);
L
Linus Torvalds 已提交
5321 5322
}

5323
bool
5324
nfs4_has_reclaimed_state(const char *name, struct nfsd_net *nn)
5325
{
5326
	struct nfs4_client_reclaim *crp;
5327

5328
	crp = nfsd4_find_reclaim_client(name, nn);
5329
	return (crp && crp->cr_clp);
5330 5331
}

L
Linus Torvalds 已提交
5332 5333 5334
/*
 * failure => all reset bets are off, nfserr_no_grace...
 */
5335
struct nfs4_client_reclaim *
5336
nfs4_client_to_reclaim(const char *name, struct nfsd_net *nn)
L
Linus Torvalds 已提交
5337 5338
{
	unsigned int strhashval;
5339
	struct nfs4_client_reclaim *crp;
L
Linus Torvalds 已提交
5340

N
NeilBrown 已提交
5341 5342
	dprintk("NFSD nfs4_client_to_reclaim NAME: %.*s\n", HEXDIR_LEN, name);
	crp = alloc_reclaim();
5343 5344 5345
	if (crp) {
		strhashval = clientstr_hashval(name);
		INIT_LIST_HEAD(&crp->cr_strhash);
5346
		list_add(&crp->cr_strhash, &nn->reclaim_str_hashtbl[strhashval]);
5347
		memcpy(crp->cr_recdir, name, HEXDIR_LEN);
5348
		crp->cr_clp = NULL;
5349
		nn->reclaim_str_hashtbl_size++;
5350 5351
	}
	return crp;
L
Linus Torvalds 已提交
5352 5353
}

5354
void
5355
nfs4_remove_reclaim_record(struct nfs4_client_reclaim *crp, struct nfsd_net *nn)
5356 5357 5358
{
	list_del(&crp->cr_strhash);
	kfree(crp);
5359
	nn->reclaim_str_hashtbl_size--;
5360 5361
}

5362
void
5363
nfs4_release_reclaim(struct nfsd_net *nn)
L
Linus Torvalds 已提交
5364 5365 5366 5367 5368
{
	struct nfs4_client_reclaim *crp = NULL;
	int i;

	for (i = 0; i < CLIENT_HASH_SIZE; i++) {
5369 5370
		while (!list_empty(&nn->reclaim_str_hashtbl[i])) {
			crp = list_entry(nn->reclaim_str_hashtbl[i].next,
L
Linus Torvalds 已提交
5371
			                struct nfs4_client_reclaim, cr_strhash);
5372
			nfs4_remove_reclaim_record(crp, nn);
L
Linus Torvalds 已提交
5373 5374
		}
	}
5375
	WARN_ON_ONCE(nn->reclaim_str_hashtbl_size);
L
Linus Torvalds 已提交
5376 5377 5378 5379
}

/*
 * called from OPEN, CLAIM_PREVIOUS with a new clientid. */
5380
struct nfs4_client_reclaim *
5381
nfsd4_find_reclaim_client(const char *recdir, struct nfsd_net *nn)
L
Linus Torvalds 已提交
5382 5383 5384 5385
{
	unsigned int strhashval;
	struct nfs4_client_reclaim *crp = NULL;

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

5388
	strhashval = clientstr_hashval(recdir);
5389
	list_for_each_entry(crp, &nn->reclaim_str_hashtbl[strhashval], cr_strhash) {
5390
		if (same_name(crp->cr_recdir, recdir)) {
L
Linus Torvalds 已提交
5391 5392 5393 5394 5395 5396 5397 5398 5399
			return crp;
		}
	}
	return NULL;
}

/*
* Called from OPEN. Look for clientid in reclaim list.
*/
5400
__be32
5401 5402 5403
nfs4_check_open_reclaim(clientid_t *clid,
		struct nfsd4_compound_state *cstate,
		struct nfsd_net *nn)
L
Linus Torvalds 已提交
5404
{
5405
	__be32 status;
5406 5407

	/* find clientid in conf_id_hashtbl */
5408 5409
	status = lookup_clientid(clid, cstate, nn);
	if (status)
5410 5411
		return nfserr_reclaim_bad;

5412 5413 5414 5415
	if (nfsd4_client_record_check(cstate->clp))
		return nfserr_reclaim_bad;

	return nfs_ok;
L
Linus Torvalds 已提交
5416 5417
}

B
Bryan Schumaker 已提交
5418 5419
#ifdef CONFIG_NFSD_FAULT_INJECTION

5420 5421
u64 nfsd_forget_client(struct nfs4_client *clp, u64 max)
{
5422 5423
	if (mark_client_expired(clp))
		return 0;
5424 5425 5426 5427
	expire_client(clp);
	return 1;
}

5428 5429 5430
u64 nfsd_print_client(struct nfs4_client *clp, u64 num)
{
	char buf[INET6_ADDRSTRLEN];
5431
	rpc_ntop((struct sockaddr *)&clp->cl_addr, buf, sizeof(buf));
5432 5433 5434 5435 5436 5437 5438 5439
	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];
5440
	rpc_ntop((struct sockaddr *)&clp->cl_addr, buf, sizeof(buf));
5441 5442 5443
	printk(KERN_INFO "NFS Client: %s has %u %s\n", buf, count, type);
}

5444 5445
static u64 nfsd_foreach_client_lock(struct nfs4_client *clp, u64 max,
				    void (*func)(struct nfs4_ol_stateid *))
B
Bryan Schumaker 已提交
5446 5447 5448
{
	struct nfs4_openowner *oop;
	struct nfs4_ol_stateid *stp, *st_next;
5449
	struct nfs4_ol_stateid *lst, *lst_next;
B
Bryan Schumaker 已提交
5450 5451 5452
	u64 count = 0;

	list_for_each_entry(oop, &clp->cl_openowners, oo_perclient) {
5453 5454 5455 5456
		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 已提交
5457
				if (func)
5458
					func(lst);
B
Bryan Schumaker 已提交
5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469
				if (++count == max)
					return count;
			}
		}
	}

	return count;
}

u64 nfsd_forget_client_locks(struct nfs4_client *clp, u64 max)
{
5470
	return nfsd_foreach_client_lock(clp, max, release_lock_stateid);
B
Bryan Schumaker 已提交
5471 5472
}

5473 5474 5475 5476 5477 5478 5479
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;
}

5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498 5499
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);
}

5500 5501 5502 5503 5504 5505 5506
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;
}

5507 5508 5509 5510 5511 5512
static u64 nfsd_find_all_delegations(struct nfs4_client *clp, u64 max,
				     struct list_head *victims)
{
	struct nfs4_delegation *dp, *next;
	u64 count = 0;

5513
	lockdep_assert_held(&state_lock);
5514
	list_for_each_entry_safe(dp, next, &clp->cl_delegations, dl_perclnt) {
5515 5516 5517 5518 5519 5520 5521 5522 5523 5524
		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;

5525 5526
			unhash_delegation_locked(dp);
			list_add(&dp->dl_recall_lru, victims);
5527
		}
5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539
		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;

5540
	spin_lock(&state_lock);
5541
	count = nfsd_find_all_delegations(clp, max, &victims);
5542
	spin_unlock(&state_lock);
5543

5544 5545
	list_for_each_entry_safe(dp, next, &victims, dl_recall_lru) {
		list_del_init(&dp->dl_recall_lru);
5546
		revoke_delegation(dp);
5547
	}
5548 5549 5550 5551 5552 5553

	return count;
}

u64 nfsd_recall_client_delegations(struct nfs4_client *clp, u64 max)
{
5554
	struct nfs4_delegation *dp;
5555 5556 5557
	LIST_HEAD(victims);
	u64 count;

5558
	spin_lock(&state_lock);
5559
	count = nfsd_find_all_delegations(clp, max, &victims);
5560 5561 5562 5563 5564
	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;
5565
		nfsd_break_one_deleg(dp);
5566
	}
5567
	spin_unlock(&state_lock);
5568 5569 5570 5571

	return count;
}

5572 5573 5574 5575
u64 nfsd_print_client_delegations(struct nfs4_client *clp, u64 max)
{
	u64 count = 0;

5576
	spin_lock(&state_lock);
5577
	count = nfsd_find_all_delegations(clp, max, NULL);
5578
	spin_unlock(&state_lock);
5579 5580 5581 5582 5583

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

5584
u64 nfsd_for_n_state(u64 max, u64 (*func)(struct nfs4_client *, u64))
B
Bryan Schumaker 已提交
5585 5586
{
	struct nfs4_client *clp, *next;
5587
	u64 count = 0;
5588
	struct nfsd_net *nn = net_generic(current->nsproxy->net_ns, nfsd_net_id);
B
Bryan Schumaker 已提交
5589

5590 5591 5592
	if (!nfsd_netns_ready(nn))
		return 0;

5593
	list_for_each_entry_safe(clp, next, &nn->client_lru, cl_lru) {
5594 5595
		count += func(clp, max - count);
		if ((max != 0) && (count >= max))
B
Bryan Schumaker 已提交
5596 5597 5598
			break;
	}

5599 5600 5601
	return count;
}

5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616
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 已提交
5617 5618
#endif /* CONFIG_NFSD_FAULT_INJECTION */

5619 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639
/*
 * 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);
}

5640
static int nfs4_state_create_net(struct net *net)
5641 5642 5643 5644 5645 5646 5647
{
	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)
5648
		goto err;
5649 5650 5651 5652
	nn->unconf_id_hashtbl = kmalloc(sizeof(struct list_head) *
			CLIENT_HASH_SIZE, GFP_KERNEL);
	if (!nn->unconf_id_hashtbl)
		goto err_unconf_id;
5653 5654 5655 5656
	nn->ownerstr_hashtbl = kmalloc(sizeof(struct list_head) *
			OWNER_HASH_SIZE, GFP_KERNEL);
	if (!nn->ownerstr_hashtbl)
		goto err_ownerstr;
5657 5658 5659 5660
	nn->sessionid_hashtbl = kmalloc(sizeof(struct list_head) *
			SESSION_HASH_SIZE, GFP_KERNEL);
	if (!nn->sessionid_hashtbl)
		goto err_sessionid;
5661

5662
	for (i = 0; i < CLIENT_HASH_SIZE; i++) {
5663
		INIT_LIST_HEAD(&nn->conf_id_hashtbl[i]);
5664
		INIT_LIST_HEAD(&nn->unconf_id_hashtbl[i]);
5665
	}
5666 5667
	for (i = 0; i < OWNER_HASH_SIZE; i++)
		INIT_LIST_HEAD(&nn->ownerstr_hashtbl[i]);
5668 5669
	for (i = 0; i < SESSION_HASH_SIZE; i++)
		INIT_LIST_HEAD(&nn->sessionid_hashtbl[i]);
5670
	nn->conf_name_tree = RB_ROOT;
5671
	nn->unconf_name_tree = RB_ROOT;
5672
	INIT_LIST_HEAD(&nn->client_lru);
5673
	INIT_LIST_HEAD(&nn->close_lru);
5674
	INIT_LIST_HEAD(&nn->del_recall_lru);
5675
	spin_lock_init(&nn->client_lock);
5676

5677
	INIT_DELAYED_WORK(&nn->laundromat_work, laundromat_main);
5678
	get_net(net);
5679

5680
	return 0;
5681

5682
err_sessionid:
5683
	kfree(nn->ownerstr_hashtbl);
5684 5685
err_ownerstr:
	kfree(nn->unconf_id_hashtbl);
5686 5687
err_unconf_id:
	kfree(nn->conf_id_hashtbl);
5688 5689
err:
	return -ENOMEM;
5690 5691 5692
}

static void
5693
nfs4_state_destroy_net(struct net *net)
5694 5695 5696 5697 5698 5699 5700 5701 5702 5703 5704
{
	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);
		}
	}
5705

5706 5707 5708 5709 5710
	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);
		}
5711 5712
	}

5713
	kfree(nn->sessionid_hashtbl);
5714
	kfree(nn->ownerstr_hashtbl);
5715
	kfree(nn->unconf_id_hashtbl);
5716
	kfree(nn->conf_id_hashtbl);
5717
	put_net(net);
5718 5719
}

5720
int
5721
nfs4_state_start_net(struct net *net)
5722
{
5723
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
5724 5725
	int ret;

5726
	ret = nfs4_state_create_net(net);
5727 5728
	if (ret)
		return ret;
5729
	nfsd4_client_tracking_init(net);
5730
	nn->boot_time = get_seconds();
5731
	locks_start_grace(net, &nn->nfsd4_manager);
5732
	nn->grace_ended = false;
5733
	printk(KERN_INFO "NFSD: starting %ld-second grace period (net %p)\n",
5734 5735
	       nn->nfsd4_grace, net);
	queue_delayed_work(laundry_wq, &nn->laundromat_work, nn->nfsd4_grace * HZ);
5736 5737 5738 5739 5740 5741 5742 5743 5744 5745
	return 0;
}

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

int
nfs4_state_start(void)
{
	int ret;

5746
	ret = set_callback_cred();
5747 5748
	if (ret)
		return -ENOMEM;
5749
	laundry_wq = create_singlethread_workqueue("nfsd4");
5750 5751 5752 5753
	if (laundry_wq == NULL) {
		ret = -ENOMEM;
		goto out_recovery;
	}
5754 5755 5756
	ret = nfsd4_create_callback_queue();
	if (ret)
		goto out_free_laundry;
5757

5758
	set_max_delegations();
5759

5760
	return 0;
5761

5762 5763
out_free_laundry:
	destroy_workqueue(laundry_wq);
5764
out_recovery:
5765
	return ret;
L
Linus Torvalds 已提交
5766 5767
}

5768
void
5769
nfs4_state_shutdown_net(struct net *net)
L
Linus Torvalds 已提交
5770 5771 5772
{
	struct nfs4_delegation *dp = NULL;
	struct list_head *pos, *next, reaplist;
5773
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
L
Linus Torvalds 已提交
5774

5775 5776
	cancel_delayed_work_sync(&nn->laundromat_work);
	locks_end_grace(&nn->nfsd4_manager);
5777

5778
	nfs4_lock_state();
L
Linus Torvalds 已提交
5779
	INIT_LIST_HEAD(&reaplist);
5780
	spin_lock(&state_lock);
5781
	list_for_each_safe(pos, next, &nn->del_recall_lru) {
L
Linus Torvalds 已提交
5782
		dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
5783 5784
		unhash_delegation_locked(dp);
		list_add(&dp->dl_recall_lru, &reaplist);
L
Linus Torvalds 已提交
5785
	}
5786
	spin_unlock(&state_lock);
L
Linus Torvalds 已提交
5787 5788
	list_for_each_safe(pos, next, &reaplist) {
		dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
5789
		list_del_init(&dp->dl_recall_lru);
5790
		nfs4_put_stid(&dp->dl_stid);
L
Linus Torvalds 已提交
5791 5792
	}

5793
	nfsd4_client_tracking_exit(net);
5794
	nfs4_state_destroy_net(net);
5795
	nfs4_unlock_state();
L
Linus Torvalds 已提交
5796 5797 5798 5799 5800
}

void
nfs4_state_shutdown(void)
{
5801
	destroy_workqueue(laundry_wq);
5802
	nfsd4_destroy_callback_queue();
L
Linus Torvalds 已提交
5803
}
5804 5805 5806 5807

static void
get_stateid(struct nfsd4_compound_state *cstate, stateid_t *stateid)
{
5808 5809
	if (HAS_STATE_ID(cstate, CURRENT_STATE_ID_FLAG) && CURRENT_STATEID(stateid))
		memcpy(stateid, &cstate->current_stateid, sizeof(stateid_t));
5810 5811 5812 5813 5814
}

static void
put_stateid(struct nfsd4_compound_state *cstate, stateid_t *stateid)
{
5815 5816 5817 5818 5819 5820 5821 5822 5823 5824
	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);
5825 5826
}

5827 5828 5829
/*
 * functions to set current state id
 */
5830 5831 5832 5833 5834 5835
void
nfsd4_set_opendowngradestateid(struct nfsd4_compound_state *cstate, struct nfsd4_open_downgrade *odp)
{
	put_stateid(cstate, &odp->od_stateid);
}

5836 5837 5838 5839 5840 5841
void
nfsd4_set_openstateid(struct nfsd4_compound_state *cstate, struct nfsd4_open *open)
{
	put_stateid(cstate, &open->op_stateid);
}

5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856
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
 */
5857

5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869
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);
}

5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881
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);
}

5882 5883 5884 5885 5886 5887 5888
void
nfsd4_get_closestateid(struct nfsd4_compound_state *cstate, struct nfsd4_close *close)
{
	get_stateid(cstate, &close->cl_stateid);
}

void
5889
nfsd4_get_lockustateid(struct nfsd4_compound_state *cstate, struct nfsd4_locku *locku)
5890
{
5891
	get_stateid(cstate, &locku->lu_stateid);
5892
}
5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904

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