Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff -u cifs.vanilla/cifsfs.c cifs/cifsfs.c
- --- cifs.vanilla/cifsfs.c 2010-06-01 18:56:03.000000000 +0200
- +++ cifs/cifsfs.c 2010-08-14 12:00:00.000000000 +0200
- @@ -64,6 +64,9 @@
- unsigned int extended_security = CIFSSEC_DEF;
- /* unsigned int ntlmv2_support = 0; */
- unsigned int sign_CIFS_PDUs = 1;
- +extern struct task_struct *oplockThread; /* remove sparse warning */
- +struct task_struct *oplockThread = NULL;
- +/* extern struct task_struct * dnotifyThread; remove sparse warning */
- static const struct super_operations cifs_super_ops;
- unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
- module_param(CIFSMaxBufSize, int, 0);
- @@ -969,12 +972,89 @@
- kmem_cache_destroy(cifs_oplock_cachep);
- }
- +static int cifs_oplock_thread(void *dummyarg)
- +{
- + struct oplock_q_entry *oplock_item;
- + struct cifsTconInfo *pTcon;
- + struct inode *inode;
- + __u16 netfid;
- + int rc, waitrc = 0;
- +
- + set_freezable();
- + do {
- + if (try_to_freeze())
- + continue;
- +
- + spin_lock(&GlobalMid_Lock);
- + if (list_empty(&GlobalOplock_Q)) {
- + spin_unlock(&GlobalMid_Lock);
- + set_current_state(TASK_INTERRUPTIBLE);
- + schedule_timeout(39*HZ);
- + } else {
- + oplock_item = list_entry(GlobalOplock_Q.next,
- + struct oplock_q_entry, qhead);
- + cFYI(1, ("found oplock item to write out"));
- + pTcon = oplock_item->tcon;
- + inode = oplock_item->pinode;
- + netfid = oplock_item->netfid;
- + spin_unlock(&GlobalMid_Lock);
- + DeleteOplockQEntry(oplock_item);
- + /* can not grab inode sem here since it would
- + deadlock when oplock received on delete
- + since vfs_unlink holds the i_mutex across
- + the call */
- + /* mutex_lock(&inode->i_mutex);*/
- + if (S_ISREG(inode->i_mode)) {
- +#ifdef CONFIG_CIFS_EXPERIMENTAL
- + if (CIFS_I(inode)->clientCanCacheAll == 0)
- + break_lease(inode, FMODE_READ);
- + else if (CIFS_I(inode)->clientCanCacheRead == 0)
- + break_lease(inode, FMODE_WRITE);
- +#endif
- + rc = filemap_fdatawrite(inode->i_mapping);
- + if (CIFS_I(inode)->clientCanCacheRead == 0) {
- + waitrc = filemap_fdatawait(
- + inode->i_mapping);
- + invalidate_remote_inode(inode);
- + }
- + if (rc == 0)
- + rc = waitrc;
- + } else
- + rc = 0;
- + /* mutex_unlock(&inode->i_mutex);*/
- + if (rc)
- + CIFS_I(inode)->write_behind_rc = rc;
- + cFYI(1, ("Oplock flush inode %p rc %d",
- + inode, rc));
- +
- + /* releasing stale oplock after recent reconnect
- + of smb session using a now incorrect file
- + handle is not a data integrity issue but do
- + not bother sending an oplock release if session
- + to server still is disconnected since oplock
- + already released by the server in that case */
- + if (!pTcon->need_reconnect) {
- + rc = CIFSSMBLock(0, pTcon, netfid,
- + 0 /* len */ , 0 /* offset */, 0,
- + 0, LOCKING_ANDX_OPLOCK_RELEASE,
- + false /* wait flag */);
- + cFYI(1, ("Oplock release rc = %d", rc));
- + }
- + set_current_state(TASK_INTERRUPTIBLE);
- + schedule_timeout(1); /* yield in case q were corrupt */
- + }
- + } while (!kthread_should_stop());
- +
- + return 0;
- +}
- +
- static int __init
- init_cifs(void)
- {
- int rc = 0;
- cifs_proc_init();
- INIT_LIST_HEAD(&cifs_tcp_ses_list);
- + INIT_LIST_HEAD(&GlobalOplock_Q);
- #ifdef CONFIG_CIFS_EXPERIMENTAL
- INIT_LIST_HEAD(&GlobalDnotifyReqList);
- INIT_LIST_HEAD(&GlobalDnotifyRsp_Q);
- @@ -1037,9 +1117,12 @@
- if (rc)
- goto out_unregister_key_type;
- #endif
- - rc = slow_work_register_user(THIS_MODULE);
- - if (rc)
- - goto out_unregister_resolver_key;
- + oplockThread = kthread_run(cifs_oplock_thread, NULL, "cifsoplockd");
- + if (IS_ERR(oplockThread)) {
- + rc = PTR_ERR(oplockThread);
- + cERROR(1, ("error %d create oplock thread", rc));
- + goto out_unregister_resolver_key;
- + }
- return 0;
- @@ -1080,6 +1163,7 @@
- cifs_destroy_inodecache();
- cifs_destroy_mids();
- cifs_destroy_request_bufs();
- + kthread_stop(oplockThread);
- }
- MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>");
- diff -u cifs.vanilla/cifsglob.h cifs/cifsglob.h
- --- cifs.vanilla/cifsglob.h 2010-06-01 18:56:03.000000000 +0200
- +++ cifs/cifsglob.h 2010-08-14 12:00:00.000000000 +0200
- @@ -18,7 +18,6 @@
- */
- #include <linux/in.h>
- #include <linux/in6.h>
- -#include <linux/slow-work.h>
- #include "cifs_fs_sb.h"
- #include "cifsacl.h"
- /*
- @@ -356,7 +355,6 @@
- atomic_t count; /* reference count */
- struct mutex fh_mutex; /* prevents reopen race after dead ses*/
- struct cifs_search_info srch_inf;
- - struct slow_work oplock_break; /* slow_work job for oplock breaks */
- };
- /* Take a reference on the file private data */
- @@ -674,6 +672,8 @@
- */
- GLOBAL_EXTERN rwlock_t GlobalSMBSeslock;
- +GLOBAL_EXTERN struct list_head GlobalOplock_Q;
- +
- /* Outstanding dir notify requests */
- GLOBAL_EXTERN struct list_head GlobalDnotifyReqList;
- /* DirNotify response queue */
- @@ -724,4 +724,3 @@
- GLOBAL_EXTERN unsigned int cifs_min_small; /* min size of small buf pool */
- GLOBAL_EXTERN unsigned int cifs_max_pending; /* MAX requests at once to server*/
- -extern const struct slow_work_ops cifs_oplock_break_ops;
- diff -u cifs.vanilla/cifsproto.h cifs/cifsproto.h
- --- cifs.vanilla/cifsproto.h 2010-06-01 18:56:03.000000000 +0200
- +++ cifs/cifsproto.h 2010-08-14 12:00:00.000000000 +0200
- @@ -86,6 +86,10 @@
- const int stage,
- const struct nls_table *nls_cp);
- extern __u16 GetNextMid(struct TCP_Server_Info *server);
- +extern struct oplock_q_entry *AllocOplockQEntry(struct inode *, u16,
- + struct cifsTconInfo *);
- +extern void DeleteOplockQEntry(struct oplock_q_entry *);
- +extern void DeleteTconOplockQEntries(struct cifsTconInfo *);
- extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601);
- extern u64 cifs_UnixTimeToNT(struct timespec);
- extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time,
- diff -u cifs.vanilla/cifs_spnego.c cifs/cifs_spnego.c
- --- cifs.vanilla/cifs_spnego.c 2010-06-01 18:56:03.000000000 +0200
- +++ cifs/cifs_spnego.c 2010-08-14 12:00:00.000000000 +0200
- @@ -125,7 +125,7 @@
- if (server->addr.sockAddr.sin_family == AF_INET)
- sprintf(dp, "ip4=%pI4", &server->addr.sockAddr.sin_addr);
- else if (server->addr.sockAddr.sin_family == AF_INET6)
- - sprintf(dp, "ip6=%pI6", &server->addr.sockAddr6.sin6_addr);
- + sprintf(dp, "ip6=%pi6", &server->addr.sockAddr6.sin6_addr);
- else
- goto out;
- diff -u cifs.vanilla/dir.c cifs/dir.c
- --- cifs.vanilla/dir.c 2010-06-01 18:56:03.000000000 +0200
- +++ cifs/dir.c 2010-08-14 12:00:00.000000000 +0200
- @@ -157,7 +157,6 @@
- mutex_init(&pCifsFile->lock_mutex);
- INIT_LIST_HEAD(&pCifsFile->llist);
- atomic_set(&pCifsFile->count, 1);
- - slow_work_init(&pCifsFile->oplock_break, &cifs_oplock_break_ops);
- write_lock(&GlobalSMBSeslock);
- list_add(&pCifsFile->tlist, &cifs_sb->tcon->openFileList);
- @@ -178,7 +177,7 @@
- pCifsInode->clientCanCacheRead = true;
- }
- write_unlock(&GlobalSMBSeslock);
- -
- +
- return pCifsFile;
- }
- diff -u cifs.vanilla/file.c cifs/file.c
- --- cifs.vanilla/file.c 2010-06-01 18:56:03.000000000 +0200
- +++ cifs/file.c 2010-08-14 12:00:00.000000000 +0200
- @@ -2274,73 +2274,6 @@
- return rc;
- }
- -static void
- -cifs_oplock_break(struct slow_work *work)
- -{
- - struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo,
- - oplock_break);
- - struct inode *inode = cfile->pInode;
- - struct cifsInodeInfo *cinode = CIFS_I(inode);
- - struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->mnt->mnt_sb);
- - int rc, waitrc = 0;
- -
- - if (inode && S_ISREG(inode->i_mode)) {
- -#ifdef CONFIG_CIFS_EXPERIMENTAL
- - if (cinode->clientCanCacheAll == 0)
- - break_lease(inode, FMODE_READ);
- - else if (cinode->clientCanCacheRead == 0)
- - break_lease(inode, FMODE_WRITE);
- -#endif
- - rc = filemap_fdatawrite(inode->i_mapping);
- - if (cinode->clientCanCacheRead == 0) {
- - waitrc = filemap_fdatawait(inode->i_mapping);
- - invalidate_remote_inode(inode);
- - }
- - if (!rc)
- - rc = waitrc;
- - if (rc)
- - cinode->write_behind_rc = rc;
- - cFYI(1, ("Oplock flush inode %p rc %d", inode, rc));
- - }
- -
- - /*
- - * releasing stale oplock after recent reconnect of smb session using
- - * a now incorrect file handle is not a data integrity issue but do
- - * not bother sending an oplock release if session to server still is
- - * disconnected since oplock already released by the server
- - */
- - if (!cfile->closePend && !cfile->oplock_break_cancelled) {
- - rc = CIFSSMBLock(0, cifs_sb->tcon, cfile->netfid, 0, 0, 0, 0,
- - LOCKING_ANDX_OPLOCK_RELEASE, false);
- - cFYI(1, ("Oplock release rc = %d", rc));
- - }
- -}
- -
- -static int
- -cifs_oplock_break_get(struct slow_work *work)
- -{
- - struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo,
- - oplock_break);
- - mntget(cfile->mnt);
- - cifsFileInfo_get(cfile);
- - return 0;
- -}
- -
- -static void
- -cifs_oplock_break_put(struct slow_work *work)
- -{
- - struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo,
- - oplock_break);
- - mntput(cfile->mnt);
- - cifsFileInfo_put(cfile);
- -}
- -
- -const struct slow_work_ops cifs_oplock_break_ops = {
- - .get_ref = cifs_oplock_break_get,
- - .put_ref = cifs_oplock_break_put,
- - .execute = cifs_oplock_break,
- -};
- -
- const struct address_space_operations cifs_addr_ops = {
- .readpage = cifs_readpage,
- .readpages = cifs_readpages,
- diff -u cifs.vanilla/inode.c cifs/inode.c
- --- cifs.vanilla/inode.c 2010-06-01 18:56:03.000000000 +0200
- +++ cifs/inode.c 2010-08-14 12:00:00.000000000 +0200
- @@ -82,7 +82,6 @@
- cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
- {
- struct cifsInodeInfo *cifs_i = CIFS_I(inode);
- - struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
- unsigned long oldtime = cifs_i->time;
- inode->i_atime = fattr->cf_atime;
- @@ -93,10 +92,7 @@
- inode->i_uid = fattr->cf_uid;
- inode->i_gid = fattr->cf_gid;
- - /* if dynperm is set, don't clobber existing mode */
- - if (inode->i_state & I_NEW ||
- - !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM))
- - inode->i_mode = fattr->cf_mode;
- + inode->i_mode = fattr->cf_mode;
- cifs_i->cifsAttrs = fattr->cf_cifsattrs;
- cifs_i->uniqueid = fattr->cf_uniqueid;
- diff -u cifs.vanilla/Kconfig cifs/Kconfig
- --- cifs.vanilla/Kconfig 2010-06-01 18:56:03.000000000 +0200
- +++ cifs/Kconfig 2010-08-14 12:00:00.000000000 +0200
- @@ -2,7 +2,6 @@
- tristate "CIFS support (advanced network filesystem, SMBFS successor)"
- depends on INET
- select NLS
- - select SLOW_WORK
- help
- This is the client VFS module for the Common Internet File System
- (CIFS) protocol which is the successor to the Server Message Block
- diff -u cifs.vanilla/misc.c cifs/misc.c
- --- cifs.vanilla/misc.c 2010-06-01 18:56:03.000000000 +0200
- +++ cifs/misc.c 2010-08-14 12:00:00.000000000 +0200
- @@ -32,6 +32,7 @@
- extern mempool_t *cifs_sm_req_poolp;
- extern mempool_t *cifs_req_poolp;
- +extern struct task_struct *oplockThread;
- /* The xid serves as a useful identifier for each incoming vfs request,
- in a similar way to the mid which is useful to track each sent smb,
- @@ -499,7 +500,6 @@
- struct cifsTconInfo *tcon;
- struct cifsInodeInfo *pCifsInode;
- struct cifsFileInfo *netfile;
- - int rc;
- cFYI(1, ("Checking for oplock break or dnotify response"));
- if ((pSMB->hdr.Command == SMB_COM_NT_TRANSACT) &&
- @@ -578,17 +578,18 @@
- read_unlock(&cifs_tcp_ses_lock);
- return true;
- }
- -
- +
- cFYI(1, ("file id match, oplock break"));
- pCifsInode = CIFS_I(netfile->pInode);
- pCifsInode->clientCanCacheAll = false;
- if (pSMB->OplockLevel == 0)
- pCifsInode->clientCanCacheRead = false;
- - rc = slow_work_enqueue(&netfile->oplock_break);
- - if (rc) {
- - cERROR(1, ("failed to enqueue oplock "
- - "break: %d\n", rc));
- - } else {
- + AllocOplockQEntry(netfile->pInode,
- + netfile->netfid, tcon);
- + cFYI(1, ("about to wake up oplock thread"));
- + if (oplockThread)
- + {
- + wake_up_process(oplockThread);
- netfile->oplock_break_cancelled = false;
- }
- read_unlock(&GlobalSMBSeslock);
- diff -u cifs.vanilla/transport.c cifs/transport.c
- --- cifs.vanilla/transport.c 2010-06-01 18:56:03.000000000 +0200
- +++ cifs/transport.c 2010-08-14 12:00:00.000000000 +0200
- @@ -103,6 +103,57 @@
- mempool_free(midEntry, cifs_mid_poolp);
- }
- +struct oplock_q_entry *
- +AllocOplockQEntry(struct inode *pinode, __u16 fid, struct cifsTconInfo *tcon)
- +{
- + struct oplock_q_entry *temp;
- + if ((pinode == NULL) || (tcon == NULL)) {
- + cERROR(1, ("Null parms passed to AllocOplockQEntry"));
- + return NULL;
- + }
- + temp = (struct oplock_q_entry *) kmem_cache_alloc(cifs_oplock_cachep,
- + GFP_KERNEL);
- + if (temp == NULL)
- + return temp;
- + else {
- + temp->pinode = pinode;
- + temp->tcon = tcon;
- + temp->netfid = fid;
- + spin_lock(&GlobalMid_Lock);
- + list_add_tail(&temp->qhead, &GlobalOplock_Q);
- + spin_unlock(&GlobalMid_Lock);
- + }
- + return temp;
- +
- +}
- +
- +void DeleteOplockQEntry(struct oplock_q_entry *oplockEntry)
- +{
- + spin_lock(&GlobalMid_Lock);
- + /* should we check if list empty first? */
- + list_del(&oplockEntry->qhead);
- + spin_unlock(&GlobalMid_Lock);
- + kmem_cache_free(cifs_oplock_cachep, oplockEntry);
- +}
- +
- +
- +void DeleteTconOplockQEntries(struct cifsTconInfo *tcon)
- +{
- + struct oplock_q_entry *temp;
- +
- + if (tcon == NULL)
- + return;
- +
- + spin_lock(&GlobalMid_Lock);
- + list_for_each_entry(temp, &GlobalOplock_Q, qhead) {
- + if ((temp->tcon) && (temp->tcon == tcon)) {
- + list_del(&temp->qhead);
- + kmem_cache_free(cifs_oplock_cachep, temp);
- + }
- + }
- + spin_unlock(&GlobalMid_Lock);
- +}
- +
- static int
- smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
- {
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement