inode.c 48.3 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>
A
Alexey Dobriyan 已提交
18
#include <linux/sched.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 36
#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/nfs_idmap.h>
#include <linux/vfs.h>
37 38
#include <linux/inet.h>
#include <linux/nfs_xdr.h>
39
#include <linux/slab.h>
40
#include <linux/compat.h>
41
#include <linux/freezer.h>
42
#include <linux/crc32.h>
L
Linus Torvalds 已提交
43 44 45 46

#include <asm/system.h>
#include <asm/uaccess.h>

47
#include "nfs4_fs.h"
48
#include "callback.h"
L
Linus Torvalds 已提交
49
#include "delegation.h"
50
#include "iostat.h"
D
David Howells 已提交
51
#include "internal.h"
52
#include "fscache.h"
53
#include "dns_resolve.h"
54
#include "pnfs.h"
55
#include "netns.h"
L
Linus Torvalds 已提交
56 57 58

#define NFSDBG_FACILITY		NFSDBG_VFS

59 60 61
#define NFS_64_BIT_INODE_NUMBERS_ENABLED	1

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

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

67
static struct kmem_cache * nfs_inode_cachep;
68

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

75 76 77 78 79 80 81 82
/**
 * nfs_wait_bit_killable - helper for functions that are sleeping on bit locks
 * @word: long word containing the bit lock
 */
int nfs_wait_bit_killable(void *word)
{
	if (fatal_signal_pending(current))
		return -ERESTARTSYS;
83
	freezable_schedule();
84 85 86
	return 0;
}

87 88 89 90 91 92 93 94 95
/**
 * 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)
{
96 97 98 99 100
#ifdef CONFIG_COMPAT
	compat_ulong_t ino;
#else	
	unsigned long ino;
#endif
101 102 103 104 105 106 107 108 109

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

110
static void nfs_clear_inode(struct inode *inode)
L
Linus Torvalds 已提交
111
{
T
Trond Myklebust 已提交
112 113 114 115
	/*
	 * The following should never happen...
	 */
	BUG_ON(nfs_have_writebacks(inode));
116
	BUG_ON(!list_empty(&NFS_I(inode)->open_files));
117
	nfs_zap_acl_cache(inode);
118
	nfs_access_zap_cache(inode);
D
David Howells 已提交
119
	nfs_fscache_release_inode_cookie(inode);
L
Linus Torvalds 已提交
120 121
}

122 123 124 125 126 127 128
void nfs_evict_inode(struct inode *inode)
{
	truncate_inode_pages(&inode->i_data, 0);
	end_writeback(inode);
	nfs_clear_inode(inode);
}

T
Trond Myklebust 已提交
129 130 131 132 133
/**
 * nfs_sync_mapping - helper to flush all mmapped dirty data to disk
 */
int nfs_sync_mapping(struct address_space *mapping)
{
T
Trond Myklebust 已提交
134
	int ret = 0;
T
Trond Myklebust 已提交
135

T
Trond Myklebust 已提交
136 137 138 139
	if (mapping->nrpages != 0) {
		unmap_mapping_range(mapping, 0, 0, 0);
		ret = nfs_wb_all(mapping->host);
	}
T
Trond Myklebust 已提交
140 141 142
	return ret;
}

L
Linus Torvalds 已提交
143 144 145
/*
 * Invalidate the local caches
 */
146
static void nfs_zap_caches_locked(struct inode *inode)
L
Linus Torvalds 已提交
147 148 149 150
{
	struct nfs_inode *nfsi = NFS_I(inode);
	int mode = inode->i_mode;

C
Chuck Lever 已提交
151 152
	nfs_inc_stats(inode, NFSIOS_ATTRINVALIDATE);

153 154
	nfsi->attrtimeo = NFS_MINATTRTIMEO(inode);
	nfsi->attrtimeo_timestamp = jiffies;
L
Linus Torvalds 已提交
155 156 157

	memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode)));
	if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))
158
		nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE;
L
Linus Torvalds 已提交
159
	else
160
		nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE;
161
}
162

163 164 165 166
void nfs_zap_caches(struct inode *inode)
{
	spin_lock(&inode->i_lock);
	nfs_zap_caches_locked(inode);
167
	spin_unlock(&inode->i_lock);
168 169
}

170 171 172 173 174 175 176 177 178
void nfs_zap_mapping(struct inode *inode, struct address_space *mapping)
{
	if (mapping->nrpages != 0) {
		spin_lock(&inode->i_lock);
		NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA;
		spin_unlock(&inode->i_lock);
	}
}

179
void nfs_zap_acl_cache(struct inode *inode)
180 181 182 183 184 185
{
	void (*clear_acl_cache)(struct inode *);

	clear_acl_cache = NFS_PROTO(inode)->clear_acl_cache;
	if (clear_acl_cache != NULL)
		clear_acl_cache(inode);
186
	spin_lock(&inode->i_lock);
187
	NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_ACL;
188
	spin_unlock(&inode->i_lock);
L
Linus Torvalds 已提交
189 190
}

191 192 193 194 195 196 197
void nfs_invalidate_atime(struct inode *inode)
{
	spin_lock(&inode->i_lock);
	NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME;
	spin_unlock(&inode->i_lock);
}

L
Linus Torvalds 已提交
198
/*
199 200
 * Invalidate, but do not unhash, the inode.
 * NB: must be called with inode->i_lock held!
L
Linus Torvalds 已提交
201
 */
202
static void nfs_invalidate_inode(struct inode *inode)
L
Linus Torvalds 已提交
203
{
B
Benny Halevy 已提交
204
	set_bit(NFS_INO_STALE, &NFS_I(inode)->flags);
205
	nfs_zap_caches_locked(inode);
L
Linus Torvalds 已提交
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 237 238 239 240
}

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

241
	set_nfs_fileid(inode, fattr->fileid);
L
Linus Torvalds 已提交
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
	nfs_copy_fh(NFS_FH(inode), desc->fh);
	return 0;
}

/*
 * This is our front-end to iget that looks up inodes by file handle
 * instead of inode number.
 */
