aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r--fs/nfs/dir.c92
1 files changed, 49 insertions, 43 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index d33da530097a..2c3eb33b904d 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -33,8 +33,8 @@
33#include <linux/namei.h> 33#include <linux/namei.h>
34#include <linux/mount.h> 34#include <linux/mount.h>
35#include <linux/sched.h> 35#include <linux/sched.h>
36#include <linux/vmalloc.h>
37#include <linux/kmemleak.h> 36#include <linux/kmemleak.h>
37#include <linux/xattr.h>
38 38
39#include "delegation.h" 39#include "delegation.h"
40#include "iostat.h" 40#include "iostat.h"
@@ -125,9 +125,10 @@ const struct inode_operations nfs4_dir_inode_operations = {
125 .permission = nfs_permission, 125 .permission = nfs_permission,
126 .getattr = nfs_getattr, 126 .getattr = nfs_getattr,
127 .setattr = nfs_setattr, 127 .setattr = nfs_setattr,
128 .getxattr = nfs4_getxattr, 128 .getxattr = generic_getxattr,
129 .setxattr = nfs4_setxattr, 129 .setxattr = generic_setxattr,
130 .listxattr = nfs4_listxattr, 130 .listxattr = generic_listxattr,
131 .removexattr = generic_removexattr,
131}; 132};
132 133
133#endif /* CONFIG_NFS_V4 */ 134#endif /* CONFIG_NFS_V4 */
@@ -172,7 +173,7 @@ struct nfs_cache_array {
172 struct nfs_cache_array_entry array[0]; 173 struct nfs_cache_array_entry array[0];
173}; 174};
174 175
175typedef __be32 * (*decode_dirent_t)(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int); 176typedef int (*decode_dirent_t)(struct xdr_stream *, struct nfs_entry *, int);
176typedef struct { 177typedef struct {
177 struct file *file; 178 struct file *file;
178 struct page *page; 179 struct page *page;
@@ -378,14 +379,14 @@ error:
378 return error; 379 return error;
379} 380}
380 381
381/* Fill in an entry based on the xdr code stored in desc->page */ 382static int xdr_decode(nfs_readdir_descriptor_t *desc,
382static 383 struct nfs_entry *entry, struct xdr_stream *xdr)
383int xdr_decode(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry, struct xdr_stream *stream)
384{ 384{
385 __be32 *p = desc->decode(stream, entry, NFS_SERVER(desc->file->f_path.dentry->d_inode), desc->plus); 385 int error;
386 if (IS_ERR(p))
387 return PTR_ERR(p);
388 386
387 error = desc->decode(xdr, entry, desc->plus);
388 if (error)
389 return error;
389 entry->fattr->time_start = desc->timestamp; 390 entry->fattr->time_start = desc->timestamp;
390 entry->fattr->gencount = desc->gencount; 391 entry->fattr->gencount = desc->gencount;
391 return 0; 392 return 0;
@@ -438,7 +439,6 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry)
438 if (dentry == NULL) 439 if (dentry == NULL)
439 return; 440 return;
440 441
441 d_set_d_op(dentry, NFS_PROTO(dir)->dentry_ops);
442 inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr); 442 inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr);
443 if (IS_ERR(inode)) 443 if (IS_ERR(inode))
444 goto out; 444 goto out;
@@ -459,25 +459,26 @@ out:
459/* Perform conversion from xdr to cache array */ 459/* Perform conversion from xdr to cache array */
460static 460static
461int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry, 461int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry,
462 void *xdr_page, struct page *page, unsigned int buflen) 462 struct page **xdr_pages, struct page *page, unsigned int buflen)
463{ 463{
464 struct xdr_stream stream; 464 struct xdr_stream stream;
465 struct xdr_buf buf; 465 struct xdr_buf buf = {
466 __be32 *ptr = xdr_page; 466 .pages = xdr_pages,
467 .page_len = buflen,
468 .buflen = buflen,
469 .len = buflen,
470 };
471 struct page *scratch;
467 struct nfs_cache_array *array; 472 struct nfs_cache_array *array;
468 unsigned int count = 0; 473 unsigned int count = 0;
469 int status; 474 int status;
470 475
471 buf.head->iov_base = xdr_page; 476 scratch = alloc_page(GFP_KERNEL);
472 buf.head->iov_len = buflen; 477 if (scratch == NULL)
473 buf.tail->iov_len = 0; 478 return -ENOMEM;
474 buf.page_base = 0;
475 buf.page_len = 0;
476 buf.buflen = buf.head->iov_len;
477 buf.len = buf.head->iov_len;
478
479 xdr_init_decode(&stream, &buf, ptr);
480 479
480 xdr_init_decode(&stream, &buf, NULL);
481 xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE);
481 482
482 do { 483 do {
483 status = xdr_decode(desc, entry, &stream); 484 status = xdr_decode(desc, entry, &stream);
@@ -506,6 +507,8 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en
506 } else 507 } else
507 status = PTR_ERR(array); 508 status = PTR_ERR(array);
508 } 509 }
510
511 put_page(scratch);
509 return status; 512 return status;
510} 513}
511 514
@@ -521,7 +524,6 @@ static
521void nfs_readdir_free_large_page(void *ptr, struct page **pages, 524void nfs_readdir_free_large_page(void *ptr, struct page **pages,
522 unsigned int npages) 525 unsigned int npages)
523{ 526{
524 vm_unmap_ram(ptr, npages);
525 nfs_readdir_free_pagearray(pages, npages); 527 nfs_readdir_free_pagearray(pages, npages);
526} 528}
527 529
@@ -530,9 +532,8 @@ void nfs_readdir_free_large_page(void *ptr, struct page **pages,
530 * to nfs_readdir_free_large_page 532 * to nfs_readdir_free_large_page
531 */ 533 */
532static 534static
533void *nfs_readdir_large_page(struct page **pages, unsigned int npages) 535int nfs_readdir_large_page(struct page **pages, unsigned int npages)
534{ 536{
535 void *ptr;
536 unsigned int i; 537 unsigned int i;
537 538
538 for (i = 0; i < npages; i++) { 539 for (i = 0; i < npages; i++) {
@@ -541,13 +542,11 @@ void *nfs_readdir_large_page(struct page **pages, unsigned int npages)
541 goto out_freepages; 542 goto out_freepages;
542 pages[i] = page; 543 pages[i] = page;
543 } 544 }
545 return 0;
544 546
545 ptr = vm_map_ram(pages, npages, 0, PAGE_KERNEL);
546 if (!IS_ERR_OR_NULL(ptr))
547 return ptr;
548out_freepages: 547out_freepages:
549 nfs_readdir_free_pagearray(pages, i); 548 nfs_readdir_free_pagearray(pages, i);
550 return NULL; 549 return -ENOMEM;
551} 550}
552 551
553static 552static
@@ -566,6 +565,7 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,
566 entry.eof = 0; 565 entry.eof = 0;
567 entry.fh = nfs_alloc_fhandle(); 566 entry.fh = nfs_alloc_fhandle();
568 entry.fattr = nfs_alloc_fattr(); 567 entry.fattr = nfs_alloc_fattr();
568 entry.server = NFS_SERVER(inode);
569 if (entry.fh == NULL || entry.fattr == NULL) 569 if (entry.fh == NULL || entry.fattr == NULL)
570 goto out; 570 goto out;
571 571
@@ -577,8 +577,8 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,
577 memset(array, 0, sizeof(struct nfs_cache_array)); 577 memset(array, 0, sizeof(struct nfs_cache_array));
578 array->eof_index = -1; 578 array->eof_index = -1;
579 579
580 pages_ptr = nfs_readdir_large_page(pages, array_size); 580 status = nfs_readdir_large_page(pages, array_size);
581 if (!pages_ptr) 581 if (status < 0)
582 goto out_release_array; 582 goto out_release_array;
583 do { 583 do {
584 unsigned int pglen; 584 unsigned int pglen;
@@ -587,7 +587,7 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,
587 if (status < 0) 587 if (status < 0)
588 break; 588 break;
589 pglen = status; 589 pglen = status;
590 status = nfs_readdir_page_filler(desc, &entry, pages_ptr, page, pglen); 590 status = nfs_readdir_page_filler(desc, &entry, pages, page, pglen);
591 if (status < 0) { 591 if (status < 0) {
592 if (status == -ENOSPC) 592 if (status == -ENOSPC)
593 status = 0; 593 status = 0;
@@ -970,7 +970,7 @@ int nfs_lookup_verify_inode(struct inode *inode, struct nameidata *nd)
970{ 970{
971 struct nfs_server *server = NFS_SERVER(inode); 971 struct nfs_server *server = NFS_SERVER(inode);
972 972
973 if (test_bit(NFS_INO_MOUNTPOINT, &NFS_I(inode)->flags)) 973 if (IS_AUTOMOUNT(inode))
974 return 0; 974 return 0;
975 if (nd != NULL) { 975 if (nd != NULL) {
976 /* VFS wants an on-the-wire revalidation */ 976 /* VFS wants an on-the-wire revalidation */
@@ -1173,6 +1173,7 @@ const struct dentry_operations nfs_dentry_operations = {
1173 .d_revalidate = nfs_lookup_revalidate, 1173 .d_revalidate = nfs_lookup_revalidate,
1174 .d_delete = nfs_dentry_delete, 1174 .d_delete = nfs_dentry_delete,
1175 .d_iput = nfs_dentry_iput, 1175 .d_iput = nfs_dentry_iput,
1176 .d_automount = nfs_d_automount,
1176}; 1177};
1177 1178
1178static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) 1179static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
@@ -1192,8 +1193,6 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
1192 if (dentry->d_name.len > NFS_SERVER(dir)->namelen) 1193 if (dentry->d_name.len > NFS_SERVER(dir)->namelen)
1193 goto out; 1194 goto out;
1194 1195
1195 d_set_d_op(dentry, NFS_PROTO(dir)->dentry_ops);
1196
1197 /* 1196 /*
1198 * If we're doing an exclusive create, optimize away the lookup 1197 * If we're doing an exclusive create, optimize away the lookup
1199 * but don't hash the dentry. 1198 * but don't hash the dentry.
@@ -1221,7 +1220,7 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
1221 goto out_unblock_sillyrename; 1220 goto out_unblock_sillyrename;
1222 } 1221 }
1223 inode = nfs_fhget(dentry->d_sb, fhandle, fattr); 1222 inode = nfs_fhget(dentry->d_sb, fhandle, fattr);
1224 res = (struct dentry *)inode; 1223 res = ERR_CAST(inode);
1225 if (IS_ERR(res)) 1224 if (IS_ERR(res))
1226 goto out_unblock_sillyrename; 1225 goto out_unblock_sillyrename;
1227 1226
@@ -1248,6 +1247,7 @@ const struct dentry_operations nfs4_dentry_operations = {
1248 .d_revalidate = nfs_open_revalidate, 1247 .d_revalidate = nfs_open_revalidate,
1249 .d_delete = nfs_dentry_delete, 1248 .d_delete = nfs_dentry_delete,
1250 .d_iput = nfs_dentry_iput, 1249 .d_iput = nfs_dentry_iput,
1250 .d_automount = nfs_d_automount,
1251}; 1251};
1252 1252
1253/* 1253/*
@@ -1337,7 +1337,6 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
1337 res = ERR_PTR(-ENAMETOOLONG); 1337 res = ERR_PTR(-ENAMETOOLONG);
1338 goto out; 1338 goto out;
1339 } 1339 }
1340 d_set_d_op(dentry, NFS_PROTO(dir)->dentry_ops);
1341 1340
1342 /* Let vfs_create() deal with O_EXCL. Instantiate, but don't hash 1341 /* Let vfs_create() deal with O_EXCL. Instantiate, but don't hash
1343 * the dentry. */ 1342 * the dentry. */
@@ -1355,8 +1354,7 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
1355 if (nd->flags & LOOKUP_CREATE) { 1354 if (nd->flags & LOOKUP_CREATE) {
1356 attr.ia_mode = nd->intent.open.create_mode; 1355 attr.ia_mode = nd->intent.open.create_mode;
1357 attr.ia_valid = ATTR_MODE; 1356 attr.ia_valid = ATTR_MODE;
1358 if (!IS_POSIXACL(dir)) 1357 attr.ia_mode &= ~current_umask();
1359 attr.ia_mode &= ~current_umask();
1360 } else { 1358 } else {
1361 open_flags &= ~(O_EXCL | O_CREAT); 1359 open_flags &= ~(O_EXCL | O_CREAT);
1362 attr.ia_valid = 0; 1360 attr.ia_valid = 0;
@@ -1410,11 +1408,15 @@ no_open:
1410static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd) 1408static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
1411{ 1409{
1412 struct dentry *parent = NULL; 1410 struct dentry *parent = NULL;
1413 struct inode *inode = dentry->d_inode; 1411 struct inode *inode;
1414 struct inode *dir; 1412 struct inode *dir;
1415 struct nfs_open_context *ctx; 1413 struct nfs_open_context *ctx;
1416 int openflags, ret = 0; 1414 int openflags, ret = 0;
1417 1415
1416 if (nd->flags & LOOKUP_RCU)
1417 return -ECHILD;
1418
1419 inode = dentry->d_inode;
1418 if (!is_atomic_open(nd) || d_mountpoint(dentry)) 1420 if (!is_atomic_open(nd) || d_mountpoint(dentry))
1419 goto no_open; 1421 goto no_open;
1420 1422
@@ -1583,6 +1585,7 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode,
1583{ 1585{
1584 struct iattr attr; 1586 struct iattr attr;
1585 int error; 1587 int error;
1588 int open_flags = 0;
1586 1589
1587 dfprintk(VFS, "NFS: create(%s/%ld), %s\n", 1590 dfprintk(VFS, "NFS: create(%s/%ld), %s\n",
1588 dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); 1591 dir->i_sb->s_id, dir->i_ino, dentry->d_name.name);
@@ -1590,7 +1593,10 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode,
1590 attr.ia_mode = mode; 1593 attr.ia_mode = mode;
1591 attr.ia_valid = ATTR_MODE; 1594 attr.ia_valid = ATTR_MODE;
1592 1595
1593 error = NFS_PROTO(dir)->create(dir, dentry, &attr, 0, NULL); 1596 if ((nd->flags & LOOKUP_CREATE) != 0)
1597 open_flags = nd->intent.open.flags;
1598
1599 error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags, NULL);
1594 if (error != 0) 1600 if (error != 0)
1595 goto out_err; 1601 goto out_err;
1596 return 0; 1602 return 0;