]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/nfs/nfs4proc.c
NFS: Throttle page dirtying while we're flushing to disk
[linux-2.6-omap-h63xx.git] / fs / nfs / nfs4proc.c
index 8dde84b988d9cd349604eb4663a70fc4333fe367..95f171e7e05a19a9afe046620f37e5b4e9457a54 100644 (file)
@@ -193,14 +193,6 @@ static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dent
        kunmap_atomic(start, KM_USER0);
 }
 
-static int nfs4_wait_bit_killable(void *word)
-{
-       if (fatal_signal_pending(current))
-               return -ERESTARTSYS;
-       schedule();
-       return 0;
-}
-
 static int nfs4_wait_clnt_recover(struct nfs_client *clp)
 {
        int res;
@@ -208,7 +200,7 @@ static int nfs4_wait_clnt_recover(struct nfs_client *clp)
        might_sleep();
 
        res = wait_on_bit(&clp->cl_state, NFS4CLNT_MANAGER_RUNNING,
-                       nfs4_wait_bit_killable, TASK_KILLABLE);
+                       nfs_wait_bit_killable, TASK_KILLABLE);
        return res;
 }
 
@@ -1439,7 +1431,7 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
        if (calldata->arg.seqid == NULL)
                goto out_free_calldata;
        calldata->arg.fmode = 0;
-       calldata->arg.bitmask = server->attr_bitmask;
+       calldata->arg.bitmask = server->cache_consistency_bitmask;
        calldata->res.fattr = &calldata->fattr;
        calldata->res.seqid = calldata->arg.seqid;
        calldata->res.server = server;
@@ -1600,6 +1592,9 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
                        server->caps |= NFS_CAP_HARDLINKS;
                if (res.has_symlinks != 0)
                        server->caps |= NFS_CAP_SYMLINKS;
+               memcpy(server->cache_consistency_bitmask, res.attr_bitmask, sizeof(server->cache_consistency_bitmask));
+               server->cache_consistency_bitmask[0] &= FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE;
+               server->cache_consistency_bitmask[1] &= FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY;
                server->acl_bitmask = res.acl_bitmask;
        }
        return status;
@@ -2079,7 +2074,7 @@ static void nfs4_proc_unlink_setup(struct rpc_message *msg, struct inode *dir)
        struct nfs_removeargs *args = msg->rpc_argp;
        struct nfs_removeres *res = msg->rpc_resp;
 
-       args->bitmask = server->attr_bitmask;
+       args->bitmask = server->cache_consistency_bitmask;
        res->server = server;
        msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE];
 }
@@ -2323,7 +2318,7 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
                .pages = &page,
                .pgbase = 0,
                .count = count,
-               .bitmask = NFS_SERVER(dentry->d_inode)->attr_bitmask,
+               .bitmask = NFS_SERVER(dentry->d_inode)->cache_consistency_bitmask,
        };
        struct nfs4_readdir_res res;
        struct rpc_message msg = {
@@ -2552,7 +2547,7 @@ static void nfs4_proc_write_setup(struct nfs_write_data *data, struct rpc_messag
 {
        struct nfs_server *server = NFS_SERVER(data->inode);
 
-       data->args.bitmask = server->attr_bitmask;
+       data->args.bitmask = server->cache_consistency_bitmask;
        data->res.server = server;
        data->timestamp   = jiffies;
 
@@ -2575,7 +2570,7 @@ static void nfs4_proc_commit_setup(struct nfs_write_data *data, struct rpc_messa
 {
        struct nfs_server *server = NFS_SERVER(data->inode);
        
-       data->args.bitmask = server->attr_bitmask;
+       data->args.bitmask = server->cache_consistency_bitmask;
        data->res.server = server;
        msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT];
 }
@@ -3678,6 +3673,19 @@ ssize_t nfs4_listxattr(struct dentry *dentry, char *buf, size_t buflen)
        return len;
 }
 
+static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr)
+{
+       if (!((fattr->valid & NFS_ATTR_FATTR_FILEID) &&
+               (fattr->valid & NFS_ATTR_FATTR_FSID) &&
+               (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL)))
+               return;
+
+       fattr->valid |= NFS_ATTR_FATTR_TYPE | NFS_ATTR_FATTR_MODE |
+               NFS_ATTR_FATTR_NLINK;
+       fattr->mode = S_IFDIR | S_IRUGO | S_IXUGO;
+       fattr->nlink = 2;
+}
+
 int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
                struct nfs4_fs_locations *fs_locations, struct page *page)
 {
@@ -3704,6 +3712,7 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
        fs_locations->server = server;
        fs_locations->nlocations = 0;
        status = rpc_call_sync(server->client, &msg, 0);
+       nfs_fixup_referral_attributes(&fs_locations->fattr);
        dprintk("%s: returned status = %d\n", __func__, status);
        return status;
 }