aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/file.c
diff options
context:
space:
mode:
authorPavel Shilovsky <pshilovsky@etersoft.ru>2012-09-19 09:22:44 -0400
committerSteve French <smfrench@gmail.com>2012-09-24 22:46:33 -0400
commit1b4b55a1d9404f51aacf1ff19887eb911484057d (patch)
treee2909277cc8db445c1d839c4859449a32cbfc08a /fs/cifs/file.c
parentb140799a11adb6023d5f96712874c37b71dab290 (diff)
CIFS: Turn lock mutex into rw semaphore
and allow several processes to walk through the lock list and read can_cache_brlcks value if they are not going to modify them. Signed-off-by: Pavel Shilovsky <pshilovsky@etersoft.ru> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r--fs/cifs/file.c60
1 files changed, 31 insertions, 29 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index e2a8e4456275..1adff75dfffc 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -260,9 +260,9 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
260 INIT_LIST_HEAD(&fdlocks->locks); 260 INIT_LIST_HEAD(&fdlocks->locks);
261 fdlocks->cfile = cfile; 261 fdlocks->cfile = cfile;
262 cfile->llist = fdlocks; 262 cfile->llist = fdlocks;
263 mutex_lock(&cinode->lock_mutex); 263 down_write(&cinode->lock_sem);
264 list_add(&fdlocks->llist, &cinode->llist); 264 list_add(&fdlocks->llist, &cinode->llist);
265 mutex_unlock(&cinode->lock_mutex); 265 up_write(&cinode->lock_sem);
266 266
267 cfile->count = 1; 267 cfile->count = 1;
268 cfile->pid = current->tgid; 268 cfile->pid = current->tgid;
@@ -351,7 +351,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
351 * Delete any outstanding lock records. We'll lose them when the file 351 * Delete any outstanding lock records. We'll lose them when the file
352 * is closed anyway. 352 * is closed anyway.
353 */ 353 */
354 mutex_lock(&cifsi->lock_mutex); 354 down_write(&cifsi->lock_sem);
355 list_for_each_entry_safe(li, tmp, &cifs_file->llist->locks, llist) { 355 list_for_each_entry_safe(li, tmp, &cifs_file->llist->locks, llist) {
356 list_del(&li->llist); 356 list_del(&li->llist);
357 cifs_del_lock_waiters(li); 357 cifs_del_lock_waiters(li);
@@ -359,7 +359,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
359 } 359 }
360 list_del(&cifs_file->llist->llist); 360 list_del(&cifs_file->llist->llist);
361 kfree(cifs_file->llist); 361 kfree(cifs_file->llist);
362 mutex_unlock(&cifsi->lock_mutex); 362 up_write(&cifsi->lock_sem);
363 363
364 cifs_put_tlink(cifs_file->tlink); 364 cifs_put_tlink(cifs_file->tlink);
365 dput(cifs_file->dentry); 365 dput(cifs_file->dentry);
@@ -762,7 +762,7 @@ cifs_lock_test(struct cifsFileInfo *cfile, __u64 offset, __u64 length,
762 struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server; 762 struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server;
763 bool exist; 763 bool exist;
764 764
765 mutex_lock(&cinode->lock_mutex); 765 down_read(&cinode->lock_sem);
766 766
767 exist = cifs_find_lock_conflict(cfile, offset, length, type, 767 exist = cifs_find_lock_conflict(cfile, offset, length, type,
768 &conf_lock); 768 &conf_lock);
@@ -779,7 +779,7 @@ cifs_lock_test(struct cifsFileInfo *cfile, __u64 offset, __u64 length,
779 else 779 else
780 flock->fl_type = F_UNLCK; 780 flock->fl_type = F_UNLCK;
781 781
782 mutex_unlock(&cinode->lock_mutex); 782 up_read(&cinode->lock_sem);
783 return rc; 783 return rc;
784} 784}
785 785
@@ -787,9 +787,9 @@ static void
787cifs_lock_add(struct cifsFileInfo *cfile, struct cifsLockInfo *lock) 787cifs_lock_add(struct cifsFileInfo *cfile, struct cifsLockInfo *lock)
788{ 788{
789 struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode); 789 struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
790 mutex_lock(&cinode->lock_mutex); 790 down_write(&cinode->lock_sem);
791 list_add_tail(&lock->llist, &cfile->llist->locks); 791 list_add_tail(&lock->llist, &cfile->llist->locks);
792 mutex_unlock(&cinode->lock_mutex); 792 up_write(&cinode->lock_sem);
793} 793}
794 794
795/* 795/*
@@ -809,13 +809,13 @@ cifs_lock_add_if(struct cifsFileInfo *cfile, struct cifsLockInfo *lock,
809 809
810try_again: 810try_again:
811 exist = false; 811 exist = false;
812 mutex_lock(&cinode->lock_mutex); 812 down_write(&cinode->lock_sem);
813 813
814 exist = cifs_find_lock_conflict(cfile, lock->offset, lock->length, 814 exist = cifs_find_lock_conflict(cfile, lock->offset, lock->length,
815 lock->type, &conf_lock); 815 lock->type, &conf_lock);
816 if (!exist && cinode->can_cache_brlcks) { 816 if (!exist && cinode->can_cache_brlcks) {
817 list_add_tail(&lock->llist, &cfile->llist->locks); 817 list_add_tail(&lock->llist, &cfile->llist->locks);
818 mutex_unlock(&cinode->lock_mutex); 818 up_write(&cinode->lock_sem);
819 return rc; 819 return rc;
820 } 820 }
821 821
@@ -825,17 +825,17 @@ try_again:
825 rc = -EACCES; 825 rc = -EACCES;
826 else { 826 else {
827 list_add_tail(&lock->blist, &conf_lock->blist); 827 list_add_tail(&lock->blist, &conf_lock->blist);
828 mutex_unlock(&cinode->lock_mutex); 828 up_write(&cinode->lock_sem);
829 rc = wait_event_interruptible(lock->block_q, 829 rc = wait_event_interruptible(lock->block_q,
830 (lock->blist.prev == &lock->blist) && 830 (lock->blist.prev == &lock->blist) &&
831 (lock->blist.next == &lock->blist)); 831 (lock->blist.next == &lock->blist));
832 if (!rc) 832 if (!rc)
833 goto try_again; 833 goto try_again;
834 mutex_lock(&cinode->lock_mutex); 834 down_write(&cinode->lock_sem);
835 list_del_init(&lock->blist); 835 list_del_init(&lock->blist);
836 } 836 }
837 837
838 mutex_unlock(&cinode->lock_mutex); 838 up_write(&cinode->lock_sem);
839 return rc; 839 return rc;
840} 840}
841 841
@@ -856,7 +856,7 @@ cifs_posix_lock_test(struct file *file, struct file_lock *flock)
856 if ((flock->fl_flags & FL_POSIX) == 0) 856 if ((flock->fl_flags & FL_POSIX) == 0)
857 return 1; 857 return 1;
858 858
859 mutex_lock(&cinode->lock_mutex); 859 down_read(&cinode->lock_sem);
860 posix_test_lock(file, flock); 860 posix_test_lock(file, flock);
861 861
862 if (flock->fl_type == F_UNLCK && !cinode->can_cache_brlcks) { 862 if (flock->fl_type == F_UNLCK && !cinode->can_cache_brlcks) {
@@ -864,7 +864,7 @@ cifs_posix_lock_test(struct file *file, struct file_lock *flock)
864 rc = 1; 864 rc = 1;
865 } 865 }
866 866
867 mutex_unlock(&cinode->lock_mutex); 867 up_read(&cinode->lock_sem);
868 return rc; 868 return rc;
869} 869}
870 870
@@ -884,14 +884,14 @@ cifs_posix_lock_set(struct file *file, struct file_lock *flock)
884 return rc; 884 return rc;
885 885
886try_again: 886try_again:
887 mutex_lock(&cinode->lock_mutex); 887 down_write(&cinode->lock_sem);
888 if (!cinode->can_cache_brlcks) { 888 if (!cinode->can_cache_brlcks) {
889 mutex_unlock(&cinode->lock_mutex); 889 up_write(&cinode->lock_sem);
890 return rc; 890 return rc;
891 } 891 }
892 892
893 rc = posix_lock_file(file, flock, NULL); 893 rc = posix_lock_file(file, flock, NULL);
894 mutex_unlock(&cinode->lock_mutex); 894 up_write(&cinode->lock_sem);
895 if (rc == FILE_LOCK_DEFERRED) { 895 if (rc == FILE_LOCK_DEFERRED) {
896 rc = wait_event_interruptible(flock->fl_wait, !flock->fl_next); 896 rc = wait_event_interruptible(flock->fl_wait, !flock->fl_next);
897 if (!rc) 897 if (!rc)
@@ -918,9 +918,10 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile)
918 xid = get_xid(); 918 xid = get_xid();
919 tcon = tlink_tcon(cfile->tlink); 919 tcon = tlink_tcon(cfile->tlink);
920 920
921 mutex_lock(&cinode->lock_mutex); 921 /* we are going to update can_cache_brlcks here - need a write access */
922 down_write(&cinode->lock_sem);
922 if (!cinode->can_cache_brlcks) { 923 if (!cinode->can_cache_brlcks) {
923 mutex_unlock(&cinode->lock_mutex); 924 up_write(&cinode->lock_sem);
924 free_xid(xid); 925 free_xid(xid);
925 return rc; 926 return rc;
926 } 927 }
@@ -931,7 +932,7 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile)
931 */ 932 */
932 max_buf = tcon->ses->server->maxBuf; 933 max_buf = tcon->ses->server->maxBuf;
933 if (!max_buf) { 934 if (!max_buf) {
934 mutex_unlock(&cinode->lock_mutex); 935 up_write(&cinode->lock_sem);
935 free_xid(xid); 936 free_xid(xid);
936 return -EINVAL; 937 return -EINVAL;
937 } 938 }
@@ -940,7 +941,7 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile)
940 sizeof(LOCKING_ANDX_RANGE); 941 sizeof(LOCKING_ANDX_RANGE);
941 buf = kzalloc(max_num * sizeof(LOCKING_ANDX_RANGE), GFP_KERNEL); 942 buf = kzalloc(max_num * sizeof(LOCKING_ANDX_RANGE), GFP_KERNEL);
942 if (!buf) { 943 if (!buf) {
943 mutex_unlock(&cinode->lock_mutex); 944 up_write(&cinode->lock_sem);
944 free_xid(xid); 945 free_xid(xid);
945 return -ENOMEM; 946 return -ENOMEM;
946 } 947 }
@@ -978,7 +979,7 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile)
978 } 979 }
979 980
980 cinode->can_cache_brlcks = false; 981 cinode->can_cache_brlcks = false;
981 mutex_unlock(&cinode->lock_mutex); 982 up_write(&cinode->lock_sem);
982 983
983 kfree(buf); 984 kfree(buf);
984 free_xid(xid); 985 free_xid(xid);
@@ -1013,9 +1014,10 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile)
1013 1014
1014 xid = get_xid(); 1015 xid = get_xid();
1015 1016
1016 mutex_lock(&cinode->lock_mutex); 1017 /* we are going to update can_cache_brlcks here - need a write access */
1018 down_write(&cinode->lock_sem);
1017 if (!cinode->can_cache_brlcks) { 1019 if (!cinode->can_cache_brlcks) {
1018 mutex_unlock(&cinode->lock_mutex); 1020 up_write(&cinode->lock_sem);
1019 free_xid(xid); 1021 free_xid(xid);
1020 return rc; 1022 return rc;
1021 } 1023 }
@@ -1031,7 +1033,7 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile)
1031 1033
1032 /* 1034 /*
1033 * Allocating count locks is enough because no FL_POSIX locks can be 1035 * Allocating count locks is enough because no FL_POSIX locks can be
1034 * added to the list while we are holding cinode->lock_mutex that 1036 * added to the list while we are holding cinode->lock_sem that
1035 * protects locking operations of this inode. 1037 * protects locking operations of this inode.
1036 */ 1038 */
1037 for (; i < count; i++) { 1039 for (; i < count; i++) {
@@ -1086,7 +1088,7 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile)
1086 1088
1087out: 1089out:
1088 cinode->can_cache_brlcks = false; 1090 cinode->can_cache_brlcks = false;
1089 mutex_unlock(&cinode->lock_mutex); 1091 up_write(&cinode->lock_sem);
1090 1092
1091 free_xid(xid); 1093 free_xid(xid);
1092 return rc; 1094 return rc;
@@ -1278,7 +1280,7 @@ cifs_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock,
1278 if (!buf) 1280 if (!buf)
1279 return -ENOMEM; 1281 return -ENOMEM;
1280 1282
1281 mutex_lock(&cinode->lock_mutex); 1283 down_write(&cinode->lock_sem);
1282 for (i = 0; i < 2; i++) { 1284 for (i = 0; i < 2; i++) {
1283 cur = buf; 1285 cur = buf;
1284 num = 0; 1286 num = 0;
@@ -1348,7 +1350,7 @@ cifs_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock,
1348 } 1350 }
1349 } 1351 }
1350 1352
1351 mutex_unlock(&cinode->lock_mutex); 1353 up_write(&cinode->lock_sem);
1352 kfree(buf); 1354 kfree(buf);
1353 return rc; 1355 return rc;
1354} 1356}