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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * linux/fs/befs/linuxvfs.c
3
 *
4
 * Copyright (C) 2001 Will Dyson <will_dyson@pobox.com
5
 *
6
 */
7
 
8
#include <linux/blkdev.h>
9
#include <linux/init.h>
10
#include <linux/module.h>
11
#include <linux/slab.h>
12
#include <linux/errno.h>
13
#include <linux/fs.h>
14
#include <linux/stat.h>
15
#include <linux/string.h>
16
#include <linux/nls.h>
17
 
18
#include "befs.h"
19
#include "btree.h"
20
#include "inode.h"
21
#include "datastream.h"
22
#include "super.h"
23
#include "io.h"
24
#include "endian.h"
25
 
26
EXPORT_NO_SYMBOLS;
27
MODULE_DESCRIPTION("BeOS File System (BeFS) driver");
28
MODULE_AUTHOR("Will Dyson");
29
MODULE_LICENSE("GPL");
30
 
31
/* The units the vfs expects inode->i_blocks to be in */
32
#define VFS_BLOCK_SIZE 512
33
 
34
static int befs_readdir(struct file *, void *, filldir_t);
35
static int befs_get_block(struct inode *, long, struct buffer_head *, int);
36
static int befs_readpage(struct file *file, struct page *page);
37
static int befs_bmap(struct address_space *mapping, long block);
38
static struct dentry *befs_lookup(struct inode *, struct dentry *);
39
static void befs_read_inode(struct inode *ino);
40
static void befs_clear_inode(struct inode *ino);
41
static int befs_init_inodecache(void);
42
static void befs_destroy_inodecache(void);
43
 
44
static int befs_readlink(struct dentry *, char *, int);
45
static int befs_follow_link(struct dentry *, struct nameidata *nd);
46
 
47
static int befs_utf2nls(struct super_block *sb, const char *in, int in_len,
48
                        char **out, int *out_len);
49
static int befs_nls2utf(struct super_block *sb, const char *in, int in_len,
50
                        char **out, int *out_len);
51
 
52
static void befs_put_super(struct super_block *);
53
static struct super_block *befs_read_super(struct super_block *, void *, int);
54
static int befs_remount(struct super_block *, int *, char *);
55
static int befs_statfs(struct super_block *, struct statfs *);
56
static int parse_options(char *, befs_mount_options *);
57
 
58
static ssize_t befs_listxattr(struct dentry *dentry, char *buffer, size_t size);
59
static ssize_t befs_getxattr(struct dentry *dentry, const char *name,
60
                             void *buffer, size_t size);
61
static int befs_setxattr(struct dentry *dentry, const char *name, void *value,
62
                         size_t size, int flags);
63
static int befs_removexattr(struct dentry *dentry, const char *name);
64
 
65
/* slab cache for befs_inode_info objects */
66
static kmem_cache_t *befs_inode_cachep;
67
 
68
static const struct super_operations befs_sops = {
69
        read_inode:befs_read_inode,     /* initialize & read inode */
70
        clear_inode:befs_clear_inode,   /* uninit inode */
71
        put_super:befs_put_super,       /* uninit super */
72
        statfs:befs_statfs,     /* statfs */
73
        remount_fs:befs_remount,
74
};
75
 
76
struct file_operations befs_dir_operations = {
77
        read:generic_read_dir,
78
        readdir:befs_readdir,
79
};
80
 
81
struct inode_operations befs_dir_inode_operations = {
82
        lookup:befs_lookup,
83
};
84
 
85
struct file_operations befs_file_operations = {
86
        llseek:default_llseek,
87
        read:generic_file_read,
88
        mmap:generic_file_mmap,
89
};
90
 
91
struct inode_operations befs_file_inode_operations = {
92
};
93
 
94
struct address_space_operations befs_aops = {
95
        readpage:befs_readpage,
96
        sync_page:block_sync_page,
97
        bmap:befs_bmap,
98
};
99
 
100
static struct inode_operations befs_symlink_inode_operations = {
101
        readlink:befs_readlink,
102
        follow_link:befs_follow_link,
103
};
104
 
105
/*
106
 * Called by generic_file_read() to read a page of data
107
 *
108
 * In turn, simply calls a generic block read function and
109
 * passes it the address of befs_get_block, for mapping file
110
 * positions to disk blocks.
111
 */
112
static int
113
befs_readpage(struct file *file, struct page *page)
114
{
115
        return block_read_full_page(page, befs_get_block);
116
}
117
 
118
static int
119
befs_bmap(struct address_space *mapping, long block)
120
{
121
        return generic_block_bmap(mapping, block, befs_get_block);
122
}
123
 
