aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r--fs/nfs/inode.c36
1 files changed, 22 insertions, 14 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 7d2d6c72aa78..6eec28656415 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -234,9 +234,6 @@ nfs_init_locked(struct inode *inode, void *opaque)
234 return 0; 234 return 0;
235} 235}
236 236
237/* Don't use READDIRPLUS on directories that we believe are too large */
238#define NFS_LIMIT_READDIRPLUS (8*PAGE_SIZE)
239
240/* 237/*
241 * This is our front-end to iget that looks up inodes by file handle 238 * This is our front-end to iget that looks up inodes by file handle
242 * instead of inode number. 239 * instead of inode number.
@@ -291,8 +288,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
291 } else if (S_ISDIR(inode->i_mode)) { 288 } else if (S_ISDIR(inode->i_mode)) {
292 inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->dir_inode_ops; 289 inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->dir_inode_ops;
293 inode->i_fop = &nfs_dir_operations; 290 inode->i_fop = &nfs_dir_operations;
294 if (nfs_server_capable(inode, NFS_CAP_READDIRPLUS) 291 if (nfs_server_capable(inode, NFS_CAP_READDIRPLUS))
295 && fattr->size <= NFS_LIMIT_READDIRPLUS)
296 set_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(inode)->flags); 292 set_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(inode)->flags);
297 /* Deal with crossing mountpoints */ 293 /* Deal with crossing mountpoints */
298 if ((fattr->valid & NFS_ATTR_FATTR_FSID) 294 if ((fattr->valid & NFS_ATTR_FATTR_FSID)
@@ -623,7 +619,7 @@ void nfs_close_context(struct nfs_open_context *ctx, int is_sync)
623 nfs_revalidate_inode(server, inode); 619 nfs_revalidate_inode(server, inode);
624} 620}
625 621
626static struct nfs_open_context *alloc_nfs_open_context(struct path *path, struct rpc_cred *cred) 622struct nfs_open_context *alloc_nfs_open_context(struct path *path, struct rpc_cred *cred, fmode_t f_mode)
627{ 623{
628 struct nfs_open_context *ctx; 624 struct nfs_open_context *ctx;
629 625
@@ -633,11 +629,13 @@ static struct nfs_open_context *alloc_nfs_open_context(struct path *path, struct
633 path_get(&ctx->path); 629 path_get(&ctx->path);
634 ctx->cred = get_rpccred(cred); 630 ctx->cred = get_rpccred(cred);
635 ctx->state = NULL; 631 ctx->state = NULL;
632 ctx->mode = f_mode;
636 ctx->flags = 0; 633 ctx->flags = 0;
637 ctx->error = 0; 634 ctx->error = 0;
638 ctx->dir_cookie = 0; 635 ctx->dir_cookie = 0;
639 nfs_init_lock_context(&ctx->lock_context); 636 nfs_init_lock_context(&ctx->lock_context);
640 ctx->lock_context.open_context = ctx; 637 ctx->lock_context.open_context = ctx;
638 INIT_LIST_HEAD(&ctx->list);
641 } 639 }
642 return ctx; 640 return ctx;
643} 641}
@@ -653,11 +651,15 @@ static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync)
653{ 651{
654 struct inode *inode = ctx->path.dentry->d_inode; 652 struct inode *inode = ctx->path.dentry->d_inode;
655 653
656 if (!atomic_dec_and_lock(&ctx->lock_context.count, &inode->i_lock)) 654 if (!list_empty(&ctx->list)) {
655 if (!atomic_dec_and_lock(&ctx->lock_context.count, &inode->i_lock))
656 return;
657 list_del(&ctx->list);
658 spin_unlock(&inode->i_lock);
659 } else if (!atomic_dec_and_test(&ctx->lock_context.count))
657 return; 660 return;
658 list_del(&ctx->list); 661 if (inode != NULL)
659 spin_unlock(&inode->i_lock); 662 NFS_PROTO(inode)->close_context(ctx, is_sync);
660 NFS_PROTO(inode)->close_context(ctx, is_sync);
661 if (ctx->cred != NULL) 663 if (ctx->cred != NULL)
662 put_rpccred(ctx->cred); 664 put_rpccred(ctx->cred);
663 path_put(&ctx->path); 665 path_put(&ctx->path);
@@ -673,7 +675,7 @@ void put_nfs_open_context(struct nfs_open_context *ctx)
673 * Ensure that mmap has a recent RPC credential for use when writing out 675 * Ensure that mmap has a recent RPC credential for use when writing out
674 * shared pages 676 * shared pages
675 */ 677 */
676static void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx) 678void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx)
677{ 679{
678 struct inode *inode = filp->f_path.dentry->d_inode; 680 struct inode *inode = filp->f_path.dentry->d_inode;
679 struct nfs_inode *nfsi = NFS_I(inode); 681 struct nfs_inode *nfsi = NFS_I(inode);
@@ -730,11 +732,10 @@ int nfs_open(struct inode *inode, struct file *filp)
730 cred = rpc_lookup_cred(); 732 cred = rpc_lookup_cred();
731 if (IS_ERR(cred)) 733 if (IS_ERR(cred))
732 return PTR_ERR(cred); 734 return PTR_ERR(cred);
733 ctx = alloc_nfs_open_context(&filp->f_path, cred); 735 ctx = alloc_nfs_open_context(&filp->f_path, cred, filp->f_mode);
734 put_rpccred(cred); 736 put_rpccred(cred);
735 if (ctx == NULL) 737 if (ctx == NULL)
736 return -ENOMEM; 738 return -ENOMEM;
737 ctx->mode = filp->f_mode;
738 nfs_file_set_open_context(filp, ctx); 739 nfs_file_set_open_context(filp, ctx);
739 put_nfs_open_context(ctx); 740 put_nfs_open_context(ctx);
740 nfs_fscache_set_inode_cookie(inode, filp); 741 nfs_fscache_set_inode_cookie(inode, filp);
@@ -1493,7 +1494,7 @@ static int nfsiod_start(void)
1493{ 1494{
1494 struct workqueue_struct *wq; 1495 struct workqueue_struct *wq;
1495 dprintk("RPC: creating workqueue nfsiod\n"); 1496 dprintk("RPC: creating workqueue nfsiod\n");
1496 wq = create_singlethread_workqueue("nfsiod"); 1497 wq = alloc_workqueue("nfsiod", WQ_RESCUER, 0);
1497 if (wq == NULL) 1498 if (wq == NULL)
1498 return -ENOMEM; 1499 return -ENOMEM;
1499 nfsiod_workqueue = wq; 1500 nfsiod_workqueue = wq;
@@ -1521,6 +1522,10 @@ static int __init init_nfs_fs(void)
1521{ 1522{
1522 int err; 1523 int err;
1523 1524
1525 err = nfs_idmap_init();
1526 if (err < 0)
1527 goto out9;
1528
1524 err = nfs_dns_resolver_init(); 1529 err = nfs_dns_resolver_init();
1525 if (err < 0) 1530 if (err < 0)
1526 goto out8; 1531 goto out8;
@@ -1585,6 +1590,8 @@ out6:
1585out7: 1590out7:
1586 nfs_dns_resolver_destroy(); 1591 nfs_dns_resolver_destroy();
1587out8: 1592out8:
1593 nfs_idmap_quit();
1594out9:
1588 return err; 1595 return err;
1589} 1596}
1590 1597
@@ -1597,6 +1604,7 @@ static void __exit exit_nfs_fs(void)
1597 nfs_destroy_nfspagecache(); 1604 nfs_destroy_nfspagecache();
1598 nfs_fscache_unregister(); 1605 nfs_fscache_unregister();
1599 nfs_dns_resolver_destroy(); 1606 nfs_dns_resolver_destroy();
1607 nfs_idmap_quit();
1600#ifdef CONFIG_PROC_FS 1608#ifdef CONFIG_PROC_FS
1601 rpc_proc_unregister("nfs"); 1609 rpc_proc_unregister("nfs");
1602#endif 1610#endif