file.c 15.2 KB
Newer Older
1
/* AFS filesystem file handling
L
Linus Torvalds 已提交
2
 *
3
 * Copyright (C) 2002, 2007 Red Hat, Inc. All Rights Reserved.
L
Linus Torvalds 已提交
4 5 6 7 8 9 10 11 12 13 14 15 16
 * Written by David Howells (dhowells@redhat.com)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
17
#include <linux/writeback.h>
18
#include <linux/gfp.h>
19
#include <linux/task_io_accounting_ops.h>
20
#include <linux/mm.h>
L
Linus Torvalds 已提交
21 22
#include "internal.h"

23
static int afs_file_mmap(struct file *file, struct vm_area_struct *vma);
D
David Howells 已提交
24
static int afs_readpage(struct file *file, struct page *page);
25 26
static void afs_invalidatepage(struct page *page, unsigned int offset,
			       unsigned int length);
D
David Howells 已提交
27
static int afs_releasepage(struct page *page, gfp_t gfp_flags);
L
Linus Torvalds 已提交
28

D
David Howells 已提交
29 30 31
static int afs_readpages(struct file *filp, struct address_space *mapping,
			 struct list_head *pages, unsigned nr_pages);

D
David Howells 已提交
32 33 34 35
const struct file_operations afs_file_operations = {
	.open		= afs_open,
	.release	= afs_release,
	.llseek		= generic_file_llseek,
36
	.read_iter	= generic_file_read_iter,
A
Al Viro 已提交
37
	.write_iter	= afs_file_write,
38
	.mmap		= afs_file_mmap,
39
	.splice_read	= generic_file_splice_read,
40
	.fsync		= afs_fsync,
D
David Howells 已提交
41 42
	.lock		= afs_lock,
	.flock		= afs_flock,
D
David Howells 已提交
43 44
};

45
const struct inode_operations afs_file_inode_operations = {
D
David Howells 已提交
46
	.getattr	= afs_getattr,
47
	.setattr	= afs_setattr,
D
David Howells 已提交
48
	.permission	= afs_permission,
D
David Howells 已提交
49
	.listxattr	= afs_listxattr,
L
Linus Torvalds 已提交
50 51
};

52
const struct address_space_operations afs_fs_aops = {
D
David Howells 已提交
53
	.readpage	= afs_readpage,
D
David Howells 已提交
54
	.readpages	= afs_readpages,
55 56
	.set_page_dirty	= afs_set_page_dirty,
	.launder_page	= afs_launder_page,
D
David Howells 已提交
57 58
	.releasepage	= afs_releasepage,
	.invalidatepage	= afs_invalidatepage,
N
Nick Piggin 已提交
59 60
	.write_begin	= afs_write_begin,
	.write_end	= afs_write_end,
61 62
	.writepage	= afs_writepage,
	.writepages	= afs_writepages,
L
Linus Torvalds 已提交
63 64
};

65 66 67 68 69 70
static const struct vm_operations_struct afs_vm_ops = {
	.fault		= filemap_fault,
	.map_pages	= filemap_map_pages,
	.page_mkwrite	= afs_page_mkwrite,
};

71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
/*
 * Discard a pin on a writeback key.
 */
void afs_put_wb_key(struct afs_wb_key *wbk)
{
	if (refcount_dec_and_test(&wbk->usage)) {
		key_put(wbk->key);
		kfree(wbk);
	}
}

/*
 * Cache key for writeback.
 */
int afs_cache_wb_key(struct afs_vnode *vnode, struct afs_file *af)
{
	struct afs_wb_key *wbk, *p;

	wbk = kzalloc(sizeof(struct afs_wb_key), GFP_KERNEL);
	if (!wbk)
		return -ENOMEM;
	refcount_set(&wbk->usage, 2);
	wbk->key = af->key;

	spin_lock(&vnode->wb_lock);
	list_for_each_entry(p, &vnode->wb_keys, vnode_link) {
		if (p->key == wbk->key)
			goto found;
	}

	key_get(wbk->key);
	list_add_tail(&wbk->vnode_link, &vnode->wb_keys);
	spin_unlock(&vnode->wb_lock);
	af->wb = wbk;
	return 0;

found:
	refcount_inc(&p->usage);
	spin_unlock(&vnode->wb_lock);
	af->wb = p;
	kfree(wbk);
	return 0;
}

D
David Howells 已提交
115 116 117 118 119 120
/*
 * open an AFS file or directory and attach a key to it
 */
int afs_open(struct inode *inode, struct file *file)
{
	struct afs_vnode *vnode = AFS_FS_I(inode);
121
	struct afs_file *af;
D
David Howells 已提交
122
	struct key *key;
123
	int ret;
D
David Howells 已提交
124

125
	_enter("{%llx:%llu},", vnode->fid.vid, vnode->fid.vnode);
D
David Howells 已提交
126 127 128

	key = afs_request_key(vnode->volume->cell);
	if (IS_ERR(key)) {
129 130
		ret = PTR_ERR(key);
		goto error;
D
David Howells 已提交
131 132
	}

133 134 135 136
	af = kzalloc(sizeof(*af), GFP_KERNEL);
	if (!af) {
		ret = -ENOMEM;
		goto error_key;
137
	}
138
	af->key = key;
139

140 141 142 143
	ret = afs_validate(vnode, key);
	if (ret < 0)
		goto error_af;

144 145 146 147 148
	if (file->f_mode & FMODE_WRITE) {
		ret = afs_cache_wb_key(vnode, af);
		if (ret < 0)
			goto error_af;
	}
149 150 151

	if (file->f_flags & O_TRUNC)
		set_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags);
152
	
153
	file->private_data = af;
D
David Howells 已提交
154 155
	_leave(" = 0");
	return 0;
156 157 158 159 160 161 162 163

error_af:
	kfree(af);
error_key:
	key_put(key);
error:
	_leave(" = %d", ret);
	return ret;
D
David Howells 已提交
164 165 166 167 168 169 170 171
}

/*
 * release an AFS file or directory and discard its key
 */
int afs_release(struct inode *inode, struct file *file)
{
	struct afs_vnode *vnode = AFS_FS_I(inode);
172
	struct afs_file *af = file->private_data;
173
	int ret = 0;
D
David Howells 已提交
174

175
	_enter("{%llx:%llu},", vnode->fid.vid, vnode->fid.vnode);
D
David Howells 已提交
176

177
	if ((file->f_mode & FMODE_WRITE))
178
		ret = vfs_fsync(file, 0);
179

180
	file->private_data = NULL;
181 182
	if (af->wb)
		afs_put_wb_key(af->wb);
183 184
	key_put(af->key);
	kfree(af);
185
	afs_prune_wb_keys(vnode);
186 187
	_leave(" = %d", ret);
	return ret;
D
David Howells 已提交
188 189
}

190 191 192 193 194 195 196
/*
 * Dispose of a ref to a read record.
 */
void afs_put_read(struct afs_read *req)
{
	int i;

D
David Howells 已提交
197
	if (refcount_dec_and_test(&req->usage)) {
198 199 200
		for (i = 0; i < req->nr_pages; i++)
			if (req->pages[i])
				put_page(req->pages[i]);
D
David Howells 已提交
201 202
		if (req->pages != req->array)
			kfree(req->pages);
203 204 205 206
		kfree(req);
	}
}

207
#ifdef CONFIG_AFS_FSCACHE
L
Linus Torvalds 已提交
208 209 210
/*
 * deal with notification that a page was read from the cache
 */
D
David Howells 已提交
211 212 213
static void afs_file_readpage_read_complete(struct page *page,
					    void *data,
					    int error)
L
Linus Torvalds 已提交
214
{
D
David Howells 已提交
215
	_enter("%p,%p,%d", page, data, error);
L
Linus Torvalds 已提交
216

D
David Howells 已提交
217 218 219
	/* if the read completes with an error, we just unlock the page and let
	 * the VM reissue the readpage */
	if (!error)
L
Linus Torvalds 已提交
220 221
		SetPageUptodate(page);
	unlock_page(page);
D
David Howells 已提交
222
}
223
#endif
L
Linus Torvalds 已提交
224

225 226 227 228 229 230
/*
 * Fetch file data from the volume.
 */
