file.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854
  1. /*
  2. RAWFS: Raw file system for NAND flash
  3. Copyright (C) 2012-2015 Perry Hsu <perry.hsu@mediatek.com>"
  4. This program can be distributed under the terms of the GNU GPL.
  5. See the file COPYING.
  6. */
  7. #if defined(CONFIG_MT_ENG_BUILD)
  8. #define DEBUG 1
  9. #endif
  10. #include <linux/module.h>
  11. #include <linux/fs.h>
  12. #include <linux/aio.h>
  13. #include <linux/uio.h>
  14. #include <linux/slab.h>
  15. #include <linux/uaccess.h>
  16. #include <linux/pagemap.h>
  17. #include "rawfs.h"
  18. #define CEILING(x, y) rawfs_div(((x)+(y)-1), (y))
  19. #define FLOOR(x, y) rawfs_div((x), (y))
  20. #define page_uptodate(page) test_bit(PG_uptodate, &(page)->flags)
  21. /* ----------------------------------------------------------------------------- */
  22. /* Block File Operation */
  23. /* ----------------------------------------------------------------------------- */
  24. /**
  25. * rawfs_block_file_aio_read - read routine for block files
  26. * @iocb: kernel I/O control block
  27. * @iov: io vector request
  28. * @nr_segs: number of segments in the iovec
  29. * @pos: current file position
  30. */
  31. ssize_t
  32. rawfs_block_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
  33. unsigned long nr_segs, loff_t pos)
  34. {
  35. struct file *filp = iocb->ki_filp;
  36. struct super_block *sb = filp->f_path.dentry->d_sb;
  37. struct rawfs_sb_info *rawfs_sb = RAWFS_SB(sb);
  38. struct inode *inode = filp->f_mapping->host;
  39. ssize_t retval;
  40. loff_t *ppos = &iocb->ki_pos;
  41. /* Always use direct I/O */
  42. loff_t size;
  43. int block_no;
  44. retval = iov_length(iov, nr_segs);
  45. mutex_lock(&rawfs_sb->rawfs_lock);
  46. RAWFS_PRINT(RAWFS_DBG_FILE,
  47. "rawfs_block_file_aio_read %s, pos %lld, len %ld\n",
  48. RAWFS_I(inode)->i_name, pos, (unsigned long)retval);
  49. size = i_size_read(inode);
  50. /* Get inode ID */
  51. block_no = filp->f_path.dentry->d_inode->i_ino - RAWFS_BLOCK0_INO;
  52. if ((retval + pos) >= size)
  53. retval = size - pos;
  54. if (pos < size) {
  55. rawfs_sb->dev.read_page_user(filp->f_path.dentry->d_inode->i_sb,
  56. block_no, pos, iov, nr_segs, retval);
  57. if (retval > 0)
  58. *ppos = pos + retval;
  59. if (retval < 0 || *ppos >= size) {
  60. file_accessed(filp);
  61. goto out;
  62. }
  63. }
  64. out:
  65. mutex_unlock(&rawfs_sb->rawfs_lock);
  66. return retval;
  67. }
  68. EXPORT_SYMBOL_GPL(rawfs_block_file_aio_read);
  69. /**
  70. * rawfs_block_file_aio_write - write data to a block file
  71. * @iocb: IO state structure
  72. * @iov: vector with data to write
  73. * @nr_segs: number of segments in the vector
  74. * @pos: position in file where to write
  75. */
  76. ssize_t rawfs_block_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
  77. unsigned long nr_segs, loff_t pos)
  78. {
  79. struct file *filp = iocb->ki_filp;
  80. ssize_t retval;
  81. loff_t *ppos = &iocb->ki_pos;
  82. retval = iov_length(iov, nr_segs);
  83. RAWFS_PRINT(RAWFS_DBG_FILE,
  84. "rawfs_block_file_aio_write %s, pos %lld, len %ld\n",
  85. RAWFS_I(filp->f_mapping->host)->i_name, pos, (unsigned long)retval);
  86. if (retval > 0)
  87. *ppos = pos + retval;
  88. file_accessed(filp);
  89. /* This function is not supported, data will not write to the device */
  90. return retval;
  91. }
  92. EXPORT_SYMBOL_GPL(rawfs_block_file_aio_write);
  93. /* ----------------------------------------------------------------------------- */
  94. /* Regular File Operation */
  95. /* ----------------------------------------------------------------------------- */
  96. ssize_t rawfs_reg_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
  97. unsigned long nr_segs, loff_t pos)
  98. {
  99. struct file *filp = iocb->ki_filp;
  100. struct super_block *sb = filp->f_path.dentry->d_sb;
  101. struct rawfs_sb_info *rawfs_sb = RAWFS_SB(sb);
  102. struct inode *inode = filp->f_mapping->host;
  103. struct rawfs_inode_info *inode_info = RAWFS_I(inode);
  104. ssize_t retval;
  105. loff_t *ppos = &iocb->ki_pos;
  106. loff_t size;
  107. unsigned int curr_file_pos = pos;
  108. unsigned int curr_buf_pos = 0;
  109. int remain_buf_size;
  110. const struct iovec *iv = &iov[0]; /* TODO: Process all io vectors */
  111. RAWFS_PRINT(RAWFS_DBG_FILE,
  112. "rawfs_reg_file_aio_read %s\n", inode_info->i_name);
  113. mutex_lock(&rawfs_sb->rawfs_lock);
  114. retval = iov_length(iov, nr_segs);
  115. size = i_size_read(inode);
  116. RAWFS_PRINT(RAWFS_DBG_FILE,
  117. "rawfs_reg_file_aio_read %s, pos %lld, len %ld, filesize: %lld\n",
  118. inode_info->i_name, pos, (unsigned long)retval, size);
  119. if ((retval + pos) >= size)
  120. retval = size - pos;
  121. if (pos < size) {
  122. /* Read File */
  123. {
  124. int preceding_pages, rear_pages;
  125. struct rawfs_page *page_buf = NULL;
  126. int i;
  127. /* Prepare page buffer */
  128. page_buf = kzalloc(rawfs_sb->page_size, GFP_NOFS);
  129. if (page_buf == NULL) {
  130. retval = 0;
  131. goto out;
  132. }
  133. preceding_pages = FLOOR((unsigned)pos, rawfs_sb->page_data_size);
  134. rear_pages = CEILING((unsigned)pos + retval,
  135. rawfs_sb->page_data_size);
  136. remain_buf_size = retval;
  137. RAWFS_PRINT(RAWFS_DBG_FILE,
  138. "rawfs_reg_file_aio_read %s, preceding %d, rear %d, remain %d\n",
  139. inode_info->i_name, preceding_pages, rear_pages,
  140. remain_buf_size);
  141. /* Step 1: Copy preceding pages, if starting pos is not 0. */
  142. for (i = preceding_pages; i < rear_pages; i++) {
  143. __u32 crc;
  144. /* Read page */
  145. rawfs_sb->dev.read_page(sb,
  146. inode_info->i_location_block,
  147. inode_info->i_location_page+i,
  148. page_buf);
  149. /* TODO: skip this page, if unrecoverable error occurs */
  150. /* CRC error should not happen,
  151. since we have already check them at bootup */
  152. crc = rawfs_page_crc_data(sb, page_buf);
  153. if (crc != page_buf->i_crc)
  154. RAWFS_PRINT(RAWFS_DBG_FILE,
  155. "rawfs_reg_file_aio_read: %s @ %X, crc fail %X, expected %X\n",
  156. page_buf->i_info.i_file_info.i_name,
  157. page_buf->i_info.i_file_info.i_parent_folder_id, crc,
  158. page_buf->i_crc);
  159. else
  160. RAWFS_PRINT(RAWFS_DBG_FILE,
  161. "rawfs_reg_file_aio_read: %s @ %X, crc %X\n",
  162. page_buf->i_info.i_file_info.i_name,
  163. page_buf->i_info.i_file_info.i_parent_folder_id,
  164. page_buf->i_crc);
  165. /* Copy required parts */
  166. {
  167. int start_in_buf;
  168. int copy_len;
  169. start_in_buf = (curr_file_pos % rawfs_sb->page_data_size);
  170. copy_len = ((start_in_buf + remain_buf_size) >
  171. rawfs_sb->page_data_size) ?
  172. (rawfs_sb->page_data_size - start_in_buf) :
  173. remain_buf_size;
  174. if (copy_to_user((char *)iv->iov_base + curr_buf_pos,
  175. &page_buf->i_data[0] + start_in_buf, copy_len)) {
  176. retval = -EFAULT;
  177. goto out2;
  178. }
  179. RAWFS_PRINT(RAWFS_DBG_FILE,
  180. "rawfs_reg_file_aio_read %s, %d, curr %d, remain %d start %d copy %d starting %X\n",
  181. inode_info->i_name, i, curr_buf_pos, remain_buf_size,
  182. start_in_buf, copy_len,
  183. *(unsigned int *)(&page_buf->i_data[0] + start_in_buf));
  184. curr_buf_pos += copy_len;
  185. remain_buf_size -= copy_len;
  186. }
  187. }
  188. out2:
  189. kfree(page_buf);
  190. }
  191. if (retval > 0)
  192. *ppos = pos + retval;
  193. if (retval < 0 || *ppos >= size) {
  194. file_accessed(filp);
  195. goto out;
  196. }
  197. } else {
  198. retval = 0;
  199. }
  200. out:
  201. /* Release Lock */
  202. mutex_unlock(&rawfs_sb->rawfs_lock);
  203. return retval;
  204. }
  205. EXPORT_SYMBOL_GPL(rawfs_reg_file_aio_read);
  206. void rawfs_fill_fileinfo_by_dentry(struct dentry *dentry,
  207. struct rawfs_file_info *file_info)
  208. {
  209. rawfs_fill_file_info(dentry->d_inode, file_info);
  210. file_info->i_parent_folder_id = RAWFS_I(dentry->d_parent->d_inode)->i_id;
  211. /* Dentry only has 32 bytes, file it with iname */
  212. strncpy(file_info->i_name, dentry->d_name.name, RAWFS_MAX_FILENAME_LEN+4);
  213. }
  214. EXPORT_SYMBOL_GPL(rawfs_fill_fileinfo_by_dentry);
  215. void rawfs_fill_file_info(struct inode *inode,
  216. struct rawfs_file_info *file_info)
  217. {
  218. int name_len;
  219. struct rawfs_inode_info *inode_info = RAWFS_I(inode);
  220. name_len = strlen(inode_info->i_name);
  221. file_info->i_atime = inode->i_atime;
  222. file_info->i_mtime = inode->i_mtime;
  223. file_info->i_ctime = inode->i_ctime;
  224. file_info->i_uid = inode->i_uid.val;
  225. file_info->i_gid = inode->i_gid.val;
  226. file_info->i_mode = inode->i_mode;
  227. file_info->i_size = inode->i_size;
  228. file_info->i_id = inode_info->i_id;
  229. file_info->i_parent_folder_id = RAWFS_ROOT_DIR_ID;
  230. /* inode->i_ino = rawfs_file_unique_ino(file_info->i_name, name_len); */
  231. /* inode->i_fop = &rawfs_file_operations; */
  232. strncpy(file_info->i_name, inode_info->i_name, name_len+1);
  233. /* inode_info->i_location_block = block_no; */
  234. /* inode_info->i_location_page = page_no; */
  235. /* inode_info->i_location_page_count = file_info->i_chunk_total; */
  236. }
  237. EXPORT_SYMBOL_GPL(rawfs_fill_file_info);
  238. ssize_t rawfs_reg_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
  239. unsigned long nr_segs, loff_t pos)
  240. {
  241. struct file *filp = iocb->ki_filp;
  242. struct super_block *sb = filp->f_path.dentry->d_sb;
  243. struct rawfs_sb_info *rawfs_sb = RAWFS_SB(sb);
  244. /* struct address_space *mapping=filp->f_mapping; */
  245. struct inode *inode = filp->f_mapping->host;
  246. struct rawfs_inode_info *inode_info = RAWFS_I(inode);
  247. ssize_t retval;
  248. /* size_t count; */
  249. loff_t *ppos = &iocb->ki_pos;
  250. struct rawfs_file_info *fi = NULL;
  251. unsigned int curr_file_pos = pos;
  252. unsigned int curr_buf_pos = 0;
  253. int starting_page, total_pages;
  254. int remain_buf_size;
  255. int result;
  256. struct rawfs_file_list_entry *entry;
  257. const struct iovec *iv = &iov[0]; /* TODO: Process all io vectors */
  258. /* Always use direct I/O */
  259. /* loff_t size; */
  260. /* int block_no; */
  261. /* Get Lock */
  262. mutex_lock(&rawfs_sb->rawfs_lock);
  263. retval = iov_length(iov, nr_segs);
  264. RAWFS_PRINT(RAWFS_DBG_FILE,
  265. "rawfs_reg_file_aio_write %s, pos %lld, len %ld\n",
  266. inode_info->i_name, pos, (unsigned long)retval);
  267. fi = kzalloc(sizeof(struct rawfs_file_info), GFP_NOFS);
  268. if (!fi) {
  269. retval = 0;
  270. goto out;
  271. }
  272. /* rawfs_fill_file_info(inode , fi); */
  273. rawfs_fill_fileinfo_by_dentry(filp->f_path.dentry, fi);
  274. /* Update file_info */
  275. if ((pos+retval) > fi->i_size)
  276. fi->i_size = pos+retval;
  277. fi->i_chunk_index = 1;
  278. fi->i_chunk_total = S_ISDIR(fi->i_mode) ? 1 : CEILING((unsigned)fi->i_size,
  279. rawfs_sb->page_data_size);
  280. /* do GC, if the required space is not enough */
  281. result = rawfs_reserve_space(sb, fi->i_chunk_total);
  282. if (result < 0) {
  283. retval = result;
  284. goto out;
  285. }
  286. /* get entry from file list */
  287. entry = rawfs_file_list_get(sb, fi->i_name, fi->i_parent_folder_id);
  288. if (!entry) {
  289. RAWFS_PRINT(RAWFS_DBG_FILE,
  290. "rawfs_reg_file_aio_write: %s file list entry missing\n", fi->i_name);
  291. dump_stack();
  292. goto out;
  293. }
  294. /* Write File */
  295. {
  296. int preceding_pages, rear_pages;
  297. struct rawfs_page *page_buf = NULL;
  298. int i;
  299. /* Prepare page buffer */
  300. page_buf = kzalloc(rawfs_sb->page_size, GFP_NOFS);
  301. if (page_buf == NULL) {
  302. retval = 0;
  303. goto out;
  304. }
  305. starting_page = rawfs_sb->data_block_free_page_index;
  306. preceding_pages = FLOOR((unsigned)pos, rawfs_sb->page_data_size);
  307. total_pages = CEILING((unsigned)fi->i_size, rawfs_sb->page_data_size);
  308. rear_pages = CEILING((unsigned)pos + iv->iov_len,
  309. rawfs_sb->page_data_size);
  310. remain_buf_size = iv->iov_len;
  311. RAWFS_PRINT(RAWFS_DBG_FILE,
  312. "rawfs_reg_file_aio_write %s, preceding %d, rear %d, total %d, remain %d\n",
  313. inode_info->i_name, preceding_pages, rear_pages, total_pages,
  314. remain_buf_size);
  315. /* Step 1: Copy preceding pages, if starting pos is not 0. */
  316. for (i = 0; i < total_pages; i++) {
  317. /* Read, if necessary, (no need for new files) */
  318. if ((i <= preceding_pages) || (i >= rear_pages))
  319. rawfs_sb->dev.read_page(sb,
  320. entry->i_location_block,
  321. entry->i_location_page+i,
  322. page_buf);
  323. /* Update info */
  324. memcpy(&page_buf->i_info.i_file_info, fi,
  325. sizeof(struct rawfs_file_info));
  326. /* Within Modify Range: Copy Modify */
  327. if ((i >= preceding_pages) && (i <= rear_pages)) {
  328. int start_in_buf;
  329. int copy_len;
  330. start_in_buf = (curr_file_pos % rawfs_sb->page_data_size);
  331. copy_len = ((start_in_buf + remain_buf_size) >
  332. rawfs_sb->page_data_size) ?
  333. (rawfs_sb->page_data_size - start_in_buf) :
  334. remain_buf_size;
  335. if (copy_from_user(&page_buf->i_data[0] + start_in_buf,
  336. (char *)iv->iov_base + curr_buf_pos, copy_len)) {
  337. retval = -EFAULT;
  338. goto out2;
  339. }
  340. curr_buf_pos += copy_len;
  341. remain_buf_size -= copy_len;
  342. RAWFS_PRINT(RAWFS_DBG_FILE,
  343. "rawfs_reg_file_aio_write %s, %d, curr %d, remain %d start %d copy %d starting %X\n",
  344. inode_info->i_name, i, curr_buf_pos, remain_buf_size,
  345. start_in_buf, copy_len,
  346. *(unsigned int *)(&page_buf->i_data[0] + start_in_buf));
  347. }
  348. rawfs_page_signature(sb, page_buf);
  349. /* Write */
  350. rawfs_sb->dev.write_page(sb,
  351. rawfs_sb->data_block,
  352. rawfs_sb->data_block_free_page_index,
  353. page_buf);
  354. rawfs_sb->data_block_free_page_index++;
  355. fi->i_chunk_index++;
  356. }
  357. out2:
  358. kfree(page_buf);
  359. }
  360. if (retval > 0)
  361. *ppos = pos + retval;
  362. file_accessed(filp);
  363. /* Update Inode: file size, block, page */
  364. i_size_write(inode, fi->i_size);
  365. /* TODO: Get inode lock when update */
  366. inode_info->i_location_block = rawfs_sb->data_block;
  367. inode_info->i_location_page = starting_page;
  368. inode_info->i_location_page_count = total_pages;
  369. /* update location */
  370. entry->i_location_block = rawfs_sb->data_block;
  371. entry->i_location_page = starting_page;
  372. entry->i_location_page_count = total_pages;
  373. out:
  374. kfree(fi);
  375. /* Release Lock */
  376. mutex_unlock(&rawfs_sb->rawfs_lock);
  377. return retval;
  378. }
  379. EXPORT_SYMBOL_GPL(rawfs_reg_file_aio_write);
  380. /* ----------------------------------------------------------------------------- */
  381. /* Internal Functions */
  382. /* ----------------------------------------------------------------------------- */
  383. int rawfs_reg_file_create(struct inode *dir, struct dentry *dentry,
  384. umode_t mode, struct nameidata *nd)
  385. {
  386. int result = 0;
  387. struct super_block *sb = dentry->d_sb;
  388. struct inode *inode = dentry->d_inode;
  389. struct rawfs_sb_info *rawfs_sb = RAWFS_SB(sb);
  390. struct rawfs_inode_info *inode_info = RAWFS_I(inode);
  391. struct rawfs_page *page_buf = NULL;
  392. RAWFS_PRINT(RAWFS_DBG_FILE, "rawfs_reg_file_create: i_name=%s\n",
  393. inode_info->i_name);
  394. page_buf = kzalloc(rawfs_sb->page_size, GFP_NOFS);
  395. if (page_buf == NULL) {
  396. result = -ENOMEM;
  397. goto out;
  398. }
  399. result = rawfs_reserve_space(sb, 1);
  400. if (result < 0)
  401. goto out;
  402. /* rawfs_fill_file_info(inode, &page_buf->i_info.i_file_info); */
  403. rawfs_fill_fileinfo_by_dentry(dentry, &page_buf->i_info.i_file_info);
  404. page_buf->i_info.i_file_info.i_mode = mode;
  405. page_buf->i_info.i_file_info.i_size = 0;
  406. page_buf->i_info.i_file_info.i_chunk_total = 1;
  407. page_buf->i_info.i_file_info.i_chunk_index = 1;
  408. rawfs_page_signature(sb, page_buf);
  409. rawfs_sb->dev.write_page(sb,
  410. rawfs_sb->data_block,
  411. rawfs_sb->data_block_free_page_index,
  412. page_buf);
  413. /* Update inode_info */
  414. inode_info->i_location_block = rawfs_sb->data_block;
  415. inode_info->i_location_page = rawfs_sb->data_block_free_page_index;
  416. inode->i_size = 0;
  417. rawfs_sb->data_block_free_page_index++;
  418. out:
  419. kfree(page_buf);
  420. return result;
  421. }
  422. EXPORT_SYMBOL_GPL(rawfs_reg_file_create);
  423. int rawfs_reg_file_delete(struct inode *dir, struct dentry *dentry)
  424. {
  425. int result = 0;
  426. struct super_block *sb = dentry->d_sb;
  427. struct inode *inode = dentry->d_inode;
  428. struct rawfs_sb_info *rawfs_sb = RAWFS_SB(sb);
  429. struct rawfs_inode_info *inode_info = RAWFS_I(inode);
  430. struct rawfs_page *page_buf = NULL;
  431. RAWFS_PRINT(RAWFS_DBG_FILE, "rawfs_reg_file_delete %s\n",
  432. dentry->d_name.name);
  433. page_buf = kzalloc(rawfs_sb->page_size, GFP_NOFS);
  434. if (page_buf == NULL) {
  435. result = -ENOMEM;
  436. goto out;
  437. }
  438. /* Do GC, if there's no free_pages */
  439. if ((rawfs_sb->data_block_free_page_index+1) > rawfs_sb->pages_per_block) {
  440. int reclaimed_size;
  441. reclaimed_size = rawfs_dev_garbage_collection(sb);
  442. if (reclaimed_size <= 0) {
  443. RAWFS_PRINT(RAWFS_DBG_FILE,
  444. "rawfs_reg_file_delete: Disk full: %d\n", reclaimed_size);
  445. result = -ENOSPC;
  446. goto out;
  447. }
  448. }
  449. /* Read existing data */
  450. rawfs_sb->dev.read_page(sb,
  451. inode_info->i_location_block,
  452. inode_info->i_location_page,
  453. page_buf);
  454. /* Set i_chun_total as zero to mark delete. */
  455. page_buf->i_info.i_file_info.i_chunk_total = -1;
  456. page_buf->i_info.i_file_info.i_chunk_index = -1;
  457. page_buf->i_info.i_file_info.i_size = 0;
  458. rawfs_page_signature(sb, page_buf);
  459. rawfs_sb->dev.write_page(sb,
  460. rawfs_sb->data_block,
  461. rawfs_sb->data_block_free_page_index,
  462. page_buf);
  463. rawfs_sb->data_block_free_page_index++;
  464. out:
  465. kfree(page_buf);
  466. return result;
  467. }
  468. EXPORT_SYMBOL_GPL(rawfs_reg_file_delete);
  469. /* This function is used by rawfs_dir_rename() & rawfs_setattr()
  470. This function will put the new copeid file into file list. */
  471. int rawfs_reg_file_copy(struct inode *src_dir, struct dentry *src_dentry,
  472. struct inode *dest_dir, struct dentry *dest_dentry)
  473. {
  474. int result = 0;
  475. int starting_page;
  476. struct inode *src_inode = src_dentry->d_inode;
  477. struct super_block *sb = src_dentry->d_sb;
  478. struct rawfs_sb_info *rawfs_sb = RAWFS_SB(sb);
  479. struct rawfs_file_info *fi = NULL;
  480. struct rawfs_file_list_entry *src_info;
  481. if ((dest_dir == NULL) && (dest_dentry == NULL)) {
  482. RAWFS_PRINT(RAWFS_DBG_FILE, "rawfs_reg_file_copy (setattr) %s\n",
  483. src_dentry->d_name.name);
  484. dest_dir = src_dir;
  485. dest_dentry = src_dentry;
  486. } else {
  487. RAWFS_PRINT(RAWFS_DBG_FILE, "rawfs_reg_file_copy (rename) %s -> %s\n",
  488. src_dentry->d_name.name, dest_dentry->d_name.name);
  489. }
  490. fi = kzalloc(sizeof(struct rawfs_file_info), GFP_NOFS);
  491. if (!fi) {
  492. result = -ENOMEM;
  493. goto out;
  494. }
  495. rawfs_fill_file_info(src_inode , fi);
  496. fi->i_parent_folder_id = RAWFS_I(dest_dir)->i_id;
  497. strncpy(fi->i_name, dest_dentry->d_name.name,
  498. strlen(dest_dentry->d_name.name)+1);
  499. fi->i_chunk_index = 1;
  500. fi->i_chunk_total = S_ISDIR(fi->i_mode) ? 1 : CEILING((unsigned)fi->i_size,
  501. rawfs_sb->page_data_size);
  502. /* do GC, if the required space is not enough */
  503. result = rawfs_reserve_space(sb, fi->i_chunk_total);
  504. if (result < 0)
  505. goto out;
  506. /* Get soruce location & starting page again,
  507. it might be change to new location after GC */
  508. src_info = rawfs_file_list_get(sb,
  509. src_dentry->d_name.name,
  510. RAWFS_I(src_dir)->i_id);
  511. starting_page = rawfs_sb->data_block_free_page_index;
  512. if (!src_info) {
  513. RAWFS_PRINT(RAWFS_DBG_FILE,
  514. "rawfs_reg_file_copy: src file %s @ %X missing after GC\n",
  515. src_dentry->d_name.name,
  516. RAWFS_I(src_dir)->i_id);
  517. goto out;
  518. }
  519. {
  520. int total_pages;
  521. struct rawfs_page *page_buf = NULL;
  522. int i;
  523. page_buf = kzalloc(rawfs_sb->page_size, GFP_NOFS);
  524. if (page_buf == NULL) {
  525. result = -ENOMEM;
  526. goto out;
  527. }
  528. total_pages = S_ISDIR(fi->i_mode) ? 1 : CEILING((unsigned)fi->i_size,
  529. rawfs_sb->page_data_size);
  530. for (i = 0; i < total_pages; i++) {
  531. RAWFS_PRINT(RAWFS_DBG_FILE,
  532. "rawfs_reg_file_copy copy %d,%d to %d,%d\n",
  533. src_info->i_location_block,
  534. src_info->i_location_page+i,
  535. rawfs_sb->data_block,
  536. rawfs_sb->data_block_free_page_index);
  537. rawfs_sb->dev.read_page(sb,
  538. src_info->i_location_block,
  539. src_info->i_location_page+i,
  540. page_buf);
  541. /* Update info */
  542. memcpy(&page_buf->i_info.i_file_info, fi,
  543. sizeof(struct rawfs_file_info));
  544. rawfs_page_signature(sb, page_buf);
  545. rawfs_sb->dev.write_page(sb,
  546. rawfs_sb->data_block,
  547. rawfs_sb->data_block_free_page_index,
  548. page_buf);
  549. rawfs_sb->data_block_free_page_index++;
  550. fi->i_chunk_index++;
  551. }
  552. kfree(page_buf);
  553. }
  554. /* Add to file list, so that rawf_dir_rename can get the new
  555. location of the file from list. */
  556. rawfs_file_list_add(sb, fi, rawfs_sb->data_block, starting_page);
  557. out:
  558. kfree(fi);
  559. return result;
  560. }
  561. EXPORT_SYMBOL_GPL(rawfs_reg_file_copy);
  562. /* Read page, by pass page cache, always read from device. */
  563. static int rawfs_readpage_nolock(struct file *filp, struct page *page)
  564. {
  565. struct super_block *sb = filp->f_path.dentry->d_sb;
  566. struct inode *inode = filp->f_path.dentry->d_inode;
  567. struct rawfs_sb_info *rawfs_sb = RAWFS_SB(sb);
  568. struct rawfs_inode_info *inode_info = RAWFS_I(inode);
  569. loff_t pos;
  570. unsigned int curr_file_pos;
  571. unsigned int curr_buf_pos = 0;
  572. int remain_buf_size;
  573. unsigned size;
  574. int retval;
  575. unsigned char *pg_buf;
  576. /* pg_buf = kmap_atomic(page); */
  577. pg_buf = kmap(page);
  578. /* TODO: check pg_buf */
  579. size = i_size_read(inode);
  580. curr_file_pos = pos = page->index << PAGE_CACHE_SHIFT;
  581. retval = PAGE_CACHE_SIZE;
  582. RAWFS_PRINT(RAWFS_DBG_FILE,
  583. "rawfs_readpage %s @ folder %X, page %ld, pos %lld, len %d, filesize: %d, pg_buf %lx\n",
  584. inode_info->i_name,
  585. inode_info->i_parent_folder_id,
  586. page->index,
  587. pos, retval, size, (unsigned long)pg_buf);
  588. if ((retval + pos) >= size)
  589. retval = size - pos;
  590. if (pos < size) {
  591. {
  592. int preceding_pages, rear_pages;
  593. struct rawfs_page *page_buf = NULL;
  594. int i;
  595. /* Prepare page buffer */
  596. page_buf = kzalloc(rawfs_sb->page_size, GFP_NOFS);
  597. if (page_buf == NULL) {
  598. retval = 0;
  599. goto out;
  600. }
  601. preceding_pages = FLOOR((unsigned)pos, rawfs_sb->page_data_size);
  602. rear_pages = CEILING((unsigned)pos + retval,
  603. rawfs_sb->page_data_size);
  604. remain_buf_size = retval;
  605. RAWFS_PRINT(RAWFS_DBG_FILE,
  606. "rawfs_readpage %s, preceding %d, rear %d, remain %d ",
  607. inode_info->i_name, preceding_pages, rear_pages,
  608. remain_buf_size);
  609. /* Step 1: Copy preceding pages, if starting pos is not 0. */
  610. for (i = preceding_pages; i < rear_pages; i++) {
  611. /* Read page */
  612. rawfs_sb->dev.read_page(sb,
  613. inode_info->i_location_block,
  614. inode_info->i_location_page+i,
  615. page_buf);
  616. /* Copy required parts */
  617. {
  618. int start_in_buf;
  619. int copy_len;
  620. start_in_buf = (curr_file_pos % rawfs_sb->page_data_size);
  621. copy_len = ((start_in_buf + remain_buf_size) >
  622. rawfs_sb->page_data_size) ?
  623. (rawfs_sb->page_data_size - start_in_buf) :
  624. remain_buf_size;
  625. memcpy(pg_buf + curr_buf_pos,
  626. &page_buf->i_data[0] + start_in_buf, copy_len);
  627. RAWFS_PRINT(RAWFS_DBG_FILE,
  628. "rawfs_readpage %s, %d, curr %d, remain %d start %d copy %d pattern %X",
  629. inode_info->i_name, i, curr_buf_pos, remain_buf_size,
  630. start_in_buf, copy_len,
  631. *(unsigned int *)(&page_buf->i_data[0] + start_in_buf));
  632. curr_buf_pos += copy_len;
  633. remain_buf_size -= copy_len;
  634. }
  635. }
  636. kfree(page_buf);
  637. }
  638. } else {
  639. retval = 0;
  640. }
  641. out:
  642. SetPageUptodate(page);
  643. ClearPageError(page);
  644. flush_dcache_page(page);
  645. /* kunmap_atomic(pg_buf); */
  646. kunmap(page);
  647. unlock_page(page);
  648. return 0;
  649. }
  650. int rawfs_readpage(struct file *filp, struct page *page)
  651. {
  652. int result;
  653. result = rawfs_readpage_nolock(filp, page);
  654. unlock_page(page);
  655. return result;
  656. }
  657. EXPORT_SYMBOL_GPL(rawfs_readpage);
  658. int rawfs_write_begin(struct file *filp, struct address_space *mapping,
  659. loff_t pos, unsigned len, unsigned flags,
  660. struct page **pagep, void **fsdata)
  661. {
  662. RAWFS_PRINT(RAWFS_DBG_FILE, "rawfs_write_begin: unexpected call !");
  663. BUG();
  664. return simple_write_begin(filp, mapping, pos, len, flags, pagep, fsdata);
  665. }
  666. EXPORT_SYMBOL_GPL(rawfs_write_begin);
  667. int rawfs_write_end(struct file *filp, struct address_space *mapping,
  668. loff_t pos, unsigned len, unsigned copied,
  669. struct page *pg, void *fsdata)
  670. {
  671. RAWFS_PRINT(RAWFS_DBG_FILE, "rawfs_write_end: unexpected call !");
  672. BUG();
  673. return simple_write_end(filp, mapping, pos, len, copied, pg, fsdata);
  674. }
  675. EXPORT_SYMBOL_GPL(rawfs_write_end);
  676. MODULE_AUTHOR("Perry Hsu <perry.hsu@mediatek.com>");
  677. MODULE_DESCRIPTION("RAW file system for NAND flash");
  678. MODULE_LICENSE("GPL");