diff --git a/[refs] b/[refs] index a9f4277eb9f2..bde23ba071b2 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: ca45fe8ea86f7a1cf11a6d3bf8bba082be4ea341 +refs/heads/master: 46edfc54ee2cc60db0f10d982d6b9b7850733ff2 diff --git a/trunk/Documentation/devices.txt b/trunk/Documentation/devices.txt index 6c46730c631a..8de132a02ba9 100644 --- a/trunk/Documentation/devices.txt +++ b/trunk/Documentation/devices.txt @@ -94,8 +94,6 @@ Your cooperation is appreciated. 9 = /dev/urandom Faster, less secure random number gen. 10 = /dev/aio Asynchronous I/O notification interface 11 = /dev/kmsg Writes to this come out as printk's - 12 = /dev/oldmem Used by crashdump kernels to access - the memory of the kernel that crashed. 1 block RAM disk 0 = /dev/ram0 First RAM disk diff --git a/trunk/arch/arm/kernel/bios32.c b/trunk/arch/arm/kernel/bios32.c index 240c448ec31c..a2dd930d11ef 100644 --- a/trunk/arch/arm/kernel/bios32.c +++ b/trunk/arch/arm/kernel/bios32.c @@ -338,7 +338,7 @@ pbus_assign_bus_resources(struct pci_bus *bus, struct pci_sys_data *root) * pcibios_fixup_bus - Called after each bus is probed, * but before its children are examined. */ -void __devinit pcibios_fixup_bus(struct pci_bus *bus) +void pcibios_fixup_bus(struct pci_bus *bus) { struct pci_sys_data *root = bus->sysdata; struct pci_dev *dev; @@ -419,7 +419,7 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus) /* * Convert from Linux-centric to bus-centric addresses for bridge devices. */ -void __devinit +void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, struct resource *res) { diff --git a/trunk/drivers/char/vt_ioctl.c b/trunk/drivers/char/vt_ioctl.c index c799b7f7bbb3..045e6888d15b 100644 --- a/trunk/drivers/char/vt_ioctl.c +++ b/trunk/drivers/char/vt_ioctl.c @@ -770,7 +770,6 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, /* * Switching-from response */ - acquire_console_sem(); if (vc->vt_newvt >= 0) { if (arg == 0) /* @@ -785,6 +784,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, * complete the switch. */ int newvt; + acquire_console_sem(); newvt = vc->vt_newvt; vc->vt_newvt = -1; i = vc_allocate(newvt); @@ -798,6 +798,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, * other console switches.. */ complete_change_console(vc_cons[newvt].d); + release_console_sem(); } } @@ -809,12 +810,9 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, /* * If it's just an ACK, ignore it */ - if (arg != VT_ACKACQ) { - release_console_sem(); + if (arg != VT_ACKACQ) return -EINVAL; - } } - release_console_sem(); return 0; diff --git a/trunk/drivers/media/video/ivtv/ivtv-fileops.c b/trunk/drivers/media/video/ivtv/ivtv-fileops.c index 66ea3cbc369c..0285c4a830eb 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-fileops.c +++ b/trunk/drivers/media/video/ivtv/ivtv-fileops.c @@ -754,11 +754,9 @@ static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts) ivtv_yuv_close(itv); } if (s->type == IVTV_DEC_STREAM_TYPE_YUV && itv->output_mode == OUT_YUV) - itv->output_mode = OUT_NONE; - else if (s->type == IVTV_DEC_STREAM_TYPE_YUV && itv->output_mode == OUT_UDMA_YUV) - itv->output_mode = OUT_NONE; + itv->output_mode = OUT_NONE; else if (s->type == IVTV_DEC_STREAM_TYPE_MPG && itv->output_mode == OUT_MPG) - itv->output_mode = OUT_NONE; + itv->output_mode = OUT_NONE; itv->speed = 0; clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags); diff --git a/trunk/fs/xfs/xfs_buf_item.h b/trunk/fs/xfs/xfs_buf_item.h index d7e136143066..fa25b7dcc6c3 100644 --- a/trunk/fs/xfs/xfs_buf_item.h +++ b/trunk/fs/xfs/xfs_buf_item.h @@ -52,6 +52,11 @@ typedef struct xfs_buf_log_format_t { #define XFS_BLI_UDQUOT_BUF 0x4 #define XFS_BLI_PDQUOT_BUF 0x8 #define XFS_BLI_GDQUOT_BUF 0x10 +/* + * This flag indicates that the buffer contains newly allocated + * inodes. + */ +#define XFS_BLI_INODE_NEW_BUF 0x20 #define XFS_BLI_CHUNK 128 #define XFS_BLI_SHIFT 7 diff --git a/trunk/fs/xfs/xfs_log_recover.c b/trunk/fs/xfs/xfs_log_recover.c index 8ae6e8e5f3db..7174991f4bef 100644 --- a/trunk/fs/xfs/xfs_log_recover.c +++ b/trunk/fs/xfs/xfs_log_recover.c @@ -1874,6 +1874,7 @@ xlog_recover_do_inode_buffer( /*ARGSUSED*/ STATIC void xlog_recover_do_reg_buffer( + xfs_mount_t *mp, xlog_recover_item_t *item, xfs_buf_t *bp, xfs_buf_log_format_t *buf_f) @@ -1884,6 +1885,50 @@ xlog_recover_do_reg_buffer( unsigned int *data_map = NULL; unsigned int map_size = 0; int error; + int stale_buf = 1; + + /* + * Scan through the on-disk inode buffer and attempt to + * determine if it has been written to since it was logged. + * + * - If any of the magic numbers are incorrect then the buffer is stale + * - If any of the modes are non-zero then the buffer is not stale + * - If all of the modes are zero and at least one of the generation + * counts is non-zero then the buffer is stale + * + * If the end result is a stale buffer then the log buffer is replayed + * otherwise it is skipped. + * + * This heuristic is not perfect. It can be improved by scanning the + * entire inode chunk for evidence that any of the inode clusters have + * been updated. To fix this problem completely we will need a major + * architectural change to the logging system. + */ + if (buf_f->blf_flags & XFS_BLI_INODE_NEW_BUF) { + xfs_dinode_t *dip; + int inodes_per_buf; + int mode_count = 0; + int gen_count = 0; + + stale_buf = 0; + inodes_per_buf = XFS_BUF_COUNT(bp) >> mp->m_sb.sb_inodelog; + for (i = 0; i < inodes_per_buf; i++) { + dip = (xfs_dinode_t *)xfs_buf_offset(bp, + i * mp->m_sb.sb_inodesize); + if (be16_to_cpu(dip->di_core.di_magic) != + XFS_DINODE_MAGIC) { + stale_buf = 1; + break; + } + if (dip->di_core.di_mode) + mode_count++; + if (dip->di_core.di_gen) + gen_count++; + } + + if (!mode_count && gen_count) + stale_buf = 1; + } switch (buf_f->blf_type) { case XFS_LI_BUF: @@ -1917,7 +1962,7 @@ xlog_recover_do_reg_buffer( -1, 0, XFS_QMOPT_DOWARN, "dquot_buf_recover"); } - if (!error) + if (!error && stale_buf) memcpy(xfs_buf_offset(bp, (uint)bit << XFS_BLI_SHIFT), /* dest */ item->ri_buf[i].i_addr, /* source */ @@ -2089,7 +2134,7 @@ xlog_recover_do_dquot_buffer( if (log->l_quotaoffs_flag & type) return; - xlog_recover_do_reg_buffer(item, bp, buf_f); + xlog_recover_do_reg_buffer(mp, item, bp, buf_f); } /* @@ -2190,7 +2235,7 @@ xlog_recover_do_buffer_trans( (XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) { xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f); } else { - xlog_recover_do_reg_buffer(item, bp, buf_f); + xlog_recover_do_reg_buffer(mp, item, bp, buf_f); } if (error) return XFS_ERROR(error); diff --git a/trunk/fs/xfs/xfs_trans_buf.c b/trunk/fs/xfs/xfs_trans_buf.c index 60b6b898022b..95fff6872a2f 100644 --- a/trunk/fs/xfs/xfs_trans_buf.c +++ b/trunk/fs/xfs/xfs_trans_buf.c @@ -966,6 +966,7 @@ xfs_trans_inode_alloc_buf( ASSERT(atomic_read(&bip->bli_refcount) > 0); bip->bli_flags |= XFS_BLI_INODE_ALLOC_BUF; + bip->bli_format.blf_flags |= XFS_BLI_INODE_NEW_BUF; } diff --git a/trunk/kernel/futex.c b/trunk/kernel/futex.c index fcc94e7b4086..e8935b195e88 100644 --- a/trunk/kernel/futex.c +++ b/trunk/kernel/futex.c @@ -1943,10 +1943,9 @@ static inline int fetch_robust_entry(struct robust_list __user **entry, void exit_robust_list(struct task_struct *curr) { struct robust_list_head __user *head = curr->robust_list; - struct robust_list __user *entry, *next_entry, *pending; - unsigned int limit = ROBUST_LIST_LIMIT, pi, next_pi, pip; + struct robust_list __user *entry, *pending; + unsigned int limit = ROBUST_LIST_LIMIT, pi, pip; unsigned long futex_offset; - int rc; /* * Fetch the list head (which was registered earlier, via @@ -1966,13 +1965,11 @@ void exit_robust_list(struct task_struct *curr) if (fetch_robust_entry(&pending, &head->list_op_pending, &pip)) return; - next_entry = NULL; /* avoid warning with gcc */ + if (pending) + handle_futex_death((void __user *)pending + futex_offset, + curr, pip); + while (entry != &head->list) { - /* - * Fetch the next entry in the list before calling - * handle_futex_death: - */ - rc = fetch_robust_entry(&next_entry, &entry->next, &next_pi); /* * A pending lock might already be on the list, so * don't process it twice: @@ -1981,10 +1978,11 @@ void exit_robust_list(struct task_struct *curr) if (handle_futex_death((void __user *)entry + futex_offset, curr, pi)) return; - if (rc) + /* + * Fetch the next entry in the list: + */ + if (fetch_robust_entry(&entry, &entry->next, &pi)) return; - entry = next_entry; - pi = next_pi; /* * Avoid excessively long or circular lists: */ @@ -1993,10 +1991,6 @@ void exit_robust_list(struct task_struct *curr) cond_resched(); } - - if (pending) - handle_futex_death((void __user *)pending + futex_offset, - curr, pip); } long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, diff --git a/trunk/kernel/futex_compat.c b/trunk/kernel/futex_compat.c index 2c2e2954b713..7e52eb051f22 100644 --- a/trunk/kernel/futex_compat.c +++ b/trunk/kernel/futex_compat.c @@ -38,11 +38,10 @@ fetch_robust_entry(compat_uptr_t *uentry, struct robust_list __user **entry, void compat_exit_robust_list(struct task_struct *curr) { struct compat_robust_list_head __user *head = curr->compat_robust_list; - struct robust_list __user *entry, *next_entry, *pending; - unsigned int limit = ROBUST_LIST_LIMIT, pi, next_pi, pip; - compat_uptr_t uentry, next_uentry, upending; + struct robust_list __user *entry, *pending; + unsigned int limit = ROBUST_LIST_LIMIT, pi, pip; + compat_uptr_t uentry, upending; compat_long_t futex_offset; - int rc; /* * Fetch the list head (which was registered earlier, via @@ -62,15 +61,10 @@ void compat_exit_robust_list(struct task_struct *curr) if (fetch_robust_entry(&upending, &pending, &head->list_op_pending, &pip)) return; + if (pending) + handle_futex_death((void __user *)pending + futex_offset, curr, pip); - next_entry = NULL; /* avoid warning with gcc */ while (entry != (struct robust_list __user *) &head->list) { - /* - * Fetch the next entry in the list before calling - * handle_futex_death: - */ - rc = fetch_robust_entry(&next_uentry, &next_entry, - (compat_uptr_t __user *)&entry->next, &next_pi); /* * A pending lock might already be on the list, so * dont process it twice: @@ -80,11 +74,12 @@ void compat_exit_robust_list(struct task_struct *curr) curr, pi)) return; - if (rc) + /* + * Fetch the next entry in the list: + */ + if (fetch_robust_entry(&uentry, &entry, + (compat_uptr_t __user *)&entry->next, &pi)) return; - uentry = next_uentry; - entry = next_entry; - pi = next_pi; /* * Avoid excessively long or circular lists: */ @@ -93,9 +88,6 @@ void compat_exit_robust_list(struct task_struct *curr) cond_resched(); } - if (pending) - handle_futex_death((void __user *)pending + futex_offset, - curr, pip); } asmlinkage long diff --git a/trunk/kernel/sys.c b/trunk/kernel/sys.c index 8ae2e636eb1b..1b33b05d346b 100644 --- a/trunk/kernel/sys.c +++ b/trunk/kernel/sys.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include @@ -879,7 +878,6 @@ void kernel_power_off(void) kernel_shutdown_prepare(SYSTEM_POWER_OFF); if (pm_power_off_prepare) pm_power_off_prepare(); - disable_nonboot_cpus(); sysdev_shutdown(); printk(KERN_EMERG "Power down.\n"); machine_power_off(); diff --git a/trunk/mm/hugetlb.c b/trunk/mm/hugetlb.c index eab8c428cc93..84c795ee2d65 100644 --- a/trunk/mm/hugetlb.c +++ b/trunk/mm/hugetlb.c @@ -42,7 +42,7 @@ static void clear_huge_page(struct page *page, unsigned long addr) might_sleep(); for (i = 0; i < (HPAGE_SIZE/PAGE_SIZE); i++) { cond_resched(); - clear_user_highpage(page + i, addr + i * PAGE_SIZE); + clear_user_highpage(page + i, addr); } }