[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
5 changed files with 42 additions and 7 deletions
|
@ -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
|
||||
------------
|
||||
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 int cifs_ioctl (struct inode * inode, struct file * filep,
|
||||
unsigned int command, unsigned long arg);
|
||||
#define CIFS_VERSION "1.42"
|
||||
#define CIFS_VERSION "1.43"
|
||||
#endif /* _CIFSFS_H */
|
||||
|
|
|
@ -267,7 +267,7 @@ extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
|
|||
const int waitFlag);
|
||||
extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
|
||||
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);
|
||||
extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon);
|
||||
extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses);
|
||||
|
|
|
@ -1355,7 +1355,8 @@ 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 file_lock *pLockData, const __u16 lock_type,
|
||||
const int waitFlag)
|
||||
{
|
||||
struct smb_com_transaction2_sfi_req *pSMB = 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;
|
||||
|
||||
cFYI(1, ("Posix Lock"));
|
||||
|
||||
if(pLockData == NULL)
|
||||
return EINVAL;
|
||||
|
||||
rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
|
||||
|
||||
if (rc)
|
||||
|
@ -1406,7 +1411,7 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
|
|||
if(waitFlag)
|
||||
parm_data->lock_flags = 1;
|
||||
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 */
|
||||
|
||||
pSMB->DataOffset = cpu_to_le16(offset);
|
||||
|
@ -1419,8 +1424,33 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
|
|||
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
|
||||
if (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)
|
||||
cifs_small_buf_release(pSMB);
|
||||
|
||||
|
|
|
@ -656,7 +656,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
|
|||
else
|
||||
posix_lock_type = CIFS_WRLCK;
|
||||
rc = CIFSSMBPosixLock(xid, pTcon, netfid, 1 /* get */,
|
||||
length, pfLock->fl_start,
|
||||
length, pfLock,
|
||||
posix_lock_type, wait_flag);
|
||||
FreeXid(xid);
|
||||
return rc;
|
||||
|
@ -704,7 +704,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
|
|||
return -EOPNOTSUPP;
|
||||
}
|
||||
rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */,
|
||||
length, pfLock->fl_start,
|
||||
length, pfLock,
|
||||
posix_lock_type, wait_flag);
|
||||
} else
|
||||
rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start,
|
||||
|
|
Loading…
Reference in a new issue