support.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:7k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * support.c -  Specific support functions
  3.  *
  4.  * Copyright (C) 1997 Martin von L鰓is
  5.  * Copyright (C) 1997 R間is Duchesne
  6.  * Copyright (C) 2001 Anton Altaparmakov (AIA)
  7.  */
  8. #include "ntfstypes.h"
  9. #include "struct.h"
  10. #include "support.h"
  11. #include <stdarg.h>
  12. #include <linux/slab.h>
  13. #include <linux/locks.h>
  14. #include <linux/fs.h>
  15. #include "util.h"
  16. #include "inode.h"
  17. #include "macros.h"
  18. #include <linux/nls.h>
  19. static char print_buf[1024];
  20. #ifdef DEBUG
  21. #include "sysctl.h"
  22. #include <linux/kernel.h>
  23. /* Debugging output */
  24. void ntfs_debug(int mask, const char *fmt, ...)
  25. {
  26. va_list ap;
  27. /* Filter it with the debugging level required */
  28. if (ntdebug & mask) {
  29. va_start(ap,fmt);
  30. strcpy(print_buf, KERN_DEBUG "NTFS: ");
  31. vsprintf(print_buf + 9, fmt, ap);
  32. printk(print_buf);
  33. va_end(ap);
  34. }
  35. }
  36. #ifndef ntfs_malloc
  37. /* Verbose kmalloc */
  38. void *ntfs_malloc(int size)
  39. {
  40. void *ret;
  41. ret = kmalloc(size, GFP_KERNEL);
  42. ntfs_debug(DEBUG_MALLOC, "Allocating %x at %pn", size, ret);
  43. return ret;
  44. }
  45. #endif
  46. #ifndef ntfs_free
  47. /* Verbose kfree() */
  48. void ntfs_free(void *block)
  49. {
  50.         ntfs_debug(DEBUG_MALLOC, "Freeing memory at %pn", block);
  51. kfree(block);
  52. }
  53. #endif
  54. #else /* End of DEBUG functions. Normal ones below... */
  55. #ifndef ntfs_malloc
  56. void *ntfs_malloc(int size)
  57. {
  58. return kmalloc(size, GFP_KERNEL);
  59. }
  60. #endif
  61. #ifndef ntfs_free
  62. void ntfs_free(void *block)
  63. {
  64. kfree(block);
  65. }
  66. #endif
  67. #endif /* DEBUG */
  68. void ntfs_bzero(void *s, int n)
  69. {
  70. memset(s, 0, n);
  71. }
  72. /* These functions deliberately return no value. It is dest, anyway,
  73.    and not used anywhere in the NTFS code.  */
  74. void ntfs_memcpy(void *dest, const void *src, ntfs_size_t n)
  75. {
  76. memcpy(dest, src, n);
  77. }
  78. void ntfs_memmove(void *dest, const void *src, ntfs_size_t n)
  79. {
  80. memmove(dest, src, n);
  81. }
  82. /* Warn that an error occurred. */
  83. void ntfs_error(const char *fmt,...)
  84. {
  85.         va_list ap;
  86.         va_start(ap, fmt);
  87.         strcpy(print_buf, KERN_ERR "NTFS: ");
  88.         vsprintf(print_buf + 9, fmt, ap);
  89.         printk(print_buf);
  90.         va_end(ap);
  91. }
  92. int ntfs_read_mft_record(ntfs_volume *vol, int mftno, char *buf)
  93. {
  94. int error;
  95. ntfs_io io;
  96. ntfs_debug(DEBUG_OTHER, "read_mft_record 0x%xn", mftno);
  97. if (mftno == FILE_Mft)
  98. {
  99. ntfs_memcpy(buf, vol->mft, vol->mft_record_size);
  100. return 0;
  101. }
  102. if (!vol->mft_ino)
  103. {
  104. printk(KERN_ERR "NTFS: mft_ino is NULL. Something is terribly "
  105. "wrong here!n");
  106. return -ENODATA;
  107. }
  108.   io.fn_put = ntfs_put;
  109. io.fn_get = 0;
  110. io.param = buf;
  111. io.size = vol->mft_record_size;
  112. ntfs_debug(DEBUG_OTHER, "read_mft_record: calling ntfs_read_attr with: "
  113. "mftno = 0x%x, vol->mft_record_size_bits = 0x%x, "
  114. "mftno << vol->mft_record_size_bits = 0x%Lxn", mftno,
  115. vol->mft_record_size_bits,
  116. (__s64)mftno << vol->mft_record_size_bits);
  117. error = ntfs_read_attr(vol->mft_ino, vol->at_data, NULL,
  118. (__s64)mftno << vol->mft_record_size_bits, &io);
  119. if (error || (io.size != vol->mft_record_size)) {
  120. ntfs_debug(DEBUG_OTHER, "read_mft_record: read 0x%x failed "
  121.     "(%d,%d,%d)n", mftno, error, io.size,
  122.     vol->mft_record_size);
  123. return error ? error : -ENODATA;
  124. }
  125. ntfs_debug(DEBUG_OTHER, "read_mft_record: finished read 0x%xn", mftno);
  126. if (!ntfs_check_mft_record(vol, buf)) {
  127. /* FIXME: This is incomplete behaviour. We might be able to
  128.  * recover at this stage. ntfs_check_mft_record() is too
  129.  * conservative at aborting it's operations. It is OK for
  130.  * now as we just can't handle some on disk structures
  131.  * this way. (AIA) */
  132. printk(KERN_WARNING "NTFS: Invalid MFT record for 0x%xn", mftno);
  133. return -EIO;
  134. }
  135. ntfs_debug(DEBUG_OTHER, "read_mft_record: Done 0x%xn", mftno);
  136. return 0;
  137. }
  138. int ntfs_getput_clusters(ntfs_volume *vol, int cluster, ntfs_size_t start_offs,
  139. ntfs_io *buf)
  140. {
  141. struct super_block *sb = NTFS_SB(vol);
  142. struct buffer_head *bh;
  143. int length = buf->size;
  144. int error = 0;
  145. ntfs_size_t to_copy;
  146. ntfs_debug(DEBUG_OTHER, "%s_clusters %d %d %dn", 
  147.    buf->do_read ? "get" : "put", cluster, start_offs, length);
  148. to_copy = vol->cluster_size - start_offs;
  149. while (length) {
  150. if (!(bh = sb_bread(sb, cluster))) {
  151. ntfs_debug(DEBUG_OTHER, "%s failedn",
  152.    buf->do_read ? "Reading" : "Writing");
  153. error = -EIO;
  154. goto error_ret;
  155. }
  156. if (to_copy > length)
  157. to_copy = length;
  158. lock_buffer(bh);
  159. if (buf->do_read) {
  160. buf->fn_put(buf, bh->b_data + start_offs, to_copy);
  161. unlock_buffer(bh);
  162. } else {
  163. buf->fn_get(bh->b_data + start_offs, buf, to_copy);
  164. mark_buffer_dirty(bh);
  165. unlock_buffer(bh);
  166. /*
  167.  * Note: We treat synchronous IO on a per volume basis
  168.  * disregarding flags of individual inodes. This can
  169.  * lead to some strange write ordering effects upon a
  170.  * remount with a change in the sync flag but it should
  171.  * not break anything. [Except if the system crashes
  172.  * at that point in time but there would be more thigs
  173.  * to worry about than that in that case...]. (AIA)
  174.  */
  175. if (sb->s_flags & MS_SYNCHRONOUS) {
  176. ll_rw_block(WRITE, 1, &bh);
  177. wait_on_buffer(bh);
  178. if (buffer_req(bh) && !buffer_uptodate(bh)) {
  179. printk(KERN_ERR "IO error syncing NTFS "
  180.        "cluster [%s:%i]n",
  181.        bdevname(sb->s_dev), cluster);
  182. brelse(bh);
  183. error = -EIO;
  184. goto error_ret;
  185. }
  186. }
  187. }
  188. brelse(bh);
  189. length -= to_copy;
  190. start_offs = 0;
  191. to_copy = vol->cluster_size;
  192. cluster++;
  193. }
  194. error_ret:
  195. return error;
  196. }
  197. ntfs_time64_t ntfs_now(void)
  198. {
  199. return ntfs_unixutc2ntutc(CURRENT_TIME);
  200. }
  201. int ntfs_dupuni2map(ntfs_volume *vol, ntfs_u16 *in, int in_len, char **out,
  202. int *out_len)
  203. {
  204. int i, o, chl, chi;
  205. char *result, *buf, charbuf[NLS_MAX_CHARSET_SIZE];
  206. struct nls_table *nls = vol->nls_map;
  207. result = ntfs_malloc(in_len + 1);
  208. if (!result)
  209. return -ENOMEM;
  210. *out_len = in_len;
  211. for (i = o = 0; i < in_len; i++) {
  212. /* FIXME: Byte order? */
  213. wchar_t uni = in[i];
  214. if ((chl = nls->uni2char(uni, charbuf,
  215. NLS_MAX_CHARSET_SIZE)) > 0) {
  216. /* Adjust result buffer. */
  217. if (chl > 1) {
  218. buf = ntfs_malloc(*out_len + chl - 1);
  219. if (!buf) {
  220. i = -ENOMEM;
  221. goto err_ret;
  222. }
  223. memcpy(buf, result, o);
  224. ntfs_free(result);
  225. result = buf;
  226. *out_len += (chl - 1);
  227. }
  228. for (chi = 0; chi < chl; chi++)
  229. result[o++] = charbuf[chi];
  230. } else {
  231. /* Invalid character. */
  232. printk(KERN_ERR "NTFS: Unicode name contains a "
  233. "character that cannot be converted "
  234. "to chosen character set. Remount "
  235. "with utf8 encoding and this should "
  236. "work.n");
  237. i = -EILSEQ;
  238. goto err_ret;
  239. }
  240. }
  241. result[*out_len] = '';
  242. *out = result;
  243. return 0;
  244. err_ret:
  245. ntfs_free(result);
  246. *out_len = 0;
  247. *out = NULL;
  248. return i;
  249. }
  250. int ntfs_dupmap2uni(ntfs_volume *vol, char* in, int in_len, ntfs_u16 **out,
  251. int *out_len)
  252. {
  253. int i, o;
  254. ntfs_u16 *result;
  255. struct nls_table *nls = vol->nls_map;
  256. *out = result = ntfs_malloc(2 * in_len);
  257. if (!result) {
  258. *out_len = 0;
  259. return -ENOMEM;
  260. }
  261. *out_len = in_len;
  262. for (i = o = 0; i < in_len; i++, o++) {
  263. wchar_t uni;
  264. int charlen;
  265. charlen = nls->char2uni(&in[i], in_len - i, &uni);
  266. if (charlen < 0) {
  267. i = charlen;
  268. goto err_ret;
  269. }
  270. *out_len -= charlen - 1;
  271. i += charlen - 1;
  272. /* FIXME: Byte order? */
  273. result[o] = uni;
  274. if (!result[o]) {
  275. i = -EILSEQ;
  276. goto err_ret;
  277. }
  278. }
  279. return 0;
  280. err_ret:
  281. printk(KERN_ERR "NTFS: Name contains a character that cannot be "
  282. "converted to Unicode.n");
  283. ntfs_free(result);
  284. *out_len = 0;
  285. *out = NULL;
  286. return i;
  287. }