struct inode *
nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
{
	struct nfs_find_desc desc = {
		.fh	= fh,
		.fattr	= fattr
	};
257
	struct inode *inode = ERR_PTR(-ENOENT);
L
Linus Torvalds 已提交
258 259
	unsigned long hash;

260 261
	nfs_attr_check_mountpoint(sb, fattr);

262 263
	if (((fattr->valid & NFS_ATTR_FATTR_FILEID) == 0) &&
	    !nfs_attr_use_mounted_on_fileid(fattr))
L
Linus Torvalds 已提交
264
		goto out_no_inode;
265
	if ((fattr->valid & NFS_ATTR_FATTR_TYPE) == 0)
L
Linus Torvalds 已提交
266 267 268 269
		goto out_no_inode;

	hash = nfs_fattr_to_ino_t(fattr);

270 271 272
	inode = iget5_locked(sb, hash, nfs_find_actor, nfs_init_locked, &desc);
	if (inode == NULL) {
		inode = ERR_PTR(-ENOMEM);
L
Linus Torvalds 已提交
273
		goto out_no_inode;
274
	}
L
Linus Torvalds 已提交
275 276 277

	if (inode->i_state & I_NEW) {
		struct nfs_inode *nfsi = NFS_I(inode);
278
		unsigned long now = jiffies;
L
Linus Torvalds 已提交
279 280 281 282 283 284 285 286

		/* 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;
287 288 289 290 291
		if ((fattr->valid & NFS_ATTR_FATTR_MODE) == 0
				&& nfs_server_capable(inode, NFS_CAP_MODE))
			nfsi->cache_validity |= NFS_INO_INVALID_ATTR
				| NFS_INO_INVALID_ACCESS
				| NFS_INO_INVALID_ACL;
L
Linus Torvalds 已提交
292 293 294
		/* Why so? Because we want revalidate for devices/FIFOs, and
		 * that's precisely what we have in nfs_file_inode_operations.
		 */
295
		inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->file_inode_ops;
L
Linus Torvalds 已提交
296
		if (S_ISREG(inode->i_mode)) {
297
			inode->i_fop = NFS_SB(sb)->nfs_client->rpc_ops->file_ops;
L
Linus Torvalds 已提交
298 299 300
			inode->i_data.a_ops = &nfs_file_aops;
			inode->i_data.backing_dev_info = &NFS_SB(sb)->backing_dev_info;
		} else if (S_ISDIR(inode->i_mode)) {
301
			inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->dir_inode_ops;
L
Linus Torvalds 已提交
302
			inode->i_fop = &nfs_dir_operations;
303
			inode->i_data.a_ops = &nfs_dir_aops;
B
Bryan Schumaker 已提交
304
			if (nfs_server_capable(inode, NFS_CAP_READDIRPLUS))
B
Benny Halevy 已提交
305
				set_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(inode)->flags);
306
			/* Deal with crossing mountpoints */
307 308
			if (fattr->valid & NFS_ATTR_FATTR_MOUNTPOINT ||
					fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) {
M
Manoj Naik 已提交
309 310 311 312
				if (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL)
					inode->i_op = &nfs_referral_inode_operations;
				else
					inode->i_op = &nfs_mountpoint_inode_operations;
313
				inode->i_fop = NULL;
314
				inode->i_flags |= S_AUTOMOUNT;
315
			}
L
Linus Torvalds 已提交
316 317 318 319 320
		} else if (S_ISLNK(inode->i_mode))
			inode->i_op = &nfs_symlink_inode_operations;
		else
			init_special_inode(inode, inode->i_mode, fattr->rdev);

321 322 323
		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));
324
		inode->i_version = 0;
325
		inode->i_size = 0;
326
		clear_nlink(inode);
327 328 329 330 331
		inode->i_uid = -2;
		inode->i_gid = -2;
		inode->i_blocks = 0;
		memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));

332
		nfsi->read_cache_jiffies = fattr->time_start;
333
		nfsi->attr_gencount = fattr->gencount;
334 335
		if (fattr->valid & NFS_ATTR_FATTR_ATIME)
			inode->i_atime = fattr->atime;
336 337
		else if (nfs_server_capable(inode, NFS_CAP_ATIME))
			nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
338 339
		if (fattr->valid & NFS_ATTR_FATTR_MTIME)
			inode->i_mtime = fattr->mtime;
340 341 342
		else if (nfs_server_capable(inode, NFS_CAP_MTIME))
			nfsi->cache_validity |= NFS_INO_INVALID_ATTR
				| NFS_INO_INVALID_DATA;
343 344
		if (fattr->valid & NFS_ATTR_FATTR_CTIME)
			inode->i_ctime = fattr->ctime;
345 346 347 348
		else if (nfs_server_capable(inode, NFS_CAP_CTIME))
			nfsi->cache_validity |= NFS_INO_INVALID_ATTR
				| NFS_INO_INVALID_ACCESS
				| NFS_INO_INVALID_ACL;
349
		if (fattr->valid & NFS_ATTR_FATTR_CHANGE)
350
			inode->i_version = fattr->change_attr;
351 352 353
		else if (nfs_server_capable(inode, NFS_CAP_CHANGE_ATTR))
			nfsi->cache_validity |= NFS_INO_INVALID_ATTR
				| NFS_INO_INVALID_DATA;
354 355
		if (fattr->valid & NFS_ATTR_FATTR_SIZE)
			inode->i_size = nfs_size_to_loff_t(fattr->size);
356 357 358 359
		else
			nfsi->cache_validity |= NFS_INO_INVALID_ATTR
				| NFS_INO_INVALID_DATA
				| NFS_INO_REVAL_PAGECACHE;
360
		if (fattr->valid & NFS_ATTR_FATTR_NLINK)
M
Miklos Szeredi 已提交
361
			set_nlink(inode, fattr->nlink);
362 363
		else if (nfs_server_capable(inode, NFS_CAP_NLINK))
			nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
364 365
		if (fattr->valid & NFS_ATTR_FATTR_OWNER)
			inode->i_uid = fattr->uid;
366 367 368 369
		else if (nfs_server_capable(inode, NFS_CAP_OWNER))
			nfsi->cache_validity |= NFS_INO_INVALID_ATTR
				| NFS_INO_INVALID_ACCESS
				| NFS_INO_INVALID_ACL;
370 371
		if (fattr->valid & NFS_ATTR_FATTR_GROUP)
			inode->i_gid = fattr->gid;
372 373 374 375
		else if (nfs_server_capable(inode, NFS_CAP_OWNER_GROUP))
			nfsi->cache_validity |= NFS_INO_INVALID_ATTR
				| NFS_INO_INVALID_ACCESS
				| NFS_INO_INVALID_ACL;
376 377 378
		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 已提交
379 380 381 382 383 384
			/*
			 * report the blocks in 512byte units
			 */
			inode->i_blocks = nfs_calc_block_size(fattr->du.nfs3.used);
		}
		nfsi->attrtimeo = NFS_MINATTRTIMEO(inode);
385
		nfsi->attrtimeo_timestamp = now;
386
		nfsi->access_cache = RB_ROOT;
L
Linus Torvalds 已提交
387

D
David Howells 已提交
388 389
		nfs_fscache_init_inode_cookie(inode);

L
Linus Torvalds 已提交
390 391 392
		unlock_new_inode(inode);
	} else
		nfs_refresh_inode(inode, fattr);
393
	dprintk("NFS: nfs_fhget(%s/%Ld fh_crc=0x%08x ct=%d)\n",
L
Linus Torvalds 已提交
394 395
		inode->i_sb->s_id,
		(long long)NFS_FILEID(inode),
396
		nfs_display_fhandle_hash(fh),
L
Linus Torvalds 已提交
397 398 399 400 401 402
		atomic_read(&inode->i_count));

out:
	return inode;

out_no_inode:
403
	dprintk("nfs_fhget: iget failed with error %ld\n", PTR_ERR(inode));
L
Linus Torvalds 已提交
404 405 406
	goto out;
}

407
#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 已提交
408 409 410 411 412

int
nfs_setattr(struct dentry *dentry, struct iattr *attr)
{
	struct inode *inode = dentry->d_inode;
413 414
	struct nfs_fattr *fattr;
	int error = -ENOMEM;
L
Linus Torvalds 已提交
415

C
Chuck Lever 已提交
416 417
	nfs_inc_stats(inode, NFSIOS_VFSSETATTR);

418 419 420 421
	/* 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 已提交
422 423 424 425 426 427 428
	if (attr->ia_valid & ATTR_SIZE) {
		if (!S_ISREG(inode->i_mode) || attr->ia_size == i_size_read(inode))
			attr->ia_valid &= ~ATTR_SIZE;
	}

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

432
	/* Write all dirty data */
433
	if (S_ISREG(inode->i_mode))
434
		nfs_wb_all(inode);
435 436 437 438

	fattr = nfs_alloc_fattr();
	if (fattr == NULL)
		goto out;
439 440 441 442 443
	/*
	 * Return any delegations if we're going to change ACLs
	 */
	if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0)
		nfs_inode_return_delegation(inode);
