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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [fs/] [fat/] [buffer.c] - Blame information for rev 1628

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1628 jcastillo
/*
2
 * linux/fs/fat/buffer.c
3
 *
4
 *
5
 */
6
 
7
#include <linux/mm.h>
8
#include <linux/malloc.h>
9
#include <linux/string.h>
10
#include <linux/fs.h>
11
#include <linux/msdos_fs.h>
12
 
13
#if 0
14
#  define PRINTK(x) printk x
15
#else
16
#  define PRINTK(x)
17
#endif
18
 
19
struct buffer_head *fat_bread (
20
        struct super_block *sb,
21
        int block)
22
{
23
        struct buffer_head *ret = NULL;
24
 
25
        PRINTK(("fat_bread: block=0x%x\n", block));
26
        /* Note that the blocksize is 512 or 1024, but the first read
27
           is always of size 1024. Doing readahead may be counterproductive
28
           or just plain wrong. */
29
        if (sb->s_blocksize == 512) {
30
                ret = bread (sb->s_dev,block,512);
31
        } else {
32
                struct buffer_head *real = bread (sb->s_dev,block>>1,1024);
33
 
34
                if (real != NULL){
35
                        ret = (struct buffer_head *)
36
                          kmalloc (sizeof(struct buffer_head), GFP_KERNEL);
37
                        if (ret != NULL) {
38
                                /* #Specification: msdos / strategy / special device / dummy blocks
39
                                        Many special device (Scsi optical disk for one) use
40
                                        larger hardware sector size. This allows for higher
41
                                        capacity.
42
 
43
                                        Most of the time, the MsDOS file system that sit
44
                                        on this device is totally unaligned. It use logically
45
                                        512 bytes sector size, with logical sector starting
46
                                        in the middle of a hardware block. The bad news is
47
                                        that a hardware sector may hold data own by two
48
                                        different files. This means that the hardware sector
49
                                        must be read, patch and written almost all the time.
50
 
51
                                        Needless to say that it kills write performance
52
                                        on all OS.
53
 
54
                                        Internally the linux msdos fs is using 512 bytes
55
                                        logical sector. When accessing such a device, we
56
                                        allocate dummy buffer cache blocks, that we stuff
57
                                        with the information of a real one (1k large).
58
 
59
                                        This strategy is used to hide this difference to
60
                                        the core of the msdos fs. The slowdown is not
61
                                        hidden though!
62
                                */
63
                                /*
64
                                        The memset is there only to catch errors. The msdos
65
                                        fs is only using b_data
66
                                */
67
                                memset (ret,0,sizeof(*ret));
68
                                ret->b_data = real->b_data;
69
                                if (block & 1) ret->b_data += 512;
70
                                ret->b_next = real;
71
                        }else{
72
                                brelse (real);
73
                        }
74
                }
75
        }
76
        return ret;
77
}
78
struct buffer_head *fat_getblk (
79
        struct super_block *sb,
80
        int block)
81
{
82
        struct buffer_head *ret = NULL;
83
        PRINTK(("fat_getblk: block=0x%x\n", block));
84
        if (sb->s_blocksize == 512){
85
                ret = getblk (sb->s_dev,block,512);
86
        }else{
87
                /* #Specification: msdos / special device / writing
88
                        A write is always preceded by a read of the complete block
89
                        (large hardware sector size). This defeat write performance.
90
                        There is a possibility to optimize this when writing large
91
                        chunk by making sure we are filling large block. Volunteer ?
92
                */
93
                ret = fat_bread (sb,block);
94
        }
95
        return ret;
96
}
97
 
98
void fat_brelse (
99
        struct super_block *sb,
100
        struct buffer_head *bh)
101
{
102
        if (bh != NULL){
103
                if (sb->s_blocksize == 512){
104
                        brelse (bh);
105
                }else{
106
                        brelse (bh->b_next);
107
                        /* We can free the dummy because a new one is allocated at
108
                                each fat_getblk() and fat_bread().
109
                        */
110
                        kfree (bh);
111
                }
112
        }
113
}
114
 
115
void fat_mark_buffer_dirty (
116
        struct super_block *sb,
117
        struct buffer_head *bh,
118
        int dirty_val)
119
{
120
        if (sb->s_blocksize != 512){
121
                bh = bh->b_next;
122
        }
123
        mark_buffer_dirty (bh,dirty_val);
124
}
125
 
126
void fat_set_uptodate (
127
        struct super_block *sb,
128
        struct buffer_head *bh,
129
        int val)
130
{
131
        if (sb->s_blocksize != 512){
132
                bh = bh->b_next;
133
        }
134
        mark_buffer_uptodate(bh, val);
135
}
136
int fat_is_uptodate (
137
        struct super_block *sb,
138
        struct buffer_head *bh)
139
{
140
        if (sb->s_blocksize != 512){
141
                bh = bh->b_next;
142
        }
143
        return buffer_uptodate(bh);
144
}
145
 
146
void fat_ll_rw_block (
147
        struct super_block *sb,
148
        int opr,
149
        int nbreq,
150
        struct buffer_head *bh[32])
151
{
152
        if (sb->s_blocksize == 512){
153
                ll_rw_block(opr,nbreq,bh);
154
        }else{
155
                struct buffer_head *tmp[32];
156
                int i;
157
                for (i=0; i<nbreq; i++){
158
                        tmp[i] = bh[i]->b_next;
159
                }
160
                ll_rw_block(opr,nbreq,tmp);
161
        }
162
}
163
 

powered by: WebSVN 2.1.0

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