inode.c 58.6 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7
/*
 *  linux/fs/nfs/inode.c
 *
 *  Copyright (C) 1992  Rick Sladkey
 *
 *  nfs inode and superblock handling functions
 *
A
Alan Cox 已提交
8
 *  Modularised by Alan Cox <alan@lxorguk.ukuu.org.uk>, while hacking some
L
Linus Torvalds 已提交
9 10 11 12 13 14 15 16 17
 *  experimental NFS changes. Modularisation taken straight from SYS5 fs.
 *
 *  Change to nfs_read_super() to permit NFS mounts to multi-homed hosts.
 *  J.S.Peatfield@damtp.cam.ac.uk
 *
 */

#include <linux/module.h>
#include <linux/init.h>
18
#include <linux/sched/signal.h>
L
Linus Torvalds 已提交
19 20 21 22 23 24 25 26 27
#include <linux/time.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/errno.h>
#include <linux/unistd.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/stats.h>
28
#include <linux/sunrpc/metrics.h>
L
Linus Torvalds 已提交
29 30 31 32 33 34 35
#include <linux/nfs_fs.h>
#include <linux/nfs_mount.h>
#include <linux/nfs4_mount.h>
#include <linux/lockd/bind.h>
#include <linux/seq_file.h>
#include <linux/mount.h>
#include <linux/vfs.h>
36 37
#include <linux/inet.h>
#include <linux/nfs_xdr.h>
38
#include <linux/slab.h>
39
#include <linux/compat.h>
40
#include <linux/freezer.h>
L
Linus Torvalds 已提交
41

42
#include <linux/uaccess.h>
L
Linus Torvalds 已提交
43

44
#include "nfs4_fs.h"
45
#include "callback.h"
L
Linus Torvalds 已提交
46
#include "delegation.h"
47
#include "iostat.h"
D
David Howells 已提交
48
#include "internal.h"
49
#include "fscache.h"
50
#include "pnfs.h"
51
#include "nfs.h"
52
#include "netns.h"
L
Linus Torvalds 已提交
53

54 55
#include "nfstrace.h"

L
Linus Torvalds 已提交
56 57
#define NFSDBG_FACILITY		NFSDBG_VFS

58 59 60
#define NFS_64_BIT_INODE_NUMBERS_ENABLED	1

/* Default is to see 64-bit inode numbers */
61
static bool enable_ino64 = NFS_64_BIT_INODE_NUMBERS_ENABLED;
62

L
Linus Torvalds 已提交
63
static void nfs_invalidate_inode(struct inode *);
64
static int nfs_update_inode(struct inode *, struct nfs_fattr *);
L
Linus Torvalds 已提交
65

66
static struct kmem_cache * nfs_inode_cachep;
67

L
Linus Torvalds 已提交
68 69 70 71 72 73
static inline unsigned long
nfs_fattr_to_ino_t(struct nfs_fattr *fattr)
{
	return nfs_fileid_to_ino_t(fattr->fileid);
}

74
static int nfs_wait_killable(int mode)
75
{
76
	freezable_schedule_unsafe();
77 78
	if (signal_pending_state(mode, current))
		return -ERESTARTSYS;
79 80
	return 0;
}
81 82 83 84 85

int nfs_wait_bit_killable(struct wait_bit_key *key, int mode)
{
	return nfs_wait_killable(mode);
}
B
Bryan Schumaker 已提交
86
EXPORT_SYMBOL_GPL(nfs_wait_bit_killable);
87

88 89 90 91 92
int nfs_wait_atomic_killable(atomic_t *p)
{
	return nfs_wait_killable(TASK_KILLABLE);
}

93 94 95 96 97 98 99 100 101
/**
 * nfs_compat_user_ino64 - returns the user-visible inode number
 * @fileid: 64-bit fileid
 *
 * This function returns a 32-bit inode number if the boot parameter
 * nfs.enable_ino64 is zero.
 */
u64 nfs_compat_user_ino64(u64 fileid)
{
102 103 104 105 106
#ifdef CONFIG_COMPAT
	compat_ulong_t ino;
#else	
	unsigned long ino;
#endif
107 108 109 110 111 112 113 114 115

	if (enable_ino64)
		return fileid;
	ino = fileid;
	if (sizeof(ino) < sizeof(fileid))
		ino ^= fileid >> (sizeof(fileid)-sizeof(ino)) * 8;
	return ino;
}

116 117 118 119 120 121
int nfs_drop_inode(struct inode *inode)
{
	return NFS_STALE(inode) || generic_drop_inode(inode);
}
EXPORT_SYMBOL_GPL(nfs_drop_inode);

122
void nfs_clear_inode(struct inode *inode)
L
Linus Torvalds 已提交
123
{
T
Trond Myklebust 已提交
124 125 126
	/*
	 * The following should never happen...
	 */
127 128
	WARN_ON_ONCE(nfs_have_writebacks(inode));
	WARN_ON_ONCE(!list_empty(&NFS_I(inode)->open_files));
129
	nfs_zap_acl_cache(inode);
130
	nfs_access_zap_cache(inode);
131
	nfs_fscache_clear_inode(inode);
L
Linus Torvalds 已提交
132
}
B
Bryan Schumaker 已提交
133
EXPORT_SYMBOL_GPL(nfs_clear_inode);
L
Linus Torvalds 已提交
134

135 136
void nfs_evict_inode(struct inode *inode)
{
137
	truncate_inode_pages_final(&inode->i_data);
138
	clear_inode(inode);
139 140 141
	nfs_clear_inode(inode);
}

142
int nfs_sync_inode(struct inode *inode)
143
{
144
	inode_dio_wait(inode);
145 146
	return nfs_wb_all(inode);
}
147
EXPORT_SYMBOL_GPL(nfs_sync_inode);
148

T
Trond Myklebust 已提交
149 150 151 152 153
/**
 * nfs_sync_mapping - helper to flush all mmapped dirty data to disk
 */
int nfs_sync_mapping(struct address_space *mapping)
{
T
Trond Myklebust 已提交
154
	int ret = 0;
T
Trond Myklebust 已提交
155

T
Trond Myklebust 已提交
156 157 158 159
	if (mapping->nrpages != 0) {
		unmap_mapping_range(mapping, 0, 0, 0);
		ret = nfs_wb_all(mapping->host);
	}
T
Trond Myklebust 已提交
160 161 162
	return ret;
}

163 164 165 166 167 168 169
static int nfs_attribute_timeout(struct inode *inode)
{
	struct nfs_inode *nfsi = NFS_I(inode);

	return !time_in_range_open(jiffies, nfsi->read_cache_jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo);
}

170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
static bool nfs_check_cache_invalid_delegated(struct inode *inode, unsigned long flags)
{
	unsigned long cache_validity = READ_ONCE(NFS_I(inode)->cache_validity);

	/* Special case for the pagecache or access cache */
	if (flags == NFS_INO_REVAL_PAGECACHE &&
	    !(cache_validity & NFS_INO_REVAL_FORCED))
		return false;
	return (cache_validity & flags) != 0;
}

static bool nfs_check_cache_invalid_not_delegated(struct inode *inode, unsigned long flags)
{
	unsigned long cache_validity = READ_ONCE(NFS_I(inode)->cache_validity);

	if ((cache_validity & flags) != 0)
		return true;
	if (nfs_attribute_timeout(inode))
		return true;
	return false;
}

bool nfs_check_cache_invalid(struct inode *inode, unsigned long flags)
{
	if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ))
		return nfs_check_cache_invalid_delegated(inode, flags);

	return nfs_check_cache_invalid_not_delegated(inode, flags);
}

200 201 202 203 204 205 206 207 208 209 210
static void nfs_set_cache_invalid(struct inode *inode, unsigned long flags)
{
	struct nfs_inode *nfsi = NFS_I(inode);

	if (inode->i_mapping->nrpages == 0)
		flags &= ~NFS_INO_INVALID_DATA;
	nfsi->cache_validity |= flags;
	if (flags & NFS_INO_INVALID_DATA)
		nfs_fscache_invalidate(inode);
}

L
Linus Torvalds 已提交
211 212 213
/*
 * Invalidate the local caches
 */
214
static void nfs_zap_caches_locked(struct inode *inode)
L
Linus Torvalds 已提交
215 216 217 218
{
	struct nfs_inode *nfsi = NFS_I(inode);
	int mode = inode->i_mode;

C
Chuck Lever 已提交
219 220
	nfs_inc_stats(inode, NFSIOS_ATTRINVALIDATE);

221 222
	nfsi->attrtimeo = NFS_MINATTRTIMEO(inode);
	nfsi->attrtimeo_timestamp = jiffies;
L
Linus Torvalds 已提交
223

224
	memset(NFS_I(inode)->cookieverf, 0, sizeof(NFS_I(inode)->cookieverf));
D
David Howells 已提交
225
	if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) {
226
		nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR
227 228 229
					| NFS_INO_INVALID_DATA
					| NFS_INO_INVALID_ACCESS
					| NFS_INO_INVALID_ACL
230
					| NFS_INO_REVAL_PAGECACHE);
231
	} else
232
		nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR
233 234
					| NFS_INO_INVALID_ACCESS
					| NFS_INO_INVALID_ACL
235
					| NFS_INO_REVAL_PAGECACHE);
236
	nfs_zap_label_cache_locked(nfsi);
237
}
238

239 240 241 242
void nfs_zap_caches(struct inode *inode)
{
	spin_lock(&inode->i_lock);
	nfs_zap_caches_locked(inode);
243
	spin_unlock(&inode->i_lock);
244 245
}

246 247 248 249
void nfs_zap_mapping(struct inode *inode, struct address_space *mapping)
{
	if (mapping->nrpages != 0) {
		spin_lock(&inode->i_lock);
250
		nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA);
251 252 253 254
		spin_unlock(&inode->i_lock);
	}
}

255
void nfs_zap_acl_cache(struct inode *inode)
256 257 258 259 260 261
{
	void (*clear_acl_cache)(struct inode *);

	clear_acl_cache = NFS_PROTO(inode)->clear_acl_cache;
	if (clear_acl_cache != NULL)
		clear_acl_cache(inode);
262
	spin_lock(&inode->i_lock);
263
	NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_ACL;
264
	spin_unlock(&inode->i_lock);
L
Linus Torvalds 已提交
265
}
B
Bryan Schumaker 已提交
266
EXPORT_SYMBOL_GPL(nfs_zap_acl_cache);
L
Linus Torvalds 已提交
267

268 269 270
void nfs_invalidate_atime(struct inode *inode)
{
	spin_lock(&inode->i_lock);
271
	nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATIME);
272 273
	spin_unlock(&inode->i_lock);
}
B
Bryan Schumaker 已提交
274
EXPORT_SYMBOL_GPL(nfs_invalidate_atime);
275

L
Linus Torvalds 已提交
276
/*
277 278
 * Invalidate, but do not unhash, the inode.
 * NB: must be called with inode->i_lock held!
L
Linus Torvalds 已提交
279
 */
280
static void nfs_invalidate_inode(struct inode *inode)
L
Linus Torvalds 已提交
281
{
B
Benny Halevy 已提交
282
	set_bit(NFS_INO_STALE, &NFS_I(inode)->flags);
283
	nfs_zap_caches_locked(inode);
L
Linus Torvalds 已提交
284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305
}

struct nfs_find_desc {
	struct nfs_fh		*fh;
	struct nfs_fattr	*fattr;
};

/*
 * In NFSv3 we can have 64bit inode numbers. In order to support
 * this, and re-exported directories (also seen in NFSv2)
 * we are forced to allow 2 different inodes to have the same
 * i_ino.
 */
