Merge branch 'audit.b61' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 5 Jan 2009 00:32:11 +0000 (16:32 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 5 Jan 2009 00:32:11 +0000 (16:32 -0800)
* 'audit.b61' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current:
  audit: validate comparison operations, store them in sane form
  clean up audit_rule_{add,del} a bit
  make sure that filterkey of task,always rules is reported
  audit rules ordering, part 2
  fixing audit rule ordering mess, part 1
  audit_update_lsm_rules() misses the audit_inode_hash[] ones
  sanitize audit_log_capset()
  sanitize audit_fd_pair()
  sanitize audit_mq_open()
  sanitize AUDIT_MQ_SENDRECV
  sanitize audit_mq_notify()
  sanitize audit_mq_getsetattr()
  sanitize audit_ipc_set_perm()
  sanitize audit_ipc_obj()
  sanitize audit_socketcall
  don't reallocate buffer in every audit_sockaddr()

34 files changed:
drivers/rtc/Kconfig
drivers/rtc/interface.c
drivers/rtc/rtc-dev.c
drivers/video/via/viafbdev.c
fs/affs/file.c
fs/afs/write.c
fs/buffer.c
fs/cifs/file.c
fs/ecryptfs/mmap.c
fs/ext3/inode.c
fs/ext3/namei.c
fs/ext4/ext4_sb.h
fs/ext4/inode.c
fs/ext4/namei.c
fs/fuse/file.c
fs/gfs2/ops_address.c
fs/hostfs/hostfs_kern.c
fs/jffs2/file.c
fs/libfs.c
fs/namei.c
fs/nfs/file.c
fs/reiserfs/inode.c
fs/smbfs/file.c
fs/ubifs/file.c
include/linux/blockgroup_lock.h
include/linux/ext2_fs_sb.h
include/linux/ext3_fs_sb.h
include/linux/fs.h
include/linux/pagemap.h
include/linux/rtc.h
include/linux/spi/spi.h
kernel/cgroup.c
mm/filemap.c
mm/vmalloc.c

index 123092d..165a818 100644 (file)
@@ -102,9 +102,13 @@ config RTC_INTF_DEV_UIE_EMUL
        depends on RTC_INTF_DEV
        help
          Provides an emulation for RTC_UIE if the underlying rtc chip
-         driver does not expose RTC_UIE ioctls.  Those requests generate
+         driver does not expose RTC_UIE ioctls. Those requests generate
          once-per-second update interrupts, used for synchronization.
 
+         The emulation code will read the time from the hardware
+         clock several times per second, please enable this option
+         only if you know that you really need it.
+
 config RTC_DRV_TEST
        tristate "Test driver/device"
        help
index a04c1b6..fd2c652 100644 (file)
@@ -307,6 +307,60 @@ int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
 }
 EXPORT_SYMBOL_GPL(rtc_set_alarm);
 
+int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled)
+{
+       int err = mutex_lock_interruptible(&rtc->ops_lock);
+       if (err)
+               return err;
+
+       if (!rtc->ops)
+               err = -ENODEV;
+       else if (!rtc->ops->alarm_irq_enable)
+               err = -EINVAL;
+       else
+               err = rtc->ops->alarm_irq_enable(rtc->dev.parent, enabled);
+
+       mutex_unlock(&rtc->ops_lock);
+       return err;
+}
+EXPORT_SYMBOL_GPL(rtc_alarm_irq_enable);
+
+int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled)
+{
+       int err = mutex_lock_interruptible(&rtc->ops_lock);
+       if (err)
+               return err;
+
+#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
+       if (enabled == 0 && rtc->uie_irq_active) {
+               mutex_unlock(&rtc->ops_lock);
+               return rtc_dev_update_irq_enable_emul(rtc, enabled);
+       }
+#endif
+
+       if (!rtc->ops)
+               err = -ENODEV;
+       else if (!rtc->ops->update_irq_enable)
+               err = -EINVAL;
+       else
+               err = rtc->ops->update_irq_enable(rtc->dev.parent, enabled);
+
+       mutex_unlock(&rtc->ops_lock);
+
+#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
+       /*
+        * Enable emulation if the driver did not provide
+        * the update_irq_enable function pointer or if returned
+        * -EINVAL to signal that it has been configured without
+        * interrupts or that are not available at the moment.
+        */
+       if (err == -EINVAL)
+               err = rtc_dev_update_irq_enable_emul(rtc, enabled);
+#endif
+       return err;
+}
+EXPORT_SYMBOL_GPL(rtc_update_irq_enable);
+
 /**
  * rtc_update_irq - report RTC periodic, alarm, and/or update irqs
  * @rtc: the rtc device
index ecdea44..45152f4 100644 (file)
@@ -92,10 +92,10 @@ static void rtc_uie_timer(unsigned long data)
        spin_unlock_irqrestore(&rtc->irq_lock, flags);
 }
 
-static void clear_uie(struct rtc_device *rtc)
+static int clear_uie(struct rtc_device *rtc)
 {
        spin_lock_irq(&rtc->irq_lock);
-       if (rtc->irq_active) {
+       if (rtc->uie_irq_active) {
                rtc->stop_uie_polling = 1;
                if (rtc->uie_timer_active) {
                        spin_unlock_irq(&rtc->irq_lock);
@@ -108,9 +108,10 @@ static void clear_uie(struct rtc_device *rtc)
                        flush_scheduled_work();
                        spin_lock_irq(&rtc->irq_lock);
                }
-               rtc->irq_active = 0;
+               rtc->uie_irq_active = 0;
        }
        spin_unlock_irq(&rtc->irq_lock);
+       return 0;
 }
 
 static int set_uie(struct rtc_device *rtc)
@@ -122,8 +123,8 @@ static int set_uie(struct rtc_device *rtc)
        if (err)
                return err;
        spin_lock_irq(&rtc->irq_lock);
-       if (!rtc->irq_active) {
-               rtc->irq_active = 1;
+       if (!rtc->uie_irq_active) {
+               rtc->uie_irq_active = 1;
                rtc->stop_uie_polling = 0;
                rtc->oldsecs = tm.tm_sec;
                rtc->uie_task_active = 1;
@@ -134,6 +135,16 @@ static int set_uie(struct rtc_device *rtc)
        spin_unlock_irq(&rtc->irq_lock);
        return 0;
 }
+
+int rtc_dev_update_irq_enable_emul(struct rtc_device *rtc, unsigned int enabled)
+{
+       if (enabled)
+               return set_uie(rtc);
+       else
+               return clear_uie(rtc);
+}
+EXPORT_SYMBOL(rtc_dev_update_irq_enable_emul);
+
 #endif /* CONFIG_RTC_INTF_DEV_UIE_EMUL */
 
 static ssize_t
