diff options
| -rw-r--r-- | fs/cifs/CHANGES | 5 | ||||
| -rw-r--r-- | fs/cifs/cifsfs.h | 2 | ||||
| -rw-r--r-- | fs/cifs/cifsproto.h | 2 | ||||
| -rw-r--r-- | fs/cifs/cifssmb.c | 36 | ||||
| -rw-r--r-- | fs/cifs/file.c | 4 |
5 files changed, 42 insertions, 7 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 1a27ecb46c9a..dfd364c66313 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
| @@ -1,3 +1,8 @@ | |||
| 1 | Version 1.43 | ||
| 2 | ------------ | ||
| 3 | POSIX locking to servers which support CIFS POSIX Extensions | ||
| 4 | (disabled by default controlled by proc/fs/cifs/Experimental) | ||
| 5 | |||
| 1 | Version 1.42 | 6 | Version 1.42 |
| 2 | ------------ | 7 | ------------ |
| 3 | Fix slow oplock break when mounted to different servers at the same time and | 8 | Fix slow oplock break when mounted to different servers at the same time and |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 4e829dc672a6..c98755dca868 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
| @@ -99,5 +99,5 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); | |||
| 99 | extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); | 99 | extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); |
| 100 | extern int cifs_ioctl (struct inode * inode, struct file * filep, | 100 | extern int cifs_ioctl (struct inode * inode, struct file * filep, |
| 101 | unsigned int command, unsigned long arg); | 101 | unsigned int command, unsigned long arg); |
| 102 | #define CIFS_VERSION "1.42" | 102 | #define CIFS_VERSION "1.43" |
| 103 | #endif /* _CIFSFS_H */ | 103 | #endif /* _CIFSFS_H */ |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 2879ba343ca7..310ea2f0e0bf 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
| @@ -267,7 +267,7 @@ extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, | |||
| 267 | const int waitFlag); | 267 | const int waitFlag); |
| 268 | extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, | 268 | extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, |
| 269 | const __u16 smb_file_id, const int get_flag, | 269 | const __u16 smb_file_id, const int get_flag, |
| 270 | const __u64 len, const __u64 offset, | 270 | const __u64 len, struct file_lock *, |
| 271 | const __u16 lock_type, const int waitFlag); | 271 | const __u16 lock_type, const int waitFlag); |
| 272 | extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon); | 272 | extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon); |
| 273 | extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses); | 273 | extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses); |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index fd36892eda55..20d5e748f41e 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
| @@ -1355,7 +1355,8 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, | |||
| 1355 | int | 1355 | int |
| 1356 | CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, | 1356 | CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, |
| 1357 | const __u16 smb_file_id, const int get_flag, const __u64 len, | 1357 | const __u16 smb_file_id, const int get_flag, const __u64 len, |
| 1358 | const __u64 lkoffset, const __u16 lock_type, const int waitFlag) | 1358 | struct file_lock *pLockData, const __u16 lock_type, |
| 1359 | const int waitFlag) | ||
| 1359 | { | 1360 | { |
| 1360 | struct smb_com_transaction2_sfi_req *pSMB = NULL; | 1361 | struct smb_com_transaction2_sfi_req *pSMB = NULL; |
| 1361 | struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; | 1362 | struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; |
| @@ -1366,6 +1367,10 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, | |||
| 1366 | __u16 params, param_offset, offset, byte_count, count; | 1367 | __u16 params, param_offset, offset, byte_count, count; |
| 1367 | 1368 | ||
| 1368 | cFYI(1, ("Posix Lock")); | 1369 | cFYI(1, ("Posix Lock")); |
| 1370 | |||
| 1371 | if(pLockData == NULL) | ||
| 1372 | return EINVAL; | ||
| 1373 | |||
| 1369 | rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); | 1374 | rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); |
| 1370 | 1375 | ||
| 1371 | if (rc) | 1376 | if (rc) |
| @@ -1406,7 +1411,7 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, | |||
| 1406 | if(waitFlag) | 1411 | if(waitFlag) |
| 1407 | parm_data->lock_flags = 1; | 1412 | parm_data->lock_flags = 1; |
| 1408 | parm_data->pid = cpu_to_le32(current->tgid); | 1413 | parm_data->pid = cpu_to_le32(current->tgid); |
| 1409 | parm_data->start = lkoffset; | 1414 | parm_data->start = cpu_to_le64(pLockData->fl_start); |
| 1410 | parm_data->length = len; /* normalize negative numbers */ | 1415 | parm_data->length = len; /* normalize negative numbers */ |
| 1411 | 1416 | ||
| 1412 | pSMB->DataOffset = cpu_to_le16(offset); | 1417 | pSMB->DataOffset = cpu_to_le16(offset); |
| @@ -1419,8 +1424,33 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, | |||
| 1419 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | 1424 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); |
| 1420 | if (rc) { | 1425 | if (rc) { |
| 1421 | cFYI(1, ("Send error in Posix Lock = %d", rc)); | 1426 | cFYI(1, ("Send error in Posix Lock = %d", rc)); |
| 1422 | } | 1427 | } else if (get_flag) { |
| 1428 | /* lock structure can be returned on get */ | ||
| 1429 | __u16 data_offset; | ||
| 1430 | __u16 data_count; | ||
| 1431 | rc = validate_t2((struct smb_t2_rsp *)pSMBr); | ||
| 1423 | 1432 | ||
| 1433 | if (rc || (pSMBr->ByteCount < sizeof(struct cifs_posix_lock))) { | ||
| 1434 | rc = -EIO; /* bad smb */ | ||
| 1435 | goto plk_err_exit; | ||
| 1436 | } | ||
| 1437 | if(pLockData == NULL) { | ||
| 1438 | rc = -EINVAL; | ||
| 1439 | goto plk_err_exit; | ||
| 1440 | } | ||
| 1441 | data_offset = le16_to_cpu(pSMBr->t2.DataOffset); | ||
| 1442 | data_count = le16_to_cpu(pSMBr->t2.DataCount); | ||
| 1443 | if(data_count < sizeof(struct cifs_posix_lock)) { | ||
| 1444 | rc = -EIO; | ||
| 1445 | goto plk_err_exit; | ||
| 1446 | } | ||
| 1447 | parm_data = (struct cifs_posix_lock *) | ||
| 1448 | ((char *)&pSMBr->hdr.Protocol + data_offset); | ||
| 1449 | if(parm_data->lock_type == cpu_to_le16(CIFS_UNLCK)) | ||
| 1450 | pLockData->fl_type = F_UNLCK; | ||
| 1451 | } | ||
| 1452 | |||
| 1453 | plk_err_exit: | ||
| 1424 | if (pSMB) | 1454 | if (pSMB) |
| 1425 | cifs_small_buf_release(pSMB); | 1455 | cifs_small_buf_release(pSMB); |
| 1426 | 1456 | ||
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index e152bf6afa60..7ef30efe8f98 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
| @@ -656,7 +656,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
| 656 | else | 656 | else |
| 657 | posix_lock_type = CIFS_WRLCK; | 657 | posix_lock_type = CIFS_WRLCK; |
| 658 | rc = CIFSSMBPosixLock(xid, pTcon, netfid, 1 /* get */, | 658 | rc = CIFSSMBPosixLock(xid, pTcon, netfid, 1 /* get */, |
| 659 | length, pfLock->fl_start, | 659 | length, pfLock, |
| 660 | posix_lock_type, wait_flag); | 660 | posix_lock_type, wait_flag); |
| 661 | FreeXid(xid); | 661 | FreeXid(xid); |
| 662 | return rc; | 662 | return rc; |
| @@ -704,7 +704,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
| 704 | return -EOPNOTSUPP; | 704 | return -EOPNOTSUPP; |
| 705 | } | 705 | } |
| 706 | rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */, | 706 | rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */, |
| 707 | length, pfLock->fl_start, | 707 | length, pfLock, |
| 708 | posix_lock_type, wait_flag); | 708 | posix_lock_type, wait_flag); |
| 709 | } else | 709 | } else |
| 710 | rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start, | 710 | rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start, |