static int
nfs_find_actor(struct inode *inode, void *opaque)
{
	struct nfs_find_desc	*desc = (struct nfs_find_desc *)opaque;
	struct nfs_fh		*fh = desc->fh;
	struct nfs_fattr	*fattr = desc->fattr;

	if (NFS_FILEID(inode) != fattr->fileid)
		return 0;
306 307
	if ((S_IFMT & inode->i_mode) != (S_IFMT & fattr->mode))
		return 0;
L
Linus Torvalds 已提交
308 309 310 311 312 313 314 315 316 317 318 319 320
	if (nfs_compare_fh(NFS_FH(inode), fh))
		return 0;
	if (is_bad_inode(inode) || NFS_STALE(inode))
		return 0;
	return 1;
}

static int
nfs_init_locked(struct inode *inode, void *opaque)
{
	struct nfs_find_desc	*desc = (struct nfs_find_desc *)opaque;
	struct nfs_fattr	*fattr = desc->fattr;

321
	set_nfs_fileid(inode, fattr->fileid);
322
	inode->i_mode = fattr->mode;
L
Linus Torvalds 已提交
323 324 325 326
	nfs_copy_fh(NFS_FH(inode), desc->fh);
	return 0;
}

327
#ifdef CONFIG_NFS_V4_SECURITY_LABEL
328 329 330 331 332 333 334
static void nfs_clear_label_invalid(struct inode *inode)
{
	spin_lock(&inode->i_lock);
	NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_LABEL;
	spin_unlock(&inode->i_lock);
}

335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351
void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr,
					struct nfs4_label *label)
{
	int error;

	if (label == NULL)
		return;

	if ((fattr->valid & NFS_ATTR_FATTR_V4_SECURITY_LABEL) && inode->i_security) {
		error = security_inode_notifysecctx(inode, label->label,
				label->len);
		if (error)
			printk(KERN_ERR "%s() %s %d "
					"security_inode_notifysecctx() %d\n",
					__func__,
					(char *)label->label,
					label->len, error);
352
		nfs_clear_label_invalid(inode);
353 354 355
	}
}

356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380
struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags)
{
	struct nfs4_label *label = NULL;
	int minor_version = server->nfs_client->cl_minorversion;

	if (minor_version < 2)
		return label;

	if (!(server->caps & NFS_CAP_SECURITY_LABEL))
		return label;

	label = kzalloc(sizeof(struct nfs4_label), flags);
	if (label == NULL)
		return ERR_PTR(-ENOMEM);

	label->label = kzalloc(NFS4_MAXLABELLEN, flags);
	if (label->label == NULL) {
		kfree(label);
		return ERR_PTR(-ENOMEM);
	}
	label->len = NFS4_MAXLABELLEN;

	return label;
}
EXPORT_SYMBOL_GPL(nfs4_label_alloc);
381
#else
382
void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr,
383 384 385
					struct nfs4_label *label)
{
}
386
#endif
387
EXPORT_SYMBOL_GPL(nfs_setsecurity);
388

L
Linus Torvalds 已提交
389 390 391 392 393
/*
 * This is our front-end to iget that looks up inodes by file handle
 * instead of inode number.
 */
struct inode *
394
nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, struct nfs4_label *label)
L
Linus Torvalds 已提交
395 396 397 398 399
{
	struct nfs_find_desc desc = {
		.fh	= fh,
		.fattr	= fattr
	};
400
	struct inode *inode = ERR_PTR(-ENOENT);
L
Linus Torvalds 已提交
401 402
	unsigned long hash;

403 404
	nfs_attr_check_mountpoint(sb, fattr);

405 406 407
	if (nfs_attr_use_mounted_on_fileid(fattr))
		fattr->fileid = fattr->mounted_on_fileid;
	else if ((fattr->valid & NFS_ATTR_FATTR_FILEID) == 0)
L
Linus Torvalds 已提交
408
		goto out_no_inode;
409
	if ((fattr->valid & NFS_ATTR_FATTR_TYPE) == 0)
L
Linus Torvalds 已提交
410 411 412 413
		goto out_no_inode;

	hash = nfs_fattr_to_ino_t(fattr);

414 415 416
	inode = iget5_locked(sb, hash, nfs_find_actor, nfs_init_locked, &desc);
	if (inode == NULL) {
		inode = ERR_PTR(-ENOMEM);
L
Linus Torvalds 已提交
417
		goto out_no_inode;
418
	}
L
Linus Torvalds 已提交
419 420 421

	if (inode->i_state & I_NEW) {
		struct nfs_inode *nfsi = NFS_I(inode);
422
		unsigned long now = jiffies;
L
Linus Torvalds 已提交
423 424 425 426 427 428 429 430

		/* We set i_ino for the few things that still rely on it,
		 * such as stat(2) */
		inode->i_ino = hash;

		/* We can't support update_atime(), since the server will reset it */
		inode->i_flags |= S_NOATIME|S_NOCMTIME;
		inode->i_mode = fattr->mode;
431 432
		if ((fattr->valid & NFS_ATTR_FATTR_MODE) == 0
				&& nfs_server_capable(inode, NFS_CAP_MODE))
433
			nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
L
Linus Torvalds 已提交
434 435 436
		/* Why so? Because we want revalidate for devices/FIFOs, and
		 * that's precisely what we have in nfs_file_inode_operations.
		 */
437
		inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->file_inode_ops;
L
Linus Torvalds 已提交
438
		if (S_ISREG(inode->i_mode)) {
439
			inode->i_fop = NFS_SB(sb)->nfs_client->rpc_ops->file_ops;
L
Linus Torvalds 已提交
440 441
			inode->i_data.a_ops = &nfs_file_aops;
		} else if (S_ISDIR(inode->i_mode)) {
442
			inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->dir_inode_ops;
L
Linus Torvalds 已提交
443
			inode->i_fop = &nfs_dir_operations;
444
			inode->i_data.a_ops = &nfs_dir_aops;
445
			/* Deal with crossing mountpoints */
446 447
			if (fattr->valid & NFS_ATTR_FATTR_MOUNTPOINT ||
					fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) {
M
Manoj Naik 已提交
448 449 450 451
				if (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL)
					inode->i_op = &nfs_referral_inode_operations;
				else
					inode->i_op = &nfs_mountpoint_inode_operations;
452
				inode->i_fop = NULL;
453
				inode->i_flags |= S_AUTOMOUNT;
454
			}
455
		} else if (S_ISLNK(inode->i_mode)) {
L
Linus Torvalds 已提交
456
			inode->i_op = &nfs_symlink_inode_operations;
457 458
			inode_nohighmem(inode);
		} else
L
Linus Torvalds 已提交
459 460
			init_special_inode(inode, inode->i_mode, fattr->rdev);

461 462 463
		memset(&inode->i_atime, 0, sizeof(inode->i_atime));
		memset(&inode->i_mtime, 0, sizeof(inode->i_mtime));
		memset(&inode->i_ctime, 0, sizeof(inode->i_ctime));
464
		inode->i_version = 0;
465
		inode->i_size = 0;
466
		clear_nlink(inode);
467 468
		inode->i_uid = make_kuid(&init_user_ns, -2);
		inode->i_gid = make_kgid(&init_user_ns, -2);
469 470
		inode->i_blocks = 0;
		memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
471 472
		nfsi->write_io = 0;
		nfsi->read_io = 0;
473

474
		nfsi->read_cache_jiffies = fattr->time_start;
475
		nfsi->attr_gencount = fattr->gencount;
476 477
		if (fattr->valid & NFS_ATTR_FATTR_ATIME)
			inode->i_atime = fattr->atime;
478
		else if (nfs_server_capable(inode, NFS_CAP_ATIME))
479
			nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
480 481
		if (fattr->valid & NFS_ATTR_FATTR_MTIME)
			inode->i_mtime = fattr->mtime;
482
		else if (nfs_server_capable(inode, NFS_CAP_MTIME))
483
			nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
484 485
		if (fattr->valid & NFS_ATTR_FATTR_CTIME)
			inode->i_ctime = fattr->ctime;
486
		else if (nfs_server_capable(inode, NFS_CAP_CTIME))
487
			nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
488
		if (fattr->valid & NFS_ATTR_FATTR_CHANGE)
489
			inode->i_version = fattr->change_attr;
490
		else
491 492
			nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR
				| NFS_INO_REVAL_PAGECACHE);
493 494
		if (fattr->valid & NFS_ATTR_FATTR_SIZE)
			inode->i_size = nfs_size_to_loff_t(fattr->size);
495
		else
496 497
			nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR
				| NFS_INO_REVAL_PAGECACHE);
498
		if (fattr->valid & NFS_ATTR_FATTR_NLINK)
M
Miklos Szeredi 已提交
499
			set_nlink(inode, fattr->nlink);
500
		else if (nfs_server_capable(inode, NFS_CAP_NLINK))
501
			nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
502 503
		if (fattr->valid & NFS_ATTR_FATTR_OWNER)
			inode->i_uid = fattr->uid;
504
		else if (nfs_server_capable(inode, NFS_CAP_OWNER))
505
			nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
506 507
		if (fattr->valid & NFS_ATTR_FATTR_GROUP)
			inode->i_gid = fattr->gid;
508
		else if (nfs_server_capable(inode, NFS_CAP_OWNER_GROUP))
509
			nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
510 511 512
		if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED)
			inode->i_blocks = fattr->du.nfs2.blocks;
		if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) {
L
Linus Torvalds 已提交
513 514 515 516 517
			/*
			 * report the blocks in 512byte units
			 */
			inode->i_blocks = nfs_calc_block_size(fattr->du.nfs3.used);
		}
518 519 520

		nfs_setsecurity(inode, fattr, label);

L
Linus Torvalds 已提交
521
		nfsi->attrtimeo = NFS_MINATTRTIMEO(inode);
522
		nfsi->attrtimeo_timestamp = now;
523
		nfsi->access_cache = RB_ROOT;
L
Linus Torvalds 已提交
524

525
		nfs_fscache_init_inode(inode);
D
David Howells 已提交
526

L
Linus Torvalds 已提交
527
		unlock_new_inode(inode);
528 529 530 531 532 533 534 535
	} else {
		int err = nfs_refresh_inode(inode, fattr);
		if (err < 0) {
			iput(inode);
			inode = ERR_PTR(err);
			goto out_no_inode;
		}
	}
536
	dprintk("NFS: nfs_fhget(%s/%Lu fh_crc=0x%08x ct=%d)\n",
L
Linus Torvalds 已提交
537
		inode->i_sb->s_id,
538
		(unsigned long long)NFS_FILEID(inode),
539
		nfs_display_fhandle_hash(fh),
L
Linus Torvalds 已提交
540 541 542 543 544 545
		atomic_read(&inode->i_count));

out:
	return inode;

out_no_inode:
546
	dprintk("nfs_fhget: iget failed with error %ld\n", PTR_ERR(inode));
L
Linus Torvalds 已提交
547 548
	goto out;
}
B
Bryan Schumaker 已提交
549
EXPORT_SYMBOL_GPL(nfs_fhget);
L
Linus Torvalds 已提交
550

551
#define NFS_VALID_ATTRS (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|ATTR_ATIME|ATTR_ATIME_SET|ATTR_MTIME|ATTR_MTIME_SET|ATTR_FILE|ATTR_OPEN)
L
Linus Torvalds 已提交
552 553 554 555