124
/*
125
 * Generic function to map a file position (block) to a
126
 * disk offset (passed back in bh_result).
127
 *
128
 * Used by many higher level functions.
129
 *
130
 * Calls befs_fblock2brun() in datastream.c to do the real work.
131
 *
132
 * -WD 10-26-01
133
 */
134
 
135
static int
136
befs_get_block(struct inode *inode, long block,
137
               struct buffer_head *bh_result, int create)
138
{
139
        struct super_block *sb = inode->i_sb;
140
        befs_data_stream *ds = &BEFS_I(inode)->i_data.ds;
141
        befs_block_run run = BAD_IADDR;
142
        int res = 0;
143
        ulong disk_off;
144
 
145
        befs_debug(sb, "---> befs_get_block() for inode %lu, block %ld",
146
                   inode->i_ino, block);
147
 
148
        if (block < 0) {
149
                befs_error(sb, "befs_get_block() was asked for a block "
150
                           "number less than zero: block %ld in inode %lu",
151
                           block, inode->i_ino);
152
                return -EIO;
153
        }
154
 
155
        if (create) {
156
                befs_error(sb, "befs_get_block() was asked to write to "
157
                           "block %ld in inode %lu", block, inode->i_ino);
158
                return -EPERM;
159
        }
160
 
161
        res = befs_fblock2brun(sb, ds, block, &run);
162
        if (res != BEFS_OK) {
163
                befs_error(sb,
164
                           "<--- befs_get_block() for inode %lu, block "
165
                           "%ld ERROR", inode->i_ino, block);
166
                return -EFBIG;
167
        }
168
 
169
        disk_off = (ulong) iaddr2blockno(sb, &run);
170
 
171
        bh_result->b_dev = inode->i_dev;
172
        bh_result->b_blocknr = disk_off;
173
        bh_result->b_state |= (1UL << BH_Mapped);
174
 
175
        befs_debug(sb, "<--- befs_get_block() for inode %lu, block %ld, "
176
                   "disk address %lu", inode->i_ino, block, disk_off);
177
 
178
        return 0;
179
}
180
 
181
static struct dentry *
182
befs_lookup(struct inode *dir, struct dentry *dentry)
183
{
184
        struct inode *inode = NULL;
185
        struct super_block *sb = dir->i_sb;
186
        befs_data_stream *ds = &BEFS_I(dir)->i_data.ds;
187
        befs_off_t offset;
188
        int ret;
189
        int utfnamelen;
190
        char *utfname;
191
        const char *name = dentry->d_name.name;
192
 
193
        befs_debug(sb, "---> befs_lookup() "
194
                   "name %s inode %ld", dentry->d_name.name, dir->i_ino);
195
 
196
        /* Convert to UTF-8 */
197
        if (BEFS_SB(sb)->nls) {
198
                ret =
199
                    befs_nls2utf(sb, name, strlen(name), &utfname, &utfnamelen);
200
                if (ret < 0) {
201
                        befs_debug(sb, "<--- befs_lookup() ERROR");
202
                        return ERR_PTR(ret);
203
                }
204
                ret = befs_btree_find(sb, ds, utfname, &offset);
205
                kfree(utfname);
206
 
207
        } else {
208
                ret = befs_btree_find(sb, ds, dentry->d_name.name, &offset);
209
        }
210
 
211
        if (ret == BEFS_BT_NOT_FOUND) {
212
                befs_debug(sb, "<--- befs_lookup() %s not found",
213
                           dentry->d_name.name);
214
                return ERR_PTR(-ENOENT);
215
 
216
        } else if (ret != BEFS_OK || offset == 0) {
217
                befs_warning(sb, "<--- befs_lookup() Error");
218
                return ERR_PTR(-ENODATA);
219
        }
220
 
221
        inode = iget(dir->i_sb, (ino_t) offset);
222
        if (!inode)
223
                return ERR_PTR(-EACCES);
224
 
225
        d_add(dentry, inode);
226
 
227
        befs_debug(sb, "<--- befs_lookup()");
228
 
229
        return NULL;
230
}
231
 