444
	error = NFS_PROTO(inode)->setattr(dentry, fattr, attr);
445
	if (error == 0)
446 447 448
		nfs_refresh_inode(inode, fattr);
	nfs_free_fattr(fattr);
out:
449 450 451
	return error;
}

452 453 454 455 456 457 458 459 460 461 462
/**
 * 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.
 */
static int nfs_vmtruncate(struct inode * inode, loff_t offset)
{
N
npiggin@suse.de 已提交
463 464
	loff_t oldsize;
	int err;
465

N
npiggin@suse.de 已提交
466 467 468
	err = inode_newsize_ok(inode, offset);
	if (err)
		goto out;
469

N
npiggin@suse.de 已提交
470 471 472 473 474 475 476 477
	spin_lock(&inode->i_lock);
	oldsize = inode->i_size;
	i_size_write(inode, offset);
	spin_unlock(&inode->i_lock);

	truncate_pagecache(inode, oldsize, offset);
out:
	return err;
478 479
}

480 481 482 483 484 485 486 487 488 489 490
/**
 * 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.
 */
void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr)
{
	if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0) {
491
		spin_lock(&inode->i_lock);
L
Linus Torvalds 已提交
492
		if ((attr->ia_valid & ATTR_MODE) != 0) {
493 494
			int mode = attr->ia_mode & S_IALLUGO;
			mode |= inode->i_mode & ~S_IALLUGO;
L
Linus Torvalds 已提交
495 496 497 498 499 500
			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;
501
		NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
502
		spin_unlock(&inode->i_lock);
503 504
	}
	if ((attr->ia_valid & ATTR_SIZE) != 0) {
C
Chuck Lever 已提交
505
		nfs_inc_stats(inode, NFSIOS_SETATTRTRUNC);
506
		nfs_vmtruncate(inode, attr->ia_size);
507
	}
L
Linus Torvalds 已提交
508 509 510 511 512
}

int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
{
	struct inode *inode = dentry->d_inode;
513
	int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME;
L
Linus Torvalds 已提交
514 515
	int err;

516
	/* Flush out writes to the server in order to update c/mtime.  */
517
	if (S_ISREG(inode->i_mode)) {
518 519 520
		err = filemap_write_and_wait(inode->i_mapping);
		if (err)
			goto out;
521
	}
522 523 524 525 526 527 528 529 530 531 532 533

	/*
	 * 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.
	 */
 	if ((mnt->mnt_flags & MNT_NOATIME) ||
 	    ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)))
L
Linus Torvalds 已提交
534
		need_atime = 0;
535

L
Linus Torvalds 已提交
536 537 538 539
	if (need_atime)
		err = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
	else
		err = nfs_revalidate_inode(NFS_SERVER(inode), inode);
P
Peter Staubach 已提交
540
	if (!err) {
L
Linus Torvalds 已提交
541
		generic_fillattr(inode, stat);
542
		stat->ino = nfs_compat_user_ino64(NFS_FILEID(inode));
P
Peter Staubach 已提交
543
	}
544
out:
L
Linus Torvalds 已提交
545 546 547
	return err;
}

548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573
static void nfs_init_lock_context(struct nfs_lock_context *l_ctx)
{
	atomic_set(&l_ctx->count, 1);
	l_ctx->lockowner = current->files;
	l_ctx->pid = current->tgid;
	INIT_LIST_HEAD(&l_ctx->list);
}

static struct nfs_lock_context *__nfs_find_lock_context(struct nfs_open_context *ctx)
{
	struct nfs_lock_context *pos;

	list_for_each_entry(pos, &ctx->lock_context.list, list) {
		if (pos->lockowner != current->files)
			continue;
		if (pos->pid != current->tgid)
			continue;
		atomic_inc(&pos->count);
		return pos;
	}
	return NULL;
}

struct nfs_lock_context *nfs_get_lock_context(struct nfs_open_context *ctx)
{
	struct nfs_lock_context *res, *new = NULL;
574
	struct inode *inode = ctx->dentry->d_inode;
575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600

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

void nfs_put_lock_context(struct nfs_lock_context *l_ctx)
{
	struct nfs_open_context *ctx = l_ctx->open_context;
601
	struct inode *inode = ctx->dentry->d_inode;
602 603 604 605 606 607 608 609

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

T
Trond Myklebust 已提交
610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626
/**
 * nfs_close_context - Common close_context() routine NFSv2/v3
 * @ctx: pointer to context
 * @is_sync: is this a synchronous close
 *
 * always ensure that the attributes are up to date if we're mounted
 * with close-to-open semantics
 */
void nfs_close_context(struct nfs_open_context *ctx, int is_sync)
{
	struct inode *inode;
	struct nfs_server *server;

	if (!(ctx->mode & FMODE_WRITE))
		return;
	if (!is_sync)
		return;
627
	inode = ctx->dentry->d_inode;
T
Trond Myklebust 已提交
628 629 630 631 632 633 634 635
	if (!list_empty(&NFS_I(inode)->open_files))
		return;
	server = NFS_SERVER(inode);
	if (server->flags & NFS_MOUNT_NOCTO)
		return;
	nfs_revalidate_inode(server, inode);
}

636
struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, fmode_t f_mode)
L
Linus Torvalds 已提交
637 638
{
	struct nfs_open_context *ctx;
639 640 641
	struct rpc_cred *cred = rpc_lookup_cred();
	if (IS_ERR(cred))
		return ERR_CAST(cred);
L
Linus Torvalds 已提交
642

643
	ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
644 645 646
	if (!ctx) {
		put_rpccred(cred);
		return ERR_PTR(-ENOMEM);
L
Linus Torvalds 已提交
647
	}
648 649 650 651 652 653 654 655 656 657
	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;
	nfs_init_lock_context(&ctx->lock_context);
	ctx->lock_context.open_context = ctx;
	INIT_LIST_HEAD(&ctx->list);
L
Linus Torvalds 已提交
658 659 660 661 662 663
	return ctx;
}

struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx)
{
	if (ctx != NULL)
664
		atomic_inc(&ctx->lock_context.count);
L
Linus Torvalds 已提交
665 666 667
	return ctx;
}

T
Trond Myklebust 已提交
668
static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync)
L
Linus Torvalds 已提交
669
{
670 671
	struct inode *inode = ctx->dentry->d_inode;
	struct super_block *sb = ctx->dentry->d_sb;
672

673
	if (!list_empty(&ctx->list)) {
674 675 676 677 678
		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 已提交
679
		return;
680 681
	if (inode != NULL)
		NFS_PROTO(inode)->close_context(ctx, is_sync);
682 683
	if (ctx->cred != NULL)
		put_rpccred(ctx->cred);
684 685
	dput(ctx->dentry);
	nfs_sb_deactive(sb);
686 687 688
	kfree(ctx);
}

689 690 691 692 693
void put_nfs_open_context(struct nfs_open_context *ctx)
{
	__put_nfs_open_context(ctx, 0);
}

L
Linus Torvalds 已提交
694 695 696 697
/*
 * Ensure that mmap has a recent RPC credential for use when writing out
 * shared pages
 */
698
void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx)
L
Linus Torvalds 已提交
699
{
700
	struct inode *inode = filp->f_path.dentry->d_inode;
L
Linus Torvalds 已提交
701 702 703 704 705 706 707 708
	struct nfs_inode *nfsi = NFS_I(inode);

	filp->private_data = get_nfs_open_context(ctx);
	spin_lock(&inode->i_lock);
	list_add(&ctx->list, &nfsi->open_files);
	spin_unlock(&inode->i_lock);
}