int
nfs_setattr(struct dentry *dentry, struct iattr *attr)
{
556
	struct inode *inode = d_inode(dentry);
557
	struct nfs_fattr *fattr;
558
	int error = 0;
L
Linus Torvalds 已提交
559

C
Chuck Lever 已提交
560 561
	nfs_inc_stats(inode, NFSIOS_VFSSETATTR);

562 563 564 565
	/* skip mode change if it's just for clearing setuid/setgid */
	if (attr->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
		attr->ia_valid &= ~ATTR_MODE;

L
Linus Torvalds 已提交
566
	if (attr->ia_valid & ATTR_SIZE) {
567 568
		BUG_ON(!S_ISREG(inode->i_mode));

569 570 571 572 573
		error = inode_newsize_ok(inode, attr->ia_size);
		if (error)
			return error;

		if (attr->ia_size == i_size_read(inode))
L
Linus Torvalds 已提交
574 575 576 577 578
			attr->ia_valid &= ~ATTR_SIZE;
	}

	/* Optimization: if the end result is no change, don't RPC */
	attr->ia_valid &= NFS_VALID_ATTRS;
579
	if ((attr->ia_valid & ~(ATTR_FILE|ATTR_OPEN)) == 0)
L
Linus Torvalds 已提交
580 581
		return 0;

582 583
	trace_nfs_setattr_enter(inode);

584
	/* Write all dirty data */
585 586
	if (S_ISREG(inode->i_mode))
		nfs_sync_inode(inode);
587 588

	fattr = nfs_alloc_fattr();
589 590
	if (fattr == NULL) {
		error = -ENOMEM;
591
		goto out;
592 593
	}

594 595 596 597
	/*
	 * Return any delegations if we're going to change ACLs
	 */
	if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0)
598
		NFS_PROTO(inode)->return_delegation(inode);
599
	error = NFS_PROTO(inode)->setattr(dentry, fattr, attr);
600
	if (error == 0)
601
		error = nfs_refresh_inode(inode, fattr);
602 603
	nfs_free_fattr(fattr);
out:
604
	trace_nfs_setattr_exit(inode, error);
605 606
	return error;
}
B
Bryan Schumaker 已提交
607
EXPORT_SYMBOL_GPL(nfs_setattr);
608

609 610 611 612 613 614 615 616
/**
 * nfs_vmtruncate - unmap mappings "freed" by truncate() syscall
 * @inode: inode of the file used
 * @offset: file offset to start truncating
 *
 * This is a copy of the common vmtruncate, but with the locking
 * corrected to take into account the fact that NFS requires
 * inode->i_size to be updated under the inode->i_lock.
617
 * Note: must be called with inode->i_lock held!
618 619 620
 */
static int nfs_vmtruncate(struct inode * inode, loff_t offset)
{
N
npiggin@suse.de 已提交
621
	int err;
622

N
npiggin@suse.de 已提交
623 624 625
	err = inode_newsize_ok(inode, offset);
	if (err)
		goto out;
626

N
npiggin@suse.de 已提交
627
	i_size_write(inode, offset);
628 629 630
	/* Optimisation */
	if (offset == 0)
		NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_DATA;
N
npiggin@suse.de 已提交
631

632
	spin_unlock(&inode->i_lock);
633
	truncate_pagecache(inode, offset);
634
	spin_lock(&inode->i_lock);
N
npiggin@suse.de 已提交
635 636
out:
	return err;
637 638
}

639 640 641 642 643 644 645 646
/**
 * nfs_setattr_update_inode - Update inode metadata after a setattr call.
 * @inode: pointer to struct inode
 * @attr: pointer to struct iattr
 *
 * Note: we do this in the *proc.c in order to ensure that
 *       it works for things like exclusive creates too.
 */
647 648
void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr,
		struct nfs_fattr *fattr)
649
{
650 651 652 653 654
	/* Barrier: bump the attribute generation count. */
	nfs_fattr_set_barrier(fattr);

	spin_lock(&inode->i_lock);
	NFS_I(inode)->attr_gencount = fattr->gencount;
655
	if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0) {
L
Linus Torvalds 已提交
656
		if ((attr->ia_valid & ATTR_MODE) != 0) {
657 658
			int mode = attr->ia_mode & S_IALLUGO;
			mode |= inode->i_mode & ~S_IALLUGO;
L
Linus Torvalds 已提交
659 660 661 662 663 664
			inode->i_mode = mode;
		}
		if ((attr->ia_valid & ATTR_UID) != 0)
			inode->i_uid = attr->ia_uid;
		if ((attr->ia_valid & ATTR_GID) != 0)
			inode->i_gid = attr->ia_gid;
665 666
		nfs_set_cache_invalid(inode, NFS_INO_INVALID_ACCESS
				| NFS_INO_INVALID_ACL);
667 668
	}
	if ((attr->ia_valid & ATTR_SIZE) != 0) {
C
Chuck Lever 已提交
669
		nfs_inc_stats(inode, NFSIOS_SETATTRTRUNC);
670
		nfs_vmtruncate(inode, attr->ia_size);
671
	}
672 673 674 675
	if (fattr->valid)
		nfs_update_inode(inode, fattr);
	else
		NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR;
676
	spin_unlock(&inode->i_lock);
L
Linus Torvalds 已提交
677
}
B
Bryan Schumaker 已提交
678
EXPORT_SYMBOL_GPL(nfs_setattr_update_inode);
L
Linus Torvalds 已提交
679

680
static void nfs_readdirplus_parent_cache_miss(struct dentry *dentry)
681 682 683
{
	struct dentry *parent;

684 685
	if (!nfs_server_capable(d_inode(dentry), NFS_CAP_READDIRPLUS))
		return;
686
	parent = dget_parent(dentry);
687
	nfs_force_use_readdirplus(d_inode(parent));
688 689 690
	dput(parent);
}

691 692 693 694 695 696 697 698 699 700 701
static void nfs_readdirplus_parent_cache_hit(struct dentry *dentry)
{
	struct dentry *parent;

	if (!nfs_server_capable(d_inode(dentry), NFS_CAP_READDIRPLUS))
		return;
	parent = dget_parent(dentry);
	nfs_advise_use_readdirplus(d_inode(parent));
	dput(parent);
}

702 703 704 705 706 707 708 709 710 711
static bool nfs_need_revalidate_inode(struct inode *inode)
{
	if (NFS_I(inode)->cache_validity &
			(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_LABEL))
		return true;
	if (nfs_attribute_cache_expired(inode))
		return true;
	return false;
}

712 713
int nfs_getattr(const struct path *path, struct kstat *stat,
		u32 request_mask, unsigned int query_flags)
L
Linus Torvalds 已提交
714
{
715
	struct inode *inode = d_inode(path->dentry);
716
	int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME;
717
	int err = 0;
L
Linus Torvalds 已提交
718

719
	trace_nfs_getattr_enter(inode);
720
	/* Flush out writes to the server in order to update c/mtime.  */
721
	if (S_ISREG(inode->i_mode)) {
722
		err = filemap_write_and_wait(inode->i_mapping);
723 724
		if (err)
			goto out;
725
	}
726 727 728 729 730 731 732 733 734 735

	/*
	 * We may force a getattr if the user cares about atime.
	 *
	 * Note that we only have to check the vfsmount flags here:
	 *  - NFS always sets S_NOATIME by so checking it would give a
	 *    bogus result
	 *  - NFS never sets MS_NOATIME or MS_NODIRATIME so there is
	 *    no point in checking those.
	 */
736 737
	if ((path->mnt->mnt_flags & MNT_NOATIME) ||
	    ((path->mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)))
L
Linus Torvalds 已提交
738
		need_atime = 0;
739

740 741 742
	if (need_atime || nfs_need_revalidate_inode(inode)) {
		struct nfs_server *server = NFS_SERVER(inode);

743 744 745 746
		if (!(server->flags & NFS_MOUNT_NOAC))
			nfs_readdirplus_parent_cache_miss(path->dentry);
		else
			nfs_readdirplus_parent_cache_hit(path->dentry);
747
		err = __nfs_revalidate_inode(server, inode);
748
	} else
749
		nfs_readdirplus_parent_cache_hit(path->dentry);
P
Peter Staubach 已提交
750
	if (!err) {
L
Linus Torvalds 已提交
751
		generic_fillattr(inode, stat);
752
		stat->ino = nfs_compat_user_ino64(NFS_FILEID(inode));
753 754
		if (S_ISDIR(inode->i_mode))
			stat->blksize = NFS_SERVER(inode)->dtsize;
P
Peter Staubach 已提交
755
	}
756
out:
757
	trace_nfs_getattr_exit(inode, err);
L
Linus Torvalds 已提交
758 759
	return err;
}
B
Bryan Schumaker 已提交
760
EXPORT_SYMBOL_GPL(nfs_getattr);
L
Linus Torvalds 已提交
761

762 763 764
static void nfs_init_lock_context(struct nfs_lock_context *l_ctx)
{
	atomic_set(&l_ctx->count, 1);
N
NeilBrown 已提交
765
	l_ctx->lockowner = current->files;
766
	INIT_LIST_HEAD(&l_ctx->list);
767
	atomic_set(&l_ctx->io_count, 0);
768 769 770 771
}

static struct nfs_lock_context *__nfs_find_lock_context(struct nfs_open_context *ctx)
{
772 773
	struct nfs_lock_context *head = &ctx->lock_context;
	struct nfs_lock_context *pos = head;
774

775
	do {
N
NeilBrown 已提交
776
		if (pos->lockowner != current->files)
777 778 779
			continue;
		atomic_inc(&pos->count);
		return pos;
780
	} while ((pos = list_entry(pos->list.next, typeof(*pos), list)) != head);
781 782 783 784 785 786
	return NULL;
}

struct nfs_lock_context *nfs_get_lock_context(struct nfs_open_context *ctx)
{
	struct nfs_lock_context *res, *new = NULL;
787
	struct inode *inode = d_inode(ctx->dentry);
788 789 790 791 792 793 794

	spin_lock(&inode->i_lock);
	res = __nfs_find_lock_context(ctx);
	if (res == NULL) {
		spin_unlock(&inode->i_lock);
		new = kmalloc(sizeof(*new), GFP_KERNEL);
		if (new == NULL)
795
			return ERR_PTR(-ENOMEM);
796 797 798 799 800 801 802 803 804 805 806 807 808 809
		nfs_init_lock_context(new);
		spin_lock(&inode->i_lock);
		res = __nfs_find_lock_context(ctx);
		if (res == NULL) {
			list_add_tail(&new->list, &ctx->lock_context.list);
			new->open_context = ctx;
			res = new;
			new = NULL;
		}
	}
	spin_unlock(&inode->i_lock);
	kfree(new);
	return res;
}
A
Anna Schumaker 已提交
810
EXPORT_SYMBOL_GPL(nfs_get_lock_context);
811 812 813 814

void nfs_put_lock_context(struct nfs_lock_context *l_ctx)
{
	struct nfs_open_context *ctx = l_ctx->open_context;
815
	struct inode *inode = d_inode(ctx->dentry);
816 817 818 819 820 821 822

	if (!atomic_dec_and_lock(&l_ctx->count, &inode->i_lock))
		return;
	list_del(&l_ctx->list);
	spin_unlock(&inode->i_lock);
	kfree(l_ctx);
}
A
Anna Schumaker 已提交
823
EXPORT_SYMBOL_GPL(nfs_put_lock_context);
824

T
Trond Myklebust 已提交
825 826 827 828 829
/**
 * nfs_close_context - Common close_context() routine NFSv2/v3
 * @ctx: pointer to context
 * @is_sync: is this a synchronous close
 *
830 831 832
 * Ensure that the attributes are up to date if we're mounted
 * with close-to-open semantics and we have cached data that will
 * need to be revalidated on open.
T
Trond Myklebust 已提交
833 834 835
 */
void nfs_close_context(struct nfs_open_context *ctx, int is_sync)
{
836
	struct nfs_inode *nfsi;
T
Trond Myklebust 已提交
837 838 839 840 841 842 843
	struct inode *inode;
	struct nfs_server *server;

	if (!(ctx->mode & FMODE_WRITE))
		return;
	if (!is_sync)
		return;
844
	inode = d_inode(ctx->dentry);
845 846
	if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ))
		return;
847 848 849 850 851 852
	nfsi = NFS_I(inode);
	if (inode->i_mapping->nrpages == 0)
		return;
	if (nfsi->cache_validity & NFS_INO_INVALID_DATA)
		return;
	if (!list_empty(&nfsi->open_files))