232
static int
233
befs_readdir(struct file *filp, void *dirent, filldir_t filldir)
234
{
235
        struct inode *inode = filp->f_dentry->d_inode;
236
        struct super_block *sb = inode->i_sb;
237
        befs_data_stream *ds = &BEFS_I(inode)->i_data.ds;
238
        befs_off_t value;
239
        int result;
240
        size_t keysize;
241
        unsigned char d_type;
242
        char keybuf[BEFS_NAME_LEN + 1];
243
        char *nlsname;
244
        int nlsnamelen;
245
        const char *dirname = filp->f_dentry->d_name.name;
246
 
247
        befs_debug(sb, "---> befs_readdir() "
248
                   "name %s, inode %ld, filp->f_pos %Ld",
249
                   dirname, inode->i_ino, filp->f_pos);
250
 
251
        result = befs_btree_read(sb, ds, filp->f_pos, BEFS_NAME_LEN + 1,
252
                                 keybuf, &keysize, &value);
253
 
254
        if (result == BEFS_ERR) {
255
                befs_debug(sb, "<--- befs_readdir() ERROR");
256
                befs_error(sb, "IO error reading %s (inode %lu)",
257
                           dirname, inode->i_ino);
258
                return -EIO;
259
 
260
        } else if (result == BEFS_BT_END) {
261
                befs_debug(sb, "<--- befs_readdir() END");
262
                return 0;
263
 
264
        } else if (result == BEFS_BT_EMPTY) {
265
                befs_debug(sb, "<--- befs_readdir() Empty directory");
266
                return 0;
267
        }
268
 
269
        d_type = DT_UNKNOWN;
270
 
271
        /* Convert to NLS */
272
        if (BEFS_SB(sb)->nls) {
273
                result =
274
                    befs_utf2nls(sb, keybuf, keysize, &nlsname, &nlsnamelen);
275
                if (result < 0) {
276
                        befs_debug(sb, "<--- befs_readdir() ERROR");
277
                        return result;
278
                }
279
                result = filldir(dirent, nlsname, nlsnamelen, filp->f_pos,
280
                                 (ino_t) value, d_type);
281
                kfree(nlsname);
282
 
283
        } else {
284
                result = filldir(dirent, keybuf, keysize, filp->f_pos,
285
                                 (ino_t) value, d_type);
286
        }
287
 
288
        filp->f_pos++;
289
 
290
        befs_debug(sb, "<--- befs_readdir() filp->f_pos %Ld", filp->f_pos);
291
 
292
        return 0;
293
}
294
 
295
static void
296
befs_clear_inode(struct inode *inode)
297
{
298
        befs_inode_info *b_ino = BEFS_I(inode);
299
        inode->u.generic_ip = NULL;
300
 
301
        if (b_ino) {
302
                kmem_cache_free(befs_inode_cachep, b_ino);
303
        }
304
        return;
305
}
306
 
