aboutsummaryrefslogtreecommitdiffstats
path: root/fs/locks.c
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 15:09:25 -0500
commit5263e31e452fb84138b9bee061d5c06c0f359fea (patch)
tree68726ce860d2c824f605e6ec3f2adc9187d6dc86 /fs/locks.c
parentc362781cadd37858c3d8f5d18b1e9957d4671298 (diff)
locks: move flock locks to file_lock_context
Signed-off-by: Jeff Layton <jlayton@primarydata.com> Acked-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/locks.c')
-rw-r--r--fs/locks.c54
1 files changed, 35 insertions, 19 deletions
diff --git a/fs/locks.c b/fs/locks.c
index 526d5fca67c8..055df53f19de 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -694,6 +694,14 @@ static void locks_insert_lock(struct file_lock **pos, struct file_lock *fl)
694 locks_insert_global_locks(fl); 694 locks_insert_global_locks(fl);
695} 695}
696 696
697static void
698locks_insert_lock_ctx(struct file_lock *fl, struct list_head *before)
699{
700 fl->fl_nspid = get_pid(task_tgid(current));
701 list_add_tail(&fl->fl_list, before);
702 locks_insert_global_locks(fl);
703}
704
697/** 705/**
698 * locks_delete_lock - Delete a lock and then free it. 706 * locks_delete_lock - Delete a lock and then free it.
699 * @thisfl_p: pointer that points to the fl_next field of the previous 707 * @thisfl_p: pointer that points to the fl_next field of the previous
@@ -739,6 +747,18 @@ static void locks_delete_lock(struct file_lock **thisfl_p,
739 locks_free_lock(fl); 747 locks_free_lock(fl);
740} 748}
741 749
750static void
751locks_delete_lock_ctx(struct file_lock *fl, struct list_head *dispose)
752{
753 locks_delete_global_locks(fl);
754 if (fl->fl_nspid) {
755 put_pid(fl->fl_nspid);
756 fl->fl_nspid = NULL;
757 }
758 locks_wake_up_blocks(fl);
759 list_move(&fl->fl_list, dispose);
760}
761
742/* Determine if lock sys_fl blocks lock caller_fl. Common functionality 762/* Determine if lock sys_fl blocks lock caller_fl. Common functionality
743 * checks for shared/exclusive status of overlapping locks. 763 * checks for shared/exclusive status of overlapping locks.
744 */ 764 */
@@ -888,12 +908,17 @@ static int posix_locks_deadlock(struct file_lock *caller_fl,
888static int flock_lock_file(struct file *filp, struct file_lock *request) 908static int flock_lock_file(struct file *filp, struct file_lock *request)
889{ 909{
890 struct file_lock *new_fl = NULL; 910 struct file_lock *new_fl = NULL;
891 struct file_lock **before; 911 struct file_lock *fl;
892 struct inode * inode = file_inode(filp); 912 struct file_lock_context *ctx;
913 struct inode *inode = file_inode(filp);
893 int error = 0; 914 int error = 0;
894 int found = 0; 915 bool found = false;
895 LIST_HEAD(dispose); 916 LIST_HEAD(dispose);
896 917
918 ctx = locks_get_lock_context(inode);
919 if (!ctx)
920 return -ENOMEM;
921
897 if (!(request->fl_flags & FL_ACCESS) && (request->fl_type != F_UNLCK)) { 922 if (!(request->fl_flags & FL_ACCESS) && (request->fl_type != F_UNLCK)) {
898 new_fl = locks_alloc_lock(); 923 new_fl = locks_alloc_lock();
899 if (!new_fl) 924 if (!new_fl)
@@ -904,18 +929,13 @@ static int flock_lock_file(struct file *filp, struct file_lock *request)
904 if (request->fl_flags & FL_ACCESS) 929 if (request->fl_flags & FL_ACCESS)
905 goto find_conflict; 930 goto find_conflict;
906 931
907 for_each_lock(inode, before) { 932 list_for_each_entry(fl, &ctx->flc_flock, fl_list) {
908 struct file_lock *fl = *before;
909 if (IS_POSIX(fl))
910 break;
911 if (IS_LEASE(fl))
912 continue;
913 if (filp != fl->fl_file) 933 if (filp != fl->fl_file)
914 continue; 934 continue;
915 if (request->fl_type == fl->fl_type) 935 if (request->fl_type == fl->fl_type)
916 goto out; 936 goto out;
917 found = 1; 937 found = true;
918 locks_delete_lock(before, &dispose); 938 locks_delete_lock_ctx(fl, &dispose);
919 break; 939 break;
920 } 940 }
921 941
@@ -936,12 +956,7 @@ static int flock_lock_file(struct file *filp, struct file_lock *request)
936 } 956 }
937 957
938find_conflict: 958find_conflict:
939 for_each_lock(inode, before) { 959 list_for_each_entry(fl, &ctx->flc_flock, fl_list) {
940 struct file_lock *fl = *before;
941 if (IS_POSIX(fl))
942 break;
943 if (IS_LEASE(fl))
944 continue;
945 if (!flock_locks_conflict(request, fl)) 960 if (!flock_locks_conflict(request, fl))
946 continue; 961 continue;
947 error = -EAGAIN; 962 error = -EAGAIN;
@@ -954,7 +969,7 @@ find_conflict:
954 if (request->fl_flags & FL_ACCESS) 969 if (request->fl_flags & FL_ACCESS)
955 goto out; 970 goto out;
956 locks_copy_lock(new_fl, request); 971 locks_copy_lock(new_fl, request);
957 locks_insert_lock(before, new_fl); 972 locks_insert_lock_ctx(new_fl, &ctx->flc_flock);
958 new_fl = NULL; 973 new_fl = NULL;
959 error = 0; 974 error = 0;
960 975
@@ -2412,8 +2427,9 @@ locks_remove_flock(struct file *filp)
2412 .fl_type = F_UNLCK, 2427 .fl_type = F_UNLCK,
2413 .fl_end = OFFSET_MAX, 2428 .fl_end = OFFSET_MAX,
2414 }; 2429 };
2430 struct file_lock_context *flctx = file_inode(filp)->i_flctx;
2415 2431
2416 if (!file_inode(filp)->i_flock) 2432 if (!flctx || list_empty(&flctx->flc_flock))
2417 return; 2433 return;
2418 2434
2419 if (filp->f_op->flock) 2435 if (filp->f_op->flock)