diff options
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/Kconfig | 1 | ||||
-rw-r--r-- | fs/cifs/cifsfs.c | 5 | ||||
-rw-r--r-- | fs/cifs/cifsglob.h | 8 | ||||
-rw-r--r-- | fs/cifs/dir.c | 2 | ||||
-rw-r--r-- | fs/cifs/file.c | 30 | ||||
-rw-r--r-- | fs/cifs/misc.c | 20 |
6 files changed, 32 insertions, 34 deletions
diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig index 5739fd7f88b4..efcb3a78a327 100644 --- a/fs/cifs/Kconfig +++ b/fs/cifs/Kconfig | |||
@@ -2,7 +2,6 @@ config CIFS | |||
2 | tristate "CIFS support (advanced network filesystem, SMBFS successor)" | 2 | tristate "CIFS support (advanced network filesystem, SMBFS successor)" |
3 | depends on INET | 3 | depends on INET |
4 | select NLS | 4 | select NLS |
5 | select SLOW_WORK | ||
6 | help | 5 | help |
7 | This is the client VFS module for the Common Internet File System | 6 | This is the client VFS module for the Common Internet File System |
8 | (CIFS) protocol which is the successor to the Server Message Block | 7 | (CIFS) protocol which is the successor to the Server Message Block |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 8a2cf129e535..5ac541a30c1d 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -939,15 +939,10 @@ init_cifs(void) | |||
939 | if (rc) | 939 | if (rc) |
940 | goto out_unregister_key_type; | 940 | goto out_unregister_key_type; |
941 | #endif | 941 | #endif |
942 | rc = slow_work_register_user(THIS_MODULE); | ||
943 | if (rc) | ||
944 | goto out_unregister_resolver_key; | ||
945 | 942 | ||
946 | return 0; | 943 | return 0; |
947 | 944 | ||
948 | out_unregister_resolver_key: | ||
949 | #ifdef CONFIG_CIFS_DFS_UPCALL | 945 | #ifdef CONFIG_CIFS_DFS_UPCALL |
950 | cifs_exit_dns_resolver(); | ||
951 | out_unregister_key_type: | 946 | out_unregister_key_type: |
952 | #endif | 947 | #endif |
953 | #ifdef CONFIG_CIFS_UPCALL | 948 | #ifdef CONFIG_CIFS_UPCALL |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 59906146ad36..0cdfb8c32ac6 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <linux/in.h> | 22 | #include <linux/in.h> |
23 | #include <linux/in6.h> | 23 | #include <linux/in6.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/slow-work.h> | 25 | #include <linux/workqueue.h> |
26 | #include "cifs_fs_sb.h" | 26 | #include "cifs_fs_sb.h" |
27 | #include "cifsacl.h" | 27 | #include "cifsacl.h" |
28 | /* | 28 | /* |
@@ -356,7 +356,7 @@ struct cifsFileInfo { | |||
356 | atomic_t count; /* reference count */ | 356 | atomic_t count; /* reference count */ |
357 | struct mutex fh_mutex; /* prevents reopen race after dead ses*/ | 357 | struct mutex fh_mutex; /* prevents reopen race after dead ses*/ |
358 | struct cifs_search_info srch_inf; | 358 | struct cifs_search_info srch_inf; |
359 | struct slow_work oplock_break; /* slow_work job for oplock breaks */ | 359 | struct work_struct oplock_break; /* work for oplock breaks */ |
360 | }; | 360 | }; |
361 | 361 | ||
362 | /* Take a reference on the file private data */ | 362 | /* Take a reference on the file private data */ |
@@ -728,6 +728,10 @@ GLOBAL_EXTERN unsigned int cifs_min_rcv; /* min size of big ntwrk buf pool */ | |||
728 | GLOBAL_EXTERN unsigned int cifs_min_small; /* min size of small buf pool */ | 728 | GLOBAL_EXTERN unsigned int cifs_min_small; /* min size of small buf pool */ |
729 | GLOBAL_EXTERN unsigned int cifs_max_pending; /* MAX requests at once to server*/ | 729 | GLOBAL_EXTERN unsigned int cifs_max_pending; /* MAX requests at once to server*/ |
730 | 730 | ||
731 | void cifs_oplock_break(struct work_struct *work); | ||
732 | void cifs_oplock_break_get(struct cifsFileInfo *cfile); | ||
733 | void cifs_oplock_break_put(struct cifsFileInfo *cfile); | ||
734 | |||
731 | extern const struct slow_work_ops cifs_oplock_break_ops; | 735 | extern const struct slow_work_ops cifs_oplock_break_ops; |
732 | 736 | ||
733 | #endif /* _CIFS_GLOB_H */ | 737 | #endif /* _CIFS_GLOB_H */ |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index a7de5e9fff11..578d88c5b46e 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -157,7 +157,7 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, | |||
157 | mutex_init(&pCifsFile->lock_mutex); | 157 | mutex_init(&pCifsFile->lock_mutex); |
158 | INIT_LIST_HEAD(&pCifsFile->llist); | 158 | INIT_LIST_HEAD(&pCifsFile->llist); |
159 | atomic_set(&pCifsFile->count, 1); | 159 | atomic_set(&pCifsFile->count, 1); |
160 | slow_work_init(&pCifsFile->oplock_break, &cifs_oplock_break_ops); | 160 | INIT_WORK(&pCifsFile->oplock_break, cifs_oplock_break); |
161 | 161 | ||
162 | write_lock(&GlobalSMBSeslock); | 162 | write_lock(&GlobalSMBSeslock); |
163 | list_add(&pCifsFile->tlist, &cifs_sb->tcon->openFileList); | 163 | list_add(&pCifsFile->tlist, &cifs_sb->tcon->openFileList); |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index fa04a00d126d..db11fdef0e92 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -2307,8 +2307,7 @@ static void cifs_invalidate_page(struct page *page, unsigned long offset) | |||
2307 | cifs_fscache_invalidate_page(page, &cifsi->vfs_inode); | 2307 | cifs_fscache_invalidate_page(page, &cifsi->vfs_inode); |
2308 | } | 2308 | } |
2309 | 2309 | ||
2310 | static void | 2310 | void cifs_oplock_break(struct work_struct *work) |
2311 | cifs_oplock_break(struct slow_work *work) | ||
2312 | { | 2311 | { |
2313 | struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo, | 2312 | struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo, |
2314 | oplock_break); | 2313 | oplock_break); |
@@ -2345,33 +2344,30 @@ cifs_oplock_break(struct slow_work *work) | |||
2345 | LOCKING_ANDX_OPLOCK_RELEASE, false); | 2344 | LOCKING_ANDX_OPLOCK_RELEASE, false); |
2346 | cFYI(1, "Oplock release rc = %d", rc); | 2345 | cFYI(1, "Oplock release rc = %d", rc); |
2347 | } | 2346 | } |
2347 | |||
2348 | /* | ||
2349 | * We might have kicked in before is_valid_oplock_break() | ||
2350 | * finished grabbing reference for us. Make sure it's done by | ||
2351 | * waiting for GlobalSMSSeslock. | ||
2352 | */ | ||
2353 | write_lock(&GlobalSMBSeslock); | ||
2354 | write_unlock(&GlobalSMBSeslock); | ||
2355 | |||
2356 | cifs_oplock_break_put(cfile); | ||
2348 | } | 2357 | } |
2349 | 2358 | ||
2350 | static int | 2359 | void cifs_oplock_break_get(struct cifsFileInfo *cfile) |
2351 | cifs_oplock_break_get(struct slow_work *work) | ||
2352 | { | 2360 | { |
2353 | struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo, | ||
2354 | oplock_break); | ||
2355 | mntget(cfile->mnt); | 2361 | mntget(cfile->mnt); |
2356 | cifsFileInfo_get(cfile); | 2362 | cifsFileInfo_get(cfile); |
2357 | return 0; | ||
2358 | } | 2363 | } |
2359 | 2364 | ||
2360 | static void | 2365 | void cifs_oplock_break_put(struct cifsFileInfo *cfile) |
2361 | cifs_oplock_break_put(struct slow_work *work) | ||
2362 | { | 2366 | { |
2363 | struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo, | ||
2364 | oplock_break); | ||
2365 | mntput(cfile->mnt); | 2367 | mntput(cfile->mnt); |
2366 | cifsFileInfo_put(cfile); | 2368 | cifsFileInfo_put(cfile); |
2367 | } | 2369 | } |
2368 | 2370 | ||
2369 | const struct slow_work_ops cifs_oplock_break_ops = { | ||
2370 | .get_ref = cifs_oplock_break_get, | ||
2371 | .put_ref = cifs_oplock_break_put, | ||
2372 | .execute = cifs_oplock_break, | ||
2373 | }; | ||
2374 | |||
2375 | const struct address_space_operations cifs_addr_ops = { | 2371 | const struct address_space_operations cifs_addr_ops = { |
2376 | .readpage = cifs_readpage, | 2372 | .readpage = cifs_readpage, |
2377 | .readpages = cifs_readpages, | 2373 | .readpages = cifs_readpages, |
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 1394aa37f26c..3ccadc1326d6 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c | |||
@@ -498,7 +498,6 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) | |||
498 | struct cifsTconInfo *tcon; | 498 | struct cifsTconInfo *tcon; |
499 | struct cifsInodeInfo *pCifsInode; | 499 | struct cifsInodeInfo *pCifsInode; |
500 | struct cifsFileInfo *netfile; | 500 | struct cifsFileInfo *netfile; |
501 | int rc; | ||
502 | 501 | ||
503 | cFYI(1, "Checking for oplock break or dnotify response"); | 502 | cFYI(1, "Checking for oplock break or dnotify response"); |
504 | if ((pSMB->hdr.Command == SMB_COM_NT_TRANSACT) && | 503 | if ((pSMB->hdr.Command == SMB_COM_NT_TRANSACT) && |
@@ -583,13 +582,18 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) | |||
583 | pCifsInode->clientCanCacheAll = false; | 582 | pCifsInode->clientCanCacheAll = false; |
584 | if (pSMB->OplockLevel == 0) | 583 | if (pSMB->OplockLevel == 0) |
585 | pCifsInode->clientCanCacheRead = false; | 584 | pCifsInode->clientCanCacheRead = false; |
586 | rc = slow_work_enqueue(&netfile->oplock_break); | 585 | |
587 | if (rc) { | 586 | /* |
588 | cERROR(1, "failed to enqueue oplock " | 587 | * cifs_oplock_break_put() can't be called |
589 | "break: %d\n", rc); | 588 | * from here. Get reference after queueing |
590 | } else { | 589 | * succeeded. cifs_oplock_break() will |
591 | netfile->oplock_break_cancelled = false; | 590 | * synchronize using GlobalSMSSeslock. |
592 | } | 591 | */ |
592 | if (queue_work(system_nrt_wq, | ||
593 | &netfile->oplock_break)) | ||
594 | cifs_oplock_break_get(netfile); | ||
595 | netfile->oplock_break_cancelled = false; | ||
596 | |||
593 | read_unlock(&GlobalSMBSeslock); | 597 | read_unlock(&GlobalSMBSeslock); |
594 | read_unlock(&cifs_tcp_ses_lock); | 598 | read_unlock(&cifs_tcp_ses_lock); |
595 | return true; | 599 | return true; |