diff options
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r-- | fs/nfs/nfs4proc.c | 47 |
1 files changed, 33 insertions, 14 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 8dde84b988d9..97bacccff579 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -193,14 +193,6 @@ static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dent | |||
193 | kunmap_atomic(start, KM_USER0); | 193 | kunmap_atomic(start, KM_USER0); |
194 | } | 194 | } |
195 | 195 | ||
196 | static int nfs4_wait_bit_killable(void *word) | ||
197 | { | ||
198 | if (fatal_signal_pending(current)) | ||
199 | return -ERESTARTSYS; | ||
200 | schedule(); | ||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | static int nfs4_wait_clnt_recover(struct nfs_client *clp) | 196 | static int nfs4_wait_clnt_recover(struct nfs_client *clp) |
205 | { | 197 | { |
206 | int res; | 198 | int res; |
@@ -208,7 +200,7 @@ static int nfs4_wait_clnt_recover(struct nfs_client *clp) | |||
208 | might_sleep(); | 200 | might_sleep(); |
209 | 201 | ||
210 | res = wait_on_bit(&clp->cl_state, NFS4CLNT_MANAGER_RUNNING, | 202 | res = wait_on_bit(&clp->cl_state, NFS4CLNT_MANAGER_RUNNING, |
211 | nfs4_wait_bit_killable, TASK_KILLABLE); | 203 | nfs_wait_bit_killable, TASK_KILLABLE); |
212 | return res; | 204 | return res; |
213 | } | 205 | } |
214 | 206 | ||
@@ -1439,7 +1431,7 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait) | |||
1439 | if (calldata->arg.seqid == NULL) | 1431 | if (calldata->arg.seqid == NULL) |
1440 | goto out_free_calldata; | 1432 | goto out_free_calldata; |
1441 | calldata->arg.fmode = 0; | 1433 | calldata->arg.fmode = 0; |
1442 | calldata->arg.bitmask = server->attr_bitmask; | 1434 | calldata->arg.bitmask = server->cache_consistency_bitmask; |
1443 | calldata->res.fattr = &calldata->fattr; | 1435 | calldata->res.fattr = &calldata->fattr; |
1444 | calldata->res.seqid = calldata->arg.seqid; | 1436 | calldata->res.seqid = calldata->arg.seqid; |
1445 | calldata->res.server = server; | 1437 | calldata->res.server = server; |
@@ -1580,6 +1572,15 @@ out_drop: | |||
1580 | return 0; | 1572 | return 0; |
1581 | } | 1573 | } |
1582 | 1574 | ||
1575 | void nfs4_close_context(struct nfs_open_context *ctx, int is_sync) | ||
1576 | { | ||
1577 | if (ctx->state == NULL) | ||
1578 | return; | ||
1579 | if (is_sync) | ||
1580 | nfs4_close_sync(&ctx->path, ctx->state, ctx->mode); | ||
1581 | else | ||
1582 | nfs4_close_state(&ctx->path, ctx->state, ctx->mode); | ||
1583 | } | ||
1583 | 1584 | ||
1584 | static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle) | 1585 | static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle) |
1585 | { | 1586 | { |
@@ -1600,6 +1601,9 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f | |||
1600 | server->caps |= NFS_CAP_HARDLINKS; | 1601 | server->caps |= NFS_CAP_HARDLINKS; |
1601 | if (res.has_symlinks != 0) | 1602 | if (res.has_symlinks != 0) |
1602 | server->caps |= NFS_CAP_SYMLINKS; | 1603 | server->caps |= NFS_CAP_SYMLINKS; |
1604 | memcpy(server->cache_consistency_bitmask, res.attr_bitmask, sizeof(server->cache_consistency_bitmask)); | ||
1605 | server->cache_consistency_bitmask[0] &= FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE; | ||
1606 | server->cache_consistency_bitmask[1] &= FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY; | ||
1603 | server->acl_bitmask = res.acl_bitmask; | 1607 | server->acl_bitmask = res.acl_bitmask; |
1604 | } | 1608 | } |
1605 | return status; | 1609 | return status; |
@@ -2079,7 +2083,7 @@ static void nfs4_proc_unlink_setup(struct rpc_message *msg, struct inode *dir) | |||
2079 | struct nfs_removeargs *args = msg->rpc_argp; | 2083 | struct nfs_removeargs *args = msg->rpc_argp; |
2080 | struct nfs_removeres *res = msg->rpc_resp; | 2084 | struct nfs_removeres *res = msg->rpc_resp; |
2081 | 2085 | ||
2082 | args->bitmask = server->attr_bitmask; | 2086 | args->bitmask = server->cache_consistency_bitmask; |
2083 | res->server = server; | 2087 | res->server = server; |
2084 | msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE]; | 2088 | msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE]; |
2085 | } | 2089 | } |
@@ -2323,7 +2327,7 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, | |||
2323 | .pages = &page, | 2327 | .pages = &page, |
2324 | .pgbase = 0, | 2328 | .pgbase = 0, |
2325 | .count = count, | 2329 | .count = count, |
2326 | .bitmask = NFS_SERVER(dentry->d_inode)->attr_bitmask, | 2330 | .bitmask = NFS_SERVER(dentry->d_inode)->cache_consistency_bitmask, |
2327 | }; | 2331 | }; |
2328 | struct nfs4_readdir_res res; | 2332 | struct nfs4_readdir_res res; |
2329 | struct rpc_message msg = { | 2333 | struct rpc_message msg = { |
@@ -2552,7 +2556,7 @@ static void nfs4_proc_write_setup(struct nfs_write_data *data, struct rpc_messag | |||
2552 | { | 2556 | { |
2553 | struct nfs_server *server = NFS_SERVER(data->inode); | 2557 | struct nfs_server *server = NFS_SERVER(data->inode); |
2554 | 2558 | ||
2555 | data->args.bitmask = server->attr_bitmask; | 2559 | data->args.bitmask = server->cache_consistency_bitmask; |
2556 | data->res.server = server; | 2560 | data->res.server = server; |
2557 | data->timestamp = jiffies; | 2561 | data->timestamp = jiffies; |
2558 | 2562 | ||
@@ -2575,7 +2579,7 @@ static void nfs4_proc_commit_setup(struct nfs_write_data *data, struct rpc_messa | |||
2575 | { | 2579 | { |
2576 | struct nfs_server *server = NFS_SERVER(data->inode); | 2580 | struct nfs_server *server = NFS_SERVER(data->inode); |
2577 | 2581 | ||
2578 | data->args.bitmask = server->attr_bitmask; | 2582 | data->args.bitmask = server->cache_consistency_bitmask; |
2579 | data->res.server = server; | 2583 | data->res.server = server; |
2580 | msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT]; | 2584 | msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT]; |
2581 | } | 2585 | } |
@@ -3678,6 +3682,19 @@ ssize_t nfs4_listxattr(struct dentry *dentry, char *buf, size_t buflen) | |||
3678 | return len; | 3682 | return len; |
3679 | } | 3683 | } |
3680 | 3684 | ||
3685 | static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr) | ||
3686 | { | ||
3687 | if (!((fattr->valid & NFS_ATTR_FATTR_FILEID) && | ||
3688 | (fattr->valid & NFS_ATTR_FATTR_FSID) && | ||
3689 | (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL))) | ||
3690 | return; | ||
3691 | |||
3692 | fattr->valid |= NFS_ATTR_FATTR_TYPE | NFS_ATTR_FATTR_MODE | | ||
3693 | NFS_ATTR_FATTR_NLINK; | ||
3694 | fattr->mode = S_IFDIR | S_IRUGO | S_IXUGO; | ||
3695 | fattr->nlink = 2; | ||
3696 | } | ||
3697 | |||
3681 | int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, | 3698 | int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, |
3682 | struct nfs4_fs_locations *fs_locations, struct page *page) | 3699 | struct nfs4_fs_locations *fs_locations, struct page *page) |
3683 | { | 3700 | { |
@@ -3704,6 +3721,7 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, | |||
3704 | fs_locations->server = server; | 3721 | fs_locations->server = server; |
3705 | fs_locations->nlocations = 0; | 3722 | fs_locations->nlocations = 0; |
3706 | status = rpc_call_sync(server->client, &msg, 0); | 3723 | status = rpc_call_sync(server->client, &msg, 0); |
3724 | nfs_fixup_referral_attributes(&fs_locations->fattr); | ||
3707 | dprintk("%s: returned status = %d\n", __func__, status); | 3725 | dprintk("%s: returned status = %d\n", __func__, status); |
3708 | return status; | 3726 | return status; |
3709 | } | 3727 | } |
@@ -3767,6 +3785,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = { | |||
3767 | .commit_done = nfs4_commit_done, | 3785 | .commit_done = nfs4_commit_done, |
3768 | .lock = nfs4_proc_lock, | 3786 | .lock = nfs4_proc_lock, |
3769 | .clear_acl_cache = nfs4_zap_acl_attr, | 3787 | .clear_acl_cache = nfs4_zap_acl_attr, |
3788 | .close_context = nfs4_close_context, | ||
3770 | }; | 3789 | }; |
3771 | 3790 | ||
3772 | /* | 3791 | /* |