aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/delegation.c6
-rw-r--r--fs/nfs/direct.c36
-rw-r--r--fs/nfs/file.c19
-rw-r--r--fs/nfs/mount_clnt.c4
-rw-r--r--fs/nfs/nfs4proc.c9
-rw-r--r--fs/nfs/nfs4state.c16
-rw-r--r--fs/nfs/pagelist.c8
7 files changed, 58 insertions, 40 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index b9c3c43cea1d..98e8e35c4408 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -24,8 +24,6 @@
24 24
25static void nfs_do_free_delegation(struct nfs_delegation *delegation) 25static void nfs_do_free_delegation(struct nfs_delegation *delegation)
26{ 26{
27 if (delegation->cred)
28 put_rpccred(delegation->cred);
29 kfree(delegation); 27 kfree(delegation);
30} 28}
31 29
@@ -38,6 +36,10 @@ static void nfs_free_delegation_callback(struct rcu_head *head)
38 36
39static void nfs_free_delegation(struct nfs_delegation *delegation) 37static void nfs_free_delegation(struct nfs_delegation *delegation)
40{ 38{
39 if (delegation->cred) {
40 put_rpccred(delegation->cred);
41 delegation->cred = NULL;
42 }
41 call_rcu(&delegation->rcu, nfs_free_delegation_callback); 43 call_rcu(&delegation->rcu, nfs_free_delegation_callback);
42} 44}
43 45
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 064a80961677..e0e9d49773bd 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -407,15 +407,18 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq,
407 pos += vec->iov_len; 407 pos += vec->iov_len;
408 } 408 }
409 409
410 /*
411 * If no bytes were started, return the error, and let the
412 * generic layer handle the completion.
413 */
414 if (requested_bytes == 0) {
415 nfs_direct_req_release(dreq);
416 return result < 0 ? result : -EIO;
417 }
418
410 if (put_dreq(dreq)) 419 if (put_dreq(dreq))
411 nfs_direct_complete(dreq); 420 nfs_direct_complete(dreq);
412 421 return 0;
413 if (requested_bytes != 0)
414 return 0;
415
416 if (result < 0)
417 return result;
418 return -EIO;
419} 422}
420 423
421static ssize_t nfs_direct_read(struct kiocb *iocb, const struct iovec *iov, 424static ssize_t nfs_direct_read(struct kiocb *iocb, const struct iovec *iov,
@@ -841,15 +844,18 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
841 pos += vec->iov_len; 844 pos += vec->iov_len;
842 } 845 }
843 846
847 /*
848 * If no bytes were started, return the error, and let the
849 * generic layer handle the completion.
850 */
851 if (requested_bytes == 0) {
852 nfs_direct_req_release(dreq);
853 return result < 0 ? result : -EIO;
854 }
855
844 if (put_dreq(dreq)) 856 if (put_dreq(dreq))
845 nfs_direct_write_complete(dreq, dreq->inode); 857 nfs_direct_write_complete(dreq, dreq->inode);
846 858 return 0;
847 if (requested_bytes != 0)
848 return 0;
849
850 if (result < 0)
851 return result;
852 return -EIO;
853} 859}
854 860
855static ssize_t nfs_direct_write(struct kiocb *iocb, const struct iovec *iov, 861static ssize_t nfs_direct_write(struct kiocb *iocb, const struct iovec *iov,
@@ -873,7 +879,7 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, const struct iovec *iov,
873 dreq->inode = inode; 879 dreq->inode = inode;
874 dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp)); 880 dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp));
875 dreq->l_ctx = nfs_get_lock_context(dreq->ctx); 881 dreq->l_ctx = nfs_get_lock_context(dreq->ctx);
876 if (dreq->l_ctx != NULL) 882 if (dreq->l_ctx == NULL)
877 goto out_release; 883 goto out_release;
878 if (!is_sync_kiocb(iocb)) 884 if (!is_sync_kiocb(iocb))
879 dreq->iocb = iocb; 885 dreq->iocb = iocb;
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 05bf3c0dc751..22a185b328ef 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -551,7 +551,7 @@ static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
551 struct file *filp = vma->vm_file; 551 struct file *filp = vma->vm_file;
552 struct dentry *dentry = filp->f_path.dentry; 552 struct dentry *dentry = filp->f_path.dentry;
553 unsigned pagelen; 553 unsigned pagelen;
554 int ret = -EINVAL; 554 int ret = VM_FAULT_NOPAGE;
555 struct address_space *mapping; 555 struct address_space *mapping;
556 556
557 dfprintk(PAGECACHE, "NFS: vm_page_mkwrite(%s/%s(%ld), offset %lld)\n", 557 dfprintk(PAGECACHE, "NFS: vm_page_mkwrite(%s/%s(%ld), offset %lld)\n",
@@ -567,21 +567,20 @@ static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
567 if (mapping != dentry->d_inode->i_mapping) 567 if (mapping != dentry->d_inode->i_mapping)
568 goto out_unlock; 568 goto out_unlock;
569 569
570 ret = 0;
571 pagelen = nfs_page_length(page); 570 pagelen = nfs_page_length(page);
572 if (pagelen == 0) 571 if (pagelen == 0)
573 goto out_unlock; 572 goto out_unlock;
574 573
575 ret = nfs_flush_incompatible(filp, page); 574 ret = VM_FAULT_LOCKED;
576 if (ret != 0) 575 if (nfs_flush_incompatible(filp, page) == 0 &&
577 goto out_unlock; 576 nfs_updatepage(filp, page, 0, pagelen) == 0)
577 goto out;
578 578
579 ret = nfs_updatepage(filp, page, 0, pagelen); 579 ret = VM_FAULT_SIGBUS;
580out_unlock: 580out_unlock:
581 if (!ret)
582 return VM_FAULT_LOCKED;
583 unlock_page(page); 581 unlock_page(page);
584 return VM_FAULT_SIGBUS; 582out:
583 return ret;
585} 584}
586 585
587static const struct vm_operations_struct nfs_file_vm_ops = { 586static const struct vm_operations_struct nfs_file_vm_ops = {
@@ -688,6 +687,7 @@ static int do_getlk(struct file *filp, int cmd, struct file_lock *fl)
688{ 687{
689 struct inode *inode = filp->f_mapping->host; 688 struct inode *inode = filp->f_mapping->host;
690 int status = 0; 689 int status = 0;
690 unsigned int saved_type = fl->fl_type;
691 691
692 /* Try local locking first */ 692 /* Try local locking first */
693 posix_test_lock(filp, fl); 693 posix_test_lock(filp, fl);
@@ -695,6 +695,7 @@ static int do_getlk(struct file *filp, int cmd, struct file_lock *fl)
695 /* found a conflict */ 695 /* found a conflict */
696 goto out; 696 goto out;
697 } 697 }
698 fl->fl_type = saved_type;
698 699
699 if (nfs_have_delegation(inode, FMODE_READ)) 700 if (nfs_have_delegation(inode, FMODE_READ))
700 goto out_noconflict; 701 goto out_noconflict;
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
index 59047f8d7d72..3dde50c093b5 100644
--- a/fs/nfs/mount_clnt.c
+++ b/fs/nfs/mount_clnt.c
@@ -503,13 +503,13 @@ static struct rpc_procinfo mnt3_procedures[] = {
503 503
504static struct rpc_version mnt_version1 = { 504static struct rpc_version mnt_version1 = {
505 .number = 1, 505 .number = 1,
506 .nrprocs = 2, 506 .nrprocs = ARRAY_SIZE(mnt_procedures),
507 .procs = mnt_procedures, 507 .procs = mnt_procedures,
508}; 508};
509 509
510static struct rpc_version mnt_version3 = { 510static struct rpc_version mnt_version3 = {
511 .number = 3, 511 .number = 3,
512 .nrprocs = 2, 512 .nrprocs = ARRAY_SIZE(mnt3_procedures),
513 .procs = mnt3_procedures, 513 .procs = mnt3_procedures,
514}; 514};
515 515
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 089da5b5d20a..74aa54e1712e 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -255,9 +255,6 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode,
255 nfs4_state_mark_reclaim_nograce(clp, state); 255 nfs4_state_mark_reclaim_nograce(clp, state);
256 goto do_state_recovery; 256 goto do_state_recovery;
257 case -NFS4ERR_STALE_STATEID: 257 case -NFS4ERR_STALE_STATEID:
258 if (state == NULL)
259 break;
260 nfs4_state_mark_reclaim_reboot(clp, state);
261 case -NFS4ERR_STALE_CLIENTID: 258 case -NFS4ERR_STALE_CLIENTID:
262 case -NFS4ERR_EXPIRED: 259 case -NFS4ERR_EXPIRED:
263 goto do_state_recovery; 260 goto do_state_recovery;
@@ -1120,6 +1117,7 @@ static int nfs4_open_recover(struct nfs4_opendata *opendata, struct nfs4_state *
1120 clear_bit(NFS_DELEGATED_STATE, &state->flags); 1117 clear_bit(NFS_DELEGATED_STATE, &state->flags);
1121 smp_rmb(); 1118 smp_rmb();
1122 if (state->n_rdwr != 0) { 1119 if (state->n_rdwr != 0) {
1120 clear_bit(NFS_O_RDWR_STATE, &state->flags);
1123 ret = nfs4_open_recover_helper(opendata, FMODE_READ|FMODE_WRITE, &newstate); 1121 ret = nfs4_open_recover_helper(opendata, FMODE_READ|FMODE_WRITE, &newstate);
1124 if (ret != 0) 1122 if (ret != 0)
1125 return ret; 1123 return ret;
@@ -1127,6 +1125,7 @@ static int nfs4_open_recover(struct nfs4_opendata *opendata, struct nfs4_state *
1127 return -ESTALE; 1125 return -ESTALE;
1128 } 1126 }
1129 if (state->n_wronly != 0) { 1127 if (state->n_wronly != 0) {
1128 clear_bit(NFS_O_WRONLY_STATE, &state->flags);
1130 ret = nfs4_open_recover_helper(opendata, FMODE_WRITE, &newstate); 1129 ret = nfs4_open_recover_helper(opendata, FMODE_WRITE, &newstate);
1131 if (ret != 0) 1130 if (ret != 0)
1132 return ret; 1131 return ret;
@@ -1134,6 +1133,7 @@ static int nfs4_open_recover(struct nfs4_opendata *opendata, struct nfs4_state *
1134 return -ESTALE; 1133 return -ESTALE;
1135 } 1134 }
1136 if (state->n_rdonly != 0) { 1135 if (state->n_rdonly != 0) {
1136 clear_bit(NFS_O_RDONLY_STATE, &state->flags);
1137 ret = nfs4_open_recover_helper(opendata, FMODE_READ, &newstate); 1137 ret = nfs4_open_recover_helper(opendata, FMODE_READ, &newstate);
1138 if (ret != 0) 1138 if (ret != 0)
1139 return ret; 1139 return ret;
@@ -3490,9 +3490,6 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
3490 nfs4_state_mark_reclaim_nograce(clp, state); 3490 nfs4_state_mark_reclaim_nograce(clp, state);
3491 goto do_state_recovery; 3491 goto do_state_recovery;
3492 case -NFS4ERR_STALE_STATEID: 3492 case -NFS4ERR_STALE_STATEID:
3493 if (state == NULL)
3494 break;
3495 nfs4_state_mark_reclaim_reboot(clp, state);
3496 case -NFS4ERR_STALE_CLIENTID: 3493 case -NFS4ERR_STALE_CLIENTID:
3497 case -NFS4ERR_EXPIRED: 3494 case -NFS4ERR_EXPIRED:
3498 goto do_state_recovery; 3495 goto do_state_recovery;
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 3e2f19b04c06..940cf7c070af 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -1138,16 +1138,14 @@ static void nfs4_reclaim_complete(struct nfs_client *clp,
1138 (void)ops->reclaim_complete(clp); 1138 (void)ops->reclaim_complete(clp);
1139} 1139}
1140 1140
1141static void nfs4_state_end_reclaim_reboot(struct nfs_client *clp) 1141static int nfs4_state_clear_reclaim_reboot(struct nfs_client *clp)
1142{ 1142{
1143 struct nfs4_state_owner *sp; 1143 struct nfs4_state_owner *sp;
1144 struct rb_node *pos; 1144 struct rb_node *pos;
1145 struct nfs4_state *state; 1145 struct nfs4_state *state;
1146 1146
1147 if (!test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) 1147 if (!test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state))
1148 return; 1148 return 0;
1149
1150 nfs4_reclaim_complete(clp, clp->cl_mvops->reboot_recovery_ops);
1151 1149
1152 for (pos = rb_first(&clp->cl_state_owners); pos != NULL; pos = rb_next(pos)) { 1150 for (pos = rb_first(&clp->cl_state_owners); pos != NULL; pos = rb_next(pos)) {
1153 sp = rb_entry(pos, struct nfs4_state_owner, so_client_node); 1151 sp = rb_entry(pos, struct nfs4_state_owner, so_client_node);
@@ -1161,6 +1159,14 @@ static void nfs4_state_end_reclaim_reboot(struct nfs_client *clp)
1161 } 1159 }
1162 1160
1163 nfs_delegation_reap_unclaimed(clp); 1161 nfs_delegation_reap_unclaimed(clp);
1162 return 1;
1163}
1164
1165static void nfs4_state_end_reclaim_reboot(struct nfs_client *clp)
1166{
1167 if (!nfs4_state_clear_reclaim_reboot(clp))
1168 return;
1169 nfs4_reclaim_complete(clp, clp->cl_mvops->reboot_recovery_ops);
1164} 1170}
1165 1171
1166static void nfs_delegation_clear_all(struct nfs_client *clp) 1172static void nfs_delegation_clear_all(struct nfs_client *clp)
@@ -1187,7 +1193,7 @@ static int nfs4_recovery_handle_error(struct nfs_client *clp, int error)
1187 case -NFS4ERR_STALE_CLIENTID: 1193 case -NFS4ERR_STALE_CLIENTID:
1188 case -NFS4ERR_LEASE_MOVED: 1194 case -NFS4ERR_LEASE_MOVED:
1189 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); 1195 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1190 nfs4_state_end_reclaim_reboot(clp); 1196 nfs4_state_clear_reclaim_reboot(clp);
1191 nfs4_state_start_reclaim_reboot(clp); 1197 nfs4_state_start_reclaim_reboot(clp);
1192 break; 1198 break;
1193 case -NFS4ERR_EXPIRED: 1199 case -NFS4ERR_EXPIRED:
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 919490232e17..137b549e63db 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -65,6 +65,13 @@ nfs_create_request(struct nfs_open_context *ctx, struct inode *inode,
65 if (req == NULL) 65 if (req == NULL)
66 return ERR_PTR(-ENOMEM); 66 return ERR_PTR(-ENOMEM);
67 67
68 /* get lock context early so we can deal with alloc failures */
69 req->wb_lock_context = nfs_get_lock_context(ctx);
70 if (req->wb_lock_context == NULL) {
71 nfs_page_free(req);
72 return ERR_PTR(-ENOMEM);
73 }
74
68 /* Initialize the request struct. Initially, we assume a 75 /* Initialize the request struct. Initially, we assume a
69 * long write-back delay. This will be adjusted in 76 * long write-back delay. This will be adjusted in
70 * update_nfs_request below if the region is not locked. */ 77 * update_nfs_request below if the region is not locked. */
@@ -79,7 +86,6 @@ nfs_create_request(struct nfs_open_context *ctx, struct inode *inode,
79 req->wb_pgbase = offset; 86 req->wb_pgbase = offset;
80 req->wb_bytes = count; 87 req->wb_bytes = count;
81 req->wb_context = get_nfs_open_context(ctx); 88 req->wb_context = get_nfs_open_context(ctx);
82 req->wb_lock_context = nfs_get_lock_context(ctx);
83 kref_init(&req->wb_kref); 89 kref_init(&req->wb_kref);
84 return req; 90 return req;
85} 91}