dir.c 65.9 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*
 *  linux/fs/nfs/dir.c
 *
 *  Copyright (C) 1992  Rick Sladkey
 *
 *  nfs directory handling functions
 *
 * 10 Apr 1996	Added silly rename for unlink	--okir
 * 28 Sep 1996	Improved directory cache --okir
 * 23 Aug 1997  Claus Heine claus@momo.math.rwth-aachen.de 
 *              Re-implemented silly rename for unlink, newly implemented
 *              silly rename for nfs_rename() following the suggestions
 *              of Olaf Kirch (okir) found in this file.
 *              Following Linus comments on my original hack, this version
 *              depends only on the dcache stuff and doesn't touch the inode
 *              layer (iput() and friends).
 *  6 Jun 1999	Cache readdir lookups in the page cache. -DaveM
 */

20
#include <linux/module.h>
Linus Torvalds's avatar
Linus Torvalds committed
21 22 23 24 25 26 27 28 29 30 31 32
#include <linux/time.h>
#include <linux/errno.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/sunrpc/clnt.h>
#include <linux/nfs_fs.h>
#include <linux/nfs_mount.h>
#include <linux/pagemap.h>
33
#include <linux/pagevec.h>
Linus Torvalds's avatar
Linus Torvalds committed
34
#include <linux/namei.h>
35
#include <linux/mount.h>
36
#include <linux/swap.h>
Alexey Dobriyan's avatar
Alexey Dobriyan committed
37
#include <linux/sched.h>
38
#include <linux/kmemleak.h>
39
#include <linux/xattr.h>
Linus Torvalds's avatar
Linus Torvalds committed
40 41

#include "delegation.h"
42
#include "iostat.h"
43
#include "internal.h"
44
#include "fscache.h"
Linus Torvalds's avatar
Linus Torvalds committed
45

46 47
#include "nfstrace.h"

Linus Torvalds's avatar
Linus Torvalds committed
48 49 50
/* #define NFS_DEBUG_VERBOSE 1 */

static int nfs_opendir(struct inode *, struct file *);
51
static int nfs_closedir(struct inode *, struct file *);
Al Viro's avatar
Al Viro committed
52
static int nfs_readdir(struct file *, struct dir_context *);
53
static int nfs_fsync_dir(struct file *, loff_t, loff_t, int);
54
static loff_t nfs_llseek_dir(struct file *, loff_t, int);
55
static void nfs_readdir_clear_array(struct page*);
Linus Torvalds's avatar
Linus Torvalds committed
56

57
const struct file_operations nfs_dir_operations = {
58
	.llseek		= nfs_llseek_dir,
Linus Torvalds's avatar
Linus Torvalds committed
59
	.read		= generic_read_dir,
60
	.iterate	= nfs_readdir,
Linus Torvalds's avatar
Linus Torvalds committed
61
	.open		= nfs_opendir,
62
	.release	= nfs_closedir,
Linus Torvalds's avatar
Linus Torvalds committed
63 64 65
	.fsync		= nfs_fsync_dir,
};

66 67
const struct address_space_operations nfs_dir_aops = {
	.freepage = nfs_readdir_clear_array,
68 69
};

70
static struct nfs_open_dir_context *alloc_nfs_open_dir_context(struct inode *dir, const struct cred *cred)
71
{
72
	struct nfs_inode *nfsi = NFS_I(dir);
73 74 75
	struct nfs_open_dir_context *ctx;
	ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
	if (ctx != NULL) {
76
		ctx->duped = 0;
77
		ctx->attr_gencount = nfsi->attr_gencount;
78
		ctx->dir_cookie = 0;
79
		ctx->dup_cookie = 0;
80
		ctx->cred = get_cred(cred);
81 82 83
		spin_lock(&dir->i_lock);
		list_add(&ctx->list, &nfsi->open_files);
		spin_unlock(&dir->i_lock);
84 85 86
		return ctx;
	}
	return  ERR_PTR(-ENOMEM);
87 88
}

89
static void put_nfs_open_dir_context(struct inode *dir, struct nfs_open_dir_context *ctx)
90
{
91 92 93
	spin_lock(&dir->i_lock);
	list_del(&ctx->list);
	spin_unlock(&dir->i_lock);
94
	put_cred(ctx->cred);
95 96 97
	kfree(ctx);
}

Linus Torvalds's avatar
Linus Torvalds committed
98 99 100 101 102 103
/*
 * Open file
 */
static int
nfs_opendir(struct inode *inode, struct file *filp)
{
104 105
	int res = 0;
	struct nfs_open_dir_context *ctx;
Linus Torvalds's avatar
Linus Torvalds committed
106

107
	dfprintk(FILE, "NFS: open dir(%pD2)\n", filp);
108 109

	nfs_inc_stats(inode, NFSIOS_VFSOPEN);
Chuck Lever's avatar
Chuck Lever committed
110

111
	ctx = alloc_nfs_open_dir_context(inode, current_cred());
112 113 114 115 116 117
	if (IS_ERR(ctx)) {
		res = PTR_ERR(ctx);
		goto out;
	}
	filp->private_data = ctx;
out:
Linus Torvalds's avatar
Linus Torvalds committed
118 119 120
	return res;
}

121 122 123
static int
nfs_closedir(struct inode *inode, struct file *filp)
{
Al Viro's avatar
Al Viro committed
124
	put_nfs_open_dir_context(file_inode(filp), filp->private_data);
125 126 127
	return 0;
}

128 129 130 131
struct nfs_cache_array_entry {
	u64 cookie;
	u64 ino;
	struct qstr string;
132
	unsigned char d_type;
133 134 135
};

struct nfs_cache_array {
136
	int size;
137 138 139 140 141
	int eof_index;
	u64 last_cookie;
	struct nfs_cache_array_entry array[0];
};

142
typedef int (*decode_dirent_t)(struct xdr_stream *, struct nfs_entry *, bool);
Linus Torvalds's avatar
Linus Torvalds committed
143 144 145
typedef struct {
	struct file	*file;
	struct page	*page;
Al Viro's avatar
Al Viro committed
146
	struct dir_context *ctx;
Linus Torvalds's avatar
Linus Torvalds committed
147
	unsigned long	page_index;
148
	u64		*dir_cookie;
149
	u64		last_cookie;
150
	loff_t		current_index;
Linus Torvalds's avatar
Linus Torvalds committed
151
	decode_dirent_t	decode;
152

153
	unsigned long	timestamp;
154
	unsigned long	gencount;
155
	unsigned int	cache_entry_index;
156 157
	bool plus;
	bool eof;
Linus Torvalds's avatar
Linus Torvalds committed
158 159
} nfs_readdir_descriptor_t;

160 161 162 163
/*
 * we are freeing strings created by nfs_add_to_readdir_array()
 */
static
164
void nfs_readdir_clear_array(struct page *page)
165
{
166
	struct nfs_cache_array *array;
167
	int i;
168

169
	array = kmap_atomic(page);
170 171
	for (i = 0; i < array->size; i++)
		kfree(array->array[i].string.name);
172
	kunmap_atomic(array);
173 174 175 176 177 178 179 180
}

/*
 * the caller is responsible for freeing qstr.name
 * when called by nfs_readdir_add_to_array, the strings will be freed in
 * nfs_clear_readdir_array()
 */
static
181
int nfs_readdir_make_qstr(struct qstr *string, const char *name, unsigned int len)
182 183 184
{
	string->len = len;
	string->name = kmemdup(name, len, GFP_KERNEL);
185 186
	if (string->name == NULL)
		return -ENOMEM;
187 188 189 190 191
	/*
	 * Avoid a kmemleak false positive. The pointer to the name is stored
	 * in a page cache page which kmemleak does not scan.
	 */
	kmemleak_not_leak(string->name);
192
	string->hash = full_name_hash(NULL, name, len);
193
	return 0;
194 195 196 197 198
}

static
int nfs_readdir_add_to_array(struct nfs_entry *entry, struct page *page)
{
199
	struct nfs_cache_array *array = kmap(page);
200 201 202
	struct nfs_cache_array_entry *cache_entry;
	int ret;

203 204 205
	cache_entry = &array->array[array->size];

	/* Check that this entry lies within the page bounds */
206
	ret = -ENOSPC;
207
	if ((char *)&cache_entry[1] - (char *)page_address(page) > PAGE_SIZE)
208
		goto out;
209

210 211
	cache_entry->cookie = entry->prev_cookie;
	cache_entry->ino = entry->ino;
212
	cache_entry->d_type = entry->d_type;
213 214 215
	ret = nfs_readdir_make_qstr(&cache_entry->string, entry->name, entry->len);
	if (ret)
		goto out;
216
	array->last_cookie = entry->cookie;
217
	array->size++;
Trond Myklebust's avatar
Trond Myklebust committed
218
	if (entry->eof != 0)
219
		array->eof_index = array->size;
220
out:
221
	kunmap(page);
222
	return ret;
223 224 225 226 227
}

static
int nfs_readdir_search_for_pos(struct nfs_cache_array *array, nfs_readdir_descriptor_t *desc)
{
Al Viro's avatar
Al Viro committed
228
	loff_t diff = desc->ctx->pos - desc->current_index;
229 230 231 232 233
	unsigned int index;

	if (diff < 0)
		goto out_eof;
	if (diff >= array->size) {
234
		if (array->eof_index >= 0)
235 236 237 238 239 240 241 242 243
			goto out_eof;
		return -EAGAIN;
	}

	index = (unsigned int)diff;
	*desc->dir_cookie = array->array[index].cookie;
	desc->cache_entry_index = index;
	return 0;
out_eof:
244
	desc->eof = true;
245 246 247
	return -EBADCOOKIE;
}

248 249 250 251 252 253 254 255 256
static bool
nfs_readdir_inode_mapping_valid(struct nfs_inode *nfsi)
{
	if (nfsi->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA))
		return false;
	smp_rmb();
	return !test_bit(NFS_INO_INVALIDATING, &nfsi->flags);
}

