diff options
author | Pavel Shilovsky <piastry@etersoft.ru> | 2012-02-28 06:04:17 -0500 |
---|---|---|
committer | Pavel Shilovsky <piastry@etersoft.ru> | 2012-05-17 05:07:41 -0400 |
commit | 55157dfbb566e23e3c76489cb028fc82bd985ea1 (patch) | |
tree | 46f8284bce1d3d37f69c33731b637ea82fbffff5 | |
parent | 106dc538abac88e804c63b7fe21ffb09cffaefc7 (diff) |
CIFS: Separate protocol specific part from getlk
Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru>
-rw-r--r-- | fs/cifs/cifsglob.h | 2 | ||||
-rw-r--r-- | fs/cifs/file.c | 52 | ||||
-rw-r--r-- | fs/cifs/smb1ops.c | 7 |
3 files changed, 39 insertions, 22 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 6943448c57e2..b6e97f8586d2 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -156,10 +156,12 @@ enum smb_version { | |||
156 | 156 | ||
157 | struct mid_q_entry; | 157 | struct mid_q_entry; |
158 | struct TCP_Server_Info; | 158 | struct TCP_Server_Info; |
159 | struct cifsFileInfo; | ||
159 | 160 | ||
160 | struct smb_version_operations { | 161 | struct smb_version_operations { |
161 | int (*send_cancel)(struct TCP_Server_Info *, void *, | 162 | int (*send_cancel)(struct TCP_Server_Info *, void *, |
162 | struct mid_q_entry *); | 163 | struct mid_q_entry *); |
164 | bool (*compare_fids)(struct cifsFileInfo *, struct cifsFileInfo *); | ||
163 | }; | 165 | }; |
164 | 166 | ||
165 | struct smb_version_values { | 167 | struct smb_version_values { |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index ac71f85cff72..9c2d85d8e5e1 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -671,7 +671,7 @@ cifs_del_lock_waiters(struct cifsLockInfo *lock) | |||
671 | 671 | ||
672 | static bool | 672 | static bool |
673 | cifs_find_fid_lock_conflict(struct cifsFileInfo *cfile, __u64 offset, | 673 | cifs_find_fid_lock_conflict(struct cifsFileInfo *cfile, __u64 offset, |
674 | __u64 length, __u8 type, __u16 netfid, | 674 | __u64 length, __u8 type, struct cifsFileInfo *cur, |
675 | struct cifsLockInfo **conf_lock) | 675 | struct cifsLockInfo **conf_lock) |
676 | { | 676 | { |
677 | struct cifsLockInfo *li; | 677 | struct cifsLockInfo *li; |
@@ -682,8 +682,8 @@ cifs_find_fid_lock_conflict(struct cifsFileInfo *cfile, __u64 offset, | |||
682 | offset >= li->offset + li->length) | 682 | offset >= li->offset + li->length) |
683 | continue; | 683 | continue; |
684 | else if ((type & server->vals->shared_lock_type) && | 684 | else if ((type & server->vals->shared_lock_type) && |
685 | ((netfid == cfile->netfid && current->tgid == li->pid) | 685 | ((server->ops->compare_fids(cur, cfile) && |
686 | || type == li->type)) | 686 | current->tgid == li->pid) || type == li->type)) |
687 | continue; | 687 | continue; |
688 | else { | 688 | else { |
689 | *conf_lock = li; | 689 | *conf_lock = li; |
@@ -694,17 +694,17 @@ cifs_find_fid_lock_conflict(struct cifsFileInfo *cfile, __u64 offset, | |||
694 | } | 694 | } |
695 | 695 | ||
696 | static bool | 696 | static bool |
697 | cifs_find_lock_conflict(struct cifsInodeInfo *cinode, __u64 offset, | 697 | cifs_find_lock_conflict(struct cifsFileInfo *cfile, __u64 offset, __u64 length, |
698 | __u64 length, __u8 type, __u16 netfid, | 698 | __u8 type, struct cifsLockInfo **conf_lock) |
699 | struct cifsLockInfo **conf_lock) | ||
700 | { | 699 | { |
701 | bool rc = false; | 700 | bool rc = false; |
702 | struct cifsFileInfo *fid, *tmp; | 701 | struct cifsFileInfo *fid, *tmp; |
702 | struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode); | ||
703 | 703 | ||
704 | spin_lock(&cifs_file_list_lock); | 704 | spin_lock(&cifs_file_list_lock); |
705 | list_for_each_entry_safe(fid, tmp, &cinode->openFileList, flist) { | 705 | list_for_each_entry_safe(fid, tmp, &cinode->openFileList, flist) { |
706 | rc = cifs_find_fid_lock_conflict(fid, offset, length, type, | 706 | rc = cifs_find_fid_lock_conflict(fid, offset, length, type, |
707 | netfid, conf_lock); | 707 | cfile, conf_lock); |
708 | if (rc) | 708 | if (rc) |
709 | break; | 709 | break; |
710 | } | 710 | } |
@@ -732,8 +732,8 @@ cifs_lock_test(struct cifsFileInfo *cfile, __u64 offset, __u64 length, | |||
732 | 732 | ||
733 | mutex_lock(&cinode->lock_mutex); | 733 | mutex_lock(&cinode->lock_mutex); |
734 | 734 | ||
735 | exist = cifs_find_lock_conflict(cinode, offset, length, type, | 735 | exist = cifs_find_lock_conflict(cfile, offset, length, type, |
736 | cfile->netfid, &conf_lock); | 736 | &conf_lock); |
737 | if (exist) { | 737 | if (exist) { |
738 | flock->fl_start = conf_lock->offset; | 738 | flock->fl_start = conf_lock->offset; |
739 | flock->fl_end = conf_lock->offset + conf_lock->length - 1; | 739 | flock->fl_end = conf_lock->offset + conf_lock->length - 1; |
@@ -779,8 +779,8 @@ try_again: | |||
779 | exist = false; | 779 | exist = false; |
780 | mutex_lock(&cinode->lock_mutex); | 780 | mutex_lock(&cinode->lock_mutex); |
781 | 781 | ||
782 | exist = cifs_find_lock_conflict(cinode, lock->offset, lock->length, | 782 | exist = cifs_find_lock_conflict(cfile, lock->offset, lock->length, |
783 | lock->type, cfile->netfid, &conf_lock); | 783 | lock->type, &conf_lock); |
784 | if (!exist && cinode->can_cache_brlcks) { | 784 | if (!exist && cinode->can_cache_brlcks) { |
785 | list_add_tail(&lock->llist, &cfile->llist); | 785 | list_add_tail(&lock->llist, &cfile->llist); |
786 | mutex_unlock(&cinode->lock_mutex); | 786 | mutex_unlock(&cinode->lock_mutex); |
@@ -1117,6 +1117,15 @@ cifs_read_flock(struct file_lock *flock, __u32 *type, int *lock, int *unlock, | |||
1117 | } | 1117 | } |
1118 | 1118 | ||
1119 | static int | 1119 | static int |
1120 | cifs_mandatory_lock(int xid, struct cifsFileInfo *cfile, __u64 offset, | ||
1121 | __u64 length, __u32 type, int lock, int unlock, bool wait) | ||
1122 | { | ||
1123 | return CIFSSMBLock(xid, tlink_tcon(cfile->tlink), cfile->netfid, | ||
1124 | current->tgid, length, offset, unlock, lock, | ||
1125 | (__u8)type, wait, 0); | ||
1126 | } | ||
1127 | |||
1128 | static int | ||
1120 | cifs_getlk(struct file *file, struct file_lock *flock, __u32 type, | 1129 | cifs_getlk(struct file *file, struct file_lock *flock, __u32 type, |
1121 | bool wait_flag, bool posix_lck, int xid) | 1130 | bool wait_flag, bool posix_lck, int xid) |
1122 | { | 1131 | { |
@@ -1149,12 +1158,11 @@ cifs_getlk(struct file *file, struct file_lock *flock, __u32 type, | |||
1149 | return rc; | 1158 | return rc; |
1150 | 1159 | ||
1151 | /* BB we could chain these into one lock request BB */ | 1160 | /* BB we could chain these into one lock request BB */ |
1152 | rc = CIFSSMBLock(xid, tcon, netfid, current->tgid, length, | 1161 | rc = cifs_mandatory_lock(xid, cfile, flock->fl_start, length, type, |
1153 | flock->fl_start, 0, 1, type, 0, 0); | 1162 | 1, 0, false); |
1154 | if (rc == 0) { | 1163 | if (rc == 0) { |
1155 | rc = CIFSSMBLock(xid, tcon, netfid, current->tgid, | 1164 | rc = cifs_mandatory_lock(xid, cfile, flock->fl_start, length, |
1156 | length, flock->fl_start, 1, 0, | 1165 | type, 0, 1, false); |
1157 | type, 0, 0); | ||
1158 | flock->fl_type = F_UNLCK; | 1166 | flock->fl_type = F_UNLCK; |
1159 | if (rc != 0) | 1167 | if (rc != 0) |
1160 | cERROR(1, "Error unlocking previously locked " | 1168 | cERROR(1, "Error unlocking previously locked " |
@@ -1167,13 +1175,13 @@ cifs_getlk(struct file *file, struct file_lock *flock, __u32 type, | |||
1167 | return 0; | 1175 | return 0; |
1168 | } | 1176 | } |
1169 | 1177 | ||
1170 | rc = CIFSSMBLock(xid, tcon, netfid, current->tgid, length, | 1178 | rc = cifs_mandatory_lock(xid, cfile, flock->fl_start, length, |
1171 | flock->fl_start, 0, 1, | 1179 | type | server->vals->shared_lock_type, 1, 0, |
1172 | type | server->vals->shared_lock_type, 0, 0); | 1180 | false); |
1173 | if (rc == 0) { | 1181 | if (rc == 0) { |
1174 | rc = CIFSSMBLock(xid, tcon, netfid, current->tgid, | 1182 | rc = cifs_mandatory_lock(xid, cfile, flock->fl_start, length, |
1175 | length, flock->fl_start, 1, 0, | 1183 | type | server->vals->shared_lock_type, |
1176 | type | server->vals->shared_lock_type, 0, 0); | 1184 | 0, 1, false); |
1177 | flock->fl_type = F_RDLCK; | 1185 | flock->fl_type = F_RDLCK; |
1178 | if (rc != 0) | 1186 | if (rc != 0) |
1179 | cERROR(1, "Error unlocking previously locked " | 1187 | cERROR(1, "Error unlocking previously locked " |
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index af48a8b8b75d..ce27f8698b20 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c | |||
@@ -60,8 +60,15 @@ send_nt_cancel(struct TCP_Server_Info *server, void *buf, | |||
60 | return rc; | 60 | return rc; |
61 | } | 61 | } |
62 | 62 | ||
63 | static bool | ||
64 | cifs_compare_fids(struct cifsFileInfo *ob1, struct cifsFileInfo *ob2) | ||
65 | { | ||
66 | return ob1->netfid == ob2->netfid; | ||
67 | } | ||
68 | |||
63 | struct smb_version_operations smb1_operations = { | 69 | struct smb_version_operations smb1_operations = { |
64 | .send_cancel = send_nt_cancel, | 70 | .send_cancel = send_nt_cancel, |
71 | .compare_fids = cifs_compare_fids, | ||
65 | }; | 72 | }; |
66 | 73 | ||
67 | struct smb_version_values smb1_values = { | 74 | struct smb_version_values smb1_values = { |