aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/inode.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-03-25 12:18:27 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-25 12:18:27 -0500
commit53846a21c1766326bb14ce8ab6e997a0c120675d (patch)
tree37b04485e29844b4e734479181276a2f4d2447e4 /fs/nfs/inode.c
parent2e9abdd9bad485970b37cd53a82f92702054984c (diff)
parent1ebbe2b20091d306453a5cf480a87e6cd28ae76f (diff)
Merge git://git.linux-nfs.org/pub/linux/nfs-2.6
* git://git.linux-nfs.org/pub/linux/nfs-2.6: (103 commits) SUNRPC,RPCSEC_GSS: spkm3--fix config dependencies SUNRPC,RPCSEC_GSS: spkm3: import contexts using NID_cast5_cbc LOCKD: Make nlmsvc_traverse_shares return void LOCKD: nlmsvc_traverse_blocks return is unused SUNRPC,RPCSEC_GSS: fix krb5 sequence numbers. NFSv4: Dont list system.nfs4_acl for filesystems that don't support it. SUNRPC,RPCSEC_GSS: remove unnecessary kmalloc of a checksum SUNRPC: Ensure rpc_call_async() always calls tk_ops->rpc_release() SUNRPC: Fix memory barriers for req->rq_received NFS: Fix a race in nfs_sync_inode() NFS: Clean up nfs_flush_list() NFS: Fix a race with PG_private and nfs_release_page() NFSv4: Ensure the callback daemon flushes signals SUNRPC: Fix a 'Busy inodes' error in rpc_pipefs NFS, NLM: Allow blocking locks to respect signals NFS: Make nfs_fhget() return appropriate error values NFSv4: Fix an oops in nfs4_fill_super lockd: blocks should hold a reference to the nlm_file NFSv4: SETCLIENTID_CONFIRM should handle NFS4ERR_DELAY/NFS4ERR_RESOURCE NFSv4: Send the delegation stateid for SETATTR calls ...
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r--fs/nfs/inode.c229
1 files changed, 171 insertions, 58 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 3413996f9a86..2f7656b911b6 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -26,6 +26,7 @@
26#include <linux/unistd.h> 26#include <linux/unistd.h>
27#include <linux/sunrpc/clnt.h> 27#include <linux/sunrpc/clnt.h>
28#include <linux/sunrpc/stats.h> 28#include <linux/sunrpc/stats.h>
29#include <linux/sunrpc/metrics.h>
29#include <linux/nfs_fs.h> 30#include <linux/nfs_fs.h>
30#include <linux/nfs_mount.h> 31#include <linux/nfs_mount.h>
31#include <linux/nfs4_mount.h> 32#include <linux/nfs4_mount.h>
@@ -42,6 +43,7 @@
42#include "nfs4_fs.h" 43#include "nfs4_fs.h"
43#include "callback.h" 44#include "callback.h"
44#include "delegation.h" 45#include "delegation.h"
46#include "iostat.h"
45 47
46#define NFSDBG_FACILITY NFSDBG_VFS 48#define NFSDBG_FACILITY NFSDBG_VFS
47#define NFS_PARANOIA 1 49#define NFS_PARANOIA 1
@@ -65,6 +67,7 @@ static void nfs_clear_inode(struct inode *);
65static void nfs_umount_begin(struct super_block *); 67static void nfs_umount_begin(struct super_block *);
66static int nfs_statfs(struct super_block *, struct kstatfs *); 68static int nfs_statfs(struct super_block *, struct kstatfs *);
67static int nfs_show_options(struct seq_file *, struct vfsmount *); 69static int nfs_show_options(struct seq_file *, struct vfsmount *);
70static int nfs_show_stats(struct seq_file *, struct vfsmount *);
68static void nfs_zap_acl_cache(struct inode *); 71static void nfs_zap_acl_cache(struct inode *);
69 72
70static struct rpc_program nfs_program; 73static struct rpc_program nfs_program;
@@ -78,6 +81,7 @@ static struct super_operations nfs_sops = {
78 .clear_inode = nfs_clear_inode, 81 .clear_inode = nfs_clear_inode,
79 .umount_begin = nfs_umount_begin, 82 .umount_begin = nfs_umount_begin,
80 .show_options = nfs_show_options, 83 .show_options = nfs_show_options,
84 .show_stats = nfs_show_stats,
81}; 85};
82 86
83/* 87/*
@@ -133,7 +137,7 @@ nfs_fattr_to_ino_t(struct nfs_fattr *fattr)
133static int 137static int
134nfs_write_inode(struct inode *inode, int sync) 138nfs_write_inode(struct inode *inode, int sync)
135{ 139{
136 int flags = sync ? FLUSH_WAIT : 0; 140 int flags = sync ? FLUSH_SYNC : 0;
137 int ret; 141 int ret;
138 142
139 ret = nfs_commit_inode(inode, flags); 143 ret = nfs_commit_inode(inode, flags);
@@ -237,7 +241,6 @@ static struct inode *
237nfs_get_root(struct super_block *sb, struct nfs_fh *rootfh, struct nfs_fsinfo *fsinfo) 241nfs_get_root(struct super_block *sb, struct nfs_fh *rootfh, struct nfs_fsinfo *fsinfo)
238{ 242{
239 struct nfs_server *server = NFS_SB(sb); 243 struct nfs_server *server = NFS_SB(sb);
240 struct inode *rooti;
241 int error; 244 int error;
242 245
243 error = server->rpc_ops->getroot(server, rootfh, fsinfo); 246 error = server->rpc_ops->getroot(server, rootfh, fsinfo);
@@ -246,10 +249,7 @@ nfs_get_root(struct super_block *sb, struct nfs_fh *rootfh, struct nfs_fsinfo *f
246 return ERR_PTR(error); 249 return ERR_PTR(error);
247 } 250 }
248 251
249 rooti = nfs_fhget(sb, rootfh, fsinfo->fattr); 252 return nfs_fhget(sb, rootfh, fsinfo->fattr);
250 if (!rooti)
251 return ERR_PTR(-ENOMEM);
252 return rooti;
253} 253}
254 254
255/* 255/*
@@ -277,6 +277,10 @@ nfs_sb_init(struct super_block *sb, rpc_authflavor_t authflavor)
277 277
278 sb->s_magic = NFS_SUPER_MAGIC; 278 sb->s_magic = NFS_SUPER_MAGIC;
279 279
280 server->io_stats = nfs_alloc_iostats();
281 if (server->io_stats == NULL)
282 return -ENOMEM;
283
280 root_inode = nfs_get_root(sb, &server->fh, &fsinfo); 284 root_inode = nfs_get_root(sb, &server->fh, &fsinfo);
281 /* Did getting the root inode fail? */ 285 /* Did getting the root inode fail? */
282 if (IS_ERR(root_inode)) { 286 if (IS_ERR(root_inode)) {
@@ -290,6 +294,9 @@ nfs_sb_init(struct super_block *sb, rpc_authflavor_t authflavor)
290 } 294 }
291 sb->s_root->d_op = server->rpc_ops->dentry_ops; 295 sb->s_root->d_op = server->rpc_ops->dentry_ops;
292 296
297 /* mount time stamp, in seconds */
298 server->mount_time = jiffies;
299
293 /* Get some general file system info */ 300 /* Get some general file system info */
294 if (server->namelen == 0 && 301 if (server->namelen == 0 &&
295 server->rpc_ops->pathconf(server, &server->fh, &pathinfo) >= 0) 302 server->rpc_ops->pathconf(server, &server->fh, &pathinfo) >= 0)
@@ -396,6 +403,9 @@ nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data)
396 403
397 nfs_init_timeout_values(&timeparms, proto, data->timeo, data->retrans); 404 nfs_init_timeout_values(&timeparms, proto, data->timeo, data->retrans);
398 405
406 server->retrans_timeo = timeparms.to_initval;
407 server->retrans_count = timeparms.to_retries;
408
399 /* create transport and client */ 409 /* create transport and client */
400 xprt = xprt_create_proto(proto, &server->addr, &timeparms); 410 xprt = xprt_create_proto(proto, &server->addr, &timeparms);
401 if (IS_ERR(xprt)) { 411 if (IS_ERR(xprt)) {
@@ -579,7 +589,7 @@ nfs_statfs(struct super_block *sb, struct kstatfs *buf)
579 589
580} 590}
581 591
582static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt) 592static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, int showdefaults)
583{ 593{
584 static struct proc_nfs_info { 594 static struct proc_nfs_info {
585 int flag; 595 int flag;
@@ -588,28 +598,26 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
588 } nfs_info[] = { 598 } nfs_info[] = {
589 { NFS_MOUNT_SOFT, ",soft", ",hard" }, 599 { NFS_MOUNT_SOFT, ",soft", ",hard" },
590 { NFS_MOUNT_INTR, ",intr", "" }, 600 { NFS_MOUNT_INTR, ",intr", "" },
591 { NFS_MOUNT_POSIX, ",posix", "" },
592 { NFS_MOUNT_NOCTO, ",nocto", "" }, 601 { NFS_MOUNT_NOCTO, ",nocto", "" },
593 { NFS_MOUNT_NOAC, ",noac", "" }, 602 { NFS_MOUNT_NOAC, ",noac", "" },
594 { NFS_MOUNT_NONLM, ",nolock", ",lock" }, 603 { NFS_MOUNT_NONLM, ",nolock", "" },
595 { NFS_MOUNT_NOACL, ",noacl", "" }, 604 { NFS_MOUNT_NOACL, ",noacl", "" },
596 { 0, NULL, NULL } 605 { 0, NULL, NULL }
597 }; 606 };
598 struct proc_nfs_info *nfs_infop; 607 struct proc_nfs_info *nfs_infop;
599 struct nfs_server *nfss = NFS_SB(mnt->mnt_sb);
600 char buf[12]; 608 char buf[12];
601 char *proto; 609 char *proto;
602 610
603 seq_printf(m, ",v%d", nfss->rpc_ops->version); 611 seq_printf(m, ",vers=%d", nfss->rpc_ops->version);
604 seq_printf(m, ",rsize=%d", nfss->rsize); 612 seq_printf(m, ",rsize=%d", nfss->rsize);
605 seq_printf(m, ",wsize=%d", nfss->wsize); 613 seq_printf(m, ",wsize=%d", nfss->wsize);
606 if (nfss->acregmin != 3*HZ) 614 if (nfss->acregmin != 3*HZ || showdefaults)
607 seq_printf(m, ",acregmin=%d", nfss->acregmin/HZ); 615 seq_printf(m, ",acregmin=%d", nfss->acregmin/HZ);
608 if (nfss->acregmax != 60*HZ) 616 if (nfss->acregmax != 60*HZ || showdefaults)
609 seq_printf(m, ",acregmax=%d", nfss->acregmax/HZ); 617 seq_printf(m, ",acregmax=%d", nfss->acregmax/HZ);
610 if (nfss->acdirmin != 30*HZ) 618 if (nfss->acdirmin != 30*HZ || showdefaults)
611 seq_printf(m, ",acdirmin=%d", nfss->acdirmin/HZ); 619 seq_printf(m, ",acdirmin=%d", nfss->acdirmin/HZ);
612 if (nfss->acdirmax != 60*HZ) 620 if (nfss->acdirmax != 60*HZ || showdefaults)
613 seq_printf(m, ",acdirmax=%d", nfss->acdirmax/HZ); 621 seq_printf(m, ",acdirmax=%d", nfss->acdirmax/HZ);
614 for (nfs_infop = nfs_info; nfs_infop->flag; nfs_infop++) { 622 for (nfs_infop = nfs_info; nfs_infop->flag; nfs_infop++) {
615 if (nfss->flags & nfs_infop->flag) 623 if (nfss->flags & nfs_infop->flag)
@@ -629,8 +637,96 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
629 proto = buf; 637 proto = buf;
630 } 638 }
631 seq_printf(m, ",proto=%s", proto); 639 seq_printf(m, ",proto=%s", proto);
640 seq_printf(m, ",timeo=%lu", 10U * nfss->retrans_timeo / HZ);
641 seq_printf(m, ",retrans=%u", nfss->retrans_count);
642}
643
644static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
645{
646 struct nfs_server *nfss = NFS_SB(mnt->mnt_sb);
647
648 nfs_show_mount_options(m, nfss, 0);
649
632 seq_puts(m, ",addr="); 650 seq_puts(m, ",addr=");
633 seq_escape(m, nfss->hostname, " \t\n\\"); 651 seq_escape(m, nfss->hostname, " \t\n\\");
652
653 return 0;
654}
655
656static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt)
657{
658 int i, cpu;
659 struct nfs_server *nfss = NFS_SB(mnt->mnt_sb);
660 struct rpc_auth *auth = nfss->client->cl_auth;
661 struct nfs_iostats totals = { };
662
663 seq_printf(m, "statvers=%s", NFS_IOSTAT_VERS);
664
665 /*
666 * Display all mount option settings
667 */
668 seq_printf(m, "\n\topts:\t");
669 seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? "ro" : "rw");
670 seq_puts(m, mnt->mnt_sb->s_flags & MS_SYNCHRONOUS ? ",sync" : "");
671 seq_puts(m, mnt->mnt_sb->s_flags & MS_NOATIME ? ",noatime" : "");
672 seq_puts(m, mnt->mnt_sb->s_flags & MS_NODIRATIME ? ",nodiratime" : "");
673 nfs_show_mount_options(m, nfss, 1);
674
675 seq_printf(m, "\n\tage:\t%lu", (jiffies - nfss->mount_time) / HZ);
676
677 seq_printf(m, "\n\tcaps:\t");
678 seq_printf(m, "caps=0x%x", nfss->caps);
679 seq_printf(m, ",wtmult=%d", nfss->wtmult);
680 seq_printf(m, ",dtsize=%d", nfss->dtsize);
681 seq_printf(m, ",bsize=%d", nfss->bsize);
682 seq_printf(m, ",namelen=%d", nfss->namelen);
683
684#ifdef CONFIG_NFS_V4
685 if (nfss->rpc_ops->version == 4) {
686 seq_printf(m, "\n\tnfsv4:\t");
687 seq_printf(m, "bm0=0x%x", nfss->attr_bitmask[0]);
688 seq_printf(m, ",bm1=0x%x", nfss->attr_bitmask[1]);
689 seq_printf(m, ",acl=0x%x", nfss->acl_bitmask);
690 }
691#endif
692
693 /*
694 * Display security flavor in effect for this mount
695 */
696 seq_printf(m, "\n\tsec:\tflavor=%d", auth->au_ops->au_flavor);
697 if (auth->au_flavor)
698 seq_printf(m, ",pseudoflavor=%d", auth->au_flavor);
699
700 /*
701 * Display superblock I/O counters
702 */
703 for (cpu = 0; cpu < NR_CPUS; cpu++) {
704 struct nfs_iostats *stats;
705
706 if (!cpu_possible(cpu))
707 continue;
708
709 preempt_disable();
710 stats = per_cpu_ptr(nfss->io_stats, cpu);
711
712 for (i = 0; i < __NFSIOS_COUNTSMAX; i++)
713 totals.events[i] += stats->events[i];
714 for (i = 0; i < __NFSIOS_BYTESMAX; i++)
715 totals.bytes[i] += stats->bytes[i];
716
717 preempt_enable();
718 }
719
720 seq_printf(m, "\n\tevents:\t");
721 for (i = 0; i < __NFSIOS_COUNTSMAX; i++)
722 seq_printf(m, "%lu ", totals.events[i]);
723 seq_printf(m, "\n\tbytes:\t");
724 for (i = 0; i < __NFSIOS_BYTESMAX; i++)
725 seq_printf(m, "%Lu ", totals.bytes[i]);
726 seq_printf(m, "\n");
727
728 rpc_print_iostats(m, nfss->client);
729
634 return 0; 730 return 0;
635} 731}
636 732
@@ -660,6 +756,8 @@ static void nfs_zap_caches_locked(struct inode *inode)
660 struct nfs_inode *nfsi = NFS_I(inode); 756 struct nfs_inode *nfsi = NFS_I(inode);
661 int mode = inode->i_mode; 757 int mode = inode->i_mode;
662 758
759 nfs_inc_stats(inode, NFSIOS_ATTRINVALIDATE);
760
663 NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode); 761 NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode);
664 NFS_ATTRTIMEO_UPDATE(inode) = jiffies; 762 NFS_ATTRTIMEO_UPDATE(inode) = jiffies;
665 763
@@ -751,7 +849,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
751 .fh = fh, 849 .fh = fh,
752 .fattr = fattr 850 .fattr = fattr
753 }; 851 };
754 struct inode *inode = NULL; 852 struct inode *inode = ERR_PTR(-ENOENT);
755 unsigned long hash; 853 unsigned long hash;
756 854
757 if ((fattr->valid & NFS_ATTR_FATTR) == 0) 855 if ((fattr->valid & NFS_ATTR_FATTR) == 0)
@@ -764,8 +862,11 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
764 862
765 hash = nfs_fattr_to_ino_t(fattr); 863 hash = nfs_fattr_to_ino_t(fattr);
766 864
767 if (!(inode = iget5_locked(sb, hash, nfs_find_actor, nfs_init_locked, &desc))) 865 inode = iget5_locked(sb, hash, nfs_find_actor, nfs_init_locked, &desc);
866 if (inode == NULL) {
867 inode = ERR_PTR(-ENOMEM);
768 goto out_no_inode; 868 goto out_no_inode;
869 }
769 870
770 if (inode->i_state & I_NEW) { 871 if (inode->i_state & I_NEW) {
771 struct nfs_inode *nfsi = NFS_I(inode); 872 struct nfs_inode *nfsi = NFS_I(inode);
@@ -834,7 +935,7 @@ out:
834 return inode; 935 return inode;
835 936
836out_no_inode: 937out_no_inode:
837 printk("nfs_fhget: iget failed\n"); 938 dprintk("nfs_fhget: iget failed with error %ld\n", PTR_ERR(inode));
838 goto out; 939 goto out;
839} 940}
840 941
@@ -847,6 +948,8 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
847 struct nfs_fattr fattr; 948 struct nfs_fattr fattr;
848 int error; 949 int error;
849 950
951 nfs_inc_stats(inode, NFSIOS_VFSSETATTR);
952
850 if (attr->ia_valid & ATTR_SIZE) { 953 if (attr->ia_valid & ATTR_SIZE) {
851 if (!S_ISREG(inode->i_mode) || attr->ia_size == i_size_read(inode)) 954 if (!S_ISREG(inode->i_mode) || attr->ia_size == i_size_read(inode))
852 attr->ia_valid &= ~ATTR_SIZE; 955 attr->ia_valid &= ~ATTR_SIZE;
@@ -859,11 +962,9 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
859 962
860 lock_kernel(); 963 lock_kernel();
861 nfs_begin_data_update(inode); 964 nfs_begin_data_update(inode);
862 /* Write all dirty data if we're changing file permissions or size */ 965 /* Write all dirty data */
863 if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE)) != 0) { 966 filemap_write_and_wait(inode->i_mapping);
864 filemap_write_and_wait(inode->i_mapping); 967 nfs_wb_all(inode);
865 nfs_wb_all(inode);
866 }
867 /* 968 /*
868 * Return any delegations if we're going to change ACLs 969 * Return any delegations if we're going to change ACLs
869 */ 970 */
@@ -902,6 +1003,7 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr)
902 spin_unlock(&inode->i_lock); 1003 spin_unlock(&inode->i_lock);
903 } 1004 }
904 if ((attr->ia_valid & ATTR_SIZE) != 0) { 1005 if ((attr->ia_valid & ATTR_SIZE) != 0) {
1006 nfs_inc_stats(inode, NFSIOS_SETATTRTRUNC);
905 inode->i_size = attr->ia_size; 1007 inode->i_size = attr->ia_size;
906 vmtruncate(inode, attr->ia_size); 1008 vmtruncate(inode, attr->ia_size);
907 } 1009 }
@@ -949,7 +1051,7 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
949 int err; 1051 int err;
950 1052
951 /* Flush out writes to the server in order to update c/mtime */ 1053 /* Flush out writes to the server in order to update c/mtime */
952 nfs_sync_inode(inode, 0, 0, FLUSH_WAIT|FLUSH_NOCOMMIT); 1054 nfs_sync_inode_wait(inode, 0, 0, FLUSH_NOCOMMIT);
953 1055
954 /* 1056 /*
955 * We may force a getattr if the user cares about atime. 1057 * We may force a getattr if the user cares about atime.
@@ -973,7 +1075,7 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
973 return err; 1075 return err;
974} 1076}
975 1077
976struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, struct rpc_cred *cred) 1078static struct nfs_open_context *alloc_nfs_open_context(struct vfsmount *mnt, struct dentry *dentry, struct rpc_cred *cred)
977{ 1079{
978 struct nfs_open_context *ctx; 1080 struct nfs_open_context *ctx;
979 1081
@@ -981,6 +1083,7 @@ struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, struct rp
981 if (ctx != NULL) { 1083 if (ctx != NULL) {
982 atomic_set(&ctx->count, 1); 1084 atomic_set(&ctx->count, 1);
983 ctx->dentry = dget(dentry); 1085 ctx->dentry = dget(dentry);
1086 ctx->vfsmnt = mntget(mnt);
984 ctx->cred = get_rpccred(cred); 1087 ctx->cred = get_rpccred(cred);
985 ctx->state = NULL; 1088 ctx->state = NULL;
986 ctx->lockowner = current->files; 1089 ctx->lockowner = current->files;
@@ -1011,6 +1114,7 @@ void put_nfs_open_context(struct nfs_open_context *ctx)
1011 if (ctx->cred != NULL) 1114 if (ctx->cred != NULL)
1012 put_rpccred(ctx->cred); 1115 put_rpccred(ctx->cred);
1013 dput(ctx->dentry); 1116 dput(ctx->dentry);
1117 mntput(ctx->vfsmnt);
1014 kfree(ctx); 1118 kfree(ctx);
1015 } 1119 }
1016} 1120}
@@ -1019,7 +1123,7 @@ void put_nfs_open_context(struct nfs_open_context *ctx)
1019 * Ensure that mmap has a recent RPC credential for use when writing out 1123 * Ensure that mmap has a recent RPC credential for use when writing out
1020 * shared pages 1124 * shared pages
1021 */ 1125 */
1022void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx) 1126static void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx)
1023{ 1127{
1024 struct inode *inode = filp->f_dentry->d_inode; 1128 struct inode *inode = filp->f_dentry->d_inode;
1025 struct nfs_inode *nfsi = NFS_I(inode); 1129 struct nfs_inode *nfsi = NFS_I(inode);
@@ -1051,7 +1155,7 @@ struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_c
1051 return ctx; 1155 return ctx;
1052} 1156}
1053 1157
1054void nfs_file_clear_open_context(struct file *filp) 1158static void nfs_file_clear_open_context(struct file *filp)
1055{ 1159{
1056 struct inode *inode = filp->f_dentry->d_inode; 1160 struct inode *inode = filp->f_dentry->d_inode;
1057 struct nfs_open_context *ctx = (struct nfs_open_context *)filp->private_data; 1161 struct nfs_open_context *ctx = (struct nfs_open_context *)filp->private_data;
@@ -1076,7 +1180,7 @@ int nfs_open(struct inode *inode, struct file *filp)
1076 cred = rpcauth_lookupcred(NFS_CLIENT(inode)->cl_auth, 0); 1180 cred = rpcauth_lookupcred(NFS_CLIENT(inode)->cl_auth, 0);
1077 if (IS_ERR(cred)) 1181 if (IS_ERR(cred))
1078 return PTR_ERR(cred); 1182 return PTR_ERR(cred);
1079 ctx = alloc_nfs_open_context(filp->f_dentry, cred); 1183 ctx = alloc_nfs_open_context(filp->f_vfsmnt, filp->f_dentry, cred);
1080 put_rpccred(cred); 1184 put_rpccred(cred);
1081 if (ctx == NULL) 1185 if (ctx == NULL)
1082 return -ENOMEM; 1186 return -ENOMEM;
@@ -1185,6 +1289,7 @@ int nfs_attribute_timeout(struct inode *inode)
1185 */ 1289 */
1186int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) 1290int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
1187{ 1291{
1292 nfs_inc_stats(inode, NFSIOS_INODEREVALIDATE);
1188 if (!(NFS_I(inode)->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA)) 1293 if (!(NFS_I(inode)->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA))
1189 && !nfs_attribute_timeout(inode)) 1294 && !nfs_attribute_timeout(inode))
1190 return NFS_STALE(inode) ? -ESTALE : 0; 1295 return NFS_STALE(inode) ? -ESTALE : 0;
@@ -1201,6 +1306,7 @@ void nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping)
1201 struct nfs_inode *nfsi = NFS_I(inode); 1306 struct nfs_inode *nfsi = NFS_I(inode);
1202 1307
1203 if (nfsi->cache_validity & NFS_INO_INVALID_DATA) { 1308 if (nfsi->cache_validity & NFS_INO_INVALID_DATA) {
1309 nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE);
1204 if (S_ISREG(inode->i_mode)) 1310 if (S_ISREG(inode->i_mode))
1205 nfs_sync_mapping(mapping); 1311 nfs_sync_mapping(mapping);
1206 invalidate_inode_pages2(mapping); 1312 invalidate_inode_pages2(mapping);
@@ -1299,39 +1405,37 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
1299 if ((fattr->valid & NFS_ATTR_FATTR) == 0) 1405 if ((fattr->valid & NFS_ATTR_FATTR) == 0)
1300 return 0; 1406 return 0;
1301 1407
1408 /* Has the inode gone and changed behind our back? */
1409 if (nfsi->fileid != fattr->fileid
1410 || (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) {
1411 return -EIO;
1412 }
1413
1302 /* Are we in the process of updating data on the server? */ 1414 /* Are we in the process of updating data on the server? */
1303 data_unstable = nfs_caches_unstable(inode); 1415 data_unstable = nfs_caches_unstable(inode);
1304 1416
1305 /* Do atomic weak cache consistency updates */ 1417 /* Do atomic weak cache consistency updates */
1306 nfs_wcc_update_inode(inode, fattr); 1418 nfs_wcc_update_inode(inode, fattr);
1307 1419
1308 if ((fattr->valid & NFS_ATTR_FATTR_V4) != 0 && 1420 if ((fattr->valid & NFS_ATTR_FATTR_V4) != 0) {
1309 nfsi->change_attr != fattr->change_attr) { 1421 if (nfsi->change_attr == fattr->change_attr)
1422 goto out;
1310 nfsi->cache_validity |= NFS_INO_INVALID_ATTR; 1423 nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
1311 if (!data_unstable) 1424 if (!data_unstable)
1312 nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE; 1425 nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE;
1313 } 1426 }
1314 1427
1315 /* Has the inode gone and changed behind our back? */
1316 if (nfsi->fileid != fattr->fileid
1317 || (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) {
1318 return -EIO;
1319 }
1320
1321 cur_size = i_size_read(inode);
1322 new_isize = nfs_size_to_loff_t(fattr->size);
1323
1324 /* Verify a few of the more important attributes */ 1428 /* Verify a few of the more important attributes */
1325 if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) { 1429 if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) {
1326 nfsi->cache_validity |= NFS_INO_INVALID_ATTR; 1430 nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
1327 if (!data_unstable) 1431 if (!data_unstable)
1328 nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE; 1432 nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE;
1329 } 1433 }
1330 if (cur_size != new_isize) { 1434
1331 nfsi->cache_validity |= NFS_INO_INVALID_ATTR; 1435 cur_size = i_size_read(inode);
1332 if (nfsi->npages == 0) 1436 new_isize = nfs_size_to_loff_t(fattr->size);
1333 nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE; 1437 if (cur_size != new_isize && nfsi->npages == 0)
1334 } 1438 nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
1335 1439
1336 /* Have any file permissions changed? */ 1440 /* Have any file permissions changed? */
1337 if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) 1441 if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)
@@ -1343,6 +1447,7 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
1343 if (inode->i_nlink != fattr->nlink) 1447 if (inode->i_nlink != fattr->nlink)
1344 nfsi->cache_validity |= NFS_INO_INVALID_ATTR; 1448 nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
1345 1449
1450out:
1346 if (!timespec_equal(&inode->i_atime, &fattr->atime)) 1451 if (!timespec_equal(&inode->i_atime, &fattr->atime))
1347 nfsi->cache_validity |= NFS_INO_INVALID_ATIME; 1452 nfsi->cache_validity |= NFS_INO_INVALID_ATIME;
1348 1453
@@ -1481,15 +1586,6 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1481 nfsi->cache_change_attribute = jiffies; 1586 nfsi->cache_change_attribute = jiffies;
1482 } 1587 }
1483 1588
1484 if ((fattr->valid & NFS_ATTR_FATTR_V4)
1485 && nfsi->change_attr != fattr->change_attr) {
1486 dprintk("NFS: change_attr change on server for file %s/%ld\n",
1487 inode->i_sb->s_id, inode->i_ino);
1488 nfsi->change_attr = fattr->change_attr;
1489 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
1490 nfsi->cache_change_attribute = jiffies;
1491 }
1492
1493 /* If ctime has changed we should definitely clear access+acl caches */ 1589 /* If ctime has changed we should definitely clear access+acl caches */
1494 if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) { 1590 if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) {
1495 invalid |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; 1591 invalid |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
@@ -1519,8 +1615,20 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1519 inode->i_blksize = fattr->du.nfs2.blocksize; 1615 inode->i_blksize = fattr->du.nfs2.blocksize;
1520 } 1616 }
1521 1617
1618 if ((fattr->valid & NFS_ATTR_FATTR_V4)) {
1619 if (nfsi->change_attr != fattr->change_attr) {
1620 dprintk("NFS: change_attr change on server for file %s/%ld\n",
1621 inode->i_sb->s_id, inode->i_ino);
1622 nfsi->change_attr = fattr->change_attr;
1623 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
1624 nfsi->cache_change_attribute = jiffies;
1625 } else
1626 invalid &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA);
1627 }
1628
1522 /* Update attrtimeo value if we're out of the unstable period */ 1629 /* Update attrtimeo value if we're out of the unstable period */
1523 if (invalid & NFS_INO_INVALID_ATTR) { 1630 if (invalid & NFS_INO_INVALID_ATTR) {
1631 nfs_inc_stats(inode, NFSIOS_ATTRINVALIDATE);
1524 nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); 1632 nfsi->attrtimeo = NFS_MINATTRTIMEO(inode);
1525 nfsi->attrtimeo_timestamp = jiffies; 1633 nfsi->attrtimeo_timestamp = jiffies;
1526 } else if (time_after(jiffies, nfsi->attrtimeo_timestamp+nfsi->attrtimeo)) { 1634 } else if (time_after(jiffies, nfsi->attrtimeo_timestamp+nfsi->attrtimeo)) {
@@ -1637,10 +1745,9 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
1637#endif /* CONFIG_NFS_V3 */ 1745#endif /* CONFIG_NFS_V3 */
1638 1746
1639 s = ERR_PTR(-ENOMEM); 1747 s = ERR_PTR(-ENOMEM);
1640 server = kmalloc(sizeof(struct nfs_server), GFP_KERNEL); 1748 server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL);
1641 if (!server) 1749 if (!server)
1642 goto out_err; 1750 goto out_err;
1643 memset(server, 0, sizeof(struct nfs_server));
1644 /* Zero out the NFS state stuff */ 1751 /* Zero out the NFS state stuff */
1645 init_nfsv4_state(server); 1752 init_nfsv4_state(server);
1646 server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL); 1753 server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL);
@@ -1712,6 +1819,7 @@ static void nfs_kill_super(struct super_block *s)
1712 1819
1713 rpciod_down(); /* release rpciod */ 1820 rpciod_down(); /* release rpciod */
1714 1821
1822 nfs_free_iostats(server->io_stats);
1715 kfree(server->hostname); 1823 kfree(server->hostname);
1716 kfree(server); 1824 kfree(server);
1717} 1825}
@@ -1738,6 +1846,7 @@ static struct super_operations nfs4_sops = {
1738 .clear_inode = nfs4_clear_inode, 1846 .clear_inode = nfs4_clear_inode,
1739 .umount_begin = nfs_umount_begin, 1847 .umount_begin = nfs_umount_begin,
1740 .show_options = nfs_show_options, 1848 .show_options = nfs_show_options,
1849 .show_stats = nfs_show_stats,
1741}; 1850};
1742 1851
1743/* 1852/*
@@ -1800,6 +1909,9 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
1800 1909
1801 nfs_init_timeout_values(&timeparms, data->proto, data->timeo, data->retrans); 1910 nfs_init_timeout_values(&timeparms, data->proto, data->timeo, data->retrans);
1802 1911
1912 server->retrans_timeo = timeparms.to_initval;
1913 server->retrans_count = timeparms.to_retries;
1914
1803 clp = nfs4_get_client(&server->addr.sin_addr); 1915 clp = nfs4_get_client(&server->addr.sin_addr);
1804 if (!clp) { 1916 if (!clp) {
1805 dprintk("%s: failed to create NFS4 client.\n", __FUNCTION__); 1917 dprintk("%s: failed to create NFS4 client.\n", __FUNCTION__);
@@ -1941,10 +2053,9 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
1941 return ERR_PTR(-EINVAL); 2053 return ERR_PTR(-EINVAL);
1942 } 2054 }
1943 2055
1944 server = kmalloc(sizeof(struct nfs_server), GFP_KERNEL); 2056 server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL);
1945 if (!server) 2057 if (!server)
1946 return ERR_PTR(-ENOMEM); 2058 return ERR_PTR(-ENOMEM);
1947 memset(server, 0, sizeof(struct nfs_server));
1948 /* Zero out the NFS state stuff */ 2059 /* Zero out the NFS state stuff */
1949 init_nfsv4_state(server); 2060 init_nfsv4_state(server);
1950 server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL); 2061 server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL);
@@ -2024,10 +2135,12 @@ static void nfs4_kill_super(struct super_block *sb)
2024 2135
2025 if (server->client != NULL && !IS_ERR(server->client)) 2136 if (server->client != NULL && !IS_ERR(server->client))
2026 rpc_shutdown_client(server->client); 2137 rpc_shutdown_client(server->client);
2027 rpciod_down(); /* release rpciod */
2028 2138
2029 destroy_nfsv4_state(server); 2139 destroy_nfsv4_state(server);
2030 2140
2141 rpciod_down();
2142
2143 nfs_free_iostats(server->io_stats);
2031 kfree(server->hostname); 2144 kfree(server->hostname);
2032 kfree(server); 2145 kfree(server);
2033} 2146}