diff options
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r-- | fs/nfs/inode.c | 36 |
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 | ||
626 | static struct nfs_open_context *alloc_nfs_open_context(struct path *path, struct rpc_cred *cred) | 622 | struct 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 | */ |
676 | static void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx) | 678 | void 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: | |||
1585 | out7: | 1590 | out7: |
1586 | nfs_dns_resolver_destroy(); | 1591 | nfs_dns_resolver_destroy(); |
1587 | out8: | 1592 | out8: |
1593 | nfs_idmap_quit(); | ||
1594 | out9: | ||
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 |