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

Merge tag 'for-linus' of git://github.com/prasad-joshi/logfs_upstream

There are few important bug fixes for LogFS

* tag 'for-linus' of git://github.com/prasad-joshi/logfs_upstream:
Logfs: Allow NULL block_isbad() methods
logfs: Grow inode in delete path
logfs: Free areas before calling generic_shutdown_super()
logfs: remove useless BUG_ON
MAINTAINERS: Add Prasad Joshi in LogFS maintiners
logfs: Propagate page parameter to __logfs_write_inode
logfs: set superblock shutdown flag after generic sb shutdown
logfs: take write mutex lock during fsync and sync
logfs: Prevent memory corruption
logfs: update page reference count for pined pages

Fix up conflict in fs/logfs/dev_mtd.c due to semantic change in what
"mtd->block_isbad" means in commit f2933e86ad93: "Logfs: Allow NULL
block_isbad() methods" clashing with the abstraction changes in the
commits 7086c19d0742: "mtd: introduce mtd_block_isbad interface" and
d58b27ed58a3: "logfs: do not use 'mtd->block_isbad' directly".

This resolution takes the semantics from commit f2933e86ad93, and just
makes mtd_block_isbad() return zero (false) if the 'block_isbad'
function is NULL. But that also means that now "mtd_can_have_bb()"
always returns 0.

Now, "mtd_block_markbad()" will obviously return an error if the
low-level driver doesn't support bad blocks, so this is somewhat
non-symmetric, but it actually makes sense if a NULL "block_isbad"
function is considered to mean "I assume that all my blocks are always
good".

