Skip to content

Commit d847471

Browse files
ijctorvalds
authored andcommitted
fbdefio: add set_page_dirty handler to deferred IO FB
Fixes kernel BUG at lib/radix-tree.c:473. Previously the handler was incidentally provided by tmpfs but this was removed with: commit 14fcc23 Author: Hugh Dickins <[email protected]> Date: Mon Jul 28 15:46:19 2008 -0700 tmpfs: fix kernel BUG in shmem_delete_inode relying on this behaviour was incorrect in any case and the BUG also appeared when the device node was on an ext3 filesystem. v2: override a_ops at open() time rather than mmap() time to minimise races per AKPM's concerns. Signed-off-by: Ian Campbell <[email protected]> Cc: Jaya Kumar <[email protected]> Cc: Nick Piggin <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Hugh Dickins <[email protected]> Cc: Johannes Weiner <[email protected]> Cc: Jeremy Fitzhardinge <[email protected]> Cc: Kel Modderman <[email protected]> Cc: Markus Armbruster <[email protected]> Cc: Krzysztof Helt <[email protected]> Cc: <[email protected]> [14fcc23 is in 2.6.25.14 and 2.6.26.1] Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent b42f931 commit d847471

File tree

3 files changed

+26
-0
lines changed

3 files changed

+26
-0
lines changed

drivers/video/fb_defio.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,17 @@ static struct vm_operations_struct fb_deferred_io_vm_ops = {
114114
.page_mkwrite = fb_deferred_io_mkwrite,
115115
};
116116

117+
static int fb_deferred_io_set_page_dirty(struct page *page)
118+
{
119+
if (!PageDirty(page))
120+
SetPageDirty(page);
121+
return 0;
122+
}
123+
124+
static const struct address_space_operations fb_deferred_io_aops = {
125+
.set_page_dirty = fb_deferred_io_set_page_dirty,
126+
};
127+
117128
static int fb_deferred_io_mmap(struct fb_info *info, struct vm_area_struct *vma)
118129
{
119130
vma->vm_ops = &fb_deferred_io_vm_ops;
@@ -163,6 +174,14 @@ void fb_deferred_io_init(struct fb_info *info)
163174
}
164175
EXPORT_SYMBOL_GPL(fb_deferred_io_init);
165176

177+
void fb_deferred_io_open(struct fb_info *info,
178+
struct inode *inode,
179+
struct file *file)
180+
{
181+
file->f_mapping->a_ops = &fb_deferred_io_aops;
182+
}
183+
EXPORT_SYMBOL_GPL(fb_deferred_io_open);
184+
166185
void fb_deferred_io_cleanup(struct fb_info *info)
167186
{
168187
void *screen_base = (void __force *) info->screen_base;

drivers/video/fbmem.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,6 +1344,10 @@ fb_open(struct inode *inode, struct file *file)
13441344
if (res)
13451345
module_put(info->fbops->owner);
13461346
}
1347+
#ifdef CONFIG_FB_DEFERRED_IO
1348+
if (info->fbdefio)
1349+
fb_deferred_io_open(info, inode, file);
1350+
#endif
13471351
out:
13481352
unlock_kernel();
13491353
return res;

include/linux/fb.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -976,6 +976,9 @@ static inline void __fb_pad_aligned_buffer(u8 *dst, u32 d_pitch,
976976

977977
/* drivers/video/fb_defio.c */
978978
extern void fb_deferred_io_init(struct fb_info *info);
979+
extern void fb_deferred_io_open(struct fb_info *info,
980+
struct inode *inode,
981+
struct file *file);
979982
extern void fb_deferred_io_cleanup(struct fb_info *info);
980983
extern int fb_deferred_io_fsync(struct file *file, struct dentry *dentry,
981984
int datasync);

0 commit comments

Comments
 (0)