[CIFS] Fix new POSIX Locking for setting lock_type correctly on unlock
Signed-off-by: Steve French <sfrench@us.ibm.com>
This commit is contained in:
parent
d9ec5ad24c
commit
fc94cdb944
@ -1,3 +1,8 @@
|
|||||||
|
Version 1.43
|
||||||
|
------------
|
||||||
|
POSIX locking to servers which support CIFS POSIX Extensions
|
||||||
|
(disabled by default controlled by proc/fs/cifs/Experimental)
|
||||||
|
|
||||||
Version 1.42
|
Version 1.42
|
||||||
------------
|
------------
|
||||||
Fix slow oplock break when mounted to different servers at the same time and
|
Fix slow oplock break when mounted to different servers at the same time and
|
||||||
|
@ -99,5 +99,5 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
|
|||||||
extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
|
extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
|
||||||
extern int cifs_ioctl (struct inode * inode, struct file * filep,
|
extern int cifs_ioctl (struct inode * inode, struct file * filep,
|
||||||
unsigned int command, unsigned long arg);
|
unsigned int command, unsigned long arg);
|
||||||
#define CIFS_VERSION "1.42"
|
#define CIFS_VERSION "1.43"
|
||||||
#endif /* _CIFSFS_H */
|
#endif /* _CIFSFS_H */
|
||||||
|
@ -267,7 +267,7 @@ extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
|
|||||||
const int waitFlag);
|
const int waitFlag);
|
||||||
extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
|
extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
|
||||||
const __u16 smb_file_id, const int get_flag,
|
const __u16 smb_file_id, const int get_flag,
|
||||||
const __u64 len, const __u64 offset,
|
const __u64 len, struct file_lock *,
|
||||||
const __u16 lock_type, const int waitFlag);
|
const __u16 lock_type, const int waitFlag);
|
||||||
extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon);
|
extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon);
|
||||||
extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses);
|
extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses);
|
||||||
|
@ -1355,7 +1355,8 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
|
|||||||
int
|
int
|
||||||
CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
|
CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
|
||||||
const __u16 smb_file_id, const int get_flag, const __u64 len,
|
const __u16 smb_file_id, const int get_flag, const __u64 len,
|
||||||
const __u64 lkoffset, const __u16 lock_type, const int waitFlag)
|
struct file_lock *pLockData, const __u16 lock_type,
|
||||||
|
const int waitFlag)
|
||||||
{
|
{
|
||||||
struct smb_com_transaction2_sfi_req *pSMB = NULL;
|
struct smb_com_transaction2_sfi_req *pSMB = NULL;
|
||||||
struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
|
struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
|
||||||
@ -1366,6 +1367,10 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
|
|||||||
__u16 params, param_offset, offset, byte_count, count;
|
__u16 params, param_offset, offset, byte_count, count;
|
||||||
|
|
||||||
cFYI(1, ("Posix Lock"));
|
cFYI(1, ("Posix Lock"));
|
||||||
|
|
||||||
|
if(pLockData == NULL)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
|
rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
|
||||||
|
|
||||||
if (rc)
|
if (rc)
|
||||||
@ -1406,7 +1411,7 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
|
|||||||
if(waitFlag)
|
if(waitFlag)
|
||||||
parm_data->lock_flags = 1;
|
parm_data->lock_flags = 1;
|
||||||
parm_data->pid = cpu_to_le32(current->tgid);
|
parm_data->pid = cpu_to_le32(current->tgid);
|
||||||
parm_data->start = lkoffset;
|
parm_data->start = cpu_to_le64(pLockData->fl_start);
|
||||||
parm_data->length = len; /* normalize negative numbers */
|
parm_data->length = len; /* normalize negative numbers */
|
||||||
|
|
||||||
pSMB->DataOffset = cpu_to_le16(offset);
|
pSMB->DataOffset = cpu_to_le16(offset);
|
||||||
@ -1419,8 +1424,33 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
|
|||||||
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
|
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
cFYI(1, ("Send error in Posix Lock = %d", rc));
|
cFYI(1, ("Send error in Posix Lock = %d", rc));
|
||||||
}
|
} else if (get_flag) {
|
||||||
|
/* lock structure can be returned on get */
|
||||||
|
__u16 data_offset;
|
||||||
|
__u16 data_count;
|
||||||
|
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
|
||||||
|
|
||||||
|
if (rc || (pSMBr->ByteCount < sizeof(struct cifs_posix_lock))) {
|
||||||
|
rc = -EIO; /* bad smb */
|
||||||
|
goto plk_err_exit;
|
||||||
|
}
|
||||||
|
if(pLockData == NULL) {
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto plk_err_exit;
|
||||||
|
}
|
||||||
|
data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
|
||||||
|
data_count = le16_to_cpu(pSMBr->t2.DataCount);
|
||||||
|
if(data_count < sizeof(struct cifs_posix_lock)) {
|
||||||
|
rc = -EIO;
|
||||||
|
goto plk_err_exit;
|
||||||
|
}
|
||||||
|
parm_data = (struct cifs_posix_lock *)
|
||||||
|
((char *)&pSMBr->hdr.Protocol + data_offset);
|
||||||
|
if(parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
|
||||||
|
pLockData->fl_type = F_UNLCK;
|
||||||
|
}
|
||||||
|
|
||||||
|
plk_err_exit:
|
||||||
if (pSMB)
|
if (pSMB)
|
||||||
cifs_small_buf_release(pSMB);
|
cifs_small_buf_release(pSMB);
|
||||||
|
|
||||||
|
@ -656,7 +656,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
|
|||||||
else
|
else
|
||||||
posix_lock_type = CIFS_WRLCK;
|
posix_lock_type = CIFS_WRLCK;
|
||||||
rc = CIFSSMBPosixLock(xid, pTcon, netfid, 1 /* get */,
|
rc = CIFSSMBPosixLock(xid, pTcon, netfid, 1 /* get */,
|
||||||
length, pfLock->fl_start,
|
length, pfLock,
|
||||||
posix_lock_type, wait_flag);
|
posix_lock_type, wait_flag);
|
||||||
FreeXid(xid);
|
FreeXid(xid);
|
||||||
return rc;
|
return rc;
|
||||||
@ -704,7 +704,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
|
|||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */,
|
rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */,
|
||||||
length, pfLock->fl_start,
|
length, pfLock,
|
||||||
posix_lock_type, wait_flag);
|
posix_lock_type, wait_flag);
|
||||||
} else
|
} else
|
||||||
rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start,
|
rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user