Annotation of dmsdos/src/dblspace_buffer.c, revision 1.1

1.1     ! root        1: /*
        !             2: dblspace_buffer.c 
        !             3: 
        !             4: DMSDOS CVF-FAT module: low-level buffered read-write access functions
        !             5: 
        !             6: ******************************************************************************
        !             7: DMSDOS (compressed MSDOS filesystem support) for Linux
        !             8: written 1995-1998 by Frank Gockel and Pavel Pisa
        !             9: 
        !            10:     (C) Copyright 1995-1998 by Frank Gockel
        !            11:     (C) Copyright 1996-1998 by Pavel Pisa
        !            12: 
        !            13: Some code of dmsdos has been copied from the msdos filesystem
        !            14: so there are the following additional copyrights:
        !            15: 
        !            16:     (C) Copyright 1992,1993 by Werner Almesberger (msdos filesystem)
        !            17:     (C) Copyright 1994,1995 by Jacques Gelinas (mmap code)
        !            18:     (C) Copyright 1992-1995 by Linus Torvalds
        !            19: 
        !            20: DMSDOS was inspired by the THS filesystem (a simple doublespace
        !            21: DS-0-2 compressed read-only filesystem) written 1994 by Thomas Scheuermann.
        !            22: 
        !            23: The DMSDOS code is distributed under the Gnu General Public Licence.
        !            24: See file COPYING for details.
        !            25: ******************************************************************************
        !            26: 
        !            27: */
        !            28: 
        !            29: #ifndef __KERNEL__
        !            30: #error This file needs __KERNEL__
        !            31: #endif
        !            32: 
        !            33: #include <linux/fs.h>
        !            34: #include <linux/msdos_fs.h>
        !            35: #include <linux/sched.h>
        !            36: #include <linux/kernel.h>
        !            37: #include <linux/errno.h>
        !            38: #include <linux/string.h>
        !            39: #include <linux/stat.h>
        !            40: #include <linux/mm.h>
        !            41: #include <linux/malloc.h>
        !            42: #include "dmsdos.h"
        !            43: 
        !            44: /* This is just cut'n'paste from the fat fs original :) 
        !            45:    We don't do a virtual sector translation here */
        !            46: 
        !            47: struct buffer_head *raw_bread (
        !            48:        struct super_block *sb,
        !            49:        int block)
        !            50: {
        !            51:        struct buffer_head *ret = NULL;
        !            52: 
        !            53:        /* Note that the blocksize is 512 or 1024, but the first read
        !            54:           is always of size 1024. Doing readahead may be counterproductive
        !            55:           or just plain wrong. */
        !            56:        if (sb->s_blocksize == 512) {
        !            57:                ret = bread (sb->s_dev,block,512);
        !            58:        } else {
        !            59:                struct buffer_head *real = bread (sb->s_dev,block>>1,1024);
        !            60: 
        !            61:                if (real != NULL){
        !            62:                        ret = (struct buffer_head *)
        !            63:                          kmalloc (sizeof(struct buffer_head), GFP_KERNEL);
        !            64:                        if (ret != NULL) {
        !            65:                                /* #Specification: msdos / strategy / special device / dummy blocks
        !            66:                                        Many special device (Scsi optical disk for one) use
        !            67:                                        larger hardware sector size. This allows for higher
        !            68:                                        capacity.
        !            69: 
        !            70:                                        Most of the time, the MsDOS file system that sit
        !            71:                                        on this device is totally unaligned. It use logically
        !            72:                                        512 bytes sector size, with logical sector starting
        !            73:                                        in the middle of a hardware block. The bad news is
        !            74:                                        that a hardware sector may hold data own by two
        !            75:                                        different files. This means that the hardware sector
        !            76:                                        must be read, patch and written almost all the time.
        !            77: 
        !            78:                                        Needless to say that it kills write performance
        !            79:                                        on all OS.
        !            80: 
        !            81:                                        Internally the linux msdos fs is using 512 bytes
        !            82:                                        logical sector. When accessing such a device, we
        !            83:                                        allocate dummy buffer cache blocks, that we stuff
        !            84:                                        with the information of a real one (1k large).
        !            85: 
        !            86:                                        This strategy is used to hide this difference to
        !            87:                                        the core of the msdos fs. The slowdown is not
        !            88:                                        hidden though!
        !            89:                                */
        !            90:                                /*
        !            91:                                        The memset is there only to catch errors. The msdos
        !            92:                                        fs is only using b_data
        !            93:                                */
        !            94:                                memset (ret,0,sizeof(*ret));
        !            95:                                ret->b_data = real->b_data;
        !            96:                                if (block & 1) ret->b_data += 512;
        !            97:                                ret->b_next = real;
        !            98:                        }else{
        !            99:                                brelse (real);
        !           100:                        }
        !           101:                }
        !           102:        }
        !           103:        return ret;
        !           104: }
        !           105: struct buffer_head *raw_getblk (
        !           106:        struct super_block *sb,
        !           107:        int block)
        !           108: {
        !           109:        struct buffer_head *ret = NULL;
        !           110:        if (sb->s_blocksize == 512){
        !           111:                ret = getblk (sb->s_dev,block,512);
        !           112:        }else{
        !           113:                /* #Specification: msdos / special device / writing
        !           114:                        A write is always preceded by a read of the complete block
        !           115:                        (large hardware sector size). This defeat write performance.
        !           116:                        There is a possibility to optimize this when writing large
        !           117:                        chunk by making sure we are filling large block. Volunteer ?
        !           118:                */
        !           119:                ret = raw_bread (sb,block);
        !           120:        }
        !           121:        return ret;
        !           122: }
        !           123: 
        !           124: void raw_brelse (
        !           125:        struct super_block *sb,
        !           126:        struct buffer_head *bh)
        !           127: {
        !           128:        if (bh != NULL){
        !           129:                if (sb->s_blocksize == 512){
        !           130:                        brelse (bh);
        !           131:                }else{
        !           132:                        brelse (bh->b_next);
        !           133:                        /* We can free the dummy because a new one is allocated at
        !           134:                                each fat_getblk() and fat_bread().
        !           135:                        */
        !           136:                        kfree (bh);
        !           137:                }
        !           138:        }
        !           139: }
        !           140:        
        !           141: void raw_mark_buffer_dirty (
        !           142:        struct super_block *sb,
        !           143:        struct buffer_head *bh,
        !           144:        int dirty_val)
        !           145: {
        !           146: 
        !           147: #ifdef DBL_WRITEACCESS
        !           148:        if (sb->s_blocksize != 512){
        !           149:                bh = bh->b_next;
        !           150:        }
        !           151:        mark_buffer_dirty (bh,dirty_val);
        !           152: #else
        !           153: printk(KERN_NOTICE "DMSDOS: write access not compiled in, ignored\n");
        !           154: #endif
        !           155:     
        !           156: }
        !           157: 
        !           158: void raw_set_uptodate (
        !           159:        struct super_block *sb,
        !           160:        struct buffer_head *bh,
        !           161:        int val)
        !           162: {
        !           163:        if (sb->s_blocksize != 512){
        !           164:                bh = bh->b_next;
        !           165:        }
        !           166:        mark_buffer_uptodate(bh, val);
        !           167: }
        !           168: int raw_is_uptodate (
        !           169:        struct super_block *sb,
        !           170:        struct buffer_head *bh)
        !           171: {
        !           172:        if (sb->s_blocksize != 512){
        !           173:                bh = bh->b_next;
        !           174:        }
        !           175:        return buffer_uptodate(bh);
        !           176: }
        !           177: 
        !           178: /* we really need this for read-ahead */
        !           179: void raw_ll_rw_block (
        !           180:        struct super_block *sb,
        !           181:        int opr,
        !           182:        int nbreq,
        !           183:        struct buffer_head *bh[32])
        !           184: {
        !           185:        if (sb->s_blocksize == 512){
        !           186:                ll_rw_block(opr,nbreq,bh);
        !           187:        }else{
        !           188:                struct buffer_head *tmp[32];
        !           189:                int i;
        !           190:                for (i=0; i<nbreq; i++){
        !           191:                        tmp[i] = bh[i]->b_next;
        !           192:                }
        !           193:                ll_rw_block(opr,nbreq,tmp);
        !           194:        }
        !           195: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.