dfr.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /*
  2. * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation; either version 2
  7. * of the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #ifndef _SDFAT_DEFRAG_H
  18. #define _SDFAT_DEFRAG_H
  19. #ifdef CONFIG_SDFAT_DFR
  20. /* Tuning parameters */
  21. #define DFR_MIN_TIMEOUT (1 * HZ) // Minimum timeout for forced-sync
  22. #define DFR_DEFAULT_TIMEOUT (10 * HZ) // Default timeout for forced-sync
  23. #define DFR_DEFAULT_CLEAN_RATIO (50) // Wake-up daemon when clean AU ratio under 50%
  24. #define DFR_DEFAULT_WAKEUP_RATIO (10) // Wake-up daemon when clean AU ratio under 10%, regardless of frag_ratio
  25. #define DFR_DEFAULT_FRAG_RATIO (130) // Wake-up daemon when frag_ratio over 130%
  26. #define DFR_DEFAULT_PACKING_RATIO (10) // Call allocator with PACKING flag, when clean AU ratio under 10%
  27. #define DFR_DEFAULT_STOP_RATIO (98) // Stop defrag_daemon when disk used ratio over 98%
  28. #define DFR_FULL_RATIO (100)
  29. #define DFR_MAX_AU_MOVED (16) // Maximum # of AUs for a request
  30. /* Debugging support*/
  31. #define dfr_err(fmt, args...) pr_err("DFR: " fmt "\n", args)
  32. #ifdef CONFIG_SDFAT_DFR_DEBUG
  33. #define dfr_debug(fmt, args...) pr_debug("DFR: " fmt "\n", args)
  34. #else
  35. #define dfr_debug(fmt, args...)
  36. #endif
  37. /* Error handling */
  38. #define ERR_HANDLE(err) { \
  39. if (err) { \
  40. dfr_debug("err %d", err); \
  41. goto error; \
  42. } \
  43. }
  44. #define ERR_HANDLE2(cond, err, val) { \
  45. if (cond) { \
  46. err = val; \
  47. dfr_debug("err %d", err); \
  48. goto error; \
  49. } \
  50. }
  51. /* Arguments IN-OUT */
  52. #define IN
  53. #define OUT
  54. #define INOUT
  55. /* Macros */
  56. #define GET64_HI(var64) ((unsigned int)((var64) >> 32))
  57. #define GET64_LO(var64) ((unsigned int)(((var64) << 32) >> 32))
  58. #define SET64_HI(dst64, var32) { (dst64) = ((loff_t)(var32) << 32) | ((dst64) & 0x00000000ffffffffLL); }
  59. #define SET64_LO(dst64, var32) { (dst64) = ((dst64) & 0xffffffff00000000LL) | ((var32) & 0x00000000ffffffffLL); }
  60. #define GET32_HI(var32) ((unsigned short)((var32) >> 16))
  61. #define GET32_LO(var32) ((unsigned short)(((var32) << 16) >> 16))
  62. #define SET32_HI(dst32, var16) { (dst32) = ((unsigned int)(var16) << 16) | ((dst32) & 0x0000ffff); }
  63. #define SET32_LO(dst32, var16) { (dst32) = ((dst32) & 0xffff0000) | ((unsigned int)(var16) & 0x0000ffff); }
  64. /* FAT32 related */
  65. #define FAT32_EOF (0x0fffffff)
  66. #define FAT32_RESERVED (0x0ffffff7)
  67. #define FAT32_UNUSED_CLUS (2)
  68. #define CLUS_PER_AU(sb) ( \
  69. (SDFAT_SB(sb)->options.amap_opt.sect_per_au) >> (SDFAT_SB(sb)->fsi.sect_per_clus_bits) \
  70. )
  71. #define PAGES_PER_AU(sb) ( \
  72. ((SDFAT_SB(sb)->options.amap_opt.sect_per_au) << ((sb)->s_blocksize_bits)) \
  73. >> PAGE_SHIFT \
  74. )
  75. #define PAGES_PER_CLUS(sb) ((SDFAT_SB(sb)->fsi.cluster_size) >> PAGE_SHIFT)
  76. #define FAT32_CHECK_CLUSTER(fsi, clus, err) \
  77. { \
  78. if (((clus) < FAT32_UNUSED_CLUS) || \
  79. ((clus) > (fsi)->num_clusters) || \
  80. ((clus) >= FAT32_RESERVED)) { \
  81. dfr_err("clus %08x, fsi->num_clusters %08x", (clus), (fsi)->num_clusters); \
  82. err = -EINVAL; \
  83. } else { \
  84. err = 0; \
  85. } \
  86. }
  87. /* IOCTL_DFR_INFO */
  88. struct defrag_info_arg {
  89. /* PBS info */
  90. unsigned int sec_sz;
  91. unsigned int clus_sz;
  92. unsigned long long total_sec;
  93. unsigned long long fat_offset_sec;
  94. unsigned int fat_sz_sec;
  95. unsigned int n_fat;
  96. unsigned int hidden_sectors;
  97. /* AU info */
  98. unsigned int sec_per_au;
  99. };
  100. /* IOC_DFR_TRAV */
  101. #define DFR_TRAV_HEADER_IDX (0)
  102. #define DFR_TRAV_TYPE_HEADER (0x0000000F)
  103. #define DFR_TRAV_TYPE_DIR (1)
  104. #define DFR_TRAV_TYPE_FILE (2)
  105. #define DFR_TRAV_TYPE_TEST (DFR_TRAV_TYPE_HEADER | 0x10000000)
  106. #define DFR_TRAV_ROOT_IPOS (0xFFFFFFFFFFFFFFFFLL)
  107. struct defrag_trav_arg {
  108. int type;
  109. unsigned int start_clus;
  110. loff_t i_pos;
  111. char name[MAX_DOSNAME_BUF_SIZE];
  112. char dummy1;
  113. int dummy2;
  114. };
  115. #define DFR_TRAV_STAT_DONE (0x1)
  116. #define DFR_TRAV_STAT_MORE (0x2)
  117. #define DFR_TRAV_STAT_ERR (0xFF)
  118. struct defrag_trav_header {
  119. int type;
  120. unsigned int start_clus;
  121. loff_t i_pos;
  122. char name[MAX_DOSNAME_BUF_SIZE];
  123. char stat;
  124. unsigned int nr_entries;
  125. };
  126. /* IOC_DFR_REQ */
  127. #define REQ_HEADER_IDX (0)
  128. #define DFR_CHUNK_STAT_ERR (0xFFFFFFFF)
  129. #define DFR_CHUNK_STAT_REQ (0x1)
  130. #define DFR_CHUNK_STAT_WB (0x2)
  131. #define DFR_CHUNK_STAT_FAT (0x4)
  132. #define DFR_CHUNK_STAT_PREP (DFR_CHUNK_STAT_REQ | DFR_CHUNK_STAT_WB | DFR_CHUNK_STAT_FAT)
  133. #define DFR_CHUNK_STAT_PASS (0x0000000F)
  134. struct defrag_chunk_header {
  135. int mode;
  136. unsigned int nr_chunks;
  137. loff_t dummy1;
  138. int dummy2[4];
  139. union {
  140. int *dummy3;
  141. int dummy4;
  142. };
  143. int dummy5;
  144. };
  145. struct defrag_chunk_info {
  146. int stat;
  147. /* File related */
  148. unsigned int f_clus;
  149. loff_t i_pos;
  150. /* Cluster related */
  151. unsigned int d_clus;
  152. unsigned int nr_clus;
  153. unsigned int prev_clus;
  154. unsigned int next_clus;
  155. union {
  156. void *dummy;
  157. /* req status */
  158. unsigned int new_idx;
  159. };
  160. /* AU related */
  161. unsigned int au_clus;
  162. };
  163. /* Global info */
  164. #define DFR_MODE_BACKGROUND (0x1)
  165. #define DFR_MODE_FOREGROUND (0x2)
  166. #define DFR_MODE_ONESHOT (0x4)
  167. #define DFR_MODE_BATCHED (0x8)
  168. #define DFR_MODE_TEST (DFR_MODE_BACKGROUND | 0x10000000)
  169. #define DFR_SB_STAT_IDLE (0)
  170. #define DFR_SB_STAT_REQ (1)
  171. #define DFR_SB_STAT_VALID (2)
  172. #define DFR_INO_STAT_IDLE (0)
  173. #define DFR_INO_STAT_REQ (1)
  174. struct defrag_info {
  175. struct mutex lock;
  176. atomic_t stat;
  177. struct defrag_chunk_info *chunks;
  178. unsigned int nr_chunks;
  179. struct list_head entry;
  180. };
  181. /* SPO test flags */
  182. #define DFR_SPO_NONE (0)
  183. #define DFR_SPO_NORMAL (1)
  184. #define DFR_SPO_DISCARD (2)
  185. #define DFR_SPO_FAT_NEXT (3)
  186. #define DFR_SPO_RANDOM (4)
  187. /* Extern functions */
  188. int defrag_get_info(struct super_block *sb, struct defrag_info_arg *arg);
  189. int defrag_scan_dir(struct super_block *sb, struct defrag_trav_arg *arg);
  190. int defrag_validate_cluster(struct inode *inode, struct defrag_chunk_info *chunk, int skip_prev);
  191. int defrag_reserve_clusters(struct super_block *sb, int nr_clus);
  192. int defrag_mark_ignore(struct super_block *sb, unsigned int clus);
  193. void defrag_unmark_ignore_all(struct super_block *sb);
  194. int defrag_map_cluster(struct inode *inode, unsigned int clu_offset, unsigned int *clu);
  195. void defrag_writepage_end_io(struct page *page);
  196. void defrag_update_fat_prev(struct super_block *sb, int force);
  197. void defrag_update_fat_next(struct super_block *sb);
  198. void defrag_check_discard(struct super_block *sb);
  199. int defrag_free_cluster(struct super_block *sb, unsigned int clus);
  200. int defrag_check_defrag_required(struct super_block *sb, int *totalau, int *cleanau, int *fullau);
  201. int defrag_check_defrag_on(struct inode *inode, loff_t start, loff_t end, int cancel, const char *caller);
  202. #ifdef CONFIG_SDFAT_DFR_DEBUG
  203. void defrag_spo_test(struct super_block *sb, int flag, const char *caller);
  204. #endif
  205. #endif /* CONFIG_SDFAT_DFR */
  206. #endif /* _SDFAT_DEFRAG_H */