307
static void
308
befs_read_inode(struct inode *inode)
309
{
310
        struct buffer_head *bh = NULL;
311
        befs_inode *raw_inode = NULL;
312
 
313
        struct super_block *sb = inode->i_sb;
314
        befs_sb_info *befs_sb = BEFS_SB(sb);
315
        befs_inode_info *befs_ino = NULL;
316
 
317
        befs_debug(sb, "---> befs_read_inode() " "inode = %lu", inode->i_ino);
318
 
319
        inode->u.generic_ip = kmem_cache_alloc(befs_inode_cachep, GFP_NOFS);
320
        if (inode->u.generic_ip == NULL) {
321
                befs_error(sb, "Unable to allocate memory for private "
322
                           "portion of inode %lu.", inode->i_ino);
323
                goto unaquire_none;
324
        }
325
        befs_ino = BEFS_I(inode);
326
 
327
        /* convert from vfs's inode number to befs's inode number */
328
        befs_ino->i_inode_num = blockno2iaddr(sb, inode->i_ino);
329
 
330
        befs_debug(sb, "  real inode number [%u, %hu, %hu]",
331
                   befs_ino->i_inode_num.allocation_group,
332
                   befs_ino->i_inode_num.start, befs_ino->i_inode_num.len);
333
 
334
        bh = befs_bread_iaddr(sb, befs_ino->i_inode_num);
335
        if (!bh) {
336
                befs_error(sb, "unable to read inode block - "
337
                           "inode = %lu", inode->i_ino);
338
                goto unaquire_ino_info;
339
        }
340
 
341
        raw_inode = (befs_inode *) bh->b_data;
342
 
343
        befs_dump_inode(sb, raw_inode);
344
 
345
        if (befs_check_inode(sb, raw_inode, inode->i_ino) != BEFS_OK) {
346
                befs_error(sb, "Bad inode: %lu", inode->i_ino);
347
                goto unaquire_bh;
348
        }
349
 
350
        inode->i_mode = (umode_t) fs32_to_cpu(sb, raw_inode->mode);
351
 
352
        /*
353
         * set uid and gid.  But since current BeOS is single user OS, so
354
         * you can change by "uid" or "gid" options.
355
         */
356
 
357
        inode->i_uid = befs_sb->mount_opts.use_uid ?
358
            befs_sb->mount_opts.uid : (uid_t) fs32_to_cpu(sb, raw_inode->uid);
359
        inode->i_gid = befs_sb->mount_opts.use_gid ?
360
            befs_sb->mount_opts.gid : (gid_t) fs32_to_cpu(sb, raw_inode->gid);
361
 
362
        inode->i_nlink = 1;
363
 
364
        /*
365
         * BEFS's time is 64 bits, but current VFS is 32 bits...
366
         * BEFS don't have access time. Nor inode change time. VFS
367
         * doesn't have creation time.
368
         */
369
 
370
        inode->i_mtime =
371
            (time_t) (fs64_to_cpu(sb, raw_inode->last_modified_time) >> 16);
372
        inode->i_ctime = inode->i_mtime;
373
        inode->i_atime = inode->i_mtime;
374
        inode->i_blkbits = befs_sb->block_shift;
375
        inode->i_blksize = befs_sb->block_size;
376
 
377
        befs_ino->i_inode_num = fsrun_to_cpu(sb, raw_inode->inode_num);
378
        befs_ino->i_parent = fsrun_to_cpu(sb, raw_inode->parent);
379
        befs_ino->i_attribute = fsrun_to_cpu(sb, raw_inode->attributes);
380
        befs_ino->i_flags = fs32_to_cpu(sb, raw_inode->flags);
381
 
382
        if (S_ISLNK(inode->i_mode) && !(inode->i_flags & BEFS_LONG_SYMLINK)) {
383
                inode->i_size = 0;
384
                inode->i_blocks = befs_sb->block_size / VFS_BLOCK_SIZE;
385
                strncpy(befs_ino->i_data.symlink, raw_inode->data.symlink,
386
                        BEFS_SYMLINK_LEN);
387
        } else {
388
                int num_blks;
389
 
390
                befs_ino->i_data.ds =
391
                    fsds_to_cpu(sb, raw_inode->data.datastream);
392
 
393
                num_blks = befs_count_blocks(sb, &befs_ino->i_data.ds);
394
                inode->i_blocks =
395
                    num_blks * (befs_sb->block_size / VFS_BLOCK_SIZE);
396
                inode->i_size = befs_ino->i_data.ds.size;
397
        }
398
 
399
        inode->i_mapping->a_ops = &befs_aops;
400
 
401
        if (S_ISREG(inode->i_mode)) {
402
                inode->i_fop = &befs_file_operations;
403
                inode->i_op = &befs_file_inode_operations;
404
        } else if (S_ISDIR(inode->i_mode)) {
405
                inode->i_op = &befs_dir_inode_operations;
406
                inode->i_fop = &befs_dir_operations;
407
        } else if (S_ISLNK(inode->i_mode)) {
408
                inode->i_op = &befs_symlink_inode_operations;
409
        } else {
410
                befs_error(sb, "Inode %lu is not a regular file, "
411
                           "directory or symlink. THAT IS WRONG! BeFS has no "
412
                           "on disk special files", inode->i_ino);
413
                goto unaquire_bh;
414
        }
415
 
416
        brelse(bh);
417
        befs_debug(sb, "<--- befs_read_inode()");
418
        return;
419
 
420
      unaquire_bh:
421
        brelse(bh);
422
 
423
      unaquire_ino_info:
424
        kmem_cache_free(befs_inode_cachep, inode->u.generic_ip);
425
 
426
      unaquire_none:
427
        make_bad_inode(inode);
428
        inode->u.generic_ip = NULL;
429
        befs_debug(sb, "<--- befs_read_inode() - Bad inode");
430
        return;
431
}
432
 
433
/* Initialize the inode cache. Called at fs setup.
434
 *
435
 * Taken from NFS implementation by Al Viro.
436
 */
437
static int
438
befs_init_inodecache(void)
439
{
440
        befs_inode_cachep = kmem_cache_create("befs_inode_cache",
441
                                              sizeof (struct befs_inode_info),
442
                                              0, SLAB_HWCACHE_ALIGN,
443
                                              NULL, NULL);
444
        if (befs_inode_cachep == NULL) {
445
                printk(KERN_ERR "befs_init_inodecache: "
446
                       "Couldn't initalize inode slabcache\n");
447
                return -ENOMEM;
448
        }
449
 
450
        return 0;
451
}
452
 
453
/* Called at fs teardown.
454
 *
455
 * Taken from NFS implementation by Al Viro.
456
 */
457
static void
458
befs_destroy_inodecache(void)
459
{
460
        if (kmem_cache_destroy(befs_inode_cachep))
461
                printk(KERN_ERR "befs_destroy_inodecache: "
462
                       "not all structures were freed\n");
463
}
464
 
465
/*
466
 * The inode of symbolic link is different to data stream.
467
 * The data stream become link name. Unless the LONG_SYMLINK
468
 * flag is set.
469
 */