257 258 259 260
static
int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_descriptor_t *desc)
{
	int i;
261
	loff_t new_pos;
262 263 264 265
	int status = -EAGAIN;

	for (i = 0; i < array->size; i++) {
		if (array->array[i].cookie == *desc->dir_cookie) {
Al Viro's avatar
Al Viro committed
266
			struct nfs_inode *nfsi = NFS_I(file_inode(desc->file));
267 268
			struct nfs_open_dir_context *ctx = desc->file->private_data;

269
			new_pos = desc->current_index + i;
270 271
			if (ctx->attr_gencount != nfsi->attr_gencount ||
			    !nfs_readdir_inode_mapping_valid(nfsi)) {
272 273
				ctx->duped = 0;
				ctx->attr_gencount = nfsi->attr_gencount;
Al Viro's avatar
Al Viro committed
274
			} else if (new_pos < desc->ctx->pos) {
275 276 277
				if (ctx->duped > 0
				    && ctx->dup_cookie == *desc->dir_cookie) {
					if (printk_ratelimit()) {
278
						pr_notice("NFS: directory %pD2 contains a readdir loop."
279
								"Please contact your server vendor.  "
280 281 282
								"The file: %.*s has duplicate cookie %llu\n",
								desc->file, array->array[i].string.len,
								array->array[i].string.name, *desc->dir_cookie);
283 284 285 286
					}
					status = -ELOOP;
					goto out;
				}
287
				ctx->dup_cookie = *desc->dir_cookie;
288
				ctx->duped = -1;
289
			}
Al Viro's avatar
Al Viro committed
290
			desc->ctx->pos = new_pos;
291
			desc->cache_entry_index = i;
Trond Myklebust's avatar
Trond Myklebust committed
292
			return 0;
293 294
		}
	}
Trond Myklebust's avatar
Trond Myklebust committed
295
	if (array->eof_index >= 0) {
296
		status = -EBADCOOKIE;
297
		if (*desc->dir_cookie == array->last_cookie)
298
			desc->eof = true;
299
	}
300
out:
301 302 303 304 305 306 307
	return status;
}

static
int nfs_readdir_search_array(nfs_readdir_descriptor_t *desc)
{
	struct nfs_cache_array *array;
Trond Myklebust's avatar
Trond Myklebust committed
308
	int status;
309

310
	array = kmap(desc->page);
311 312 313 314 315 316

	if (*desc->dir_cookie == 0)
		status = nfs_readdir_search_for_pos(array, desc);
	else
		status = nfs_readdir_search_for_cookie(array, desc);

Trond Myklebust's avatar
Trond Myklebust committed
317
	if (status == -EAGAIN) {
318
		desc->last_cookie = array->last_cookie;
319
		desc->current_index += array->size;
Trond Myklebust's avatar
Trond Myklebust committed
320 321
		desc->page_index++;
	}
322
	kunmap(desc->page);
323 324 325 326 327
	return status;
}

/* Fill a page with xdr information before transferring to the cache page */
static
328
int nfs_readdir_xdr_filler(struct page **pages, nfs_readdir_descriptor_t *desc,
329
			struct nfs_entry *entry, struct file *file, struct inode *inode)
Linus Torvalds's avatar
Linus Torvalds committed
330
{
331
	struct nfs_open_dir_context *ctx = file->private_data;
332
	const struct cred *cred = ctx->cred;
333
	unsigned long	timestamp, gencount;
Linus Torvalds's avatar
Linus Torvalds committed
334 335 336 337
	int		error;

 again:
	timestamp = jiffies;
338
	gencount = nfs_inc_attr_generation_counter();
Miklos Szeredi's avatar
Miklos Szeredi committed
339
	error = NFS_PROTO(inode)->readdir(file_dentry(file), cred, entry->cookie, pages,
Linus Torvalds's avatar
Linus Torvalds committed
340 341 342 343 344
					  NFS_SERVER(inode)->dtsize, desc->plus);
	if (error < 0) {
		/* We requested READDIRPLUS, but the server doesn't grok it */
		if (error == -ENOTSUPP && desc->plus) {
			NFS_SERVER(inode)->caps &= ~NFS_CAP_READDIRPLUS;
345
			clear_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(inode)->flags);
346
			desc->plus = false;
Linus Torvalds's avatar
Linus Torvalds committed
347 348 349 350
			goto again;
		}
		goto error;
	}
351
	desc->timestamp = timestamp;
352
	desc->gencount = gencount;
353 354
error:
	return error;
Linus Torvalds's avatar
Linus Torvalds committed
355 356
}

357 358
static int xdr_decode(nfs_readdir_descriptor_t *desc,
		      struct nfs_entry *entry, struct xdr_stream *xdr)
Linus Torvalds's avatar
Linus Torvalds committed
359
{
360
	int error;
Linus Torvalds's avatar
Linus Torvalds committed
361

362 363 364
	error = desc->decode(xdr, entry, desc->plus);
	if (error)
		return error;
365 366 367
	entry->fattr->time_start = desc->timestamp;
	entry->fattr->gencount = desc->gencount;
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
368 369
}

370 371 372
/* Match file and dirent using either filehandle or fileid
 * Note: caller is responsible for checking the fsid
 */
Bryan Schumaker's avatar
Bryan Schumaker committed
373 374 375
static
int nfs_same_file(struct dentry *dentry, struct nfs_entry *entry)
{
376
	struct inode *inode;
377 378
	struct nfs_inode *nfsi;

379 380
	if (d_really_is_negative(dentry))
		return 0;
381

382 383 384 385 386
	inode = d_inode(dentry);
	if (is_bad_inode(inode) || NFS_STALE(inode))
		return 0;

	nfsi = NFS_I(inode);
387 388 389 390 391
	if (entry->fattr->fileid != nfsi->fileid)
		return 0;
	if (entry->fh->size && nfs_compare_fh(entry->fh, &nfsi->fh) != 0)
		return 0;
	return 1;
Bryan Schumaker's avatar
Bryan Schumaker committed
392 393
}

