aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Shilovsky <piastry@etersoft.ru>2012-02-28 06:04:17 -0500
committerPavel Shilovsky <piastry@etersoft.ru>2012-05-17 05:07:41 -0400
commit55157dfbb566e23e3c76489cb028fc82bd985ea1 (patch)
tree46f8284bce1d3d37f69c33731b637ea82fbffff5
parent106dc538abac88e804c63b7fe21ffb09cffaefc7 (diff)
CIFS: Separate protocol specific part from getlk
Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru>
-rw-r--r--fs/cifs/cifsglob.h2
-rw-r--r--fs/cifs/file.c52
-rw-r--r--fs/cifs/smb1ops.c7
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
157struct mid_q_entry; 157struct mid_q_entry;
158struct TCP_Server_Info; 158struct TCP_Server_Info;
159struct cifsFileInfo;
159 160
160struct smb_version_operations { 161struct 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
165struct smb_version_values { 167struct 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
672static bool 672static bool
673cifs_find_fid_lock_conflict(struct cifsFileInfo *cfile, __u64 offset, 673cifs_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
696static bool 696static bool
697cifs_find_lock_conflict(struct cifsInodeInfo *cinode, __u64 offset, 697cifs_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
1119static int 1119static int
1120cifs_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
1128static int
1120cifs_getlk(struct file *file, struct file_lock *flock, __u32 type, 1129cifs_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
63static bool
64cifs_compare_fids(struct cifsFileInfo *ob1, struct cifsFileInfo *ob2)
65{
66 return ob1->netfid == ob2->netfid;
67}
68
63struct smb_version_operations smb1_operations = { 69struct 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
67struct smb_version_values smb1_values = { 74struct smb_version_values smb1_values = {