470
static int
471
befs_follow_link(struct dentry *dentry, struct nameidata *nd)
472
{
473
        struct super_block *sb = dentry->d_sb;
474
        befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
475
        char *link;
476
        int res;
477
 
478
        if (befs_ino->i_flags & BEFS_LONG_SYMLINK) {
479
                befs_data_stream *data = &befs_ino->i_data.ds;
480
                befs_off_t linklen = data->size;
481
 
482
                befs_debug(sb, "Follow long symlink");
483
 
484
                link = kmalloc(linklen, GFP_NOFS);
485
                if (link == NULL)
486
                        return -ENOMEM;
487
 
488
                if (befs_read_lsymlink(sb, data, link, linklen) != linklen) {
489
                        kfree(link);
490
                        befs_error(sb, "Failed to read entire long symlink");
491
                        return -EIO;
492
                }
493
 
494
                res = vfs_follow_link(nd, link);
495
 
496
                kfree(link);
497
        } else {
498
                link = befs_ino->i_data.symlink;
499
                res = vfs_follow_link(nd, link);
500
        }
501
 
502
        return res;
503
}
504
 
505
static int
506
befs_readlink(struct dentry *dentry, char *buffer, int buflen)
507
{
508
        struct super_block *sb = dentry->d_sb;
509
        befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
510
        char *link;
511
        int res;
512
 
513
        if (befs_ino->i_flags & BEFS_LONG_SYMLINK) {
514
                befs_data_stream *data = &befs_ino->i_data.ds;
515
                befs_off_t linklen = data->size;
516
 
517
                befs_debug(sb, "Read long symlink");
518
 
519
                link = kmalloc(linklen, GFP_NOFS);
520
                if (link == NULL)
521
                        return -ENOMEM;
522
 
523
                if (befs_read_lsymlink(sb, data, link, linklen) != linklen) {
524
                        kfree(link);
525
                        befs_error(sb, "Failed to read entire long symlink");
526
                        return -EIO;
527
                }
528
 
529
                res = vfs_readlink(dentry, buffer, buflen, link);
530
 
531
                kfree(link);
532
        } else {
533
                link = befs_ino->i_data.symlink;
534
                res = vfs_readlink(dentry, buffer, buflen, link);
535
        }
536
 
537
        return res;
538
}
539
 
540
/*
541
 * UTF-8 to NLS charset  convert routine
542
 *
543
 * Changed 8/10/01 by Will Dyson. Now use uni2char() / char2uni() rather than
544
 * the nls tables directly
545
 */
546
 
547
static int
548
befs_utf2nls(struct super_block *sb, const char *in,
549
             int in_len, char **out, int *out_len)
550
{
551
        struct nls_table *nls = BEFS_SB(sb)->nls;
552
        int i, o;
553
        wchar_t uni;
554
        int unilen, utflen;
555
        char *result;
556
        int maxlen = in_len;    /* The utf8->nls conversion cant make more chars */
557
 
558
        befs_debug(sb, "---> utf2nls()");
559
 
560
        if (!nls) {
561
                befs_error(sb, "befs_utf2nls called with no NLS table loaded");
562
                return -EINVAL;
563
        }
564
 
565
        *out = result = kmalloc(maxlen, GFP_NOFS);
566
        if (!*out) {
567
                befs_error(sb, "befs_utf2nls() cannot allocate memory");
568
                *out_len = 0;
569
                return -ENOMEM;
570
        }
571
 
572
        for (i = o = 0; i < in_len; i += utflen, o += unilen) {
573
 
574
                /* convert from UTF-8 to Unicode */
575
                utflen = utf8_mbtowc(&uni, &in[i], in_len - i);
576
                if (utflen < 0) {
577
                        goto conv_err;
578
                }
579
 
580
                /* convert from Unicode to nls */
581
                unilen = nls->uni2char(uni, &result[o], 1);
582
                if (unilen < 0) {
583
                        goto conv_err;
584
                }
585
        }
586
        result[o] = '\0';
587
 
588
        befs_debug(sb, "<--- utf2nls()");
589
 
590
        return o;
591
        *out_len = o;
592
 
593
      conv_err:
594
        befs_error(sb, "Name using charecter set %s contains a charecter that "
595
                   "cannot be converted to unicode.", nls->charset);
596
        befs_debug(sb, "<--- utf2nls()");
597
        kfree(result);
598
        return -EILSEQ;
599
}
600
 
601
/**
602
 * befs_nls2utf - Convert NLS string to utf8 encodeing
603
 * @sb: Superblock
604
 * @src: Input string buffer in NLS format
605
 * @srclen: Length of input string in bytes
606
 * @dest: The output string in UTF8 format
607
 * @destlen: Length of the output buffer
608
 *
609
 * Converts input string @src, which is in the format of the loaded NLS map,
610
 * into a utf8 string.
611
 *
612
 * The destination string @dest is allocated by this function and the caller is
613
 * responsible for freeing it with kfree()
614
 *
615
 * On return, *@destlen is the length of @dest in bytes.
616
 *
617
 * On success, the return value is the number of utf8 charecters written to
618
 * the ouput buffer @dest.
619
 *
620
 * On Failure, a negative number coresponding to the error code is returned.
621
 */
622
 
623
static int
624
befs_nls2utf(struct super_block *sb, const char *in,
625
             int in_len, char **out, int *out_len)
626
{
627
        struct nls_table *nls = BEFS_SB(sb)->nls;
628
        int i, o;
629
        wchar_t uni;
630
        int unilen, utflen;
631
        char *result;
632
        int maxlen = 3 * in_len;
633
 
634
        befs_debug(sb, "---> nls2utf()\n");
635
 
636
        if (!nls) {
637
                befs_error(sb, "befs_nls2utf called with no NLS table loaded.");
638
                return -EINVAL;
639
        }
640
 
641
        *out = result = kmalloc(maxlen, GFP_NOFS);
642
        if (!*out) {
643
                befs_error(sb, "befs_nls2utf() cannot allocate memory");
644
                *out_len = 0;
645
                return -ENOMEM;
646
        }
647
 
648
        for (i = o = 0; i < in_len; i += unilen, o += utflen) {
649
 
650
                /* convert from nls to unicode */
651
                unilen = nls->char2uni(&in[i], in_len - i, &uni);
652
                if (unilen < 0) {
653
                        goto conv_err;
654
                }
655
 
656
                /* convert from unicode to UTF-8 */
657
                utflen = utf8_wctomb(&result[o], uni, 3);
658
                if (utflen <= 0) {
659
                        goto conv_err;
660
                }
661
        }
662
 
663
        result[o] = '\0';
664
        *out_len = o;
665
 
666
        befs_debug(sb, "<--- nls2utf()");
667
 
668
        return i;
669
 
670
      conv_err:
671
        befs_error(sb, "Name using charecter set %s contains a charecter that "
672
                   "cannot be converted to unicode.", nls->charset);
673
        befs_debug(sb, "<--- nls2utf()");
674
        kfree(result);
675
        return -EILSEQ;
676
}
677
 
678
/****Xattr****/
679
 
680
static ssize_t
681
befs_listxattr(struct dentry *dentry, char *buffer, size_t size)
682
{
683
        printk(KERN_ERR "befs_listxattr called\n");
684
        return 0;
685
}
686
 
687
static ssize_t
688
befs_getxattr(struct dentry *dentry, const char *name,
689
              void *buffer, size_t size)
690
{
691
        return 0;
692
}
693
 
694
static int
695
befs_setxattr(struct dentry *dentry, const char *name,
696
              void *value, size_t size, int flags)
697
{
698
        return 0;
699
}
700
 
701
static int
702
befs_removexattr(struct dentry *dentry, const char *name)
703
{
704
        return 0;
705
}
706
 
707
/****Superblock****/
708
 
709
static int
710
parse_options(char *options, befs_mount_options * opts)
711
{
712
        char *this_char;
713
        char *value;
714
        int ret = 1;
715
 
716
        /* Initialize options */
717
        opts->uid = 0;
718
        opts->gid = 0;
719
        opts->use_uid = 0;
720
        opts->use_gid = 0;
721
        opts->iocharset = NULL;
722
        opts->debug = 0;
723
 
724
        if (!options)
725
                return ret;
726
 
727
        for (this_char = strtok(options, ","); this_char != NULL;
728
             this_char = strtok(NULL, ",")) {
729
 
730
                if ((value = strchr(this_char, '=')) != NULL)
731
                        *value++ = 0;
732
 
733
                if (!strcmp(this_char, "uid")) {
734
                        if (!value || !*value) {
735
                                ret = 0;
736
                        } else {
737
                                opts->uid = simple_strtoul(value, &value, 0);
738
                                opts->use_uid = 1;
739
                                if (*value) {
740
                                        printk(KERN_ERR "BEFS: Invalid uid "
741
                                               "option: %s\n", value);
742
                                        ret = 0;
743
                                }
744
                        }
745
                } else if (!strcmp(this_char, "gid")) {
746
                        if (!value || !*value)
747
                                ret = 0;
748
                        else {
749
                                opts->gid = simple_strtoul(value, &value, 0);
750
                                opts->use_gid = 1;
751
                                if (*value) {
752
                                        printk(KERN_ERR
753
                                               "BEFS: Invalid gid option: "
754
                                               "%s\n", value);
755
                                        ret = 0;
756
                                }
757
                        }
758
                } else if (!strcmp(this_char, "iocharset") && value) {
759
                        char *p = value;
760
                        int len;
761
 
762
                        while (*value && *value != ',')
763
                                value++;
764
                        len = value - p;
765
                        if (len) {
766
                                char *buffer = kmalloc(len + 1, GFP_NOFS);
767
                                if (buffer) {
768
                                        opts->iocharset = buffer;
769
                                        memcpy(buffer, p, len);
770
                                        buffer[len] = 0;
771
 
772
                                } else {
773
                                        printk(KERN_ERR "BEFS: "
774
                                               "cannot allocate memory\n");
775
                                        ret = 0;
776
                                }
777
                        }
778
                } else if (!strcmp(this_char, "debug")) {
779
                        opts->debug = 1;
780
                }
781
        }
782
 
783
        return ret;
784
}
785
 
