aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/inode.c8
-rw-r--r--fs/nfs/nfs4_fs.h2
-rw-r--r--fs/nfs/nfs4proc.c6
-rw-r--r--fs/nfs/nfs4state.c14
-rw-r--r--fs/nfs/nfs4xdr.c6
-rw-r--r--fs/nfs/pagelist.c4
-rw-r--r--fs/nfs/write.c10
-rw-r--r--include/linux/nfs_fs.h8
8 files changed, 42 insertions, 16 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index b5e2913dff2d..126a4cbbb98f 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -547,8 +547,8 @@ EXPORT_SYMBOL_GPL(nfs_getattr);
547static void nfs_init_lock_context(struct nfs_lock_context *l_ctx) 547static void nfs_init_lock_context(struct nfs_lock_context *l_ctx)
548{ 548{
549 atomic_set(&l_ctx->count, 1); 549 atomic_set(&l_ctx->count, 1);
550 l_ctx->lockowner = current->files; 550 l_ctx->lockowner.l_owner = current->files;
551 l_ctx->pid = current->tgid; 551 l_ctx->lockowner.l_pid = current->tgid;
552 INIT_LIST_HEAD(&l_ctx->list); 552 INIT_LIST_HEAD(&l_ctx->list);
553} 553}
554 554
@@ -557,9 +557,9 @@ static struct nfs_lock_context *__nfs_find_lock_context(struct nfs_open_context
557 struct nfs_lock_context *pos; 557 struct nfs_lock_context *pos;
558 558
559 list_for_each_entry(pos, &ctx->lock_context.list, list) { 559 list_for_each_entry(pos, &ctx->lock_context.list, list) {
560 if (pos->lockowner != current->files) 560 if (pos->lockowner.l_owner != current->files)
561 continue; 561 continue;
562 if (pos->pid != current->tgid) 562 if (pos->lockowner.l_pid != current->tgid)
563 continue; 563 continue;
564 atomic_inc(&pos->count); 564 atomic_inc(&pos->count);
565 return pos; 565 return pos;
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index da0618aeeadb..d95e25ec3574 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -351,7 +351,7 @@ extern void nfs41_handle_server_scope(struct nfs_client *,
351extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp); 351extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp);
352extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl); 352extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl);
353extern void nfs4_select_rw_stateid(nfs4_stateid *, struct nfs4_state *, 353extern void nfs4_select_rw_stateid(nfs4_stateid *, struct nfs4_state *,
354 fmode_t, fl_owner_t, pid_t); 354 fmode_t, const struct nfs_lockowner *);
355 355
356extern struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter, gfp_t gfp_mask); 356extern struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter, gfp_t gfp_mask);
357extern int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task); 357extern int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index ddfebb128017..f19ea4f0f0c5 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2013,8 +2013,12 @@ static int _nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
2013 nfs_fattr_init(fattr); 2013 nfs_fattr_init(fattr);
2014 2014
2015 if (state != NULL) { 2015 if (state != NULL) {
2016 struct nfs_lockowner lockowner = {
2017 .l_owner = current->files,
2018 .l_pid = current->tgid,
2019 };
2016 nfs4_select_rw_stateid(&arg.stateid, state, FMODE_WRITE, 2020 nfs4_select_rw_stateid(&arg.stateid, state, FMODE_WRITE,
2017 current->files, current->tgid); 2021 &lockowner);
2018 } else if (nfs4_copy_delegation_stateid(&arg.stateid, inode, 2022 } else if (nfs4_copy_delegation_stateid(&arg.stateid, inode,
2019 FMODE_WRITE)) { 2023 FMODE_WRITE)) {
2020 /* Use that stateid */ 2024 /* Use that stateid */
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 55148def5540..03a4e7825f3b 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -911,14 +911,22 @@ int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl)
911} 911}
912 912
913static bool nfs4_copy_lock_stateid(nfs4_stateid *dst, struct nfs4_state *state, 913static bool nfs4_copy_lock_stateid(nfs4_stateid *dst, struct nfs4_state *state,
914 fl_owner_t fl_owner, pid_t fl_pid) 914 const struct nfs_lockowner *lockowner)
915{ 915{
916 struct nfs4_lock_state *lsp; 916 struct nfs4_lock_state *lsp;
917 fl_owner_t fl_owner;
918 pid_t fl_pid;
917 bool ret = false; 919 bool ret = false;
918 920
921
922 if (lockowner == NULL)
923 goto out;
924
919 if (test_bit(LK_STATE_IN_USE, &state->flags) == 0) 925 if (test_bit(LK_STATE_IN_USE, &state->flags) == 0)
920 goto out; 926 goto out;
921 927
928 fl_owner = lockowner->l_owner;
929 fl_pid = lockowner->l_pid;
922 spin_lock(&state->state_lock); 930 spin_lock(&state->state_lock);
923 lsp = __nfs4_find_lock_state(state, fl_owner, fl_pid, NFS4_ANY_LOCK_TYPE); 931 lsp = __nfs4_find_lock_state(state, fl_owner, fl_pid, NFS4_ANY_LOCK_TYPE);
924 if (lsp != NULL && (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0) { 932 if (lsp != NULL && (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0) {
@@ -946,11 +954,11 @@ static void nfs4_copy_open_stateid(nfs4_stateid *dst, struct nfs4_state *state)
946 * requests. 954 * requests.
947 */ 955 */
948void nfs4_select_rw_stateid(nfs4_stateid *dst, struct nfs4_state *state, 956void nfs4_select_rw_stateid(nfs4_stateid *dst, struct nfs4_state *state,
949 fmode_t fmode, fl_owner_t fl_owner, pid_t fl_pid) 957 fmode_t fmode, const struct nfs_lockowner *lockowner)
950{ 958{
951 if (nfs4_copy_delegation_stateid(dst, state->inode, fmode)) 959 if (nfs4_copy_delegation_stateid(dst, state->inode, fmode))
952 return; 960 return;
953 if (nfs4_copy_lock_stateid(dst, state, fl_owner, fl_pid)) 961 if (nfs4_copy_lock_stateid(dst, state, lockowner))
954 return; 962 return;
955 nfs4_copy_open_stateid(dst, state); 963 nfs4_copy_open_stateid(dst, state);
956} 964}
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index a756349b0fa4..7ab29abb3160 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -1509,8 +1509,12 @@ static void encode_open_stateid(struct xdr_stream *xdr,
1509 nfs4_stateid stateid; 1509 nfs4_stateid stateid;
1510 1510
1511 if (ctx->state != NULL) { 1511 if (ctx->state != NULL) {
1512 const struct nfs_lockowner *lockowner = NULL;
1513
1514 if (l_ctx != NULL)
1515 lockowner = &l_ctx->lockowner;
1512 nfs4_select_rw_stateid(&stateid, ctx->state, 1516 nfs4_select_rw_stateid(&stateid, ctx->state,
1513 fmode, l_ctx->lockowner, l_ctx->pid); 1517 fmode, lockowner);
1514 if (zero_seqid) 1518 if (zero_seqid)
1515 stateid.seqid = 0; 1519 stateid.seqid = 0;
1516 encode_nfs4_stateid(xdr, &stateid); 1520 encode_nfs4_stateid(xdr, &stateid);
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index dfd764bd943d..e56e846e9d2d 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -292,7 +292,9 @@ static bool nfs_can_coalesce_requests(struct nfs_page *prev,
292{ 292{
293 if (req->wb_context->cred != prev->wb_context->cred) 293 if (req->wb_context->cred != prev->wb_context->cred)
294 return false; 294 return false;
295 if (req->wb_lock_context->lockowner != prev->wb_lock_context->lockowner) 295 if (req->wb_lock_context->lockowner.l_owner != prev->wb_lock_context->lockowner.l_owner)
296 return false;
297 if (req->wb_lock_context->lockowner.l_pid != prev->wb_lock_context->lockowner.l_pid)
296 return false; 298 return false;
297 if (req->wb_context->state != prev->wb_context->state) 299 if (req->wb_context->state != prev->wb_context->state)
298 return false; 300 return false;
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index e3b55372726c..e1b5fe4d873a 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -846,6 +846,7 @@ static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page,
846int nfs_flush_incompatible(struct file *file, struct page *page) 846int nfs_flush_incompatible(struct file *file, struct page *page)
847{ 847{
848 struct nfs_open_context *ctx = nfs_file_open_context(file); 848 struct nfs_open_context *ctx = nfs_file_open_context(file);
849 struct nfs_lock_context *l_ctx;
849 struct nfs_page *req; 850 struct nfs_page *req;
850 int do_flush, status; 851 int do_flush, status;
851 /* 852 /*
@@ -860,9 +861,12 @@ int nfs_flush_incompatible(struct file *file, struct page *page)
860 req = nfs_page_find_request(page); 861 req = nfs_page_find_request(page);
861 if (req == NULL) 862 if (req == NULL)
862 return 0; 863 return 0;
863 do_flush = req->wb_page != page || req->wb_context != ctx || 864 l_ctx = req->wb_lock_context;
864 req->wb_lock_context->lockowner != current->files || 865 do_flush = req->wb_page != page || req->wb_context != ctx;
865 req->wb_lock_context->pid != current->tgid; 866 if (l_ctx) {
867 do_flush |= l_ctx->lockowner.l_owner != current->files
868 || l_ctx->lockowner.l_pid != current->tgid;
869 }
866 nfs_release_request(req); 870 nfs_release_request(req);
867 if (!do_flush) 871 if (!do_flush)
868 return 0; 872 return 0;
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 4b03f56e280e..869eac0c2635 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -81,12 +81,16 @@ struct nfs_access_entry {
81 int mask; 81 int mask;
82}; 82};
83 83
84struct nfs_lockowner {
85 fl_owner_t l_owner;
86 pid_t l_pid;
87};
88
84struct nfs_lock_context { 89struct nfs_lock_context {
85 atomic_t count; 90 atomic_t count;
86 struct list_head list; 91 struct list_head list;
87 struct nfs_open_context *open_context; 92 struct nfs_open_context *open_context;
88 fl_owner_t lockowner; 93 struct nfs_lockowner lockowner;
89 pid_t pid;
90}; 94};
91 95
92struct nfs4_state; 96struct nfs4_state;