394
static
Al Viro's avatar
Al Viro committed
395
bool nfs_use_readdirplus(struct inode *dir, struct dir_context *ctx)
396 397 398 399 400
{
	if (!nfs_server_capable(dir, NFS_CAP_READDIRPLUS))
		return false;
	if (test_and_clear_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(dir)->flags))
		return true;
Al Viro's avatar
Al Viro committed
401
	if (ctx->pos == 0)
402 403 404 405 406
		return true;
	return false;
}

/*
407 408
 * This function is called by the lookup and getattr code to request the
 * use of readdirplus to accelerate any future lookups in the same
409 410 411 412
 * directory.
 */
void nfs_advise_use_readdirplus(struct inode *dir)
{
413 414 415 416 417
	struct nfs_inode *nfsi = NFS_I(dir);

	if (nfs_server_capable(dir, NFS_CAP_READDIRPLUS) &&
	    !list_empty(&nfsi->open_files))
		set_bit(NFS_INO_ADVISE_RDPLUS, &nfsi->flags);
418 419
}

420 421 422 423 424 425 426 427 428 429
/*
 * This function is mainly for use by nfs_getattr().
 *
 * If this is an 'ls -l', we want to force use of readdirplus.
 * Do this by checking if there is an active file descriptor
 * and calling nfs_advise_use_readdirplus, then forcing a
 * cache flush.
 */
void nfs_force_use_readdirplus(struct inode *dir)
{
430 431 432 433 434
	struct nfs_inode *nfsi = NFS_I(dir);

	if (nfs_server_capable(dir, NFS_CAP_READDIRPLUS) &&
	    !list_empty(&nfsi->open_files)) {
		set_bit(NFS_INO_ADVISE_RDPLUS, &nfsi->flags);
435
		invalidate_mapping_pages(dir->i_mapping, 0, -1);
436 437 438
	}
}

Bryan Schumaker's avatar
Bryan Schumaker committed
439 440 441
static
void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry)
{
442
	struct qstr filename = QSTR_INIT(entry->name, entry->len);
Al Viro's avatar
Al Viro committed
443
	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
444 445
	struct dentry *dentry;
	struct dentry *alias;
446
	struct inode *dir = d_inode(parent);
Bryan Schumaker's avatar
Bryan Schumaker committed
447
	struct inode *inode;
448
	int status;
Bryan Schumaker's avatar
Bryan Schumaker committed
449

450 451
	if (!(entry->fattr->valid & NFS_ATTR_FATTR_FILEID))
		return;
452 453
	if (!(entry->fattr->valid & NFS_ATTR_FATTR_FSID))
		return;
454 455 456 457 458 459 460 461
	if (filename.len == 0)
		return;
	/* Validate that the name doesn't contain any illegal '\0' */
	if (strnlen(filename.name, filename.len) != filename.len)
		return;
	/* ...or '/' */
	if (strnchr(filename.name, filename.len, '/'))
		return;
462 463 464 465 466 467
	if (filename.name[0] == '.') {
		if (filename.len == 1)
			return;
		if (filename.len == 2 && filename.name[1] == '.')
			return;
	}
468
	filename.hash = full_name_hash(parent, filename.name, filename.len);
Bryan Schumaker's avatar
Bryan Schumaker committed
469

470
	dentry = d_lookup(parent, &filename);
Al Viro's avatar
Al Viro committed
471 472 473 474 475 476 477
again:
	if (!dentry) {
		dentry = d_alloc_parallel(parent, &filename, &wq);
		if (IS_ERR(dentry))
			return;
	}
	if (!d_in_lookup(dentry)) {
478 479 480 481
		/* Is there a mountpoint here? If so, just exit */
		if (!nfs_fsid_equal(&NFS_SB(dentry->d_sb)->fsid,
					&entry->fattr->fsid))
			goto out;
Bryan Schumaker's avatar
Bryan Schumaker committed
482
		if (nfs_same_file(dentry, entry)) {
483 484
			if (!entry->fh->size)
				goto out;
485
			nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
486
			status = nfs_refresh_inode(d_inode(dentry), entry->fattr);
487
			if (!status)
488
				nfs_setsecurity(d_inode(dentry), entry->fattr, entry->label);
Bryan Schumaker's avatar
Bryan Schumaker committed
489 490
			goto out;
		} else {
491
			d_invalidate(dentry);
Bryan Schumaker's avatar
Bryan Schumaker committed
492
			dput(dentry);
Al Viro's avatar
Al Viro committed
493 494
			dentry = NULL;
			goto again;
Bryan Schumaker's avatar
Bryan Schumaker committed
495 496
		}
	}
497 498 499 500
	if (!entry->fh->size) {
		d_lookup_done(dentry);
		goto out;
	}
Bryan Schumaker's avatar
Bryan Schumaker committed
501

502
	inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr, entry->label);
503
	alias = d_splice_alias(inode, dentry);
Al Viro's avatar
Al Viro committed
504 505 506 507 508 509 510 511
	d_lookup_done(dentry);
	if (alias) {
		if (IS_ERR(alias))
			goto out;
		dput(dentry);
		dentry = alias;
	}
	nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
Bryan Schumaker's avatar
Bryan Schumaker committed
512 513 514 515
out:
	dput(dentry);
}

