Commit f4a818e0 authored by Linus Torvalds's avatar Linus Torvalds

Import 1.1.55

parent 057f54fb
VERSION = 1 VERSION = 1
PATCHLEVEL = 1 PATCHLEVEL = 1
SUBLEVEL = 54 SUBLEVEL = 55
ARCH = i386 ARCH = i386
......
...@@ -25,9 +25,9 @@ ...@@ -25,9 +25,9 @@
/* Define the following if you don't like that your drives seek audibly /* Define the following if you don't like that your drives seek audibly
* after a disk change * after a disk change (but it may not work correctly for everybody)
*/ */
#define SILENT_DC_CLEAR /* #define SILENT_DC_CLEAR */
/* End of configuration */ /* End of configuration */
...@@ -304,7 +304,7 @@ static struct floppy_struct floppy_type[32] = { ...@@ -304,7 +304,7 @@ static struct floppy_struct floppy_type[32] = {
{ 5760,36,2,80,0,0x1B,0x43,0xAF,0x54,"CompaQ"}, /* 9 2.88MB 3.5" */ { 5760,36,2,80,0,0x1B,0x43,0xAF,0x54,"CompaQ"}, /* 9 2.88MB 3.5" */
{ 2880,18,2,80,0,0x25,0x00,0xDF,0x02,"h1440" }, /* 10 1.44MB 5.25" */ { 2880,18,2,80,0,0x25,0x00,0xDF,0x02,"h1440" }, /* 10 1.44MB 5.25" */
{ 3360,21,2,80,0,0x1C,0x00,0xCF,0x6C,"H1680" }, /* 11 1.68MB 3.5" */ { 3360,21,2,80,0,0x1C,0x00,0xCF,0x0C,"H1680" }, /* 11 1.68MB 3.5" */
{ 820,10,2,41,1,0x25,0x01,0xDF,0x2E,"h410" }, /* 12 410KB 5.25" */ { 820,10,2,41,1,0x25,0x01,0xDF,0x2E,"h410" }, /* 12 410KB 5.25" */
{ 1640,10,2,82,0,0x25,0x02,0xDF,0x2E,"H820" }, /* 13 820KB 3.5" */ { 1640,10,2,82,0,0x25,0x02,0xDF,0x2E,"H820" }, /* 13 820KB 3.5" */
{ 2952,18,2,82,0,0x25,0x00,0xDF,0x02,"h1476" }, /* 14 1.48MB 5.25" */ { 2952,18,2,82,0,0x25,0x00,0xDF,0x02,"h1476" }, /* 14 1.48MB 5.25" */
...@@ -317,8 +317,8 @@ static struct floppy_struct floppy_type[32] = { ...@@ -317,8 +317,8 @@ static struct floppy_struct floppy_type[32] = {
{ 1760,11,2,80,0,0x1C,0x09,0xCF,0x6C,"h880" }, /* 20 880KB 5.25" */ { 1760,11,2,80,0,0x1C,0x09,0xCF,0x6C,"h880" }, /* 20 880KB 5.25" */
{ 2080,13,2,80,0,0x1C,0x01,0xCF,0x6C,"D1040" }, /* 21 1.04MB 3.5" */ { 2080,13,2,80,0,0x1C,0x01,0xCF,0x6C,"D1040" }, /* 21 1.04MB 3.5" */
{ 2240,14,2,80,0,0x1C,0x19,0xCF,0x6C,"D1120" }, /* 22 1.12MB 3.5" */ { 2240,14,2,80,0,0x1C,0x19,0xCF,0x6C,"D1120" }, /* 22 1.12MB 3.5" */
{ 3200,20,2,80,0,0x1C,0x20,0xCF,0x6C,"h1600" }, /* 23 1.6MB 5.25" */ { 3200,20,2,80,0,0x1C,0x20,0xCF,0x2C,"h1600" }, /* 23 1.6MB 5.25" */
{ 3520,22,2,80,0,0x1C,0x08,0xCF,0x6C,"H1760" }, /* 24 1.76MB 3.5" */ { 3520,22,2,80,0,0x1C,0x08,0xCF,0x2e,"H1760" }, /* 24 1.76MB 3.5" */
{ 3840,24,2,80,0,0x1C,0x20,0xCF,0x6C,"H1920" }, /* 25 1.92MB 3.5" */ { 3840,24,2,80,0,0x1C,0x20,0xCF,0x6C,"H1920" }, /* 25 1.92MB 3.5" */
{ 6400,40,2,80,0,0x25,0x5B,0xCF,0x6C,"E3200" }, /* 26 3.20MB 3.5" */ { 6400,40,2,80,0,0x25,0x5B,0xCF,0x6C,"E3200" }, /* 26 3.20MB 3.5" */
{ 7040,44,2,80,0,0x25,0x5B,0xCF,0x6C,"E3520" }, /* 27 3.52MB 3.5" */ { 7040,44,2,80,0,0x25,0x5B,0xCF,0x6C,"E3520" }, /* 27 3.52MB 3.5" */
...@@ -326,7 +326,7 @@ static struct floppy_struct floppy_type[32] = { ...@@ -326,7 +326,7 @@ static struct floppy_struct floppy_type[32] = {
{ 3680,23,2,80,0,0x1C,0x10,0xCF,0x6C,"H1840" }, /* 29 1.84MB 3.5" */ { 3680,23,2,80,0,0x1C,0x10,0xCF,0x6C,"H1840" }, /* 29 1.84MB 3.5" */
{ 1600,10,2,80,0,0x25,0x02,0xDF,0x2E,"D800" }, /* 30 800KB 3.5" */ { 1600,10,2,80,0,0x25,0x02,0xDF,0x2E,"D800" }, /* 30 800KB 3.5" */
{ 3200,20,2,80,0,0x1C,0x00,0xCF,0x6C,"H1600" }, /* 31 1.6MB 3.5" */ { 3200,20,2,80,0,0x1C,0x00,0xCF,0x2C,"H1600" }, /* 31 1.6MB 3.5" */
}; };
#define NUMBER(x) (sizeof(x) / sizeof(*(x))) #define NUMBER(x) (sizeof(x) / sizeof(*(x)))
...@@ -1278,9 +1278,10 @@ static void recal_interrupt(void) ...@@ -1278,9 +1278,10 @@ static void recal_interrupt(void)
debugt("recal interrupt need 1 recal:"); debugt("recal interrupt need 1 recal:");
#endif #endif
/* after a second recalibrate, we still haven't /* after a second recalibrate, we still haven't
* reached track 0. Probably no drive */ * reached track 0. Probably no drive. Raise an
DRS->track = PROVEN_ABSENT; * error, as failing immediately might upset
cont->done(0); * computers possessed by the Devil :-) */
cont->error();
cont->redo(); cont->redo();
return; return;
case NEED_2_RECAL: case NEED_2_RECAL:
...@@ -1691,7 +1692,7 @@ static void setup_format_params(void) ...@@ -1691,7 +1692,7 @@ static void setup_format_params(void)
int count,head_shift,track_shift; int count,head_shift,track_shift;
raw_cmd.flags = FD_RAW_WRITE | FD_RAW_INTR | FD_RAW_SPIN | raw_cmd.flags = FD_RAW_WRITE | FD_RAW_INTR | FD_RAW_SPIN |
FD_RAW_NEED_DISK | FD_RAW_NEED_SEEK; /*FD_RAW_NEED_DISK |*/ FD_RAW_NEED_SEEK;
raw_cmd.rate = floppy->rate & 0x3; raw_cmd.rate = floppy->rate & 0x3;
raw_cmd.cmd_count = NR_F; raw_cmd.cmd_count = NR_F;
COMMAND = FM_MODE(floppy,FD_FORMAT); COMMAND = FM_MODE(floppy,FD_FORMAT);
......
This diff is collapsed.
...@@ -514,4 +514,12 @@ int init_module(void) ...@@ -514,4 +514,12 @@ int init_module(void)
return 0; return 0;
} }
void cleanup_module(void)
{
if(MOD_IN_USE)
printk("lp: busy - remove delayed\n");
else
unregister_chrdev(LP_MAJOR,"lp");
}
#endif #endif
...@@ -54,7 +54,11 @@ config: configure /usr/include/sys/soundcard.h ...@@ -54,7 +54,11 @@ config: configure /usr/include/sys/soundcard.h
@echo \#define SOUND_CONFIG_DATE \"`date`\" >> local.h @echo \#define SOUND_CONFIG_DATE \"`date`\" >> local.h
@echo \#define SOUND_CONFIG_BY \"`whoami`\" >> local.h @echo \#define SOUND_CONFIG_BY \"`whoami`\" >> local.h
@echo \#define SOUND_CONFIG_HOST \"`hostname`\" >> local.h @echo \#define SOUND_CONFIG_HOST \"`hostname`\" >> local.h
@echo \#define SOUND_CONFIG_DOMAIN \"`domainname`\" >> local.h @if [ -x /bin/dnsdomainname ]; then \
echo \#define SOUND_CONFIG_DOMAIN \"`dnsdomainname`\"; \
else \
echo \#define SOUND_CONFIG_DOMAIN \"`domainname`\"; \
fi >> local.h
clrconf: clrconf:
rm -f local.h .depend rm -f local.h .depend
......
...@@ -612,8 +612,8 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -612,8 +612,8 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
current->mm->start_code = start_code; current->mm->start_code = start_code;
current->mm->end_data = end_data; current->mm->end_data = end_data;
current->mm->start_stack = bprm->p; current->mm->start_stack = bprm->p;
current->suid = current->euid = bprm->e_uid; current->suid = current->euid = current->fsuid = bprm->e_uid;
current->sgid = current->egid = bprm->e_gid; current->sgid = current->egid = current->fsgid = bprm->e_gid;
/* Calling sys_brk effectively mmaps the pages that we need for the bss and break /* Calling sys_brk effectively mmaps the pages that we need for the bss and break
sections */ sections */
......
...@@ -20,6 +20,9 @@ ...@@ -20,6 +20,9 @@
#include <linux/ext_fs.h> #include <linux/ext_fs.h>
#include <linux/stat.h> #include <linux/stat.h>
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
#define ROUND_UP(x) (((x)+3) & ~3)
static int ext_dir_read(struct inode * inode, struct file * filp, char * buf, int count) static int ext_dir_read(struct inode * inode, struct file * filp, char * buf, int count)
{ {
return -EISDIR; return -EISDIR;
...@@ -65,6 +68,7 @@ static int ext_readdir(struct inode * inode, struct file * filp, ...@@ -65,6 +68,7 @@ static int ext_readdir(struct inode * inode, struct file * filp,
struct dirent * dirent, int count) struct dirent * dirent, int count)
{ {
unsigned int i; unsigned int i;
unsigned int ret;
off_t offset; off_t offset;
char c; char c;
struct buffer_head * bh; struct buffer_head * bh;
...@@ -74,15 +78,23 @@ static int ext_readdir(struct inode * inode, struct file * filp, ...@@ -74,15 +78,23 @@ static int ext_readdir(struct inode * inode, struct file * filp,
return -EBADF; return -EBADF;
if ((filp->f_pos & 7) != 0) if ((filp->f_pos & 7) != 0)
return -EBADF; return -EBADF;
while (filp->f_pos < inode->i_size) { ret = 0;
while (!ret && filp->f_pos < inode->i_size) {
offset = filp->f_pos & 1023; offset = filp->f_pos & 1023;
bh = ext_bread(inode,(filp->f_pos)>>BLOCK_SIZE_BITS,0); bh = ext_bread(inode,(filp->f_pos)>>BLOCK_SIZE_BITS,0);
if (!bh) { if (!bh) {
filp->f_pos += 1024-offset; filp->f_pos += 1024-offset;
continue; continue;
} }
for (i = 0; i < 1024 && i < offset; ) {
de = (struct ext_dir_entry *) (bh->b_data + i);
if (!de->rec_len)
break;
i += de->rec_len;
}
offset = i;
de = (struct ext_dir_entry *) (offset + bh->b_data); de = (struct ext_dir_entry *) (offset + bh->b_data);
while (offset < 1024 && filp->f_pos < inode->i_size) { while (!ret && offset < 1024 && filp->f_pos < inode->i_size) {
if (de->rec_len < 8 || de->rec_len % 8 != 0 || if (de->rec_len < 8 || de->rec_len % 8 != 0 ||
de->rec_len < de->name_len + 8 || de->rec_len < de->name_len + 8 ||
(de->rec_len + (off_t) filp->f_pos - 1) / 1024 > ((off_t) filp->f_pos / 1024)) { (de->rec_len + (off_t) filp->f_pos - 1) / 1024 > ((off_t) filp->f_pos / 1024)) {
...@@ -106,8 +118,8 @@ static int ext_readdir(struct inode * inode, struct file * filp, ...@@ -106,8 +118,8 @@ static int ext_readdir(struct inode * inode, struct file * filp,
put_fs_long(de->inode,&dirent->d_ino); put_fs_long(de->inode,&dirent->d_ino);
put_fs_byte(0,i+dirent->d_name); put_fs_byte(0,i+dirent->d_name);
put_fs_word(i,&dirent->d_reclen); put_fs_word(i,&dirent->d_reclen);
brelse(bh); ret = ROUND_UP(NAME_OFFSET(dirent)+i+1);
return i; break;
} }
} }
de = (struct ext_dir_entry *) ((char *) de de = (struct ext_dir_entry *) ((char *) de
...@@ -115,5 +127,5 @@ static int ext_readdir(struct inode * inode, struct file * filp, ...@@ -115,5 +127,5 @@ static int ext_readdir(struct inode * inode, struct file * filp,
} }
brelse(bh); brelse(bh);
} }
return 0; return ret;
} }
...@@ -22,6 +22,9 @@ ...@@ -22,6 +22,9 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/stat.h> #include <linux/stat.h>
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
#define ROUND_UP(x) (((x)+3) & ~3)
static int ext2_dir_read (struct inode * inode, struct file * filp, static int ext2_dir_read (struct inode * inode, struct file * filp,
char * buf, int count) char * buf, int count)
{ {
...@@ -98,17 +101,21 @@ static int ext2_readdir (struct inode * inode, struct file * filp, ...@@ -98,17 +101,21 @@ static int ext2_readdir (struct inode * inode, struct file * filp,
struct dirent * dirent, int count) struct dirent * dirent, int count)
{ {
unsigned long offset, blk; unsigned long offset, blk;
int i, num; int i, num, stored, dlen;
struct buffer_head * bh, * tmp, * bha[16]; struct buffer_head * bh, * tmp, * bha[16];
struct ext2_dir_entry * de; struct ext2_dir_entry * de;
struct super_block * sb; struct super_block * sb;
int err; int err, version;
if (!inode || !S_ISDIR(inode->i_mode)) if (!inode || !S_ISDIR(inode->i_mode))
return -EBADF; return -EBADF;
sb = inode->i_sb; sb = inode->i_sb;
while (filp->f_pos < inode->i_size) {
offset = filp->f_pos & (sb->s_blocksize - 1); stored = 0;
bh = NULL;
offset = filp->f_pos & (sb->s_blocksize - 1);
while (count > 0 && !stored && filp->f_pos < inode->i_size) {
blk = (filp->f_pos) >> EXT2_BLOCK_SIZE_BITS(sb); blk = (filp->f_pos) >> EXT2_BLOCK_SIZE_BITS(sb);
bh = ext2_bread (inode, blk, 0, &err); bh = ext2_bread (inode, blk, 0, &err);
if (!bh) { if (!bh) {
...@@ -135,39 +142,78 @@ static int ext2_readdir (struct inode * inode, struct file * filp, ...@@ -135,39 +142,78 @@ static int ext2_readdir (struct inode * inode, struct file * filp,
} }
} }
de = (struct ext2_dir_entry *) (offset + bh->b_data); revalidate:
while (offset < sb->s_blocksize && filp->f_pos < inode->i_size) { /* If the dir block has changed since the last call to
readdir(2), then we might be pointing to an invalid dirent
right now. Scan from the start of the block to make
sure. */
for (i = 0; i < sb->s_blocksize && i < offset; ) {
de = (struct ext2_dir_entry *) (bh->b_data + i);
/* It's too expensive to do a full dirent test
* each time round this loop, but we do have
* to test at least that it is non-zero. A
* failure will be detected in the dirent test
* below. */
if (de->rec_len < EXT2_DIR_REC_LEN(1))
break;
i += de->rec_len;
}
offset = i;
filp->f_pos = (filp->f_pos & ~(sb->s_blocksize - 1)) | offset;
while (count > 0 && filp->f_pos < inode->i_size
&& offset < sb->s_blocksize) {
de = (struct ext2_dir_entry *) (bh->b_data + offset);
if (!ext2_check_dir_entry ("ext2_readdir", inode, de, if (!ext2_check_dir_entry ("ext2_readdir", inode, de,
bh, offset)) { bh, offset)) {
/* On error, skip the f_pos to the next block. */
filp->f_pos = (filp->f_pos & (sb->s_blocksize - 1))
+ sb->s_blocksize;
brelse (bh); brelse (bh);
return 0; return stored;
} }
offset += de->rec_len;
filp->f_pos += de->rec_len;
if (de->inode) { if (de->inode) {
memcpy_tofs (dirent->d_name, de->name, dlen = ROUND_UP(NAME_OFFSET(dirent)
de->name_len); + de->name_len + 1);
/* Old libc libraries always use a count of 1. */
if (count == 1 && !stored)
count = dlen;
if (count < dlen) {
count = 0;
break;
}
/* We might block in the next section
* if the data destination is
* currently swapped out. So, use a
* version stamp to detect whether or
* not the directory has been modified
* during the copy operation. */
version = inode->i_version;
i = de->name_len;
memcpy_tofs (dirent->d_name, de->name, i);
put_fs_long (de->inode, &dirent->d_ino); put_fs_long (de->inode, &dirent->d_ino);
put_fs_byte (0, de->name_len + dirent->d_name); put_fs_byte (0, dirent->d_name + i);
put_fs_word (de->name_len, &dirent->d_reclen); put_fs_word (i, &dirent->d_reclen);
put_fs_long (dlen, &dirent->d_off);
if (version != inode->i_version)
goto revalidate;
dcache_add(inode, de->name, de->name_len, dcache_add(inode, de->name, de->name_len,
de->inode); de->inode);
i = de->name_len;
brelse (bh); stored += dlen;
if (!IS_RDONLY(inode)) { count -= dlen;
inode->i_atime = CURRENT_TIME; ((char *) dirent) += dlen;
inode->i_dirt = 1;
}
return i;
} }
de = (struct ext2_dir_entry *) ((char *) de + offset += de->rec_len;
de->rec_len); filp->f_pos += de->rec_len;
} }
offset = 0;
brelse (bh); brelse (bh);
} }
if (!IS_RDONLY(inode)) { if (!IS_RDONLY(inode)) {
inode->i_atime = CURRENT_TIME; inode->i_atime = CURRENT_TIME;
inode->i_dirt = 1; inode->i_dirt = 1;
} }
return 0; return stored;
} }
...@@ -318,6 +318,7 @@ static struct buffer_head * ext2_add_entry (struct inode * dir, ...@@ -318,6 +318,7 @@ static struct buffer_head * ext2_add_entry (struct inode * dir,
*/ */
dir->i_mtime = dir->i_ctime = CURRENT_TIME; dir->i_mtime = dir->i_ctime = CURRENT_TIME;
dir->i_dirt = 1; dir->i_dirt = 1;
dir->i_version = ++event;
mark_buffer_dirty(bh, 1); mark_buffer_dirty(bh, 1);
*res_dir = de; *res_dir = de;
*err = 0; *err = 0;
...@@ -923,8 +924,10 @@ static int do_ext2_rename (struct inode * old_dir, const char * old_name, ...@@ -923,8 +924,10 @@ static int do_ext2_rename (struct inode * old_dir, const char * old_name,
goto start_up; goto start_up;
try_again: try_again:
if (new_bh && new_de) if (new_bh && new_de) {
ext2_delete_entry(new_de, new_bh); ext2_delete_entry(new_de, new_bh);
new_dir->i_version = ++event;
}
brelse (old_bh); brelse (old_bh);
brelse (new_bh); brelse (new_bh);
brelse (dir_bh); brelse (dir_bh);
...@@ -1002,6 +1005,7 @@ static int do_ext2_rename (struct inode * old_dir, const char * old_name, ...@@ -1002,6 +1005,7 @@ static int do_ext2_rename (struct inode * old_dir, const char * old_name,
&retval); &retval);
if (!new_bh) if (!new_bh)
goto end_rename; goto end_rename;
new_dir->i_version = ++event;
/* /*
* sanity checking before doing the rename - avoid races * sanity checking before doing the rename - avoid races
*/ */
...@@ -1015,7 +1019,6 @@ static int do_ext2_rename (struct inode * old_dir, const char * old_name, ...@@ -1015,7 +1019,6 @@ static int do_ext2_rename (struct inode * old_dir, const char * old_name,
* ok, that's it * ok, that's it
*/ */
new_de->inode = old_inode->i_ino; new_de->inode = old_inode->i_ino;
new_dir->i_version = ++event;
dcache_add(new_dir, new_de->name, new_de->name_len, new_de->inode); dcache_add(new_dir, new_de->name, new_de->name_len, new_de->inode);
retval = ext2_delete_entry (old_de, old_bh); retval = ext2_delete_entry (old_de, old_bh);
if (retval == -ENOENT) if (retval == -ENOENT)
......
...@@ -117,6 +117,9 @@ ...@@ -117,6 +117,9 @@
/* notation */ /* notation */
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
#define ROUND_UP(x) (((x)+3) & ~3)
#define little_ushort(x) (*(unsigned short *) &(x)) #define little_ushort(x) (*(unsigned short *) &(x))
typedef void nonconst; typedef void nonconst;
...@@ -1345,13 +1348,13 @@ static int hpfs_readdir(struct inode *inode, struct file *filp, ...@@ -1345,13 +1348,13 @@ static int hpfs_readdir(struct inode *inode, struct file *filp,
case 0: case 0:
write_one_dirent(dirent, ".", 1, inode->i_ino, lc); write_one_dirent(dirent, ".", 1, inode->i_ino, lc);
filp->f_pos = -1; filp->f_pos = -1;
return 1; return ROUND_UP(NAME_OFFSET(dirent) + 2);
case -1: case -1:
write_one_dirent(dirent, "..", 2, write_one_dirent(dirent, "..", 2,
inode->i_hpfs_parent_dir, lc); inode->i_hpfs_parent_dir, lc);
filp->f_pos = 1; filp->f_pos = 1;
return 2; return ROUND_UP(NAME_OFFSET(dirent) + 3);
case -2: case -2:
return 0; return 0;
...@@ -1371,7 +1374,7 @@ static int hpfs_readdir(struct inode *inode, struct file *filp, ...@@ -1371,7 +1374,7 @@ static int hpfs_readdir(struct inode *inode, struct file *filp,
write_one_dirent(dirent, de->name, namelen, ino, lc); write_one_dirent(dirent, de->name, namelen, ino, lc);
brelse4(&qbh); brelse4(&qbh);
return namelen; return ROUND_UP(NAME_OFFSET(dirent) + namelen + 1);
} }
} }
......
...@@ -22,6 +22,9 @@ ...@@ -22,6 +22,9 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/locks.h> #include <linux/locks.h>
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
#define ROUND_UP(x) (((x)+3) & ~3)
static int isofs_readdir(struct inode *, struct file *, struct dirent *, int); static int isofs_readdir(struct inode *, struct file *, struct dirent *, int);
static struct file_operations isofs_dir_operations = { static struct file_operations isofs_dir_operations = {
...@@ -228,7 +231,7 @@ static int isofs_readdir(struct inode * inode, struct file * filp, ...@@ -228,7 +231,7 @@ static int isofs_readdir(struct inode * inode, struct file * filp,
put_fs_byte(0,i+dirent->d_name); put_fs_byte(0,i+dirent->d_name);
put_fs_word(i,&dirent->d_reclen); put_fs_word(i,&dirent->d_reclen);
brelse(bh); brelse(bh);
return i; return ROUND_UP(NAME_OFFSET(dirent) + i + 1);
} }
} }
/* We go here for any condition we cannot handle. We also drop through /* We go here for any condition we cannot handle. We also drop through
......
...@@ -13,6 +13,9 @@ ...@@ -13,6 +13,9 @@
#include <linux/minix_fs.h> #include <linux/minix_fs.h>
#include <linux/stat.h> #include <linux/stat.h>
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
#define ROUND_UP(x) (((x)+3) & ~3)
static int minix_dir_read(struct inode * inode, struct file * filp, char * buf, int count) static int minix_dir_read(struct inode * inode, struct file * filp, char * buf, int count)
{ {
return -EISDIR; return -EISDIR;
...@@ -57,7 +60,8 @@ struct inode_operations minix_dir_inode_operations = { ...@@ -57,7 +60,8 @@ struct inode_operations minix_dir_inode_operations = {
static int minix_readdir(struct inode * inode, struct file * filp, static int minix_readdir(struct inode * inode, struct file * filp,
struct dirent * dirent, int count) struct dirent * dirent, int count)
{ {
unsigned int offset,i; unsigned int offset,i,ret;
int version;
char c; char c;
struct buffer_head * bh; struct buffer_head * bh;
struct minix_dir_entry * de; struct minix_dir_entry * de;
...@@ -68,17 +72,19 @@ static int minix_readdir(struct inode * inode, struct file * filp, ...@@ -68,17 +72,19 @@ static int minix_readdir(struct inode * inode, struct file * filp,
info = &inode->i_sb->u.minix_sb; info = &inode->i_sb->u.minix_sb;
if (filp->f_pos & (info->s_dirsize - 1)) if (filp->f_pos & (info->s_dirsize - 1))
return -EBADF; return -EBADF;
while (filp->f_pos < inode->i_size) { ret = 0;
while (!ret && filp->f_pos < inode->i_size) {
offset = filp->f_pos & 1023; offset = filp->f_pos & 1023;
bh = minix_bread(inode,(filp->f_pos)>>BLOCK_SIZE_BITS,0); bh = minix_bread(inode,(filp->f_pos)>>BLOCK_SIZE_BITS,0);
if (!bh) { if (!bh) {
filp->f_pos += 1024-offset; filp->f_pos += 1024-offset;
continue; continue;
} }
while (offset < 1024 && filp->f_pos < inode->i_size) { while (!ret && offset < 1024 && filp->f_pos < inode->i_size) {
de = (struct minix_dir_entry *) (offset + bh->b_data); de = (struct minix_dir_entry *) (offset + bh->b_data);
offset += info->s_dirsize; offset += info->s_dirsize;
filp->f_pos += info->s_dirsize; filp->f_pos += info->s_dirsize;
retry:
if (de->inode) { if (de->inode) {
for (i = 0; i < info->s_namelen; i++) for (i = 0; i < info->s_namelen; i++)
if ((c = de->name[i]) != 0) if ((c = de->name[i]) != 0)
...@@ -86,15 +92,17 @@ static int minix_readdir(struct inode * inode, struct file * filp, ...@@ -86,15 +92,17 @@ static int minix_readdir(struct inode * inode, struct file * filp,
else else
break; break;
if (i) { if (i) {
version = inode->i_version;
put_fs_long(de->inode,&dirent->d_ino); put_fs_long(de->inode,&dirent->d_ino);
put_fs_byte(0,i+dirent->d_name); put_fs_byte(0,i+dirent->d_name);
put_fs_word(i,&dirent->d_reclen); put_fs_word(i,&dirent->d_reclen);
brelse(bh); if (version != inode->i_version)
return i; goto retry;
ret = ROUND_UP(NAME_OFFSET(dirent)+i+1);
} }
} }
} }
brelse(bh); brelse(bh);
} }
return 0; return ret;
} }
...@@ -195,6 +195,7 @@ static int minix_add_entry(struct inode * dir, ...@@ -195,6 +195,7 @@ static int minix_add_entry(struct inode * dir,
dir->i_mtime = dir->i_ctime = CURRENT_TIME; dir->i_mtime = dir->i_ctime = CURRENT_TIME;
for (i = 0; i < info->s_namelen ; i++) for (i = 0; i < info->s_namelen ; i++)
de->name[i] = (i < namelen) ? name[i] : 0; de->name[i] = (i < namelen) ? name[i] : 0;
dir->i_version = ++event;
mark_buffer_dirty(bh, 1); mark_buffer_dirty(bh, 1);
*res_dir = de; *res_dir = de;
break; break;
...@@ -470,11 +471,12 @@ int minix_rmdir(struct inode * dir, const char * name, int len) ...@@ -470,11 +471,12 @@ int minix_rmdir(struct inode * dir, const char * name, int len)
if (inode->i_nlink != 2) if (inode->i_nlink != 2)
printk("empty directory has nlink!=2 (%d)\n",inode->i_nlink); printk("empty directory has nlink!=2 (%d)\n",inode->i_nlink);
de->inode = 0; de->inode = 0;
dir->i_version = ++event;
mark_buffer_dirty(bh, 1); mark_buffer_dirty(bh, 1);
inode->i_nlink=0; inode->i_nlink=0;
inode->i_dirt=1; inode->i_dirt=1;
dir->i_nlink--;
inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
dir->i_nlink--;
dir->i_dirt=1; dir->i_dirt=1;
retval = 0; retval = 0;
end_rmdir: end_rmdir:
...@@ -523,6 +525,7 @@ int minix_unlink(struct inode * dir, const char * name, int len) ...@@ -523,6 +525,7 @@ int minix_unlink(struct inode * dir, const char * name, int len)
inode->i_nlink=1; inode->i_nlink=1;
} }
de->inode = 0; de->inode = 0;
dir->i_version = ++event;
mark_buffer_dirty(bh, 1); mark_buffer_dirty(bh, 1);
dir->i_ctime = dir->i_mtime = CURRENT_TIME; dir->i_ctime = dir->i_mtime = CURRENT_TIME;
dir->i_dirt = 1; dir->i_dirt = 1;
...@@ -768,8 +771,10 @@ static int do_minix_rename(struct inode * old_dir, const char * old_name, int ol ...@@ -768,8 +771,10 @@ static int do_minix_rename(struct inode * old_dir, const char * old_name, int ol
new_de->inode = old_inode->i_ino; new_de->inode = old_inode->i_ino;
old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME; old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
old_dir->i_dirt = 1; old_dir->i_dirt = 1;
old_dir->i_version = ++event;
new_dir->i_ctime = new_dir->i_mtime = CURRENT_TIME; new_dir->i_ctime = new_dir->i_mtime = CURRENT_TIME;
new_dir->i_dirt = 1; new_dir->i_dirt = 1;
new_dir->i_version = ++event;
if (new_inode) { if (new_inode) {
new_inode->i_nlink--; new_inode->i_nlink--;
new_inode->i_ctime = CURRENT_TIME; new_inode->i_ctime = CURRENT_TIME;
......
...@@ -14,6 +14,9 @@ ...@@ -14,6 +14,9 @@
#include <linux/stat.h> #include <linux/stat.h>
#include <linux/string.h> #include <linux/string.h>
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
#define ROUND_UP(x) (((x)+3) & ~3)
static int msdos_dir_read(struct inode * inode,struct file * filp, char * buf,int count) static int msdos_dir_read(struct inode * inode,struct file * filp, char * buf,int count)
{ {
...@@ -73,7 +76,7 @@ int msdos_readdir( ...@@ -73,7 +76,7 @@ int msdos_readdir(
put_fs_long(MSDOS_ROOT_INO,&dirent->d_ino); put_fs_long(MSDOS_ROOT_INO,&dirent->d_ino);
put_fs_byte(0,dirent->d_name+i); put_fs_byte(0,dirent->d_name+i);
put_fs_word(i,&dirent->d_reclen); put_fs_word(i,&dirent->d_reclen);
return i; return ROUND_UP(NAME_OFFSET(dirent) + i + 1);
} }
} }
if (filp->f_pos & (sizeof(struct msdos_dir_entry)-1)) return -ENOENT; if (filp->f_pos & (sizeof(struct msdos_dir_entry)-1)) return -ENOENT;
...@@ -110,7 +113,7 @@ int msdos_readdir( ...@@ -110,7 +113,7 @@ int msdos_readdir(
memcpy_tofs(dirent->d_name,bufname,i+1); memcpy_tofs(dirent->d_name,bufname,i+1);
put_fs_word(i,&dirent->d_reclen); put_fs_word(i,&dirent->d_reclen);
brelse(bh); brelse(bh);
return i; return ROUND_UP(NAME_OFFSET(dirent) + i + 1);
} }
} }
} }
......
...@@ -18,6 +18,9 @@ ...@@ -18,6 +18,9 @@
#include <asm/segment.h> /* for fs functions */ #include <asm/segment.h> /* for fs functions */
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
#define ROUND_UP(x) (((x)+3) & ~3)
static int nfs_dir_read(struct inode *, struct file *filp, char *buf, static int nfs_dir_read(struct inode *, struct file *filp, char *buf,
int count); int count);
static int nfs_readdir(struct inode *, struct file *, struct dirent *, int); static int nfs_readdir(struct inode *, struct file *, struct dirent *, int);
...@@ -153,7 +156,7 @@ static int nfs_readdir(struct inode *inode, struct file *filp, ...@@ -153,7 +156,7 @@ static int nfs_readdir(struct inode *inode, struct file *filp,
put_fs_long(entry->fileid, &dirent->d_ino); put_fs_long(entry->fileid, &dirent->d_ino);
put_fs_word(i, &dirent->d_reclen); put_fs_word(i, &dirent->d_reclen);
filp->f_pos = entry->cookie; filp->f_pos = entry->cookie;
return i; return ROUND_UP(NAME_OFFSET(dirent)+i+1);
} }
return 0; return 0;
} }
......
...@@ -92,7 +92,8 @@ static int proc_fd_dupf(struct inode * inode, struct file * f) ...@@ -92,7 +92,8 @@ static int proc_fd_dupf(struct inode * inode, struct file * f)
new_f->f_count++; new_f->f_count++;
current->files->fd[fd] = new_f; current->files->fd[fd] = new_f;
f->f_count--; if (!--f->f_count)
iput(f->f_inode);
return 0; return 0;
} }
......
...@@ -13,8 +13,14 @@ ...@@ -13,8 +13,14 @@
#include <asm/segment.h> #include <asm/segment.h>
/* /*
* Count is not yet used: but we'll probably support reading several entries * Count is now a supported feature, but currently only the ext2fs
* at once in the future. Use count=1 in the library for future expansions. * uses it. A count value of 1 is supported for compatibility with
* earlier libraries, but larger values are supported: count should
* indicate the total buffer space available for filling with dirents.
* The d_off entry in the dirents will then indicate the offset from
* each dirent to the next, and the return value will indicate the
* number of bytes written. All dirents will be written at
* word-aligned addresses. [sct Oct 1994]
*/ */
asmlinkage int sys_readdir(unsigned int fd, struct dirent * dirent, unsigned int count) asmlinkage int sys_readdir(unsigned int fd, struct dirent * dirent, unsigned int count)
{ {
...@@ -62,8 +68,10 @@ asmlinkage int sys_lseek(unsigned int fd, off_t offset, unsigned int origin) ...@@ -62,8 +68,10 @@ asmlinkage int sys_lseek(unsigned int fd, off_t offset, unsigned int origin)
} }
if (tmp < 0) if (tmp < 0)
return -EINVAL; return -EINVAL;
file->f_pos = tmp; if (tmp != file->f_pos) {
file->f_reada = 0; file->f_pos = tmp;
file->f_reada = 0;
}
return file->f_pos; return file->f_pos;
} }
......
...@@ -20,6 +20,9 @@ ...@@ -20,6 +20,9 @@
#include <linux/sysv_fs.h> #include <linux/sysv_fs.h>
#include <linux/stat.h> #include <linux/stat.h>
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
#define ROUND_UP(x) (((x)+3) & ~3)
static int sysv_dir_read(struct inode * inode, struct file * filp, char * buf, int count) static int sysv_dir_read(struct inode * inode, struct file * filp, char * buf, int count)
{ {
return -EISDIR; return -EISDIR;
...@@ -100,7 +103,7 @@ static int sysv_readdir(struct inode * inode, struct file * filp, ...@@ -100,7 +103,7 @@ static int sysv_readdir(struct inode * inode, struct file * filp,
put_fs_byte(0,i+dirent->d_name); put_fs_byte(0,i+dirent->d_name);
put_fs_word(i,&dirent->d_reclen); put_fs_word(i,&dirent->d_reclen);
brelse(bh); brelse(bh);
return i; return ROUND_UP(NAME_OFFSET(dirent)+i+1);
} }
} }
} }
......
...@@ -19,6 +19,9 @@ ...@@ -19,6 +19,9 @@
#include "xiafs_mac.h" #include "xiafs_mac.h"
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
#define ROUND_UP(x) (((x)+3) & ~3)
static int xiafs_dir_read(struct inode *, struct file *, char *, int); static int xiafs_dir_read(struct inode *, struct file *, char *, int);
static int xiafs_readdir(struct inode *, struct file *, struct dirent *, int); static int xiafs_readdir(struct inode *, struct file *, struct dirent *, int);
...@@ -65,7 +68,7 @@ static int xiafs_dir_read(struct inode * inode, ...@@ -65,7 +68,7 @@ static int xiafs_dir_read(struct inode * inode,
static int xiafs_readdir(struct inode * inode, static int xiafs_readdir(struct inode * inode,
struct file * filp, struct dirent * dirent, int count) struct file * filp, struct dirent * dirent, int count)
{ {
u_int offset, i; u_int offset, i,ret;
struct buffer_head * bh; struct buffer_head * bh;
struct xiafs_direct * de; struct xiafs_direct * de;
...@@ -73,15 +76,24 @@ static int xiafs_readdir(struct inode * inode, ...@@ -73,15 +76,24 @@ static int xiafs_readdir(struct inode * inode,
return -EBADF; return -EBADF;
if (inode->i_size & (XIAFS_ZSIZE(inode->i_sb) - 1) ) if (inode->i_size & (XIAFS_ZSIZE(inode->i_sb) - 1) )
return -EBADF; return -EBADF;
while (filp->f_pos < inode->i_size) { ret = 0;
while (!ret && filp->f_pos < inode->i_size) {
offset = filp->f_pos & (XIAFS_ZSIZE(inode->i_sb) - 1); offset = filp->f_pos & (XIAFS_ZSIZE(inode->i_sb) - 1);
bh = xiafs_bread(inode, filp->f_pos >> XIAFS_ZSIZE_BITS(inode->i_sb),0); bh = xiafs_bread(inode, filp->f_pos >> XIAFS_ZSIZE_BITS(inode->i_sb),0);
if (!bh) { if (!bh) {
filp->f_pos += XIAFS_ZSIZE(inode->i_sb)-offset; filp->f_pos += XIAFS_ZSIZE(inode->i_sb)-offset;
continue; continue;
} }
for (i = 0; i < XIAFS_ZSIZE(inode->i_sb) && i < offset; ) {
de = (struct xiafs_direct *) (bh->b_data + i);
if (!de->d_rec_len)
break;
i += de->d_rec_len;
}
offset = i;
de = (struct xiafs_direct *) (offset + bh->b_data); de = (struct xiafs_direct *) (offset + bh->b_data);
while (offset < XIAFS_ZSIZE(inode->i_sb) && filp->f_pos < inode->i_size) {
while (!ret && offset < XIAFS_ZSIZE(inode->i_sb) && filp->f_pos < inode->i_size) {
if (de->d_ino > inode->i_sb->u.xiafs_sb.s_ninodes || if (de->d_ino > inode->i_sb->u.xiafs_sb.s_ninodes ||
de->d_rec_len < 12 || de->d_rec_len < 12 ||
(char *)de+de->d_rec_len > XIAFS_ZSIZE(inode->i_sb)+bh->b_data || (char *)de+de->d_rec_len > XIAFS_ZSIZE(inode->i_sb)+bh->b_data ||
...@@ -100,12 +112,12 @@ static int xiafs_readdir(struct inode * inode, ...@@ -100,12 +112,12 @@ static int xiafs_readdir(struct inode * inode,
put_fs_byte(0,i+dirent->d_name); put_fs_byte(0,i+dirent->d_name);
put_fs_long(de->d_ino,&dirent->d_ino); put_fs_long(de->d_ino,&dirent->d_ino);
put_fs_word(i,&dirent->d_reclen); put_fs_word(i,&dirent->d_reclen);
brelse(bh);
if (!IS_RDONLY (inode)) { if (!IS_RDONLY (inode)) {
inode->i_atime=CURRENT_TIME; inode->i_atime=CURRENT_TIME;
inode->i_dirt=1; inode->i_dirt=1;
} }
return i; ret = ROUND_UP(NAME_OFFSET(dirent)+i+1);
break;
} }
de = (struct xiafs_direct *) (offset + bh->b_data); de = (struct xiafs_direct *) (offset + bh->b_data);
} }
......
...@@ -71,7 +71,6 @@ struct hd_geometry { ...@@ -71,7 +71,6 @@ struct hd_geometry {
#define HDIO_SETUNMASKINTR 0x303 #define HDIO_SETUNMASKINTR 0x303
#define HDIO_GETMULTCOUNT 0x304 #define HDIO_GETMULTCOUNT 0x304
#define HDIO_SETMULTCOUNT 0x305 #define HDIO_SETMULTCOUNT 0x305
#define HDIO_SETFEATURE 0x306
#define HDIO_GETIDENTITY 0x307 #define HDIO_GETIDENTITY 0x307
#endif #endif
......
...@@ -289,6 +289,7 @@ extern void stop_tty(struct tty_struct * tty); ...@@ -289,6 +289,7 @@ extern void stop_tty(struct tty_struct * tty);
extern void start_tty(struct tty_struct * tty); extern void start_tty(struct tty_struct * tty);
extern int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc); extern int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc);
extern int tty_register_driver(struct tty_driver *driver); extern int tty_register_driver(struct tty_driver *driver);
extern int tty_unregister_driver(struct tty_driver *driver);
extern int tty_read_raw_data(struct tty_struct *tty, unsigned char *bufp, extern int tty_read_raw_data(struct tty_struct *tty, unsigned char *bufp,
int buflen); int buflen);
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/termios.h> #include <linux/termios.h>
#include <linux/tqueue.h> #include <linux/tqueue.h>
#include <linux/tty.h>
#include <linux/serial.h> #include <linux/serial.h>
#ifdef CONFIG_INET #ifdef CONFIG_INET
#include <linux/netdevice.h> #include <linux/netdevice.h>
...@@ -91,6 +92,9 @@ struct symbol_table symbol_table = { 0, 0, 0, /* for stacked module support */ ...@@ -91,6 +92,9 @@ struct symbol_table symbol_table = { 0, 0, 0, /* for stacked module support */
X(unregister_chrdev), X(unregister_chrdev),
X(register_blkdev), X(register_blkdev),
X(unregister_blkdev), X(unregister_blkdev),
X(tty_register_driver),
X(tty_unregister_driver),
X(tty_std_termios),
/* block device driver support */ /* block device driver support */
X(block_read), X(block_read),
......
...@@ -83,6 +83,7 @@ ...@@ -83,6 +83,7 @@
* Matt Dillon : Yet more small nasties remove from the TCP code * Matt Dillon : Yet more small nasties remove from the TCP code
* (Be very nice to this man if tcp finally works 100%) 8) * (Be very nice to this man if tcp finally works 100%) 8)
* Alan Cox : BSD accept semantics. * Alan Cox : BSD accept semantics.
* Peter De Schrijver : ENOTCONN check missing in tcp_sendto().
* *
* *
* To Fix: * To Fix:
...@@ -1221,15 +1222,17 @@ static int tcp_sendto(struct sock *sk, unsigned char *from, ...@@ -1221,15 +1222,17 @@ static int tcp_sendto(struct sock *sk, unsigned char *from,
{ {
if (flags & ~(MSG_OOB|MSG_DONTROUTE)) if (flags & ~(MSG_OOB|MSG_DONTROUTE))
return -EINVAL; return -EINVAL;
if (addr_len < sizeof(*addr)) if (!tcp_connected(sk->state))
return(-EINVAL); return -ENOTCONN;
if (addr_len < sizeof(*addr))
return -EINVAL;
if (addr->sin_family && addr->sin_family != AF_INET) if (addr->sin_family && addr->sin_family != AF_INET)
return(-EINVAL); return -EINVAL;
if (addr->sin_port != sk->dummy_th.dest) if (addr->sin_port != sk->dummy_th.dest)
return(-EISCONN); return -EISCONN;
if (addr->sin_addr.s_addr != sk->daddr) if (addr->sin_addr.s_addr != sk->daddr)
return(-EISCONN); return -EISCONN;
return(tcp_write(sk, from, len, nonblock, flags)); return tcp_write(sk, from, len, nonblock, flags);
} }
...@@ -2238,7 +2241,7 @@ static void tcp_close(struct sock *sk, int timeout) ...@@ -2238,7 +2241,7 @@ static void tcp_close(struct sock *sk, int timeout)
/* The +1 is not needed because the FIN takes up seq /* The +1 is not needed because the FIN takes up seq
is not read!!! */ is not read!!! */
if(skb->len > 0 && after(skb->h.th->seq + skb->len , sk->copied_seq)) if(skb->len > 0 && after(skb->h.th->seq + skb->len , sk->copied_seq))
need_reset = 1; need_reset = 0;
kfree_skb(skb, FREE_READ); kfree_skb(skb, FREE_READ);
} }
if(sk->debug) if(sk->debug)
......
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