aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorJeff Layton <jlayton@primarydata.com>2015-01-16 15:05:55 -0500
committerJeff Layton <jeff.layton@primarydata.com>2015-01-16 16:08:16 -0500
commitbd61e0a9c852de2d705b6f1bb2cc54c5774db570 (patch)
tree67a583912923f2ae621bddf94fbba8816cb0e49d /fs/nfs
parent5263e31e452fb84138b9bee061d5c06c0f359fea (diff)
locks: convert posix locks to file_lock_context
Signed-off-by: Jeff Layton <jlayton@primarydata.com> Acked-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/delegation.c28
-rw-r--r--fs/nfs/nfs4state.c52
-rw-r--r--fs/nfs/pagelist.c8
-rw-r--r--fs/nfs/write.c30
4 files changed, 35 insertions, 83 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index 9f9f67b17e2b..3fb1caa3874d 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -85,17 +85,17 @@ static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_
85{ 85{
86 struct inode *inode = state->inode; 86 struct inode *inode = state->inode;
87 struct file_lock *fl; 87 struct file_lock *fl;
88 struct file_lock_context *flctx; 88 struct file_lock_context *flctx = inode->i_flctx;
89 struct list_head *list;
89 int status = 0; 90 int status = 0;
90 91
91 if (inode->i_flock == NULL && inode->i_flctx == NULL) 92 if (flctx == NULL)
92 goto out; 93 goto out;
93 94
94 /* Protect inode->i_flock using the i_lock */ 95 list = &flctx->flc_posix;
95 spin_lock(&inode->i_lock); 96 spin_lock(&inode->i_lock);
96 for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { 97restart:
97 if (!(fl->fl_flags & (FL_POSIX))) 98 list_for_each_entry(fl, list, fl_list) {
98 continue;
99 if (nfs_file_open_context(fl->fl_file) != ctx) 99 if (nfs_file_open_context(fl->fl_file) != ctx)
100 continue; 100 continue;
101 spin_unlock(&inode->i_lock); 101 spin_unlock(&inode->i_lock);
@@ -104,19 +104,9 @@ static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_
104 goto out; 104 goto out;
105 spin_lock(&inode->i_lock); 105 spin_lock(&inode->i_lock);
106 } 106 }
107 107 if (list == &flctx->flc_posix) {
108 flctx = inode->i_flctx; 108 list = &flctx->flc_flock;
109 if (flctx) { 109 goto restart;
110 list_for_each_entry(fl, &flctx->flc_flock, fl_list) {
111 if (nfs_file_open_context(fl->fl_file) != ctx)
112 continue;
113 spin_unlock(&inode->i_lock);
114 status = nfs4_lock_delegation_recall(fl, state,
115 stateid);
116 if (status < 0)
117 goto out;
118 spin_lock(&inode->i_lock);
119 }
120 } 110 }
121 spin_unlock(&inode->i_lock); 111 spin_unlock(&inode->i_lock);
122out: 112out:
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 65c404bf61ae..6084c267f3a0 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -1367,53 +1367,18 @@ static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_
1367 struct file_lock *fl; 1367 struct file_lock *fl;
1368 int status = 0; 1368 int status = 0;
1369 struct file_lock_context *flctx = inode->i_flctx; 1369 struct file_lock_context *flctx = inode->i_flctx;
1370 struct list_head *list;
1370 1371
1371 if (inode->i_flock == NULL && flctx == NULL) 1372 if (flctx == NULL)
1372 return 0; 1373 return 0;
1373 1374
1375 list = &flctx->flc_posix;
1376
1374 /* Guard against delegation returns and new lock/unlock calls */ 1377 /* Guard against delegation returns and new lock/unlock calls */
1375 down_write(&nfsi->rwsem); 1378 down_write(&nfsi->rwsem);
1376 /* Protect inode->i_flock using the BKL */
1377 spin_lock(&inode->i_lock); 1379 spin_lock(&inode->i_lock);
1378 for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { 1380restart:
1379 if (!(fl->fl_flags & FL_POSIX)) 1381 list_for_each_entry(fl, list, fl_list) {
1380 continue;
1381 if (nfs_file_open_context(fl->fl_file)->state != state)
1382 continue;
1383 spin_unlock(&inode->i_lock);
1384 status = ops->recover_lock(state, fl);
1385 switch (status) {
1386 case 0:
1387 break;
1388 case -ESTALE:
1389 case -NFS4ERR_ADMIN_REVOKED:
1390 case -NFS4ERR_STALE_STATEID:
1391 case -NFS4ERR_BAD_STATEID:
1392 case -NFS4ERR_EXPIRED:
1393 case -NFS4ERR_NO_GRACE:
1394 case -NFS4ERR_STALE_CLIENTID:
1395 case -NFS4ERR_BADSESSION:
1396 case -NFS4ERR_BADSLOT:
1397 case -NFS4ERR_BAD_HIGH_SLOT:
1398 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
1399 goto out;
1400 default:
1401 printk(KERN_ERR "NFS: %s: unhandled error %d\n",
1402 __func__, status);
1403 case -ENOMEM:
1404 case -NFS4ERR_DENIED:
1405 case -NFS4ERR_RECLAIM_BAD:
1406 case -NFS4ERR_RECLAIM_CONFLICT:
1407 /* kill_proc(fl->fl_pid, SIGLOST, 1); */
1408 status = 0;
1409 }
1410 spin_lock(&inode->i_lock);
1411 }
1412
1413 if (!flctx)
1414 goto out_unlock;
1415
1416 list_for_each_entry(fl, &flctx->flc_flock, fl_list) {
1417 if (nfs_file_open_context(fl->fl_file)->state != state) 1382 if (nfs_file_open_context(fl->fl_file)->state != state)
1418 continue; 1383 continue;
1419 spin_unlock(&inode->i_lock); 1384 spin_unlock(&inode->i_lock);
@@ -1445,7 +1410,10 @@ static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_
1445 } 1410 }
1446 spin_lock(&inode->i_lock); 1411 spin_lock(&inode->i_lock);
1447 } 1412 }
1448out_unlock: 1413 if (list == &flctx->flc_posix) {
1414 list = &flctx->flc_flock;
1415 goto restart;
1416 }
1449 spin_unlock(&inode->i_lock); 1417 spin_unlock(&inode->i_lock);
1450out: 1418out:
1451 up_write(&nfsi->rwsem); 1419 up_write(&nfsi->rwsem);
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index a3b62e15b444..29c7f33c9cf1 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -831,12 +831,10 @@ static bool nfs_can_coalesce_requests(struct nfs_page *prev,
831 if (prev) { 831 if (prev) {
832 if (!nfs_match_open_context(req->wb_context, prev->wb_context)) 832 if (!nfs_match_open_context(req->wb_context, prev->wb_context))
833 return false; 833 return false;
834 if (req->wb_context->dentry->d_inode->i_flock != NULL &&
835 !nfs_match_lock_context(req->wb_lock_context,
836 prev->wb_lock_context))
837 return false;
838 flctx = req->wb_context->dentry->d_inode->i_flctx; 834 flctx = req->wb_context->dentry->d_inode->i_flctx;
839 if (flctx != NULL && !list_empty_careful(&flctx->flc_flock) && 835 if (flctx != NULL &&
836 !(list_empty_careful(&flctx->flc_posix) &&
837 list_empty_careful(&flctx->flc_flock)) &&
840 !nfs_match_lock_context(req->wb_lock_context, 838 !nfs_match_lock_context(req->wb_lock_context,
841 prev->wb_lock_context)) 839 prev->wb_lock_context))
842 return false; 840 return false;
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index e072aeb34195..784c13485b3f 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -1091,6 +1091,7 @@ int nfs_flush_incompatible(struct file *file, struct page *page)
1091{ 1091{
1092 struct nfs_open_context *ctx = nfs_file_open_context(file); 1092 struct nfs_open_context *ctx = nfs_file_open_context(file);
1093 struct nfs_lock_context *l_ctx; 1093 struct nfs_lock_context *l_ctx;
1094 struct file_lock_context *flctx = file_inode(file)->i_flctx;
1094 struct nfs_page *req; 1095 struct nfs_page *req;
1095 int do_flush, status; 1096 int do_flush, status;
1096 /* 1097 /*
@@ -1109,12 +1110,9 @@ int nfs_flush_incompatible(struct file *file, struct page *page)
1109 do_flush = req->wb_page != page || req->wb_context != ctx; 1110 do_flush = req->wb_page != page || req->wb_context != ctx;
1110 /* for now, flush if more than 1 request in page_group */ 1111 /* for now, flush if more than 1 request in page_group */
1111 do_flush |= req->wb_this_page != req; 1112 do_flush |= req->wb_this_page != req;
1112 if (l_ctx && ctx->dentry->d_inode->i_flock != NULL) { 1113 if (l_ctx && flctx &&
1113 do_flush |= l_ctx->lockowner.l_owner != current->files 1114 !(list_empty_careful(&flctx->flc_posix) &&
1114 || l_ctx->lockowner.l_pid != current->tgid; 1115 list_empty_careful(&flctx->flc_flock))) {
1115 }
1116 if (l_ctx && ctx->dentry->d_inode->i_flctx &&
1117 !list_empty_careful(&ctx->dentry->d_inode->i_flctx->flc_flock)) {
1118 do_flush |= l_ctx->lockowner.l_owner != current->files 1116 do_flush |= l_ctx->lockowner.l_owner != current->files
1119 || l_ctx->lockowner.l_pid != current->tgid; 1117 || l_ctx->lockowner.l_pid != current->tgid;
1120 } 1118 }
@@ -1202,26 +1200,24 @@ static int nfs_can_extend_write(struct file *file, struct page *page, struct ino
1202 return 0; 1200 return 0;
1203 if (NFS_PROTO(inode)->have_delegation(inode, FMODE_WRITE)) 1201 if (NFS_PROTO(inode)->have_delegation(inode, FMODE_WRITE))
1204 return 1; 1202 return 1;
1205 if (!inode->i_flock && !flctx) 1203 if (!flctx || (list_empty_careful(&flctx->flc_flock) &&
1204 list_empty_careful(&flctx->flc_posix)))
1206 return 0; 1205 return 0;
1207 1206
1208 /* Check to see if there are whole file write locks */ 1207 /* Check to see if there are whole file write locks */
1209 spin_lock(&inode->i_lock);
1210 ret = 0; 1208 ret = 0;
1211 1209 spin_lock(&inode->i_lock);
1212 fl = inode->i_flock; 1210 if (!list_empty(&flctx->flc_posix)) {
1213 if (fl && is_whole_file_wrlock(fl)) { 1211 fl = list_first_entry(&flctx->flc_posix, struct file_lock,
1214 ret = 1; 1212 fl_list);
1215 goto out; 1213 if (is_whole_file_wrlock(fl))
1216 } 1214 ret = 1;
1217 1215 } else if (!list_empty(&flctx->flc_flock)) {
1218 if (!list_empty(&flctx->flc_flock)) {
1219 fl = list_first_entry(&flctx->flc_flock, struct file_lock, 1216 fl = list_first_entry(&flctx->flc_flock, struct file_lock,
1220 fl_list); 1217 fl_list);
1221 if (fl->fl_type == F_WRLCK) 1218 if (fl->fl_type == F_WRLCK)
1222 ret = 1; 1219 ret = 1;
1223 } 1220 }
1224out:
1225 spin_unlock(&inode->i_lock); 1221 spin_unlock(&inode->i_lock);
1226 return ret; 1222 return ret;
1227} 1223}