Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'locks-v3.20-2' of git://git.samba.org/jlayton/linux

Pull file locking fixes from Jeff Layton:
"A small set of patches to fix problems with the recent file locking
changes that we discussed earlier this week"
"

* tag 'locks-v3.20-2' of git://git.samba.org/jlayton/linux:
locks: fix list insertion when lock is split in two
locks: remove conditional lock release in middle of flock_lock_file
locks: only remove leases associated with the file being closed
Revert "locks: keep a count of locks on the flctx lists"

+36 -49
+7 -2
fs/ceph/locks.c
··· 245 245 */ 246 246 void ceph_count_locks(struct inode *inode, int *fcntl_count, int *flock_count) 247 247 { 248 + struct file_lock *lock; 248 249 struct file_lock_context *ctx; 249 250 250 251 *fcntl_count = 0; ··· 253 252 254 253 ctx = inode->i_flctx; 255 254 if (ctx) { 256 - *fcntl_count = ctx->flc_posix_cnt; 257 - *flock_count = ctx->flc_flock_cnt; 255 + spin_lock(&ctx->flc_lock); 256 + list_for_each_entry(lock, &ctx->flc_posix, fl_list) 257 + ++(*fcntl_count); 258 + list_for_each_entry(lock, &ctx->flc_flock, fl_list) 259 + ++(*flock_count); 260 + spin_unlock(&ctx->flc_lock); 258 261 } 259 262 dout("counted %d flock locks and %d fcntl locks", 260 263 *flock_count, *fcntl_count);
+10 -4
fs/cifs/file.c
··· 1129 1129 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); 1130 1130 struct file_lock *flock; 1131 1131 struct file_lock_context *flctx = inode->i_flctx; 1132 - unsigned int i; 1132 + unsigned int count = 0, i; 1133 1133 int rc = 0, xid, type; 1134 1134 struct list_head locks_to_send, *el; 1135 1135 struct lock_to_push *lck, *tmp; ··· 1140 1140 if (!flctx) 1141 1141 goto out; 1142 1142 1143 + spin_lock(&flctx->flc_lock); 1144 + list_for_each(el, &flctx->flc_posix) { 1145 + count++; 1146 + } 1147 + spin_unlock(&flctx->flc_lock); 1148 + 1143 1149 INIT_LIST_HEAD(&locks_to_send); 1144 1150 1145 1151 /* 1146 - * Allocating flc_posix_cnt locks is enough because no FL_POSIX locks 1147 - * can be added to the list while we are holding cinode->lock_sem that 1152 + * Allocating count locks is enough because no FL_POSIX locks can be 1153 + * added to the list while we are holding cinode->lock_sem that 1148 1154 * protects locking operations of this inode. 1149 1155 */ 1150 - for (i = 0; i < flctx->flc_posix_cnt; i++) { 1156 + for (i = 0; i < count; i++) { 1151 1157 lck = kmalloc(sizeof(struct lock_to_push), GFP_KERNEL); 1152 1158 if (!lck) { 1153 1159 rc = -ENOMEM;
+19 -40
fs/locks.c
··· 681 681 } 682 682 683 683 static void 684 - locks_insert_lock_ctx(struct file_lock *fl, int *counter, 685 - struct list_head *before) 684 + locks_insert_lock_ctx(struct file_lock *fl, struct list_head *before) 686 685 { 687 686 fl->fl_nspid = get_pid(task_tgid(current)); 688 687 list_add_tail(&fl->fl_list, before); 689 - ++*counter; 690 688 locks_insert_global_locks(fl); 691 689 } 692 690 693 691 static void 694 - locks_unlink_lock_ctx(struct file_lock *fl, int *counter) 692 + locks_unlink_lock_ctx(struct file_lock *fl) 695 693 { 696 694 locks_delete_global_locks(fl); 697 695 list_del_init(&fl->fl_list); 698 - --*counter; 699 696 if (fl->fl_nspid) { 700 697 put_pid(fl->fl_nspid); 701 698 fl->fl_nspid = NULL; ··· 701 704 } 702 705 703 706 static void 704 - locks_delete_lock_ctx(struct file_lock *fl, int *counter, 705 - struct list_head *dispose) 707 + locks_delete_lock_ctx(struct file_lock *fl, struct list_head *dispose) 706 708 { 707 - locks_unlink_lock_ctx(fl, counter); 709 + locks_unlink_lock_ctx(fl); 708 710 if (dispose) 709 711 list_add(&fl->fl_list, dispose); 710 712 else ··· 891 895 if (request->fl_type == fl->fl_type) 892 896 goto out; 893 897 found = true; 894 - locks_delete_lock_ctx(fl, &ctx->flc_flock_cnt, &dispose); 898 + locks_delete_lock_ctx(fl, &dispose); 895 899 break; 896 900 } 897 901 ··· 899 903 if ((request->fl_flags & FL_EXISTS) && !found) 900 904 error = -ENOENT; 901 905 goto out; 902 - } 903 - 904 - /* 905 - * If a higher-priority process was blocked on the old file lock, 906 - * give it the opportunity to lock the file. 907 - */ 908 - if (found) { 909 - spin_unlock(&ctx->flc_lock); 910 - cond_resched(); 911 - spin_lock(&ctx->flc_lock); 912 906 } 913 907 914 908 find_conflict: ··· 915 929 if (request->fl_flags & FL_ACCESS) 916 930 goto out; 917 931 locks_copy_lock(new_fl, request); 918 - locks_insert_lock_ctx(new_fl, &ctx->flc_flock_cnt, &ctx->flc_flock); 932 + locks_insert_lock_ctx(new_fl, &ctx->flc_flock); 919 933 new_fl = NULL; 920 934 error = 0; 921 935 ··· 1032 1046 else 1033 1047 request->fl_end = fl->fl_end; 1034 1048 if (added) { 1035 - locks_delete_lock_ctx(fl, &ctx->flc_posix_cnt, 1036 - &dispose); 1049 + locks_delete_lock_ctx(fl, &dispose); 1037 1050 continue; 1038 1051 } 1039 1052 request = fl; ··· 1061 1076 * one (This may happen several times). 1062 1077 */ 1063 1078 if (added) { 1064 - locks_delete_lock_ctx(fl, 1065 - &ctx->flc_posix_cnt, &dispose); 1079 + locks_delete_lock_ctx(fl, &dispose); 1066 1080 continue; 1067 1081 } 1068 1082 /* ··· 1077 1093 locks_copy_lock(new_fl, request); 1078 1094 request = new_fl; 1079 1095 new_fl = NULL; 1080 - locks_insert_lock_ctx(request, 1081 - &ctx->flc_posix_cnt, &fl->fl_list); 1082 - locks_delete_lock_ctx(fl, 1083 - &ctx->flc_posix_cnt, &dispose); 1096 + locks_insert_lock_ctx(request, &fl->fl_list); 1097 + locks_delete_lock_ctx(fl, &dispose); 1084 1098 added = true; 1085 1099 } 1086 1100 } ··· 1106 1124 goto out; 1107 1125 } 1108 1126 locks_copy_lock(new_fl, request); 1109 - locks_insert_lock_ctx(new_fl, &ctx->flc_posix_cnt, 1110 - &fl->fl_list); 1127 + locks_insert_lock_ctx(new_fl, &fl->fl_list); 1128 + fl = new_fl; 1111 1129 new_fl = NULL; 1112 1130 } 1113 1131 if (right) { ··· 1118 1136 left = new_fl2; 1119 1137 new_fl2 = NULL; 1120 1138 locks_copy_lock(left, right); 1121 - locks_insert_lock_ctx(left, &ctx->flc_posix_cnt, 1122 - &fl->fl_list); 1139 + locks_insert_lock_ctx(left, &fl->fl_list); 1123 1140 } 1124 1141 right->fl_start = request->fl_end + 1; 1125 1142 locks_wake_up_blocks(right); ··· 1302 1321 /* We already had a lease on this file; just change its type */ 1303 1322 int lease_modify(struct file_lock *fl, int arg, struct list_head *dispose) 1304 1323 { 1305 - struct file_lock_context *flctx; 1306 1324 int error = assign_type(fl, arg); 1307 1325 1308 1326 if (error) ··· 1311 1331 if (arg == F_UNLCK) { 1312 1332 struct file *filp = fl->fl_file; 1313 1333 1314 - flctx = file_inode(filp)->i_flctx; 1315 1334 f_delown(filp); 1316 1335 filp->f_owner.signum = 0; 1317 1336 fasync_helper(0, fl->fl_file, 0, &fl->fl_fasync); ··· 1318 1339 printk(KERN_ERR "locks_delete_lock: fasync == %p\n", fl->fl_fasync); 1319 1340 fl->fl_fasync = NULL; 1320 1341 } 1321 - locks_delete_lock_ctx(fl, &flctx->flc_lease_cnt, dispose); 1342 + locks_delete_lock_ctx(fl, dispose); 1322 1343 } 1323 1344 return 0; 1324 1345 } ··· 1435 1456 fl->fl_downgrade_time = break_time; 1436 1457 } 1437 1458 if (fl->fl_lmops->lm_break(fl)) 1438 - locks_delete_lock_ctx(fl, &ctx->flc_lease_cnt, 1439 - &dispose); 1459 + locks_delete_lock_ctx(fl, &dispose); 1440 1460 } 1441 1461 1442 1462 if (list_empty(&ctx->flc_lease)) ··· 1675 1697 if (!leases_enable) 1676 1698 goto out; 1677 1699 1678 - locks_insert_lock_ctx(lease, &ctx->flc_lease_cnt, &ctx->flc_lease); 1700 + locks_insert_lock_ctx(lease, &ctx->flc_lease); 1679 1701 /* 1680 1702 * The check in break_lease() is lockless. It's possible for another 1681 1703 * open to race in after we did the earlier check for a conflicting ··· 1688 1710 smp_mb(); 1689 1711 error = check_conflicting_open(dentry, arg, lease->fl_flags); 1690 1712 if (error) { 1691 - locks_unlink_lock_ctx(lease, &ctx->flc_lease_cnt); 1713 + locks_unlink_lock_ctx(lease); 1692 1714 goto out; 1693 1715 } 1694 1716 ··· 2426 2448 2427 2449 spin_lock(&ctx->flc_lock); 2428 2450 list_for_each_entry_safe(fl, tmp, &ctx->flc_lease, fl_list) 2429 - lease_modify(fl, F_UNLCK, &dispose); 2451 + if (filp == fl->fl_file) 2452 + lease_modify(fl, F_UNLCK, &dispose); 2430 2453 spin_unlock(&ctx->flc_lock); 2431 2454 locks_dispose_list(&dispose); 2432 2455 }
-3
include/linux/fs.h
··· 968 968 struct list_head flc_flock; 969 969 struct list_head flc_posix; 970 970 struct list_head flc_lease; 971 - int flc_flock_cnt; 972 - int flc_posix_cnt; 973 - int flc_lease_cnt; 974 971 }; 975 972 976 973 /* The following constant reflects the upper bound of the file/locking space */