516 517
/* Perform conversion from xdr to cache array */
static
518
int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry,
519
				struct page **xdr_pages, struct page *page, unsigned int buflen)
Linus Torvalds's avatar
Linus Torvalds committed
520
{
521
	struct xdr_stream stream;
522
	struct xdr_buf buf;
523
	struct page *scratch;
524
	struct nfs_cache_array *array;
525 526
	unsigned int count = 0;
	int status;
527

528 529 530
	scratch = alloc_page(GFP_KERNEL);
	if (scratch == NULL)
		return -ENOMEM;
531

532 533 534
	if (buflen == 0)
		goto out_nopages;

535
	xdr_init_decode_pages(&stream, &buf, xdr_pages, buflen);
536
	xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE);
537 538 539

	do {
		status = xdr_decode(desc, entry, &stream);
540 541 542
		if (status != 0) {
			if (status == -EAGAIN)
				status = 0;
543
			break;
544
		}
545

546 547
		count++;

548
		if (desc->plus)
Miklos Szeredi's avatar
Miklos Szeredi committed
549
			nfs_prime_dcache(file_dentry(desc->file), entry);
550 551 552 553

		status = nfs_readdir_add_to_array(entry, page);
		if (status != 0)
			break;
554 555
	} while (!entry->eof);

556
out_nopages:
Trond Myklebust's avatar
Trond Myklebust committed
557
	if (count == 0 || (status == -EBADCOOKIE && entry->eof != 0)) {
558 559 560 561
		array = kmap(page);
		array->eof_index = array->size;
		status = 0;
		kunmap(page);
Linus Torvalds's avatar
Linus Torvalds committed
562
	}
563 564

	put_page(scratch);
565
	return status;
566 567 568
}

static
569
void nfs_readdir_free_pages(struct page **pages, unsigned int npages)
570 571 572 573 574 575 576 577
{
	unsigned int i;
	for (i = 0; i < npages; i++)
		put_page(pages[i]);
}

/*
 * nfs_readdir_large_page will allocate pages that must be freed with a call
578
 * to nfs_readdir_free_pagearray
579 580
 */
static
581
int nfs_readdir_alloc_pages(struct page **pages, unsigned int npages)
582 583 584 585 586 587 588 589 590
{
	unsigned int i;

	for (i = 0; i < npages; i++) {
		struct page *page = alloc_page(GFP_KERNEL);
		if (page == NULL)
			goto out_freepages;
		pages[i] = page;
	}
591
	return 0;
592 593

out_freepages:
594
	nfs_readdir_free_pages(pages, i);
595
	return -ENOMEM;
Linus Torvalds's avatar
Linus Torvalds committed
596 597
}

598 599
static
int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page, struct inode *inode)
600
{
601
	struct page *pages[NFS_MAX_READDIR_PAGES];
602 603 604
	struct nfs_entry entry;
	struct file	*file = desc->file;
	struct nfs_cache_array *array;
605
	int status = -ENOMEM;
606
	unsigned int array_size = ARRAY_SIZE(pages);
607 608

	entry.prev_cookie = 0;
609
	entry.cookie = desc->last_cookie;
610 611 612
	entry.eof = 0;
	entry.fh = nfs_alloc_fhandle();
	entry.fattr = nfs_alloc_fattr();
613
	entry.server = NFS_SERVER(inode);
614 615
	if (entry.fh == NULL || entry.fattr == NULL)
		goto out;
616

617 618 619 620 621 622
	entry.label = nfs4_label_alloc(NFS_SERVER(inode), GFP_NOWAIT);
	if (IS_ERR(entry.label)) {
		status = PTR_ERR(entry.label);
		goto out;
	}

623
	array = kmap(page);
624 625
	memset(array, 0, sizeof(struct nfs_cache_array));
	array->eof_index = -1;
626

627
	status = nfs_readdir_alloc_pages(pages, array_size);
628
	if (status < 0)
629 630
		goto out_release_array;
	do {
631
		unsigned int pglen;
632
		status = nfs_readdir_xdr_filler(pages, desc, &entry, file, inode);
633

634
		if (status < 0)
635
			break;
636
		pglen = status;
637
		status = nfs_readdir_page_filler(desc, &entry, pages, page, pglen);
638 639 640 641 642 643
		if (status < 0) {
			if (status == -ENOSPC)
				status = 0;
			break;
		}
	} while (array->eof_index < 0);
644

645
	nfs_readdir_free_pages(pages, array_size);
646
out_release_array:
647
	kunmap(page);
648
	nfs4_label_free(entry.label);
649 650 651
out:
	nfs_free_fattr(entry.fattr);
	nfs_free_fhandle(entry.fh);
652 653 654 655
	return status;
}

/*
656 657 658 659
 * Now we cache directories properly, by converting xdr information
 * to an array that can be used for lookups later.  This results in
 * fewer cache pages, since we can store more information on each page.
 * We only need to convert from xdr once so future lookups are much simpler
Linus Torvalds's avatar
Linus Torvalds committed
660
 */
661 662
static
int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page* page)
Linus Torvalds's avatar
Linus Torvalds committed
663
{
Al Viro's avatar
Al Viro committed
664
	struct inode	*inode = file_inode(desc->file);
665
	int ret;
Linus Torvalds's avatar
Linus Torvalds committed
666

667 668
	ret = nfs_readdir_xdr_to_array(desc, page, inode);
	if (ret < 0)
669 670
		goto error;
	SetPageUptodate(page);
Linus Torvalds's avatar
Linus Torvalds committed
671

672 673 674
	if (invalidate_inode_pages2_range(inode->i_mapping, page->index + 1, -1) < 0) {
		/* Should never happen */
		nfs_zap_mapping(inode, inode->i_mapping);
Linus Torvalds's avatar
Linus Torvalds committed
675
	}
676 677 678 679
	unlock_page(page);
	return 0;
 error:
	unlock_page(page);
680
	return ret;
681
}
Linus Torvalds's avatar
Linus Torvalds committed
682

683 684 685
static
void cache_page_release(nfs_readdir_descriptor_t *desc)
{
686 687
	if (!desc->page->mapping)
		nfs_readdir_clear_array(desc->page);
688
	put_page(desc->page);
689 690 691 692 693 694
	desc->page = NULL;
}

static
struct page *get_cache_page(nfs_readdir_descriptor_t *desc)
{
695
	return read_cache_page(desc->file->f_mapping,
696
			desc->page_index, (filler_t *)nfs_readdir_filler, desc);
Linus Torvalds's avatar
Linus Torvalds committed
697 698 699
}

/*
700
 * Returns 0 if desc->dir_cookie was found on page desc->page_index
Linus Torvalds's avatar
Linus Torvalds committed
701
 */
702 703 704 705 706 707 708 709 710 711
static
int find_cache_page(nfs_readdir_descriptor_t *desc)
{
	int res;

	desc->page = get_cache_page(desc);
	if (IS_ERR(desc->page))
		return PTR_ERR(desc->page);

	res = nfs_readdir_search_array(desc);
Trond Myklebust's avatar
Trond Myklebust committed
712 713
	if (res != 0)
		cache_page_release(desc);
714 715 716 717
	return res;
}

/* Search for desc->dir_cookie from the beginning of the page cache */
Linus Torvalds's avatar
Linus Torvalds committed
718 719 720
static inline
int readdir_search_pagecache(nfs_readdir_descriptor_t *desc)
{
721
	int res;
722

723
	if (desc->page_index == 0) {
724
		desc->current_index = 0;
725 726
		desc->last_cookie = 0;
	}
Trond Myklebust's avatar
Trond Myklebust committed
727
	do {
728
		res = find_cache_page(desc);
Trond Myklebust's avatar
Trond Myklebust committed
729
	} while (res == -EAGAIN);
Linus Torvalds's avatar
Linus Torvalds committed
730 731 732 733 734 735 736
	return res;
}

/*
 * Once we've found the start of the dirent within a page: fill 'er up...
 */
static 
Al Viro's avatar
Al Viro committed
737
int nfs_do_filldir(nfs_readdir_descriptor_t *desc)
Linus Torvalds's avatar
Linus Torvalds committed
738 739
{
	struct file	*file = desc->file;
740 741 742
	int i = 0;
	int res = 0;
	struct nfs_cache_array *array = NULL;
743 744
	struct nfs_open_dir_context *ctx = file->private_data;

745
	array = kmap(desc->page);
746
	for (i = desc->cache_entry_index; i < array->size; i++) {
747
		struct nfs_cache_array_entry *ent;
Linus Torvalds's avatar
Linus Torvalds committed
748

749
		ent = &array->array[i];
Al Viro's avatar
Al Viro committed
750 751
		if (!dir_emit(desc->ctx, ent->string.name, ent->string.len,
		    nfs_compat_user_ino64(ent->ino), ent->d_type)) {
752
			desc->eof = true;
Linus Torvalds's avatar
Linus Torvalds committed
753
			break;
754
		}
Al Viro's avatar
Al Viro committed
755
		desc->ctx->pos++;
756 757 758 759
		if (i < (array->size-1))
			*desc->dir_cookie = array->array[i+1].cookie;
		else
			*desc->dir_cookie = array->last_cookie;
760 761
		if (ctx->duped != 0)
			ctx->duped = 1;
Linus Torvalds's avatar
Linus Torvalds committed
762
	}
Trond Myklebust's avatar
Trond Myklebust committed
763
	if (array->eof_index >= 0)
764
		desc->eof = true;
765

766
	kunmap(desc->page);
767
	cache_page_release(desc);
Chuck Lever's avatar
Chuck Lever committed
768 769
	dfprintk(DIRCACHE, "NFS: nfs_do_filldir() filling ended @ cookie %Lu; returning = %d\n",
			(unsigned long long)*desc->dir_cookie, res);
Linus Torvalds's avatar
Linus Torvalds committed
770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785
	return res;
}

/*
 * If we cannot find a cookie in our cache, we suspect that this is
 * because it points to a deleted file, so we ask the server to return
 * whatever it thinks is the next entry. We then feed this to filldir.
 * If all goes well, we should then be able to find our way round the
 * cache on the next call to readdir_search_pagecache();
 *
 * NOTE: we cannot add the anonymous page to the pagecache because
 *	 the data it contains might not be page aligned. Besides,
 *	 we should already have a complete representation of the
 *	 directory in the page cache by the time we get here.
 */
