Advertisement
Guest User

[KERNEL] CIFS + UTF8 NLS support for the official HTC Desire Froyo kernel

a guest
Aug 14th, 2010
507
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 13.46 KB | None | 0 0
  1. diff -u cifs.vanilla/cifsfs.c cifs/cifsfs.c
  2. --- cifs.vanilla/cifsfs.c   2010-06-01 18:56:03.000000000 +0200
  3. +++ cifs/cifsfs.c   2010-08-14 12:00:00.000000000 +0200
  4. @@ -64,6 +64,9 @@
  5.  unsigned int extended_security = CIFSSEC_DEF;
  6.  /* unsigned int ntlmv2_support = 0; */
  7.  unsigned int sign_CIFS_PDUs = 1;
  8. +extern struct task_struct *oplockThread; /* remove sparse warning */
  9. +struct task_struct *oplockThread = NULL;
  10. +/* extern struct task_struct * dnotifyThread; remove sparse warning */
  11.  static const struct super_operations cifs_super_ops;
  12.  unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
  13.  module_param(CIFSMaxBufSize, int, 0);
  14. @@ -969,12 +972,89 @@
  15.     kmem_cache_destroy(cifs_oplock_cachep);
  16.  }
  17.  
  18. +static int cifs_oplock_thread(void *dummyarg)
  19. +{
  20. +   struct oplock_q_entry *oplock_item;
  21. +   struct cifsTconInfo *pTcon;
  22. +   struct inode *inode;
  23. +   __u16  netfid;
  24. +   int rc, waitrc = 0;
  25. +
  26. +   set_freezable();
  27. +   do {
  28. +       if (try_to_freeze())
  29. +           continue;
  30. +
  31. +       spin_lock(&GlobalMid_Lock);
  32. +       if (list_empty(&GlobalOplock_Q)) {
  33. +           spin_unlock(&GlobalMid_Lock);
  34. +           set_current_state(TASK_INTERRUPTIBLE);
  35. +           schedule_timeout(39*HZ);
  36. +       } else {
  37. +           oplock_item = list_entry(GlobalOplock_Q.next,
  38. +                       struct oplock_q_entry, qhead);
  39. +           cFYI(1, ("found oplock item to write out"));
  40. +           pTcon = oplock_item->tcon;
  41. +           inode = oplock_item->pinode;
  42. +           netfid = oplock_item->netfid;
  43. +           spin_unlock(&GlobalMid_Lock);
  44. +           DeleteOplockQEntry(oplock_item);
  45. +           /* can not grab inode sem here since it would
  46. +               deadlock when oplock received on delete
  47. +               since vfs_unlink holds the i_mutex across
  48. +               the call */
  49. +           /* mutex_lock(&inode->i_mutex);*/
  50. +           if (S_ISREG(inode->i_mode)) {
  51. +#ifdef CONFIG_CIFS_EXPERIMENTAL
  52. +               if (CIFS_I(inode)->clientCanCacheAll == 0)
  53. +                   break_lease(inode, FMODE_READ);
  54. +               else if (CIFS_I(inode)->clientCanCacheRead == 0)
  55. +                   break_lease(inode, FMODE_WRITE);
  56. +#endif
  57. +               rc = filemap_fdatawrite(inode->i_mapping);
  58. +               if (CIFS_I(inode)->clientCanCacheRead == 0) {
  59. +                   waitrc = filemap_fdatawait(
  60. +                                 inode->i_mapping);
  61. +                   invalidate_remote_inode(inode);
  62. +               }
  63. +               if (rc == 0)
  64. +                   rc = waitrc;
  65. +           } else
  66. +               rc = 0;
  67. +           /* mutex_unlock(&inode->i_mutex);*/
  68. +           if (rc)
  69. +               CIFS_I(inode)->write_behind_rc = rc;
  70. +           cFYI(1, ("Oplock flush inode %p rc %d",
  71. +               inode, rc));
  72. +
  73. +               /* releasing stale oplock after recent reconnect
  74. +               of smb session using a now incorrect file
  75. +               handle is not a data integrity issue but do
  76. +               not bother sending an oplock release if session
  77. +               to server still is disconnected since oplock
  78. +               already released by the server in that case */
  79. +           if (!pTcon->need_reconnect) {
  80. +               rc = CIFSSMBLock(0, pTcon, netfid,
  81. +                       0 /* len */ , 0 /* offset */, 0,
  82. +                       0, LOCKING_ANDX_OPLOCK_RELEASE,
  83. +                       false /* wait flag */);
  84. +               cFYI(1, ("Oplock release rc = %d", rc));
  85. +           }
  86. +           set_current_state(TASK_INTERRUPTIBLE);
  87. +           schedule_timeout(1);  /* yield in case q were corrupt */
  88. +       }
  89. +   } while (!kthread_should_stop());
  90. +
  91. +   return 0;
  92. +}
  93. +
  94.  static int __init
  95.  init_cifs(void)
  96.  {
  97.     int rc = 0;
  98.     cifs_proc_init();
  99.     INIT_LIST_HEAD(&cifs_tcp_ses_list);
  100. +   INIT_LIST_HEAD(&GlobalOplock_Q);
  101.  #ifdef CONFIG_CIFS_EXPERIMENTAL
  102.     INIT_LIST_HEAD(&GlobalDnotifyReqList);
  103.     INIT_LIST_HEAD(&GlobalDnotifyRsp_Q);
  104. @@ -1037,9 +1117,12 @@
  105.     if (rc)
  106.         goto out_unregister_key_type;
  107.  #endif
  108. -   rc = slow_work_register_user(THIS_MODULE);
  109. -   if (rc)
  110. -       goto out_unregister_resolver_key;
  111. +   oplockThread = kthread_run(cifs_oplock_thread, NULL, "cifsoplockd");
  112. +   if (IS_ERR(oplockThread)) {
  113. +       rc = PTR_ERR(oplockThread);
  114. +       cERROR(1, ("error %d create oplock thread", rc));
  115. +       goto  out_unregister_resolver_key;
  116. +   }
  117.  
  118.     return 0;
  119.  
  120. @@ -1080,6 +1163,7 @@
  121.     cifs_destroy_inodecache();
  122.     cifs_destroy_mids();
  123.     cifs_destroy_request_bufs();
  124. +   kthread_stop(oplockThread);
  125.  }
  126.  
  127.  MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>");
  128. diff -u cifs.vanilla/cifsglob.h cifs/cifsglob.h
  129. --- cifs.vanilla/cifsglob.h 2010-06-01 18:56:03.000000000 +0200
  130. +++ cifs/cifsglob.h 2010-08-14 12:00:00.000000000 +0200
  131. @@ -18,7 +18,6 @@
  132.   */
  133.  #include <linux/in.h>
  134.  #include <linux/in6.h>
  135. -#include <linux/slow-work.h>
  136.  #include "cifs_fs_sb.h"
  137.  #include "cifsacl.h"
  138.  /*
  139. @@ -356,7 +355,6 @@
  140.     atomic_t count;     /* reference count */
  141.     struct mutex fh_mutex; /* prevents reopen race after dead ses*/
  142.     struct cifs_search_info srch_inf;
  143. -   struct slow_work oplock_break; /* slow_work job for oplock breaks */
  144.  };
  145.  
  146.  /* Take a reference on the file private data */
  147. @@ -674,6 +672,8 @@
  148.   */
  149.  GLOBAL_EXTERN rwlock_t GlobalSMBSeslock;
  150.  
  151. +GLOBAL_EXTERN struct list_head GlobalOplock_Q;
  152. +
  153.  /* Outstanding dir notify requests */
  154.  GLOBAL_EXTERN struct list_head GlobalDnotifyReqList;
  155.  /* DirNotify response queue */
  156. @@ -724,4 +724,3 @@
  157.  GLOBAL_EXTERN unsigned int cifs_min_small;  /* min size of small buf pool */
  158.  GLOBAL_EXTERN unsigned int cifs_max_pending; /* MAX requests at once to server*/
  159.  
  160. -extern const struct slow_work_ops cifs_oplock_break_ops;
  161. diff -u cifs.vanilla/cifsproto.h cifs/cifsproto.h
  162. --- cifs.vanilla/cifsproto.h    2010-06-01 18:56:03.000000000 +0200
  163. +++ cifs/cifsproto.h    2010-08-14 12:00:00.000000000 +0200
  164. @@ -86,6 +86,10 @@
  165.                  const int stage,
  166.                  const struct nls_table *nls_cp);
  167.  extern __u16 GetNextMid(struct TCP_Server_Info *server);
  168. +extern struct oplock_q_entry *AllocOplockQEntry(struct inode *, u16,
  169. +                        struct cifsTconInfo *);
  170. +extern void DeleteOplockQEntry(struct oplock_q_entry *);
  171. +extern void DeleteTconOplockQEntries(struct cifsTconInfo *);
  172.  extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601);
  173.  extern u64 cifs_UnixTimeToNT(struct timespec);
  174.  extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time,
  175. diff -u cifs.vanilla/cifs_spnego.c cifs/cifs_spnego.c
  176. --- cifs.vanilla/cifs_spnego.c  2010-06-01 18:56:03.000000000 +0200
  177. +++ cifs/cifs_spnego.c  2010-08-14 12:00:00.000000000 +0200
  178. @@ -125,7 +125,7 @@
  179.     if (server->addr.sockAddr.sin_family == AF_INET)
  180.         sprintf(dp, "ip4=%pI4", &server->addr.sockAddr.sin_addr);
  181.     else if (server->addr.sockAddr.sin_family == AF_INET6)
  182. -       sprintf(dp, "ip6=%pI6", &server->addr.sockAddr6.sin6_addr);
  183. +       sprintf(dp, "ip6=%pi6", &server->addr.sockAddr6.sin6_addr);
  184.     else
  185.         goto out;
  186.  
  187. diff -u cifs.vanilla/dir.c cifs/dir.c
  188. --- cifs.vanilla/dir.c  2010-06-01 18:56:03.000000000 +0200
  189. +++ cifs/dir.c  2010-08-14 12:00:00.000000000 +0200
  190. @@ -157,7 +157,6 @@
  191.     mutex_init(&pCifsFile->lock_mutex);
  192.     INIT_LIST_HEAD(&pCifsFile->llist);
  193.     atomic_set(&pCifsFile->count, 1);
  194. -   slow_work_init(&pCifsFile->oplock_break, &cifs_oplock_break_ops);
  195.  
  196.     write_lock(&GlobalSMBSeslock);
  197.     list_add(&pCifsFile->tlist, &cifs_sb->tcon->openFileList);
  198. @@ -178,7 +177,7 @@
  199.                 pCifsInode->clientCanCacheRead = true;
  200.     }
  201.     write_unlock(&GlobalSMBSeslock);
  202. -
  203. +  
  204.     return pCifsFile;
  205.  }
  206.  
  207. diff -u cifs.vanilla/file.c cifs/file.c
  208. --- cifs.vanilla/file.c 2010-06-01 18:56:03.000000000 +0200
  209. +++ cifs/file.c 2010-08-14 12:00:00.000000000 +0200
  210. @@ -2274,73 +2274,6 @@
  211.     return rc;
  212.  }
  213.  
  214. -static void
  215. -cifs_oplock_break(struct slow_work *work)
  216. -{
  217. -   struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo,
  218. -                         oplock_break);
  219. -   struct inode *inode = cfile->pInode;
  220. -   struct cifsInodeInfo *cinode = CIFS_I(inode);
  221. -   struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->mnt->mnt_sb);
  222. -   int rc, waitrc = 0;
  223. -
  224. -   if (inode && S_ISREG(inode->i_mode)) {
  225. -#ifdef CONFIG_CIFS_EXPERIMENTAL
  226. -       if (cinode->clientCanCacheAll == 0)
  227. -           break_lease(inode, FMODE_READ);
  228. -       else if (cinode->clientCanCacheRead == 0)
  229. -           break_lease(inode, FMODE_WRITE);
  230. -#endif
  231. -       rc = filemap_fdatawrite(inode->i_mapping);
  232. -       if (cinode->clientCanCacheRead == 0) {
  233. -           waitrc = filemap_fdatawait(inode->i_mapping);
  234. -           invalidate_remote_inode(inode);
  235. -       }
  236. -       if (!rc)
  237. -           rc = waitrc;
  238. -       if (rc)
  239. -           cinode->write_behind_rc = rc;
  240. -       cFYI(1, ("Oplock flush inode %p rc %d", inode, rc));
  241. -   }
  242. -
  243. -   /*
  244. -    * releasing stale oplock after recent reconnect of smb session using
  245. -    * a now incorrect file handle is not a data integrity issue but do
  246. -    * not bother sending an oplock release if session to server still is
  247. -    * disconnected since oplock already released by the server
  248. -    */
  249. -   if (!cfile->closePend && !cfile->oplock_break_cancelled) {
  250. -       rc = CIFSSMBLock(0, cifs_sb->tcon, cfile->netfid, 0, 0, 0, 0,
  251. -                LOCKING_ANDX_OPLOCK_RELEASE, false);
  252. -       cFYI(1, ("Oplock release rc = %d", rc));
  253. -   }
  254. -}
  255. -
  256. -static int
  257. -cifs_oplock_break_get(struct slow_work *work)
  258. -{
  259. -   struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo,
  260. -                         oplock_break);
  261. -   mntget(cfile->mnt);
  262. -   cifsFileInfo_get(cfile);
  263. -   return 0;
  264. -}
  265. -
  266. -static void
  267. -cifs_oplock_break_put(struct slow_work *work)
  268. -{
  269. -   struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo,
  270. -                         oplock_break);
  271. -   mntput(cfile->mnt);
  272. -   cifsFileInfo_put(cfile);
  273. -}
  274. -
  275. -const struct slow_work_ops cifs_oplock_break_ops = {
  276. -   .get_ref    = cifs_oplock_break_get,
  277. -   .put_ref    = cifs_oplock_break_put,
  278. -   .execute    = cifs_oplock_break,
  279. -};
  280. -
  281.  const struct address_space_operations cifs_addr_ops = {
  282.     .readpage = cifs_readpage,
  283.     .readpages = cifs_readpages,
  284. diff -u cifs.vanilla/inode.c cifs/inode.c
  285. --- cifs.vanilla/inode.c    2010-06-01 18:56:03.000000000 +0200
  286. +++ cifs/inode.c    2010-08-14 12:00:00.000000000 +0200
  287. @@ -82,7 +82,6 @@
  288.  cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
  289.  {
  290.     struct cifsInodeInfo *cifs_i = CIFS_I(inode);
  291. -   struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
  292.     unsigned long oldtime = cifs_i->time;
  293.  
  294.     inode->i_atime = fattr->cf_atime;
  295. @@ -93,10 +92,7 @@
  296.     inode->i_uid = fattr->cf_uid;
  297.     inode->i_gid = fattr->cf_gid;
  298.  
  299. -   /* if dynperm is set, don't clobber existing mode */
  300. -   if (inode->i_state & I_NEW ||
  301. -       !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM))
  302. -       inode->i_mode = fattr->cf_mode;
  303. +   inode->i_mode = fattr->cf_mode;
  304.  
  305.     cifs_i->cifsAttrs = fattr->cf_cifsattrs;
  306.     cifs_i->uniqueid = fattr->cf_uniqueid;
  307. diff -u cifs.vanilla/Kconfig cifs/Kconfig
  308. --- cifs.vanilla/Kconfig    2010-06-01 18:56:03.000000000 +0200
  309. +++ cifs/Kconfig    2010-08-14 12:00:00.000000000 +0200
  310. @@ -2,7 +2,6 @@
  311.     tristate "CIFS support (advanced network filesystem, SMBFS successor)"
  312.     depends on INET
  313.     select NLS
  314. -   select SLOW_WORK
  315.     help
  316.       This is the client VFS module for the Common Internet File System
  317.       (CIFS) protocol which is the successor to the Server Message Block
  318. diff -u cifs.vanilla/misc.c cifs/misc.c
  319. --- cifs.vanilla/misc.c 2010-06-01 18:56:03.000000000 +0200
  320. +++ cifs/misc.c 2010-08-14 12:00:00.000000000 +0200
  321. @@ -32,6 +32,7 @@
  322.  
  323.  extern mempool_t *cifs_sm_req_poolp;
  324.  extern mempool_t *cifs_req_poolp;
  325. +extern struct task_struct *oplockThread;
  326.  
  327.  /* The xid serves as a useful identifier for each incoming vfs request,
  328.     in a similar way to the mid which is useful to track each sent smb,
  329. @@ -499,7 +500,6 @@
  330.     struct cifsTconInfo *tcon;
  331.     struct cifsInodeInfo *pCifsInode;
  332.     struct cifsFileInfo *netfile;
  333. -   int rc;
  334.  
  335.     cFYI(1, ("Checking for oplock break or dnotify response"));
  336.     if ((pSMB->hdr.Command == SMB_COM_NT_TRANSACT) &&
  337. @@ -578,17 +578,18 @@
  338.                     read_unlock(&cifs_tcp_ses_lock);
  339.                     return true;
  340.                 }
  341. -
  342. +                  
  343.                 cFYI(1, ("file id match, oplock break"));
  344.                 pCifsInode = CIFS_I(netfile->pInode);
  345.                 pCifsInode->clientCanCacheAll = false;
  346.                 if (pSMB->OplockLevel == 0)
  347.                     pCifsInode->clientCanCacheRead = false;
  348. -               rc = slow_work_enqueue(&netfile->oplock_break);
  349. -               if (rc) {
  350. -                   cERROR(1, ("failed to enqueue oplock "
  351. -                          "break: %d\n", rc));
  352. -               } else {
  353. +               AllocOplockQEntry(netfile->pInode,
  354. +                         netfile->netfid, tcon);
  355. +               cFYI(1, ("about to wake up oplock thread"));
  356. +               if (oplockThread)
  357. +               {
  358. +                   wake_up_process(oplockThread);
  359.                     netfile->oplock_break_cancelled = false;
  360.                 }
  361.                 read_unlock(&GlobalSMBSeslock);
  362. diff -u cifs.vanilla/transport.c cifs/transport.c
  363. --- cifs.vanilla/transport.c    2010-06-01 18:56:03.000000000 +0200
  364. +++ cifs/transport.c    2010-08-14 12:00:00.000000000 +0200
  365. @@ -103,6 +103,57 @@
  366.     mempool_free(midEntry, cifs_mid_poolp);
  367.  }
  368.  
  369. +struct oplock_q_entry *
  370. +AllocOplockQEntry(struct inode *pinode, __u16 fid, struct cifsTconInfo *tcon)
  371. +{
  372. +   struct oplock_q_entry *temp;
  373. +   if ((pinode == NULL) || (tcon == NULL)) {
  374. +       cERROR(1, ("Null parms passed to AllocOplockQEntry"));
  375. +       return NULL;
  376. +   }
  377. +   temp = (struct oplock_q_entry *) kmem_cache_alloc(cifs_oplock_cachep,
  378. +                              GFP_KERNEL);
  379. +   if (temp == NULL)
  380. +       return temp;
  381. +   else {
  382. +       temp->pinode = pinode;
  383. +       temp->tcon = tcon;
  384. +       temp->netfid = fid;
  385. +       spin_lock(&GlobalMid_Lock);
  386. +       list_add_tail(&temp->qhead, &GlobalOplock_Q);
  387. +       spin_unlock(&GlobalMid_Lock);
  388. +   }
  389. +   return temp;
  390. +
  391. +}
  392. +
  393. +void DeleteOplockQEntry(struct oplock_q_entry *oplockEntry)
  394. +{
  395. +   spin_lock(&GlobalMid_Lock);
  396. +    /* should we check if list empty first? */
  397. +   list_del(&oplockEntry->qhead);
  398. +   spin_unlock(&GlobalMid_Lock);
  399. +   kmem_cache_free(cifs_oplock_cachep, oplockEntry);
  400. +}
  401. +
  402. +
  403. +void DeleteTconOplockQEntries(struct cifsTconInfo *tcon)
  404. +{
  405. +   struct oplock_q_entry *temp;
  406. +
  407. +   if (tcon == NULL)
  408. +       return;
  409. +
  410. +   spin_lock(&GlobalMid_Lock);
  411. +   list_for_each_entry(temp, &GlobalOplock_Q, qhead) {
  412. +       if ((temp->tcon) && (temp->tcon == tcon)) {
  413. +           list_del(&temp->qhead);
  414. +           kmem_cache_free(cifs_oplock_cachep, temp);
  415. +       }
  416. +   }
  417. +   spin_unlock(&GlobalMid_Lock);
  418. +}
  419. +
  420.  static int
  421.  smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
  422.  {
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement