Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ufs_get_locked_page(): make sure we have buffer_heads

callers rely upon that, but find_lock_page() racing with attempt of
page eviction by memory pressure might have left us with
* try_to_free_buffers() successfully done
* __remove_mapping() failed, leaving the page in our mapping
* find_lock_page() returning an uptodate page with no
buffer_heads attached.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Al Viro 267309f3 c596961d

+8 -9
+8 -9
fs/ufs/util.c
··· 243 243 struct page *ufs_get_locked_page(struct address_space *mapping, 244 244 pgoff_t index) 245 245 { 246 - struct page *page; 247 - 248 - page = find_lock_page(mapping, index); 246 + struct inode *inode = mapping->host; 247 + struct page *page = find_lock_page(mapping, index); 249 248 if (!page) { 250 249 page = read_mapping_page(mapping, index, NULL); 251 250 ··· 252 253 printk(KERN_ERR "ufs_change_blocknr: " 253 254 "read_mapping_page error: ino %lu, index: %lu\n", 254 255 mapping->host->i_ino, index); 255 - goto out; 256 + return page; 256 257 } 257 258 258 259 lock_page(page); ··· 261 262 /* Truncate got there first */ 262 263 unlock_page(page); 263 264 put_page(page); 264 - page = NULL; 265 - goto out; 265 + return NULL; 266 266 } 267 267 268 268 if (!PageUptodate(page) || PageError(page)) { ··· 270 272 271 273 printk(KERN_ERR "ufs_change_blocknr: " 272 274 "can not read page: ino %lu, index: %lu\n", 273 - mapping->host->i_ino, index); 275 + inode->i_ino, index); 274 276 275 - page = ERR_PTR(-EIO); 277 + return ERR_PTR(-EIO); 276 278 } 277 279 } 278 - out: 280 + if (!page_has_buffers(page)) 281 + create_empty_buffers(page, 1 << inode->i_blkbits, 0); 279 282 return page; 280 283 }