T
Trond Myklebust 已提交
853 854 855 856 857 858
		return;
	server = NFS_SERVER(inode);
	if (server->flags & NFS_MOUNT_NOCTO)
		return;
	nfs_revalidate_inode(server, inode);
}
B
Bryan Schumaker 已提交
859
EXPORT_SYMBOL_GPL(nfs_close_context);
T
Trond Myklebust 已提交
860

N
NeilBrown 已提交
861 862 863
struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry,
						fmode_t f_mode,
						struct file *filp)
L
Linus Torvalds 已提交
864 865
{
	struct nfs_open_context *ctx;
866 867 868
	struct rpc_cred *cred = rpc_lookup_cred();
	if (IS_ERR(cred))
		return ERR_CAST(cred);
L
Linus Torvalds 已提交
869

870
	ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
871 872 873
	if (!ctx) {
		put_rpccred(cred);
		return ERR_PTR(-ENOMEM);
L
Linus Torvalds 已提交
874
	}
875 876 877 878 879 880 881
	nfs_sb_active(dentry->d_sb);
	ctx->dentry = dget(dentry);
	ctx->cred = cred;
	ctx->state = NULL;
	ctx->mode = f_mode;
	ctx->flags = 0;
	ctx->error = 0;
N
NeilBrown 已提交
882
	ctx->flock_owner = (fl_owner_t)filp;
883 884 885
	nfs_init_lock_context(&ctx->lock_context);
	ctx->lock_context.open_context = ctx;
	INIT_LIST_HEAD(&ctx->list);
886
	ctx->mdsthreshold = NULL;
L
Linus Torvalds 已提交
887 888
	return ctx;
}
B
Bryan Schumaker 已提交
889
EXPORT_SYMBOL_GPL(alloc_nfs_open_context);
L
Linus Torvalds 已提交
890 891 892 893

struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx)
{
	if (ctx != NULL)
894
		atomic_inc(&ctx->lock_context.count);
L
Linus Torvalds 已提交
895 896
	return ctx;
}
B
Bryan Schumaker 已提交
897
EXPORT_SYMBOL_GPL(get_nfs_open_context);
L
Linus Torvalds 已提交
898

T
Trond Myklebust 已提交
899
static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync)
L
Linus Torvalds 已提交
900
{
901
	struct inode *inode = d_inode(ctx->dentry);
902
	struct super_block *sb = ctx->dentry->d_sb;
903

904
	if (!list_empty(&ctx->list)) {
905 906 907 908 909
		if (!atomic_dec_and_lock(&ctx->lock_context.count, &inode->i_lock))
			return;
		list_del(&ctx->list);
		spin_unlock(&inode->i_lock);
	} else if (!atomic_dec_and_test(&ctx->lock_context.count))
T
Trond Myklebust 已提交
910
		return;
911 912
	if (inode != NULL)
		NFS_PROTO(inode)->close_context(ctx, is_sync);
913 914
	if (ctx->cred != NULL)
		put_rpccred(ctx->cred);
915
	dput(ctx->dentry);
916
	nfs_sb_deactive(sb);
917
	kfree(ctx->mdsthreshold);
918 919 920
	kfree(ctx);
}

921 922 923 924
void put_nfs_open_context(struct nfs_open_context *ctx)
{
	__put_nfs_open_context(ctx, 0);
}
B
Bryan Schumaker 已提交
925
EXPORT_SYMBOL_GPL(put_nfs_open_context);
926

927 928 929 930 931
static void put_nfs_open_context_sync(struct nfs_open_context *ctx)
{
	__put_nfs_open_context(ctx, 1);
}

L
Linus Torvalds 已提交
932 933 934 935
/*
 * Ensure that mmap has a recent RPC credential for use when writing out
 * shared pages
 */
936
void nfs_inode_attach_open_context(struct nfs_open_context *ctx)
L
Linus Torvalds 已提交
937
{
938
	struct inode *inode = d_inode(ctx->dentry);
L
Linus Torvalds 已提交
939 940 941
	struct nfs_inode *nfsi = NFS_I(inode);

	spin_lock(&inode->i_lock);
942 943 944 945
	if (ctx->mode & FMODE_WRITE)
		list_add(&ctx->list, &nfsi->open_files);
	else
		list_add_tail(&ctx->list, &nfsi->open_files);
L
Linus Torvalds 已提交
946 947
	spin_unlock(&inode->i_lock);
}
948 949 950 951 952 953 954 955
EXPORT_SYMBOL_GPL(nfs_inode_attach_open_context);

void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx)
{
	filp->private_data = get_nfs_open_context(ctx);
	if (list_empty(&ctx->list))
		nfs_inode_attach_open_context(ctx);
}
B
Bryan Schumaker 已提交
956
EXPORT_SYMBOL_GPL(nfs_file_set_open_context);
L
Linus Torvalds 已提交
957

958 959 960
/*
 * Given an inode, search for an open context with the desired characteristics
 */
961
struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_cred *cred, fmode_t mode)
L
Linus Torvalds 已提交
962 963 964 965 966 967
{
	struct nfs_inode *nfsi = NFS_I(inode);
	struct nfs_open_context *pos, *ctx = NULL;

	spin_lock(&inode->i_lock);
	list_for_each_entry(pos, &nfsi->open_files, list) {
968 969
		if (cred != NULL && pos->cred != cred)
			continue;
970 971 972 973
		if ((pos->mode & (FMODE_READ|FMODE_WRITE)) != mode)
			continue;
		ctx = get_nfs_open_context(pos);
		break;
L
Linus Torvalds 已提交
974 975 976 977 978
	}
	spin_unlock(&inode->i_lock);
	return ctx;
}

A
Anna Schumaker 已提交
979
void nfs_file_clear_open_context(struct file *filp)
L
Linus Torvalds 已提交
980
{
981
	struct nfs_open_context *ctx = nfs_file_open_context(filp);
L
Linus Torvalds 已提交
982 983

	if (ctx) {
984
		struct inode *inode = d_inode(ctx->dentry);
985

986 987 988 989 990 991
		/*
		 * We fatal error on write before. Try to writeback
		 * every page again.
		 */
		if (ctx->error < 0)
			invalidate_inode_pages2(inode->i_mapping);
L
Linus Torvalds 已提交
992 993 994 995
		filp->private_data = NULL;
		spin_lock(&inode->i_lock);
		list_move_tail(&ctx->list, &NFS_I(inode)->open_files);
		spin_unlock(&inode->i_lock);
996
		put_nfs_open_context_sync(ctx);
L
Linus Torvalds 已提交
997 998 999 1000 1001 1002 1003 1004 1005 1006
	}
}

/*
 * These allocate and release file read/write context information.
 */
int nfs_open(struct inode *inode, struct file *filp)
{
	struct nfs_open_context *ctx;

N
NeilBrown 已提交
1007
	ctx = alloc_nfs_open_context(file_dentry(filp), filp->f_mode, filp);
1008 1009
	if (IS_ERR(ctx))
		return PTR_ERR(ctx);
L
Linus Torvalds 已提交
1010 1011
	nfs_file_set_open_context(filp, ctx);
	put_nfs_open_context(ctx);
1012
	nfs_fscache_open_file(inode, filp);
L
Linus Torvalds 已提交
1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023
	return 0;
}

/*
 * This function is called whenever some part of NFS notices that
 * the cached attributes have to be refreshed.
 */
int
__nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
{
	int		 status = -ESTALE;
1024
	struct nfs4_label *label = NULL;
1025
	struct nfs_fattr *fattr = NULL;
L
Linus Torvalds 已提交
1026 1027
	struct nfs_inode *nfsi = NFS_I(inode);

1028 1029
	dfprintk(PAGECACHE, "NFS: revalidating (%s/%Lu)\n",
		inode->i_sb->s_id, (unsigned long long)NFS_FILEID(inode));
L
Linus Torvalds 已提交
1030

1031 1032
	trace_nfs_revalidate_inode_enter(inode);

1033
	if (is_bad_inode(inode))
1034
		goto out;
L
Linus Torvalds 已提交
1035
	if (NFS_STALE(inode))
1036
		goto out;
1037

1038 1039 1040 1041 1042 1043 1044
	/* pNFS: Attributes aren't updated until we layoutcommit */
	if (S_ISREG(inode->i_mode)) {
		status = pnfs_sync_inode(inode, false);
		if (status)
			goto out;
	}

1045 1046 1047 1048 1049
	status = -ENOMEM;
	fattr = nfs_alloc_fattr();
	if (fattr == NULL)
		goto out;

1050
	nfs_inc_stats(inode, NFSIOS_INODEREVALIDATE);
1051 1052 1053 1054 1055 1056 1057

	label = nfs4_label_alloc(NFS_SERVER(inode), GFP_KERNEL);
	if (IS_ERR(label)) {
		status = PTR_ERR(label);
		goto out;
	}

1058
	status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), fattr, label);
L
Linus Torvalds 已提交
1059
	if (status != 0) {
1060
		dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Lu) getattr failed, error=%d\n",
L
Linus Torvalds 已提交
1061
			 inode->i_sb->s_id,
1062
			 (unsigned long long)NFS_FILEID(inode), status);
L
Linus Torvalds 已提交
1063 1064 1065
		if (status == -ESTALE) {
			nfs_zap_caches(inode);
			if (!S_ISDIR(inode->i_mode))
B
Benny Halevy 已提交
1066
				set_bit(NFS_INO_STALE, &NFS_I(inode)->flags);
L
Linus Torvalds 已提交
1067
		}
1068
		goto err_out;
L
Linus Torvalds 已提交
1069 1070
	}

1071
	status = nfs_refresh_inode(inode, fattr);
L
Linus Torvalds 已提交
1072
	if (status) {
1073
		dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Lu) refresh failed, error=%d\n",
L
Linus Torvalds 已提交
1074
			 inode->i_sb->s_id,
1075
			 (unsigned long long)NFS_FILEID(inode), status);
1076
		goto err_out;
L
Linus Torvalds 已提交
1077
	}
1078

1079
	if (nfsi->cache_validity & NFS_INO_INVALID_ACL)
1080
		nfs_zap_acl_cache(inode);
1081

1082 1083
	nfs_setsecurity(inode, fattr, label);

1084
	dfprintk(PAGECACHE, "NFS: (%s/%Lu) revalidation complete\n",
L
Linus Torvalds 已提交
1085
		inode->i_sb->s_id,
1086
		(unsigned long long)NFS_FILEID(inode));
L
Linus Torvalds 已提交
1087

1088 1089 1090
err_out:
	nfs4_label_free(label);
out:
1091
	nfs_free_fattr(fattr);
1092
	trace_nfs_revalidate_inode_exit(inode, status);
L
Linus Torvalds 已提交
1093 1094 1095
	return status;
}

1096
int nfs_attribute_cache_expired(struct inode *inode)
1097
{
1098
	if (nfs_have_delegated_attributes(inode))
L
Linus Torvalds 已提交
1099
		return 0;
1100
	return nfs_attribute_timeout(inode);
L
Linus Torvalds 已提交
1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111
}

/**
 * nfs_revalidate_inode - Revalidate the inode attributes
 * @server - pointer to nfs_server struct
 * @inode - pointer to inode struct
 *
 * Updates inode attribute information by retrieving the data from the server.
 */
int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
{
1112
	if (!nfs_need_revalidate_inode(inode))
L
Linus Torvalds 已提交
1113 1114 1115
		return NFS_STALE(inode) ? -ESTALE : 0;
	return __nfs_revalidate_inode(server, inode);
}
B
Bryan Schumaker 已提交
1116
EXPORT_SYMBOL_GPL(nfs_revalidate_inode);
L
Linus Torvalds 已提交
1117

