diff --git a/[refs] b/[refs] index aa1e402e626b..a7b99cd5033a 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: f187a4514f54382ab017e8630d7d1f51732dabd8 +refs/heads/master: 044b9414c7caf9a26192c73a5b88fa1a8a32a1c1 diff --git a/trunk/Documentation/arm/OMAP/DSS b/trunk/Documentation/arm/OMAP/DSS index 888ae7b83ae4..0af0e9eed5d6 100644 --- a/trunk/Documentation/arm/OMAP/DSS +++ b/trunk/Documentation/arm/OMAP/DSS @@ -255,10 +255,9 @@ framebuffer parameters. Kernel boot arguments --------------------- -vram=[,] - - Amount of total VRAM to preallocate and optionally a physical start - memory address. For example, "10M". omapfb allocates memory for - framebuffers from VRAM. +vram= + - Amount of total VRAM to preallocate. For example, "10M". omapfb + allocates memory for framebuffers from VRAM. omapfb.mode=:[,...] - Default video mode for specified displays. For example, diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 8e6548dbd5db..88b74a75d932 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -945,7 +945,7 @@ M: Magnus Damm L: linux-sh@vger.kernel.org W: http://oss.renesas.com Q: http://patchwork.kernel.org/project/linux-sh/list/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6.git rmobile-latest +T: git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/genesis-2.6.git S: Supported F: arch/arm/mach-shmobile/ F: drivers/sh/ @@ -2435,7 +2435,6 @@ F: drivers/net/wan/sdla.c FRAMEBUFFER LAYER L: linux-fbdev@vger.kernel.org W: http://linux-fbdev.sourceforge.net/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-2.6.git S: Orphan F: Documentation/fb/ F: drivers/video/fb* @@ -5706,7 +5705,7 @@ M: Paul Mundt L: linux-sh@vger.kernel.org W: http://www.linux-sh.org Q: http://patchwork.kernel.org/project/linux-sh/list/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6.git sh-latest +T: git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6.git S: Supported F: Documentation/sh/ F: arch/sh/ diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index db524e75c4a2..8ae3d48d504c 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -646,7 +646,7 @@ config ARCH_S3C2410 select ARCH_HAS_CPUFREQ select HAVE_CLK select ARCH_USES_GETTIMEOFFSET - select HAVE_S3C2410_I2C if I2C + select HAVE_S3C2410_I2C help Samsung S3C2410X CPU based systems, such as the Simtec Electronics BAST (), the IPAQ 1940 or @@ -676,8 +676,8 @@ config ARCH_S3C64XX select S3C_DEV_NAND select USB_ARCH_HAS_OHCI select SAMSUNG_GPIOLIB_4BIT - select HAVE_S3C2410_I2C if I2C - select HAVE_S3C2410_WATCHDOG if WATCHDOG + select HAVE_S3C2410_I2C + select HAVE_S3C2410_WATCHDOG help Samsung S3C64XX series based systems @@ -686,10 +686,10 @@ config ARCH_S5P64X0 select CPU_V6 select GENERIC_GPIO select HAVE_CLK - select HAVE_S3C2410_WATCHDOG if WATCHDOG + select HAVE_S3C2410_WATCHDOG select ARCH_USES_GETTIMEOFFSET - select HAVE_S3C2410_I2C if I2C - select HAVE_S3C_RTC if RTC_CLASS + select HAVE_S3C2410_I2C + select HAVE_S3C_RTC help Samsung S5P64X0 CPU based systems, such as the Samsung SMDK6440, SMDK6450. @@ -700,7 +700,7 @@ config ARCH_S5P6442 select GENERIC_GPIO select HAVE_CLK select ARCH_USES_GETTIMEOFFSET - select HAVE_S3C2410_WATCHDOG if WATCHDOG + select HAVE_S3C2410_WATCHDOG help Samsung S5P6442 CPU based systems @@ -711,9 +711,9 @@ config ARCH_S5PC100 select CPU_V7 select ARM_L1_CACHE_SHIFT_6 select ARCH_USES_GETTIMEOFFSET - select HAVE_S3C2410_I2C if I2C - select HAVE_S3C_RTC if RTC_CLASS - select HAVE_S3C2410_WATCHDOG if WATCHDOG + select HAVE_S3C2410_I2C + select HAVE_S3C_RTC + select HAVE_S3C2410_WATCHDOG help Samsung S5PC100 series based systems @@ -726,9 +726,9 @@ config ARCH_S5PV210 select ARM_L1_CACHE_SHIFT_6 select ARCH_HAS_CPUFREQ select ARCH_USES_GETTIMEOFFSET - select HAVE_S3C2410_I2C if I2C - select HAVE_S3C_RTC if RTC_CLASS - select HAVE_S3C2410_WATCHDOG if WATCHDOG + select HAVE_S3C2410_I2C + select HAVE_S3C_RTC + select HAVE_S3C2410_WATCHDOG help Samsung S5PV210/S5PC110 series based systems @@ -739,9 +739,9 @@ config ARCH_S5PV310 select GENERIC_GPIO select HAVE_CLK select GENERIC_CLOCKEVENTS - select HAVE_S3C_RTC if RTC_CLASS - select HAVE_S3C2410_I2C if I2C - select HAVE_S3C2410_WATCHDOG if WATCHDOG + select HAVE_S3C_RTC + select HAVE_S3C2410_I2C + select HAVE_S3C2410_WATCHDOG help Samsung S5PV310 series based systems diff --git a/trunk/arch/arm/mach-s3c64xx/Kconfig b/trunk/arch/arm/mach-s3c64xx/Kconfig index 579d2f0f4dd0..1ca7bdc6485c 100644 --- a/trunk/arch/arm/mach-s3c64xx/Kconfig +++ b/trunk/arch/arm/mach-s3c64xx/Kconfig @@ -143,7 +143,7 @@ config MACH_SMDK6410 select S3C_DEV_USB_HSOTG select S3C_DEV_WDT select SAMSUNG_DEV_KEYPAD - select HAVE_S3C2410_WATCHDOG if WATCHDOG + select HAVE_S3C2410_WATCHDOG select S3C64XX_SETUP_SDHCI select S3C64XX_SETUP_I2C1 select S3C64XX_SETUP_IDE diff --git a/trunk/arch/arm/mach-shmobile/board-ap4evb.c b/trunk/arch/arm/mach-shmobile/board-ap4evb.c index d3260542b943..32d9e2816e56 100644 --- a/trunk/arch/arm/mach-shmobile/board-ap4evb.c +++ b/trunk/arch/arm/mach-shmobile/board-ap4evb.c @@ -163,13 +163,11 @@ static struct mtd_partition nor_flash_partitions[] = { .name = "loader", .offset = 0x00000000, .size = 512 * 1024, - .mask_flags = MTD_WRITEABLE, }, { .name = "bootenv", .offset = MTDPART_OFS_APPEND, .size = 512 * 1024, - .mask_flags = MTD_WRITEABLE, }, { .name = "kernel_ro", @@ -583,10 +581,6 @@ static int fsi_set_rate(int is_porta, int rate) return -EINVAL; switch (rate) { - case 44100: - clk_set_rate(fsib_clk, clk_round_rate(fsib_clk, 11283000)); - ret = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64; - break; case 48000: clk_set_rate(fsib_clk, clk_round_rate(fsib_clk, 85428000)); clk_set_rate(fdiv_clk, clk_round_rate(fdiv_clk, 12204000)); diff --git a/trunk/arch/arm/mach-shmobile/intc-sh7372.c b/trunk/arch/arm/mach-shmobile/intc-sh7372.c index 30b2f400666a..4cd3cae38e72 100644 --- a/trunk/arch/arm/mach-shmobile/intc-sh7372.c +++ b/trunk/arch/arm/mach-shmobile/intc-sh7372.c @@ -98,7 +98,7 @@ static struct intc_vect intca_vectors[] __initdata = { INTC_VECT(IRQ14A, 0x03c0), INTC_VECT(IRQ15A, 0x03e0), INTC_VECT(IRQ16A, 0x3200), INTC_VECT(IRQ17A, 0x3220), INTC_VECT(IRQ18A, 0x3240), INTC_VECT(IRQ19A, 0x3260), - INTC_VECT(IRQ20A, 0x3280), INTC_VECT(IRQ21A, 0x32a0), + INTC_VECT(IRQ20A, 0x3280), INTC_VECT(IRQ31A, 0x32a0), INTC_VECT(IRQ22A, 0x32c0), INTC_VECT(IRQ23A, 0x32e0), INTC_VECT(IRQ24A, 0x3300), INTC_VECT(IRQ25A, 0x3320), INTC_VECT(IRQ26A, 0x3340), INTC_VECT(IRQ27A, 0x3360), diff --git a/trunk/drivers/rtc/rtc-sh.c b/trunk/drivers/rtc/rtc-sh.c index 06e41ed93230..5efbd5990ff8 100644 --- a/trunk/drivers/rtc/rtc-sh.c +++ b/trunk/drivers/rtc/rtc-sh.c @@ -761,7 +761,7 @@ static int __init sh_rtc_probe(struct platform_device *pdev) clk_put(rtc->clk); iounmap(rtc->regbase); err_badmap: - release_mem_region(rtc->res->start, rtc->regsize); + release_resource(rtc->res); err_badres: kfree(rtc); @@ -786,7 +786,7 @@ static int __exit sh_rtc_remove(struct platform_device *pdev) } iounmap(rtc->regbase); - release_mem_region(rtc->res->start, rtc->regsize); + release_resource(rtc->res); clk_disable(rtc->clk); clk_put(rtc->clk); diff --git a/trunk/drivers/sh/clk/core.c b/trunk/drivers/sh/clk/core.c index cb12a8e1466b..09615b51d591 100644 --- a/trunk/drivers/sh/clk/core.c +++ b/trunk/drivers/sh/clk/core.c @@ -571,7 +571,7 @@ long clk_round_parent(struct clk *clk, unsigned long target, *best_freq = freq_max; } - pr_debug("too low freq %u, error %lu\n", freq->frequency, + pr_debug("too low freq %lu, error %lu\n", freq->frequency, target - freq_max); if (!error) @@ -591,7 +591,7 @@ long clk_round_parent(struct clk *clk, unsigned long target, *best_freq = freq_min; } - pr_debug("too high freq %u, error %lu\n", freq->frequency, + pr_debug("too high freq %lu, error %lu\n", freq->frequency, freq_min - target); if (!error) diff --git a/trunk/drivers/sh/intc/virq.c b/trunk/drivers/sh/intc/virq.c index 4e0ff7181164..e5bf5d3c698e 100644 --- a/trunk/drivers/sh/intc/virq.c +++ b/trunk/drivers/sh/intc/virq.c @@ -215,7 +215,7 @@ static void __init intc_subgroup_map(struct intc_desc_int *d) entry = radix_tree_deref_slot((void **)entries[i]); if (unlikely(!entry)) continue; - if (radix_tree_deref_retry(entry)) + if (unlikely(entry == RADIX_TREE_RETRY)) goto restart; irq = create_irq(); diff --git a/trunk/drivers/video/omap2/vram.c b/trunk/drivers/video/omap2/vram.c index 2fd7e5271be9..fed2a72bc6b6 100644 --- a/trunk/drivers/video/omap2/vram.c +++ b/trunk/drivers/video/omap2/vram.c @@ -554,15 +554,9 @@ void __init omap_vram_reserve_sdram_memblock(void) size = PAGE_ALIGN(size); if (paddr) { - if (paddr & ~PAGE_MASK) { - pr_err("VRAM start address 0x%08x not page aligned\n", - paddr); - return; - } - - if (!memblock_is_region_memory(paddr, size)) { - pr_err("Illegal SDRAM region 0x%08x..0x%08x for VRAM\n", - paddr, paddr + size - 1); + if ((paddr & ~PAGE_MASK) || + !memblock_is_region_memory(paddr, size)) { + pr_err("Illegal SDRAM region for VRAM\n"); return; } @@ -576,12 +570,9 @@ void __init omap_vram_reserve_sdram_memblock(void) return; } } else { - paddr = memblock_alloc(size, PAGE_SIZE); + paddr = memblock_alloc_base(size, PAGE_SIZE, MEMBLOCK_REAL_LIMIT); } - memblock_free(paddr, size); - memblock_remove(paddr, size); - omap_vram_add_region(paddr, size); pr_info("Reserving %u bytes SDRAM for VRAM\n", size); diff --git a/trunk/drivers/video/sh_mobile_hdmi.c b/trunk/drivers/video/sh_mobile_hdmi.c index d7df10315d8d..55b3077ff6ff 100644 --- a/trunk/drivers/video/sh_mobile_hdmi.c +++ b/trunk/drivers/video/sh_mobile_hdmi.c @@ -1071,10 +1071,6 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work) if (!hdmi->info) goto out; - hdmi->monspec.modedb_len = 0; - fb_destroy_modedb(hdmi->monspec.modedb); - hdmi->monspec.modedb = NULL; - acquire_console_sem(); /* HDMI disconnect */ @@ -1082,6 +1078,7 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work) release_console_sem(); pm_runtime_put(hdmi->dev); + fb_destroy_modedb(hdmi->monspec.modedb); } out: diff --git a/trunk/drivers/video/sh_mobile_lcdcfb.c b/trunk/drivers/video/sh_mobile_lcdcfb.c index 9b1364723c65..50963739a409 100644 --- a/trunk/drivers/video/sh_mobile_lcdcfb.c +++ b/trunk/drivers/video/sh_mobile_lcdcfb.c @@ -115,16 +115,15 @@ static const struct fb_videomode default_720p = { .xres = 1280, .yres = 720, - .left_margin = 220, - .right_margin = 110, - .hsync_len = 40, + .left_margin = 200, + .right_margin = 88, + .hsync_len = 48, .upper_margin = 20, .lower_margin = 5, .vsync_len = 5, .pixclock = 13468, - .refresh = 60, .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT, }; @@ -1198,7 +1197,6 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) const struct fb_videomode *mode = cfg->lcd_cfg; unsigned long max_size = 0; int k; - int num_cfg; ch->info = framebuffer_alloc(0, &pdev->dev); if (!ch->info) { @@ -1234,14 +1232,8 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) info->fix = sh_mobile_lcdc_fix; info->fix.smem_len = max_size * (cfg->bpp / 8) * 2; - if (!mode) { + if (!mode) mode = &default_720p; - num_cfg = 1; - } else { - num_cfg = ch->cfg.num_cfg; - } - - fb_videomode_to_modelist(mode, num_cfg, &info->modelist); fb_videomode_to_var(var, mode); /* Default Y virtual resolution is 2x panel size */ @@ -1289,6 +1281,10 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) for (i = 0; i < j; i++) { struct sh_mobile_lcdc_chan *ch = priv->ch + i; + const struct fb_videomode *mode = ch->cfg.lcd_cfg; + + if (!mode) + mode = &default_720p; info = ch->info; @@ -1301,6 +1297,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) } } + fb_videomode_to_modelist(mode, ch->cfg.num_cfg, &info->modelist); error = register_framebuffer(info); if (error < 0) goto err1; diff --git a/trunk/drivers/video/sis/sis_main.c b/trunk/drivers/video/sis/sis_main.c index 3dde12b0ab06..b52f8e4ef1fd 100644 --- a/trunk/drivers/video/sis/sis_main.c +++ b/trunk/drivers/video/sis/sis_main.c @@ -4181,9 +4181,6 @@ static void __devinit sisfb_post_map_vram(struct sis_video_info *ivideo, unsigned int *mapsize, unsigned int min) { - if (*mapsize < (min << 20)) - return; - ivideo->video_vbase = ioremap(ivideo->video_base, (*mapsize)); if(!ivideo->video_vbase) { @@ -4517,7 +4514,7 @@ sisfb_post_sis300(struct pci_dev *pdev) } else { #endif /* Need to map max FB size for finding out about RAM size */ - mapsize = ivideo->video_size; + mapsize = 64 << 20; sisfb_post_map_vram(ivideo, &mapsize, 4); if(ivideo->video_vbase) { @@ -4683,7 +4680,7 @@ sisfb_post_xgi_ramsize(struct sis_video_info *ivideo) orSISIDXREG(SISSR, 0x20, (0x80 | 0x04)); /* Need to map max FB size for finding out about RAM size */ - mapsize = ivideo->video_size; + mapsize = 256 << 20; sisfb_post_map_vram(ivideo, &mapsize, 32); if(!ivideo->video_vbase) { @@ -5939,7 +5936,6 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } ivideo->video_base = pci_resource_start(pdev, 0); - ivideo->video_size = pci_resource_len(pdev, 0); ivideo->mmio_base = pci_resource_start(pdev, 1); ivideo->mmio_size = pci_resource_len(pdev, 1); ivideo->SiS_Pr.RelIO = pci_resource_start(pdev, 2) + 0x30; diff --git a/trunk/fs/gfs2/export.c b/trunk/fs/gfs2/export.c index 06d582732d34..5ab3839dfcb9 100644 --- a/trunk/fs/gfs2/export.c +++ b/trunk/fs/gfs2/export.c @@ -138,10 +138,8 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, struct gfs2_inum_host *inum) { struct gfs2_sbd *sdp = sb->s_fs_info; - struct gfs2_holder i_gh; struct inode *inode; struct dentry *dentry; - int error; inode = gfs2_ilookup(sb, inum->no_addr); if (inode) { @@ -152,52 +150,16 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, goto out_inode; } - error = gfs2_glock_nq_num(sdp, inum->no_addr, &gfs2_inode_glops, - LM_ST_SHARED, LM_FLAG_ANY, &i_gh); - if (error) - return ERR_PTR(error); - - error = gfs2_check_blk_type(sdp, inum->no_addr, GFS2_BLKST_DINODE); - if (error) - goto fail; - - inode = gfs2_inode_lookup(sb, DT_UNKNOWN, inum->no_addr, 0); - if (IS_ERR(inode)) { - error = PTR_ERR(inode); - goto fail; - } - - error = gfs2_inode_refresh(GFS2_I(inode)); - if (error) { - iput(inode); - goto fail; - } - - /* Pick up the works we bypass in gfs2_inode_lookup */ - if (inode->i_state & I_NEW) - gfs2_set_iop(inode); - - if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) { - iput(inode); - goto fail; - } - - error = -EIO; - if (GFS2_I(inode)->i_diskflags & GFS2_DIF_SYSTEM) { - iput(inode); - goto fail; - } - - gfs2_glock_dq_uninit(&i_gh); + inode = gfs2_lookup_by_inum(sdp, inum->no_addr, &inum->no_formal_ino, + GFS2_BLKST_DINODE); + if (IS_ERR(inode)) + return ERR_CAST(inode); out_inode: dentry = d_obtain_alias(inode); if (!IS_ERR(dentry)) dentry->d_op = &gfs2_dops; return dentry; -fail: - gfs2_glock_dq_uninit(&i_gh); - return ERR_PTR(error); } static struct dentry *gfs2_fh_to_dentry(struct super_block *sb, struct fid *fid, diff --git a/trunk/fs/gfs2/glock.c b/trunk/fs/gfs2/glock.c index 87778857f099..f92c17704169 100644 --- a/trunk/fs/gfs2/glock.c +++ b/trunk/fs/gfs2/glock.c @@ -686,21 +686,20 @@ static void delete_work_func(struct work_struct *work) { struct gfs2_glock *gl = container_of(work, struct gfs2_glock, gl_delete); struct gfs2_sbd *sdp = gl->gl_sbd; - struct gfs2_inode *ip = NULL; + struct gfs2_inode *ip; struct inode *inode; - u64 no_addr = 0; + u64 no_addr = gl->gl_name.ln_number; + + ip = gl->gl_object; + /* Note: Unsafe to dereference ip as we don't hold right refs/locks */ - spin_lock(&gl->gl_spin); - ip = (struct gfs2_inode *)gl->gl_object; if (ip) - no_addr = ip->i_no_addr; - spin_unlock(&gl->gl_spin); - if (ip) { inode = gfs2_ilookup(sdp->sd_vfs, no_addr); - if (inode) { - d_prune_aliases(inode); - iput(inode); - } + else + inode = gfs2_lookup_by_inum(sdp, no_addr, NULL, GFS2_BLKST_UNLINKED); + if (inode && !IS_ERR(inode)) { + d_prune_aliases(inode); + iput(inode); } gfs2_glock_put(gl); } diff --git a/trunk/fs/gfs2/inode.c b/trunk/fs/gfs2/inode.c index 06370f8bd8cf..e1213f7f9217 100644 --- a/trunk/fs/gfs2/inode.c +++ b/trunk/fs/gfs2/inode.c @@ -73,49 +73,6 @@ static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr) return iget5_locked(sb, hash, iget_test, iget_set, &no_addr); } -struct gfs2_skip_data { - u64 no_addr; - int skipped; -}; - -static int iget_skip_test(struct inode *inode, void *opaque) -{ - struct gfs2_inode *ip = GFS2_I(inode); - struct gfs2_skip_data *data = opaque; - - if (ip->i_no_addr == data->no_addr) { - if (inode->i_state & (I_FREEING|I_WILL_FREE)){ - data->skipped = 1; - return 0; - } - return 1; - } - return 0; -} - -static int iget_skip_set(struct inode *inode, void *opaque) -{ - struct gfs2_inode *ip = GFS2_I(inode); - struct gfs2_skip_data *data = opaque; - - if (data->skipped) - return 1; - inode->i_ino = (unsigned long)(data->no_addr); - ip->i_no_addr = data->no_addr; - return 0; -} - -static struct inode *gfs2_iget_skip(struct super_block *sb, - u64 no_addr) -{ - struct gfs2_skip_data data; - unsigned long hash = (unsigned long)no_addr; - - data.no_addr = no_addr; - data.skipped = 0; - return iget5_locked(sb, hash, iget_skip_test, iget_skip_set, &data); -} - /** * GFS2 lookup code fills in vfs inode contents based on info obtained * from directory entry inside gfs2_inode_lookup(). This has caused issues @@ -243,93 +200,54 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, return ERR_PTR(error); } -/** - * gfs2_process_unlinked_inode - Lookup an unlinked inode for reclamation - * and try to reclaim it by doing iput. - * - * This function assumes no rgrp locks are currently held. - * - * @sb: The super block - * no_addr: The inode number - * - */ - -void gfs2_process_unlinked_inode(struct super_block *sb, u64 no_addr) +struct inode *gfs2_lookup_by_inum(struct gfs2_sbd *sdp, u64 no_addr, + u64 *no_formal_ino, unsigned int blktype) { - struct gfs2_sbd *sdp; - struct gfs2_inode *ip; - struct gfs2_glock *io_gl = NULL; - int error; - struct gfs2_holder gh; + struct super_block *sb = sdp->sd_vfs; + struct gfs2_holder i_gh; struct inode *inode; + int error; - inode = gfs2_iget_skip(sb, no_addr); - - if (!inode) - return; - - /* If it's not a new inode, someone's using it, so leave it alone. */ - if (!(inode->i_state & I_NEW)) { - iput(inode); - return; - } - - ip = GFS2_I(inode); - sdp = GFS2_SB(inode); - ip->i_no_formal_ino = -1; + error = gfs2_glock_nq_num(sdp, no_addr, &gfs2_inode_glops, + LM_ST_SHARED, LM_FLAG_ANY, &i_gh); + if (error) + return ERR_PTR(error); - error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); - if (unlikely(error)) + error = gfs2_check_blk_type(sdp, no_addr, blktype); + if (error) goto fail; - ip->i_gl->gl_object = ip; - error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl); - if (unlikely(error)) - goto fail_put; - - set_bit(GIF_INVALID, &ip->i_flags); - error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, LM_FLAG_TRY | GL_EXACT, - &ip->i_iopen_gh); - if (unlikely(error)) - goto fail_iopen; + inode = gfs2_inode_lookup(sb, DT_UNKNOWN, no_addr, 0); + if (IS_ERR(inode)) + goto fail; - ip->i_iopen_gh.gh_gl->gl_object = ip; - gfs2_glock_put(io_gl); - io_gl = NULL; + error = gfs2_inode_refresh(GFS2_I(inode)); + if (error) + goto fail_iput; - inode->i_mode = DT2IF(DT_UNKNOWN); + /* Pick up the works we bypass in gfs2_inode_lookup */ + if (inode->i_state & I_NEW) + gfs2_set_iop(inode); - /* - * We must read the inode in order to work out its type in - * this case. Note that this doesn't happen often as we normally - * know the type beforehand. This code path only occurs during - * unlinked inode recovery (where it is safe to do this glock, - * which is not true in the general case). - */ - error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY, - &gh); - if (unlikely(error)) - goto fail_glock; + /* Two extra checks for NFS only */ + if (no_formal_ino) { + error = -ESTALE; + if (GFS2_I(inode)->i_no_formal_ino != *no_formal_ino) + goto fail_iput; - /* Inode is now uptodate */ - gfs2_glock_dq_uninit(&gh); - gfs2_set_iop(inode); + error = -EIO; + if (GFS2_I(inode)->i_diskflags & GFS2_DIF_SYSTEM) + goto fail_iput; - /* The iput will cause it to be deleted. */ - iput(inode); - return; + error = 0; + } -fail_glock: - gfs2_glock_dq(&ip->i_iopen_gh); -fail_iopen: - if (io_gl) - gfs2_glock_put(io_gl); -fail_put: - ip->i_gl->gl_object = NULL; - gfs2_glock_put(ip->i_gl); fail: - iget_failed(inode); - return; + gfs2_glock_dq_uninit(&i_gh); + return error ? ERR_PTR(error) : inode; +fail_iput: + iput(inode); + goto fail; } static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) diff --git a/trunk/fs/gfs2/inode.h b/trunk/fs/gfs2/inode.h index 6720d7d5fbc6..d8499fadcc53 100644 --- a/trunk/fs/gfs2/inode.h +++ b/trunk/fs/gfs2/inode.h @@ -99,7 +99,9 @@ static inline int gfs2_check_internal_file_size(struct inode *inode, extern void gfs2_set_iop(struct inode *inode); extern struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type, u64 no_addr, u64 no_formal_ino); -extern void gfs2_process_unlinked_inode(struct super_block *sb, u64 no_addr); +extern struct inode *gfs2_lookup_by_inum(struct gfs2_sbd *sdp, u64 no_addr, + u64 *no_formal_ino, + unsigned int blktype); extern struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr); extern int gfs2_inode_refresh(struct gfs2_inode *ip); diff --git a/trunk/fs/gfs2/rgrp.c b/trunk/fs/gfs2/rgrp.c index bef3ab6cf5c1..33c8407b876f 100644 --- a/trunk/fs/gfs2/rgrp.c +++ b/trunk/fs/gfs2/rgrp.c @@ -963,17 +963,18 @@ static int try_rgrp_fit(struct gfs2_rgrpd *rgd, struct gfs2_alloc *al) * The inode, if one has been found, in inode. */ -static u64 try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, - u64 skip) +static void try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, u64 skip) { u32 goal = 0, block; u64 no_addr; struct gfs2_sbd *sdp = rgd->rd_sbd; unsigned int n; + struct gfs2_glock *gl; + struct gfs2_inode *ip; + int error; + int found = 0; - for(;;) { - if (goal >= rgd->rd_data) - break; + while (goal < rgd->rd_data) { down_write(&sdp->sd_log_flush_lock); n = 1; block = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED, @@ -990,11 +991,32 @@ static u64 try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, if (no_addr == skip) continue; *last_unlinked = no_addr; - return no_addr; + + error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &gl); + if (error) + continue; + + /* If the inode is already in cache, we can ignore it here + * because the existing inode disposal code will deal with + * it when all refs have gone away. Accessing gl_object like + * this is not safe in general. Here it is ok because we do + * not dereference the pointer, and we only need an approx + * answer to whether it is NULL or not. + */ + ip = gl->gl_object; + + if (ip || queue_work(gfs2_delete_workqueue, &gl->gl_delete) == 0) + gfs2_glock_put(gl); + else + found++; + + /* Limit reclaim to sensible number of tasks */ + if (found > 2*NR_CPUS) + return; } rgd->rd_flags &= ~GFS2_RDF_CHECK; - return 0; + return; } /** @@ -1075,11 +1097,9 @@ static void forward_rgrp_set(struct gfs2_sbd *sdp, struct gfs2_rgrpd *rgd) * Try to acquire rgrp in way which avoids contending with others. * * Returns: errno - * unlinked: the block address of an unlinked block to be reclaimed */ -static int get_local_rgrp(struct gfs2_inode *ip, u64 *unlinked, - u64 *last_unlinked) +static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); struct gfs2_rgrpd *rgd, *begin = NULL; @@ -1089,7 +1109,6 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *unlinked, int loops = 0; int error, rg_locked; - *unlinked = 0; rgd = gfs2_blk2rgrpd(sdp, ip->i_goal); while (rgd) { @@ -1106,17 +1125,10 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *unlinked, case 0: if (try_rgrp_fit(rgd, al)) goto out; - /* If the rg came in already locked, there's no - way we can recover from a failed try_rgrp_unlink - because that would require an iput which can only - happen after the rgrp is unlocked. */ - if (!rg_locked && rgd->rd_flags & GFS2_RDF_CHECK) - *unlinked = try_rgrp_unlink(rgd, last_unlinked, - ip->i_no_addr); + if (rgd->rd_flags & GFS2_RDF_CHECK) + try_rgrp_unlink(rgd, last_unlinked, ip->i_no_addr); if (!rg_locked) gfs2_glock_dq_uninit(&al->al_rgd_gh); - if (*unlinked) - return -EAGAIN; /* fall through */ case GLR_TRYFAILED: rgd = recent_rgrp_next(rgd); @@ -1145,13 +1157,10 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *unlinked, case 0: if (try_rgrp_fit(rgd, al)) goto out; - if (!rg_locked && rgd->rd_flags & GFS2_RDF_CHECK) - *unlinked = try_rgrp_unlink(rgd, last_unlinked, - ip->i_no_addr); + if (rgd->rd_flags & GFS2_RDF_CHECK) + try_rgrp_unlink(rgd, last_unlinked, ip->i_no_addr); if (!rg_locked) gfs2_glock_dq_uninit(&al->al_rgd_gh); - if (*unlinked) - return -EAGAIN; break; case GLR_TRYFAILED: @@ -1204,12 +1213,12 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, int hold_rindex, struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); struct gfs2_alloc *al = ip->i_alloc; int error = 0; - u64 last_unlinked = NO_BLOCK, unlinked; + u64 last_unlinked = NO_BLOCK; + int tries = 0; if (gfs2_assert_warn(sdp, al->al_requested)) return -EINVAL; -try_again: if (hold_rindex) { /* We need to hold the rindex unless the inode we're using is the rindex itself, in which case it's already held. */ @@ -1218,31 +1227,23 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, int hold_rindex, else if (!sdp->sd_rgrps) /* We may not have the rindex read in, so: */ error = gfs2_ri_update_special(ip); + if (error) + return error; } - if (error) - return error; + do { + error = get_local_rgrp(ip, &last_unlinked); + /* If there is no space, flushing the log may release some */ + if (error) + gfs2_log_flush(sdp, NULL); + } while (error && tries++ < 3); - /* Find an rgrp suitable for allocation. If it encounters any unlinked - dinodes along the way, error will equal -EAGAIN and unlinked will - contains it block address. We then need to look up that inode and - try to free it, and try the allocation again. */ - error = get_local_rgrp(ip, &unlinked, &last_unlinked); if (error) { if (hold_rindex && ip != GFS2_I(sdp->sd_rindex)) gfs2_glock_dq_uninit(&al->al_ri_gh); - if (error != -EAGAIN) - return error; - - gfs2_process_unlinked_inode(ip->i_inode.i_sb, unlinked); - /* regardless of whether or not gfs2_process_unlinked_inode - was successful, we don't want to repeat it again. */ - last_unlinked = unlinked; - gfs2_log_flush(sdp, NULL); - error = 0; - - goto try_again; + return error; } + /* no error, so we have the rgrp set in the inode's allocation. */ al->al_file = file; al->al_line = line; diff --git a/trunk/fs/ocfs2/ocfs2.h b/trunk/fs/ocfs2/ocfs2.h index 1efea3615589..d8408217e3bd 100644 --- a/trunk/fs/ocfs2/ocfs2.h +++ b/trunk/fs/ocfs2/ocfs2.h @@ -159,9 +159,7 @@ struct ocfs2_lock_res { char l_name[OCFS2_LOCK_ID_MAX_LEN]; unsigned int l_ro_holders; unsigned int l_ex_holders; - char l_level; - char l_requested; - char l_blocking; + unsigned char l_level; /* Data packed - type enum ocfs2_lock_type */ unsigned char l_type; @@ -171,6 +169,8 @@ struct ocfs2_lock_res { unsigned char l_action; /* Data packed - enum type ocfs2_unlock_action */ unsigned char l_unlock_action; + unsigned char l_requested; + unsigned char l_blocking; unsigned int l_pending_gen; spinlock_t l_lock; diff --git a/trunk/include/linux/fsl-diu-fb.h b/trunk/include/linux/fsl-diu-fb.h index 781d4671415f..fc295d7ea463 100644 --- a/trunk/include/linux/fsl-diu-fb.h +++ b/trunk/include/linux/fsl-diu-fb.h @@ -54,6 +54,7 @@ struct aoi_display_offset { }; #define MFB_SET_CHROMA_KEY _IOW('M', 1, struct mfb_chroma_key) +#define MFB_WAIT_FOR_VSYNC _IOW('F', 0x20, u_int32_t) #define MFB_SET_BRIGHTNESS _IOW('M', 3, __u8) #define MFB_SET_ALPHA 0x80014d00 diff --git a/trunk/include/linux/sh_intc.h b/trunk/include/linux/sh_intc.h index 5812fefbcedf..f656d1a43dc0 100644 --- a/trunk/include/linux/sh_intc.h +++ b/trunk/include/linux/sh_intc.h @@ -79,7 +79,7 @@ struct intc_hw_desc { unsigned int nr_subgroups; }; -#define _INTC_ARRAY(a) a, __same_type(a, NULL) ? 0 : sizeof(a)/sizeof(*a) +#define _INTC_ARRAY(a) a, a == NULL ? 0 : sizeof(a)/sizeof(*a) #define INTC_HW_DESC(vectors, groups, mask_regs, \ prio_regs, sense_regs, ack_regs) \ diff --git a/trunk/mm/slub.c b/trunk/mm/slub.c index 981fb730aa04..8fd5401bb071 100644 --- a/trunk/mm/slub.c +++ b/trunk/mm/slub.c @@ -3273,9 +3273,9 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size, kfree(n); kfree(s); } -err: up_write(&slub_lock); +err: if (flags & SLAB_PANIC) panic("Cannot create slabcache %s\n", name); else @@ -3862,7 +3862,6 @@ static ssize_t show_slab_objects(struct kmem_cache *s, x += sprintf(buf + x, " N%d=%lu", node, nodes[node]); #endif - up_read(&slub_lock); kfree(nodes); return x + sprintf(buf + x, "\n"); }