709 710 711
/*
 * Given an inode, search for an open context with the desired characteristics
 */
712
struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_cred *cred, fmode_t mode)
L
Linus Torvalds 已提交
713 714 715 716 717 718
{
	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) {
719 720
		if (cred != NULL && pos->cred != cred)
			continue;
721 722 723 724
		if ((pos->mode & (FMODE_READ|FMODE_WRITE)) != mode)
			continue;
		ctx = get_nfs_open_context(pos);
		break;
L
Linus Torvalds 已提交
725 726 727 728 729
	}
	spin_unlock(&inode->i_lock);
	return ctx;
}

730
static void nfs_file_clear_open_context(struct file *filp)
L
Linus Torvalds 已提交
731
{
732
	struct inode *inode = filp->f_path.dentry->d_inode;
733
	struct nfs_open_context *ctx = nfs_file_open_context(filp);
L
Linus Torvalds 已提交
734 735 736 737 738 739

	if (ctx) {
		filp->private_data = NULL;
		spin_lock(&inode->i_lock);
		list_move_tail(&ctx->list, &NFS_I(inode)->open_files);
		spin_unlock(&inode->i_lock);
740
		__put_nfs_open_context(ctx, filp->f_flags & O_DIRECT ? 0 : 1);
L
Linus Torvalds 已提交
741 742 743 744 745 746 747 748 749 750
	}
}

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

751 752 753
	ctx = alloc_nfs_open_context(filp->f_path.dentry, filp->f_mode);
	if (IS_ERR(ctx))
		return PTR_ERR(ctx);
L
Linus Torvalds 已提交
754 755
	nfs_file_set_open_context(filp, ctx);
	put_nfs_open_context(ctx);
D
David Howells 已提交
756
	nfs_fscache_set_inode_cookie(inode, filp);
L
Linus Torvalds 已提交
757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773
	return 0;
}

int nfs_release(struct inode *inode, struct file *filp)
{
	nfs_file_clear_open_context(filp);
	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;
774
	struct nfs_fattr *fattr = NULL;
L
Linus Torvalds 已提交
775 776 777 778 779
	struct nfs_inode *nfsi = NFS_I(inode);

	dfprintk(PAGECACHE, "NFS: revalidating (%s/%Ld)\n",
		inode->i_sb->s_id, (long long)NFS_FILEID(inode));

780
	if (is_bad_inode(inode))
781
		goto out;
L
Linus Torvalds 已提交
782
	if (NFS_STALE(inode))
783
		goto out;
784

785 786 787 788 789
	status = -ENOMEM;
	fattr = nfs_alloc_fattr();
	if (fattr == NULL)
		goto out;

790
	nfs_inc_stats(inode, NFSIOS_INODEREVALIDATE);
791
	status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), fattr);
L
Linus Torvalds 已提交
792 793 794 795 796 797 798
	if (status != 0) {
		dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) getattr failed, error=%d\n",
			 inode->i_sb->s_id,
			 (long long)NFS_FILEID(inode), status);
		if (status == -ESTALE) {
			nfs_zap_caches(inode);
			if (!S_ISDIR(inode->i_mode))
B
Benny Halevy 已提交
799
				set_bit(NFS_INO_STALE, &NFS_I(inode)->flags);
L
Linus Torvalds 已提交
800 801 802 803
		}
		goto out;
	}

804
	status = nfs_refresh_inode(inode, fattr);
L
Linus Torvalds 已提交
805 806 807 808 809 810
	if (status) {
		dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) refresh failed, error=%d\n",
			 inode->i_sb->s_id,
			 (long long)NFS_FILEID(inode), status);
		goto out;
	}
811

812
	if (nfsi->cache_validity & NFS_INO_INVALID_ACL)
813
		nfs_zap_acl_cache(inode);
814

L
Linus Torvalds 已提交
815 816 817 818
	dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n",
		inode->i_sb->s_id,
		(long long)NFS_FILEID(inode));

819
 out:
820
	nfs_free_fattr(fattr);
L
Linus Torvalds 已提交
821 822 823 824 825 826 827
	return status;
}

int nfs_attribute_timeout(struct inode *inode)
{
	struct nfs_inode *nfsi = NFS_I(inode);

828 829 830 831 832
	return !time_in_range_open(jiffies, nfsi->read_cache_jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo);
}

static int nfs_attribute_cache_expired(struct inode *inode)
{
833
	if (nfs_have_delegated_attributes(inode))
L
Linus Torvalds 已提交
834
		return 0;
835
	return nfs_attribute_timeout(inode);
L
Linus Torvalds 已提交
836 837 838 839 840 841 842 843 844 845 846
}

/**
 * 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)
{
847
	if (!(NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATTR)
848
			&& !nfs_attribute_cache_expired(inode))
L
Linus Torvalds 已提交
849 850 851 852
		return NFS_STALE(inode) ? -ESTALE : 0;
	return __nfs_revalidate_inode(server, inode);
}

853
static int nfs_invalidate_mapping(struct inode *inode, struct address_space *mapping)
854 855 856 857 858 859 860 861 862 863
{
	struct nfs_inode *nfsi = NFS_I(inode);
	
	if (mapping->nrpages != 0) {
		int ret = invalidate_inode_pages2(mapping);
		if (ret < 0)
			return ret;
	}
	spin_lock(&inode->i_lock);
	nfsi->cache_validity &= ~NFS_INO_INVALID_DATA;
864
	if (S_ISDIR(inode->i_mode))
865 866 867
		memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
	spin_unlock(&inode->i_lock);
	nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE);
D
David Howells 已提交
868
	nfs_fscache_reset_inode_cookie(inode);
869 870 871 872 873 874 875 876 877 878 879 880 881 882
	dfprintk(PAGECACHE, "NFS: (%s/%Ld) data cache invalidated\n",
			inode->i_sb->s_id, (long long)NFS_FILEID(inode));
	return 0;
}

/**
 * nfs_revalidate_mapping - Revalidate the pagecache
 * @inode - pointer to host inode
 * @mapping - pointer to mapping
 */
int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping)
{
	struct nfs_inode *nfsi = NFS_I(inode);
	int ret = 0;
883

884
	if ((nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE)
885 886
			|| nfs_attribute_cache_expired(inode)
			|| NFS_STALE(inode)) {
887 888 889
		ret = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
		if (ret < 0)
			goto out;
890
	}
891 892
	if (nfsi->cache_validity & NFS_INO_INVALID_DATA)
		ret = nfs_invalidate_mapping(inode, mapping);
893
out:
894
	return ret;
895 896
}