786
/* This function has the responsibiltiy of getting the
787
 * filesystem ready for unmounting.
788
 * Basicly, we free everything that we allocated in
789
 * befs_read_inode
790
 */
791
static void
792
befs_put_super(struct super_block *sb)
793
{
794
        if (BEFS_SB(sb)->mount_opts.iocharset) {
795
                kfree(BEFS_SB(sb)->mount_opts.iocharset);
796
                BEFS_SB(sb)->mount_opts.iocharset = NULL;
797
        }
798
 
799
        if (BEFS_SB(sb)->nls) {
800
                unload_nls(BEFS_SB(sb)->nls);
801
                BEFS_SB(sb)->nls = NULL;
802
        }
803
 
804
        if (sb->u.generic_sbp) {
805
                kfree(sb->u.generic_sbp);
806
                sb->u.generic_sbp = NULL;
807
        }
808
        return;
809
}
810
 
811
/* Allocate private field of the superblock, fill it.
812
 *
813
 * Finish filling the public superblock fields
814
 * Make the root directory
815
 * Load a set of NLS translations if needed.
816
 */
817
static struct super_block *
818
befs_read_super(struct super_block *sb, void *data, int silent)
819
{
820
        struct buffer_head *bh;
821
        befs_sb_info *befs_sb;
822
        befs_super_block *disk_sb;
823
        int blocksize;
824
 
825
        const unsigned long sb_block = 0;
826
        const off_t x86_sb_off = 512;
827
 
828
        sb->u.generic_sbp = kmalloc(sizeof (struct befs_sb_info), GFP_NOFS);
829
        if (sb->u.generic_sbp == NULL) {
830
                printk(KERN_ERR
831
                       "BeFS(%s): Unable to allocate memory for private "
832
                       "portion of superblock. Bailing.\n",
833
                       kdevname(sb->s_dev));
834
                goto unaquire_none;
835
        }
836
        befs_sb = BEFS_SB(sb);
837
 
838
        if (!parse_options((char *) data, &befs_sb->mount_opts)) {
839
                befs_error(sb, "cannot parse mount options");
840
                goto unaquire_priv_sbp;
841
        }
842
 
843
        befs_debug(sb, "---> befs_read_super()");
844
 
845
#ifndef CONFIG_BEFS_RW
846
        if (!(sb->s_flags & MS_RDONLY)) {
847
                befs_warning(sb,
848
                             "No write support. Marking filesystem read-only");
849
                sb->s_flags |= MS_RDONLY;
850
        }
851
#endif                          /* CONFIG_BEFS_RW */
852
 
853
        /*
854
         * Set dummy blocksize to read super block.
855
         * Will be set to real fs blocksize later.
856
         *
857
         * Linux 2.4.10 and later refuse to read blocks smaller than
858
         * the hardsect size for the device. But we also need to read at
859
         * least 1k to get the second 512 bytes of the volume.
860
         * -WD 10-26-01
861
         */
862
        blocksize = max_t(int, get_hardsect_size(sb->s_dev), 1024);
863
        set_blocksize(sb->s_dev, blocksize);
864
 
865
        if (!(bh = bread(sb->s_dev, sb_block, blocksize))) {
866
                befs_error(sb, "unable to read superblock");
867
                goto unaquire_priv_sbp;
868
        }
869
 
870
        /* account for offset of super block on x86 */
871
        disk_sb = (befs_super_block *) bh->b_data;
872
        if ((le32_to_cpu(disk_sb->magic1) == BEFS_SUPER_MAGIC1) ||
873
            (be32_to_cpu(disk_sb->magic1) == BEFS_SUPER_MAGIC1)) {
874
                befs_debug(sb, "Using PPC superblock location");
875
        } else {
876
                befs_debug(sb, "Using x86 superblock location");
877
                disk_sb =
878
                    (befs_super_block *) ((void *) bh->b_data + x86_sb_off);
879
        }
880
 
881
        if (befs_load_sb(sb, disk_sb) != BEFS_OK)
882
                goto unaquire_bh;
883
 
884
        befs_dump_super_block(sb, disk_sb);
885
 
886
        brelse(bh);
887
 
888
        if (befs_check_sb(sb) != BEFS_OK)
889
                goto unaquire_priv_sbp;
890
 
891
        /*
892
         * set up enough so that it can read an inode
893
         * Fill in kernel superblock fields from private sb
894
         */
895
        sb->s_magic = BEFS_SUPER_MAGIC;
896
        sb->s_blocksize = (ulong) befs_sb->block_size;
897
        sb->s_blocksize_bits = (unsigned char) befs_sb->block_shift;
898
        sb->s_op = (struct super_operations *) &befs_sops;
899
        sb->s_root =
900
            d_alloc_root(iget(sb, iaddr2blockno(sb, &(befs_sb->root_dir))));
901
        if (!sb->s_root) {
902
                befs_error(sb, "get root inode failed");
903
                goto unaquire_priv_sbp;
904
        }
905
 
906
        /* load nls library */
907
        if (befs_sb->mount_opts.iocharset) {
908
                befs_debug(sb, "Loading nls: %s",
909
                           befs_sb->mount_opts.iocharset);
910
                befs_sb->nls = load_nls(befs_sb->mount_opts.iocharset);
911
                if (!befs_sb->nls) {
912
                        befs_warning(sb, "Cannot load nls %s"
913
                                     "loding default nls",
914
                                     befs_sb->mount_opts.iocharset);
915
                        befs_sb->nls = load_nls_default();
916
                }
917
        }
918
 
919
        /* Set real blocksize of fs */
920
        set_blocksize(sb->s_dev, (int) befs_sb->block_size);
921
 
922
        return sb;
923
/*****************/
924
      unaquire_bh:
925
        brelse(bh);
926
 
927
      unaquire_priv_sbp:
928
        kfree(sb->u.generic_sbp);
929
 
930
      unaquire_none:
931
        sb->s_dev = 0;
932
        sb->u.generic_sbp = NULL;
933
        return NULL;
934
}
935
 
