Author: asser Date: 2005-08-28 14:59:17 +0000 (Sun, 28 Aug 2005) New Revision: 40
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=linux-cifs-client&rev=40 Log: fixed is_valid_dnotify_rsp not accepting STATUS_SUCCESS without file_notify_information structs Added a kmem_cache for the dir_notify_req structs Modified: branches/SOC/linux-2.6bk-dnotify/fs/cifs/cifsfs.c branches/SOC/linux-2.6bk-dnotify/fs/cifs/cifssmb.c branches/SOC/linux-2.6bk-dnotify/fs/cifs/misc.c Changeset: Modified: branches/SOC/linux-2.6bk-dnotify/fs/cifs/cifsfs.c =================================================================== --- branches/SOC/linux-2.6bk-dnotify/fs/cifs/cifsfs.c 2005-08-26 16:35:18 UTC (rev 39) +++ branches/SOC/linux-2.6bk-dnotify/fs/cifs/cifsfs.c 2005-08-28 14:59:17 UTC (rev 40) @@ -83,6 +83,7 @@ extern mempool_t *cifs_mid_poolp; extern kmem_cache_t *cifs_oplock_cachep; +extern kmem_cache_t *cifs_dnotify_cachep; static int cifs_read_super(struct super_block *sb, void *data, @@ -235,6 +236,7 @@ static kmem_cache_t *cifs_req_cachep; static kmem_cache_t *cifs_mid_cachep; kmem_cache_t *cifs_oplock_cachep; +kmem_cache_t *cifs_dnotify_cachep; static kmem_cache_t *cifs_sm_req_cachep; mempool_t *cifs_sm_req_poolp; mempool_t *cifs_req_poolp; @@ -755,6 +757,16 @@ mempool_destroy(cifs_mid_poolp); return -ENOMEM; } + + cifs_dnotify_cachep = kmem_cache_create("cifs_dir_notify_req_structs", + sizeof (struct dir_notify_req), 0, + SLAB_HWCACHE_ALIGN, NULL, NULL); + if(cifs_dnotify_cachep == NULL) { + kmem_cache_destroy(cifs_oplock_cachep); + kmem_cache_destroy(cifs_mid_cachep); + mempool_destroy(cifs_mid_poolp); + return -ENOMEM; + } return 0; } @@ -770,6 +782,10 @@ if (kmem_cache_destroy(cifs_oplock_cachep)) printk(KERN_WARNING "error not all oplock structures were freed\n"); + + if (kmem_cache_destroy(cifs_dnotify_cachep)) + printk(KERN_WARNING + "error not all dnotify structures were freed\n"); } static int cifs_oplock_thread(void * dummyarg) @@ -895,7 +911,7 @@ cERROR(1,("CIFSSMBClose failed in cifs_dnotify_thread rc = %d", rc)); } } - kfree(dnotify_req); + kmem_cache_free(cifs_dnotify_cachep, dnotify_req); FreeXid(xid); } } Modified: branches/SOC/linux-2.6bk-dnotify/fs/cifs/cifssmb.c =================================================================== --- branches/SOC/linux-2.6bk-dnotify/fs/cifs/cifssmb.c 2005-08-26 16:35:18 UTC (rev 39) +++ branches/SOC/linux-2.6bk-dnotify/fs/cifs/cifssmb.c 2005-08-28 14:59:17 UTC (rev 40) @@ -38,6 +38,8 @@ #include "cifs_unicode.h" #include "cifs_debug.h" +extern kmem_cache_t *cifs_dnotify_cachep; + #ifdef CONFIG_CIFS_POSIX static struct { int index; @@ -3906,8 +3908,8 @@ cFYI(1, ("Error in Notify = %d", rc)); } else { /* Add file to outstanding requests */ - dnotify_req = (struct dir_notify_req *) kmalloc( - sizeof(struct dir_notify_req), GFP_KERNEL); + dnotify_req = (struct dir_notify_req*) kmem_cache_alloc(cifs_dnotify_cachep, + SLAB_KERNEL); dnotify_req->Pid = pSMB->hdr.Pid; dnotify_req->PidHigh = pSMB->hdr.PidHigh; dnotify_req->Mid = pSMB->hdr.Mid; @@ -3917,10 +3919,9 @@ dnotify_req->file = file; dnotify_req->filter = filter; dnotify_req->multishot = multishot; - cFYI(1,("Locking GlobalMid_Lock")); + spin_lock(&GlobalMid_Lock); list_add_tail(&dnotify_req->lhead, &GlobalDnotifyReqList); - cFYI(1,("Unlocking GlobalMid_Lock")); spin_unlock(&GlobalMid_Lock); } cifs_buf_release(pSMB); Modified: branches/SOC/linux-2.6bk-dnotify/fs/cifs/misc.c =================================================================== --- branches/SOC/linux-2.6bk-dnotify/fs/cifs/misc.c 2005-08-26 16:35:18 UTC (rev 39) +++ branches/SOC/linux-2.6bk-dnotify/fs/cifs/misc.c 2005-08-28 14:59:17 UTC (rev 40) @@ -30,6 +30,7 @@ #include "nterr.h" #include "cifs_unicode.h" +extern kmem_cache_t *cifs_dnotify_cachep; extern mempool_t *cifs_sm_req_poolp; extern mempool_t *cifs_req_poolp; extern struct task_struct * oplockThread; @@ -407,32 +408,33 @@ cFYI(1,("pSMBr ParameterOffset:%ld DataOffset:%ld", (unsigned long)pSMBr->ParameterOffset, (unsigned long)pSMBr->DataOffset)); pnotify = (struct file_notify_information *) (&pSMBr->hdr.Protocol) + pSMBr->DataOffset; cFYI(1,("pnotify NextEntryOffset:%lx Action:%lx FileNameLength:%ld",(unsigned long)pnotify->NextEntryOffset,(unsigned long)pnotify->Action,(unsigned long)pnotify->FileNameLength)); - cFYI(1,("notify err 0x%x (cancelled == 0x%x)",pSMBr->hdr.Status.CifsError,(NT_STATUS_CANCELLED))); - if((pSMBr->ByteCount > sizeof(struct file_notify_information)) || - (pSMBr->hdr.Status.CifsError)) { - /* Find the request on the req list */ - spin_lock(&GlobalMid_Lock); - list_for_each_safe(tmp, tmp1, &GlobalDnotifyReqList) { - dnotify_req = list_entry(tmp, struct dir_notify_req, lhead); + cFYI(1,("notify err 0x%x",pSMBr->hdr.Status.CifsError)); + /* Find the request on the req list */ + spin_lock(&GlobalMid_Lock); + list_for_each_safe(tmp, tmp1, &GlobalDnotifyReqList) { + dnotify_req = list_entry(tmp, struct dir_notify_req, lhead); - if(dnotify_req->Mid == pSMBr->hdr.Mid && - dnotify_req->PidHigh == pSMBr->hdr.PidHigh && - dnotify_req->Pid == pSMBr->hdr.Pid) - { - list_del(tmp); - if ((NT_STATUS_CANCELLED) == - le32_to_cpu(pSMBr->hdr.Status.CifsError)) { - cFYI(1,("Request was cancelled (err %lx nt_status_cancelled %lx)", pSMBr->hdr.Status.CifsError,NT_STATUS_CANCELLED)); - kfree(dnotify_req); - } else { - list_add_tail(&dnotify_req->lhead, &GlobalDnotifyRsp_Q); - } + if(dnotify_req->Mid == pSMBr->hdr.Mid && + dnotify_req->PidHigh == pSMBr->hdr.PidHigh && + dnotify_req->Pid == pSMBr->hdr.Pid) + { + list_del(tmp); + if ((NT_STATUS_CANCELLED) == + le32_to_cpu(pSMBr->hdr.Status.CifsError)) { + cFYI(1,("Request was cancelled (err %lx)", pSMBr->hdr.Status.CifsError)); + kfree(dnotify_req); + } else if(SUCCESS == le32_to_cpu(pSMBr->hdr.Status.CifsError) || + STATUS_NOTIFY_ENUM_DIR == le32_to_cpu(pSMBr->hdr.Status.CifsError)) { + list_add_tail(&dnotify_req->lhead, &GlobalDnotifyRsp_Q); + } else { + cFYI(1,("Unknown NOTIFY response 0x%lx", pSMBr->hdr.Status.CifsError)); + kmem_cache_free(cifs_dnotify_cachep, dnotify_req); } } - spin_unlock(&GlobalMid_Lock); - wake_up_process(dnotifyThread); - return TRUE; - } /* ASF TODO: file_notify_information */ + } + spin_unlock(&GlobalMid_Lock); + wake_up_process(dnotifyThread); + return TRUE; } return FALSE; }
