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 | ||