diff options
Diffstat (limited to 'fs/cifs/cifssmb.c')
-rw-r--r-- | fs/cifs/cifssmb.c | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 0ddd97b1d87d..fea32e395cc6 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -1353,6 +1353,84 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, | |||
1353 | } | 1353 | } |
1354 | 1354 | ||
1355 | int | 1355 | int |
1356 | CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, | ||
1357 | const __u16 smb_file_id, const int get_flag, const __u64 len, | ||
1358 | const __u64 lkoffset, const __u16 lock_type, const int waitFlag) | ||
1359 | { | ||
1360 | struct smb_com_transaction2_sfi_req *pSMB = NULL; | ||
1361 | struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; | ||
1362 | char *data_offset; | ||
1363 | struct cifs_posix_lock *parm_data; | ||
1364 | int rc = 0; | ||
1365 | int bytes_returned = 0; | ||
1366 | __u16 params, param_offset, offset, byte_count, count; | ||
1367 | |||
1368 | cFYI(1, ("Posix Lock")); | ||
1369 | rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); | ||
1370 | |||
1371 | if (rc) | ||
1372 | return rc; | ||
1373 | |||
1374 | pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB; | ||
1375 | |||
1376 | params = 6; | ||
1377 | pSMB->MaxSetupCount = 0; | ||
1378 | pSMB->Reserved = 0; | ||
1379 | pSMB->Flags = 0; | ||
1380 | pSMB->Timeout = 0; | ||
1381 | pSMB->Reserved2 = 0; | ||
1382 | param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; | ||
1383 | offset = param_offset + params; | ||
1384 | |||
1385 | data_offset = (char *) (&pSMB->hdr.Protocol) + offset; | ||
1386 | |||
1387 | count = sizeof(struct cifs_posix_lock); | ||
1388 | pSMB->MaxParameterCount = cpu_to_le16(2); | ||
1389 | pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */ | ||
1390 | pSMB->SetupCount = 1; | ||
1391 | pSMB->Reserved3 = 0; | ||
1392 | if(get_flag) | ||
1393 | pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); | ||
1394 | else | ||
1395 | pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); | ||
1396 | byte_count = 3 /* pad */ + params + count; | ||
1397 | pSMB->DataCount = cpu_to_le16(count); | ||
1398 | pSMB->ParameterCount = cpu_to_le16(params); | ||
1399 | pSMB->TotalDataCount = pSMB->DataCount; | ||
1400 | pSMB->TotalParameterCount = pSMB->ParameterCount; | ||
1401 | pSMB->ParameterOffset = cpu_to_le16(param_offset); | ||
1402 | parm_data = (struct cifs_posix_lock *) | ||
1403 | (((char *) &pSMB->hdr.Protocol) + offset); | ||
1404 | |||
1405 | parm_data->lock_type = cpu_to_le16(lock_type); | ||
1406 | if(waitFlag) | ||
1407 | parm_data->lock_flags = 1; | ||
1408 | parm_data->pid = cpu_to_le32(current->tgid); | ||
1409 | parm_data->start = lkoffset; | ||
1410 | parm_data->length = len; /* normalize negative numbers */ | ||
1411 | |||
1412 | pSMB->DataOffset = cpu_to_le16(offset); | ||
1413 | pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK); | ||
1414 | pSMB->Reserved4 = 0; | ||
1415 | pSMB->hdr.smb_buf_length += byte_count; | ||
1416 | pSMB->ByteCount = cpu_to_le16(byte_count); | ||
1417 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, | ||
1418 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | ||
1419 | if (rc) { | ||
1420 | cFYI(1, ("Send error in Posix Lock = %d", rc)); | ||
1421 | } | ||
1422 | |||
1423 | if (pSMB) | ||
1424 | cifs_small_buf_release(pSMB); | ||
1425 | |||
1426 | /* Note: On -EAGAIN error only caller can retry on handle based calls | ||
1427 | since file handle passed in no longer valid */ | ||
1428 | |||
1429 | return rc; | ||
1430 | } | ||
1431 | |||
1432 | |||
1433 | int | ||
1356 | CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id) | 1434 | CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id) |
1357 | { | 1435 | { |
1358 | int rc = 0; | 1436 | int rc = 0; |