diff options
Diffstat (limited to 'fs/cifs/cifsfs.c')
-rw-r--r-- | fs/cifs/cifsfs.c | 100 |
1 files changed, 7 insertions, 93 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 3610e9958b4c..9a5e4f5f3122 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -50,7 +50,7 @@ | |||
50 | #define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDUs */ | 50 | #define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDUs */ |
51 | 51 | ||
52 | #ifdef CONFIG_CIFS_QUOTA | 52 | #ifdef CONFIG_CIFS_QUOTA |
53 | static struct quotactl_ops cifs_quotactl_ops; | 53 | static const struct quotactl_ops cifs_quotactl_ops; |
54 | #endif /* QUOTA */ | 54 | #endif /* QUOTA */ |
55 | 55 | ||
56 | int cifsFYI = 0; | 56 | int cifsFYI = 0; |
@@ -64,9 +64,6 @@ unsigned int multiuser_mount = 0; | |||
64 | unsigned int extended_security = CIFSSEC_DEF; | 64 | unsigned int extended_security = CIFSSEC_DEF; |
65 | /* unsigned int ntlmv2_support = 0; */ | 65 | /* unsigned int ntlmv2_support = 0; */ |
66 | unsigned int sign_CIFS_PDUs = 1; | 66 | unsigned int sign_CIFS_PDUs = 1; |
67 | extern struct task_struct *oplockThread; /* remove sparse warning */ | ||
68 | struct task_struct *oplockThread = NULL; | ||
69 | /* extern struct task_struct * dnotifyThread; remove sparse warning */ | ||
70 | static const struct super_operations cifs_super_ops; | 67 | static const struct super_operations cifs_super_ops; |
71 | unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE; | 68 | unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE; |
72 | module_param(CIFSMaxBufSize, int, 0); | 69 | module_param(CIFSMaxBufSize, int, 0); |
@@ -185,8 +182,7 @@ out_mount_failed: | |||
185 | cifs_sb->mountdata = NULL; | 182 | cifs_sb->mountdata = NULL; |
186 | } | 183 | } |
187 | #endif | 184 | #endif |
188 | if (cifs_sb->local_nls) | 185 | unload_nls(cifs_sb->local_nls); |
189 | unload_nls(cifs_sb->local_nls); | ||
190 | kfree(cifs_sb); | 186 | kfree(cifs_sb); |
191 | } | 187 | } |
192 | return rc; | 188 | return rc; |
@@ -517,7 +513,7 @@ int cifs_xstate_get(struct super_block *sb, struct fs_quota_stat *qstats) | |||
517 | return rc; | 513 | return rc; |
518 | } | 514 | } |
519 | 515 | ||
520 | static struct quotactl_ops cifs_quotactl_ops = { | 516 | static const struct quotactl_ops cifs_quotactl_ops = { |
521 | .set_xquota = cifs_xquota_set, | 517 | .set_xquota = cifs_xquota_set, |
522 | .get_xquota = cifs_xquota_get, | 518 | .get_xquota = cifs_xquota_get, |
523 | .set_xstate = cifs_xstate_set, | 519 | .set_xstate = cifs_xstate_set, |
@@ -973,89 +969,12 @@ cifs_destroy_mids(void) | |||
973 | kmem_cache_destroy(cifs_oplock_cachep); | 969 | kmem_cache_destroy(cifs_oplock_cachep); |
974 | } | 970 | } |
975 | 971 | ||
976 | static int cifs_oplock_thread(void *dummyarg) | ||
977 | { | ||
978 | struct oplock_q_entry *oplock_item; | ||
979 | struct cifsTconInfo *pTcon; | ||
980 | struct inode *inode; | ||
981 | __u16 netfid; | ||
982 | int rc, waitrc = 0; | ||
983 | |||
984 | set_freezable(); | ||
985 | do { | ||
986 | if (try_to_freeze()) | ||
987 | continue; | ||
988 | |||
989 | spin_lock(&cifs_oplock_lock); | ||
990 | if (list_empty(&cifs_oplock_list)) { | ||
991 | spin_unlock(&cifs_oplock_lock); | ||
992 | set_current_state(TASK_INTERRUPTIBLE); | ||
993 | schedule_timeout(39*HZ); | ||
994 | } else { | ||
995 | oplock_item = list_entry(cifs_oplock_list.next, | ||
996 | struct oplock_q_entry, qhead); | ||
997 | cFYI(1, ("found oplock item to write out")); | ||
998 | pTcon = oplock_item->tcon; | ||
999 | inode = oplock_item->pinode; | ||
1000 | netfid = oplock_item->netfid; | ||
1001 | spin_unlock(&cifs_oplock_lock); | ||
1002 | DeleteOplockQEntry(oplock_item); | ||
1003 | /* can not grab inode sem here since it would | ||
1004 | deadlock when oplock received on delete | ||
1005 | since vfs_unlink holds the i_mutex across | ||
1006 | the call */ | ||
1007 | /* mutex_lock(&inode->i_mutex);*/ | ||
1008 | if (S_ISREG(inode->i_mode)) { | ||
1009 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
1010 | if (CIFS_I(inode)->clientCanCacheAll == 0) | ||
1011 | break_lease(inode, FMODE_READ); | ||
1012 | else if (CIFS_I(inode)->clientCanCacheRead == 0) | ||
1013 | break_lease(inode, FMODE_WRITE); | ||
1014 | #endif | ||
1015 | rc = filemap_fdatawrite(inode->i_mapping); | ||
1016 | if (CIFS_I(inode)->clientCanCacheRead == 0) { | ||
1017 | waitrc = filemap_fdatawait( | ||
1018 | inode->i_mapping); | ||
1019 | invalidate_remote_inode(inode); | ||
1020 | } | ||
1021 | if (rc == 0) | ||
1022 | rc = waitrc; | ||
1023 | } else | ||
1024 | rc = 0; | ||
1025 | /* mutex_unlock(&inode->i_mutex);*/ | ||
1026 | if (rc) | ||
1027 | CIFS_I(inode)->write_behind_rc = rc; | ||
1028 | cFYI(1, ("Oplock flush inode %p rc %d", | ||
1029 | inode, rc)); | ||
1030 | |||
1031 | /* releasing stale oplock after recent reconnect | ||
1032 | of smb session using a now incorrect file | ||
1033 | handle is not a data integrity issue but do | ||
1034 | not bother sending an oplock release if session | ||
1035 | to server still is disconnected since oplock | ||
1036 | already released by the server in that case */ | ||
1037 | if (!pTcon->need_reconnect) { | ||
1038 | rc = CIFSSMBLock(0, pTcon, netfid, | ||
1039 | 0 /* len */ , 0 /* offset */, 0, | ||
1040 | 0, LOCKING_ANDX_OPLOCK_RELEASE, | ||
1041 | false /* wait flag */); | ||
1042 | cFYI(1, ("Oplock release rc = %d", rc)); | ||
1043 | } | ||
1044 | set_current_state(TASK_INTERRUPTIBLE); | ||
1045 | schedule_timeout(1); /* yield in case q were corrupt */ | ||
1046 | } | ||
1047 | } while (!kthread_should_stop()); | ||
1048 | |||
1049 | return 0; | ||
1050 | } | ||
1051 | |||
1052 | static int __init | 972 | static int __init |
1053 | init_cifs(void) | 973 | init_cifs(void) |
1054 | { | 974 | { |
1055 | int rc = 0; | 975 | int rc = 0; |
1056 | cifs_proc_init(); | 976 | cifs_proc_init(); |
1057 | INIT_LIST_HEAD(&cifs_tcp_ses_list); | 977 | INIT_LIST_HEAD(&cifs_tcp_ses_list); |
1058 | INIT_LIST_HEAD(&cifs_oplock_list); | ||
1059 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 978 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
1060 | INIT_LIST_HEAD(&GlobalDnotifyReqList); | 979 | INIT_LIST_HEAD(&GlobalDnotifyReqList); |
1061 | INIT_LIST_HEAD(&GlobalDnotifyRsp_Q); | 980 | INIT_LIST_HEAD(&GlobalDnotifyRsp_Q); |
@@ -1084,7 +1003,6 @@ init_cifs(void) | |||
1084 | rwlock_init(&GlobalSMBSeslock); | 1003 | rwlock_init(&GlobalSMBSeslock); |
1085 | rwlock_init(&cifs_tcp_ses_lock); | 1004 | rwlock_init(&cifs_tcp_ses_lock); |
1086 | spin_lock_init(&GlobalMid_Lock); | 1005 | spin_lock_init(&GlobalMid_Lock); |
1087 | spin_lock_init(&cifs_oplock_lock); | ||
1088 | 1006 | ||
1089 | if (cifs_max_pending < 2) { | 1007 | if (cifs_max_pending < 2) { |
1090 | cifs_max_pending = 2; | 1008 | cifs_max_pending = 2; |
@@ -1119,16 +1037,13 @@ init_cifs(void) | |||
1119 | if (rc) | 1037 | if (rc) |
1120 | goto out_unregister_key_type; | 1038 | goto out_unregister_key_type; |
1121 | #endif | 1039 | #endif |
1122 | oplockThread = kthread_run(cifs_oplock_thread, NULL, "cifsoplockd"); | 1040 | rc = slow_work_register_user(); |
1123 | if (IS_ERR(oplockThread)) { | 1041 | if (rc) |
1124 | rc = PTR_ERR(oplockThread); | 1042 | goto out_unregister_resolver_key; |
1125 | cERROR(1, ("error %d create oplock thread", rc)); | ||
1126 | goto out_unregister_dfs_key_type; | ||
1127 | } | ||
1128 | 1043 | ||
1129 | return 0; | 1044 | return 0; |
1130 | 1045 | ||
1131 | out_unregister_dfs_key_type: | 1046 | out_unregister_resolver_key: |
1132 | #ifdef CONFIG_CIFS_DFS_UPCALL | 1047 | #ifdef CONFIG_CIFS_DFS_UPCALL |
1133 | unregister_key_type(&key_type_dns_resolver); | 1048 | unregister_key_type(&key_type_dns_resolver); |
1134 | out_unregister_key_type: | 1049 | out_unregister_key_type: |
@@ -1165,7 +1080,6 @@ exit_cifs(void) | |||
1165 | cifs_destroy_inodecache(); | 1080 | cifs_destroy_inodecache(); |
1166 | cifs_destroy_mids(); | 1081 | cifs_destroy_mids(); |
1167 | cifs_destroy_request_bufs(); | 1082 | cifs_destroy_request_bufs(); |
1168 | kthread_stop(oplockThread); | ||
1169 | } | 1083 | } |
1170 | 1084 | ||
1171 | MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>"); | 1085 | MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>"); |