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