1118
static int nfs_invalidate_mapping(struct inode *inode, struct address_space *mapping)
1119 1120
{
	struct nfs_inode *nfsi = NFS_I(inode);
1121 1122
	int ret;

1123
	if (mapping->nrpages != 0) {
1124
		if (S_ISREG(inode->i_mode)) {
1125
			unmap_mapping_range(mapping, 0, 0, 0);
1126 1127 1128 1129 1130
			ret = nfs_sync_mapping(mapping);
			if (ret < 0)
				return ret;
		}
		ret = invalidate_inode_pages2(mapping);
1131 1132 1133
		if (ret < 0)
			return ret;
	}
1134 1135
	if (S_ISDIR(inode->i_mode)) {
		spin_lock(&inode->i_lock);
1136
		memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
1137 1138
		spin_unlock(&inode->i_lock);
	}
1139
	nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE);
D
David Howells 已提交
1140
	nfs_fscache_wait_on_invalidate(inode);
1141

1142 1143 1144
	dfprintk(PAGECACHE, "NFS: (%s/%Lu) data cache invalidated\n",
			inode->i_sb->s_id,
			(unsigned long long)NFS_FILEID(inode));
1145 1146 1147
	return 0;
}

1148
bool nfs_mapping_need_revalidate_inode(struct inode *inode)
1149
{
1150 1151
	return nfs_check_cache_invalid(inode, NFS_INO_REVAL_PAGECACHE) ||
		NFS_STALE(inode);
1152 1153
}

A
Al Viro 已提交
1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174
int nfs_revalidate_mapping_rcu(struct inode *inode)
{
	struct nfs_inode *nfsi = NFS_I(inode);
	unsigned long *bitlock = &nfsi->flags;
	int ret = 0;

	if (IS_SWAPFILE(inode))
		goto out;
	if (nfs_mapping_need_revalidate_inode(inode)) {
		ret = -ECHILD;
		goto out;
	}
	spin_lock(&inode->i_lock);
	if (test_bit(NFS_INO_INVALIDATING, bitlock) ||
	    (nfsi->cache_validity & NFS_INO_INVALID_DATA))
		ret = -ECHILD;
	spin_unlock(&inode->i_lock);
out:
	return ret;
}

1175
/**
1176
 * nfs_revalidate_mapping - Revalidate the pagecache
1177 1178 1179
 * @inode - pointer to host inode
 * @mapping - pointer to mapping
 */
1180 1181
int nfs_revalidate_mapping(struct inode *inode,
		struct address_space *mapping)
1182 1183
{
	struct nfs_inode *nfsi = NFS_I(inode);
1184
	unsigned long *bitlock = &nfsi->flags;
1185
	int ret = 0;
1186

1187 1188 1189 1190
	/* swapfiles are not supposed to be shared. */
	if (IS_SWAPFILE(inode))
		goto out;

1191
	if (nfs_mapping_need_revalidate_inode(inode)) {
1192 1193 1194
		ret = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
		if (ret < 0)
			goto out;
1195
	}
1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209

	/*
	 * We must clear NFS_INO_INVALID_DATA first to ensure that
	 * invalidations that come in while we're shooting down the mappings
	 * are respected. But, that leaves a race window where one revalidator
	 * can clear the flag, and then another checks it before the mapping
	 * gets invalidated. Fix that by serializing access to this part of
	 * the function.
	 *
	 * At the same time, we need to allow other tasks to see whether we
	 * might be in the middle of invalidating the pages, so we only set
	 * the bit lock here if it looks like we're going to be doing that.
	 */
	for (;;) {
1210 1211
		ret = wait_on_bit_action(bitlock, NFS_INO_INVALIDATING,
					 nfs_wait_bit_killable, TASK_KILLABLE);
1212 1213
		if (ret)
			goto out;
1214 1215 1216 1217 1218 1219
		spin_lock(&inode->i_lock);
		if (test_bit(NFS_INO_INVALIDATING, bitlock)) {
			spin_unlock(&inode->i_lock);
			continue;
		}
		if (nfsi->cache_validity & NFS_INO_INVALID_DATA)
1220 1221
			break;
		spin_unlock(&inode->i_lock);
1222
		goto out;
1223 1224
	}

1225
	set_bit(NFS_INO_INVALIDATING, bitlock);
1226
	smp_wmb();
1227 1228 1229
	nfsi->cache_validity &= ~NFS_INO_INVALID_DATA;
	spin_unlock(&inode->i_lock);
	trace_nfs_invalidate_mapping_enter(inode);
1230
	ret = nfs_invalidate_mapping(inode, mapping);
1231 1232
	trace_nfs_invalidate_mapping_exit(inode, ret);

1233
	clear_bit_unlock(NFS_INO_INVALIDATING, bitlock);
1234
	smp_mb__after_atomic();
1235
	wake_up_bit(bitlock, NFS_INO_INVALIDATING);
1236
out:
1237
	return ret;
1238 1239
}

1240
static bool nfs_file_has_writers(struct nfs_inode *nfsi)
1241
{
1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256
	struct inode *inode = &nfsi->vfs_inode;

	assert_spin_locked(&inode->i_lock);

	if (!S_ISREG(inode->i_mode))
		return false;
	if (list_empty(&nfsi->open_files))
		return false;
	/* Note: This relies on nfsi->open_files being ordered with writers
	 *       being placed at the head of the list.
	 *       See nfs_inode_attach_open_context()
	 */
	return (list_first_entry(&nfsi->open_files,
			struct nfs_open_context,
			list)->mode & FMODE_WRITE) == FMODE_WRITE;
1257 1258
}

1259
static bool nfs_file_has_buffered_writers(struct nfs_inode *nfsi)
1260
{
1261
	return nfs_file_has_writers(nfsi) && nfs_file_io_is_buffered(nfsi);
1262 1263
}

1264
static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1265 1266
{
	struct nfs_inode *nfsi = NFS_I(inode);
1267
	unsigned long ret = 0;
1268

1269 1270
	if ((fattr->valid & NFS_ATTR_FATTR_PRECHANGE)
			&& (fattr->valid & NFS_ATTR_FATTR_CHANGE)
1271 1272
			&& inode->i_version == fattr->pre_change_attr) {
		inode->i_version = fattr->change_attr;
1273
		if (S_ISDIR(inode->i_mode))
1274
			nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA);
1275
		ret |= NFS_INO_INVALID_ATTR;
1276
	}
1277
	/* If we have atomic WCC data, we may update some attributes */
1278 1279
	if ((fattr->valid & NFS_ATTR_FATTR_PRECTIME)
			&& (fattr->valid & NFS_ATTR_FATTR_CTIME)
1280 1281 1282 1283
			&& timespec_equal(&inode->i_ctime, &fattr->pre_ctime)) {
		memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
		ret |= NFS_INO_INVALID_ATTR;
	}
1284 1285 1286 1287

	if ((fattr->valid & NFS_ATTR_FATTR_PREMTIME)
			&& (fattr->valid & NFS_ATTR_FATTR_MTIME)
			&& timespec_equal(&inode->i_mtime, &fattr->pre_mtime)) {
1288 1289
		memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));
		if (S_ISDIR(inode->i_mode))
1290
			nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA);
1291
		ret |= NFS_INO_INVALID_ATTR;
1292
	}
1293 1294 1295
	if ((fattr->valid & NFS_ATTR_FATTR_PRESIZE)
			&& (fattr->valid & NFS_ATTR_FATTR_SIZE)
			&& i_size_read(inode) == nfs_size_to_loff_t(fattr->pre_size)
1296
			&& nfsi->nrequests == 0) {
1297 1298 1299
		i_size_write(inode, nfs_size_to_loff_t(fattr->size));
		ret |= NFS_INO_INVALID_ATTR;
	}
D
David Howells 已提交
1300

1301
	return ret;
1302 1303
}

L
Linus Torvalds 已提交
1304
/**
1305
 * nfs_check_inode_attributes - verify consistency of the inode attribute cache
L
Linus Torvalds 已提交
1306 1307 1308 1309 1310 1311 1312
 * @inode - pointer to inode
 * @fattr - updated attributes
 *
 * Verifies the attribute cache. If we have just changed the attributes,
 * so that fattr carries weak cache consistency data, then it may
 * also update the ctime/mtime/change_attribute.
 */
1313
static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fattr)
L
Linus Torvalds 已提交
1314 1315 1316
{
	struct nfs_inode *nfsi = NFS_I(inode);
	loff_t cur_size, new_isize;
1317
	unsigned long invalid = 0;
L
Linus Torvalds 已提交
1318

1319

1320 1321
	if (nfs_have_delegated_attributes(inode))
		return 0;
1322
	/* Has the inode gone and changed behind our back? */
1323
	if ((fattr->valid & NFS_ATTR_FATTR_FILEID) && nfsi->fileid != fattr->fileid)
1324
		return -ESTALE;
1325
	if ((fattr->valid & NFS_ATTR_FATTR_TYPE) && (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT))
1326
		return -ESTALE;
1327

1328
	if (!nfs_file_has_buffered_writers(nfsi)) {
1329 1330 1331
		/* Verify a few of the more important attributes */
		if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 && inode->i_version != fattr->change_attr)
			invalid |= NFS_INO_INVALID_ATTR | NFS_INO_REVAL_PAGECACHE;
L
Linus Torvalds 已提交
1332

1333 1334
		if ((fattr->valid & NFS_ATTR_FATTR_MTIME) && !timespec_equal(&inode->i_mtime, &fattr->mtime))
			invalid |= NFS_INO_INVALID_ATTR;
1335

1336 1337 1338 1339 1340 1341 1342 1343 1344
		if ((fattr->valid & NFS_ATTR_FATTR_CTIME) && !timespec_equal(&inode->i_ctime, &fattr->ctime))
			invalid |= NFS_INO_INVALID_ATTR;

		if (fattr->valid & NFS_ATTR_FATTR_SIZE) {
			cur_size = i_size_read(inode);
			new_isize = nfs_size_to_loff_t(fattr->size);
			if (cur_size != new_isize)
				invalid |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
		}
1345
	}
L
Linus Torvalds 已提交
1346 1347

	/* Have any file permissions changed? */
1348 1349
	if ((fattr->valid & NFS_ATTR_FATTR_MODE) && (inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO))
		invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
1350
	if ((fattr->valid & NFS_ATTR_FATTR_OWNER) && !uid_eq(inode->i_uid, fattr->uid))
1351
		invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
1352
	if ((fattr->valid & NFS_ATTR_FATTR_GROUP) && !gid_eq(inode->i_gid, fattr->gid))
1353
		invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
L
Linus Torvalds 已提交
1354 1355

	/* Has the link count changed? */
1356
	if ((fattr->valid & NFS_ATTR_FATTR_NLINK) && inode->i_nlink != fattr->nlink)
1357
		invalid |= NFS_INO_INVALID_ATTR;
L
Linus Torvalds 已提交
1358

1359
	if ((fattr->valid & NFS_ATTR_FATTR_ATIME) && !timespec_equal(&inode->i_atime, &fattr->atime))
1360 1361 1362
		invalid |= NFS_INO_INVALID_ATIME;

	if (invalid != 0)
1363
		nfs_set_cache_invalid(inode, invalid | NFS_INO_REVAL_FORCED);
L
Linus Torvalds 已提交
1364

1365
	nfsi->read_cache_jiffies = fattr->time_start;
L
Linus Torvalds 已提交
1366 1367 1368
	return 0;
}

1369
static atomic_long_t nfs_attr_generation_counter;
1370 1371 1372

static unsigned long nfs_read_attr_generation_counter(void)
{
1373
	return atomic_long_read(&nfs_attr_generation_counter);
1374 1375 1376 1377
}

unsigned long nfs_inc_attr_generation_counter(void)
{
1378
	return atomic_long_inc_return(&nfs_attr_generation_counter);
1379
}
1380
EXPORT_SYMBOL_GPL(nfs_inc_attr_generation_counter);
1381 1382 1383 1384 1385 1386

void nfs_fattr_init(struct nfs_fattr *fattr)
{
	fattr->valid = 0;
	fattr->time_start = jiffies;
	fattr->gencount = nfs_inc_attr_generation_counter();
1387 1388
	fattr->owner_name = NULL;
	fattr->group_name = NULL;
1389
}
B
Bryan Schumaker 已提交
1390
EXPORT_SYMBOL_GPL(nfs_fattr_init);
1391

