Commit 60efec8e authored by David S. Miller's avatar David S. Miller

Merge davem@nuts.davemloft.net:/disk1/BK/sparc-2.6

into kernel.bkbits.net:/home/davem/sparc-2.6
parents 79bd9937 3dc527ec
......@@ -19,23 +19,18 @@ fmask=### -- The permission mask for files.
codepage=### -- Sets the codepage number for converting to shortname
characters on FAT filesystem.
NOTE: If this option was not specified, the file name
may not be read/written rightly, also filesystem is
mounted as read-only.
By default, FAT_DEFAULT_CODEPAGE setting is used.
iocharset=name -- Character set to use for converting between the
encoding is used for user visible filename and 16 bit
Unicode characters. Long filenames are stored on disk
in Unicode format, but Unix for the most part doesn't
know how to deal with Unicode.
By default, FAT_DEFAULT_IOCHARSET setting is used.
There is also an option of doing UTF8 translations
with the utf8 option.
NOTE: If this option was not specified, the file name
may not be read/written rightly, also filesystem is
mounted as read-only.
NOTE: "iocharset=utf8" is not recommended. If unsure,
you should consider the following option instead.
......
......@@ -5182,7 +5182,7 @@ struct _snd_pcm_runtime {
The callback is much more complicated than the text-file
version. You need to use a low-level i/o functions such as
<function>copy_from/to_user()</function> to transfer the
data. Also, you have to keep tracking the file position, too.
data.
<informalexample>
<programlisting>
......@@ -5190,14 +5190,15 @@ struct _snd_pcm_runtime {
static long my_file_io_read(snd_info_entry_t *entry,
void *file_private_data,
struct file *file,
char *buf, long count)
char *buf,
unsigned long count,
unsigned long pos)
{
long size = count;
if (file->f_pos + size > local_max_size)
size = local_max_size - file->f_pos;
if (copy_to_user(buf, local_data + file->f_pos, size))
if (pos + size > local_max_size)
size = local_max_size - pos;
if (copy_to_user(buf, local_data + pos, size))
return -EFAULT;
file->f_pos += size;
return size;
}
]]>
......
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 8
EXTRAVERSION =-rc3
EXTRAVERSION =-rc4
NAME=Zonked Quokka
# *DOCUMENTATION*
......
......@@ -7,10 +7,10 @@ LDFLAGS_bootp :=-p --no-undefined -X \
--defsym params_phys=$(PARAMS_PHYS) -T
AFLAGS_initrd.o :=-DINITRD=\"$(INITRD)\"
targets := bootp bootp.lds init.o kernel.o initrd.o
targets := bootp init.o kernel.o initrd.o
# Note that bootp.lds picks up kernel.o and initrd.o
$(obj)/bootp: $(addprefix $(obj)/,bootp.lds init.o kernel.o initrd.o) FORCE
$(obj)/bootp: $(src)/bootp.lds $(addprefix $(obj)/,init.o kernel.o initrd.o) FORCE
$(call if_changed,ld)
@:
......
......@@ -101,7 +101,7 @@ $(obj)/piggy.o: $(obj)/piggy.gz FORCE
CFLAGS_font.o := -Dstatic=
$(obj)/font.o: $(FONTC)
$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in Makefile arch/arm/boot/Makefile .config
$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile .config
@sed "$(SEDFLAGS)" < $< > $@
$(obj)/misc.o: $(obj)/misc.c include/asm/arch/uncompress.h lib/inflate.c
......
......@@ -60,11 +60,11 @@ int sysctl_lasatstring(ctl_table *table, int *name, int nlen,
/* And the same for proc */
int proc_dolasatstring(ctl_table *table, int write, struct file *filp,
void *buffer, size_t *lenp)
void *buffer, size_t *lenp, loff_t *ppos)
{
int r;
down(&lasat_info_sem);
r = proc_dostring(table, write, filp, buffer, lenp);
r = proc_dostring(table, write, filp, buffer, lenp, ppos);
if ( (!write) || r) {
up(&lasat_info_sem);
return r;
......@@ -76,11 +76,11 @@ int proc_dolasatstring(ctl_table *table, int write, struct file *filp,
/* proc function to write EEPROM after changing int entry */
int proc_dolasatint(ctl_table *table, int write, struct file *filp,
void *buffer, size_t *lenp)
void *buffer, size_t *lenp, loff_t *ppos)
{
int r;
down(&lasat_info_sem);
r = proc_dointvec(table, write, filp, buffer, lenp);
r = proc_dointvec(table, write, filp, buffer, lenp, ppos);
if ( (!write) || r) {
up(&lasat_info_sem);
return r;
......@@ -95,7 +95,7 @@ static int rtctmp;
#ifdef CONFIG_DS1603
/* proc function to read/write RealTime Clock */
int proc_dolasatrtc(ctl_table *table, int write, struct file *filp,
void *buffer, size_t *lenp)
void *buffer, size_t *lenp, loff_t *ppos)
{
int r;
down(&lasat_info_sem);
......@@ -105,7 +105,7 @@ int proc_dolasatrtc(ctl_table *table, int write, struct file *filp,
if (rtctmp < 0)
rtctmp = 0;
}
r = proc_dointvec(table, write, filp, buffer, lenp);
r = proc_dointvec(table, write, filp, buffer, lenp, ppos);
if ( (!write) || r) {
up(&lasat_info_sem);
return r;
......@@ -180,14 +180,14 @@ void update_bcastaddr(void)
static char proc_lasat_ipbuf[32];
/* Parsing of IP address */
int proc_lasat_ip(ctl_table *table, int write, struct file *filp,
void *buffer, size_t *lenp)
void *buffer, size_t *lenp, loff_t *ppos)
{
int len;
unsigned int ip;
char *p, c;
if (!table->data || !table->maxlen || !*lenp ||
(filp->f_pos && !write)) {
(*ppos && !write)) {
*lenp = 0;
return 0;
}
......@@ -213,7 +213,7 @@ int proc_lasat_ip(ctl_table *table, int write, struct file *filp,
return -EFAULT;
}
proc_lasat_ipbuf[len] = 0;
filp->f_pos += *lenp;
*ppos += *lenp;
/* Now see if we can convert it to a valid IP */
ip = in_aton(proc_lasat_ipbuf);
*(unsigned int *)(table->data) = ip;
......@@ -241,7 +241,7 @@ int proc_lasat_ip(ctl_table *table, int write, struct file *filp,
len++;
}
*lenp = len;
filp->f_pos += len;
*ppos += len;
}
update_bcastaddr();
up(&lasat_info_sem);
......@@ -277,11 +277,11 @@ static int sysctl_lasat_eeprom_value(ctl_table *table, int *name, int nlen,
}
int proc_lasat_eeprom_value(ctl_table *table, int write, struct file *filp,
void *buffer, size_t *lenp)
void *buffer, size_t *lenp, loff_t *ppos)
{
int r;
down(&lasat_info_sem);
r = proc_dointvec(table, write, filp, buffer, lenp);
r = proc_dointvec(table, write, filp, buffer, lenp, ppos);
if ( (!write) || r) {
up(&lasat_info_sem);
return r;
......
......@@ -37,9 +37,6 @@ _GLOBAL(slb_allocate)
* a free slot first but that took too long. Unfortunately we
* dont have any LRU information to help us choose a slot.
*/
srdi r9,r1,27
ori r9,r9,1 /* mangle SP for later compare */
ld r10,PACASTABRR(r13)
3:
addi r10,r10,1
......@@ -48,18 +45,32 @@ _GLOBAL(slb_allocate)
blt+ 4f
li r10,SLB_NUM_BOLTED
4:
slbmfee r11,r10
/* Don't throw out the segment for our kernel stack. Since we
/*
* Never cast out the segment for our kernel stack. Since we
* dont invalidate the ERAT we could have a valid translation
* for the kernel stack during the first part of exception
* exit which gets invalidated due to a tlbie from another cpu
* at a non recoverable point (after setting srr0/1) - Anton
*
* for the kernel stack during the first part of exception exit
* which gets invalidated due to a tlbie from another cpu at a
* non recoverable point (after setting srr0/1) - Anton
*/
4: slbmfee r11,r10
srdi r11,r11,27
/*
* Use paca->ksave as the value of the kernel stack pointer,
* because this is valid at all times.
* The >> 27 (rather than >> 28) is so that the LSB is the
* valid bit - this way we check valid and ESID in one compare.
* In order to completely close the tiny race in the context
* switch (between updating r1 and updating paca->ksave),
* we check against both r1 and paca->ksave.
*/
srdi r11,r11,27
srdi r9,r1,27
ori r9,r9,1 /* mangle SP for later compare */
cmpd r11,r9
beq- 3b
ld r9,PACAKSAVE(r13)
srdi r9,r9,27
ori r9,r9,1
cmpd r11,r9
beq- 3b
......
......@@ -345,7 +345,7 @@ acpi_system_write_alarm (
acpi_set_register(ACPI_BITREG_RT_CLOCK_ENABLE, 1, ACPI_MTX_LOCK);
file->f_pos += count;
*ppos += count;
result = 0;
end:
......
......@@ -94,7 +94,7 @@ isdn_divert_read(struct file *file, char *buf, size_t count, loff_t * off)
if ((len = strlen(inf->info_start)) <= count) {
if (copy_to_user(buf, inf->info_start, len))
return -EFAULT;
file->f_pos += len;
*off += len;
return (len);
}
return (0);
......@@ -142,7 +142,7 @@ isdn_divert_open(struct inode *ino, struct file *filep)
(struct divert_info **) filep->private_data = &divert_info_head;
spin_unlock_irqrestore( &divert_info_lock, flags );
/* start_divert(); */
return (0);
return nonseekable_open(ino, filep);
} /* isdn_divert_open */
/*******************/
......
......@@ -234,7 +234,7 @@ hysdn_log_read(struct file *file, char __user *buf, size_t count, loff_t * off)
if ((len = strlen(inf->log_start)) <= count) {
if (copy_to_user(buf, inf->log_start, len))
return -EFAULT;
file->f_pos += len;
*off += len;
return (len);
}
return (0);
......
......@@ -179,7 +179,7 @@ static int dvb_dmx_swfilter_sectionfilter (struct dvb_demux_feed *feed,
neq |= f->maskandnotmode[i] & xor;
}
if (f->doneq & !neq)
if (f->doneq && !neq)
return 0;
return feed->cb.sec (feed->feed.sec.secbuf, feed->feed.sec.seclen,
......
......@@ -554,6 +554,44 @@ menu "DOS/FAT/NT Filesystems"
config FAT_FS
tristate
select NLS
help
If you want to use one of the FAT-based file systems (the MS-DOS,
VFAT (Windows 95) and UMSDOS (used to run Linux on top of an
ordinary DOS partition) file systems), then you must say Y or M here
to include FAT support. You will then be able to mount partitions or
diskettes with FAT-based file systems and transparently access the
files on them, i.e. MSDOS files will look and behave just like all
other Unix files.
This FAT support is not a file system in itself, it only provides
the foundation for the other file systems. You will have to say Y or
M to at least one of "MSDOS fs support" or "VFAT fs support" in
order to make use of it.
Another way to read and write MSDOS floppies and hard drive
partitions from within Linux (but not transparently) is with the
mtools ("man mtools") program suite. You don't need to say Y here in
order to do that.
If you need to move large files on floppies between a DOS and a
Linux box, say Y here, mount the floppy under Linux with an MSDOS
file system and use GNU tar's M option. GNU tar is a program
available for Unix and DOS ("man tar" or "info tar").
It is now also becoming possible to read and write compressed FAT
file systems; read <file:Documentation/filesystems/fat_cvf.txt> for
details.
The FAT support will enlarge your kernel by about 37 KB. If unsure,
say Y.
To compile this as a module, choose M here: the module will be called
fat. Note that if you compile the FAT support as a module, you
cannot compile any of the FAT-based file systems into the kernel
-- they will have to be modules as well.
The file system of your root partition (the one containing the
directory /) cannot be a module, so don't say M here if you intend
to use UMSDOS as your root file system.
config MSDOS_FS
tristate "MSDOS fs support"
......@@ -606,6 +644,25 @@ config VFAT_FS
To compile this as a module, choose M here: the module will be called
vfat.
config FAT_DEFAULT_CODEPAGE
int "Default codepage for FAT"
depends on MSDOS_FS || VFAT_FS
default 437
help
This option should be set to the codepage of your FAT filesystems.
It can be overridden with the 'codepage' mount option.
config FAT_DEFAULT_IOCHARSET
string "Default iocharset for FAT"
depends on VFAT_FS
default "iso8859-1"
help
Set this to the default I/O character set you'd like FAT to use.
It should probably match the character set that most of your
FAT filesystems use, and can be overridded with the 'iocharset'
mount option for FAT filesystems. Note that UTF8 is *not* a
supported charset for FAT filesystems.
config UMSDOS_FS
#dep_tristate ' UMSDOS: Unix-like file system on top of standard MSDOS fs' CONFIG_UMSDOS_FS $CONFIG_MSDOS_FS
# UMSDOS is temprory broken
......
......@@ -23,6 +23,14 @@
#include <linux/parser.h>
#include <asm/unaligned.h>
#ifndef CONFIG_FAT_DEFAULT_IOCHARSET
/* if user don't select VFAT, this is undefined. */
#define CONFIG_FAT_DEFAULT_IOCHARSET ""
#endif
static int fat_default_codepage = CONFIG_FAT_DEFAULT_CODEPAGE;
static char fat_default_iocharset[] = CONFIG_FAT_DEFAULT_IOCHARSET;
/*
* New FAT inode stuff. We do the following:
* a) i_ino is constant and has nothing with on-disk location.
......@@ -166,15 +174,15 @@ void fat_put_super(struct super_block *sb)
if (sbi->nls_disk) {
unload_nls(sbi->nls_disk);
sbi->nls_disk = NULL;
sbi->options.codepage = 0;
sbi->options.codepage = fat_default_codepage;
}
if (sbi->nls_io) {
unload_nls(sbi->nls_io);
sbi->nls_io = NULL;
}
if (sbi->options.iocharset) {
if (sbi->options.iocharset != fat_default_iocharset) {
kfree(sbi->options.iocharset);
sbi->options.iocharset = NULL;
sbi->options.iocharset = fat_default_iocharset;
}
sb->s_fs_info = NULL;
......@@ -193,10 +201,11 @@ static int fat_show_options(struct seq_file *m, struct vfsmount *mnt)
seq_printf(m, ",gid=%u", opts->fs_gid);
seq_printf(m, ",fmask=%04o", opts->fs_fmask);
seq_printf(m, ",dmask=%04o", opts->fs_dmask);
if (sbi->nls_disk && opts->codepage)
if (sbi->nls_disk && opts->codepage != fat_default_codepage)
seq_printf(m, ",codepage=%s", sbi->nls_disk->charset);
if (isvfat) {
if (sbi->nls_io && opts->iocharset)
if (sbi->nls_io &&
strcmp(opts->iocharset, fat_default_iocharset))
seq_printf(m, ",iocharset=%s", sbi->nls_io->charset);
switch (opts->shortname) {
......@@ -327,14 +336,15 @@ static int parse_options(char *options, int is_vfat, int *debug,
char *p;
substring_t args[MAX_OPT_ARGS];
int option;
char *iocharset;
opts->isvfat = is_vfat;
opts->fs_uid = current->uid;
opts->fs_gid = current->gid;
opts->fs_fmask = opts->fs_dmask = current->fs->umask;
opts->codepage = 0;
opts->iocharset = NULL;
opts->codepage = fat_default_codepage;
opts->iocharset = fat_default_iocharset;
if (is_vfat)
opts->shortname = VFAT_SFN_DISPLAY_LOWER|VFAT_SFN_CREATE_WIN95;
else
......@@ -433,11 +443,12 @@ static int parse_options(char *options, int is_vfat, int *debug,
/* vfat specific */
case Opt_charset:
if (opts->iocharset)
if (opts->iocharset != fat_default_iocharset)
kfree(opts->iocharset);
opts->iocharset = match_strdup(&args[0]);
if (opts->iocharset == NULL)
iocharset = match_strdup(&args[0]);
if (!iocharset)
return -ENOMEM;
opts->iocharset = iocharset;
break;
case Opt_shortname_lower:
opts->shortname = VFAT_SFN_DISPLAY_LOWER
......@@ -486,9 +497,15 @@ static int parse_options(char *options, int is_vfat, int *debug,
return -EINVAL;
}
}
/* UTF8 doesn't provide FAT semantics */
if (!strcmp(opts->iocharset, "utf8")) {
printk(KERN_ERR "FAT: utf8 is not a recommended IO charset"
" for FAT filesystems, filesystem will be case sensitive!\n");
}
if (opts->unicode_xlate)
opts->utf8 = 0;
return 0;
}
......@@ -768,66 +785,6 @@ static struct export_operations fat_export_ops = {
.get_parent = fat_get_parent,
};
static int fat_load_nls(struct super_block *sb)
{
struct msdos_sb_info *sbi = MSDOS_SB(sb);
struct fat_mount_options *opts = &sbi->options;
char codepage[50], *iocharset;
int error = 0, not_specified = 0;
if (opts->codepage)
snprintf(codepage, sizeof(codepage), "cp%d", opts->codepage);
else {
not_specified = 1;
strcpy(codepage, "default");
}
sbi->nls_disk = load_nls(codepage);
if (sbi->nls_disk == NULL) {
printk(KERN_ERR "FAT: codepage %s not found\n", codepage);
error = -EINVAL;
goto out;
}
if (opts->isvfat) {
if (opts->iocharset)
iocharset = opts->iocharset;
else {
not_specified = 1;
iocharset = "default";
}
/*
* FIXME: utf8 is using iocharset for upper/lower conversion
* UTF8 doesn't provide FAT semantics
*/
if (!strcmp(iocharset, "utf8")) {
printk(KERN_WARNING
"FAT: utf8 is not a recommended IO charset"
" for FAT filesystem,"
" filesystem will be case sensitive!\n");
}
sbi->nls_io = load_nls(iocharset);
if (sbi->nls_io == NULL) {
printk(KERN_ERR "FAT: IO charset %s not found\n",
iocharset);
error = -EINVAL;
goto out;
}
}
if (not_specified) {
unsigned long not_ro = !(sb->s_flags & MS_RDONLY);
if (not_ro)
sb->s_flags |= MS_RDONLY;
printk(KERN_INFO "FAT: %s option didn't specified\n"
" File name can not access proper%s\n",
opts->isvfat ? "codepage or iocharset" : "codepage",
not_ro ? " (mounted as read-only)" : "");
}
out:
return error;
}
/*
* Read the super block of an MS-DOS FS.
*/
......@@ -843,6 +800,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent,
int debug, first;
unsigned int media;
long error;
char buf[50];
sbi = kmalloc(sizeof(struct msdos_sb_info), GFP_KERNEL);
if (!sbi)
......@@ -1057,9 +1015,23 @@ int fat_fill_super(struct super_block *sb, void *data, int silent,
goto out_invalid;
}
error = fat_load_nls(sb);
if (error)
error = -EINVAL;
sprintf(buf, "cp%d", sbi->options.codepage);
sbi->nls_disk = load_nls(buf);
if (!sbi->nls_disk) {
printk(KERN_ERR "FAT: codepage %s not found\n", buf);
goto out_fail;
}
/* FIXME: utf8 is using iocharset for upper/lower conversion */
if (sbi->options.isvfat) {
sbi->nls_io = load_nls(sbi->options.iocharset);
if (!sbi->nls_io) {
printk(KERN_ERR "FAT: IO charset %s not found\n",
sbi->options.iocharset);
goto out_fail;
}
}
error = -ENOMEM;
root_inode = new_inode(sb);
......@@ -1093,7 +1065,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent,
unload_nls(sbi->nls_io);
if (sbi->nls_disk)
unload_nls(sbi->nls_disk);
if (sbi->options.iocharset)
if (sbi->options.iocharset != fat_default_iocharset)
kfree(sbi->options.iocharset);
sb->s_fs_info = NULL;
kfree(sbi);
......
......@@ -74,7 +74,7 @@ decode_fh(u32 *p, struct svc_fh *fhp)
static inline u32 *
encode_fh(u32 *p, struct svc_fh *fhp)
{
int size = fhp->fh_handle.fh_size;
unsigned int size = fhp->fh_handle.fh_size;
*p++ = htonl(size);
if (size) p[XDR_QUADLEN(size)-1]=0;
memcpy(p, &fhp->fh_handle.fh_base, size);
......@@ -328,7 +328,7 @@ int
nfs3svc_decode_readargs(struct svc_rqst *rqstp, u32 *p,
struct nfsd3_readargs *args)
{
int len;
unsigned int len;
int v,pn;
if (!(p = decode_fh(p, &args->fh))
......@@ -358,7 +358,7 @@ int
nfs3svc_decode_writeargs(struct svc_rqst *rqstp, u32 *p,
struct nfsd3_writeargs *args)
{
int len, v;
unsigned int len, v, hdr;
if (!(p = decode_fh(p, &args->fh))
|| !(p = xdr_decode_hyper(p, &args->offset)))
......@@ -368,9 +368,12 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, u32 *p,
args->stable = ntohl(*p++);
len = args->len = ntohl(*p++);
hdr = (void*)p - rqstp->rq_arg.head[0].iov_base;
if (rqstp->rq_arg.len < len + hdr)
return 0;
args->vec[0].iov_base = (void*)p;
args->vec[0].iov_len = rqstp->rq_arg.head[0].iov_len -
(((void*)p) - rqstp->rq_arg.head[0].iov_base);
args->vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr;
if (len > NFSSVC_MAXBLKSIZE)
len = NFSSVC_MAXBLKSIZE;
......@@ -427,7 +430,7 @@ int
nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, u32 *p,
struct nfsd3_symlinkargs *args)
{
int len;
unsigned int len;
int avail;
char *old, *new;
struct kvec *vec;
......@@ -444,7 +447,7 @@ nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, u32 *p,
*/
svc_take_page(rqstp);
len = ntohl(*p++);
if (len <= 0 || len > NFS3_MAXPATHLEN || len >= PAGE_SIZE)
if (len == 0 || len > NFS3_MAXPATHLEN || len >= PAGE_SIZE)
return 0;
args->tname = new = page_address(rqstp->rq_respages[rqstp->rq_resused-1]);
args->tlen = len;
......
......@@ -234,7 +234,7 @@ int
nfssvc_decode_readargs(struct svc_rqst *rqstp, u32 *p,
struct nfsd_readargs *args)
{
int len;
unsigned int len;
int v,pn;
if (!(p = decode_fh(p, &args->fh)))
return 0;
......@@ -266,7 +266,7 @@ int
nfssvc_decode_writeargs(struct svc_rqst *rqstp, u32 *p,
struct nfsd_writeargs *args)
{
int len;
unsigned int len;
int v;
if (!(p = decode_fh(p, &args->fh)))
return 0;
......
......@@ -270,6 +270,16 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_
EXPORT_SYMBOL(vfs_write);
static inline loff_t file_pos_read(struct file *file)
{
return file->f_pos;
}
static inline void file_pos_write(struct file *file, loff_t pos)
{
file->f_pos = pos;
}
asmlinkage ssize_t sys_read(unsigned int fd, char __user * buf, size_t count)
{
struct file *file;
......@@ -278,7 +288,9 @@ asmlinkage ssize_t sys_read(unsigned int fd, char __user * buf, size_t count)
file = fget_light(fd, &fput_needed);
if (file) {
ret = vfs_read(file, buf, count, &file->f_pos);
loff_t pos = file_pos_read(file);
ret = vfs_read(file, buf, count, &pos);
file_pos_write(file, pos);
fput_light(file, fput_needed);
}
......@@ -294,7 +306,9 @@ asmlinkage ssize_t sys_write(unsigned int fd, const char __user * buf, size_t co
file = fget_light(fd, &fput_needed);
if (file) {
ret = vfs_write(file, buf, count, &file->f_pos);
loff_t pos = file_pos_read(file);
ret = vfs_write(file, buf, count, &pos);
file_pos_write(file, pos);
fput_light(file, fput_needed);
}
......@@ -520,7 +534,9 @@ sys_readv(unsigned long fd, const struct iovec __user *vec, unsigned long vlen)
file = fget_light(fd, &fput_needed);
if (file) {
ret = vfs_readv(file, vec, vlen, &file->f_pos);
loff_t pos = file_pos_read(file);
ret = vfs_readv(file, vec, vlen, &pos);
file_pos_write(file, pos);
fput_light(file, fput_needed);
}
......@@ -536,7 +552,9 @@ sys_writev(unsigned long fd, const struct iovec __user *vec, unsigned long vlen)
file = fget_light(fd, &fput_needed);
if (file) {
ret = vfs_writev(file, vec, vlen, &file->f_pos);
loff_t pos = file_pos_read(file);
ret = vfs_writev(file, vec, vlen, &pos);
file_pos_write(file, pos);
fput_light(file, fput_needed);
}
......
......@@ -24,6 +24,8 @@
#ifndef _DVBOSD_H_
#define _DVBOSD_H_
#include <linux/compiler.h>
typedef enum {
// All functions return -2 on "not open"
OSD_Close=1, // ()
......
......@@ -24,6 +24,8 @@
#ifndef _DVBVIDEO_H_
#define _DVBVIDEO_H_
#include <linux/compiler.h>
#ifdef __KERNEL__
#include <linux/types.h>
#else
......
......@@ -54,9 +54,11 @@ struct snd_info_entry_ops {
int (*release) (snd_info_entry_t * entry,
unsigned short mode, void *file_private_data);
long (*read) (snd_info_entry_t *entry, void *file_private_data,
struct file * file, char __user *buf, long count);
struct file * file, char __user *buf,
unsigned long count, unsigned long pos);
long (*write) (snd_info_entry_t *entry, void *file_private_data,
struct file * file, const char __user *buf, long count);
struct file * file, const char __user *buf,
unsigned long count, unsigned long pos);
long long (*llseek) (snd_info_entry_t *entry, void *file_private_data,
struct file * file, long long offset, int orig);
unsigned int (*poll) (snd_info_entry_t *entry, void *file_private_data,
......
......@@ -181,30 +181,37 @@ static ssize_t snd_info_entry_read(struct file *file, char __user *buffer,
struct snd_info_entry *entry;
snd_info_buffer_t *buf;
size_t size = 0;
loff_t pos;
data = snd_magic_cast(snd_info_private_data_t, file->private_data, return -ENXIO);
snd_assert(data != NULL, return -ENXIO);
pos = *offset;
if (pos < 0 || (long) pos != pos || (ssize_t) count < 0)
return -EIO;
if ((unsigned long) pos + (unsigned long) count < (unsigned long) pos)
return -EIO;
entry = data->entry;
switch (entry->content) {
case SNDRV_INFO_CONTENT_TEXT:
buf = data->rbuffer;
if (buf == NULL)
return -EIO;
if (file->f_pos >= (long)buf->size)
if (pos >= buf->size)
return 0;
size = buf->size - file->f_pos;
size = buf->size - pos;
size = min(count, size);
if (copy_to_user(buffer, buf->buffer + file->f_pos, size))
if (copy_to_user(buffer, buf->buffer + pos, size))
return -EFAULT;
file->f_pos += size;
break;
case SNDRV_INFO_CONTENT_DATA:
if (entry->c.ops->read)
return entry->c.ops->read(entry,
size = entry->c.ops->read(entry,
data->file_private_data,
file, buffer, count);
file, buffer, count, pos);
break;
}
if ((ssize_t) size > 0)
*offset = pos + size;
return size;
}
......@@ -215,34 +222,39 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer
struct snd_info_entry *entry;
snd_info_buffer_t *buf;
size_t size = 0;
loff_t pos;
data = snd_magic_cast(snd_info_private_data_t, file->private_data, return -ENXIO);
snd_assert(data != NULL, return -ENXIO);
entry = data->entry;
pos = *offset;
if (pos < 0 || (long) pos != pos || (ssize_t) count < 0)
return -EIO;
if ((unsigned long) pos + (unsigned long) count < (unsigned long) pos)
return -EIO;
switch (entry->content) {
case SNDRV_INFO_CONTENT_TEXT:
buf = data->wbuffer;
if (buf == NULL)
return -EIO;
if (file->f_pos < 0)
return -EINVAL;
if (file->f_pos >= (long)buf->len)
if (pos >= buf->len)
return -ENOMEM;
size = buf->len - file->f_pos;
size = buf->len - pos;
size = min(count, size);
if (copy_from_user(buf->buffer + file->f_pos, buffer, size))
if (copy_from_user(buf->buffer + pos, buffer, size))
return -EFAULT;
if ((long)buf->size < file->f_pos + size)
buf->size = file->f_pos + size;
file->f_pos += size;
if ((long)buf->size < pos + size)
buf->size = pos + size;
break;
case SNDRV_INFO_CONTENT_DATA:
if (entry->c.ops->write)
return entry->c.ops->write(entry,
size = entry->c.ops->write(entry,
data->file_private_data,
file, buffer, count);
file, buffer, count, pos);
break;
}
if ((ssize_t) size > 0)
*offset = pos + size;
return size;
}
......
......@@ -50,41 +50,42 @@ static int snd_opl4_mem_proc_release(snd_info_entry_t *entry,
}
static long snd_opl4_mem_proc_read(snd_info_entry_t *entry, void *file_private_data,
struct file *file, char __user *_buf, long count)
struct file *file, char __user *_buf,
unsigned long count, unsigned long pos)
{
opl4_t *opl4 = snd_magic_cast(opl4_t, entry->private_data, return -ENXIO);
long size;
char* buf;
size = count;
if (file->f_pos + size > entry->size)
size = entry->size - file->f_pos;
if (pos + size > entry->size)
size = entry->size - pos;
if (size > 0) {
buf = vmalloc(size);
if (!buf)
return -ENOMEM;
snd_opl4_read_memory(opl4, buf, file->f_pos, size);
snd_opl4_read_memory(opl4, buf, pos, size);
if (copy_to_user(_buf, buf, size)) {
vfree(buf);
return -EFAULT;
}
vfree(buf);
file->f_pos += size;
return size;
}
return 0;
}
static long snd_opl4_mem_proc_write(snd_info_entry_t *entry, void *file_private_data,
struct file *file, const char __user *_buf, long count)
struct file *file, const char __user *_buf,
unsigned long count, unsigned long pos)
{
opl4_t *opl4 = snd_magic_cast(opl4_t, entry->private_data, return -ENXIO);
long size;
char *buf;
size = count;
if (file->f_pos + size > entry->size)
size = entry->size - file->f_pos;
if (pos + size > entry->size)
size = entry->size - pos;
if (size > 0) {
buf = vmalloc(size);
if (!buf)
......@@ -93,9 +94,8 @@ static long snd_opl4_mem_proc_write(snd_info_entry_t *entry, void *file_private_
vfree(buf);
return -EFAULT;
}
snd_opl4_write_memory(opl4, buf, file->f_pos, size);
snd_opl4_write_memory(opl4, buf, pos, size);
vfree(buf);
file->f_pos += size;
return size;
}
return 0;
......
......@@ -33,7 +33,8 @@ typedef struct gus_proc_private {
} gus_proc_private_t;
static long snd_gf1_mem_proc_dump(snd_info_entry_t *entry, void *file_private_data,
struct file *file, char __user *buf, long count)
struct file *file, char __user *buf,
unsigned long count, unsigned long pos)
{
long size;
gus_proc_private_t *priv = snd_magic_cast(gus_proc_private_t, entry->private_data, return -ENXIO);
......@@ -41,12 +42,11 @@ static long snd_gf1_mem_proc_dump(snd_info_entry_t *entry, void *file_private_da
int err;
size = count;
if (file->f_pos + size > priv->size)
size = (long)priv->size - file->f_pos;
if (pos + size > priv->size)
size = (long)priv->size - pos;
if (size > 0) {
if ((err = snd_gus_dram_read(gus, buf, file->f_pos, size, priv->rom)) < 0)
if ((err = snd_gus_dram_read(gus, buf, pos, size, priv->rom)) < 0)
return err;
file->f_pos += size;
return size;
}
return 0;
......
......@@ -1185,35 +1185,35 @@ static void snd_cs4281_proc_read(snd_info_entry_t *entry,
}
static long snd_cs4281_BA0_read(snd_info_entry_t *entry, void *file_private_data,
struct file *file, char __user *buf, long count)
struct file *file, char __user *buf,
unsigned long count, unsigned long pos)
{
long size;
cs4281_t *chip = snd_magic_cast(cs4281_t, entry->private_data, return -ENXIO);
size = count;
if (file->f_pos + size > CS4281_BA0_SIZE)
size = (long)CS4281_BA0_SIZE - file->f_pos;
if (pos + size > CS4281_BA0_SIZE)
size = (long)CS4281_BA0_SIZE - pos;
if (size > 0) {
if (copy_to_user_fromio(buf, chip->ba0 + file->f_pos, size))
if (copy_to_user_fromio(buf, chip->ba0 + pos, size))
return -EFAULT;
file->f_pos += size;
}
return size;
}
static long snd_cs4281_BA1_read(snd_info_entry_t *entry, void *file_private_data,
struct file *file, char __user *buf, long count)
struct file *file, char __user *buf,
unsigned long count, unsigned long pos)
{
long size;
cs4281_t *chip = snd_magic_cast(cs4281_t, entry->private_data, return -ENXIO);
size = count;
if (file->f_pos + size > CS4281_BA1_SIZE)
size = (long)CS4281_BA1_SIZE - file->f_pos;
if (pos + size > CS4281_BA1_SIZE)
size = (long)CS4281_BA1_SIZE - pos;
if (size > 0) {
if (copy_to_user_fromio(buf, chip->ba1 + file->f_pos, size))
if (copy_to_user_fromio(buf, chip->ba1 + pos, size))
return -EFAULT;
file->f_pos += size;
}
return size;
}
......
......@@ -2866,18 +2866,18 @@ void __devinit snd_cs46xx_gameport(cs46xx_t *chip)
*/
static long snd_cs46xx_io_read(snd_info_entry_t *entry, void *file_private_data,
struct file *file, char __user *buf, long count)
struct file *file, char __user *buf,
unsigned long count, unsigned long pos)
{
long size;
snd_cs46xx_region_t *region = (snd_cs46xx_region_t *)entry->private_data;
size = count;
if (file->f_pos + (size_t)size > region->size)
size = region->size - file->f_pos;
if (pos + (size_t)size > region->size)
size = region->size - pos;
if (size > 0) {
if (copy_to_user_fromio(buf, region->remap_addr + file->f_pos, size))
if (copy_to_user_fromio(buf, region->remap_addr + pos, size))
return -EFAULT;
file->f_pos += size;
}
return size;
}
......
......@@ -191,7 +191,8 @@ static void snd_emu10k1_proc_acode_read(snd_info_entry_t *entry,
#define TOTAL_SIZE_CODE (0x200*8)
static long snd_emu10k1_fx8010_read(snd_info_entry_t *entry, void *file_private_data,
struct file *file, char __user *buf, long count)
struct file *file, char __user *buf,
unsigned long count, unsigned long pos)
{
long size;
emu10k1_t *emu = snd_magic_cast(emu10k1_t, entry->private_data, return -ENXIO);
......@@ -209,21 +210,20 @@ static long snd_emu10k1_fx8010_read(snd_info_entry_t *entry, void *file_private_
offset = emu->audigy ? A_FXGPREGBASE : FXGPREGBASE;
}
size = count;
if (file->f_pos + size > entry->size)
size = (long)entry->size - file->f_pos;
if (pos + size > entry->size)
size = (long)entry->size - pos;
if (size > 0) {
unsigned int *tmp;
long res;
unsigned int idx;
if ((tmp = kmalloc(size + 8, GFP_KERNEL)) == NULL)
return -ENOMEM;
for (idx = 0; idx < ((file->f_pos & 3) + size + 3) >> 2; idx++)
tmp[idx] = snd_emu10k1_ptr_read(emu, offset + idx + (file->f_pos >> 2), 0);
if (copy_to_user(buf, ((char *)tmp) + (file->f_pos & 3), size))
for (idx = 0; idx < ((pos & 3) + size + 3) >> 2; idx++)
tmp[idx] = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0);
if (copy_to_user(buf, ((char *)tmp) + (pos & 3), size))
res = -EFAULT;
else {
res = size;
file->f_pos += size;
}
kfree(tmp);
return res;
......
......@@ -1154,18 +1154,18 @@ static long long snd_mixart_BA1_llseek(snd_info_entry_t *entry,
mixart_BA0 proc interface for BAR 0 - read callback
*/
static long snd_mixart_BA0_read(snd_info_entry_t *entry, void *file_private_data,
struct file *file, char __user *buf, long count)
struct file *file, char __user *buf,
unsigned long count, unsigned long pos)
{
mixart_mgr_t *mgr = snd_magic_cast(mixart_mgr_t, entry->private_data, return -ENXIO);
count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
if(count <= 0)
return 0;
if(file->f_pos + count > MIXART_BA0_SIZE)
count = (long)(MIXART_BA0_SIZE - file->f_pos);
if(copy_to_user_fromio(buf, MIXART_MEM( mgr, file->f_pos ), count))
if(pos + count > MIXART_BA0_SIZE)
count = (long)(MIXART_BA0_SIZE - pos);
if(copy_to_user_fromio(buf, MIXART_MEM( mgr, pos ), count))
return -EFAULT;
file->f_pos += count;
return count;
}
......@@ -1173,18 +1173,18 @@ static long snd_mixart_BA0_read(snd_info_entry_t *entry, void *file_private_data
mixart_BA1 proc interface for BAR 1 - read callback
*/
static long snd_mixart_BA1_read(snd_info_entry_t *entry, void *file_private_data,
struct file *file, char __user *buf, long count)
struct file *file, char __user *buf,
unsigned long count, unsigned long pos)
{
mixart_mgr_t *mgr = snd_magic_cast(mixart_mgr_t, entry->private_data, return -ENXIO);
count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
if(count <= 0)
return 0;
if(file->f_pos + count > MIXART_BA1_SIZE)
count = (long)(MIXART_BA1_SIZE - file->f_pos);
if(copy_to_user_fromio(buf, MIXART_REG( mgr, file->f_pos ), count))
if(pos + count > MIXART_BA1_SIZE)
count = (long)(MIXART_BA1_SIZE - pos);
if(copy_to_user_fromio(buf, MIXART_REG( mgr, pos ), count))
return -EFAULT;
file->f_pos += count;
return count;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment