The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/befs/linuxvfs.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    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)

Cache object: c4306db9e273ebf38960f81a72f2a5c9


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.