1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407
/**
 * nfs_fattr_set_barrier
 * @fattr: attributes
 *
 * Used to set a barrier after an attribute was updated. This
 * barrier ensures that older attributes from RPC calls that may
 * have raced with our update cannot clobber these new values.
 * Note that you are still responsible for ensuring that other
 * operations which change the attribute on the server do not
 * collide.
 */
void nfs_fattr_set_barrier(struct nfs_fattr *fattr)
{
	fattr->gencount = nfs_inc_attr_generation_counter();
}

1408 1409 1410 1411 1412 1413 1414 1415 1416
struct nfs_fattr *nfs_alloc_fattr(void)
{
	struct nfs_fattr *fattr;

	fattr = kmalloc(sizeof(*fattr), GFP_NOFS);
	if (fattr != NULL)
		nfs_fattr_init(fattr);
	return fattr;
}
B
Bryan Schumaker 已提交
1417
EXPORT_SYMBOL_GPL(nfs_alloc_fattr);
1418 1419 1420 1421 1422 1423 1424 1425 1426 1427

struct nfs_fh *nfs_alloc_fhandle(void)
{
	struct nfs_fh *fh;

	fh = kmalloc(sizeof(struct nfs_fh), GFP_NOFS);
	if (fh != NULL)
		fh->size = 0;
	return fh;
}
B
Bryan Schumaker 已提交
1428
EXPORT_SYMBOL_GPL(nfs_alloc_fhandle);
1429

1430
#ifdef NFS_DEBUG
1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442
/*
 * _nfs_display_fhandle_hash - calculate the crc32 hash for the filehandle
 *                             in the same way that wireshark does
 *
 * @fh: file handle
 *
 * For debugging only.
 */
u32 _nfs_display_fhandle_hash(const struct nfs_fh *fh)
{
	/* wireshark uses 32-bit AUTODIN crc and does a bitwise
	 * not on the result */
1443
	return nfs_fhandle_hash(fh);
1444
}
C
Chuck Lever 已提交
1445
EXPORT_SYMBOL_GPL(_nfs_display_fhandle_hash);
1446 1447

/*
1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458
 * _nfs_display_fhandle - display an NFS file handle on the console
 *
 * @fh: file handle to display
 * @caption: display caption
 *
 * For debugging only.
 */
void _nfs_display_fhandle(const struct nfs_fh *fh, const char *caption)
{
	unsigned short i;

1459
	if (fh == NULL || fh->size == 0) {
1460 1461 1462 1463
		printk(KERN_DEFAULT "%s at %p is empty\n", caption, fh);
		return;
	}

1464 1465
	printk(KERN_DEFAULT "%s at %p is %u bytes, crc: 0x%08x:\n",
	       caption, fh, fh->size, _nfs_display_fhandle_hash(fh));
1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489
	for (i = 0; i < fh->size; i += 16) {
		__be32 *pos = (__be32 *)&fh->data[i];

		switch ((fh->size - i - 1) >> 2) {
		case 0:
			printk(KERN_DEFAULT " %08x\n",
				be32_to_cpup(pos));
			break;
		case 1:
			printk(KERN_DEFAULT " %08x %08x\n",
				be32_to_cpup(pos), be32_to_cpup(pos + 1));
			break;
		case 2:
			printk(KERN_DEFAULT " %08x %08x %08x\n",
				be32_to_cpup(pos), be32_to_cpup(pos + 1),
				be32_to_cpup(pos + 2));
			break;
		default:
			printk(KERN_DEFAULT " %08x %08x %08x %08x\n",
				be32_to_cpup(pos), be32_to_cpup(pos + 1),
				be32_to_cpup(pos + 2), be32_to_cpup(pos + 3));
		}
	}
}
C
Chuck Lever 已提交
1490
EXPORT_SYMBOL_GPL(_nfs_display_fhandle);
1491 1492
#endif

1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505
/**
 * nfs_inode_attrs_need_update - check if the inode attributes need updating
 * @inode - pointer to inode
 * @fattr - attributes
 *
 * Attempt to divine whether or not an RPC call reply carrying stale
 * attributes got scheduled after another call carrying updated ones.
 *
 * To do so, the function first assumes that a more recent ctime means
 * that the attributes in fattr are newer, however it also attempt to
 * catch the case where ctime either didn't change, or went backwards
 * (if someone reset the clock on the server) by looking at whether
 * or not this RPC call was started after the inode was last updated.
1506
 * Note also the check for wraparound of 'attr_gencount'
1507 1508 1509 1510 1511 1512 1513 1514 1515
 *
 * The function returns 'true' if it thinks the attributes in 'fattr' are
 * more recent than the ones cached in the inode.
 *
 */
static int nfs_inode_attrs_need_update(const struct inode *inode, const struct nfs_fattr *fattr)
{
	const struct nfs_inode *nfsi = NFS_I(inode);

1516 1517
	return ((long)fattr->gencount - (long)nfsi->attr_gencount) > 0 ||
		((long)nfsi->attr_gencount - (long)nfs_read_attr_generation_counter() > 0);
1518 1519 1520 1521
}

static int nfs_refresh_inode_locked(struct inode *inode, struct nfs_fattr *fattr)
{
1522 1523 1524 1525
	int ret;

	trace_nfs_refresh_inode_enter(inode);

1526
	if (nfs_inode_attrs_need_update(inode, fattr))
1527 1528 1529 1530 1531 1532
		ret = nfs_update_inode(inode, fattr);
	else
		ret = nfs_check_inode_attributes(inode, fattr);

	trace_nfs_refresh_inode_exit(inode, ret);
	return ret;
1533 1534
}

1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551
/**
 * nfs_refresh_inode - try to update the inode attribute cache
 * @inode - pointer to inode
 * @fattr - updated attributes
 *
 * Check that an RPC call that returned attributes has not overlapped with
 * other recent updates of the inode metadata, then decide whether it is
 * safe to do a full update of the inode attributes, or whether just to
 * call nfs_check_inode_attributes.
 */
int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
{
	int status;

	if ((fattr->valid & NFS_ATTR_FATTR) == 0)
		return 0;
	spin_lock(&inode->i_lock);
1552
	status = nfs_refresh_inode_locked(inode, fattr);
1553
	spin_unlock(&inode->i_lock);
D
David Howells 已提交
1554

1555 1556
	return status;
}
B
Bryan Schumaker 已提交
1557
EXPORT_SYMBOL_GPL(nfs_refresh_inode);
1558

1559 1560
static int nfs_post_op_update_inode_locked(struct inode *inode, struct nfs_fattr *fattr)
{
1561
	unsigned long invalid = NFS_INO_INVALID_ATTR;
1562

1563 1564 1565
	if (S_ISDIR(inode->i_mode))
		invalid |= NFS_INO_INVALID_DATA;
	nfs_set_cache_invalid(inode, invalid);
1566 1567 1568 1569 1570
	if ((fattr->valid & NFS_ATTR_FATTR) == 0)
		return 0;
	return nfs_refresh_inode_locked(inode, fattr);
}

1571 1572 1573 1574 1575 1576 1577
/**
 * nfs_post_op_update_inode - try to update the inode attribute cache
 * @inode - pointer to inode
 * @fattr - updated attributes
 *
 * After an operation that has changed the inode metadata, mark the
 * attribute cache as being invalid, then try to update it.
1578 1579 1580 1581 1582 1583
 *
 * NB: if the server didn't return any post op attributes, this
 * function will force the retrieval of attributes before the next
 * NFS request.  Thus it should be used only for operations that
 * are expected to change one or more attributes, to avoid
 * unnecessary NFS requests and trips through nfs_update_inode().
1584 1585 1586
 */
int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr)
{
1587
	int status;
1588

1589
	spin_lock(&inode->i_lock);
1590
	nfs_fattr_set_barrier(fattr);
1591
	status = nfs_post_op_update_inode_locked(inode, fattr);
1592
	spin_unlock(&inode->i_lock);
1593

1594
	return status;
1595
}
B
Bryan Schumaker 已提交
1596
EXPORT_SYMBOL_GPL(nfs_post_op_update_inode);
1597

1598
/**
1599
 * nfs_post_op_update_inode_force_wcc_locked - update the inode attribute cache
1600 1601 1602 1603 1604 1605 1606 1607 1608
 * @inode - pointer to inode
 * @fattr - updated attributes
 *
 * After an operation that has changed the inode metadata, mark the
 * attribute cache as being invalid, then try to update it. Fake up
 * weak cache consistency data, if none exist.
 *
 * This function is mainly designed to be used by the ->write_done() functions.
 */
1609
int nfs_post_op_update_inode_force_wcc_locked(struct inode *inode, struct nfs_fattr *fattr)
1610
{
1611 1612 1613 1614 1615
	int status;

	/* Don't do a WCC update if these attributes are already stale */
	if ((fattr->valid & NFS_ATTR_FATTR) == 0 ||
			!nfs_inode_attrs_need_update(inode, fattr)) {
1616 1617 1618 1619
		fattr->valid &= ~(NFS_ATTR_FATTR_PRECHANGE
				| NFS_ATTR_FATTR_PRESIZE
				| NFS_ATTR_FATTR_PREMTIME
				| NFS_ATTR_FATTR_PRECTIME);
1620 1621
		goto out_noforce;
	}
1622 1623
	if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 &&
			(fattr->valid & NFS_ATTR_FATTR_PRECHANGE) == 0) {
1624
		fattr->pre_change_attr = inode->i_version;
1625
		fattr->valid |= NFS_ATTR_FATTR_PRECHANGE;
1626
	}
1627 1628
	if ((fattr->valid & NFS_ATTR_FATTR_CTIME) != 0 &&
			(fattr->valid & NFS_ATTR_FATTR_PRECTIME) == 0) {
1629
		memcpy(&fattr->pre_ctime, &inode->i_ctime, sizeof(fattr->pre_ctime));
1630 1631 1632 1633
		fattr->valid |= NFS_ATTR_FATTR_PRECTIME;
	}
	if ((fattr->valid & NFS_ATTR_FATTR_MTIME) != 0 &&
			(fattr->valid & NFS_ATTR_FATTR_PREMTIME) == 0) {
1634
		memcpy(&fattr->pre_mtime, &inode->i_mtime, sizeof(fattr->pre_mtime));
1635 1636 1637 1638
		fattr->valid |= NFS_ATTR_FATTR_PREMTIME;
	}
	if ((fattr->valid & NFS_ATTR_FATTR_SIZE) != 0 &&
			(fattr->valid & NFS_ATTR_FATTR_PRESIZE) == 0) {
1639
		fattr->pre_size = i_size_read(inode);
1640
		fattr->valid |= NFS_ATTR_FATTR_PRESIZE;
1641
	}
1642 1643
out_noforce:
	status = nfs_post_op_update_inode_locked(inode, fattr);
1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662
	return status;
}

/**
 * nfs_post_op_update_inode_force_wcc - try to update the inode attribute cache
 * @inode - pointer to inode
 * @fattr - updated attributes
 *
 * After an operation that has changed the inode metadata, mark the
 * attribute cache as being invalid, then try to update it. Fake up
 * weak cache consistency data, if none exist.
 *
 * This function is mainly designed to be used by the ->write_done() functions.
 */
int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fattr)
{
	int status;

	spin_lock(&inode->i_lock);
1663
	nfs_fattr_set_barrier(fattr);
1664
	status = nfs_post_op_update_inode_force_wcc_locked(inode, fattr);
1665 1666
	spin_unlock(&inode->i_lock);
	return status;
1667
}
B
Bryan Schumaker 已提交
1668
EXPORT_SYMBOL_GPL(nfs_post_op_update_inode_force_wcc);
1669

1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682

