source: svn/trunk/newcon3bcm2_21bu/BSEAV/lib/bfile/bfile_buffered.c @ 11

Last change on this file since 11 was 2, checked in by jglee, 11 years ago

first commit

  • Property svn:executable set to *
File size: 6.6 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2007-2010, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile: bfile_buffered.c $
11 * $brcm_Revision: 2 $
12 * $brcm_Date: 1/14/10 1:03p $
13 *
14 * Module Description:
15 *
16 * Block based cached file I/O
17 *
18 * Revision History:
19 *
20 * $brcm_Log: /BSEAV/lib/bfile/bfile_buffered.c $
21 *
22 * 2   1/14/10 1:03p vsilyaev
23 * SW3548-2711: Fixed memory overrun
24 *
25 * 1   9/18/08 3:25p vsilyaev
26 * PR 47105: Layered buffer cache that provides cached interface for any
27 * file descriptor
28 *
29 *******************************************************************************/
30
31#include "bstd.h"
32#include "bfile_buffered.h"
33#include "bkni.h"
34
35
36BDBG_MODULE(bfile_buffered);
37
38BDBG_OBJECT_ID(bfile_buffered);
39
40struct bfile_buffered_proxy {
41        struct bfile_io_read file; /* shall be the first member */
42    bfile_buffered_t parent;
43};
44
45struct bfile_buffered {
46        struct bfile_io_read file; /* shall be the first member */
47    BDBG_OBJECT(bfile_buffered)
48    bfile_io_read_t fd;
49    off_t pos;
50    bfile_buffer_t buffer;
51    bfile_buffered_cfg cfg;
52    struct bfile_buffered_proxy proxy_fd;
53    uint8_t buf[1]; /* variable size buffer */
54};
55
56
57void 
58bfile_buffered_default_cfg(bfile_buffered_cfg *cfg)
59{
60    BDBG_ASSERT(cfg);
61    cfg->nsegs = 8;
62    cfg->buf_len = cfg->nsegs * (BIO_BLOCK_SIZE*4);
63    return;
64}
65
66static ssize_t 
67b_file_buffered_proxy_read(bfile_io_read_t fd, void *buf, size_t length)
68{
69        bfile_buffered_t file= ((struct bfile_buffered_proxy *)fd)->parent;
70        BDBG_OBJECT_ASSERT(file, bfile_buffered);
71    if(file->fd) {
72        return file->fd->read(file->fd, buf, length);
73    }
74    return -1;
75}
76
77static off_t
78b_file_buffered_proxy_seek(bfile_io_read_t fd, off_t offset, int whence)
79{
80        bfile_buffered_t file= ((struct bfile_buffered_proxy *)fd)->parent;
81        BDBG_OBJECT_ASSERT(file, bfile_buffered);
82    if(file->fd) {
83        return file->fd->seek(file->fd, offset, whence);
84    }
85    return -1;
86}
87
88static int
89b_file_buffered_proxy_bounds(bfile_io_read_t fd, off_t *first, off_t *last)
90{
91        bfile_buffered_t file= ((struct bfile_buffered_proxy *)fd)->parent;
92        BDBG_OBJECT_ASSERT(file, bfile_buffered);
93    if(file->fd) {
94        return file->fd->bounds(file->fd, first, last);
95    }
96    *first = *last = 0;
97    return -1;
98}
99
100static const struct bfile_io_read b_file_buffered_proxy_ops = {
101        b_file_buffered_proxy_read,
102        b_file_buffered_proxy_seek,
103        b_file_buffered_proxy_bounds,
104        BIO_DEFAULT_PRIORITY
105};
106
107static ssize_t 
108b_file_buffered_read(bfile_io_read_t fd, void *buf, size_t length)
109{
110        bfile_buffered_t file=(void *)fd;
111        BDBG_OBJECT_ASSERT(file, bfile_buffered);
112    if(file->fd) {
113        bfile_buffer_result result;
114        batom_t data = bfile_buffer_read(file->buffer, file->pos, length, &result);
115        if(data) {
116            size_t len;
117            batom_cursor cursor;
118
119            batom_cursor_from_atom(&cursor, data);
120            len = batom_cursor_copy(&cursor, buf, length);
121            file->pos += len;
122            batom_release(data);
123            return (ssize_t) len;
124        }
125    }
126    return -1;
127}
128
129static off_t
130b_file_buffered_seek(bfile_io_read_t fd, off_t offset, int whence)
131{
132        bfile_buffered_t file=(void *)fd;
133        BDBG_OBJECT_ASSERT(file, bfile_buffered);
134    if(file->fd) {
135        off_t first, last;
136        int rc;
137
138        switch(whence) {
139        case SEEK_CUR:
140        case SEEK_END:
141            rc = file->fd->bounds(file->fd, &first, &last);
142            if(rc<0) { goto error;}
143            if(whence==SEEK_END) {
144                offset = last + offset;
145            } else {
146                offset = file->pos + offset;
147            }
148            if(offset<first) {
149                offset = first;
150            } else if (offset>last) {
151                offset = last;
152            }
153            /* keep going */
154        case SEEK_SET:
155        default:
156            file->pos = offset;
157            break;
158        }
159        return offset;
160    }
161error:
162    return -1;
163}
164
165static int
166b_file_buffered_bounds(bfile_io_read_t fd, off_t *first, off_t *last)
167{
168        bfile_buffered_t file=(void *)fd;
169        BDBG_OBJECT_ASSERT(file, bfile_buffered);
170    if(file->fd) {
171        return file->fd->bounds(file->fd, first, last);
172    }
173    *first = *last = 0;
174    return -1;
175}
176
177static const struct bfile_io_read b_file_buffered_ops = {
178        b_file_buffered_read,
179        b_file_buffered_seek,
180        b_file_buffered_bounds,
181        BIO_DEFAULT_PRIORITY
182};
183
184
185bfile_buffered_t
186bfile_buffered_create(batom_factory_t factory, bfile_buffered_cfg *cfg)
187{
188    bfile_buffered_t  file;
189    bfile_buffer_cfg buffer_cfg;
190    BERR_Code rc;
191
192    BDBG_ASSERT(factory);
193    BDBG_ASSERT(cfg);
194
195    file = BKNI_Malloc(sizeof(*file)+cfg->buf_len);
196    if(!file) {rc=BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);goto err_alloc;}
197    BDBG_OBJECT_INIT(file, bfile_buffered);
198    file->cfg = *cfg;
199    file->fd = NULL;
200    file->pos = 0;
201    file->proxy_fd.parent = file;
202    file->proxy_fd.file = b_file_buffered_proxy_ops;
203    file->file = b_file_buffered_ops;
204
205    bfile_buffer_default_cfg(&buffer_cfg);
206    buffer_cfg.nsegs = cfg->nsegs;
207    buffer_cfg.buf_len = cfg->buf_len;
208    buffer_cfg.buf = &file->buf;
209    buffer_cfg.fd = &file->proxy_fd.file;
210    file->buffer = bfile_buffer_create(factory, &buffer_cfg);
211    if(!file->buffer) {rc=BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);goto err_buffer;}
212
213    return file;
214err_buffer:
215    BKNI_Free(file);
216err_alloc:
217    return NULL;
218}
219
220void 
221bfile_buffered_destroy(bfile_buffered_t file)
222{
223    BDBG_OBJECT_ASSERT(file, bfile_buffered);
224
225    bfile_buffer_destroy(file->buffer);
226    BDBG_OBJECT_DESTROY(file, bfile_buffered);
227    BKNI_Free(file);
228    return;
229}
230
231
232bfile_io_read_t
233bfile_buffered_attach(bfile_buffered_t file, bfile_io_read_t fd)
234{
235    BDBG_OBJECT_ASSERT(file, bfile_buffered);
236    BDBG_ASSERT(fd);
237
238    if(file->fd) {
239        BDBG_ERR(("bfile_buffered_attach: %#lx already attached file %#lx", (unsigned long)file, (unsigned long)fd));
240    }
241
242    file->pos = 0;
243    file->fd = fd;
244    return &file->file;
245}
246
247void 
248bfile_buffered_detach(bfile_buffered_t file)
249{
250    BDBG_OBJECT_ASSERT(file, bfile_buffered);
251    if(!file->fd) {
252        BDBG_ERR(("bfile_buffered_detach: %#lx no attached file", (unsigned long)file));
253    }
254    bfile_buffer_clear(file->buffer);
255    file->fd = NULL;
256    file->pos = 0;
257    return;
258}
259
260
261bfile_buffer_t
262bfile_buffered_get_buffer(bfile_buffered_t file)
263{
264    BDBG_OBJECT_ASSERT(file, bfile_buffered);
265    return file->buffer;
266}
Note: See TracBrowser for help on using the repository browser.