static inline
Al Viro's avatar
Al Viro committed
786
int uncached_readdir(nfs_readdir_descriptor_t *desc)
Linus Torvalds's avatar
Linus Torvalds committed
787 788 789
{
	struct page	*page = NULL;
	int		status;
Al Viro's avatar
Al Viro committed
790
	struct inode *inode = file_inode(desc->file);
791
	struct nfs_open_dir_context *ctx = desc->file->private_data;
Linus Torvalds's avatar
Linus Torvalds committed
792

Chuck Lever's avatar
Chuck Lever committed
793 794
	dfprintk(DIRCACHE, "NFS: uncached_readdir() searching for cookie %Lu\n",
			(unsigned long long)*desc->dir_cookie);
Linus Torvalds's avatar
Linus Torvalds committed
795 796 797 798 799 800

	page = alloc_page(GFP_HIGHUSER);
	if (!page) {
		status = -ENOMEM;
		goto out;
	}
801

802
	desc->page_index = 0;
803
	desc->last_cookie = *desc->dir_cookie;
804
	desc->page = page;
805
	ctx->duped = 0;
806

807 808
	status = nfs_readdir_xdr_to_array(desc, page, inode);
	if (status < 0)
Linus Torvalds's avatar
Linus Torvalds committed
809 810
		goto out_release;

Al Viro's avatar
Al Viro committed
811
	status = nfs_do_filldir(desc);
Linus Torvalds's avatar
Linus Torvalds committed
812 813

 out:
Chuck Lever's avatar
Chuck Lever committed
814
	dfprintk(DIRCACHE, "NFS: %s: returns %d\n",
815
			__func__, status);
Linus Torvalds's avatar
Linus Torvalds committed
816 817
	return status;
 out_release:
818
	cache_page_release(desc);
Linus Torvalds's avatar
Linus Torvalds committed
819 820 821
	goto out;
}

822 823 824
/* The file offset position represents the dirent entry number.  A
   last cookie cache takes care of the common case of reading the
   whole directory.
Linus Torvalds's avatar
Linus Torvalds committed
825
 */
Al Viro's avatar
Al Viro committed
826
static int nfs_readdir(struct file *file, struct dir_context *ctx)
Linus Torvalds's avatar
Linus Torvalds committed
827
{
Miklos Szeredi's avatar
Miklos Szeredi committed
828
	struct dentry	*dentry = file_dentry(file);
829
	struct inode	*inode = d_inode(dentry);
Linus Torvalds's avatar
Linus Torvalds committed
830 831
	nfs_readdir_descriptor_t my_desc,
			*desc = &my_desc;
Al Viro's avatar
Al Viro committed
832
	struct nfs_open_dir_context *dir_ctx = file->private_data;
833
	int res = 0;
Linus Torvalds's avatar
Linus Torvalds committed
834

835 836
	dfprintk(FILE, "NFS: readdir(%pD2) starting at cookie %llu\n",
			file, (long long)ctx->pos);
837 838
	nfs_inc_stats(inode, NFSIOS_VFSGETDENTS);

Linus Torvalds's avatar
Linus Torvalds committed
839
	/*
Al Viro's avatar
Al Viro committed
840
	 * ctx->pos points to the dirent entry number.
841
	 * *desc->dir_cookie has the cookie for the next entry. We have
842 843
	 * to either find the entry with the appropriate number or
	 * revalidate the cookie.
Linus Torvalds's avatar
Linus Torvalds committed
844 845 846
	 */
	memset(desc, 0, sizeof(*desc));

Al Viro's avatar
Al Viro committed
847 848
	desc->file = file;
	desc->ctx = ctx;
849
	desc->dir_cookie = &dir_ctx->dir_cookie;
Linus Torvalds's avatar
Linus Torvalds committed
850
	desc->decode = NFS_PROTO(inode)->decode_dirent;
851
	desc->plus = nfs_use_readdirplus(inode, ctx);
Linus Torvalds's avatar
Linus Torvalds committed
852

853
	if (ctx->pos == 0 || nfs_attribute_cache_expired(inode))
854
		res = nfs_revalidate_mapping(inode, file->f_mapping);
855 856 857
	if (res < 0)
		goto out;

Trond Myklebust's avatar
Trond Myklebust committed
858
	do {
Linus Torvalds's avatar
Linus Torvalds committed
859
		res = readdir_search_pagecache(desc);
860

Linus Torvalds's avatar
Linus Torvalds committed
861
		if (res == -EBADCOOKIE) {
862
			res = 0;
Linus Torvalds's avatar
Linus Torvalds committed
863
			/* This means either end of directory */
864
			if (*desc->dir_cookie && !desc->eof) {
Linus Torvalds's avatar
Linus Torvalds committed
865
				/* Or that the server has 'lost' a cookie */
Al Viro's avatar
Al Viro committed
866
				res = uncached_readdir(desc);
867
				if (res == 0)
Linus Torvalds's avatar
Linus Torvalds committed
868 869 870 871 872
					continue;
			}
			break;
		}
		if (res == -ETOOSMALL && desc->plus) {
873
			clear_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(inode)->flags);
Linus Torvalds's avatar
Linus Torvalds committed
874
			nfs_zap_caches(inode);
875
			desc->page_index = 0;
876 877
			desc->plus = false;
			desc->eof = false;
Linus Torvalds's avatar
Linus Torvalds committed
878 879 880 881 882
			continue;
		}
		if (res < 0)
			break;

Al Viro's avatar
Al Viro committed
883
		res = nfs_do_filldir(desc);
884
		if (res < 0)
Linus Torvalds's avatar
Linus Torvalds committed
885
			break;
Trond Myklebust's avatar
Trond Myklebust committed
886
	} while (!desc->eof);
