[Prev][Next][Index][Thread]
possibly a bug in generic_file_read
It appears that there is a bug in generic_file_read in the linux/fs
code. The file position index is never updated, so repeated calls to
fill a buffer, e.g., with the read system call, always fill from the
beginning of the file. Here is a diff for linux/fs/dev.c that seems to
fix the problem.
*** dev.c Fri Jan 1 12:22:06 1999
--- dev.c.0 Fri Jan 1 12:19:37 1999
***************
*** 431,437 ****
}
retval = count - bytesleft;
- filp->f_pos += retval;
done:
if (bytesleft != count && ! IS_RDONLY(inode)) {
/* Then we have read something -- update the atime. */
--- 431,436 ----
I have also attached a test program that exposes the bug.
Mike
/*
* Copyright (c) 1996, 1998 University of Utah and the Flux Group.
* All rights reserved.
*
* This file is part of the Flux OSKit. The OSKit is free software, also known
* as "open source;" you can redistribute it and/or modify it under the terms
* of the GNU General Public License (GPL), version 2, as published by the Free
* Software Foundation (FSF). To explore alternate licensing terms, contact
* the University of Utah at csl-dist@cs.utah.edu or +1-801-585-3271.
*
* The OSKit is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GPL for more details. You should have
* received a copy of the GPL along with the OSKit; see the file COPYING. If
* not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA.
*/
/*
* Example of using the fsread library.
*
* It opens a file "/etc/passwd" and dumps it out.
*
* You will need to make sure DISK_NAME, PART_NAME, and FILE_NAME are
* appropriate.
*/
#define DISK_NAME "sda"
#define PART_NAME "b"
#define FILE_NAME "/etc/passwd"
#include <oskit/dev/dev.h>
#include <oskit/diskpart/diskpart.h>
#include <oskit/io/blkio.h>
#include <oskit/dev/linux.h>
#include <oskit/fs/linux.h>
#include <oskit/fs/read.h>
#include <oskit/principal.h>
#include <oskit/c/fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <fs.h>
/* Partition array, filled in by the diskpart library. */
#define MAX_PARTS 30
static diskpart_t part_array[MAX_PARTS];
#define CHECK(err, pred, f, args) ({ \
(err) = f args; \
if (pred) panic(#f" failed: %s (0x%lx)", strerror(err), (err));\
})
/* Identity of current client process. */
static oskit_principal_t *cur_principal;
#define MYBUFSIZE 20
int
main(int argc, char **argv)
{
char buf[MYBUFSIZE];
oskit_blkio_t *disk;
oskit_blkio_t *part;
oskit_u32_t i;
oskit_error_t err;
char *diskname = DISK_NAME;
char *partname = PART_NAME;
char *filename = FILE_NAME;
int nparts;
oskit_filesystem_t *out_fs;
int fd, n;
oskit_identity_t id;
oskit_dir_t *dir;
printf(">>>Initializing devices...\n");
oskit_dev_init();
oskit_linux_init_ide();
oskit_linux_init_scsi();
printf(">>>Probing devices...\n");
oskit_dev_probe();
printf(">>>Establishing client identity\n");
id.uid = 0;
id.gid = 0;
id.ngroups = 0;
id.groups = 0;
CHECK(err, err, oskit_principal_create, (&id, &cur_principal));
CHECK(err, err, oskit_linux_block_open,
(diskname, OSKIT_DEV_OPEN_READ, &disk));
nparts = diskpart_blkio_get_partition(disk, part_array, MAX_PARTS);
assert(nparts > 0);
CHECK(err, !err,
diskpart_blkio_lookup_bsd_string,
(part_array, partname, disk, &part));
oskit_blkio_release(disk); /* partition has a ref */
printf(">>>Trying open\n");
fs_linux_init();
assert(fs_linux_mount(part,OSKIT_FS_RDONLY,&out_fs) == 0);
/* oskit_blkio_release(part); can we release the partition now? */
CHECK(err, err, oskit_filesystem_getroot, (out_fs, &dir));
CHECK(err, err, fs_init, (dir));
CHECK(fd, fd == -1, open, (filename, O_RDONLY));
printf ("open fd = %d\n", fd);
do {
n = read(fd, buf, MYBUFSIZE);
printf("n = %d\n", n);
for (i = 0; i < n; i++) putchar(buf[i]);
} while (n == MYBUFSIZE);
return 0;
}
oskit_error_t
oskit_get_call_context(const struct oskit_guid *iid, void **out_if)
{
if (memcmp(iid, &oskit_iunknown_iid, sizeof(*iid)) == 0 ||
memcmp(iid, &oskit_principal_iid, sizeof(*iid)) == 0) {
*out_if = cur_principal;
oskit_principal_addref(cur_principal);
return 0;
} else {
printf("crapped out in oskit_get_call_context\n");
exit (1);
}
}
Follow-Ups: