diff options
author | Jeff Layton <jlayton@primarydata.com> | 2015-01-16 15:05:55 -0500 |
---|---|---|
committer | Jeff Layton <jeff.layton@primarydata.com> | 2015-01-16 16:08:16 -0500 |
commit | bd61e0a9c852de2d705b6f1bb2cc54c5774db570 (patch) | |
tree | 67a583912923f2ae621bddf94fbba8816cb0e49d /fs/nfs | |
parent | 5263e31e452fb84138b9bee061d5c06c0f359fea (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.c | 28 | ||||
-rw-r--r-- | fs/nfs/nfs4state.c | 52 | ||||
-rw-r--r-- | fs/nfs/pagelist.c | 8 | ||||
-rw-r--r-- | fs/nfs/write.c | 30 |
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) { | 97 | restart: |
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); |
122 | out: | 112 | out: |
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) { | 1380 | restart: |
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 | } |
1448 | out_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); |
1450 | out: | 1418 | out: |
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 | } |
1224 | out: | ||
1225 | spin_unlock(&inode->i_lock); | 1221 | spin_unlock(&inode->i_lock); |
1226 | return ret; | 1222 | return ret; |
1227 | } | 1223 | } |