static inline bool nfs_fileid_valid(struct nfs_inode *nfsi,
				    struct nfs_fattr *fattr)
{
	bool ret1 = true, ret2 = true;

	if (fattr->valid & NFS_ATTR_FATTR_FILEID)
		ret1 = (nfsi->fileid == fattr->fileid);
	if (fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID)
		ret2 = (nfsi->fileid == fattr->mounted_on_fileid);
	return ret1 || ret2;
}

L
Linus Torvalds 已提交
1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694
/*
 * Many nfs protocol calls return the new file attributes after
 * an operation.  Here we update the inode to reflect the state
 * of the server's inode.
 *
 * This is a bit tricky because we have to make sure all dirty pages
 * have been sent off to the server before calling invalidate_inode_pages.
 * To make sure no other process adds more write requests while we try
 * our best to flush them, we make them sleep during the attribute refresh.
 *
 * A very similar scenario holds for the dir cache.
 */
1695
static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
L
Linus Torvalds 已提交
1696
{
1697
	struct nfs_server *server;
L
Linus Torvalds 已提交
1698
	struct nfs_inode *nfsi = NFS_I(inode);
1699
	loff_t cur_isize, new_isize;
1700
	unsigned long invalid = 0;
1701
	unsigned long now = jiffies;
1702
	unsigned long save_cache_validity;
1703
	bool have_writers = nfs_file_has_buffered_writers(nfsi);
1704
	bool cache_revalidated = true;
L
Linus Torvalds 已提交
1705

1706
	dfprintk(VFS, "NFS: %s(%s/%lu fh_crc=0x%08x ct=%d info=0x%x)\n",
1707
			__func__, inode->i_sb->s_id, inode->i_ino,
1708
			nfs_display_fhandle_hash(NFS_FH(inode)),
L
Linus Torvalds 已提交
1709 1710
			atomic_read(&inode->i_count), fattr->valid);

1711
	if (!nfs_fileid_valid(nfsi, fattr)) {
1712 1713 1714 1715 1716 1717 1718
		printk(KERN_ERR "NFS: server %s error: fileid changed\n"
			"fsid %s: expected fileid 0x%Lx, got 0x%Lx\n",
			NFS_SERVER(inode)->nfs_client->cl_hostname,
			inode->i_sb->s_id, (long long)nfsi->fileid,
			(long long)fattr->fileid);
		goto out_err;
	}
L
Linus Torvalds 已提交
1719 1720 1721 1722

	/*
	 * Make sure the inode's type hasn't changed.
	 */
1723 1724 1725 1726
	if ((fattr->valid & NFS_ATTR_FATTR_TYPE) && (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) {
		/*
		* Big trouble! The inode has become a different object.
		*/
1727
		printk(KERN_DEBUG "NFS: %s: inode %lu mode changed, %07o to %07o\n",
1728 1729 1730
				__func__, inode->i_ino, inode->i_mode, fattr->mode);
		goto out_err;
	}
L
Linus Torvalds 已提交
1731

1732
	server = NFS_SERVER(inode);
T
Trond Myklebust 已提交
1733
	/* Update the fsid? */
1734
	if (S_ISDIR(inode->i_mode) && (fattr->valid & NFS_ATTR_FATTR_FSID) &&
1735
			!nfs_fsid_equal(&server->fsid, &fattr->fsid) &&
1736
			!IS_AUTOMOUNT(inode))
1737 1738
		server->fsid = fattr->fsid;

L
Linus Torvalds 已提交
1739 1740 1741
	/*
	 * Update the read time so we don't revalidate too often.
	 */
1742
	nfsi->read_cache_jiffies = fattr->time_start;
1743

1744 1745 1746 1747 1748
	save_cache_validity = nfsi->cache_validity;
	nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR
			| NFS_INO_INVALID_ATIME
			| NFS_INO_REVAL_FORCED
			| NFS_INO_REVAL_PAGECACHE);
L
Linus Torvalds 已提交
1749

1750
	/* Do atomic weak cache consistency updates */
1751
	invalid |= nfs_wcc_update_inode(inode, fattr);
1752

1753 1754 1755 1756
	if (pnfs_layoutcommit_outstanding(inode)) {
		nfsi->cache_validity |= save_cache_validity & NFS_INO_INVALID_ATTR;
		cache_revalidated = false;
	}
1757

1758
	/* More cache consistency checks */
1759
	if (fattr->valid & NFS_ATTR_FATTR_CHANGE) {
1760
		if (inode->i_version != fattr->change_attr) {
1761 1762
			dprintk("NFS: change_attr change on server for file %s/%ld\n",
					inode->i_sb->s_id, inode->i_ino);
1763
			/* Could it be a race with writeback? */
1764
			if (!have_writers) {
1765 1766 1767 1768 1769 1770 1771
				invalid |= NFS_INO_INVALID_ATTR
					| NFS_INO_INVALID_DATA
					| NFS_INO_INVALID_ACCESS
					| NFS_INO_INVALID_ACL;
				if (S_ISDIR(inode->i_mode))
					nfs_force_lookup_revalidate(inode);
			}
1772
			inode->i_version = fattr->change_attr;
1773
		}
1774
	} else {
1775
		nfsi->cache_validity |= save_cache_validity;
1776 1777
		cache_revalidated = false;
	}
1778 1779

	if (fattr->valid & NFS_ATTR_FATTR_MTIME) {
1780
		memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));
1781
	} else if (server->caps & NFS_CAP_MTIME) {
1782 1783
		nfsi->cache_validity |= save_cache_validity &
				(NFS_INO_INVALID_ATTR
1784
				| NFS_INO_REVAL_FORCED);
1785 1786
		cache_revalidated = false;
	}
1787

1788
	if (fattr->valid & NFS_ATTR_FATTR_CTIME) {
1789
		memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
1790
	} else if (server->caps & NFS_CAP_CTIME) {
1791 1792
		nfsi->cache_validity |= save_cache_validity &
				(NFS_INO_INVALID_ATTR
1793
				| NFS_INO_REVAL_FORCED);
1794 1795
		cache_revalidated = false;
	}
1796

1797
	/* Check if our cached file size is stale */
1798 1799 1800 1801 1802 1803
	if (fattr->valid & NFS_ATTR_FATTR_SIZE) {
		new_isize = nfs_size_to_loff_t(fattr->size);
		cur_isize = i_size_read(inode);
		if (new_isize != cur_isize) {
			/* Do we perhaps have any outstanding writes, or has
			 * the file grown beyond our last write? */
1804
			if (nfsi->nrequests == 0 || new_isize > cur_isize) {
1805
				i_size_write(inode, new_isize);
1806 1807
				if (!have_writers)
					invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
1808
			}
1809 1810 1811 1812 1813 1814
			dprintk("NFS: isize change on server for file %s/%ld "
					"(%Ld to %Ld)\n",
					inode->i_sb->s_id,
					inode->i_ino,
					(long long)cur_isize,
					(long long)new_isize);
L
Linus Torvalds 已提交
1815
		}
1816
	} else {
1817 1818
		nfsi->cache_validity |= save_cache_validity &
				(NFS_INO_INVALID_ATTR
1819 1820
				| NFS_INO_REVAL_PAGECACHE
				| NFS_INO_REVAL_FORCED);
1821 1822
		cache_revalidated = false;
	}
L
Linus Torvalds 已提交
1823 1824


1825 1826
	if (fattr->valid & NFS_ATTR_FATTR_ATIME)
		memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
1827
	else if (server->caps & NFS_CAP_ATIME) {
1828 1829
		nfsi->cache_validity |= save_cache_validity &
				(NFS_INO_INVALID_ATIME
1830
				| NFS_INO_REVAL_FORCED);
1831 1832
		cache_revalidated = false;
	}
L
Linus Torvalds 已提交
1833

1834 1835
	if (fattr->valid & NFS_ATTR_FATTR_MODE) {
		if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)) {
1836 1837 1838
			umode_t newmode = inode->i_mode & S_IFMT;
			newmode |= fattr->mode & S_IALLUGO;
			inode->i_mode = newmode;
1839 1840
			invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
		}
1841
	} else if (server->caps & NFS_CAP_MODE) {
1842 1843
		nfsi->cache_validity |= save_cache_validity &
				(NFS_INO_INVALID_ATTR
1844 1845 1846
				| NFS_INO_INVALID_ACCESS
				| NFS_INO_INVALID_ACL
				| NFS_INO_REVAL_FORCED);
1847 1848
		cache_revalidated = false;
	}
1849

1850
	if (fattr->valid & NFS_ATTR_FATTR_OWNER) {
1851
		if (!uid_eq(inode->i_uid, fattr->uid)) {
1852 1853 1854
			invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
			inode->i_uid = fattr->uid;
		}
1855
	} else if (server->caps & NFS_CAP_OWNER) {
1856 1857
		nfsi->cache_validity |= save_cache_validity &
				(NFS_INO_INVALID_ATTR
1858 1859 1860
				| NFS_INO_INVALID_ACCESS
				| NFS_INO_INVALID_ACL
				| NFS_INO_REVAL_FORCED);
1861 1862
		cache_revalidated = false;
	}
1863

1864
	if (fattr->valid & NFS_ATTR_FATTR_GROUP) {
1865
		if (!gid_eq(inode->i_gid, fattr->gid)) {
1866 1867 1868
			invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
			inode->i_gid = fattr->gid;
		}
1869
	} else if (server->caps & NFS_CAP_OWNER_GROUP) {
1870 1871
		nfsi->cache_validity |= save_cache_validity &
				(NFS_INO_INVALID_ATTR
1872 1873 1874
				| NFS_INO_INVALID_ACCESS
				| NFS_INO_INVALID_ACL
				| NFS_INO_REVAL_FORCED);
1875 1876
		cache_revalidated = false;
	}
1877

1878 1879 1880 1881 1882
	if (fattr->valid & NFS_ATTR_FATTR_NLINK) {
		if (inode->i_nlink != fattr->nlink) {
			invalid |= NFS_INO_INVALID_ATTR;
			if (S_ISDIR(inode->i_mode))
				invalid |= NFS_INO_INVALID_DATA;
M
Miklos Szeredi 已提交
1883
			set_nlink(inode, fattr->nlink);
1884
		}
1885
	} else if (server->caps & NFS_CAP_NLINK) {
1886 1887
		nfsi->cache_validity |= save_cache_validity &
				(NFS_INO_INVALID_ATTR
1888
				| NFS_INO_REVAL_FORCED);
1889 1890
		cache_revalidated = false;
	}
L
Linus Torvalds 已提交
1891

1892
	if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) {
L
Linus Torvalds 已提交
1893 1894 1895 1896
		/*
		 * report the blocks in 512byte units
		 */
		inode->i_blocks = nfs_calc_block_size(fattr->du.nfs3.used);
1897
	} else if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED)
1898
		inode->i_blocks = fattr->du.nfs2.blocks;
1899 1900
	else
		cache_revalidated = false;
L
Linus Torvalds 已提交
1901 1902

	/* Update attrtimeo value if we're out of the unstable period */
1903
	if (invalid & NFS_INO_INVALID_ATTR) {
C
Chuck Lever 已提交
1904
		nfs_inc_stats(inode, NFSIOS_ATTRINVALIDATE);
L
Linus Torvalds 已提交
1905
		nfsi->attrtimeo = NFS_MINATTRTIMEO(inode);
1906
		nfsi->attrtimeo_timestamp = now;
1907
		/* Set barrier to be more recent than all outstanding updates */
1908
		nfsi->attr_gencount = nfs_inc_attr_generation_counter();
1909
	} else {
1910 1911 1912 1913 1914 1915 1916
		if (cache_revalidated) {
			if (!time_in_range_open(now, nfsi->attrtimeo_timestamp,
				nfsi->attrtimeo_timestamp + nfsi->attrtimeo)) {
				nfsi->attrtimeo <<= 1;
				if (nfsi->attrtimeo > NFS_MAXATTRTIMEO(inode))
					nfsi->attrtimeo = NFS_MAXATTRTIMEO(inode);
			}
1917 1918
			nfsi->attrtimeo_timestamp = now;
		}
1919 1920 1921
		/* Set the barrier to be more recent than this fattr */
		if ((long)fattr->gencount - (long)nfsi->attr_gencount > 0)
			nfsi->attr_gencount = fattr->gencount;
L
Linus Torvalds 已提交
1922
	}
