aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifssmb.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/cifssmb.c')
-rw-r--r--fs/cifs/cifssmb.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 0ddd97b1d87d43..fea32e395cc69e 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -1353,6 +1353,84 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
}
int
+CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
+ const __u16 smb_file_id, const int get_flag, const __u64 len,
+ const __u64 lkoffset, const __u16 lock_type, const int waitFlag)
+{
+ struct smb_com_transaction2_sfi_req *pSMB = NULL;
+ struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
+ char *data_offset;
+ struct cifs_posix_lock *parm_data;
+ int rc = 0;
+ int bytes_returned = 0;
+ __u16 params, param_offset, offset, byte_count, count;
+
+ cFYI(1, ("Posix Lock"));
+ rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
+
+ if (rc)
+ return rc;
+
+ pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
+
+ params = 6;
+ pSMB->MaxSetupCount = 0;
+ pSMB->Reserved = 0;
+ pSMB->Flags = 0;
+ pSMB->Timeout = 0;
+ pSMB->Reserved2 = 0;
+ param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
+ offset = param_offset + params;
+
+ data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
+
+ count = sizeof(struct cifs_posix_lock);
+ pSMB->MaxParameterCount = cpu_to_le16(2);
+ pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */
+ pSMB->SetupCount = 1;
+ pSMB->Reserved3 = 0;
+ if(get_flag)
+ pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
+ else
+ pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
+ byte_count = 3 /* pad */ + params + count;
+ pSMB->DataCount = cpu_to_le16(count);
+ pSMB->ParameterCount = cpu_to_le16(params);
+ pSMB->TotalDataCount = pSMB->DataCount;
+ pSMB->TotalParameterCount = pSMB->ParameterCount;
+ pSMB->ParameterOffset = cpu_to_le16(param_offset);
+ parm_data = (struct cifs_posix_lock *)
+ (((char *) &pSMB->hdr.Protocol) + offset);
+
+ parm_data->lock_type = cpu_to_le16(lock_type);
+ if(waitFlag)
+ parm_data->lock_flags = 1;
+ parm_data->pid = cpu_to_le32(current->tgid);
+ parm_data->start = lkoffset;
+ parm_data->length = len; /* normalize negative numbers */
+
+ pSMB->DataOffset = cpu_to_le16(offset);
+ pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
+ pSMB->Reserved4 = 0;
+ pSMB->hdr.smb_buf_length += byte_count;
+ pSMB->ByteCount = cpu_to_le16(byte_count);
+ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+ (struct smb_hdr *) pSMBr, &bytes_returned, 0);
+ if (rc) {
+ cFYI(1, ("Send error in Posix Lock = %d", rc));
+ }
+
+ if (pSMB)
+ cifs_small_buf_release(pSMB);
+
+ /* Note: On -EAGAIN error only caller can retry on handle based calls
+ since file handle passed in no longer valid */
+
+ return rc;
+}
+
+
+int
CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
{
int rc = 0;