--- zzzz-none-000/linux-2.4.17/fs/ntfs/support.c 2001-12-21 17:42:03.000000000 +0000 +++ sangam-fb-322/linux-2.4.17/fs/ntfs/support.c 2004-11-24 13:22:16.000000000 +0000 @@ -1,316 +1,316 @@ -/* - * support.c - Specific support functions - * - * Copyright (C) 1997 Martin von Löwis - * Copyright (C) 1997 Régis Duchesne - * Copyright (C) 2001 Anton Altaparmakov (AIA) - */ - -#include "ntfstypes.h" -#include "struct.h" -#include "support.h" - -#include -#include -#include -#include -#include "util.h" -#include "inode.h" -#include "macros.h" -#include - -static char print_buf[1024]; - -#ifdef DEBUG -#include "sysctl.h" -#include - -/* Debugging output */ -void ntfs_debug(int mask, const char *fmt, ...) -{ - va_list ap; - - /* Filter it with the debugging level required */ - if (ntdebug & mask) { - va_start(ap,fmt); - strcpy(print_buf, KERN_DEBUG "NTFS: "); - vsprintf(print_buf + 9, fmt, ap); - printk(print_buf); - va_end(ap); - } -} - -#ifndef ntfs_malloc -/* Verbose kmalloc */ -void *ntfs_malloc(int size) -{ - void *ret; - - ret = kmalloc(size, GFP_KERNEL); - ntfs_debug(DEBUG_MALLOC, "Allocating %x at %p\n", size, ret); - - return ret; -} -#endif - -#ifndef ntfs_free -/* Verbose kfree() */ -void ntfs_free(void *block) -{ - ntfs_debug(DEBUG_MALLOC, "Freeing memory at %p\n", block); - kfree(block); -} -#endif -#else /* End of DEBUG functions. Normal ones below... */ - -#ifndef ntfs_malloc -void *ntfs_malloc(int size) -{ - return kmalloc(size, GFP_KERNEL); -} -#endif - -#ifndef ntfs_free -void ntfs_free(void *block) -{ - kfree(block); -} -#endif -#endif /* DEBUG */ - -void ntfs_bzero(void *s, int n) -{ - memset(s, 0, n); -} - -/* These functions deliberately return no value. It is dest, anyway, - and not used anywhere in the NTFS code. */ - -void ntfs_memcpy(void *dest, const void *src, ntfs_size_t n) -{ - memcpy(dest, src, n); -} - -void ntfs_memmove(void *dest, const void *src, ntfs_size_t n) -{ - memmove(dest, src, n); -} - -/* Warn that an error occurred. */ -void ntfs_error(const char *fmt,...) -{ - va_list ap; - - va_start(ap, fmt); - strcpy(print_buf, KERN_ERR "NTFS: "); - vsprintf(print_buf + 9, fmt, ap); - printk(print_buf); - va_end(ap); -} - -int ntfs_read_mft_record(ntfs_volume *vol, int mftno, char *buf) -{ - int error; - ntfs_io io; - - ntfs_debug(DEBUG_OTHER, "read_mft_record 0x%x\n", mftno); - if (mftno == FILE_Mft) - { - ntfs_memcpy(buf, vol->mft, vol->mft_record_size); - return 0; - } - if (!vol->mft_ino) - { - printk(KERN_ERR "NTFS: mft_ino is NULL. Something is terribly " - "wrong here!\n"); - return -ENODATA; - } - io.fn_put = ntfs_put; - io.fn_get = 0; - io.param = buf; - io.size = vol->mft_record_size; - ntfs_debug(DEBUG_OTHER, "read_mft_record: calling ntfs_read_attr with: " - "mftno = 0x%x, vol->mft_record_size_bits = 0x%x, " - "mftno << vol->mft_record_size_bits = 0x%Lx\n", mftno, - vol->mft_record_size_bits, - (__s64)mftno << vol->mft_record_size_bits); - error = ntfs_read_attr(vol->mft_ino, vol->at_data, NULL, - (__s64)mftno << vol->mft_record_size_bits, &io); - if (error || (io.size != vol->mft_record_size)) { - ntfs_debug(DEBUG_OTHER, "read_mft_record: read 0x%x failed " - "(%d,%d,%d)\n", mftno, error, io.size, - vol->mft_record_size); - return error ? error : -ENODATA; - } - ntfs_debug(DEBUG_OTHER, "read_mft_record: finished read 0x%x\n", mftno); - if (!ntfs_check_mft_record(vol, buf)) { - /* FIXME: This is incomplete behaviour. We might be able to - * recover at this stage. ntfs_check_mft_record() is too - * conservative at aborting it's operations. It is OK for - * now as we just can't handle some on disk structures - * this way. (AIA) */ - printk(KERN_WARNING "NTFS: Invalid MFT record for 0x%x\n", mftno); - return -EIO; - } - ntfs_debug(DEBUG_OTHER, "read_mft_record: Done 0x%x\n", mftno); - return 0; -} - -int ntfs_getput_clusters(ntfs_volume *vol, int cluster, ntfs_size_t start_offs, - ntfs_io *buf) -{ - struct super_block *sb = NTFS_SB(vol); - struct buffer_head *bh; - int length = buf->size; - int error = 0; - ntfs_size_t to_copy; - - ntfs_debug(DEBUG_OTHER, "%s_clusters %d %d %d\n", - buf->do_read ? "get" : "put", cluster, start_offs, length); - to_copy = vol->cluster_size - start_offs; - while (length) { - if (!(bh = bread(sb->s_dev, cluster, vol->cluster_size))) { - ntfs_debug(DEBUG_OTHER, "%s failed\n", - buf->do_read ? "Reading" : "Writing"); - error = -EIO; - goto error_ret; - } - if (to_copy > length) - to_copy = length; - lock_buffer(bh); - if (buf->do_read) { - buf->fn_put(buf, bh->b_data + start_offs, to_copy); - unlock_buffer(bh); - } else { - buf->fn_get(bh->b_data + start_offs, buf, to_copy); - mark_buffer_dirty(bh); - unlock_buffer(bh); - /* - * Note: We treat synchronous IO on a per volume basis - * disregarding flags of individual inodes. This can - * lead to some strange write ordering effects upon a - * remount with a change in the sync flag but it should - * not break anything. [Except if the system crashes - * at that point in time but there would be more thigs - * to worry about than that in that case...]. (AIA) - */ - if (sb->s_flags & MS_SYNCHRONOUS) { - ll_rw_block(WRITE, 1, &bh); - wait_on_buffer(bh); - if (buffer_req(bh) && !buffer_uptodate(bh)) { - printk(KERN_ERR "IO error syncing NTFS " - "cluster [%s:%i]\n", - bdevname(sb->s_dev), cluster); - brelse(bh); - error = -EIO; - goto error_ret; - } - } - } - brelse(bh); - length -= to_copy; - start_offs = 0; - to_copy = vol->cluster_size; - cluster++; - } -error_ret: - return error; -} - -ntfs_time64_t ntfs_now(void) -{ - return ntfs_unixutc2ntutc(CURRENT_TIME); -} - -int ntfs_dupuni2map(ntfs_volume *vol, ntfs_u16 *in, int in_len, char **out, - int *out_len) -{ - int i, o, chl, chi; - char *result, *buf, charbuf[NLS_MAX_CHARSET_SIZE]; - struct nls_table *nls = vol->nls_map; - - result = ntfs_malloc(in_len + 1); - if (!result) - return -ENOMEM; - *out_len = in_len; - for (i = o = 0; i < in_len; i++) { - /* FIXME: Byte order? */ - wchar_t uni = in[i]; - if ((chl = nls->uni2char(uni, charbuf, - NLS_MAX_CHARSET_SIZE)) > 0) { - /* Adjust result buffer. */ - if (chl > 1) { - buf = ntfs_malloc(*out_len + chl - 1); - if (!buf) { - i = -ENOMEM; - goto err_ret; - } - memcpy(buf, result, o); - ntfs_free(result); - result = buf; - *out_len += (chl - 1); - } - for (chi = 0; chi < chl; chi++) - result[o++] = charbuf[chi]; - } else { - /* Invalid character. */ - printk(KERN_ERR "NTFS: Unicode name contains a " - "character that cannot be converted " - "to chosen character set. Remount " - "with utf8 encoding and this should " - "work.\n"); - i = -EILSEQ; - goto err_ret; - } - } - result[*out_len] = '\0'; - *out = result; - return 0; -err_ret: - ntfs_free(result); - *out_len = 0; - *out = NULL; - return i; -} - -int ntfs_dupmap2uni(ntfs_volume *vol, char* in, int in_len, ntfs_u16 **out, - int *out_len) -{ - int i, o; - ntfs_u16 *result; - struct nls_table *nls = vol->nls_map; - - *out = result = ntfs_malloc(2 * in_len); - if (!result) { - *out_len = 0; - return -ENOMEM; - } - *out_len = in_len; - for (i = o = 0; i < in_len; i++, o++) { - wchar_t uni; - int charlen; - - charlen = nls->char2uni(&in[i], in_len - i, &uni); - if (charlen < 0) { - i = charlen; - goto err_ret; - } - *out_len -= charlen - 1; - i += charlen - 1; - /* FIXME: Byte order? */ - result[o] = uni; - if (!result[o]) { - i = -EILSEQ; - goto err_ret; - } - } - return 0; -err_ret: - printk(KERN_ERR "NTFS: Name contains a character that cannot be " - "converted to Unicode.\n"); - ntfs_free(result); - *out_len = 0; - *out = NULL; - return i; -} - +/* + * support.c - Specific support functions + * + * Copyright (C) 1997 Martin von Löwis + * Copyright (C) 1997 Régis Duchesne + * Copyright (C) 2001 Anton Altaparmakov (AIA) + */ + +#include "ntfstypes.h" +#include "struct.h" +#include "support.h" + +#include +#include +#include +#include +#include "util.h" +#include "inode.h" +#include "macros.h" +#include + +static char print_buf[1024]; + +#ifdef DEBUG +#include "sysctl.h" +#include + +/* Debugging output */ +void ntfs_debug(int mask, const char *fmt, ...) +{ + va_list ap; + + /* Filter it with the debugging level required */ + if (ntdebug & mask) { + va_start(ap,fmt); + strcpy(print_buf, KERN_DEBUG "NTFS: "); + vsprintf(print_buf + 9, fmt, ap); + printk(print_buf); + va_end(ap); + } +} + +#ifndef ntfs_malloc +/* Verbose kmalloc */ +void *ntfs_malloc(int size) +{ + void *ret; + + ret = kmalloc(size, GFP_KERNEL); + ntfs_debug(DEBUG_MALLOC, "Allocating %x at %p\n", size, ret); + + return ret; +} +#endif + +#ifndef ntfs_free +/* Verbose kfree() */ +void ntfs_free(void *block) +{ + ntfs_debug(DEBUG_MALLOC, "Freeing memory at %p\n", block); + kfree(block); +} +#endif +#else /* End of DEBUG functions. Normal ones below... */ + +#ifndef ntfs_malloc +void *ntfs_malloc(int size) +{ + return kmalloc(size, GFP_KERNEL); +} +#endif + +#ifndef ntfs_free +void ntfs_free(void *block) +{ + kfree(block); +} +#endif +#endif /* DEBUG */ + +void ntfs_bzero(void *s, int n) +{ + memset(s, 0, n); +} + +/* These functions deliberately return no value. It is dest, anyway, + and not used anywhere in the NTFS code. */ + +void ntfs_memcpy(void *dest, const void *src, ntfs_size_t n) +{ + memcpy(dest, src, n); +} + +void ntfs_memmove(void *dest, const void *src, ntfs_size_t n) +{ + memmove(dest, src, n); +} + +/* Warn that an error occurred. */ +void ntfs_error(const char *fmt,...) +{ + va_list ap; + + va_start(ap, fmt); + strcpy(print_buf, KERN_ERR "NTFS: "); + vsprintf(print_buf + 9, fmt, ap); + printk(print_buf); + va_end(ap); +} + +int ntfs_read_mft_record(ntfs_volume *vol, int mftno, char *buf) +{ + int error; + ntfs_io io; + + ntfs_debug(DEBUG_OTHER, "read_mft_record 0x%x\n", mftno); + if (mftno == FILE_Mft) + { + ntfs_memcpy(buf, vol->mft, vol->mft_record_size); + return 0; + } + if (!vol->mft_ino) + { + printk(KERN_ERR "NTFS: mft_ino is NULL. Something is terribly " + "wrong here!\n"); + return -ENODATA; + } + io.fn_put = ntfs_put; + io.fn_get = 0; + io.param = buf; + io.size = vol->mft_record_size; + ntfs_debug(DEBUG_OTHER, "read_mft_record: calling ntfs_read_attr with: " + "mftno = 0x%x, vol->mft_record_size_bits = 0x%x, " + "mftno << vol->mft_record_size_bits = 0x%Lx\n", mftno, + vol->mft_record_size_bits, + (__s64)mftno << vol->mft_record_size_bits); + error = ntfs_read_attr(vol->mft_ino, vol->at_data, NULL, + (__s64)mftno << vol->mft_record_size_bits, &io); + if (error || (io.size != vol->mft_record_size)) { + ntfs_debug(DEBUG_OTHER, "read_mft_record: read 0x%x failed " + "(%d,%d,%d)\n", mftno, error, io.size, + vol->mft_record_size); + return error ? error : -ENODATA; + } + ntfs_debug(DEBUG_OTHER, "read_mft_record: finished read 0x%x\n", mftno); + if (!ntfs_check_mft_record(vol, buf)) { + /* FIXME: This is incomplete behaviour. We might be able to + * recover at this stage. ntfs_check_mft_record() is too + * conservative at aborting it's operations. It is OK for + * now as we just can't handle some on disk structures + * this way. (AIA) */ + printk(KERN_WARNING "NTFS: Invalid MFT record for 0x%x\n", mftno); + return -EIO; + } + ntfs_debug(DEBUG_OTHER, "read_mft_record: Done 0x%x\n", mftno); + return 0; +} + +int ntfs_getput_clusters(ntfs_volume *vol, int cluster, ntfs_size_t start_offs, + ntfs_io *buf) +{ + struct super_block *sb = NTFS_SB(vol); + struct buffer_head *bh; + int length = buf->size; + int error = 0; + ntfs_size_t to_copy; + + ntfs_debug(DEBUG_OTHER, "%s_clusters %d %d %d\n", + buf->do_read ? "get" : "put", cluster, start_offs, length); + to_copy = vol->cluster_size - start_offs; + while (length) { + if (!(bh = bread(sb->s_dev, cluster, vol->cluster_size))) { + ntfs_debug(DEBUG_OTHER, "%s failed\n", + buf->do_read ? "Reading" : "Writing"); + error = -EIO; + goto error_ret; + } + if (to_copy > length) + to_copy = length; + lock_buffer(bh); + if (buf->do_read) { + buf->fn_put(buf, bh->b_data + start_offs, to_copy); + unlock_buffer(bh); + } else { + buf->fn_get(bh->b_data + start_offs, buf, to_copy); + mark_buffer_dirty(bh); + unlock_buffer(bh); + /* + * Note: We treat synchronous IO on a per volume basis + * disregarding flags of individual inodes. This can + * lead to some strange write ordering effects upon a + * remount with a change in the sync flag but it should + * not break anything. [Except if the system crashes + * at that point in time but there would be more thigs + * to worry about than that in that case...]. (AIA) + */ + if (sb->s_flags & MS_SYNCHRONOUS) { + ll_rw_block(WRITE, 1, &bh); + wait_on_buffer(bh); + if (buffer_req(bh) && !buffer_uptodate(bh)) { + printk(KERN_ERR "IO error syncing NTFS " + "cluster [%s:%i]\n", + bdevname(sb->s_dev), cluster); + brelse(bh); + error = -EIO; + goto error_ret; + } + } + } + brelse(bh); + length -= to_copy; + start_offs = 0; + to_copy = vol->cluster_size; + cluster++; + } +error_ret: + return error; +} + +ntfs_time64_t ntfs_now(void) +{ + return ntfs_unixutc2ntutc(CURRENT_TIME); +} + +int ntfs_dupuni2map(ntfs_volume *vol, ntfs_u16 *in, int in_len, char **out, + int *out_len) +{ + int i, o, chl, chi; + char *result, *buf, charbuf[NLS_MAX_CHARSET_SIZE]; + struct nls_table *nls = vol->nls_map; + + result = ntfs_malloc(in_len + 1); + if (!result) + return -ENOMEM; + *out_len = in_len; + for (i = o = 0; i < in_len; i++) { + /* FIXME: Byte order? */ + wchar_t uni = in[i]; + if ((chl = nls->uni2char(uni, charbuf, + NLS_MAX_CHARSET_SIZE)) > 0) { + /* Adjust result buffer. */ + if (chl > 1) { + buf = ntfs_malloc(*out_len + chl - 1); + if (!buf) { + i = -ENOMEM; + goto err_ret; + } + memcpy(buf, result, o); + ntfs_free(result); + result = buf; + *out_len += (chl - 1); + } + for (chi = 0; chi < chl; chi++) + result[o++] = charbuf[chi]; + } else { + /* Invalid character. */ + printk(KERN_ERR "NTFS: Unicode name contains a " + "character that cannot be converted " + "to chosen character set. Remount " + "with utf8 encoding and this should " + "work.\n"); + i = -EILSEQ; + goto err_ret; + } + } + result[*out_len] = '\0'; + *out = result; + return 0; +err_ret: + ntfs_free(result); + *out_len = 0; + *out = NULL; + return i; +} + +int ntfs_dupmap2uni(ntfs_volume *vol, char* in, int in_len, ntfs_u16 **out, + int *out_len) +{ + int i, o; + ntfs_u16 *result; + struct nls_table *nls = vol->nls_map; + + *out = result = ntfs_malloc(2 * in_len); + if (!result) { + *out_len = 0; + return -ENOMEM; + } + *out_len = in_len; + for (i = o = 0; i < in_len; i++, o++) { + wchar_t uni; + int charlen; + + charlen = nls->char2uni(&in[i], in_len - i, &uni); + if (charlen < 0) { + i = charlen; + goto err_ret; + } + *out_len -= charlen - 1; + i += charlen - 1; + /* FIXME: Byte order? */ + result[o] = uni; + if (!result[o]) { + i = -EILSEQ; + goto err_ret; + } + } + return 0; +err_ret: + printk(KERN_ERR "NTFS: Name contains a character that cannot be " + "converted to Unicode.\n"); + ntfs_free(result); + *out_len = 0; + *out = NULL; + return i; +} +