int afs_fetch_data(struct afs_vnode *vnode, struct key *key, struct afs_read *desc)
{
	struct afs_fs_cursor fc;
231
	struct afs_status_cb *scb;
232 233
	int ret;

234
	_enter("%s{%llx:%llu.%u},%x,,,",
235 236 237 238 239 240
	       vnode->volume->name,
	       vnode->fid.vid,
	       vnode->fid.vnode,
	       vnode->fid.unique,
	       key_serial(key));

241 242 243 244
	scb = kzalloc(sizeof(struct afs_status_cb), GFP_KERNEL);
	if (!scb)
		return -ENOMEM;

245
	ret = -ERESTARTSYS;
246
	if (afs_begin_vnode_operation(&fc, vnode, key, true)) {
247 248
		afs_dataversion_t data_version = vnode->status.data_version;

249
		while (afs_select_fileserver(&fc)) {
250
			fc.cb_break = afs_calc_vnode_cb_break(vnode);
251
			afs_fs_fetch_data(&fc, scb, desc);
252 253
		}

254 255 256
		afs_check_for_remote_deletion(&fc, vnode);
		afs_vnode_commit_status(&fc, vnode, fc.cb_break,
					&data_version, scb);
257 258 259
		ret = afs_end_vnode_operation(&fc);
	}

260 261 262 263 264 265
	if (ret == 0) {
		afs_stat_v(vnode, n_fetches);
		atomic_long_add(desc->actual_len,
				&afs_v2net(vnode)->n_fetch_bytes);
	}

266
	kfree(scb);
267 268 269 270
	_leave(" = %d", ret);
	return ret;
}

L
Linus Torvalds 已提交
271
/*
272
 * read page from file, directory or symlink, given a key to use
L
Linus Torvalds 已提交
273
 */
274
int afs_page_filler(void *data, struct page *page)
L
Linus Torvalds 已提交
275
{
276 277
	struct inode *inode = page->mapping->host;
	struct afs_vnode *vnode = AFS_FS_I(inode);
278
	struct afs_read *req;
279
	struct key *key = data;
L
Linus Torvalds 已提交
280 281
	int ret;

D
David Howells 已提交
282
	_enter("{%x},{%lu},{%lu}", key_serial(key), inode->i_ino, page->index);
L
Linus Torvalds 已提交
283

M
Matt Mackall 已提交
284
	BUG_ON(!PageLocked(page));
L
Linus Torvalds 已提交
285 286

	ret = -ESTALE;
287
	if (test_bit(AFS_VNODE_DELETED, &vnode->flags))
L
Linus Torvalds 已提交
288 289 290
		goto error;

	/* is it cached? */
D
David Howells 已提交
291 292
#ifdef CONFIG_AFS_FSCACHE
	ret = fscache_read_or_alloc_page(vnode->cache,
L
Linus Torvalds 已提交
293 294 295 296 297 298 299 300 301 302 303 304
					 page,
					 afs_file_readpage_read_complete,
					 NULL,
					 GFP_KERNEL);
#else
	ret = -ENOBUFS;
#endif
	switch (ret) {
		/* read BIO submitted (page in cache) */
	case 0:
		break;

D
David Howells 已提交
305
		/* page not yet cached */
L
Linus Torvalds 已提交
306
	case -ENODATA:
D
David Howells 已提交
307 308 309 310 311 312
		_debug("cache said ENODATA");
		goto go_on;

		/* page will not be cached */
	case -ENOBUFS:
		_debug("cache said ENOBUFS");
313 314

		/* fall through */
L
Linus Torvalds 已提交
315
	default:
D
David Howells 已提交
316
	go_on:
317 318 319 320 321
		req = kzalloc(sizeof(struct afs_read) + sizeof(struct page *),
			      GFP_KERNEL);
		if (!req)
			goto enomem;

322 323 324 325
		/* We request a full page.  If the page is a partial one at the
		 * end of the file, the server will return a short read and the
		 * unmarshalling code will clear the unfilled space.
		 */
D
David Howells 已提交
326
		refcount_set(&req->usage, 1);
327
		req->pos = (loff_t)page->index << PAGE_SHIFT;
328
		req->len = PAGE_SIZE;
329
		req->nr_pages = 1;
D
David Howells 已提交
330
		req->pages = req->array;
331 332
		req->pages[0] = page;
		get_page(page);
L
Linus Torvalds 已提交
333 334 335

		/* read the contents of the file from the server into the
		 * page */
336
		ret = afs_fetch_data(vnode, key, req);
337
		afs_put_read(req);
338

L
Linus Torvalds 已提交
339
		if (ret < 0) {
340
			if (ret == -ENOENT) {
L
Linus Torvalds 已提交
341 342
				_debug("got NOENT from server"
				       " - marking file deleted and stale");
343
				set_bit(AFS_VNODE_DELETED, &vnode->flags);
L
Linus Torvalds 已提交
344 345
				ret = -ESTALE;
			}
D
David Howells 已提交
346 347 348

#ifdef CONFIG_AFS_FSCACHE
			fscache_uncache_page(vnode->cache, page);
L
Linus Torvalds 已提交
349
#endif
D
David Howells 已提交
350
			BUG_ON(PageFsCache(page));
351 352 353 354 355 356 357

			if (ret == -EINTR ||
			    ret == -ENOMEM ||
			    ret == -ERESTARTSYS ||
			    ret == -EAGAIN)
				goto error;
			goto io_error;
L
Linus Torvalds 已提交
358 359 360 361
		}

		SetPageUptodate(page);

D
David Howells 已提交
362 363 364
		/* send the page to the cache */
#ifdef CONFIG_AFS_FSCACHE
		if (PageFsCache(page) &&
365 366
		    fscache_write_page(vnode->cache, page, vnode->status.size,
				       GFP_KERNEL) != 0) {
D
David Howells 已提交
367 368
			fscache_uncache_page(vnode->cache, page);
			BUG_ON(PageFsCache(page));
L
Linus Torvalds 已提交
369 370
		}
#endif
D
David Howells 已提交
371
		unlock_page(page);
L
Linus Torvalds 已提交
372 373 374 375 376
	}

	_leave(" = 0");
	return 0;

377 378 379
io_error:
	SetPageError(page);
	goto error;
380 381
enomem:
	ret = -ENOMEM;
382
error:
L
Linus Torvalds 已提交
383 384 385
	unlock_page(page);
	_leave(" = %d", ret);
	return ret;
D
David Howells 已提交
386
}
L
Linus Torvalds 已提交
387

388 389 390 391 392 393 394 395 396 397
/*
 * read page from file, directory or symlink, given a file to nominate the key
 * to be used
 */
static int afs_readpage(struct file *file, struct page *page)
{
	struct key *key;
	int ret;

	if (file) {
398
		key = afs_file_key(file);
399 400 401 402
		ASSERT(key != NULL);
		ret = afs_page_filler(key, page);
	} else {
		struct inode *inode = page->mapping->host;
403
		key = afs_request_key(AFS_FS_S(inode->i_sb)->cell);
404 405 406 407 408 409 410 411 412 413
		if (IS_ERR(key)) {
			ret = PTR_ERR(key);
		} else {
			ret = afs_page_filler(key, page);
			key_put(key);
		}
	}
	return ret;
}

414 415 416
/*
 * Make pages available as they're filled.
 */
417
static void afs_readpages_page_done(struct afs_read *req)
418
{
419
#ifdef CONFIG_AFS_FSCACHE
420
	struct afs_vnode *vnode = req->vnode;
421
#endif
422 423 424 425 426 427 428 429
	struct page *page = req->pages[req->index];

	req->pages[req->index] = NULL;
	SetPageUptodate(page);

	/* send the page to the cache */
#ifdef CONFIG_AFS_FSCACHE
	if (PageFsCache(page) &&
430 431
	    fscache_write_page(vnode->cache, page, vnode->status.size,
			       GFP_KERNEL) != 0) {
432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449
		fscache_uncache_page(vnode->cache, page);
		BUG_ON(PageFsCache(page));
	}
#endif
	unlock_page(page);
	put_page(page);
}

/*
 * Read a contiguous set of pages.
 */
static int afs_readpages_one(struct file *file, struct address_space *mapping,
			     struct list_head *pages)
{
	struct afs_vnode *vnode = AFS_FS_I(mapping->host);
	struct afs_read *req;
	struct list_head *p;
	struct page *first, *page;
450
	struct key *key = afs_file_key(file);
451 452 453 454 455 456
	pgoff_t index;
	int ret, n, i;