897
static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr)
898 899
{
	struct nfs_inode *nfsi = NFS_I(inode);
900
	unsigned long ret = 0;
901

902 903
	if ((fattr->valid & NFS_ATTR_FATTR_PRECHANGE)
			&& (fattr->valid & NFS_ATTR_FATTR_CHANGE)
904 905
			&& inode->i_version == fattr->pre_change_attr) {
		inode->i_version = fattr->change_attr;
906 907
		if (S_ISDIR(inode->i_mode))
			nfsi->cache_validity |= NFS_INO_INVALID_DATA;
908
		ret |= NFS_INO_INVALID_ATTR;
909
	}
910
	/* If we have atomic WCC data, we may update some attributes */
911 912
	if ((fattr->valid & NFS_ATTR_FATTR_PRECTIME)
			&& (fattr->valid & NFS_ATTR_FATTR_CTIME)
913 914 915 916
			&& timespec_equal(&inode->i_ctime, &fattr->pre_ctime)) {
		memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
		ret |= NFS_INO_INVALID_ATTR;
	}
917 918 919 920

	if ((fattr->valid & NFS_ATTR_FATTR_PREMTIME)
			&& (fattr->valid & NFS_ATTR_FATTR_MTIME)
			&& timespec_equal(&inode->i_mtime, &fattr->pre_mtime)) {
921 922 923 924
		memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));
		if (S_ISDIR(inode->i_mode))
			nfsi->cache_validity |= NFS_INO_INVALID_DATA;
		ret |= NFS_INO_INVALID_ATTR;
925
	}
926 927 928
	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)
929 930 931 932 933
			&& nfsi->npages == 0) {
		i_size_write(inode, nfs_size_to_loff_t(fattr->size));
		ret |= NFS_INO_INVALID_ATTR;
	}
	return ret;
934 935
}

L
Linus Torvalds 已提交
936
/**
937
 * nfs_check_inode_attributes - verify consistency of the inode attribute cache
L
Linus Torvalds 已提交
938 939 940 941 942 943 944
 * @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.
 */
945
static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fattr)
L
Linus Torvalds 已提交
946 947 948
{
	struct nfs_inode *nfsi = NFS_I(inode);
	loff_t cur_size, new_isize;
949
	unsigned long invalid = 0;
L
Linus Torvalds 已提交
950

951

952
	/* Has the inode gone and changed behind our back? */
953 954 955
	if ((fattr->valid & NFS_ATTR_FATTR_FILEID) && nfsi->fileid != fattr->fileid)
		return -EIO;
	if ((fattr->valid & NFS_ATTR_FATTR_TYPE) && (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT))
956 957
		return -EIO;

958
	if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 &&
959
			inode->i_version != fattr->change_attr)
960
		invalid |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
L
Linus Torvalds 已提交
961 962

	/* Verify a few of the more important attributes */
963
	if ((fattr->valid & NFS_ATTR_FATTR_MTIME) && !timespec_equal(&inode->i_mtime, &fattr->mtime))
964
		invalid |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
965

966 967 968 969 970 971
	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 && nfsi->npages == 0)
			invalid |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
	}
L
Linus Torvalds 已提交
972 973

	/* Have any file permissions changed? */
974 975 976 977 978
	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;
	if ((fattr->valid & NFS_ATTR_FATTR_OWNER) && inode->i_uid != fattr->uid)
		invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
	if ((fattr->valid & NFS_ATTR_FATTR_GROUP) && inode->i_gid != fattr->gid)
979
		invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
L
Linus Torvalds 已提交
980 981

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

985
	if ((fattr->valid & NFS_ATTR_FATTR_ATIME) && !timespec_equal(&inode->i_atime, &fattr->atime))
986 987 988 989
		invalid |= NFS_INO_INVALID_ATIME;

	if (invalid != 0)
		nfsi->cache_validity |= invalid;
L
Linus Torvalds 已提交
990

991
	nfsi->read_cache_jiffies = fattr->time_start;
L
Linus Torvalds 已提交
992 993 994
	return 0;
}

995
static int nfs_ctime_need_update(const struct inode *inode, const struct nfs_fattr *fattr)
996
{
997 998
	if (!(fattr->valid & NFS_ATTR_FATTR_CTIME))
		return 0;
999 1000 1001 1002 1003
	return timespec_compare(&fattr->ctime, &inode->i_ctime) > 0;
}

static int nfs_size_need_update(const struct inode *inode, const struct nfs_fattr *fattr)
{
1004 1005
	if (!(fattr->valid & NFS_ATTR_FATTR_SIZE))
		return 0;
1006 1007
	return nfs_size_to_loff_t(fattr->size) > i_size_read(inode);
}
1008

1009
static atomic_long_t nfs_attr_generation_counter;
1010 1011 1012

static unsigned long nfs_read_attr_generation_counter(void)
{
1013
	return atomic_long_read(&nfs_attr_generation_counter);
1014 1015 1016 1017
}

unsigned long nfs_inc_attr_generation_counter(void)
{
1018
	return atomic_long_inc_return(&nfs_attr_generation_counter);
1019 1020 1021 1022 1023 1024 1025
}

void nfs_fattr_init(struct nfs_fattr *fattr)
{
	fattr->valid = 0;
	fattr->time_start = jiffies;
	fattr->gencount = nfs_inc_attr_generation_counter();
1026 1027
	fattr->owner_name = NULL;
	fattr->group_name = NULL;
1028 1029
}

1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049
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;
}

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

1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066
#ifdef RPC_DEBUG
/*
 * _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 */
	return ~crc32(0xFFFFFFFF, &fh->data[0], fh->size);
}

/*
1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077
 * _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;

1078
	if (fh == NULL || fh->size == 0) {
1079 1080 1081 1082
		printk(KERN_DEFAULT "%s at %p is empty\n", caption, fh);
		return;
	}

1083 1084
	printk(KERN_DEFAULT "%s at %p is %u bytes, crc: 0x%08x:\n",
	       caption, fh, fh->size, _nfs_display_fhandle_hash(fh));
1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110
	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));
		}
	}
}
#endif

1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123
/**
 * 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.
1124
 * Note also the check for wraparound of 'attr_gencount'
1125 1126 1127 1128 1129 1130 1131 1132 1133
 *
 * 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);

1134
	return ((long)fattr->gencount - (long)nfsi->attr_gencount) > 0 ||
T
Trond Myklebust 已提交
1135 1136
		nfs_ctime_need_update(inode, fattr) ||
		nfs_size_need_update(inode, fattr) ||
1137
		((long)nfsi->attr_gencount - (long)nfs_read_attr_generation_counter() > 0);
1138 1139 1140 1141 1142
}

static int nfs_refresh_inode_locked(struct inode *inode, struct nfs_fattr *fattr)
{
	if (nfs_inode_attrs_need_update(inode, fattr))
1143 1144 1145 1146
		return nfs_update_inode(inode, fattr);
	return nfs_check_inode_attributes(inode, fattr);
}

1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163
/**
 * 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);
1164
	status = nfs_refresh_inode_locked(inode, fattr);
1165
	spin_unlock(&inode->i_lock);
D
David Howells 已提交
1166

1167 1168 1169
	return status;
}

1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181
static int nfs_post_op_update_inode_locked(struct inode *inode, struct nfs_fattr *fattr)
{
	struct nfs_inode *nfsi = NFS_I(inode);

	nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
	if (S_ISDIR(inode->i_mode))
		nfsi->cache_validity |= NFS_INO_INVALID_DATA;
	if ((fattr->valid & NFS_ATTR_FATTR) == 0)
		return 0;
	return nfs_refresh_inode_locked(inode, fattr);
}

1182 1183 1184 1185 1186 1187 1188
/**
 * 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.
1189 1190 1191 1192 1193 1194
 *
 * 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().
1195 1196 1197
 */