887
out:
Chuck Lever's avatar
Chuck Lever committed
888 889
	if (res > 0)
		res = 0;
890
	dfprintk(FILE, "NFS: readdir(%pD2) returns %d\n", file, res);
Chuck Lever's avatar
Chuck Lever committed
891
	return res;
Linus Torvalds's avatar
Linus Torvalds committed
892 893
}

894
static loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int whence)
895
{
896
	struct inode *inode = file_inode(filp);
897
	struct nfs_open_dir_context *dir_ctx = filp->private_data;
898

899 900
	dfprintk(FILE, "NFS: llseek dir(%pD2, %lld, %d)\n",
			filp, offset, whence);
901

902
	switch (whence) {
903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918
	default:
		return -EINVAL;
	case SEEK_SET:
		if (offset < 0)
			return -EINVAL;
		inode_lock(inode);
		break;
	case SEEK_CUR:
		if (offset == 0)
			return filp->f_pos;
		inode_lock(inode);
		offset += filp->f_pos;
		if (offset < 0) {
			inode_unlock(inode);
			return -EINVAL;
		}
919 920 921
	}
	if (offset != filp->f_pos) {
		filp->f_pos = offset;
922
		dir_ctx->dir_cookie = 0;
923
		dir_ctx->duped = 0;
924
	}
925
	inode_unlock(inode);
926 927 928
	return offset;
}

Linus Torvalds's avatar
Linus Torvalds committed
929 930 931 932
/*
 * All directory operations under NFS are synchronous, so fsync()
 * is a dummy operation.
 */
933 934
static int nfs_fsync_dir(struct file *filp, loff_t start, loff_t end,
			 int datasync)
Linus Torvalds's avatar
Linus Torvalds committed
935
{
936
	struct inode *inode = file_inode(filp);
937

938
	dfprintk(FILE, "NFS: fsync dir(%pD2) datasync %d\n", filp, datasync);
Chuck Lever's avatar
Chuck Lever committed
939

Al Viro's avatar
Al Viro committed
940
	inode_lock(inode);
941
	nfs_inc_stats(inode, NFSIOS_VFSFSYNC);
Al Viro's avatar
Al Viro committed
942
	inode_unlock(inode);
Linus Torvalds's avatar
Linus Torvalds committed
943 944 945
	return 0;
}

946 947 948 949 950 951 952 953 954 955 956 957
/**
 * nfs_force_lookup_revalidate - Mark the directory as having changed
 * @dir - pointer to directory inode
 *
 * This forces the revalidation code in nfs_lookup_revalidate() to do a
 * full lookup on all child dentries of 'dir' whenever a change occurs
 * on the server that might have invalidated our dcache.
 *
 * The caller should be holding dir->i_lock
 */
void nfs_force_lookup_revalidate(struct inode *dir)
{
958
	NFS_I(dir)->cache_change_attribute++;
959
}
960
EXPORT_SYMBOL_GPL(nfs_force_lookup_revalidate);
961

Linus Torvalds's avatar
Linus Torvalds committed
962 963 964 965
/*
 * A check for whether or not the parent directory has changed.
 * In the case it has, we assume that the dentries are untrustworthy
 * and may need to be looked up again.
966
 * If rcu_walk prevents us from performing a full check, return 0.
Linus Torvalds's avatar
Linus Torvalds committed
967
 */
968 969
static int nfs_check_verifier(struct inode *dir, struct dentry *dentry,
			      int rcu_walk)
Linus Torvalds's avatar
Linus Torvalds committed
970 971 972
{
	if (IS_ROOT(dentry))
		return 1;
973 974
	if (NFS_SERVER(dir)->flags & NFS_MOUNT_LOOKUP_CACHE_NONE)
		return 0;
975 976 977
	if (!nfs_verify_change_attribute(dir, dentry->d_time))
		return 0;
	/* Revalidate nfsi->cache_change_attribute before we declare a match */
978 979 980 981 982 983
	if (nfs_mapping_need_revalidate_inode(dir)) {
		if (rcu_walk)
			return 0;
		if (__nfs_revalidate_inode(NFS_SERVER(dir), dir) < 0)
			return 0;
	}
984 985 986
	if (!nfs_verify_change_attribute(dir, dentry->d_time))
		return 0;
	return 1;
Linus Torvalds's avatar
Linus Torvalds committed
987 988
}

989 990 991 992
/*
 * Use intent information to check whether or not we're going to do
 * an O_EXCL create using this path component.
 */
993
static int nfs_is_exclusive_create(struct inode *dir, unsigned int flags)
994 995 996
{
	if (NFS_PROTO(dir)->version == 2)
		return 0;
997
	return flags & LOOKUP_EXCL;
998 999
}

1000 1001 1002 1003 1004 1005 1006 1007
/*
 * Inode and filehandle revalidation for lookups.
 *
 * We force revalidation in the cases where the VFS sets LOOKUP_REVAL,
 * or if the intent information indicates that we're about to open this
 * particular file and the "nocto" mount flag is not set.
 *
 */
1008
static
1009
int nfs_lookup_verify_inode(struct inode *inode, unsigned int flags)
Linus Torvalds's avatar
Linus Torvalds committed