diff options
Diffstat (limited to 'fs/cifs/cifssmb.c')
| -rw-r--r-- | fs/cifs/cifssmb.c | 40 |
1 files changed, 35 insertions, 5 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index fd36892eda55..925881e00ff2 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) |
| @@ -1404,10 +1409,10 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, | |||
| 1404 | 1409 | ||
| 1405 | parm_data->lock_type = cpu_to_le16(lock_type); | 1410 | parm_data->lock_type = cpu_to_le16(lock_type); |
| 1406 | if(waitFlag) | 1411 | if(waitFlag) |
| 1407 | parm_data->lock_flags = 1; | 1412 | parm_data->lock_flags = cpu_to_le16(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 = cpu_to_le64(len); /* normalize negative numbers */ |
| 1411 | 1416 | ||
| 1412 | pSMB->DataOffset = cpu_to_le16(offset); | 1417 | pSMB->DataOffset = cpu_to_le16(offset); |
| 1413 | pSMB->Fid = smb_file_id; | 1418 | pSMB->Fid = smb_file_id; |
| @@ -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 | ||