int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr)
{
1198
	int status;
1199

1200
	spin_lock(&inode->i_lock);
1201
	status = nfs_post_op_update_inode_locked(inode, fattr);
1202
	spin_unlock(&inode->i_lock);
1203
	return status;
1204 1205
}

1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218
/**
 * 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)
{
1219 1220 1221 1222 1223 1224
	int status;

	spin_lock(&inode->i_lock);
	/* 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)) {
1225 1226 1227 1228
		fattr->valid &= ~(NFS_ATTR_FATTR_PRECHANGE
				| NFS_ATTR_FATTR_PRESIZE
				| NFS_ATTR_FATTR_PREMTIME
				| NFS_ATTR_FATTR_PRECTIME);
1229 1230
		goto out_noforce;
	}
1231 1232
	if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 &&
			(fattr->valid & NFS_ATTR_FATTR_PRECHANGE) == 0) {
1233
		fattr->pre_change_attr = inode->i_version;
1234
		fattr->valid |= NFS_ATTR_FATTR_PRECHANGE;
1235
	}
1236 1237
	if ((fattr->valid & NFS_ATTR_FATTR_CTIME) != 0 &&
			(fattr->valid & NFS_ATTR_FATTR_PRECTIME) == 0) {
1238
		memcpy(&fattr->pre_ctime, &inode->i_ctime, sizeof(fattr->pre_ctime));
1239 1240 1241 1242
		fattr->valid |= NFS_ATTR_FATTR_PRECTIME;
	}
	if ((fattr->valid & NFS_ATTR_FATTR_MTIME) != 0 &&
			(fattr->valid & NFS_ATTR_FATTR_PREMTIME) == 0) {
1243
		memcpy(&fattr->pre_mtime, &inode->i_mtime, sizeof(fattr->pre_mtime));
1244 1245 1246 1247
		fattr->valid |= NFS_ATTR_FATTR_PREMTIME;
	}
	if ((fattr->valid & NFS_ATTR_FATTR_SIZE) != 0 &&
			(fattr->valid & NFS_ATTR_FATTR_PRESIZE) == 0) {
1248
		fattr->pre_size = i_size_read(inode);
1249
		fattr->valid |= NFS_ATTR_FATTR_PRESIZE;
1250
	}
1251 1252 1253 1254
out_noforce:
	status = nfs_post_op_update_inode_locked(inode, fattr);
	spin_unlock(&inode->i_lock);
	return status;
1255 1256
}

L
Linus Torvalds 已提交
1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268
/*
 * 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.
 */
1269
static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
L
Linus Torvalds 已提交
1270
{
1271
	struct nfs_server *server;
L
Linus Torvalds 已提交
1272
	struct nfs_inode *nfsi = NFS_I(inode);
1273
	loff_t cur_isize, new_isize;
1274
	unsigned long invalid = 0;
1275
	unsigned long now = jiffies;
1276
	unsigned long save_cache_validity;
L
Linus Torvalds 已提交
1277

1278
	dfprintk(VFS, "NFS: %s(%s/%ld fh_crc=0x%08x ct=%d info=0x%x)\n",
1279
			__func__, inode->i_sb->s_id, inode->i_ino,
1280
			nfs_display_fhandle_hash(NFS_FH(inode)),
L
Linus Torvalds 已提交
1281 1282
			atomic_read(&inode->i_count), fattr->valid);

1283
	if ((fattr->valid & NFS_ATTR_FATTR_FILEID) && nfsi->fileid != fattr->fileid)
1284
		goto out_fileid;
L
Linus Torvalds 已提交
1285 1286 1287 1288

	/*
	 * Make sure the inode's type hasn't changed.
	 */
1289
	if ((fattr->valid & NFS_ATTR_FATTR_TYPE) && (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT))
L
Linus Torvalds 已提交
1290 1291
		goto out_changed;

1292
	server = NFS_SERVER(inode);
T
Trond Myklebust 已提交
1293
	/* Update the fsid? */
1294
	if (S_ISDIR(inode->i_mode) && (fattr->valid & NFS_ATTR_FATTR_FSID) &&
1295
			!nfs_fsid_equal(&server->fsid, &fattr->fsid) &&
1296
			!IS_AUTOMOUNT(inode))
1297 1298
		server->fsid = fattr->fsid;

L
Linus Torvalds 已提交
1299 1300 1301
	/*
	 * Update the read time so we don't revalidate too often.
	 */
1302
	nfsi->read_cache_jiffies = fattr->time_start;
1303

1304 1305 1306 1307 1308
	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 已提交
1309

1310
	/* Do atomic weak cache consistency updates */
1311
	invalid |= nfs_wcc_update_inode(inode, fattr);
1312

1313
	/* More cache consistency checks */
1314
	if (fattr->valid & NFS_ATTR_FATTR_CHANGE) {
1315
		if (inode->i_version != fattr->change_attr) {
1316 1317 1318 1319 1320
			dprintk("NFS: change_attr change on server for file %s/%ld\n",
					inode->i_sb->s_id, inode->i_ino);
			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);
1321
			inode->i_version = fattr->change_attr;
1322
		}
1323 1324
	} else if (server->caps & NFS_CAP_CHANGE_ATTR)
		invalid |= save_cache_validity;
1325 1326

	if (fattr->valid & NFS_ATTR_FATTR_MTIME) {
1327 1328 1329 1330 1331
		/* NFSv2/v3: Check if the mtime agrees */
		if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) {
			dprintk("NFS: mtime change on server for file %s/%ld\n",
					inode->i_sb->s_id, inode->i_ino);
			invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
1332 1333
			if (S_ISDIR(inode->i_mode))
				nfs_force_lookup_revalidate(inode);
1334
			memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));
1335
		}
1336 1337 1338 1339 1340 1341
	} else if (server->caps & NFS_CAP_MTIME)
		invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR
				| NFS_INO_INVALID_DATA
				| NFS_INO_REVAL_PAGECACHE
				| NFS_INO_REVAL_FORCED);

1342
	if (fattr->valid & NFS_ATTR_FATTR_CTIME) {
1343
		/* If ctime has changed we should definitely clear access+acl caches */
1344
		if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) {
1345
			invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
1346 1347 1348 1349 1350 1351 1352
			/* and probably clear data for a directory too as utimes can cause
			 * havoc with our cache.
			 */
			if (S_ISDIR(inode->i_mode)) {
				invalid |= NFS_INO_INVALID_DATA;
				nfs_force_lookup_revalidate(inode);
			}
1353
			memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
1354
		}
1355 1356 1357 1358 1359
	} else if (server->caps & NFS_CAP_CTIME)
		invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR
				| NFS_INO_INVALID_ACCESS
				| NFS_INO_INVALID_ACL
				| NFS_INO_REVAL_FORCED);
1360

1361
	/* Check if our cached file size is stale */
1362 1363 1364 1365 1366 1367
	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? */
1368 1369
			if ((nfsi->npages == 0 && !test_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) ||
			     new_isize > cur_isize) {
1370 1371 1372
				i_size_write(inode, new_isize);
				invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
			}
1373 1374 1375 1376 1377 1378
			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 已提交
1379
		}
1380 1381 1382 1383
	} else
		invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR
				| NFS_INO_REVAL_PAGECACHE
				| NFS_INO_REVAL_FORCED);
L
Linus Torvalds 已提交
1384 1385


