diff --git a/Makefile b/Makefile
index fd6884d..4edfab1 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 4
SUBLEVEL = 33
-EXTRAVERSION =
+EXTRAVERSION = .4
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S
index 34125f6..340a66a 100644
--- a/arch/ppc/kernel/head.S
+++ b/arch/ppc/kernel/head.S
@@ -1705,6 +1705,8 @@ ppc970_setup_hid:
mfspr r0,SPRN_HID0
li r11,5 /* clear DOZE and SLEEP */
rldimi r0,r11,52,8 /* and set NAP and DPM */
+ li r11,0
+ rldimi r0,r11,32,31 /* clear EN_ATTN */
mtspr SPRN_HID0,r0
mfspr r0,SPRN_HID0
mfspr r0,SPRN_HID0
diff --git a/arch/s390/lib/uaccess.S b/arch/s390/lib/uaccess.S
index 1490bc6..6207032 100644
--- a/arch/s390/lib/uaccess.S
+++ b/arch/s390/lib/uaccess.S
@@ -19,8 +19,8 @@ __copy_from_user_asm:
sacf 512
0: mvcle %r2,%r4,0
jo 0b
-1: sacf 0
lr %r2,%r5
+1: sacf 0
br %r14
2: lhi %r1,-4096
lr %r3,%r4
@@ -28,17 +28,23 @@ __copy_from_user_asm:
nr %r3,%r1 # %r3 = (%r4 + 4096) & -4096
slr %r3,%r4 # %r3 = #bytes to next user page boundary
clr %r5,%r3 # copy crosses next page boundary ?
- jnh 1b # no, this page fauled
+ jnh 4f # no, this page faulted
# The page after the current user page might have faulted.
- # We cant't find out which page because the program check handler
- # might have callled schedule, destroying all lowcore information.
+ # We can't find out which page because the program check handler
+ # might have called schedule, destroying all lowcore information.
# We retry with the shortened length.
3: mvcle %r2,%r4,0
jo 3b
+4: lr %r1,%r5 # pad remaining bytes with 0
+ lr %r3,%r5
+ slr %r5,%r5
+5: mvcle %r2,%r4,0
+ jo 5b
+ lr %r2,%r1
j 1b
.section __ex_table,"a"
.long 0b,2b
- .long 3b,1b
+ .long 3b,4b
.previous
.align 4
diff --git a/arch/s390x/lib/uaccess.S b/arch/s390x/lib/uaccess.S
index 7e90f20..9916621 100644
--- a/arch/s390x/lib/uaccess.S
+++ b/arch/s390x/lib/uaccess.S
@@ -19,8 +19,8 @@ __copy_from_user_asm:
sacf 512
0: mvcle %r2,%r4,0
jo 0b
-1: sacf 0
lgr %r2,%r5
+1: sacf 0
br %r14
2: lghi %r1,-4096
lgr %r3,%r4
@@ -28,17 +28,23 @@ __copy_from_user_asm:
ngr %r3,%r1 # %r3 = (%r4 + 4096) & -4096
slgr %r3,%r4 # %r3 = #bytes to next user page boundary
clgr %r5,%r3 # copy crosses next page boundary ?
- jnh 1b # no, this page fauled
+ jnh 4f # no, this page faulted
# The page after the current user page might have faulted.
- # We cant't find out which page because the program check handler
- # might have callled schedule, destroying all lowcore information.
+ # We can't find out which page because the program check handler
+ # might have called schedule, destroying all lowcore information.
# We retry with the shortened length.
3: mvcle %r2,%r4,0
jo 3b
+4: lgr %r1,%r5 # pad remaining bytes with 0
+ lgr %r3,%r5
+ slgr %r5,%r5
+5: mvcle %r2,%r4,0
+ jo 5b
+ lgr %r2,%r1
j 1b
.section __ex_table,"a"
.quad 0b,2b
- .quad 3b,1b
+ .quad 3b,4b
.previous
.align 4
diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c
index 1c08204..f5058fe 100644
--- a/arch/sparc/kernel/sparc_ksyms.c
+++ b/arch/sparc/kernel/sparc_ksyms.c
@@ -297,6 +297,7 @@ EXPORT_SYMBOL_NOVERS(memcmp);
EXPORT_SYMBOL_NOVERS(memcpy);
EXPORT_SYMBOL_NOVERS(memset);
EXPORT_SYMBOL_NOVERS(memmove);
+EXPORT_SYMBOL_NOVERS(memchr);
EXPORT_SYMBOL_NOVERS(__ashrdi3);
EXPORT_SYMBOL_NOVERS(__ashldi3);
EXPORT_SYMBOL_NOVERS(__lshrdi3);
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index 0f1f31f..40accab 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -359,6 +359,7 @@ EXPORT_SYMBOL_NOVERS(__ret_efault);
/* No version information on these, as gcc produces such symbols. */
EXPORT_SYMBOL_NOVERS(memcmp);
EXPORT_SYMBOL_NOVERS(memcpy);
+EXPORT_SYMBOL_NOVERS(memchr);
EXPORT_SYMBOL_NOVERS(memset);
EXPORT_SYMBOL_NOVERS(memmove);
diff --git a/arch/x86_64/lib/delay.c b/arch/x86_64/lib/delay.c
index cc845d2..91345ee 100644
--- a/arch/x86_64/lib/delay.c
+++ b/arch/x86_64/lib/delay.c
@@ -19,7 +19,7 @@
void __delay(unsigned long loops)
{
- unsigned long bclock, now;
+ unsigned bclock, now;
rdtscl(bclock);
do
diff --git a/crypto/cipher.c b/crypto/cipher.c
index 6ab56eb..9b03eda 100644
--- a/crypto/cipher.c
+++ b/crypto/cipher.c
@@ -147,6 +147,15 @@ static int ecb_encrypt(struct crypto_tfm
ecb_process, 1, NULL);
}
+static int ecb_encrypt_iv(struct crypto_tfm *tfm,
+ struct scatterlist *dst,
+ struct scatterlist *src,
+ unsigned int nbytes, u8 *iv)
+{
+ ecb_encrypt(tfm, dst, src, nbytes);
+ return -ENOSYS;
+}
+
static int ecb_decrypt(struct crypto_tfm *tfm,
struct scatterlist *dst,
struct scatterlist *src,
@@ -157,6 +166,15 @@ static int ecb_decrypt(struct crypto_tfm
ecb_process, 1, NULL);
}
+static int ecb_decrypt_iv(struct crypto_tfm *tfm,
+ struct scatterlist *dst,
+ struct scatterlist *src,
+ unsigned int nbytes, u8 *iv)
+{
+ ecb_decrypt(tfm, dst, src, nbytes);
+ return -ENOSYS;
+}
+
static int cbc_encrypt(struct crypto_tfm *tfm,
struct scatterlist *dst,
struct scatterlist *src,
@@ -197,11 +215,20 @@ static int cbc_decrypt_iv(struct crypto_
cbc_process, 0, iv);
}
+/*
+ * nocrypt*() zeroize the destination buffer to make sure we don't leak
+ * uninitialized memory contents if the caller ignores the return value.
+ * This is bad since the data in the source buffer is unused and may be
+ * lost, but an infoleak would be even worse. The performance cost of
+ * memset() is irrelevant since a well-behaved caller would not bump into
+ * the error repeatedly.
+ */
static int nocrypt(struct crypto_tfm *tfm,
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes)
{
+ memset(dst, 0, nbytes);
return -ENOSYS;
}
@@ -210,6 +237,7 @@ static int nocrypt_iv(struct crypto_tfm
struct scatterlist *src,
unsigned int nbytes, u8 *iv)
{
+ memset(dst, 0, nbytes);
return -ENOSYS;
}
@@ -235,6 +263,11 @@ int crypto_init_cipher_ops(struct crypto
case CRYPTO_TFM_MODE_ECB:
ops->cit_encrypt = ecb_encrypt;
ops->cit_decrypt = ecb_decrypt;
+/* These should have been nocrypt_iv, but patch-cryptoloop-jari-2.4.22.0
+ * (and its other revisions) directly calls the *_iv() functions even in
+ * ECB mode and ignores their return value. */
+ ops->cit_encrypt_iv = ecb_encrypt_iv;
+ ops->cit_decrypt_iv = ecb_decrypt_iv;
break;
case CRYPTO_TFM_MODE_CBC:
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
index cb5a3bb..085c855 100644
--- a/drivers/block/cciss_scsi.c
+++ b/drivers/block/cciss_scsi.c
@@ -49,7 +49,7 @@ static int sendcmd(
unsigned char *scsi3addr );
-int __init cciss_scsi_detect(Scsi_Host_Template *tpnt);
+int cciss_scsi_detect(Scsi_Host_Template *tpnt);
int cciss_scsi_release(struct Scsi_Host *sh);
const char *cciss_scsi_info(struct Scsi_Host *sa);
@@ -777,7 +777,7 @@ complete_scsi_command( CommandList_struc
The scsi mid layer (scsi_register_module) is
called from cciss.c:cciss_init_one(). */
-int __init
+int
cciss_scsi_detect(Scsi_Host_Template *tpnt)
{
int i;
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
index 3924b24..c259cee 100644
--- a/drivers/block/ll_rw_blk.c
+++ b/drivers/block/ll_rw_blk.c
@@ -575,6 +575,7 @@ static struct request *get_request(reque
rq->rq_status = RQ_ACTIVE;
rq->cmd = rw;
rq->special = NULL;
+ rq->io_account = 0;
rq->q = q;
}
@@ -813,6 +814,7 @@ void req_new_io(struct request *req, int
struct hd_struct *hd1, *hd2;
locate_hd_struct(req, &hd1, &hd2);
+ req->io_account = 1;
if (hd1)
account_io_start(hd1, req, merge, sectors);
if (hd2)
@@ -823,6 +825,8 @@ void req_merged_io(struct request *req)
{
struct hd_struct *hd1, *hd2;
+ if (unlikely(req->io_account == 0))
+ return;
locate_hd_struct(req, &hd1, &hd2);
if (hd1)
down_ios(hd1);
@@ -834,6 +838,8 @@ void req_finished_io(struct request *req
{
struct hd_struct *hd1, *hd2;
+ if (unlikely(req->io_account == 0))
+ return;
locate_hd_struct(req, &hd1, &hd2);
if (hd1)
account_io_end(hd1, req);
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 777712f..4b1afa6 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -693,12 +693,23 @@ static int loop_set_fd(struct loop_devic
set_blocksize(dev, bs);
lo->lo_bh = lo->lo_bhtail = NULL;
- kernel_thread(loop_thread, lo, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
- down(&lo->lo_sem);
+ error = kernel_thread(loop_thread, lo,
+ CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
+ if (error < 0)
+ goto out_clr;
+ down(&lo->lo_sem); /* wait for the thread to start */
fput(file);
return 0;
+ out_clr:
+ lo->lo_backing_file = NULL;
+ lo->lo_device = 0;
+ lo->lo_flags = 0;
+ loop_sizes[lo->lo_number] = 0;
+ inode->i_mapping->gfp_mask = lo->old_gfp_mask;
+ lo->lo_state = Lo_unbound;
+ fput(file); /* yes, have to do it twice */
out_putf:
fput(file);
out:
diff --git a/drivers/char/sc1200wdt.c b/drivers/char/sc1200wdt.c
index 73827c7..7c9940c 100644
--- a/drivers/char/sc1200wdt.c
+++ b/drivers/char/sc1200wdt.c
@@ -382,7 +382,7 @@ static int __init sc1200wdt_init(void)
if (io == -1) {
printk(KERN_ERR PFX "io parameter must be specified\n");
ret = -EINVAL;
- goto out_clean;
+ goto out_pnp;
}
if (!request_region(io, io_len, SC1200_MODULE_NAME)) {
diff --git a/drivers/i2c/i2c-elv.c b/drivers/i2c/i2c-elv.c
index 242a02e..96019bc 100644
--- a/drivers/i2c/i2c-elv.c
+++ b/drivers/i2c/i2c-elv.c
@@ -99,7 +99,7 @@ static int bit_elv_init(void)
} else {
outb(0x0c,base+2); /* SLCT auf low */
udelay(400);
- if ( !(inb(base+1) && 0x10) ) {
+ if ( !(inb(base+1) & 0x10) ) {
outb(0x04,base+2);
DEBINIT(printk(KERN_DEBUG "i2c-elv.o: Select was high.\n"));
return -ENODEV;
diff --git a/drivers/isdn/isdn_common.c b/drivers/isdn/isdn_common.c
index c2f4c30..3155dc8 100644
--- a/drivers/isdn/isdn_common.c
+++ b/drivers/isdn/isdn_common.c
@@ -1058,6 +1058,10 @@ isdn_read(struct file *file, char *buf,
len = dev->drv[drvidx]->interface->
readstat(buf, count, 1, drvidx,
isdn_minor2chan(minor));
+ if (len < 0) {
+ retval = len;
+ goto out;
+ }
} else {
len = 0;
}
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index aa76e61..d01556c 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -510,7 +510,7 @@ static int do_write_oneword(struct map_i
or tells us why it failed. */
dq6 = CMD(1<<6);
dq5 = CMD(1<<5);
- timeo = jiffies + (HZ/1000); /* setting timeout to 1ms for now */
+ timeo = jiffies + (HZ/1000) + 1; /* setting timeout to 1ms for now */
oldstatus = cfi_read(map, adr);
status = cfi_read(map, adr);
@@ -547,7 +547,7 @@ static int do_write_oneword(struct map_i
printk(KERN_WARNING "Internal flash device timeout occurred or write operation was performed while flash was programming.\n" );
}
} else {
- printk(KERN_WARNING "Waiting for write to complete timed out in do_write_oneword.");
+ printk(KERN_WARNING "Waiting for write to complete timed out in do_write_oneword.\n");
chip->state = FL_READY;
wake_up(&chip->wq);
@@ -825,7 +825,7 @@ static inline int do_erase_chip(struct m
chip->state = FL_READY;
wake_up(&chip->wq);
cfi_spin_unlock(chip->mutex);
- printk("waiting for erase to complete timed out.");
+ printk("waiting for erase to complete timed out.\n");
DISABLE_VPP(map);
return -EIO;
}
@@ -963,7 +963,7 @@ static inline int do_erase_oneblock(stru
}
else
{
- printk( "Waiting for erase to complete timed out in do_erase_oneblock.");
+ printk( "Waiting for erase to complete timed out in do_erase_oneblock.\n");
chip->state = FL_READY;
wake_up(&chip->wq);
diff --git a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c
index f4280a1..9399d4e 100644
--- a/drivers/mtd/devices/blkmtd.c
+++ b/drivers/mtd/devices/blkmtd.c
@@ -195,6 +195,7 @@ static int commit_pages(struct blkmtd_de
int err = 0;
iobuf->length = iobuf->nr_pages << PAGE_SHIFT;
+ iobuf->offset = 0; /* all pages are aligned */
iobuf->locked = 1;
if(iobuf->length) {
int i;
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index 1953c4a..02d05b3 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -639,6 +639,7 @@ int pppoe_connect(struct socket *sock, s
po->chan.hdrlen = (sizeof(struct pppoe_hdr) +
dev->hard_header_len);
+ po->chan.mtu = dev->mtu - sizeof(struct pppoe_hdr);
po->chan.private = sk;
po->chan.ops = &pppoe_chan_ops;
diff --git a/drivers/s390/net/qeth.c b/drivers/s390/net/qeth.c
index 22f9444..ea7803a 100644
--- a/drivers/s390/net/qeth.c
+++ b/drivers/s390/net/qeth.c
@@ -6097,7 +6097,7 @@ static void qeth_qdio_input_handler(int
}
sbalf15=(card->inbound_qdio_buffers[(first_element+count-1)&
QDIO_MAX_BUFFERS_PER_Q].
- element[15].flags)&&0xff;
+ element[15].flags)&0xff;
PRINT_STUPID("inbound qdio transfer error on irq 0x%04x. " \
"qdio_error=0x%x (more than one: %c), " \
"siga_error=0x%x (more than one: %c), " \
diff --git a/drivers/scsi/cpqfcTSworker.c b/drivers/scsi/cpqfcTSworker.c
index b1dda80..c124505 100644
--- a/drivers/scsi/cpqfcTSworker.c
+++ b/drivers/scsi/cpqfcTSworker.c
@@ -1260,7 +1260,7 @@ static void ProcessELS_Request(CPQFCHBA
// Terminate I/O with "retry" potential
cpqfcTSTerminateExchange(dev, &pLoggedInPort->ScsiNexus, PORTID_CHANGED);
} else {
- printk(" Got 3 LOGOuts - terminating comm. with port_id %Xh\n", fchs->s_id && 0xFFFFFF);
+ printk(" Got 3 LOGOuts - terminating comm. with port_id %Xh\n", fchs->s_id & 0xFFFFFF);
GiveUpOnDevice = 1;
}
} else {
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 48a04df..9c816a9 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -3667,7 +3667,7 @@ static void gdth_interrupt(int irq,void
IStatus &= ~0x80;
#ifdef INT_COAL
if (coalesced)
- ha->status = pcs->ext_status && 0xffff;
+ ha->status = pcs->ext_status & 0xffff;
else
#endif
ha->status = gdth_readw(&dp6m_ptr->i960r.status);
@@ -3679,7 +3679,7 @@ static void gdth_interrupt(int irq,void
if (coalesced) {
ha->info = pcs->info0;
ha->info2 = pcs->info1;
- ha->service = (pcs->ext_status >> 16) && 0xffff;
+ ha->service = (pcs->ext_status >> 16) & 0xffff;
} else
#endif
{
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 905b8a0..8b8f281 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1192,7 +1192,7 @@ static int sg_mmap(struct file * filp, s
sg_rb_correct4mmap(rsv_schp, 1); /* do only once per fd lifetime */
sfp->mmap_called = 1;
}
- vma->vm_flags |= (VM_RESERVED | VM_IO);
+ vma->vm_flags |= VM_RESERVED;
vma->vm_private_data = sfp;
vma->vm_ops = &sg_mmap_vm_ops;
return 0;
diff --git a/drivers/usb/host/usb-ohci.c b/drivers/usb/host/usb-ohci.c
index 27fc5fe..82817f5 100644
--- a/drivers/usb/host/usb-ohci.c
+++ b/drivers/usb/host/usb-ohci.c
@@ -2159,7 +2159,7 @@ static int rh_submit_urb (struct urb * u
static int rh_unlink_urb (struct urb * urb)
{
ohci_t * ohci = urb->dev->bus->hcpriv;
- unsigned int flags;
+ unsigned long flags;
spin_lock_irqsave(&ohci->ohci_lock, flags);
if (ohci->rh.urb == urb) {
diff --git a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h
index 1bc4e4b..0260b4e 100644
--- a/drivers/usb/serial/usb-serial.h
+++ b/drivers/usb/serial/usb-serial.h
@@ -308,20 +308,9 @@ static inline int port_paranoia_check (s
return 0;
}
-
-static inline struct usb_serial* get_usb_serial (struct usb_serial_port *port, const char *function)
-{
- /* if no port was specified, or it fails a paranoia check */
- if (!port ||
- port_paranoia_check (port, function) ||
- serial_paranoia_check (port->serial, function)) {
- /* then say that we don't have a valid usb_serial thing, which will
- * end up genrating -ENODEV return values */
- return NULL;
- }
-
- return port->serial;
-}
+#define get_usb_serial(p, f) usb_serial_get_serial(p, f)
+extern struct usb_serial *usb_serial_get_serial(struct usb_serial_port *port,
+ const char *function_name);
static inline void usb_serial_debug_data (const char *file, const char *function, int size, const unsigned char *data)
diff --git a/drivers/usb/serial/usbserial.c b/drivers/usb/serial/usbserial.c
index 319bb03..ee6ef01 100644
--- a/drivers/usb/serial/usbserial.c
+++ b/drivers/usb/serial/usbserial.c
@@ -408,6 +408,25 @@ static struct usb_serial *serial_table[S
static LIST_HEAD(usb_serial_driver_list);
+struct usb_serial *usb_serial_get_serial(struct usb_serial_port *port,
+ const char *function)
+{
+
+ /* if no port was specified, or it fails a paranoia check */
+ if (!port ||
+ port_paranoia_check (port, function) ||
+ serial_paranoia_check (port->serial, function)) {
+ return NULL;
+ }
+
+ /* disconnected, cut off all operations */
+ if (port->serial->dev == NULL)
+ return NULL;
+
+ return port->serial;
+}
+
+
static struct usb_serial *get_serial_by_minor (unsigned int minor)
{
return serial_table[minor];
@@ -467,6 +486,23 @@ static void return_serial (struct usb_se
}
/*
+ * A regular foo_put(), except a) it's open-coded without kref, and
+ * b) it's not the only place which does --serial->ref (due to locking).
+ *
+ * This does not do an equivalent of return_serial() because serial_table[]
+ * has a lifetime from probe to disconnect.
+ */
+static void serial_put(struct usb_serial *serial)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&post_lock, flags);
+ if (--serial->ref == 0)
+ kfree(serial);
+ spin_unlock_irqrestore(&post_lock, flags);
+}
+
+/*
* The post kludge.
*
* Our component drivers are hideously buggy and written by people
@@ -495,7 +531,7 @@ static void post_helper(void *arg)
while (pos != &post_list) {
job = list_entry(pos, struct usb_serial_post_job, link);
port = job->port;
- /* get_usb_serial checks port->tty, so cannot be used */
+ /* get_usb_serial checks serial->dev, so cannot be used */
serial = port->serial;
if (port->write_busy) {
dbg("%s - port %d busy", __FUNCTION__, port->number);
@@ -508,7 +544,7 @@ static void post_helper(void *arg)
down(&port->sem);
dbg("%s - port %d len %d backlog %d", __FUNCTION__,
port->number, job->len, port->write_backlog);
- if (port->tty != NULL) {
+ if (serial->dev != NULL) {
int rc;
int sent = 0;
while (sent < job->len) {
@@ -581,17 +617,25 @@ static int serial_open (struct tty_struc
struct usb_serial_port *port;
unsigned int portNumber;
int retval = 0;
-
+ unsigned long flags;
+
dbg("%s", __FUNCTION__);
/* initialize the pointer incase something fails */
tty->driver_data = NULL;
+ /*
+ * In a sane refcounting system, this would've been called serial_get().
+ */
+ spin_lock_irqsave(&post_lock, flags);
/* get the serial object associated with this tty pointer */
serial = get_serial_by_minor (MINOR(tty->device));
-
- if (serial_paranoia_check (serial, __FUNCTION__))
+ if (serial_paranoia_check(serial, __FUNCTION__) || serial->dev == NULL) {
+ spin_unlock_irqrestore(&post_lock, flags);
return -ENODEV;
+ }
+ serial->ref++; /* Protect the port->sem from kfree() */
+ spin_unlock_irqrestore(&post_lock, flags);
/* set up our port structure making the tty driver remember our port object, and us it */
portNumber = MINOR(tty->device) - serial->minor;
@@ -600,7 +644,7 @@ static int serial_open (struct tty_struc
down (&port->sem);
port->tty = tty;
-
+
/* lock this module before we call it */
if (serial->type->owner)
__MOD_INC_USE_COUNT(serial->type->owner);
@@ -622,13 +666,16 @@ static int serial_open (struct tty_struc
}
up (&port->sem);
+ if (retval)
+ serial_put(serial);
return retval;
}
static void __serial_close(struct usb_serial_port *port, struct file *filp)
{
+
if (!port->open_count) {
- dbg ("%s - port not opened", __FUNCTION__);
+ err("%s - port %d: not open", __FUNCTION__, port->number);
return;
}
@@ -653,36 +700,33 @@ static void __serial_close(struct usb_se
static void serial_close(struct tty_struct *tty, struct file * filp)
{
- struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
- struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
+ struct usb_serial_port *port;
+ struct usb_serial *serial;
- if (!serial)
+ if ((port = tty->driver_data) == NULL) {
+ /* This happens if someone opened us with O_NDELAY */
return;
-
- down (&port->sem);
+ }
+ if ((serial = port->serial) == NULL) {
+ err("%s - port %d: not open (count %d)", __FUNCTION__, port->number, port->open_count);
+ return;
+ }
dbg("%s - port %d", __FUNCTION__, port->number);
- /* if disconnect beat us to the punch here, there's nothing to do */
- if (tty->driver_data) {
- /*
- * XXX The right thing would be to wait for the output to drain.
- * But we are not sufficiently daring to experiment in 2.4.
- * N.B. If we do wait, no need to run post_helper here.
- * Normall callback mechanism wakes it up just fine.
- */
-#if I_AM_A_DARING_HACKER
- tty->closing = 1;
- up (&port->sem);
- if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
- tty_wait_until_sent(tty, info->closing_wait);
- down (&port->sem);
- if (!tty->driver_data) /* woopsie, disconnect, now what */ ;
-#endif
- __serial_close(port, filp);
+ tty->closing = 1;
+ if (serial->dev != NULL) {
+ /* In most drivers, this is set with setserial */
+ /** if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) **/
+ tty_wait_until_sent(tty, /** info->closing_wait **/ 30*HZ);
}
+ down (&port->sem);
+ __serial_close(port, filp);
up (&port->sem);
+
+ serial_put(serial);
+ tty->closing = 0;
}
static int __serial_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count)
@@ -696,7 +740,7 @@ static int __serial_write (struct usb_se
dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count);
if (!port->open_count) {
- dbg("%s - port not opened", __FUNCTION__);
+ dbg("%s - port not open", __FUNCTION__);
goto exit;
}
@@ -806,6 +850,9 @@ static int serial_post_one(struct usb_se
struct usb_serial_post_job *job;
unsigned long flags;
+ if (!serial)
+ return -ENODEV;
+
dbg("%s - port %d user %d count %d", __FUNCTION__, port->number, from_user, count);
job = kmalloc(sizeof(struct usb_serial_post_job), gfp);
@@ -1239,24 +1286,25 @@ static int generic_chars_in_buffer (stru
static void generic_read_bulk_callback (struct urb *urb)
{
struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
- struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
+ struct usb_serial *serial = port->serial;
struct tty_struct *tty;
unsigned char *data = urb->transfer_buffer;
int i;
int result;
- dbg("%s - port %d", __FUNCTION__, port->number);
-
if (!serial) {
- dbg("%s - bad serial pointer, exiting", __FUNCTION__);
+ err("%s - null serial pointer, exiting", __FUNCTION__);
return;
}
if (urb->status) {
- dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
+ dbg("%s - nonzero read bulk status received: %d, pipe 0x%x",
+ __FUNCTION__, urb->status, urb->pipe);
return;
}
+ dbg("%s - port %d", __FUNCTION__, port->number);
+
usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
tty = port->tty;
@@ -1272,6 +1320,9 @@ static void generic_read_bulk_callback (
tty_flip_buffer_push(tty);
}
+ if (serial->dev == NULL)
+ return;
+
/* Continue trying to always read */
usb_fill_bulk_urb (port->read_urb, serial->dev,
usb_rcvbulkpipe (serial->dev,
@@ -1289,18 +1340,12 @@ static void generic_read_bulk_callback (
static void generic_write_bulk_callback (struct urb *urb)
{
struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
- struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
dbg("%s - port %d", __FUNCTION__, port->number);
port->write_busy = 0;
wmb();
- if (!serial) {
- err("%s - null serial pointer, exiting", __FUNCTION__);
- return;
- }
-
if (urb->status) {
dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
}
@@ -1658,26 +1703,22 @@ static void usb_serial_disconnect(struct
{
struct usb_serial *serial = (struct usb_serial *) ptr;
struct usb_serial_port *port;
- unsigned long flags;
int i;
dbg ("%s", __FUNCTION__);
if (serial) {
- /* fail all future close/read/write/ioctl/etc calls */
for (i = 0; i < serial->num_ports; ++i) {
port = &serial->port[i];
down (&port->sem);
if (port->tty != NULL)
- while (port->open_count > 0)
- __serial_close(port, NULL);
+ tty_hangup(port->tty);
up (&port->sem);
}
-
- serial->dev = NULL;
serial_shutdown (serial);
- for (i = 0; i < serial->num_ports; ++i)
- serial->port[i].open_count = 0;
+ /* fail all future close/read/write/ioctl/etc calls */
+ serial->dev = NULL;
+ wmb();
for (i = 0; i < serial->num_bulk_in; ++i) {
port = &serial->port[i];
@@ -1716,10 +1757,7 @@ static void usb_serial_disconnect(struct
return_serial (serial);
/* free up any memory that we allocated */
- spin_lock_irqsave(&post_lock, flags);
- if (--serial->ref == 0)
- kfree(serial);
- spin_unlock_irqrestore(&post_lock, flags);
+ serial_put (serial);
} else {
info("device disconnected");
@@ -1813,6 +1851,11 @@ static void __exit usb_serial_exit(void)
usb_deregister(&usb_serial_driver);
tty_unregister_driver(&serial_tty_driver);
+
+ while (!list_empty(&usb_serial_driver_list)) {
+ err("%s - module is in use, hanging...", __FUNCTION__);
+ msleep(5000);
+ }
}
@@ -1862,7 +1905,7 @@ EXPORT_SYMBOL(usb_serial_deregister);
EXPORT_SYMBOL(ezusb_writememory);
EXPORT_SYMBOL(ezusb_set_reset);
#endif
-
+EXPORT_SYMBOL(usb_serial_get_serial);
/* Module information */
MODULE_AUTHOR( DRIVER_AUTHOR );
diff --git a/drivers/usb/usbnet.c b/drivers/usb/usbnet.c
index 764be51..f2c46ff 100644
--- a/drivers/usb/usbnet.c
+++ b/drivers/usb/usbnet.c
@@ -1298,12 +1298,12 @@ static inline void nc_dump_usbctl (struc
#define STATUS_CONN_OTHER (1 << 14)
#define STATUS_SUSPEND_OTHER (1 << 13)
#define STATUS_MAILBOX_OTHER (1 << 12)
-#define STATUS_PACKETS_OTHER(n) (((n) >> 8) && 0x03)
+#define STATUS_PACKETS_OTHER(n) (((n) >> 8) & 0x03)
#define STATUS_CONN_THIS (1 << 6)
#define STATUS_SUSPEND_THIS (1 << 5)
#define STATUS_MAILBOX_THIS (1 << 4)
-#define STATUS_PACKETS_THIS(n) (((n) >> 0) && 0x03)
+#define STATUS_PACKETS_THIS(n) (((n) >> 0) & 0x03)
#define STATUS_UNSPEC_MASK 0x0c8c
#define STATUS_NOISE_MASK ((u16)~(0x0303|STATUS_UNSPEC_MASK))
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index cf616e1..fac9c73 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -388,7 +388,7 @@ static int fbmem_read_proc(char *buf, ch
int clen;
clen = 0;
- for (fi = registered_fb; fi < ®istered_fb[FB_MAX] && len < 4000; fi++)
+ for (fi = registered_fb; fi < ®istered_fb[FB_MAX] && clen < 4000; fi++)
if (*fi)
clen += sprintf(buf + clen, "%d %s\n",
GET_FB_IDX((*fi)->node),
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index b0ad905..32c8ec6 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -77,7 +77,7 @@ static struct linux_binfmt elf_format =
NULL, THIS_MODULE, load_elf_binary, load_elf_library, elf_core_dump, ELF_EXEC_PAGESIZE
};
-#define BAD_ADDR(x) ((unsigned long)(x) > TASK_SIZE)
+#define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE)
static int set_brk(unsigned long start, unsigned long end)
{
@@ -345,7 +345,7 @@ static unsigned long load_elf_interp(str
* <= p_memsize so it is only necessary to check p_memsz.
*/
k = load_addr + eppnt->p_vaddr;
- if (k > TASK_SIZE || eppnt->p_filesz > eppnt->p_memsz ||
+ if (BAD_ADDR(k) || eppnt->p_filesz > eppnt->p_memsz ||
eppnt->p_memsz > TASK_SIZE || TASK_SIZE - eppnt->p_memsz < k) {
error = -ENOMEM;
goto out_close;
@@ -772,7 +772,7 @@ static int load_elf_binary(struct linux_
* allowed task size. Note that p_filesz must always be
* <= p_memsz so it is only necessary to check p_memsz.
*/
- if (k > TASK_SIZE || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
+ if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
elf_ppnt->p_memsz > TASK_SIZE ||
TASK_SIZE - elf_ppnt->p_memsz < k) {
/* set_brk can never work. Avoid overflows. */
@@ -822,10 +822,13 @@ static int load_elf_binary(struct linux_
interpreter,
&interp_load_addr);
if (BAD_ADDR(elf_entry)) {
- printk(KERN_ERR "Unable to load interpreter %.128s\n",
- elf_interpreter);
+ // FIXME - ratelimit this before re-enabling
+ // printk(KERN_ERR "Unable to load interpreter %.128s\n",
+ // elf_interpreter);
+
force_sig(SIGSEGV, current);
- retval = IS_ERR((void *)elf_entry) ? PTR_ERR((void *)elf_entry) : -ENOEXEC;
+ retval = IS_ERR((void *)elf_entry) ?
+ (int)elf_entry : -EINVAL;
goto out_free_dentry;
}
reloc_func_desc = interp_load_addr;
@@ -833,6 +836,12 @@ static int load_elf_binary(struct linux_
allow_write_access(interpreter);
fput(interpreter);
kfree(elf_interpreter);
+ } else {
+ if (BAD_ADDR(elf_entry)) {
+ force_sig(SIGSEGV, current);
+ retval = -EINVAL;
+ goto out_free_dentry;
+ }
}
kfree(elf_phdata);
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index d510cc8..4d7c709 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -480,12 +480,8 @@ struct super_block * ext2_read_super (st
es = (struct ext2_super_block *) (((char *)bh->b_data) + offset);
sb->u.ext2_sb.s_es = es;
sb->s_magic = le16_to_cpu(es->s_magic);
- if (sb->s_magic != EXT2_SUPER_MAGIC) {
- if (!silent)
- printk ("VFS: Can't find ext2 filesystem on dev %s.\n",
- bdevname(dev));
- goto failed_mount;
- }
+ if (sb->s_magic != EXT2_SUPER_MAGIC)
+ goto cantfind_ext2;
if (le32_to_cpu(es->s_rev_level) == EXT2_GOOD_OLD_REV &&
(EXT2_HAS_COMPAT_FEATURE(sb, ~0U) ||
EXT2_HAS_RO_COMPAT_FEATURE(sb, ~0U) ||
@@ -561,16 +557,19 @@ struct super_block * ext2_read_super (st
}
sb->u.ext2_sb.s_frag_size = EXT2_MIN_FRAG_SIZE <<
le32_to_cpu(es->s_log_frag_size);
- if (sb->u.ext2_sb.s_frag_size)
- sb->u.ext2_sb.s_frags_per_block = sb->s_blocksize /
- sb->u.ext2_sb.s_frag_size;
- else
- sb->s_magic = 0;
+ if (sb->u.ext2_sb.s_frag_size == 0)
+ goto cantfind_ext2;
+ sb->u.ext2_sb.s_frags_per_block = sb->s_blocksize /
+ sb->u.ext2_sb.s_frag_size;
sb->u.ext2_sb.s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group);
sb->u.ext2_sb.s_frags_per_group = le32_to_cpu(es->s_frags_per_group);
sb->u.ext2_sb.s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group);
+ if (EXT2_INODE_SIZE(sb) == 0)
+ goto cantfind_ext2;
sb->u.ext2_sb.s_inodes_per_block = sb->s_blocksize /
EXT2_INODE_SIZE(sb);
+ if (sb->u.ext2_sb.s_inodes_per_block == 0)
+ goto cantfind_ext2;
sb->u.ext2_sb.s_itb_per_group = sb->u.ext2_sb.s_inodes_per_group /
sb->u.ext2_sb.s_inodes_per_block;
sb->u.ext2_sb.s_desc_per_block = sb->s_blocksize /
@@ -589,13 +588,10 @@ struct super_block * ext2_read_super (st
log2 (EXT2_ADDR_PER_BLOCK(sb));
sb->u.ext2_sb.s_desc_per_block_bits =
log2 (EXT2_DESC_PER_BLOCK(sb));
- if (sb->s_magic != EXT2_SUPER_MAGIC) {
- if (!silent)
- printk ("VFS: Can't find an ext2 filesystem on dev "
- "%s.\n",
- bdevname(dev));
- goto failed_mount;
- }
+
+ if (sb->s_magic != EXT2_SUPER_MAGIC)
+ goto cantfind_ext2;
+
if (sb->s_blocksize != bh->b_size) {
if (!silent)
printk ("VFS: Unsupported blocksize on dev "
@@ -625,6 +621,8 @@ struct super_block * ext2_read_super (st
goto failed_mount;
}
+ if (EXT2_BLOCKS_PER_GROUP(sb) == 0)
+ goto cantfind_ext2;
sb->u.ext2_sb.s_groups_count = (le32_to_cpu(es->s_blocks_count) -
le32_to_cpu(es->s_first_data_block) +
EXT2_BLOCKS_PER_GROUP(sb) - 1) /
@@ -678,6 +676,11 @@ struct super_block * ext2_read_super (st
}
ext2_setup_super (sb, es, sb->s_flags & MS_RDONLY);
return sb;
+cantfind_ext2:
+ if (!silent)
+ printk ("VFS: Can't find ext2 filesystem on dev %s.\n",
+ bdevname(dev));
+ goto failed_mount;
failed_mount2:
for (i = 0; i < db_count; i++)
brelse(sb->u.ext2_sb.s_group_desc[i]);
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 33e2f97..c011c50 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -979,13 +979,9 @@ struct super_block * ext3_read_super (st
es = (struct ext3_super_block *) (((char *)bh->b_data) + offset);
sbi->s_es = es;
sb->s_magic = le16_to_cpu(es->s_magic);
- if (sb->s_magic != EXT3_SUPER_MAGIC) {
- if (!silent)
- printk(KERN_ERR
- "VFS: Can't find ext3 filesystem on dev %s.\n",
- bdevname(dev));
- goto failed_mount;
- }
+ if (sb->s_magic != EXT3_SUPER_MAGIC)
+ goto cantfind_ext3;
+
if (le32_to_cpu(es->s_rev_level) == EXT3_GOOD_OLD_REV &&
(EXT3_HAS_COMPAT_FEATURE(sb, ~0U) ||
EXT3_HAS_RO_COMPAT_FEATURE(sb, ~0U) ||
@@ -1083,8 +1079,13 @@ struct super_block * ext3_read_super (st
sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group);
sbi->s_frags_per_group = le32_to_cpu(es->s_frags_per_group);
sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group);
+ if (EXT3_INODE_SIZE(sb) == 0)
+ goto cantfind_ext3;
sbi->s_inodes_per_block = blocksize / EXT3_INODE_SIZE(sb);
- sbi->s_itb_per_group = sbi->s_inodes_per_group /sbi->s_inodes_per_block;
+ if (sbi->s_inodes_per_block == 0)
+ goto cantfind_ext3;
+ sbi->s_itb_per_group = sbi->s_inodes_per_group /
+ sbi->s_inodes_per_block;
sbi->s_desc_per_block = blocksize / sizeof(struct ext3_group_desc);
sbi->s_sbh = bh;
if (sbi->s_resuid == EXT3_DEF_RESUID)
@@ -1114,6 +1115,8 @@ struct super_block * ext3_read_super (st
goto failed_mount;
}
+ if (EXT3_BLOCKS_PER_GROUP(sb) == 0)
+ goto cantfind_ext3;
sbi->s_groups_count = (le32_to_cpu(es->s_blocks_count) -
le32_to_cpu(es->s_first_data_block) +
EXT3_BLOCKS_PER_GROUP(sb) - 1) /
@@ -1240,6 +1243,12 @@ struct super_block * ext3_read_super (st
return sb;
+cantfind_ext3:
+ if (!silent)
+ printk(KERN_ERR
+ "VFS: Can't find ext3 filesystem on dev %s.\n",
+ bdevname(dev));
+ goto failed_mount;
failed_mount3:
journal_destroy(sbi->s_journal);
failed_mount2:
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 48ab5af..30e03c2 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -860,7 +860,10 @@ static int nfs_safe_remove(struct dentry
if (inode)
NFS_CACHEINV(inode);
error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
- if (error < 0)
+
+ /* if server returned ENOENT, assume that the dentry is already gone
+ * and update the cache accordingly */
+ if (error < 0 && (error != -ENOENT))
goto out;
if (inode)
inode->i_nlink--;
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 3235723..f99c836 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -204,7 +204,8 @@ char *disk_name (struct gendisk *hd, int
/*
* Add a partitions details to the devices partition description.
*/
-void add_gd_partition(struct gendisk *hd, int minor, int start, int size)
+void add_gd_partition(struct gendisk *hd, int minor, unsigned int start,
+ unsigned int size)
{
#ifndef CONFIG_DEVFS_FS
char buf[40];
diff --git a/fs/partitions/check.h b/fs/partitions/check.h
index 32d7940..dd93517 100644
--- a/fs/partitions/check.h
+++ b/fs/partitions/check.h
@@ -2,7 +2,8 @@
* add_partition adds a partitions details to the devices partition
* description.
*/
-void add_gd_partition(struct gendisk *hd, int minor, int start, int size);
+void add_gd_partition(struct gendisk *hd, int minor, unsigned int start,
+ unsigned int size);
typedef struct {struct page *v;} Sector;
diff --git a/fs/partitions/sun.c b/fs/partitions/sun.c
index a0ca0b1..cd087ca 100644
--- a/fs/partitions/sun.c
+++ b/fs/partitions/sun.c
@@ -86,7 +86,7 @@ int sun_partition(struct gendisk *hd, st
spc = be16_to_cpu(label->ntrks) * be16_to_cpu(label->nsect);
for (i = 0; i < 8; i++, p++) {
unsigned long st_sector;
- int num_sectors;
+ unsigned int num_sectors;
st_sector = first_sector + be32_to_cpu(p->start_cylinder) * spc;
num_sectors = be32_to_cpu(p->num_sectors);
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 9df2fa2..0c5b54e 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -1515,7 +1515,7 @@ udf_read_super(struct super_block *sb, v
iput(inode);
goto error_out;
}
- sb->s_maxbytes = MAX_LFS_FILESIZE;
+ sb->s_maxbytes = 1<<30;
return sb;
error_out:
diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c
index 0ae7e96..0567211 100644
--- a/fs/udf/truncate.c
+++ b/fs/udf/truncate.c
@@ -182,37 +182,51 @@ void udf_truncate_extents(struct inode *
{
if (offset)
{
- extoffset -= adsize;
- etype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1);
- if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
- {
- extoffset -= adsize;
- elen = EXT_NOT_RECORDED_NOT_ALLOCATED | (elen + offset);
- udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 0);
+ /*
+ * OK, there is not extent covering inode->i_size and
+ * no extent above inode->i_size => truncate is
+ * extending the file by 'offset'.
+ */
+ if ((!bh && extoffset == udf_file_entry_alloc_offset(inode)) ||
+ (bh && extoffset == sizeof(struct allocExtDesc))) {
+ /* File has no extents at all! */
+ memset(&eloc, 0x00, sizeof(lb_addr));
+ elen = EXT_NOT_RECORDED_NOT_ALLOCATED | offset;
+ udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1);
}
- else if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
- {
- lb_addr neloc = { 0, 0 };
+ else {
extoffset -= adsize;
- nelen = EXT_NOT_RECORDED_NOT_ALLOCATED |
- ((elen + offset + inode->i_sb->s_blocksize - 1) &
- ~(inode->i_sb->s_blocksize - 1));
- udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1);
- udf_add_aext(inode, &bloc, &extoffset, eloc, (etype << 30) | elen, &bh, 1);
- }
- else
- {
- if (elen & (inode->i_sb->s_blocksize - 1))
+ etype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1);
+ if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
+ {
+ extoffset -= adsize;
+ elen = EXT_NOT_RECORDED_NOT_ALLOCATED | (elen + offset);
+ udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 0);
+ }
+ else if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
{
+ lb_addr neloc = { 0, 0 };
extoffset -= adsize;
- elen = EXT_RECORDED_ALLOCATED |
- ((elen + inode->i_sb->s_blocksize - 1) &
+ nelen = EXT_NOT_RECORDED_NOT_ALLOCATED |
+ ((elen + offset + inode->i_sb->s_blocksize - 1) &
~(inode->i_sb->s_blocksize - 1));
- udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 1);
+ udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1);
+ udf_add_aext(inode, &bloc, &extoffset, eloc, (etype << 30) | elen, &bh, 1);
+ }
+ else
+ {
+ if (elen & (inode->i_sb->s_blocksize - 1))
+ {
+ extoffset -= adsize;
+ elen = EXT_RECORDED_ALLOCATED |
+ ((elen + inode->i_sb->s_blocksize - 1) &
+ ~(inode->i_sb->s_blocksize - 1));
+ udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 1);
+ }
+ memset(&eloc, 0x00, sizeof(lb_addr));
+ elen = EXT_NOT_RECORDED_NOT_ALLOCATED | offset;
+ udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1);
}
- memset(&eloc, 0x00, sizeof(lb_addr));
- elen = EXT_NOT_RECORDED_NOT_ALLOCATED | offset;
- udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1);
}
}
}
diff --git a/include/asm-i386/bitops.h b/include/asm-i386/bitops.h
index 9b6b55e..bb63c10 100644
--- a/include/asm-i386/bitops.h
+++ b/include/asm-i386/bitops.h
@@ -38,7 +38,7 @@ static __inline__ void set_bit(int nr, v
__asm__ __volatile__( LOCK_PREFIX
"btsl %1,%0"
:"=m" (ADDR)
- :"Ir" (nr));
+ :"Ir" (nr), "m" (ADDR));
}
/**
@@ -55,7 +55,7 @@ static __inline__ void __set_bit(int nr,
__asm__(
"btsl %1,%0"
:"=m" (ADDR)
- :"Ir" (nr));
+ :"Ir" (nr), "m" (ADDR));
}
/**
@@ -73,7 +73,7 @@ static __inline__ void clear_bit(int nr,
__asm__ __volatile__( LOCK_PREFIX
"btrl %1,%0"
:"=m" (ADDR)
- :"Ir" (nr));
+ :"Ir" (nr), "m" (ADDR));
}
#define smp_mb__before_clear_bit() barrier()
#define smp_mb__after_clear_bit() barrier()
@@ -92,7 +92,7 @@ static __inline__ void __change_bit(int
__asm__ __volatile__(
"btcl %1,%0"
:"=m" (ADDR)
- :"Ir" (nr));
+ :"Ir" (nr), "m" (ADDR));
}
/**
@@ -109,7 +109,7 @@ static __inline__ void change_bit(int nr
__asm__ __volatile__( LOCK_PREFIX
"btcl %1,%0"
:"=m" (ADDR)
- :"Ir" (nr));
+ :"Ir" (nr), "m" (ADDR));
}
/**
@@ -127,7 +127,7 @@ static __inline__ int test_and_set_bit(i
__asm__ __volatile__( LOCK_PREFIX
"btsl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit),"=m" (ADDR)
- :"Ir" (nr) : "memory");
+ :"Ir" (nr), "m" (ADDR) : "memory");
return oldbit;
}
@@ -147,7 +147,7 @@ static __inline__ int __test_and_set_bit
__asm__(
"btsl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit),"=m" (ADDR)
- :"Ir" (nr));
+ :"Ir" (nr), "m" (ADDR));
return oldbit;
}
@@ -166,7 +166,7 @@ static __inline__ int test_and_clear_bit
__asm__ __volatile__( LOCK_PREFIX
"btrl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit),"=m" (ADDR)
- :"Ir" (nr) : "memory");
+ :"Ir" (nr), "m" (ADDR) : "memory");
return oldbit;
}
@@ -186,7 +186,7 @@ static __inline__ int __test_and_clear_b
__asm__(
"btrl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit),"=m" (ADDR)
- :"Ir" (nr));
+ :"Ir" (nr), "m" (ADDR));
return oldbit;
}
@@ -198,7 +198,7 @@ static __inline__ int __test_and_change_
__asm__ __volatile__(
"btcl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit),"=m" (ADDR)
- :"Ir" (nr) : "memory");
+ :"Ir" (nr), "m" (ADDR) : "memory");
return oldbit;
}
@@ -217,7 +217,7 @@ static __inline__ int test_and_change_bi
__asm__ __volatile__( LOCK_PREFIX
"btcl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit),"=m" (ADDR)
- :"Ir" (nr) : "memory");
+ :"Ir" (nr), "m" (ADDR) : "memory");
return oldbit;
}
diff --git a/include/asm-i386/page.h b/include/asm-i386/page.h
index 90424fd..8b6b3ab 100644
--- a/include/asm-i386/page.h
+++ b/include/asm-i386/page.h
@@ -41,11 +41,13 @@ typedef struct { unsigned long pte_low,
typedef struct { unsigned long long pmd; } pmd_t;
typedef struct { unsigned long long pgd; } pgd_t;
#define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
+#define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
#else
typedef struct { unsigned long pte_low; } pte_t;
typedef struct { unsigned long pmd; } pmd_t;
typedef struct { unsigned long pgd; } pgd_t;
#define pte_val(x) ((x).pte_low)
+#define __pte(x) ((pte_t) { (x) } )
#endif
#define PTE_MASK PAGE_MASK
@@ -55,7 +57,6 @@ typedef struct { unsigned long pgprot; }
#define pgd_val(x) ((x).pgd)
#define pgprot_val(x) ((x).pgprot)
-#define __pte(x) ((pte_t) { (x) } )
#define __pmd(x) ((pmd_t) { (x) } )
#define __pgd(x) ((pgd_t) { (x) } )
#define __pgprot(x) ((pgprot_t) { (x) } )
diff --git a/include/asm-mips/page.h b/include/asm-mips/page.h
index 341262e..5e4f341 100644
--- a/include/asm-mips/page.h
+++ b/include/asm-mips/page.h
@@ -77,13 +77,16 @@ static inline void copy_user_page(void *
#ifdef CONFIG_CPU_MIPS32
typedef struct { unsigned long pte_low, pte_high; } pte_t;
#define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
+ #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
#else
typedef struct { unsigned long long pte_low; } pte_t;
#define pte_val(x) ((x).pte_low)
+ #define __pte(x) ((pte_t) { (x) } )
#endif
#else
typedef struct { unsigned long pte_low; } pte_t;
#define pte_val(x) ((x).pte_low)
+#define __pte(x) ((pte_t) { (x) } )
#endif
typedef struct { unsigned long pmd; } pmd_t;
@@ -96,7 +99,6 @@ typedef struct { unsigned long pgprot; }
#define ptep_buddy(x) ((pte_t *)((unsigned long)(x) ^ sizeof(pte_t)))
-#define __pte(x) ((pte_t) { (x) } )
#define __pmd(x) ((pmd_t) { (x) } )
#define __pgd(x) ((pgd_t) { (x) } )
#define __pgprot(x) ((pgprot_t) { (x) } )
diff --git a/include/asm-x86_64/bitops.h b/include/asm-x86_64/bitops.h
index c8a4749..f6a2a4f 100644
--- a/include/asm-x86_64/bitops.h
+++ b/include/asm-x86_64/bitops.h
@@ -38,7 +38,7 @@ static __inline__ void set_bit(long nr,
__asm__ __volatile__( LOCK_PREFIX
"btsq %1,%0"
:"=m" (ADDR)
- :"dIr" (nr));
+ :"dIr" (nr), "m" (ADDR));
}
/**
@@ -55,7 +55,7 @@ static __inline__ void __set_bit(long nr
__asm__(
"btsq %1,%0"
:"=m" (ADDR)
- :"dIr" (nr));
+ :"dIr" (nr), "m" (ADDR));
}
/**
@@ -73,7 +73,7 @@ static __inline__ void clear_bit(long nr
__asm__ __volatile__( LOCK_PREFIX
"btrq %1,%0"
:"=m" (ADDR)
- :"dIr" (nr));
+ :"dIr" (nr), "m" (ADDR));
}
#define smp_mb__before_clear_bit() barrier()
#define smp_mb__after_clear_bit() barrier()
@@ -92,7 +92,7 @@ static __inline__ void __change_bit(long
__asm__ __volatile__(
"btcq %1,%0"
:"=m" (ADDR)
- :"dIr" (nr));
+ :"dIr" (nr), "m" (ADDR));
}
/**
@@ -109,7 +109,7 @@ static __inline__ void change_bit(long n
__asm__ __volatile__( LOCK_PREFIX
"btcq %1,%0"
:"=m" (ADDR)
- :"dIr" (nr));
+ :"dIr" (nr), "m" (ADDR));
}
/**
@@ -127,7 +127,7 @@ static __inline__ int test_and_set_bit(l
__asm__ __volatile__( LOCK_PREFIX
"btsq %2,%1\n\tsbbq %0,%0"
:"=r" (oldbit),"=m" (ADDR)
- :"dIr" (nr) : "memory");
+ :"dIr" (nr), "m" (ADDR) : "memory");
return oldbit;
}
@@ -147,7 +147,7 @@ static __inline__ int __test_and_set_bit
__asm__(
"btsq %2,%1\n\tsbbq %0,%0"
:"=r" (oldbit),"=m" (ADDR)
- :"dIr" (nr));
+ :"dIr" (nr), "m" (ADDR));
return oldbit;
}
@@ -166,7 +166,7 @@ static __inline__ int test_and_clear_bit
__asm__ __volatile__( LOCK_PREFIX
"btrq %2,%1\n\tsbbq %0,%0"
:"=r" (oldbit),"=m" (ADDR)
- :"dIr" (nr) : "memory");
+ :"dIr" (nr), "m" (ADDR) : "memory");
return oldbit;
}
@@ -186,7 +186,7 @@ static __inline__ int __test_and_clear_b
__asm__(
"btrq %2,%1\n\tsbbq %0,%0"
:"=r" (oldbit),"=m" (ADDR)
- :"dIr" (nr));
+ :"dIr" (nr), "m" (ADDR));
return oldbit;
}
@@ -198,7 +198,7 @@ static __inline__ int __test_and_change_
__asm__ __volatile__(
"btcq %2,%1\n\tsbbq %0,%0"
:"=r" (oldbit),"=m" (ADDR)
- :"dIr" (nr) : "memory");
+ :"dIr" (nr), "m" (ADDR) : "memory");
return oldbit;
}
@@ -217,7 +217,7 @@ static __inline__ int test_and_change_bi
__asm__ __volatile__( LOCK_PREFIX
"btcq %2,%1\n\tsbbq %0,%0"
:"=r" (oldbit),"=m" (ADDR)
- :"dIr" (nr) : "memory");
+ :"dIr" (nr), "m" (ADDR) : "memory");
return oldbit;
}
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index fd524f2..57230bf 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -46,6 +46,7 @@ struct request {
struct buffer_head * bh;
struct buffer_head * bhtail;
request_queue_t *q;
+ char io_account;
};
#include <linux/elevator.h>
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 0e01fef..28d25a3 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -410,19 +410,6 @@ static inline int sctp_list_single_entry
return ((head->next != head) && (head->next == head->prev));
}
-/* Calculate the size (in bytes) occupied by the data of an iovec. */
-static inline size_t get_user_iov_size(struct iovec *iov, int iovlen)
-{
- size_t retval = 0;
-
- for (; iovlen > 0; --iovlen) {
- retval += iov->iov_len;
- iov++;
- }
-
- return retval;
-}
-
/* Generate a random jitter in the range of -50% ~ +50% of input RTO. */
static inline __s32 sctp_jitter(__u32 rto)
{
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index 5576db5..9052ddd 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -221,8 +221,7 @@ struct sctp_chunk *sctp_make_abort_no_da
const struct sctp_chunk *,
__u32 tsn);
struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *,
- const struct sctp_chunk *,
- const struct msghdr *);
+ const struct msghdr *, size_t msg_len);
struct sctp_chunk *sctp_make_abort_violation(const struct sctp_association *,
const struct sctp_chunk *,
const __u8 *,
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 4d2a93a..bda5090 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -293,7 +293,7 @@ void * vmap(struct page **pages, int cou
struct vm_struct *area;
unsigned long size = count << PAGE_SHIFT;
- if (!size || size > (max_mapnr << PAGE_SHIFT))
+ if (count <= 0 || count > max_mapnr)
return NULL;
area = get_vm_area(size, flags);
if (!area) {
diff --git a/net/atm/clip.c b/net/atm/clip.c
index a7ded5b..5905d30 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -489,9 +489,11 @@ static int clip_mkip(struct atm_vcc *vcc
else {
unsigned int len = skb->len;
+ skb_get(skb);
clip_push(vcc,skb);
PRIV(skb->dev)->stats.rx_packets--;
PRIV(skb->dev)->stats.rx_bytes -= len;
+ kfree_skb(skb);
}
return 0;
}
diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c
index 5d61475..3de15aa 100644
--- a/net/bridge/br_stp.c
+++ b/net/bridge/br_stp.c
@@ -140,8 +140,8 @@ void br_become_root_bridge(struct net_br
br->forward_delay = br->bridge_forward_delay;
br_topology_change_detection(br);
br_timer_clear(&br->tcn_timer);
- br_config_bpdu_generation(br);
- br_timer_set(&br->hello_timer, jiffies);
+
+ br_timer_set(&br->hello_timer, jiffies - br->hello_time);
}
/* called under bridge lock */
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 1465093..75cce3f 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -510,6 +510,8 @@ static struct sk_buff *fill_packet(struc
skb->mac.raw = ((u8 *)iph) - 14;
skb->dev = odev;
skb->pkt_type = PACKET_HOST;
+ skb->nh.iph = iph;
+ skb->h.uh = udph;
if (info->nfrags <= 0) {
pgh = (struct pktgen_hdr *)skb_put(skb, datalen);
diff --git a/net/ipv4/netfilter/ip_nat_helper.c b/net/ipv4/netfilter/ip_nat_helper.c
index 6298d96..645f46d 100644
--- a/net/ipv4/netfilter/ip_nat_helper.c
+++ b/net/ipv4/netfilter/ip_nat_helper.c
@@ -522,13 +522,7 @@ int ip_nat_helper_register(struct ip_nat
static int
kill_helper(struct ip_conntrack *i, void *helper)
{
- int ret;
-
- READ_LOCK(&ip_nat_lock);
- ret = (i->nat.info.helper == helper);
- READ_UNLOCK(&ip_nat_lock);
-
- return ret;
+ return (i->nat.info.helper == helper);
}
void ip_nat_helper_unregister(struct ip_nat_helper *me)
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 9ae7175..4218a97 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -123,6 +123,9 @@ int sctp_rcv(struct sk_buff *skb)
SCTP_INC_STATS_BH(SctpInSCTPPacks);
+ if (skb_linearize(skb, GFP_ATOMIC) != 0)
+ goto discard_it;
+
sh = (struct sctphdr *) skb->h.raw;
/* Pull up the IP and SCTP headers. */
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 556dee6..08fe461 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -798,38 +798,26 @@ no_mem:
/* Helper to create ABORT with a SCTP_ERROR_USER_ABORT error. */
struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *asoc,
- const struct sctp_chunk *chunk,
- const struct msghdr *msg)
+ const struct msghdr *msg,
+ size_t paylen)
{
struct sctp_chunk *retval;
- void *payload = NULL, *payoff;
- size_t paylen = 0;
- struct iovec *iov = NULL;
- int iovlen = 0;
-
- if (msg) {
- iov = msg->msg_iov;
- iovlen = msg->msg_iovlen;
- paylen = get_user_iov_size(iov, iovlen);
- }
+ void *payload = NULL;
+ int err;
- retval = sctp_make_abort(asoc, chunk, sizeof(sctp_errhdr_t) + paylen);
+ retval = sctp_make_abort(asoc, NULL, sizeof(sctp_errhdr_t) + paylen);
if (!retval)
goto err_chunk;
if (paylen) {
/* Put the msg_iov together into payload. */
- payload = kmalloc(paylen, GFP_ATOMIC);
+ payload = kmalloc(paylen, GFP_KERNEL);
if (!payload)
goto err_payload;
- payoff = payload;
- for (; iovlen > 0; --iovlen) {
- if (copy_from_user(payoff, iov->iov_base,iov->iov_len))
- goto err_copy;
- payoff += iov->iov_len;
- iov++;
- }
+ err = memcpy_fromiovec(payload, msg->msg_iov, paylen);
+ if (err < 0)
+ goto err_copy;
}
sctp_init_cause(retval, SCTP_ERROR_USER_ABORT, payload, paylen);
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 542f375..992043f 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -3990,18 +3990,12 @@ sctp_disposition_t sctp_sf_do_9_1_prm_ab
* from its upper layer, but retransmits data to the far end
* if necessary to fill gaps.
*/
- struct msghdr *msg = arg;
- struct sctp_chunk *abort;
+ struct sctp_chunk *abort = arg;
sctp_disposition_t retval;
retval = SCTP_DISPOSITION_CONSUME;
- /* Generate ABORT chunk to send the peer. */
- abort = sctp_make_abort_user(asoc, NULL, msg);
- if (!abort)
- retval = SCTP_DISPOSITION_NOMEM;
- else
- sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
+ sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
/* Even if we can't send the ABORT due to low memory delete the
* TCB. This is a departure from our typical NOMEM handling.
@@ -4123,8 +4117,7 @@ sctp_disposition_t sctp_sf_cookie_wait_p
void *arg,
sctp_cmd_seq_t *commands)
{
- struct msghdr *msg = arg;
- struct sctp_chunk *abort;
+ struct sctp_chunk *abort = arg;
sctp_disposition_t retval;
/* Stop T1-init timer */
@@ -4132,12 +4125,7 @@ sctp_disposition_t sctp_sf_cookie_wait_p
SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
retval = SCTP_DISPOSITION_CONSUME;
- /* Generate ABORT chunk to send the peer */
- abort = sctp_make_abort_user(asoc, NULL, msg);
- if (!abort)
- retval = SCTP_DISPOSITION_NOMEM;
- else
- sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
+ sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
SCTP_STATE(SCTP_STATE_CLOSED));
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 277b19f..8d13849 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -967,9 +967,13 @@ SCTP_STATIC void sctp_close(struct sock
sctp_unhash_established(asoc);
sctp_association_free(asoc);
- } else if (sk->linger && !sk->lingertime)
- sctp_primitive_ABORT(asoc, NULL);
- else
+ } else if (sk->linger && !sk->lingertime) {
+ struct sctp_chunk *chunk;
+
+ chunk = sctp_make_abort_user(asoc, NULL, 0);
+ if (chunk)
+ sctp_primitive_ABORT(asoc, NULL);
+ } else
sctp_primitive_SHUTDOWN(asoc, NULL);
} else
sctp_primitive_SHUTDOWN(asoc, NULL);
@@ -1199,8 +1203,16 @@ SCTP_STATIC int sctp_sendmsg(struct sock
goto out_unlock;
}
if (sinfo_flags & MSG_ABORT) {
+ struct sctp_chunk *chunk;
+
+ chunk = sctp_make_abort_user(asoc, msg, msg_len);
+ if (!chunk) {
+ err = -ENOMEM;
+ goto out_unlock;
+ }
+
SCTP_DEBUG_PRINTK("Aborting association: %p\n", asoc);
- sctp_primitive_ABORT(asoc, msg);
+ sctp_primitive_ABORT(asoc, chunk);
err = 0;
goto out_unlock;
}
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index b5a1447..fcafbf7 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -807,7 +807,7 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp)
return 0;
}
- if (test_bit(SK_CONN, &svsk->sk_flags)) {
+ if (svsk->sk_sk->state == TCP_LISTEN) {
svc_tcp_accept(svsk);
svc_sock_received(svsk);
return 0;
www.fiveanddime.net