	/* Count the number of contiguous pages at the front of the list.  Note
	 * that the list goes prev-wards rather than next-wards.
	 */
457
	first = lru_to_page(pages);
458 459 460 461 462 463 464 465 466 467 468 469 470 471 472
	index = first->index + 1;
	n = 1;
	for (p = first->lru.prev; p != pages; p = p->prev) {
		page = list_entry(p, struct page, lru);
		if (page->index != index)
			break;
		index++;
		n++;
	}

	req = kzalloc(sizeof(struct afs_read) + sizeof(struct page *) * n,
		      GFP_NOFS);
	if (!req)
		return -ENOMEM;

D
David Howells 已提交
473
	refcount_set(&req->usage, 1);
474
	req->vnode = vnode;
475 476 477
	req->page_done = afs_readpages_page_done;
	req->pos = first->index;
	req->pos <<= PAGE_SHIFT;
D
David Howells 已提交
478
	req->pages = req->array;
479 480 481 482 483 484 485 486 487 488 489

	/* Transfer the pages to the request.  We add them in until one fails
	 * to add to the LRU and then we stop (as that'll make a hole in the
	 * contiguous run.
	 *
	 * Note that it's possible for the file size to change whilst we're
	 * doing this, but we rely on the server returning less than we asked
	 * for if the file shrank.  We also rely on this to deal with a partial
	 * page at the end of the file.
	 */
	do {
490
		page = lru_to_page(pages);
491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510
		list_del(&page->lru);
		index = page->index;
		if (add_to_page_cache_lru(page, mapping, index,
					  readahead_gfp_mask(mapping))) {
#ifdef CONFIG_AFS_FSCACHE
			fscache_uncache_page(vnode->cache, page);
#endif
			put_page(page);
			break;
		}

		req->pages[req->nr_pages++] = page;
		req->len += PAGE_SIZE;
	} while (req->nr_pages < n);

	if (req->nr_pages == 0) {
		kfree(req);
		return 0;
	}

511
	ret = afs_fetch_data(vnode, key, req);
512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541
	if (ret < 0)
		goto error;

	task_io_account_read(PAGE_SIZE * req->nr_pages);
	afs_put_read(req);
	return 0;

error:
	if (ret == -ENOENT) {
		_debug("got NOENT from server"
		       " - marking file deleted and stale");
		set_bit(AFS_VNODE_DELETED, &vnode->flags);
		ret = -ESTALE;
	}

	for (i = 0; i < req->nr_pages; i++) {
		page = req->pages[i];
		if (page) {
#ifdef CONFIG_AFS_FSCACHE
			fscache_uncache_page(vnode->cache, page);
#endif
			SetPageError(page);
			unlock_page(page);
		}
	}

	afs_put_read(req);
	return ret;
}

L
Linus Torvalds 已提交
542
/*
D
David Howells 已提交
543
 * read a set of pages
L
Linus Torvalds 已提交
544
 */
D
David Howells 已提交
545 546
static int afs_readpages(struct file *file, struct address_space *mapping,
			 struct list_head *pages, unsigned nr_pages)
L
Linus Torvalds 已提交
547
{
548
	struct key *key = afs_file_key(file);
D
David Howells 已提交
549 550
	struct afs_vnode *vnode;
	int ret = 0;
L
Linus Torvalds 已提交
551

552 553 554 555
	_enter("{%d},{%lu},,%d",
	       key_serial(key), mapping->host->i_ino, nr_pages);

	ASSERT(key != NULL);
L
Linus Torvalds 已提交
556

D
David Howells 已提交
557
	vnode = AFS_FS_I(mapping->host);
558
	if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) {
D
David Howells 已提交
559 560 561
		_leave(" = -ESTALE");
		return -ESTALE;
	}
L
Linus Torvalds 已提交
562

D
David Howells 已提交
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592
	/* attempt to read as many of the pages as possible */
#ifdef CONFIG_AFS_FSCACHE
	ret = fscache_read_or_alloc_pages(vnode->cache,
					  mapping,
					  pages,
					  &nr_pages,
					  afs_file_readpage_read_complete,
					  NULL,
					  mapping_gfp_mask(mapping));
#else
	ret = -ENOBUFS;