1386 1387
	if (fattr->valid & NFS_ATTR_FATTR_ATIME)
		memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
1388 1389 1390
	else if (server->caps & NFS_CAP_ATIME)
		invalid |= save_cache_validity & (NFS_INO_INVALID_ATIME
				| NFS_INO_REVAL_FORCED);
L
Linus Torvalds 已提交
1391

1392 1393
	if (fattr->valid & NFS_ATTR_FATTR_MODE) {
		if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)) {
1394 1395 1396
			umode_t newmode = inode->i_mode & S_IFMT;
			newmode |= fattr->mode & S_IALLUGO;
			inode->i_mode = newmode;
1397 1398
			invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
		}
1399 1400 1401 1402 1403 1404
	} else if (server->caps & NFS_CAP_MODE)
		invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR
				| NFS_INO_INVALID_ACCESS
				| NFS_INO_INVALID_ACL
				| NFS_INO_REVAL_FORCED);

1405 1406 1407 1408 1409
	if (fattr->valid & NFS_ATTR_FATTR_OWNER) {
		if (inode->i_uid != fattr->uid) {
			invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
			inode->i_uid = fattr->uid;
		}
1410 1411 1412 1413 1414 1415
	} else if (server->caps & NFS_CAP_OWNER)
		invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR
				| NFS_INO_INVALID_ACCESS
				| NFS_INO_INVALID_ACL
				| NFS_INO_REVAL_FORCED);

1416 1417 1418 1419 1420
	if (fattr->valid & NFS_ATTR_FATTR_GROUP) {
		if (inode->i_gid != fattr->gid) {
			invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
			inode->i_gid = fattr->gid;
		}
1421 1422 1423 1424 1425
	} else if (server->caps & NFS_CAP_OWNER_GROUP)
		invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR
				| NFS_INO_INVALID_ACCESS
				| NFS_INO_INVALID_ACL
				| NFS_INO_REVAL_FORCED);
1426

1427 1428 1429 1430 1431
	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 已提交
1432
			set_nlink(inode, fattr->nlink);
1433
		}
1434 1435 1436
	} else if (server->caps & NFS_CAP_NLINK)
		invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR
				| NFS_INO_REVAL_FORCED);
L
Linus Torvalds 已提交
1437

1438
	if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) {
L
Linus Torvalds 已提交
1439 1440 1441 1442 1443
		/*
		 * report the blocks in 512byte units
		 */
		inode->i_blocks = nfs_calc_block_size(fattr->du.nfs3.used);
 	}
1444 1445
	if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED)
		inode->i_blocks = fattr->du.nfs2.blocks;
L
Linus Torvalds 已提交
1446 1447 1448

	/* Update attrtimeo value if we're out of the unstable period */
	if (invalid & NFS_INO_INVALID_ATTR) {
C
Chuck Lever 已提交
1449
		nfs_inc_stats(inode, NFSIOS_ATTRINVALIDATE);
L
Linus Torvalds 已提交
1450
		nfsi->attrtimeo = NFS_MINATTRTIMEO(inode);
1451
		nfsi->attrtimeo_timestamp = now;
1452
		nfsi->attr_gencount = nfs_inc_attr_generation_counter();
1453
	} else {
1454
		if (!time_in_range_open(now, nfsi->attrtimeo_timestamp, nfsi->attrtimeo_timestamp + nfsi->attrtimeo)) {
1455 1456 1457 1458
			if ((nfsi->attrtimeo <<= 1) > NFS_MAXATTRTIMEO(inode))
				nfsi->attrtimeo = NFS_MAXATTRTIMEO(inode);
			nfsi->attrtimeo_timestamp = now;
		}
L
Linus Torvalds 已提交
1459
	}
1460
	invalid &= ~NFS_INO_INVALID_ATTR;
L
Linus Torvalds 已提交
1461 1462 1463 1464
	/* 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;
1465
	if (!nfs_have_delegation(inode, FMODE_READ) ||
1466
			(save_cache_validity & NFS_INO_REVAL_FORCED))
1467
		nfsi->cache_validity |= invalid;
L
Linus Torvalds 已提交
1468 1469 1470 1471 1472 1473

	return 0;
 out_changed:
	/*
	 * Big trouble! The inode has become a different object.
	 */
1474
	printk(KERN_DEBUG "NFS: %s: inode %ld mode changed, %07o to %07o\n",
1475
			__func__, inode->i_ino, inode->i_mode, fattr->mode);
1476
 out_err:
L
Linus Torvalds 已提交
1477 1478 1479 1480 1481 1482 1483
	/*
	 * 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;
1484 1485 1486 1487

 out_fileid:
	printk(KERN_ERR "NFS: server %s error: fileid changed\n"
		"fsid %s: expected fileid 0x%Lx, got 0x%Lx\n",
1488
		NFS_SERVER(inode)->nfs_client->cl_hostname, inode->i_sb->s_id,
1489 1490
		(long long)nfsi->fileid, (long long)fattr->fileid);
	goto out_err;
L
Linus Torvalds 已提交
1491 1492
}

1493

L
Linus Torvalds 已提交
1494 1495 1496 1497 1498 1499 1500
#ifdef CONFIG_NFS_V4

/*
 * Clean out any remaining NFSv4 state that might be left over due
 * to open() calls that passed nfs_atomic_lookup, but failed to call
 * nfs_open().
 */
1501
void nfs4_evict_inode(struct inode *inode)
L
Linus Torvalds 已提交
1502
{
1503 1504
	truncate_inode_pages(&inode->i_data, 0);
	end_writeback(inode);
B
Benny Halevy 已提交
1505 1506
	pnfs_return_layout(inode);
	pnfs_destroy_layout(NFS_I(inode));
L
Linus Torvalds 已提交
1507
	/* If we are holding a delegation, return it! */
1508
	nfs_inode_return_delegation_noreclaim(inode);
L
Linus Torvalds 已提交
1509 1510 1511 1512 1513
	/* First call standard NFS clear_inode() code */
	nfs_clear_inode(inode);
}
#endif

D
David Howells 已提交
1514
struct inode *nfs_alloc_inode(struct super_block *sb)
L
Linus Torvalds 已提交
1515 1516
{
	struct nfs_inode *nfsi;
1517
	nfsi = (struct nfs_inode *)kmem_cache_alloc(nfs_inode_cachep, GFP_KERNEL);
L
Linus Torvalds 已提交
1518 1519
	if (!nfsi)
		return NULL;
1520 1521
	nfsi->flags = 0UL;
	nfsi->cache_validity = 0UL;
1522 1523 1524 1525
#ifdef CONFIG_NFS_V3_ACL
	nfsi->acl_access = ERR_PTR(-EAGAIN);
	nfsi->acl_default = ERR_PTR(-EAGAIN);
#endif
1526 1527 1528
#ifdef CONFIG_NFS_V4
	nfsi->nfs4_acl = NULL;
#endif /* CONFIG_NFS_V4 */
L
Linus Torvalds 已提交
1529 1530 1531
	return &nfsi->vfs_inode;
}

N
Nick Piggin 已提交
1532
static void nfs_i_callback(struct rcu_head *head)
L
Linus Torvalds 已提交
1533
{
N
Nick Piggin 已提交
1534
	struct inode *inode = container_of(head, struct inode, i_rcu);
L
Linus Torvalds 已提交
1535 1536 1537
	kmem_cache_free(nfs_inode_cachep, NFS_I(inode));
}

