dir.c (babddc72a9468884ce1a23db3c3d54b0afa299f0) | dir.c (56e4ebf877b6043c289bda32a5a7385b80c17dee) |
---|---|
1/* 2 * linux/fs/nfs/dir.c 3 * 4 * Copyright (C) 1992 Rick Sladkey 5 * 6 * nfs directory handling functions 7 * 8 * 10 Apr 1996 Added silly rename for unlink --okir --- 19 unchanged lines hidden (view full) --- 28#include <linux/sunrpc/clnt.h> 29#include <linux/nfs_fs.h> 30#include <linux/nfs_mount.h> 31#include <linux/pagemap.h> 32#include <linux/pagevec.h> 33#include <linux/namei.h> 34#include <linux/mount.h> 35#include <linux/sched.h> | 1/* 2 * linux/fs/nfs/dir.c 3 * 4 * Copyright (C) 1992 Rick Sladkey 5 * 6 * nfs directory handling functions 7 * 8 * 10 Apr 1996 Added silly rename for unlink --okir --- 19 unchanged lines hidden (view full) --- 28#include <linux/sunrpc/clnt.h> 29#include <linux/nfs_fs.h> 30#include <linux/nfs_mount.h> 31#include <linux/pagemap.h> 32#include <linux/pagevec.h> 33#include <linux/namei.h> 34#include <linux/mount.h> 35#include <linux/sched.h> |
36#include <linux/vmalloc.h> |
|
36 37#include "delegation.h" 38#include "iostat.h" 39#include "internal.h" 40#include "fscache.h" 41 42/* #define NFS_DEBUG_VERBOSE 1 */ 43 --- 278 unchanged lines hidden (view full) --- 322 323 nfs_readdir_release_array(desc->page); 324out: 325 return status; 326} 327 328/* Fill a page with xdr information before transferring to the cache page */ 329static | 37 38#include "delegation.h" 39#include "iostat.h" 40#include "internal.h" 41#include "fscache.h" 42 43/* #define NFS_DEBUG_VERBOSE 1 */ 44 --- 278 unchanged lines hidden (view full) --- 323 324 nfs_readdir_release_array(desc->page); 325out: 326 return status; 327} 328 329/* Fill a page with xdr information before transferring to the cache page */ 330static |
330int nfs_readdir_xdr_filler(struct page *xdr_page, nfs_readdir_descriptor_t *desc, | 331int nfs_readdir_xdr_filler(struct page **pages, nfs_readdir_descriptor_t *desc, |
331 struct nfs_entry *entry, struct file *file, struct inode *inode) 332{ 333 struct rpc_cred *cred = nfs_file_cred(file); 334 unsigned long timestamp, gencount; 335 int error; 336 337 again: 338 timestamp = jiffies; 339 gencount = nfs_inc_attr_generation_counter(); | 332 struct nfs_entry *entry, struct file *file, struct inode *inode) 333{ 334 struct rpc_cred *cred = nfs_file_cred(file); 335 unsigned long timestamp, gencount; 336 int error; 337 338 again: 339 timestamp = jiffies; 340 gencount = nfs_inc_attr_generation_counter(); |
340 error = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred, entry->cookie, xdr_page, | 341 error = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred, entry->cookie, pages, |
341 NFS_SERVER(inode)->dtsize, desc->plus); 342 if (error < 0) { 343 /* We requested READDIRPLUS, but the server doesn't grok it */ 344 if (error == -ENOTSUPP && desc->plus) { 345 NFS_SERVER(inode)->caps &= ~NFS_CAP_READDIRPLUS; 346 clear_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(inode)->flags); 347 desc->plus = 0; 348 goto again; --- 82 unchanged lines hidden (view full) --- 431 dput(dentry); 432 kfree(filename.name); 433 return; 434} 435 436/* Perform conversion from xdr to cache array */ 437static 438void nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry, | 342 NFS_SERVER(inode)->dtsize, desc->plus); 343 if (error < 0) { 344 /* We requested READDIRPLUS, but the server doesn't grok it */ 345 if (error == -ENOTSUPP && desc->plus) { 346 NFS_SERVER(inode)->caps &= ~NFS_CAP_READDIRPLUS; 347 clear_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(inode)->flags); 348 desc->plus = 0; 349 goto again; --- 82 unchanged lines hidden (view full) --- 432 dput(dentry); 433 kfree(filename.name); 434 return; 435} 436 437/* Perform conversion from xdr to cache array */ 438static 439void nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry, |
439 struct page *xdr_page, struct page *page, unsigned int buflen) | 440 void *xdr_page, struct page *page, unsigned int buflen) |
440{ 441 struct xdr_stream stream; 442 struct xdr_buf buf; | 441{ 442 struct xdr_stream stream; 443 struct xdr_buf buf; |
443 __be32 *ptr = kmap(xdr_page); | 444 __be32 *ptr = xdr_page; |
444 445 buf.head->iov_base = xdr_page; 446 buf.head->iov_len = buflen; 447 buf.tail->iov_len = 0; 448 buf.page_base = 0; 449 buf.page_len = 0; 450 buf.buflen = buf.head->iov_len; 451 buf.len = buf.head->iov_len; 452 453 xdr_init_decode(&stream, &buf, ptr); 454 455 while (xdr_decode(desc, entry, &stream) == 0) { 456 if (nfs_readdir_add_to_array(entry, page) == -1) 457 break; 458 if (desc->plus == 1) 459 nfs_prime_dcache(desc->file->f_path.dentry, entry); 460 } | 445 446 buf.head->iov_base = xdr_page; 447 buf.head->iov_len = buflen; 448 buf.tail->iov_len = 0; 449 buf.page_base = 0; 450 buf.page_len = 0; 451 buf.buflen = buf.head->iov_len; 452 buf.len = buf.head->iov_len; 453 454 xdr_init_decode(&stream, &buf, ptr); 455 456 while (xdr_decode(desc, entry, &stream) == 0) { 457 if (nfs_readdir_add_to_array(entry, page) == -1) 458 break; 459 if (desc->plus == 1) 460 nfs_prime_dcache(desc->file->f_path.dentry, entry); 461 } |
461 kunmap(xdr_page); | |
462} 463 464static | 462} 463 464static |
465void nfs_readdir_free_pagearray(struct page **pages, unsigned int npages) 466{ 467 unsigned int i; 468 for (i = 0; i < npages; i++) 469 put_page(pages[i]); 470} 471 472static 473void nfs_readdir_free_large_page(void *ptr, struct page **pages, 474 unsigned int npages) 475{ 476 vm_unmap_ram(ptr, npages); 477 nfs_readdir_free_pagearray(pages, npages); 478} 479 480/* 481 * nfs_readdir_large_page will allocate pages that must be freed with a call 482 * to nfs_readdir_free_large_page 483 */ 484static 485void *nfs_readdir_large_page(struct page **pages, unsigned int npages) 486{ 487 void *ptr; 488 unsigned int i; 489 490 for (i = 0; i < npages; i++) { 491 struct page *page = alloc_page(GFP_KERNEL); 492 if (page == NULL) 493 goto out_freepages; 494 pages[i] = page; 495 } 496 497 ptr = vm_map_ram(pages, NFS_MAX_READDIR_PAGES, 0, PAGE_KERNEL); 498 if (!IS_ERR_OR_NULL(ptr)) 499 return ptr; 500out_freepages: 501 nfs_readdir_free_pagearray(pages, i); 502 return NULL; 503} 504 505static |
|
465int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page, struct inode *inode) 466{ | 506int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page, struct inode *inode) 507{ |
467 struct page *xdr_page; | 508 struct page *pages[NFS_MAX_READDIR_PAGES]; 509 void *pages_ptr = NULL; |
468 struct nfs_entry entry; 469 struct file *file = desc->file; 470 struct nfs_cache_array *array; 471 int status = 0; | 510 struct nfs_entry entry; 511 struct file *file = desc->file; 512 struct nfs_cache_array *array; 513 int status = 0; |
472 unsigned int array_size = 1; | 514 unsigned int array_size = ARRAY_SIZE(pages); |
473 474 entry.prev_cookie = 0; 475 entry.cookie = *desc->dir_cookie; 476 entry.eof = 0; 477 entry.fh = nfs_alloc_fhandle(); 478 entry.fattr = nfs_alloc_fattr(); 479 if (entry.fh == NULL || entry.fattr == NULL) 480 goto out; 481 482 array = nfs_readdir_get_array(page); 483 memset(array, 0, sizeof(struct nfs_cache_array)); 484 array->eof_index = -1; 485 | 515 516 entry.prev_cookie = 0; 517 entry.cookie = *desc->dir_cookie; 518 entry.eof = 0; 519 entry.fh = nfs_alloc_fhandle(); 520 entry.fattr = nfs_alloc_fattr(); 521 if (entry.fh == NULL || entry.fattr == NULL) 522 goto out; 523 524 array = nfs_readdir_get_array(page); 525 memset(array, 0, sizeof(struct nfs_cache_array)); 526 array->eof_index = -1; 527 |
486 xdr_page = alloc_page(GFP_KERNEL); 487 if (!xdr_page) | 528 pages_ptr = nfs_readdir_large_page(pages, array_size); 529 if (!pages_ptr) |
488 goto out_release_array; 489 do { | 530 goto out_release_array; 531 do { |
490 status = nfs_readdir_xdr_filler(xdr_page, desc, &entry, file, inode); | 532 status = nfs_readdir_xdr_filler(pages, desc, &entry, file, inode); |
491 492 if (status < 0) 493 break; | 533 534 if (status < 0) 535 break; |
494 nfs_readdir_page_filler(desc, &entry, xdr_page, page, array_size * PAGE_SIZE); | 536 nfs_readdir_page_filler(desc, &entry, pages_ptr, page, array_size * PAGE_SIZE); |
495 } while (array->eof_index < 0 && array->size < MAX_READDIR_ARRAY); 496 | 537 } while (array->eof_index < 0 && array->size < MAX_READDIR_ARRAY); 538 |
497 put_page(xdr_page); | 539 nfs_readdir_free_large_page(pages_ptr, pages, array_size); |
498out_release_array: 499 nfs_readdir_release_array(page); 500out: 501 nfs_free_fattr(entry.fattr); 502 nfs_free_fhandle(entry.fh); 503 return status; 504} 505 --- 1652 unchanged lines hidden --- | 540out_release_array: 541 nfs_readdir_release_array(page); 542out: 543 nfs_free_fattr(entry.fattr); 544 nfs_free_fhandle(entry.fh); 545 return status; 546} 547 --- 1652 unchanged lines hidden --- |