+89 -37
+1
MAINTAINERS
··· 4140 4141 LogFS 4142 M: Joern Engel <joern@logfs.org> 4143 L: logfs@logfs.org 4144 W: logfs.org 4145 S: Maintained
··· 4140 4141 LogFS 4142 M: Joern Engel <joern@logfs.org> 4143 + M: Prasad Joshi <prasadjoshi.linux@gmail.com> 4144 L: logfs@logfs.org 4145 W: logfs.org 4146 S: Maintained
+1 -1
fs/logfs/dir.c
··· 71 72 static int write_inode(struct inode *inode) 73 { 74 - return __logfs_write_inode(inode, WF_LOCK); 75 } 76 77 static s64 dir_seek_data(struct inode *inode, s64 pos)
··· 71 72 static int write_inode(struct inode *inode) 73 { 74 + return __logfs_write_inode(inode, NULL, WF_LOCK); 75 } 76 77 static s64 dir_seek_data(struct inode *inode, s64 pos)
+2
fs/logfs/file.c
··· 230 return ret; 231 232 mutex_lock(&inode->i_mutex); 233 logfs_write_anchor(sb); 234 mutex_unlock(&inode->i_mutex); 235 236 return 0;
··· 230 return ret; 231 232 mutex_lock(&inode->i_mutex); 233 + logfs_get_wblocks(sb, NULL, WF_LOCK); 234 logfs_write_anchor(sb); 235 + logfs_put_wblocks(sb, NULL, WF_LOCK); 236 mutex_unlock(&inode->i_mutex); 237 238 return 0;
+1 -1
fs/logfs/gc.c
··· 367 int i, max_dist; 368 struct gc_candidate *cand = NULL, *this; 369 370 - max_dist = min(no_free_segments(sb), LOGFS_NO_AREAS); 371 372 for (i = max_dist; i >= 0; i--) { 373 this = first_in_list(&super->s_low_list[i]);
··· 367 int i, max_dist; 368 struct gc_candidate *cand = NULL, *this; 369 370 + max_dist = min(no_free_segments(sb), LOGFS_NO_AREAS - 1); 371 372 for (i = max_dist; i >= 0; i--) { 373 this = first_in_list(&super->s_low_list[i]);
+3 -1
fs/logfs/inode.c
··· 286 if (logfs_inode(inode)->li_flags & LOGFS_IF_STILLBORN) 287 return 0; 288 289 - ret = __logfs_write_inode(inode, flags); 290 LOGFS_BUG_ON(ret, inode->i_sb); 291 return ret; 292 } ··· 363 364 static int logfs_sync_fs(struct super_block *sb, int wait) 365 { 366 logfs_write_anchor(sb); 367 return 0; 368 } 369
··· 286 if (logfs_inode(inode)->li_flags & LOGFS_IF_STILLBORN) 287 return 0; 288 289 + ret = __logfs_write_inode(inode, NULL, flags); 290 LOGFS_BUG_ON(ret, inode->i_sb); 291 return ret; 292 } ··· 363 364 static int logfs_sync_fs(struct super_block *sb, int wait) 365 { 366 + logfs_get_wblocks(sb, NULL, WF_LOCK); 367 logfs_write_anchor(sb); 368 + logfs_put_wblocks(sb, NULL, WF_LOCK); 369 return 0; 370 } 371
-1
fs/logfs/journal.c
··· 612 if (len == 0) 613 return logfs_write_header(super, header, 0, type); 614 615 - BUG_ON(len > sb->s_blocksize); 616 compr_len = logfs_compress(buf, data, len, sb->s_blocksize); 617 if (compr_len < 0 || type == JE_ANCHOR) { 618 memcpy(data, buf, len);
··· 612 if (len == 0) 613 return logfs_write_header(super, header, 0, type); 614 615 compr_len = logfs_compress(buf, data, len, sb->s_blocksize); 616 if (compr_len < 0 || type == JE_ANCHOR) { 617 memcpy(data, buf, len);
+4 -1
fs/logfs/logfs.h
··· 528 void logfs_set_blocks(struct inode *inode, u64 no); 529 /* these logically belong into inode.c but actually reside in readwrite.c */ 530 int logfs_read_inode(struct inode *inode); 531 - int __logfs_write_inode(struct inode *inode, long flags); 532 void logfs_evict_inode(struct inode *inode); 533 534 /* journal.c */ ··· 577 __be64 *array, int page_is_empty); 578 int logfs_exist_block(struct inode *inode, u64 bix); 579 int get_page_reserve(struct inode *inode, struct page *page); 580 extern struct logfs_block_ops indirect_block_ops; 581 582 /* segment.c */ ··· 596 void logfs_sync_area(struct logfs_area *area); 597 void logfs_sync_segments(struct super_block *sb); 598 void freeseg(struct super_block *sb, u32 segno); 599 600 /* area handling */ 601 int logfs_init_areas(struct super_block *sb);
··· 528 void logfs_set_blocks(struct inode *inode, u64 no); 529 /* these logically belong into inode.c but actually reside in readwrite.c */ 530 int logfs_read_inode(struct inode *inode); 531 + int __logfs_write_inode(struct inode *inode, struct page *, long flags); 532 void logfs_evict_inode(struct inode *inode); 533 534 /* journal.c */ ··· 577 __be64 *array, int page_is_empty); 578 int logfs_exist_block(struct inode *inode, u64 bix); 579 int get_page_reserve(struct inode *inode, struct page *page); 580 + void logfs_get_wblocks(struct super_block *sb, struct page *page, int lock); 581 + void logfs_put_wblocks(struct super_block *sb, struct page *page, int lock); 582 extern struct logfs_block_ops indirect_block_ops; 583 584 /* segment.c */ ··· 594 void logfs_sync_area(struct logfs_area *area); 595 void logfs_sync_segments(struct super_block *sb); 596 void freeseg(struct super_block *sb, u32 segno); 597 + void free_areas(struct super_block *sb); 598 599 /* area handling */ 600 int logfs_init_areas(struct super_block *sb);
+34 -17
fs/logfs/readwrite.c
··· 244 * is waiting for s_write_mutex. We annotate this fact by setting PG_pre_locked 245 * in addition to PG_locked. 246 */ 247 - static void logfs_get_wblocks(struct super_block *sb, struct page *page, 248 - int lock) 249 { 250 struct logfs_super *super = logfs_super(sb); 251 ··· 259 } 260 } 261 262 - static void logfs_put_wblocks(struct super_block *sb, struct page *page, 263 - int lock) 264 { 265 struct logfs_super *super = logfs_super(sb); 266 ··· 422 if (inode->i_ino == LOGFS_INO_MASTER) 423 logfs_write_anchor(inode->i_sb); 424 else { 425 - ret = __logfs_write_inode(inode, 0); 426 /* see indirect_write_block comment */ 427 BUG_ON(ret); 428 } ··· 558 static void indirect_free_block(struct super_block *sb, 559 struct logfs_block *block) 560 { 561 - ClearPagePrivate(block->page); 562 - block->page->private = 0; 563 __free_block(sb, block); 564 } 565 ··· 653 logfs_unpack_index(page->index, &bix, &level); 654 block = __alloc_block(inode->i_sb, inode->i_ino, bix, level); 655 block->page = page; 656 SetPagePrivate(page); 657 - page->private = (unsigned long)block; 658 block->ops = &indirect_block_ops; 659 } 660 ··· 1576 static int __logfs_delete(struct inode *inode, struct page *page) 1577 { 1578 long flags = WF_DELETE; 1579 1580 inode->i_ctime = inode->i_mtime = CURRENT_TIME; 1581 1582 if (page->index < I0_BLOCKS) 1583 return logfs_write_direct(inode, page, flags); 1584 return logfs_write_rec(inode, page, page->index, 0, flags); 1585 } 1586 ··· 1633 if (inode->i_ino == LOGFS_INO_MASTER) 1634 logfs_write_anchor(inode->i_sb); 1635 else { 1636 - err = __logfs_write_inode(inode, flags); 1637 } 1638 } 1639 } ··· 1883 logfs_get_wblocks(sb, NULL, 1); 1884 err = __logfs_truncate(inode, size); 1885 if (!err) 1886 - err = __logfs_write_inode(inode, 0); 1887 logfs_put_wblocks(sb, NULL, 1); 1888 } 1889 ··· 1911 li->li_block = block; 1912 1913 block->page = NULL; 1914 - page->private = 0; 1915 - ClearPagePrivate(page); 1916 } 1917 1918 static void move_inode_to_page(struct page *page, struct inode *inode) ··· 1931 BUG_ON(PagePrivate(page)); 1932 block->ops = &indirect_block_ops; 1933 block->page = page; 1934 - page->private = (unsigned long)block; 1935 - SetPagePrivate(page); 1936 1937 block->inode = NULL; 1938 li->li_block = NULL; ··· 2123 ec_level); 2124 } 2125 2126 - int __logfs_write_inode(struct inode *inode, long flags) 2127 { 2128 struct super_block *sb = inode->i_sb; 2129 int ret; 2130 2131 - logfs_get_wblocks(sb, NULL, flags & WF_LOCK); 2132 ret = do_write_inode(inode); 2133 - logfs_put_wblocks(sb, NULL, flags & WF_LOCK); 2134 return ret; 2135 } 2136
··· 244 * is waiting for s_write_mutex. We annotate this fact by setting PG_pre_locked 245 * in addition to PG_locked. 246 */ 247 + void logfs_get_wblocks(struct super_block *sb, struct page *page, int lock) 248 { 249 struct logfs_super *super = logfs_super(sb); 250 ··· 260 } 261 } 262 263 + void logfs_put_wblocks(struct super_block *sb, struct page *page, int lock) 264 { 265 struct logfs_super *super = logfs_super(sb); 266 ··· 424 if (inode->i_ino == LOGFS_INO_MASTER) 425 logfs_write_anchor(inode->i_sb); 426 else { 427 + ret = __logfs_write_inode(inode, NULL, 0); 428 /* see indirect_write_block comment */ 429 BUG_ON(ret); 430 } ··· 560 static void indirect_free_block(struct super_block *sb, 561 struct logfs_block *block) 562 { 563 + struct page *page = block->page; 564 + 565 + if (PagePrivate(page)) { 566 + ClearPagePrivate(page); 567 + page_cache_release(page); 568 + set_page_private(page, 0); 569 + } 570 __free_block(sb, block); 571 } 572 ··· 650 logfs_unpack_index(page->index, &bix, &level); 651 block = __alloc_block(inode->i_sb, inode->i_ino, bix, level); 652 block->page = page; 653 + 654 SetPagePrivate(page); 655 + page_cache_get(page); 656 + set_page_private(page, (unsigned long) block); 657 + 658 block->ops = &indirect_block_ops; 659 } 660 ··· 1570 static int __logfs_delete(struct inode *inode, struct page *page) 1571 { 1572 long flags = WF_DELETE; 1573 + int err; 1574 1575 inode->i_ctime = inode->i_mtime = CURRENT_TIME; 1576 1577 if (page->index < I0_BLOCKS) 1578 return logfs_write_direct(inode, page, flags); 1579 + err = grow_inode(inode, page->index, 0); 1580 + if (err) 1581 + return err; 1582 return logfs_write_rec(inode, page, page->index, 0, flags); 1583 } 1584 ··· 1623 if (inode->i_ino == LOGFS_INO_MASTER) 1624 logfs_write_anchor(inode->i_sb); 1625 else { 1626 + err = __logfs_write_inode(inode, page, flags); 1627 } 1628 } 1629 } ··· 1873 logfs_get_wblocks(sb, NULL, 1); 1874 err = __logfs_truncate(inode, size); 1875 if (!err) 1876 + err = __logfs_write_inode(inode, NULL, 0); 1877 logfs_put_wblocks(sb, NULL, 1); 1878 } 1879 ··· 1901 li->li_block = block; 1902 1903 block->page = NULL; 1904 + if (PagePrivate(page)) { 1905 + ClearPagePrivate(page); 1906 + page_cache_release(page); 1907 + set_page_private(page, 0); 1908 + } 1909 } 1910 1911 static void move_inode_to_page(struct page *page, struct inode *inode) ··· 1918 BUG_ON(PagePrivate(page)); 1919 block->ops = &indirect_block_ops; 1920 block->page = page; 1921 + 1922 + if (!PagePrivate(page)) { 1923 + SetPagePrivate(page); 1924 + page_cache_get(page); 1925 + set_page_private(page, (unsigned long) block); 1926 + } 1927 1928 block->inode = NULL; 1929 li->li_block = NULL; ··· 2106 ec_level); 2107 } 2108 2109 + int __logfs_write_inode(struct inode *inode, struct page *page, long flags) 2110 { 2111 struct super_block *sb = inode->i_sb; 2112 int ret; 2113 2114 + logfs_get_wblocks(sb, page, flags & WF_LOCK); 2115 ret = do_write_inode(inode); 2116 + logfs_put_wblocks(sb, page, flags & WF_LOCK); 2117 return ret; 2118 } 2119
+39 -12
fs/logfs/segment.c
··· 86 BUG_ON(!page); /* FIXME: reserve a pool */ 87 SetPageUptodate(page); 88 memcpy(page_address(page) + offset, buf, copylen); 89 - SetPagePrivate(page); 90 page_cache_release(page); 91 92 buf += copylen; ··· 114 page = get_mapping_page(sb, index, 0); 115 BUG_ON(!page); /* FIXME: reserve a pool */ 116 memset(page_address(page) + offset, 0xff, len); 117 - SetPagePrivate(page); 118 page_cache_release(page); 119 } 120 } ··· 137 BUG_ON(!page); /* FIXME: reserve a pool */ 138 SetPageUptodate(page); 139 memset(page_address(page), 0xff, PAGE_CACHE_SIZE); 140 - SetPagePrivate(page); 141 page_cache_release(page); 142 index++; 143 no_indizes--; ··· 495 mempool_free(item, super->s_alias_pool); 496 } 497 block->page = page; 498 - SetPagePrivate(page); 499 - page->private = (unsigned long)block; 500 block->ops = &indirect_block_ops; 501 initialize_block_counters(page, block, data, 0); 502 } ··· 550 list_add(&item->list, &block->item_list); 551 } 552 block->page = NULL; 553 - ClearPagePrivate(page); 554 - page->private = 0; 555 block->ops = &btree_block_ops; 556 err = alias_tree_insert(block->sb, block->ino, block->bix, block->level, 557 block); ··· 720 page = find_get_page(mapping, ofs >> PAGE_SHIFT); 721 if (!page) 722 continue; 723 - ClearPagePrivate(page); 724 page_cache_release(page); 725 } 726 } ··· 862 kfree(area); 863 } 864 865 static struct logfs_area *alloc_area(struct super_block *sb) 866 { 867 struct logfs_area *area; ··· 954 void logfs_cleanup_areas(struct super_block *sb) 955 { 956 struct logfs_super *super = logfs_super(sb); 957 - int i; 958 959 btree_grim_visitor128(&super->s_object_alias_tree, 0, kill_alias); 960 - for_each_area(i) 961 - free_area(super->s_area[i]); 962 - free_area(super->s_journal_area); 963 }
··· 86 BUG_ON(!page); /* FIXME: reserve a pool */ 87 SetPageUptodate(page); 88 memcpy(page_address(page) + offset, buf, copylen); 89 + 90 + if (!PagePrivate(page)) { 91 + SetPagePrivate(page); 92 + page_cache_get(page); 93 + } 94 page_cache_release(page); 95 96 buf += copylen; ··· 110 page = get_mapping_page(sb, index, 0); 111 BUG_ON(!page); /* FIXME: reserve a pool */ 112 memset(page_address(page) + offset, 0xff, len); 113 + if (!PagePrivate(page)) { 114 + SetPagePrivate(page); 115 + page_cache_get(page); 116 + } 117 page_cache_release(page); 118 } 119 } ··· 130 BUG_ON(!page); /* FIXME: reserve a pool */ 131 SetPageUptodate(page); 132 memset(page_address(page), 0xff, PAGE_CACHE_SIZE); 133 + if (!PagePrivate(page)) { 134 + SetPagePrivate(page); 135 + page_cache_get(page); 136 + } 137 page_cache_release(page); 138 index++; 139 no_indizes--; ··· 485 mempool_free(item, super->s_alias_pool); 486 } 487 block->page = page; 488 + 489 + if (!PagePrivate(page)) { 490 + SetPagePrivate(page); 491 + page_cache_get(page); 492 + set_page_private(page, (unsigned long) block); 493 + } 494 block->ops = &indirect_block_ops; 495 initialize_block_counters(page, block, data, 0); 496 } ··· 536 list_add(&item->list, &block->item_list); 537 } 538 block->page = NULL; 539 + 540 + if (PagePrivate(page)) { 541 + ClearPagePrivate(page); 542 + page_cache_release(page); 543 + set_page_private(page, 0); 544 + } 545 block->ops = &btree_block_ops; 546 err = alias_tree_insert(block->sb, block->ino, block->bix, block->level, 547 block); ··· 702 page = find_get_page(mapping, ofs >> PAGE_SHIFT); 703 if (!page) 704 continue; 705 + if (PagePrivate(page)) { 706 + ClearPagePrivate(page); 707 + page_cache_release(page); 708 + } 709 page_cache_release(page); 710 } 711 } ··· 841 kfree(area); 842 } 843 844 + void free_areas(struct super_block *sb) 845 + { 846 + struct logfs_super *super = logfs_super(sb); 847 + int i; 848 + 849 + for_each_area(i) 850 + free_area(super->s_area[i]); 851 + free_area(super->s_journal_area); 852 + } 853 + 854 static struct logfs_area *alloc_area(struct super_block *sb) 855 { 856 struct logfs_area *area; ··· 923 void logfs_cleanup_areas(struct super_block *sb) 924 { 925 struct logfs_super *super = logfs_super(sb); 926 927 btree_grim_visitor128(&super->s_object_alias_tree, 0, kill_alias); 928 }
+2 -1
fs/logfs/super.c
··· 486 /* Alias entries slow down mount, so evict as many as possible */ 487 sync_filesystem(sb); 488 logfs_write_anchor(sb); 489 490 /* 491 * From this point on alias entries are simply dropped - and any 492 * writes to the object store are considered bugs. 493 */ 494 - super->s_flags |= LOGFS_SB_FLAG_SHUTDOWN; 495 log_super("LogFS: Now in shutdown\n"); 496 generic_shutdown_super(sb); 497 498 BUG_ON(super->s_dirty_used_bytes || super->s_dirty_free_bytes); 499
··· 486 /* Alias entries slow down mount, so evict as many as possible */ 487 sync_filesystem(sb); 488 logfs_write_anchor(sb); 489 + free_areas(sb); 490 491 /* 492 * From this point on alias entries are simply dropped - and any 493 * writes to the object store are considered bugs. 494 */ 495 log_super("LogFS: Now in shutdown\n"); 496 generic_shutdown_super(sb); 497 + super->s_flags |= LOGFS_SB_FLAG_SHUTDOWN; 498 499 BUG_ON(super->s_dirty_used_bytes || super->s_dirty_free_bytes); 500
+2 -2
include/linux/mtd/mtd.h
··· 441 static inline int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs) 442 { 443 if (!mtd->block_isbad) 444 - return -EOPNOTSUPP; 445 return mtd->block_isbad(mtd, ofs); 446 } 447 ··· 489 490 static inline int mtd_can_have_bb(const struct mtd_info *mtd) 491 { 492 - return !!mtd->block_isbad; 493 } 494 495 /* Kernel-side ioctl definitions */
··· 441 static inline int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs) 442 { 443 if (!mtd->block_isbad) 444 + return 0; 445 return mtd->block_isbad(mtd, ofs); 446 } 447 ··· 489 490 static inline int mtd_can_have_bb(const struct mtd_info *mtd) 491 { 492 + return 0; 493 } 494 495 /* Kernel-side ioctl definitions */