N
Nick Piggin 已提交
1538 1539 1540 1541 1542
void nfs_destroy_inode(struct inode *inode)
{
	call_rcu(&inode->i_rcu, nfs_i_callback);
}

A
Andrew Morton 已提交
1543 1544 1545 1546 1547 1548 1549
static inline void nfs4_init_once(struct nfs_inode *nfsi)
{
#ifdef CONFIG_NFS_V4
	INIT_LIST_HEAD(&nfsi->open_states);
	nfsi->delegation = NULL;
	nfsi->delegation_state = 0;
	init_rwsem(&nfsi->rwsem);
1550
	nfsi->layout = NULL;
1551
	atomic_set(&nfsi->commits_outstanding, 0);
A
Andrew Morton 已提交
1552 1553
#endif
}
D
David Howells 已提交
1554

1555
static void init_once(void *foo)
L
Linus Torvalds 已提交
1556 1557 1558
{
	struct nfs_inode *nfsi = (struct nfs_inode *) foo;

C
Christoph Lameter 已提交
1559 1560 1561 1562 1563 1564
	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);
	INIT_RADIX_TREE(&nfsi->nfs_page_tree, GFP_ATOMIC);
	nfsi->npages = 0;
1565
	nfsi->ncommit = 0;
T
Trond Myklebust 已提交
1566 1567 1568
	atomic_set(&nfsi->silly_count, 1);
	INIT_HLIST_HEAD(&nfsi->silly_list);
	init_waitqueue_head(&nfsi->waitqueue);
C
Christoph Lameter 已提交
1569
	nfs4_init_once(nfsi);
L
Linus Torvalds 已提交
1570
}
1571

D
David Howells 已提交
1572
static int __init nfs_init_inodecache(void)
L
Linus Torvalds 已提交
1573 1574 1575
{
	nfs_inode_cachep = kmem_cache_create("nfs_inode_cache",
					     sizeof(struct nfs_inode),
1576 1577
					     0, (SLAB_RECLAIM_ACCOUNT|
						SLAB_MEM_SPREAD),
1578
					     init_once);
L
Linus Torvalds 已提交
1579 1580 1581 1582 1583 1584
	if (nfs_inode_cachep == NULL)
		return -ENOMEM;

	return 0;
}

1585
static void nfs_destroy_inodecache(void)
L
Linus Torvalds 已提交
1586
{
1587
	kmem_cache_destroy(nfs_inode_cachep);
L
Linus Torvalds 已提交
1588 1589
}

T
Trond Myklebust 已提交
1590 1591 1592 1593 1594 1595 1596 1597 1598
struct workqueue_struct *nfsiod_workqueue;

/*
 * start up the nfsiod workqueue
 */
static int nfsiod_start(void)
{
	struct workqueue_struct *wq;
	dprintk("RPC:       creating workqueue nfsiod\n");
1599
	wq = alloc_workqueue("nfsiod", WQ_MEM_RECLAIM, 0);
T
Trond Myklebust 已提交
1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619
	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);
}

1620
int nfs_net_id;
1621
EXPORT_SYMBOL_GPL(nfs_net_id);
1622 1623 1624

static int nfs_net_init(struct net *net)
{
1625
	nfs_clients_init(net);
1626 1627 1628 1629 1630 1631
	return nfs_dns_resolver_cache_init(net);
}

static void nfs_net_exit(struct net *net)
{
	nfs_dns_resolver_cache_destroy(net);
1632
	nfs_cleanup_cb_ident_idr(net);
1633 1634 1635 1636 1637 1638 1639 1640 1641
}

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 已提交
1642 1643 1644 1645 1646 1647 1648
/*
 * Initialize NFS
 */
static int __init init_nfs_fs(void)
{
	int err;

B
Bryan Schumaker 已提交
1649 1650
	err = nfs_idmap_init();
	if (err < 0)
1651
		goto out10;
B
Bryan Schumaker 已提交
1652

1653
	err = nfs_dns_resolver_init();
1654 1655 1656 1657
	if (err < 0)
		goto out9;

	err = register_pernet_subsys(&nfs_net_ops);
1658 1659 1660
	if (err < 0)
		goto out8;

1661 1662 1663 1664
	err = nfs_fscache_register();
	if (err < 0)
		goto out7;

T
Trond Myklebust 已提交
1665 1666 1667 1668
	err = nfsiod_start();
	if (err)
		goto out6;

1669 1670 1671 1672
	err = nfs_fs_proc_init();
	if (err)
		goto out5;

L
Linus Torvalds 已提交
1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693
	err = nfs_init_nfspagecache();
	if (err)
		goto out4;

	err = nfs_init_inodecache();
	if (err)
		goto out3;

	err = nfs_init_readpagecache();
	if (err)
		goto out2;

	err = nfs_init_writepagecache();
	if (err)
		goto out1;

	err = nfs_init_directcache();
	if (err)
		goto out0;

#ifdef CONFIG_PROC_FS
1694
	rpc_proc_register(&init_net, &nfs_rpcstat);
L
Linus Torvalds 已提交
1695
#endif
D
David Howells 已提交
1696
	if ((err = register_nfs_fs()) != 0)
L
Linus Torvalds 已提交
1697 1698 1699 1700
		goto out;
	return 0;
out:
#ifdef CONFIG_PROC_FS
1701
	rpc_proc_unregister(&init_net, "nfs");
L
Linus Torvalds 已提交
1702 1703
#endif
	nfs_destroy_directcache();
1704 1705
out0:
	nfs_destroy_writepagecache();
L
Linus Torvalds 已提交
1706 1707 1708 1709 1710 1711 1712
out1:
	nfs_destroy_readpagecache();
out2:
	nfs_destroy_inodecache();
out3:
	nfs_destroy_nfspagecache();
out4:
1713 1714
	nfs_fs_proc_exit();
out5:
T
Trond Myklebust 已提交
1715 1716
	nfsiod_stop();
out6:
1717 1718
	nfs_fscache_unregister();
out7:
1719
	unregister_pernet_subsys(&nfs_net_ops);
1720
out8:
1721
	nfs_dns_resolver_destroy();
B
Bryan Schumaker 已提交
1722
out9:
1723 1724
	nfs_idmap_quit();
out10:
L
Linus Torvalds 已提交
1725 1726 1727 1728 1729 1730 1731 1732 1733 1734
	return err;
}

static void __exit exit_nfs_fs(void)
{
	nfs_destroy_directcache();
	nfs_destroy_writepagecache();
	nfs_destroy_readpagecache();
	nfs_destroy_inodecache();
	nfs_destroy_nfspagecache();
1735
	nfs_fscache_unregister();
1736
	unregister_pernet_subsys(&nfs_net_ops);
1737
	nfs_dns_resolver_destroy();
B
Bryan Schumaker 已提交
1738
	nfs_idmap_quit();
L
Linus Torvalds 已提交
1739
#ifdef CONFIG_PROC_FS
1740
	rpc_proc_unregister(&init_net, "nfs");
L
Linus Torvalds 已提交
1741
#endif
D
David Howells 已提交
1742
	unregister_nfs_fs();
1743
	nfs_fs_proc_exit();
T
Trond Myklebust 已提交
1744
	nfsiod_stop();
L
Linus Torvalds 已提交
1745 1746 1747 1748 1749
}

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

module_init(init_nfs_fs)
module_exit(exit_nfs_fs)