936
static int
937
befs_remount(struct super_block *sb, int *flags, char *data)
938
{
939
        if (!(*flags & MS_RDONLY))
940
                return -EINVAL;
941
        return 0;
942
}
943
 
944
static int
945
befs_statfs(struct super_block *sb, struct statfs *buf)
946
{
947
 
948
        befs_debug(sb, "---> befs_statfs()");
949
 
950
        buf->f_type = BEFS_SUPER_MAGIC;
951
        buf->f_bsize = sb->s_blocksize;
952
        buf->f_blocks = BEFS_SB(sb)->num_blocks;
953
        buf->f_bfree = BEFS_SB(sb)->num_blocks - BEFS_SB(sb)->used_blocks;
954
        buf->f_bavail = buf->f_bfree;
955
        buf->f_files = 0;        /* UNKNOWN */
956
        buf->f_ffree = 0;        /* UNKNOWN */
957
        buf->f_namelen = BEFS_NAME_LEN;
958
 
959
        befs_debug(sb, "<--- befs_statfs()");
960
 
961
        return 0;
962
}
963
 
964
/*
965
        Makes a variable of type file_system_type,
966
        named befs_fs_tipe, identified by the "befs" string,
967
        and containing a reference to the befs_read_super function
968
 
969
        Macro declared in <linux/fs.h>
970
*/
971
static DECLARE_FSTYPE_DEV(befs_fs_type, "befs", befs_read_super);
972
 
973
static int __init
974
init_befs_fs(void)
975
{
976
        int err;
977
 
978
        printk(KERN_INFO "BeFS version: %s\n", BEFS_VERSION);
979
 
980
        err = befs_init_inodecache();
981
        if (err)
982
                return err;
983
 
984
        return register_filesystem(&befs_fs_type);
985
}
986
 
987
static void __exit
988
exit_befs_fs(void)
989
{
990
        befs_destroy_inodecache();
991
 
992
        unregister_filesystem(&befs_fs_type);
993
}
994
 
995
/*
996
Macros that typecheck the init and exit functions,
997
ensures that they are called at init and cleanup,
998
and eliminates warnings about unused functions.
999
*/
1000
module_init(init_befs_fs)
1001
    module_exit(exit_befs_fs)

powered by: WebSVN 2.1.0

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