#endif

	switch (ret) {
		/* all pages are being read from the cache */
	case 0:
		BUG_ON(!list_empty(pages));
		BUG_ON(nr_pages != 0);
		_leave(" = 0 [reading all]");
		return 0;

		/* there were pages that couldn't be read from the cache */
	case -ENODATA:
	case -ENOBUFS:
		break;

		/* other error */
	default:
		_leave(" = %d", ret);
		return ret;
L
Linus Torvalds 已提交
593 594
	}

595 596 597 598 599
	while (!list_empty(pages)) {
		ret = afs_readpages_one(file, mapping, pages);
		if (ret < 0)
			break;
	}
D
David Howells 已提交
600 601 602

	_leave(" = %d [netting]", ret);
	return ret;
D
David Howells 已提交
603
}
L
Linus Torvalds 已提交
604 605

/*
D
David Howells 已提交
606 607 608 609
 * invalidate part or all of a page
 * - release a page and clean up its private data if offset is 0 (indicating
 *   the entire page)
 */
610 611
static void afs_invalidatepage(struct page *page, unsigned int offset,
			       unsigned int length)
D
David Howells 已提交
612
{
D
David Howells 已提交
613 614 615
	struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
	unsigned long priv;

616
	_enter("{%lu},%u,%u", page->index, offset, length);
D
David Howells 已提交
617 618 619 620

	BUG_ON(!PageLocked(page));

	/* we clean up only if the entire page is being invalidated */
621
	if (offset == 0 && length == PAGE_SIZE) {
D
David Howells 已提交
622 623 624 625 626 627 628 629 630
#ifdef CONFIG_AFS_FSCACHE
		if (PageFsCache(page)) {
			struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
			fscache_wait_on_page_write(vnode->cache, page);
			fscache_uncache_page(vnode->cache, page);
		}
#endif

		if (PagePrivate(page)) {
D
David Howells 已提交
631 632 633
			priv = page_private(page);
			trace_afs_page_dirty(vnode, tracepoint_string("inval"),
					     page->index, priv);
634 635
			set_page_private(page, 0);
			ClearPagePrivate(page);
D
David Howells 已提交
636 637 638 639 640 641 642 643 644
		}
	}

	_leave("");
}

/*
 * release a page and clean up its private state if it's not busy
 * - return true if the page can now be released, false if not
L
Linus Torvalds 已提交
645
 */
D
David Howells 已提交
646
static int afs_releasepage(struct page *page, gfp_t gfp_flags)
L
Linus Torvalds 已提交
647
{
D
David Howells 已提交
648
	struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
D
David Howells 已提交
649
	unsigned long priv;
L
Linus Torvalds 已提交
650

651
	_enter("{{%llx:%llu}[%lu],%lx},%x",
D
David Howells 已提交
652 653
	       vnode->fid.vid, vnode->fid.vnode, page->index, page->flags,
	       gfp_flags);
L
Linus Torvalds 已提交
654

D
David Howells 已提交
655 656 657
	/* deny if page is being written to the cache and the caller hasn't
	 * elected to wait */
#ifdef CONFIG_AFS_FSCACHE
658 659 660
	if (!fscache_maybe_release_page(vnode->cache, page, gfp_flags)) {
		_leave(" = F [cache busy]");
		return 0;
D
David Howells 已提交
661 662 663
	}
#endif

L
Linus Torvalds 已提交
664
	if (PagePrivate(page)) {
D
David Howells 已提交
665 666 667
		priv = page_private(page);
		trace_afs_page_dirty(vnode, tracepoint_string("rel"),
				     page->index, priv);
668
		set_page_private(page, 0);
L
Linus Torvalds 已提交
669 670 671
		ClearPagePrivate(page);
	}

D
David Howells 已提交
672 673 674
	/* indicate that the page can be released */
	_leave(" = T");
	return 1;
D
David Howells 已提交
675
}
676 677 678 679 680 681 682 683 684 685 686 687 688

/*
 * Handle setting up a memory mapping on an AFS file.
 */
static int afs_file_mmap(struct file *file, struct vm_area_struct *vma)
{
	int ret;

	ret = generic_file_mmap(file, vma);
	if (ret == 0)
		vma->vm_ops = &afs_vm_ops;
	return ret;
}