1923 1924

	/* Don't declare attrcache up to date if there were no attrs! */
1925
	if (cache_revalidated)
1926 1927
		invalid &= ~NFS_INO_INVALID_ATTR;

L
Linus Torvalds 已提交
1928 1929 1930 1931
	/* Don't invalidate the data if we were to blame */
	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)
				|| S_ISLNK(inode->i_mode)))
		invalid &= ~NFS_INO_INVALID_DATA;
1932
	if (!NFS_PROTO(inode)->have_delegation(inode, FMODE_READ) ||
1933
			(save_cache_validity & NFS_INO_REVAL_FORCED))
1934
		nfs_set_cache_invalid(inode, invalid);
D
David Howells 已提交
1935

L
Linus Torvalds 已提交
1936
	return 0;
1937
 out_err:
L
Linus Torvalds 已提交
1938 1939 1940 1941 1942 1943 1944 1945 1946
	/*
	 * No need to worry about unhashing the dentry, as the
	 * lookup validation will know that the inode is bad.
	 * (But we fall through to invalidate the caches.)
	 */
	nfs_invalidate_inode(inode);
	return -ESTALE;
}

D
David Howells 已提交
1947
struct inode *nfs_alloc_inode(struct super_block *sb)
L
Linus Torvalds 已提交
1948 1949
{
	struct nfs_inode *nfsi;
F
Firo Yang 已提交
1950
	nfsi = kmem_cache_alloc(nfs_inode_cachep, GFP_KERNEL);
L
Linus Torvalds 已提交
1951 1952
	if (!nfsi)
		return NULL;
1953 1954
	nfsi->flags = 0UL;
	nfsi->cache_validity = 0UL;
B
Bryan Schumaker 已提交
1955
#if IS_ENABLED(CONFIG_NFS_V4)
1956 1957
	nfsi->nfs4_acl = NULL;
#endif /* CONFIG_NFS_V4 */
L
Linus Torvalds 已提交
1958 1959
	return &nfsi->vfs_inode;
}
B
Bryan Schumaker 已提交
1960
EXPORT_SYMBOL_GPL(nfs_alloc_inode);
L
Linus Torvalds 已提交
1961

N
Nick Piggin 已提交
1962
static void nfs_i_callback(struct rcu_head *head)
L
Linus Torvalds 已提交
1963
{
N
Nick Piggin 已提交
1964
	struct inode *inode = container_of(head, struct inode, i_rcu);
L
Linus Torvalds 已提交
1965 1966 1967
	kmem_cache_free(nfs_inode_cachep, NFS_I(inode));
}

N
Nick Piggin 已提交
1968 1969 1970 1971
void nfs_destroy_inode(struct inode *inode)
{
	call_rcu(&inode->i_rcu, nfs_i_callback);
}
B
Bryan Schumaker 已提交
1972
EXPORT_SYMBOL_GPL(nfs_destroy_inode);
N
Nick Piggin 已提交
1973

A
Andrew Morton 已提交
1974 1975
static inline void nfs4_init_once(struct nfs_inode *nfsi)
{
B
Bryan Schumaker 已提交
1976
#if IS_ENABLED(CONFIG_NFS_V4)
A
Andrew Morton 已提交
1977 1978 1979
	INIT_LIST_HEAD(&nfsi->open_states);
	nfsi->delegation = NULL;
	init_rwsem(&nfsi->rwsem);
1980
	nfsi->layout = NULL;
A
Andrew Morton 已提交
1981 1982
#endif
}
D
David Howells 已提交
1983

1984
static void init_once(void *foo)
L
Linus Torvalds 已提交
1985 1986 1987
{
	struct nfs_inode *nfsi = (struct nfs_inode *) foo;

C
Christoph Lameter 已提交
1988 1989 1990 1991
	inode_init_once(&nfsi->vfs_inode);
	INIT_LIST_HEAD(&nfsi->open_files);
	INIT_LIST_HEAD(&nfsi->access_cache_entry_lru);
	INIT_LIST_HEAD(&nfsi->access_cache_inode_lru);
F
Fred Isaman 已提交
1992
	INIT_LIST_HEAD(&nfsi->commit_info.list);
1993
	nfsi->nrequests = 0;
F
Fred Isaman 已提交
1994
	nfsi->commit_info.ncommit = 0;
1995
	atomic_set(&nfsi->commit_info.rpcs_out, 0);
A
Al Viro 已提交
1996
	init_rwsem(&nfsi->rmdir_sem);
C
Christoph Lameter 已提交
1997
	nfs4_init_once(nfsi);
L
Linus Torvalds 已提交
1998
}
1999

D
David Howells 已提交
2000
static int __init nfs_init_inodecache(void)
L
Linus Torvalds 已提交
2001 2002 2003
{
	nfs_inode_cachep = kmem_cache_create("nfs_inode_cache",
					     sizeof(struct nfs_inode),
2004
					     0, (SLAB_RECLAIM_ACCOUNT|
2005
						SLAB_MEM_SPREAD|SLAB_ACCOUNT),
2006
					     init_once);
L
Linus Torvalds 已提交
2007 2008 2009 2010 2011 2012
	if (nfs_inode_cachep == NULL)
		return -ENOMEM;

	return 0;
}

2013
static void nfs_destroy_inodecache(void)
L
Linus Torvalds 已提交
2014
{
2015 2016 2017 2018 2019
	/*
	 * Make sure all delayed rcu free inodes are flushed before we
	 * destroy cache.
	 */
	rcu_barrier();
2020
	kmem_cache_destroy(nfs_inode_cachep);
L
Linus Torvalds 已提交
2021 2022
}

T
Trond Myklebust 已提交
2023
struct workqueue_struct *nfsiod_workqueue;
B
Bryan Schumaker 已提交
2024
EXPORT_SYMBOL_GPL(nfsiod_workqueue);
T
Trond Myklebust 已提交
2025 2026 2027 2028 2029 2030 2031 2032

/*
 * start up the nfsiod workqueue
 */
static int nfsiod_start(void)
{
	struct workqueue_struct *wq;
	dprintk("RPC:       creating workqueue nfsiod\n");
2033
	wq = alloc_workqueue("nfsiod", WQ_MEM_RECLAIM, 0);
T
Trond Myklebust 已提交
2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053
	if (wq == NULL)
		return -ENOMEM;
	nfsiod_workqueue = wq;
	return 0;
}

/*
 * Destroy the nfsiod workqueue
 */
static void nfsiod_stop(void)
{
	struct workqueue_struct *wq;

	wq = nfsiod_workqueue;
	if (wq == NULL)
		return;
	nfsiod_workqueue = NULL;
	destroy_workqueue(wq);
}

2054
unsigned int nfs_net_id;
2055
EXPORT_SYMBOL_GPL(nfs_net_id);
2056 2057 2058

static int nfs_net_init(struct net *net)
{
2059
	nfs_clients_init(net);
2060
	return nfs_fs_proc_net_init(net);
2061 2062 2063 2064
}

static void nfs_net_exit(struct net *net)
{
2065
	nfs_fs_proc_net_exit(net);
2066
	nfs_cleanup_cb_ident_idr(net);
2067 2068 2069 2070 2071 2072 2073 2074 2075
}

static struct pernet_operations nfs_net_ops = {
	.init = nfs_net_init,
	.exit = nfs_net_exit,
	.id   = &nfs_net_id,
	.size = sizeof(struct nfs_net),
};

L
Linus Torvalds 已提交
2076 2077 2078 2079 2080 2081 2082
/*
 * Initialize NFS
 */
static int __init init_nfs_fs(void)
{
	int err;

2083
	err = register_pernet_subsys(&nfs_net_ops);
2084
	if (err < 0)
B
Bryan Schumaker 已提交
2085
		goto out9;
2086

2087 2088
	err = nfs_fscache_register();
	if (err < 0)
B
Bryan Schumaker 已提交
2089
		goto out8;
2090

T
Trond Myklebust 已提交
2091 2092
	err = nfsiod_start();
	if (err)
B
Bryan Schumaker 已提交
2093
		goto out7;
T
Trond Myklebust 已提交
2094

2095 2096
	err = nfs_fs_proc_init();
	if (err)
B
Bryan Schumaker 已提交
2097
		goto out6;
2098

L
Linus Torvalds 已提交
2099 2100
	err = nfs_init_nfspagecache();
	if (err)
B
Bryan Schumaker 已提交
2101
		goto out5;
L
Linus Torvalds 已提交
2102 2103 2104

	err = nfs_init_inodecache();
	if (err)
B
Bryan Schumaker 已提交
2105
		goto out4;
L
Linus Torvalds 已提交
2106 2107 2108

	err = nfs_init_readpagecache();
	if (err)
B
Bryan Schumaker 已提交
2109
		goto out3;
L
Linus Torvalds 已提交
2110 2111 2112

	err = nfs_init_writepagecache();
	if (err)
B
Bryan Schumaker 已提交
2113
		goto out2;
L
Linus Torvalds 已提交
2114 2115 2116

	err = nfs_init_directcache();
	if (err)
B
Bryan Schumaker 已提交
2117
		goto out1;
L
Linus Torvalds 已提交
2118

2119
	rpc_proc_register(&init_net, &nfs_rpcstat);
2120 2121 2122

	err = register_nfs_fs();
	if (err)
2123 2124
		goto out0;

L
Linus Torvalds 已提交
2125
	return 0;
2126
out0:
2127
	rpc_proc_unregister(&init_net, "nfs");
L
Linus Torvalds 已提交
2128
	nfs_destroy_directcache();
B
Bryan Schumaker 已提交
2129
out1:
2130
	nfs_destroy_writepagecache();
B
Bryan Schumaker 已提交
2131
out2:
2132
	nfs_destroy_readpagecache();
B
Bryan Schumaker 已提交
2133
out3:
2134
	nfs_destroy_inodecache();
B
Bryan Schumaker 已提交
2135
out4:
2136
	nfs_destroy_nfspagecache();
B
Bryan Schumaker 已提交
2137
out5:
2138
	nfs_fs_proc_exit();
B
Bryan Schumaker 已提交
2139
out6:
2140
	nfsiod_stop();
B
Bryan Schumaker 已提交
2141
out7:
2142
	nfs_fscache_unregister();
B
Bryan Schumaker 已提交
2143
out8:
2144
	unregister_pernet_subsys(&nfs_net_ops);
B
Bryan Schumaker 已提交
2145
out9:
L
Linus Torvalds 已提交
2146 2147 2148 2149 2150 2151 2152 2153 2154 2155
	return err;
}

static void __exit exit_nfs_fs(void)
{
	nfs_destroy_directcache();
	nfs_destroy_writepagecache();
	nfs_destroy_readpagecache();
	nfs_destroy_inodecache();
	nfs_destroy_nfspagecache();
2156
	nfs_fscache_unregister();
2157
	unregister_pernet_subsys(&nfs_net_ops);
2158
	rpc_proc_unregister(&init_net, "nfs");
D
David Howells 已提交
2159
	unregister_nfs_fs();
2160
	nfs_fs_proc_exit();
T
Trond Myklebust 已提交
2161
	nfsiod_stop();
L
Linus Torvalds 已提交
2162 2163 2164 2165 2166
}

/* Not quite true; I just maintain it */
MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>");
MODULE_LICENSE("GPL");
2167
module_param(enable_ino64, bool, 0644);
L
Linus Torvalds 已提交
2168 2169 2170

module_init(init_nfs_fs)
module_exit(exit_nfs_fs)