@@ -357,6 +368,22 @@ static long rtc_dev_ioctl(struct file *file,
                err = rtc_irq_set_state(rtc, NULL, 0);
                break;
 
+       case RTC_AIE_ON:
+               mutex_unlock(&rtc->ops_lock);
+               return rtc_alarm_irq_enable(rtc, 1);
+
+       case RTC_AIE_OFF:
+               mutex_unlock(&rtc->ops_lock);
+               return rtc_alarm_irq_enable(rtc, 0);
+
+       case RTC_UIE_ON:
+               mutex_unlock(&rtc->ops_lock);
+               return rtc_update_irq_enable(rtc, 1);
+
+       case RTC_UIE_OFF:
+               mutex_unlock(&rtc->ops_lock);
+               return rtc_update_irq_enable(rtc, 0);
+
        case RTC_IRQP_SET:
                err = rtc_irq_set_freq(rtc, NULL, arg);
                break;
@@ -401,17 +428,6 @@ static long rtc_dev_ioctl(struct file *file,
                        err = -EFAULT;
                return err;
 
-#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
-       case RTC_UIE_OFF:
-               mutex_unlock(&rtc->ops_lock);
-               clear_uie(rtc);
-               return 0;
-
-       case RTC_UIE_ON:
-               mutex_unlock(&rtc->ops_lock);
-               err = set_uie(rtc);
-               return err;
-#endif
        default:
                err = -ENOTTY;
                break;
@@ -440,7 +456,10 @@ static int rtc_dev_release(struct inode *inode, struct file *file)
         * Leave the alarm alone; it may be set to trigger a system wakeup
         * later, or be used by kernel code, and is a one-shot event anyway.
         */
+
+       /* Keep ioctl until all drivers are converted */
        rtc_dev_ioctl(file, RTC_UIE_OFF, 0);
+       rtc_update_irq_enable(rtc, 0);
        rtc_irq_set_state(rtc, NULL, 0);
 
        if (rtc->ops->release)
index 73ac754..e21fe5b 100644 (file)
@@ -546,23 +546,25 @@ static int viafb_blank(int blank_mode, struct fb_info *info)
 
 static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
 {
-       struct viafb_ioctl_mode viamode;
-       struct viafb_ioctl_samm viasamm;
-       struct viafb_driver_version driver_version;
-       struct fb_var_screeninfo sec_var;
-       struct _panel_size_pos_info panel_pos_size_para;
+       union {
+               struct viafb_ioctl_mode viamode;
+               struct viafb_ioctl_samm viasamm;
+               struct viafb_driver_version driver_version;
+               struct fb_var_screeninfo sec_var;
+               struct _panel_size_pos_info panel_pos_size_para;
+               struct viafb_ioctl_setting viafb_setting;
+               struct device_t active_dev;
+       } u;
        u32 state_info = 0;
-       u32 viainfo_size = sizeof(struct viafb_ioctl_info);
        u32 *viafb_gamma_table;
        char driver_name[] = "viafb";
 
        u32 __user *argp = (u32 __user *) arg;
        u32 gpu32;
        u32 video_dev_info = 0;
-       struct viafb_ioctl_setting viafb_setting = {};
-       struct device_t active_dev = {};
 
        DEBUG_MSG(KERN_INFO "viafb_ioctl: 0x%X !!\n", cmd);
+       memset(&u, 0, sizeof(u));
 
        switch (cmd) {
        case VIAFB_GET_CHIP_INFO:
@@ -571,7 +573,7 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
                        return -EFAULT;
                break;
        case VIAFB_GET_INFO_SIZE:
-               return put_user(viainfo_size, argp);
+               return put_user((u32)sizeof(struct viafb_ioctl_info), argp);
        case VIAFB_GET_INFO:
                return viafb_ioctl_get_viafb_info(arg);
        case VIAFB_HOTPLUG:
@@ -584,60 +586,60 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
                viafb_hotplug = (gpu32) ? 1 : 0;
                break;
        case VIAFB_GET_RESOLUTION:
-               viamode.xres = (u32) viafb_hotplug_Xres;
-               viamode.yres = (u32) viafb_hotplug_Yres;
-               viamode.refresh = (u32) viafb_hotplug_refresh;
-               viamode.bpp = (u32) viafb_hotplug_bpp;
+               u.viamode.xres = (u32) viafb_hotplug_Xres;
+               u.viamode.yres = (u32) viafb_hotplug_Yres;
+               u.viamode.refresh = (u32) viafb_hotplug_refresh;
+               u.viamode.bpp = (u32) viafb_hotplug_bpp;
                if (viafb_SAMM_ON == 1) {
-                       viamode.xres_sec = viafb_second_xres;
-                       viamode.yres_sec = viafb_second_yres;
-                       viamode.virtual_xres_sec = viafb_second_virtual_xres;
-                       viamode.virtual_yres_sec = viafb_second_virtual_yres;
-                       viamode.refresh_sec = viafb_refresh1;
-                       viamode.bpp_sec = viafb_bpp1;
+                       u.viamode.xres_sec = viafb_second_xres;
+                       u.viamode.yres_sec = viafb_second_yres;
+                       u.viamode.virtual_xres_sec = viafb_second_virtual_xres;
+                       u.viamode.virtual_yres_sec = viafb_second_virtual_yres;
+                       u.viamode.refresh_sec = viafb_refresh1;
+                       u.viamode.bpp_sec = viafb_bpp1;
                } else {
-                       viamode.xres_sec = 0;
-                       viamode.yres_sec = 0;
-                       viamode.virtual_xres_sec = 0;
-                       viamode.virtual_yres_sec = 0;
-                       viamode.refresh_sec = 0;
-                       viamode.bpp_sec = 0;
+                       u.viamode.xres_sec = 0;
+                       u.viamode.yres_sec = 0;
+                       u.viamode.virtual_xres_sec = 0;
+                       u.viamode.virtual_yres_sec = 0;
+                       u.viamode.refresh_sec = 0;
+                       u.viamode.bpp_sec = 0;
                }
-               if (copy_to_user(argp, &viamode, sizeof(viamode)))
+               if (copy_to_user(argp, &u.viamode, sizeof(u.viamode)))
                        return -EFAULT;
                break;
        case VIAFB_GET_SAMM_INFO:
-               viasamm.samm_status = viafb_SAMM_ON;
+               u.viasamm.samm_status = viafb_SAMM_ON;
 
                if (viafb_SAMM_ON == 1) {
                        if (viafb_dual_fb) {
-                               viasamm.size_prim = viaparinfo->fbmem_free;
-                               viasamm.size_sec = viaparinfo1->fbmem_free;
+                               u.viasamm.size_prim = viaparinfo->fbmem_free;
+                               u.viasamm.size_sec = viaparinfo1->fbmem_free;
                        } else {
                                if (viafb_second_size) {
-                                       viasamm.size_prim =
+                                       u.viasamm.size_prim =
                                            viaparinfo->fbmem_free -
                                            viafb_second_size * 1024 * 1024;
-                                       viasamm.size_sec =
+                                       u.viasamm.size_sec =
                                            viafb_second_size * 1024 * 1024;
                                } else {
-                                       viasamm.size_prim =
+                                       u.viasamm.size_prim =
                                            viaparinfo->fbmem_free >> 1;
-                                       viasamm.size_sec =
+                                       u.viasamm.size_sec =
                                            (viaparinfo->fbmem_free >> 1);
                                }
                        }
-                       viasamm.mem_base = viaparinfo->fbmem;
-                       viasamm.offset_sec = viafb_second_offset;
+                       u.viasamm.mem_base = viaparinfo->fbmem;
+                       u.viasamm.offset_sec = viafb_second_offset;
                } else {
-                       viasamm.size_prim =
+                       u.viasamm.size_prim =
                            viaparinfo->memsize - viaparinfo->fbmem_used;
-                       viasamm.size_sec = 0;
-                       viasamm.mem_base = viaparinfo->fbmem;
-                       viasamm.offset_sec = 0;
+                       u.viasamm.size_sec = 0;
+                       u.viasamm.mem_base = viaparinfo->fbmem;
+                       u.viasamm.offset_sec = 0;
                }
 
-               if (copy_to_user(argp, &viasamm, sizeof(viasamm)))
+               if (copy_to_user(argp, &u.viasamm, sizeof(u.viasamm)))
                        return -EFAULT;
 
                break;
@@ -662,74 +664,75 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
                        viafb_lcd_disable();
                break;
        case VIAFB_SET_DEVICE:
-               if (copy_from_user(&active_dev, (void *)argp,
-                       sizeof(active_dev)))
+               if (copy_from_user(&u.active_dev, (void *)argp,
+                       sizeof(u.active_dev)))
                        return -EFAULT;
-               viafb_set_device(active_dev);
+               viafb_set_device(u.active_dev);
                viafb_set_par(info);
                break;
        case VIAFB_GET_DEVICE:
-               active_dev.crt = viafb_CRT_ON;
-               active_dev.dvi = viafb_DVI_ON;
-               active_dev.lcd = viafb_LCD_ON;
-               active_dev.samm = viafb_SAMM_ON;
-               active_dev.primary_dev = viafb_primary_dev;
+               u.active_dev.crt = viafb_CRT_ON;
+               u.active_dev.dvi = viafb_DVI_ON;
+               u.active_dev.lcd = viafb_LCD_ON;
+               u.active_dev.samm = viafb_SAMM_ON;
+               u.active_dev.primary_dev = viafb_primary_dev;
 
-               active_dev.lcd_dsp_cent = viafb_lcd_dsp_method;
-               active_dev.lcd_panel_id = viafb_lcd_panel_id;
-               active_dev.lcd_mode = viafb_lcd_mode;
+               u.active_dev.lcd_dsp_cent = viafb_lcd_dsp_method;
+               u.active_dev.lcd_panel_id = viafb_lcd_panel_id;
+               u.active_dev.lcd_mode = viafb_lcd_mode;
 
-               active_dev.xres = viafb_hotplug_Xres;
-               active_dev.yres = viafb_hotplug_Yres;
+               u.active_dev.xres = viafb_hotplug_Xres;
+               u.active_dev.yres = viafb_hotplug_Yres;
 
-               active_dev.xres1 = viafb_second_xres;
-               active_dev.yres1 = viafb_second_yres;
+               u.active_dev.xres1 = viafb_second_xres;
+               u.active_dev.yres1 = viafb_second_yres;
 
-               active_dev.bpp = viafb_bpp;
-               active_dev.bpp1 = viafb_bpp1;
-               active_dev.refresh = viafb_refresh;
-               active_dev.refresh1 = viafb_refresh1;
+               u.active_dev.bpp = viafb_bpp;
+               u.active_dev.bpp1 = viafb_bpp1;
+               u.active_dev.refresh = viafb_refresh;
+               u.active_dev.refresh1 = viafb_refresh1;
 
-               active_dev.epia_dvi = viafb_platform_epia_dvi;
-               active_dev.lcd_dual_edge = viafb_device_lcd_dualedge;
-               active_dev.bus_width = viafb_bus_width;
+               u.active_dev.epia_dvi = viafb_platform_epia_dvi;
+               u.active_dev.lcd_dual_edge = viafb_device_lcd_dualedge;
+               u.active_dev.bus_width = viafb_bus_width;
 
-               if (copy_to_user(argp, &active_dev, sizeof(active_dev)))
+               if (copy_to_user(argp, &u.active_dev, sizeof(u.active_dev)))
                        return -EFAULT;
                break;
 
        case VIAFB_GET_DRIVER_VERSION:
-               driver_version.iMajorNum = VERSION_MAJOR;
-               driver_version.iKernelNum = VERSION_KERNEL;
-               driver_version.iOSNum = VERSION_OS;
-               driver_version.iMinorNum = VERSION_MINOR;
+               u.driver_version.iMajorNum = VERSION_MAJOR;
+               u.driver_version.iKernelNum = VERSION_KERNEL;
+               u.driver_version.iOSNum = VERSION_OS;
+               u.driver_version.iMinorNum = VERSION_MINOR;
 
-               if (copy_to_user(argp, &driver_version,
-                       sizeof(driver_version)))
+               if (copy_to_user(argp, &u.driver_version,
+                       sizeof(u.driver_version)))
                        return -EFAULT;
 
                break;
 
        case VIAFB_SET_DEVICE_INFO:
-               if (copy_from_user(&viafb_setting,
-                       argp, sizeof(viafb_setting)))
+               if (copy_from_user(&u.viafb_setting,
+                       argp, sizeof(u.viafb_setting)))
                        return -EFAULT;
-               if (apply_device_setting(viafb_setting, info) < 0)
+               if (apply_device_setting(u.viafb_setting, info) < 0)
                        return -EINVAL;
 
                break;
 
        case VIAFB_SET_SECOND_MODE:
-               if (copy_from_user(&sec_var, argp, sizeof(sec_var)))
+               if (copy_from_user(&u.sec_var, argp, sizeof(u.sec_var)))
                        return -EFAULT;
-               apply_second_mode_setting(&sec_var);
+               apply_second_mode_setting(&u.sec_var);
                break;
 
        case VIAFB_GET_DEVICE_INFO:
 
-               retrieve_device_setting(&viafb_setting);
+               retrieve_device_setting(&u.viafb_setting);
 
-               if (copy_to_user(argp, &viafb_setting, sizeof(viafb_setting)))
+               if (copy_to_user(argp, &u.viafb_setting,
+                                sizeof(u.viafb_setting)))
                        return -EFAULT;
 
                break;
@@ -806,51 +809,51 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
                break;
 
        case VIAFB_GET_PANEL_MAX_SIZE:
-               if (copy_from_user
-                   (&panel_pos_size_para, argp, sizeof(panel_pos_size_para)))
+               if (copy_from_user(&u.panel_pos_size_para, argp,
+                                  sizeof(u.panel_pos_size_para)))
                        return -EFAULT;
-               panel_pos_size_para.x = panel_pos_size_para.y = 0;
-               if (copy_to_user(argp, &panel_pos_size_para,
-                    sizeof(panel_pos_size_para)))
+               u.panel_pos_size_para.x = u.panel_pos_size_para.y = 0;
+               if (copy_to_user(argp, &u.panel_pos_size_para,
+                    sizeof(u.panel_pos_size_para)))
                        return -EFAULT;
                break;
        case VIAFB_GET_PANEL_MAX_POSITION:
-               if (copy_from_user
-                   (&panel_pos_size_para, argp, sizeof(panel_pos_size_para)))
+               if (copy_from_user(&u.panel_pos_size_para, argp,
+                                  sizeof(u.panel_pos_size_para)))
                        return -EFAULT;
-               panel_pos_size_para.x = panel_pos_size_para.y = 0;
-               if (copy_to_user(argp, &panel_pos_size_para,
-                    sizeof(panel_pos_size_para)))
+               u.panel_pos_size_para.x = u.panel_pos_size_para.y = 0;
+               if (copy_to_user(argp, &u.panel_pos_size_para,
+                                sizeof(u.panel_pos_size_para)))
                        return -EFAULT;
                break;
 
        case VIAFB_GET_PANEL_POSITION:
-               if (copy_from_user
-                   (&panel_pos_size_para, argp, sizeof(panel_pos_size_para)))
+               if (copy_from_user(&u.panel_pos_size_para, argp,
+                                  sizeof(u.panel_pos_size_para)))
                        return -EFAULT;
-               panel_pos_size_para.x = panel_pos_size_para.y = 0;
-               if (copy_to_user(argp, &panel_pos_size_para,
-                    sizeof(panel_pos_size_para)))
+               u.panel_pos_size_para.x = u.panel_pos_size_para.y = 0;
+               if (copy_to_user(argp, &u.panel_pos_size_para,
+                                sizeof(u.panel_pos_size_para)))
                        return -EFAULT;
                break;
        case VIAFB_GET_PANEL_SIZE:
-               if (copy_from_user
-                   (&panel_pos_size_para, argp, sizeof(panel_pos_size_para)))
+               if (copy_from_user(&u.panel_pos_size_para, argp,
+                                  sizeof(u.panel_pos_size_para)))
                        return -EFAULT;
-               panel_pos_size_para.x = panel_pos_size_para.y = 0;
-               if (copy_to_user(argp, &panel_pos_size_para,
-                    sizeof(panel_pos_size_para)))
+               u.panel_pos_size_para.x = u.panel_pos_size_para.y = 0;
+               if (copy_to_user(argp, &u.panel_pos_size_para,
+                                sizeof(u.panel_pos_size_para)))
                        return -EFAULT;
                break;
 
        case VIAFB_SET_PANEL_POSITION:
-               if (copy_from_user
-                   (&panel_pos_size_para, argp, sizeof(panel_pos_size_para)))
+               if (copy_from_user(&u.panel_pos_size_para, argp,
+                                  sizeof(u.panel_pos_size_para)))
                        return -EFAULT;
                break;
        case VIAFB_SET_PANEL_SIZE:
-               if (copy_from_user
-                   (&panel_pos_size_para, argp, sizeof(panel_pos_size_para)))
+               if (copy_from_user(&u.panel_pos_size_para, argp,
+                                  sizeof(u.panel_pos_size_para)))
                        return -EFAULT;
                break;
 
@@ -1052,10 +1055,8 @@ static void viafb_imageblit(struct fb_info *info,
 
 static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
 {
-       u8 data[CURSOR_SIZE / 8];
-       u32 data_bak[CURSOR_SIZE / 32];
        u32 temp, xx, yy, bg_col = 0, fg_col = 0;
-       int size, i, j = 0;
+       int i, j = 0;
        static int hw_cursor;
        struct viafb_par *p_viafb_par;
 
@@ -1178,22 +1179,29 @@ static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
        }
 
        if (cursor->set & FB_CUR_SETSHAPE) {
-               size =
+               struct {
+                       u8 data[CURSOR_SIZE / 8];
+                       u32 bak[CURSOR_SIZE / 32];
+               } *cr_data = kzalloc(sizeof(*cr_data), GFP_ATOMIC);
+               int size =
                    ((viacursor.image.width + 7) >> 3) *
                    viacursor.image.height;
 
+               if (cr_data == NULL)
+                       goto out;
+
                if (MAX_CURS == 32) {
                        for (i = 0; i < (CURSOR_SIZE / 32); i++) {
-                               data_bak[i] = 0x0;
-                               data_bak[i + 1] = 0xFFFFFFFF;
+                               cr_data->bak[i] = 0x0;
+                               cr_data->bak[i + 1] = 0xFFFFFFFF;
                                i += 1;
                        }
                } else if (MAX_CURS == 64) {
                        for (i = 0; i < (CURSOR_SIZE / 32); i++) {
-                               data_bak[i] = 0x0;
-                               data_bak[i + 1] = 0x0;
-                               data_bak[i + 2] = 0xFFFFFFFF;
-                               data_bak[i + 3] = 0xFFFFFFFF;
+                               cr_data->bak[i] = 0x0;
+                               cr_data->bak[i + 1] = 0x0;
+                               cr_data->bak[i + 2] = 0xFFFFFFFF;
+                               cr_data->bak[i + 3] = 0xFFFFFFFF;
                                i += 3;
                        }
                }
@@ -1201,12 +1209,12 @@ static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
                switch (viacursor.rop) {
                case ROP_XOR:
                        for (i = 0; i < size; i++)
-                               data[i] = viacursor.mask[i];
+                               cr_data->data[i] = viacursor.mask[i];
                        break;
                case ROP_COPY:
 
                        for (i = 0; i < size; i++)
-                               data[i] = viacursor.mask[i];
+                               cr_data->data[i] = viacursor.mask[i];
                        break;
                default:
                        break;
@@ -1214,23 +1222,25 @@ static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
 
                if (MAX_CURS == 32) {
                        for (i = 0; i < size; i++) {
-                               data_bak[j] = (u32) data[i];
-                               data_bak[j + 1] = ~data_bak[j];
+                               cr_data->bak[j] = (u32) cr_data->data[i];
+                               cr_data->bak[j + 1] = ~cr_data->bak[j];
                                j += 2;
                        }
                } else if (MAX_CURS == 64) {
                        for (i = 0; i < size; i++) {
-                               data_bak[j] = (u32) data[i];
-                               data_bak[j + 1] = 0x0;
-                               data_bak[j + 2] = ~data_bak[j];
-                               data_bak[j + 3] = ~data_bak[j + 1];
+                               cr_data->bak[j] = (u32) cr_data->data[i];
+                               cr_data->bak[j + 1] = 0x0;
+                               cr_data->bak[j + 2] = ~cr_data->bak[j];
+                               cr_data->bak[j + 3] = ~cr_data->bak[j + 1];
                                j += 4;
                        }
                }
 
                memcpy(((struct viafb_par *)(info->par))->fbmem_virt +
                       ((struct viafb_par *)(info->par))->cursor_start,
-                      data_bak, CURSOR_SIZE);
+                      cr_data->bak, CURSOR_SIZE);
+out:
+               kfree(cr_data);
        }
 
        if (viacursor.enable)
index 1377b12..9246cb4 100644 (file)
@@ -628,7 +628,7 @@ static int affs_write_begin_ofs(struct file *file, struct address_space *mapping
        }
 
        index = pos >> PAGE_CACHE_SHIFT;
-       page = __grab_cache_page(mapping, index);
+       page = grab_cache_page_write_begin(mapping, index, flags);
        if (!page)
                return -ENOMEM;
        *pagep = page;
index d6b85da..3fb36d4 100644 (file)
@@ -144,7 +144,7 @@ int afs_write_begin(struct file *file, struct address_space *mapping,
        candidate->state = AFS_WBACK_PENDING;
        init_waitqueue_head(&candidate->waitq);
 
-       page = __grab_cache_page(mapping, index);
+       page = grab_cache_page_write_begin(mapping, index, flags);
        if (!page) {
                kfree(candidate);
                return -ENOMEM;
index 776ae09..a13f09b 100644 (file)
@@ -1996,7 +1996,7 @@ int block_write_begin(struct file *file, struct address_space *mapping,
        page = *pagep;
        if (page == NULL) {
                ownpage = 1;
-               page = __grab_cache_page(mapping, index);
+               page = grab_cache_page_write_begin(mapping, index, flags);
                if (!page) {
                        status = -ENOMEM;
                        goto out;
@@ -2502,7 +2502,7 @@ int nobh_write_begin(struct file *file, struct address_space *mapping,
        from = pos & (PAGE_CACHE_SIZE - 1);
        to = from + len;
 
-       page = __grab_cache_page(mapping, index);
+       page = grab_cache_page_write_begin(mapping, index, flags);
        if (!page)
                return -ENOMEM;
        *pagep = page;
index b1e1fc6..12bb656 100644 (file)
@@ -2074,7 +2074,7 @@ static int cifs_write_begin(struct file *file, struct address_space *mapping,
 
        cFYI(1, ("write_begin from %lld len %d", (long long)pos, len));
 
-       page = __grab_cache_page(mapping, index);
+       page = grab_cache_page_write_begin(mapping, index, flags);
        if (!page) {
                rc = -ENOMEM;
                goto out;
index 04d7b3f..46cec2b 100644 (file)
@@ -288,7 +288,7 @@ static int ecryptfs_write_begin(struct file *file,
        loff_t prev_page_end_size;
        int rc = 0;
 
-       page = __grab_cache_page(mapping, index);
+       page = grab_cache_page_write_begin(mapping, index, flags);
        if (!page)
                return -ENOMEM;
        *pagep = page;
index c4bdccf..5fa453b 100644 (file)
@@ -1161,7 +1161,7 @@ static int ext3_write_begin(struct file *file, struct address_space *mapping,
        to = from + len;
 
 retry:
-       page = __grab_cache_page(mapping, index);
+       page = grab_cache_page_write_begin(mapping, index, flags);
        if (!page)
                return -ENOMEM;
        *pagep = page;
index 297ea8d..1dd2abe 100644 (file)
@@ -2175,8 +2175,7 @@ retry:
                 * We have a transaction open.  All is sweetness.  It also sets
                 * i_size in generic_commit_write().
                 */
-               err = __page_symlink(inode, symname, l,
-                               mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS);
+               err = __page_symlink(inode, symname, l, 1);
                if (err) {
                        drop_nlink(inode);
                        unlock_new_inode(inode);
index 445fde6..b21f167 100644 (file)
@@ -146,4 +146,10 @@ struct ext4_sb_info {
        struct flex_groups *s_flex_groups;
 };
 
+static inline spinlock_t *
+sb_bgl_lock(struct ext4_sb_info *sbi, unsigned int block_group)
+{
+       return bgl_lock_ptr(&sbi->s_blockgroup_lock, block_group);
+}
+
 #endif /* _EXT4_SB */
index 7c3325e..6702a49 100644 (file)
@@ -1346,7 +1346,7 @@ retry:
                goto out;
        }
 
-       page = __grab_cache_page(mapping, index);
+       page = grab_cache_page_write_begin(mapping, index, flags);
        if (!page) {
                ext4_journal_stop(handle);
                ret = -ENOMEM;
@@ -2550,7 +2550,7 @@ retry:
                goto out;
        }
 
-       page = __grab_cache_page(mapping, index);
+       page = grab_cache_page_write_begin(mapping, index, flags);
        if (!page) {
                ext4_journal_stop(handle);
                ret = -ENOMEM;
index da98a90..9fd2a5e 100644 (file)
@@ -2212,8 +2212,7 @@ retry:
                 * We have a transaction open.  All is sweetness.  It also sets
                 * i_size in generic_commit_write().
                 */
-               err = __page_symlink(inode, symname, l,
-                               mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS);
+               err = __page_symlink(inode, symname, l, 1);
                if (err) {
                        clear_nlink(inode);
                        unlock_new_inode(inode);
index 34930a9..4c9ee70 100644 (file)
@@ -646,7 +646,7 @@ static int fuse_write_begin(struct file *file, struct address_space *mapping,
 {
        pgoff_t index = pos >> PAGE_CACHE_SHIFT;
 
-       *pagep = __grab_cache_page(mapping, index);
+       *pagep = grab_cache_page_write_begin(mapping, index, flags);
        if (!*pagep)
                return -ENOMEM;
        return 0;
@@ -779,7 +779,7 @@ static ssize_t fuse_fill_write_pages(struct fuse_req *req,
                        break;
 
                err = -ENOMEM;
-               page = __grab_cache_page(mapping, index);
+               page = grab_cache_page_write_begin(mapping, index, 0);
                if (!page)
                        break;
 
index 2756381..15f710f 100644 (file)
@@ -675,7 +675,7 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping,
                goto out_trans_fail;
 
        error = -ENOMEM;
-       page = __grab_cache_page(mapping, index);
+       page = grab_cache_page_write_begin(mapping, index, flags);
        *pagep = page;
        if (unlikely(!page))
                goto out_endtrans;
index 3a31451..5c538e0 100644 (file)
@@ -501,7 +501,7 @@ int hostfs_write_begin(struct file *file, struct address_space *mapping,
 {
        pgoff_t index = pos >> PAGE_CACHE_SHIFT;
 
-       *pagep = __grab_cache_page(mapping, index);
+       *pagep = grab_cache_page_write_begin(mapping, index, flags);
        if (!*pagep)
                return -ENOMEM;
        return 0;
index 5a98aa8..5edc2bf 100644 (file)
@@ -132,7 +132,7 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
        uint32_t pageofs = index << PAGE_CACHE_SHIFT;
        int ret = 0;
 
-       pg = __grab_cache_page(mapping, index);
+       pg = grab_cache_page_write_begin(mapping, index, flags);
        if (!pg)
                return -ENOMEM;
        *pagep = pg;
index e960a83..bdaec17 100644 (file)
@@ -360,7 +360,7 @@ int simple_write_begin(struct file *file, struct address_space *mapping,
        index = pos >> PAGE_CACHE_SHIFT;
        from = pos & (PAGE_CACHE_SIZE - 1);
 
-       page = __grab_cache_page(mapping, index);
+       page = grab_cache_page_write_begin(mapping, index, flags);
        if (!page)
                return -ENOMEM;
 
index dd5c9f0..df2d3df 100644 (file)
@@ -2817,18 +2817,23 @@ void page_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
        }
 }
 
-int __page_symlink(struct inode *inode, const char *symname, int len,
-               gfp_t gfp_mask)
+/*
+ * The nofs argument instructs pagecache_write_begin to pass AOP_FLAG_NOFS
+ */
+int __page_symlink(struct inode *inode, const char *symname, int len, int nofs)
 {
        struct address_space *mapping = inode->i_mapping;
        struct page *page;
        void *fsdata;
        int err;
        char *kaddr;
+       unsigned int flags = AOP_FLAG_UNINTERRUPTIBLE;
+       if (nofs)
+               flags |= AOP_FLAG_NOFS;
 
 retry:
        err = pagecache_write_begin(NULL, mapping, 0, len-1,
-                               AOP_FLAG_UNINTERRUPTIBLE, &page, &fsdata);
+                               flags, &page, &fsdata);
        if (err)
                goto fail;
 
@@ -2852,7 +2857,7 @@ fail:
 int page_symlink(struct inode *inode, const char *symname, int len)
 {
        return __page_symlink(inode, symname, len,
-                       mapping_gfp_mask(inode->i_mapping));
+                       !(mapping_gfp_mask(inode->i_mapping) & __GFP_FS));
 }
 
 const struct inode_operations page_symlink_inode_operations = {
index d319b49..90f292b 100644 (file)
@@ -354,7 +354,7 @@ static int nfs_write_begin(struct file *file, struct address_space *mapping,
                file->f_path.dentry->d_name.name,
                mapping->host->i_ino, len, (long long) pos);
 
-       page = __grab_cache_page(mapping, index);
+       page = grab_cache_page_write_begin(mapping, index, flags);
        if (!page)
                return -ENOMEM;
        *pagep = page;
index 145c2d3..ed04f47 100644 (file)
@@ -2561,7 +2561,7 @@ static int reiserfs_write_begin(struct file *file,
        }
 
        index = pos >> PAGE_CACHE_SHIFT;
-       page = __grab_cache_page(mapping, index);
+       page = grab_cache_page_write_begin(mapping, index, flags);
        if (!page)
                return -ENOMEM;
        *pagep = page;
index e4f8d51..92d5e8f 100644 (file)
@@ -297,7 +297,7 @@ static int smb_write_begin(struct file *file, struct address_space *mapping,
                        struct page **pagep, void **fsdata)
 {
        pgoff_t index = pos >> PAGE_CACHE_SHIFT;
-       *pagep = __grab_cache_page(mapping, index);
+       *pagep = grab_cache_page_write_begin(mapping, index, flags);
        if (!*pagep)
                return -ENOMEM;
        return 0;
index fe82d24..bf37374 100644 (file)
@@ -219,7 +219,8 @@ static void release_existing_page_budget(struct ubifs_info *c)
 }
 
 static int write_begin_slow(struct address_space *mapping,
-                           loff_t pos, unsigned len, struct page **pagep)
+                           loff_t pos, unsigned len, struct page **pagep,
+                           unsigned flags)
 {
        struct inode *inode = mapping->host;
        struct ubifs_info *c = inode->i_sb->s_fs_info;
@@ -247,7 +248,7 @@ static int write_begin_slow(struct address_space *mapping,
        if (unlikely(err))
                return err;
 
-       page = __grab_cache_page(mapping, index);
+       page = grab_cache_page_write_begin(mapping, index, flags);
        if (unlikely(!page)) {
                ubifs_release_budget(c, &req);
                return -ENOMEM;
@@ -438,7 +439,7 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
                return -EROFS;
 
        /* Try out the fast-path part first */
-       page = __grab_cache_page(mapping, index);
+       page = grab_cache_page_write_begin(mapping, index, flags);
        if (unlikely(!page))
                return -ENOMEM;
 
@@ -483,7 +484,7 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
                unlock_page(page);
                page_cache_release(page);
 
-               return write_begin_slow(mapping, pos, len, pagep);
+               return write_begin_slow(mapping, pos, len, pagep, flags);
        }
 
        /*
index 8607312..e44b88b 100644 (file)
@@ -53,7 +53,10 @@ static inline void bgl_lock_init(struct blockgroup_lock *bgl)
  * The accessor is a macro so we can embed a blockgroup_lock into different
  * superblock types
  */
-#define sb_bgl_lock(sb, block_group) \
-       (&(sb)->s_blockgroup_lock.locks[(block_group) & (NR_BG_LOCKS-1)].lock)
+static inline spinlock_t *
+bgl_lock_ptr(struct blockgroup_lock *bgl, unsigned int block_group)
+{
+       return &bgl->locks[(block_group) & (NR_BG_LOCKS-1)].lock;
+}
 
 #endif
index f273415..dc541f3 100644 (file)
@@ -108,4 +108,10 @@ struct ext2_sb_info {
        struct ext2_reserve_window_node s_rsv_window_head;
 };
 
+static inline spinlock_t *
+sb_bgl_lock(struct ext2_sb_info *sbi, unsigned int block_group)
+{
+       return bgl_lock_ptr(&sbi->s_blockgroup_lock, block_group);
+}
+
 #endif /* _LINUX_EXT2_FS_SB */
index b65f028..e024e38 100644 (file)
@@ -83,4 +83,10 @@ struct ext3_sb_info {
 #endif
 };
 
+static inline spinlock_t *
+sb_bgl_lock(struct ext3_sb_info *sbi, unsigned int block_group)
+{
+       return bgl_lock_ptr(&sbi->s_blockgroup_lock, block_group);
+}
+
 #endif /* _LINUX_EXT3_FS_SB */
index e2170ee..f2a3010 100644 (file)
@@ -423,6 +423,9 @@ enum positive_aop_returns {
 
 #define AOP_FLAG_UNINTERRUPTIBLE       0x0001 /* will not do a short write */
 #define AOP_FLAG_CONT_EXPAND           0x0002 /* called from cont_expand */
+#define AOP_FLAG_NOFS                  0x0004 /* used by filesystem to direct
+                                               * helper code (eg buffer layer)
+                                               * to clear GFP_FS from alloc */
 
 /*
  * oh the beauties of C type declarations.
@@ -2035,7 +2038,7 @@ extern int page_readlink(struct dentry *, char __user *, int);
 extern void *page_follow_link_light(struct dentry *, struct nameidata *);
 extern void page_put_link(struct dentry *, struct nameidata *, void *);
 extern int __page_symlink(struct inode *inode, const char *symname, int len,
-               gfp_t gfp_mask);
+               int nofs);
 extern int page_symlink(struct inode *inode, const char *symname, int len);
 extern const struct inode_operations page_symlink_inode_operations;
 extern int generic_readlink(struct dentry *, char __user *, int);
index 709742b..01ca085 100644 (file)
@@ -241,7 +241,8 @@ unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t start,
 unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index,
                        int tag, unsigned int nr_pages, struct page **pages);
 
-struct page *__grab_cache_page(struct address_space *mapping, pgoff_t index);
+struct page *grab_cache_page_write_begin(struct address_space *mapping,
+                       pgoff_t index, unsigned flags);
 
 /*
  * Returns locked page at given index in given cache, creating it if needed.
index 91f597a..4046b75 100644 (file)
@@ -145,6 +145,8 @@ struct rtc_class_ops {
        int (*irq_set_state)(struct device *, int enabled);
        int (*irq_set_freq)(struct device *, int freq);
        int (*read_callback)(struct device *, int data);
+       int (*alarm_irq_enable)(struct device *, unsigned int enabled);
+       int (*update_irq_enable)(struct device *, unsigned int enabled);
 };
 
 #define RTC_DEVICE_NAME_SIZE 20
@@ -181,7 +183,7 @@ struct rtc_device
        struct timer_list uie_timer;
        /* Those fields are protected by rtc->irq_lock */
        unsigned int oldsecs;
-       unsigned int irq_active:1;
+       unsigned int uie_irq_active:1;
        unsigned int stop_uie_polling:1;
        unsigned int uie_task_active:1;
        unsigned int uie_timer_active:1;
@@ -216,6 +218,10 @@ extern int rtc_irq_set_state(struct rtc_device *rtc,
                                struct rtc_task *task, int enabled);
 extern int rtc_irq_set_freq(struct rtc_device *rtc,
                                struct rtc_task *task, int freq);
+extern int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled);
+extern int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled);
+extern int rtc_dev_update_irq_enable_emul(struct rtc_device *rtc,
+                                               unsigned int enabled);
 
 typedef struct rtc_task {
        void (*func)(void *private_data);
index 4be01bb..8222931 100644 (file)
@@ -19,6 +19,8 @@
 #ifndef __LINUX_SPI_H
 #define __LINUX_SPI_H
 
+#include <linux/device.h>
+
 /*
  * INTERFACES between SPI master-side drivers and SPI infrastructure.
  * (There's no SPI slave support for Linux yet...)
index 48348dd..891a84e 100644 (file)
@@ -2945,7 +2945,11 @@ int cgroup_clone(struct task_struct *tsk, struct cgroup_subsys *subsys,
        parent = task_cgroup(tsk, subsys->subsys_id);
 
        /* Pin the hierarchy */
-       atomic_inc(&parent->root->sb->s_active);
+       if (!atomic_inc_not_zero(&parent->root->sb->s_active)) {
+               /* We race with the final deactivate_super() */
+               mutex_unlock(&cgroup_mutex);
+               return 0;
+       }
 
        /* Keep the cgroup alive */
        get_css_set(cg);
index f3e5f89..f8c6927 100644 (file)
@@ -2140,19 +2140,24 @@ EXPORT_SYMBOL(generic_file_direct_write);
  * Find or create a page at the given pagecache position. Return the locked
  * page. This function is specifically for buffered writes.
  */
-struct page *__grab_cache_page(struct address_space *mapping, pgoff_t index)
+struct page *grab_cache_page_write_begin(struct address_space *mapping,
+                                       pgoff_t index, unsigned flags)
 {
        int status;
        struct page *page;
+       gfp_t gfp_notmask = 0;
+       if (flags & AOP_FLAG_NOFS)
+               gfp_notmask = __GFP_FS;
 repeat:
        page = find_lock_page(mapping, index);
        if (likely(page))
                return page;
 
-       page = page_cache_alloc(mapping);
+       page = __page_cache_alloc(mapping_gfp_mask(mapping) & ~gfp_notmask);
        if (!page)
                return NULL;
-       status = add_to_page_cache_lru(page, mapping, index, GFP_KERNEL);
+       status = add_to_page_cache_lru(page, mapping, index,
+                                               GFP_KERNEL & ~gfp_notmask);
        if (unlikely(status)) {
                page_cache_release(page);
                if (status == -EEXIST)
@@ -2161,7 +2166,7 @@ repeat:
        }
        return page;
 }
-EXPORT_SYMBOL(__grab_cache_page);
+EXPORT_SYMBOL(grab_cache_page_write_begin);
 
 static ssize_t generic_perform_write(struct file *file,
                                struct iov_iter *i, loff_t pos)
index 1ddb77b..7465f22 100644 (file)
@@ -151,11 +151,12 @@ static int vmap_pud_range(pgd_t *pgd, unsigned long addr,
  *
  * Ie. pte at addr+N*PAGE_SIZE shall point to pfn corresponding to pages[N]
  */
-static int vmap_page_range(unsigned long addr, unsigned long end,
+static int vmap_page_range(unsigned long start, unsigned long end,
                                pgprot_t prot, struct page **pages)
 {
        pgd_t *pgd;
        unsigned long next;
+       unsigned long addr = start;
        int err = 0;
        int nr = 0;
 
@@ -167,7 +168,7 @@ static int vmap_page_range(unsigned long addr, unsigned long end,
                if (err)
                        break;
        } while (pgd++, addr = next, addr != end);
-       flush_cache_vmap(addr, end);
+       flush_cache_vmap(start, end);
 
        if (unlikely(err))
                return err;