OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [fs/] [ntfs/] [support.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.