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 15:09:25 -0500 |
commit | 5263e31e452fb84138b9bee061d5c06c0f359fea (patch) | |
tree | 68726ce860d2c824f605e6ec3f2adc9187d6dc86 /fs/locks.c | |
parent | c362781cadd37858c3d8f5d18b1e9957d4671298 (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.c | 54 |
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 | ||
697 | static void | ||
698 | locks_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 | ||
750 | static void | ||
751 | locks_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, | |||
888 | static int flock_lock_file(struct file *filp, struct file_lock *request) | 908 | static 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 | ||
938 | find_conflict: | 958 | find_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) |