Commit 5f8bb1d8 authored by Pavel Shilovsky's avatar Pavel Shilovsky

Implement byte range lock cache for 3.0

parent 2dac6574
...@@ -963,7 +963,8 @@ cifs_init_once(void *inode) ...@@ -963,7 +963,8 @@ cifs_init_once(void *inode)
struct cifsInodeInfo *cifsi = inode; struct cifsInodeInfo *cifsi = inode;
inode_init_once(&cifsi->vfs_inode); inode_init_once(&cifsi->vfs_inode);
INIT_LIST_HEAD(&cifsi->lockList); INIT_LIST_HEAD(&cifsi->llist);
mutex_init(&cifsi->lock_mutex);
} }
static int static int
......
...@@ -486,9 +486,13 @@ extern struct cifs_tcon *cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb); ...@@ -486,9 +486,13 @@ extern struct cifs_tcon *cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb);
*/ */
struct cifsLockInfo { struct cifsLockInfo {
struct list_head llist; /* pointer to next cifsLockInfo */ struct list_head llist; /* pointer to next cifsLockInfo */
struct list_head blist; /* pointer to locks blocked on this */
wait_queue_head_t block_q;
__u64 offset; __u64 offset;
__u64 length; __u64 length;
__u32 pid;
__u8 type; __u8 type;
__u16 netfid;
}; };
/* /*
...@@ -521,8 +525,6 @@ struct cifsFileInfo { ...@@ -521,8 +525,6 @@ struct cifsFileInfo {
struct dentry *dentry; struct dentry *dentry;
unsigned int f_flags; unsigned int f_flags;
struct tcon_link *tlink; struct tcon_link *tlink;
struct mutex lock_mutex;
struct list_head llist; /* list of byte range locks we have. */
bool invalidHandle:1; /* file closed via session abend */ bool invalidHandle:1; /* file closed via session abend */
bool oplock_break_cancelled:1; bool oplock_break_cancelled:1;
int count; /* refcount protected by cifs_file_list_lock */ int count; /* refcount protected by cifs_file_list_lock */
...@@ -562,7 +564,9 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file); ...@@ -562,7 +564,9 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file);
*/ */
struct cifsInodeInfo { struct cifsInodeInfo {
struct list_head lockList; struct list_head llist; /* brlocks for this inode */
bool can_cache_brlcks;
struct mutex lock_mutex; /* protect two fields above */
/* BB add in lists for dirty pages i.e. write caching info for oplock */ /* BB add in lists for dirty pages i.e. write caching info for oplock */
struct list_head openFileList; struct list_head openFileList;
__u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */ __u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */
......
...@@ -359,14 +359,17 @@ extern int CIFSGetSrvInodeNumber(const int xid, struct cifs_tcon *tcon, ...@@ -359,14 +359,17 @@ extern int CIFSGetSrvInodeNumber(const int xid, struct cifs_tcon *tcon,
const struct nls_table *nls_codepage, const struct nls_table *nls_codepage,
int remap_special_chars); int remap_special_chars);
extern int cifs_lockv(const int xid, struct cifs_tcon *tcon, const __u16 netfid,
const __u8 lock_type, const __u32 num_unlock,
const __u32 num_lock, LOCKING_ANDX_RANGE *buf);
extern int CIFSSMBLock(const int xid, struct cifs_tcon *tcon, extern int CIFSSMBLock(const int xid, struct cifs_tcon *tcon,
const __u16 netfid, const __u64 len, const __u16 netfid, const __u32 netpid, const __u64 len,
const __u64 offset, const __u32 numUnlock, const __u64 offset, const __u32 numUnlock,
const __u32 numLock, const __u8 lockType, const __u32 numLock, const __u8 lockType,
const bool waitFlag, const __u8 oplock_level); const bool waitFlag, const __u8 oplock_level);
extern int CIFSSMBPosixLock(const int xid, struct cifs_tcon *tcon, extern int CIFSSMBPosixLock(const int xid, struct cifs_tcon *tcon,
const __u16 smb_file_id, const int get_flag, const __u16 smb_file_id, const __u32 netpid,
const __u64 len, struct file_lock *, const int get_flag, const __u64 len, struct file_lock *,
const __u16 lock_type, const bool waitFlag); const __u16 lock_type, const bool waitFlag);
extern int CIFSSMBTDis(const int xid, struct cifs_tcon *tcon); extern int CIFSSMBTDis(const int xid, struct cifs_tcon *tcon);
extern int CIFSSMBEcho(struct TCP_Server_Info *server); extern int CIFSSMBEcho(struct TCP_Server_Info *server);
......
...@@ -1969,10 +1969,50 @@ CIFSSMBWrite2(const int xid, struct cifs_io_parms *io_parms, ...@@ -1969,10 +1969,50 @@ CIFSSMBWrite2(const int xid, struct cifs_io_parms *io_parms,
return rc; return rc;
} }
int cifs_lockv(const int xid, struct cifs_tcon *tcon, const __u16 netfid,
const __u8 lock_type, const __u32 num_unlock,
const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
{
int rc = 0;
LOCK_REQ *pSMB = NULL;
struct kvec iov[2];
int resp_buf_type;
__u16 count;
cFYI(1, "cifs_lockv num lock %d num unlock %d", num_lock, num_unlock);
rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
if (rc)
return rc;
pSMB->Timeout = 0;
pSMB->NumberOfLocks = cpu_to_le16(num_lock);
pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
pSMB->LockType = lock_type;
pSMB->AndXCommand = 0xFF; /* none */
pSMB->Fid = netfid; /* netfid stays le */
count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
inc_rfc1001_len(pSMB, count);
pSMB->ByteCount = cpu_to_le16(count);
iov[0].iov_base = (char *)pSMB;
iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
(num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
iov[1].iov_base = (char *)buf;
iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
cifs_stats_inc(&tcon->num_locks);
rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type, CIFS_NO_RESP);
if (rc)
cFYI(1, "Send error in cifs_lockv = %d", rc);
return rc;
}
int int
CIFSSMBLock(const int xid, struct cifs_tcon *tcon, CIFSSMBLock(const int xid, struct cifs_tcon *tcon,
const __u16 smb_file_id, const __u64 len, const __u16 smb_file_id, const __u32 netpid, const __u64 len,
const __u64 offset, const __u32 numUnlock, const __u64 offset, const __u32 numUnlock,
const __u32 numLock, const __u8 lockType, const __u32 numLock, const __u8 lockType,
const bool waitFlag, const __u8 oplock_level) const bool waitFlag, const __u8 oplock_level)
...@@ -2008,7 +2048,7 @@ CIFSSMBLock(const int xid, struct cifs_tcon *tcon, ...@@ -2008,7 +2048,7 @@ CIFSSMBLock(const int xid, struct cifs_tcon *tcon,
pSMB->Fid = smb_file_id; /* netfid stays le */ pSMB->Fid = smb_file_id; /* netfid stays le */
if ((numLock != 0) || (numUnlock != 0)) { if ((numLock != 0) || (numUnlock != 0)) {
pSMB->Locks[0].Pid = cpu_to_le16(current->tgid); pSMB->Locks[0].Pid = cpu_to_le16(netpid);
/* BB where to store pid high? */ /* BB where to store pid high? */
pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len); pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32)); pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
...@@ -2042,9 +2082,9 @@ CIFSSMBLock(const int xid, struct cifs_tcon *tcon, ...@@ -2042,9 +2082,9 @@ CIFSSMBLock(const int xid, struct cifs_tcon *tcon,
int int
CIFSSMBPosixLock(const int xid, struct cifs_tcon *tcon, CIFSSMBPosixLock(const int xid, struct cifs_tcon *tcon,
const __u16 smb_file_id, const int get_flag, const __u64 len, const __u16 smb_file_id, const __u32 netpid, const int get_flag,
struct file_lock *pLockData, const __u16 lock_type, const __u64 len, struct file_lock *pLockData,
const bool waitFlag) const __u16 lock_type, const bool 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;
...@@ -2102,7 +2142,7 @@ CIFSSMBPosixLock(const int xid, struct cifs_tcon *tcon, ...@@ -2102,7 +2142,7 @@ CIFSSMBPosixLock(const int xid, struct cifs_tcon *tcon,
} else } else
pSMB->Timeout = 0; pSMB->Timeout = 0;
parm_data->pid = cpu_to_le32(current->tgid); parm_data->pid = cpu_to_le32(netpid);
parm_data->start = cpu_to_le64(pLockData->fl_start); parm_data->start = cpu_to_le64(pLockData->fl_start);
parm_data->length = cpu_to_le64(len); /* normalize negative numbers */ parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment