]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/nfs/inode.c
NFS: Convert cache_change_attribute into a jiffy-based value
[linux-2.6-omap-h63xx.git] / fs / nfs / inode.c
index 062911e7ceb57b55ccf3cb7cd1141b82b825b10d..449df8c8aa31f0bc9204d67a4b9afb94c648f4a8 100644 (file)
@@ -595,7 +595,6 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
                { NFS_MOUNT_SOFT, ",soft", ",hard" },
                { NFS_MOUNT_INTR, ",intr", "" },
                { NFS_MOUNT_POSIX, ",posix", "" },
-               { NFS_MOUNT_TCP, ",tcp", ",udp" },
                { NFS_MOUNT_NOCTO, ",nocto", "" },
                { NFS_MOUNT_NOAC, ",noac", "" },
                { NFS_MOUNT_NONLM, ",nolock", ",lock" },
@@ -604,6 +603,8 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
        };
        struct proc_nfs_info *nfs_infop;
        struct nfs_server *nfss = NFS_SB(mnt->mnt_sb);
+       char buf[12];
+       char *proto;
 
        seq_printf(m, ",v%d", nfss->rpc_ops->version);
        seq_printf(m, ",rsize=%d", nfss->rsize);
@@ -622,6 +623,18 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
                else
                        seq_puts(m, nfs_infop->nostr);
        }
+       switch (nfss->client->cl_xprt->prot) {
+               case IPPROTO_TCP:
+                       proto = "tcp";
+                       break;
+               case IPPROTO_UDP:
+                       proto = "udp";
+                       break;
+               default:
+                       snprintf(buf, sizeof(buf), "%u", nfss->client->cl_xprt->prot);
+                       proto = buf;
+       }
+       seq_printf(m, ",proto=%s", proto);
        seq_puts(m, ",addr=");
        seq_escape(m, nfss->hostname, " \t\n\\");
        return 0;
@@ -840,6 +853,11 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
                        filemap_fdatawait(inode->i_mapping);
                nfs_wb_all(inode);
        }
+       /*
+        * Return any delegations if we're going to change ACLs
+        */
+       if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0)
+               nfs_inode_return_delegation(inode);
        error = NFS_PROTO(inode)->setattr(dentry, &fattr, attr);
        if (error == 0)
                nfs_refresh_inode(inode, &fattr);
@@ -896,12 +914,10 @@ static int nfs_wait_on_inode(struct inode *inode)
        sigset_t oldmask;
        int error;
 
-       atomic_inc(&inode->i_count);
        rpc_clnt_sigmask(clnt, &oldmask);
        error = wait_on_bit_lock(&nfsi->flags, NFS_INO_REVALIDATING,
                                        nfs_wait_schedule, TASK_INTERRUPTIBLE);
        rpc_clnt_sigunmask(clnt, &oldmask);
-       iput(inode);
 
        return error;
 }
@@ -1119,7 +1135,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
         * We may need to keep the attributes marked as invalid if
         * we raced with nfs_end_attr_update().
         */
-       if (verifier == nfsi->cache_change_attribute)
+       if (time_after_eq(verifier, nfsi->cache_change_attribute))
                nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME);
        spin_unlock(&inode->i_lock);
 
@@ -1186,7 +1202,7 @@ void nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping)
                if (S_ISDIR(inode->i_mode)) {
                        memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
                        /* This ensures we revalidate child dentries */
-                       nfsi->cache_change_attribute++;
+                       nfsi->cache_change_attribute = jiffies;
                }
                spin_unlock(&inode->i_lock);
 
@@ -1226,7 +1242,7 @@ void nfs_end_data_update(struct inode *inode)
                        nfsi->cache_validity |= NFS_INO_INVALID_DATA;
                spin_unlock(&inode->i_lock);
        }
-       nfsi->cache_change_attribute ++;
+       nfsi->cache_change_attribute = jiffies;
        atomic_dec(&nfsi->data_updates);
 }
 
@@ -1245,10 +1261,6 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
        loff_t cur_size, new_isize;
        int data_unstable;
 
-       /* Do we hold a delegation? */
-       if (nfs_have_delegation(inode, FMODE_READ))
-               return 0;
-
        spin_lock(&inode->i_lock);
 
        /* Are we in the process of updating data on the server? */
@@ -1369,7 +1381,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign
        nfsi->read_cache_jiffies = fattr->timestamp;
 
        /* Are we racing with known updates of the metadata on the server? */
-       data_unstable = ! nfs_verify_change_attribute(inode, verifier);
+       data_unstable = ! (nfs_verify_change_attribute(inode, verifier) ||
+               (nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE));
 
        /* Check if our cached file size is stale */
        new_isize = nfs_size_to_loff_t(fattr->size);
@@ -1378,7 +1391,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign
                /* Do we perhaps have any outstanding writes? */
                if (nfsi->npages == 0) {
                        /* No, but did we race with nfs_end_data_update()? */
-                       if (verifier  ==  nfsi->cache_change_attribute) {
+                       if (time_after_eq(verifier,  nfsi->cache_change_attribute)) {
                                inode->i_size = new_isize;
                                invalid |= NFS_INO_INVALID_DATA;
                        }
@@ -1663,8 +1676,7 @@ static void nfs4_clear_inode(struct inode *inode)
        struct nfs_inode *nfsi = NFS_I(inode);
 
        /* If we are holding a delegation, return it! */
-       if (nfsi->delegation != NULL)
-               nfs_inode_return_delegation(inode);
+       nfs_inode_return_delegation(inode);
        /* First call standard NFS clear_inode() code */
        nfs_clear_inode(inode);
        /* Now clear out any remaining state */