aboutsummaryrefslogtreecommitdiffstats
path: root/fs/logfs/segment.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/logfs/segment.c')
-rw-r--r--fs/logfs/segment.c54
1 files changed, 31 insertions, 23 deletions
diff --git a/fs/logfs/segment.c b/fs/logfs/segment.c
index 614d7a6fda2d..801a3a141625 100644
--- a/fs/logfs/segment.c
+++ b/fs/logfs/segment.c
@@ -94,50 +94,58 @@ void __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len,
94 } while (len); 94 } while (len);
95} 95}
96 96
97/* 97static void pad_partial_page(struct logfs_area *area)
98 * bdev_writeseg will write full pages. Memset the tail to prevent data leaks.
99 */
100static void pad_wbuf(struct logfs_area *area, int final)
101{ 98{
102 struct super_block *sb = area->a_sb; 99 struct super_block *sb = area->a_sb;
103 struct logfs_super *super = logfs_super(sb);
104 struct page *page; 100 struct page *page;
105 u64 ofs = dev_ofs(sb, area->a_segno, area->a_used_bytes); 101 u64 ofs = dev_ofs(sb, area->a_segno, area->a_used_bytes);
106 pgoff_t index = ofs >> PAGE_SHIFT; 102 pgoff_t index = ofs >> PAGE_SHIFT;
107 long offset = ofs & (PAGE_SIZE-1); 103 long offset = ofs & (PAGE_SIZE-1);
108 u32 len = PAGE_SIZE - offset; 104 u32 len = PAGE_SIZE - offset;
109 105
110 if (len == PAGE_SIZE) { 106 if (len % PAGE_SIZE) {
111 /* The math in this function can surely use some love */ 107 page = get_mapping_page(sb, index, 0);
112 len = 0;
113 }
114 if (len) {
115 BUG_ON(area->a_used_bytes >= super->s_segsize);
116
117 page = get_mapping_page(area->a_sb, index, 0);
118 BUG_ON(!page); /* FIXME: reserve a pool */ 108 BUG_ON(!page); /* FIXME: reserve a pool */
119 memset(page_address(page) + offset, 0xff, len); 109 memset(page_address(page) + offset, 0xff, len);
120 SetPagePrivate(page); 110 SetPagePrivate(page);
121 page_cache_release(page); 111 page_cache_release(page);
122 } 112 }
113}
123 114
124 if (!final) 115static void pad_full_pages(struct logfs_area *area)
125 return; 116{
117 struct super_block *sb = area->a_sb;
118 struct logfs_super *super = logfs_super(sb);
119 u64 ofs = dev_ofs(sb, area->a_segno, area->a_used_bytes);
120 u32 len = super->s_segsize - area->a_used_bytes;
121 pgoff_t index = PAGE_CACHE_ALIGN(ofs) >> PAGE_CACHE_SHIFT;
122 pgoff_t no_indizes = len >> PAGE_CACHE_SHIFT;
123 struct page *page;
126 124
127 area->a_used_bytes += len; 125 while (no_indizes) {
128 for ( ; area->a_used_bytes < super->s_segsize; 126 page = get_mapping_page(sb, index, 0);
129 area->a_used_bytes += PAGE_SIZE) {
130 /* Memset another page */
131 index++;
132 page = get_mapping_page(area->a_sb, index, 0);
133 BUG_ON(!page); /* FIXME: reserve a pool */ 127 BUG_ON(!page); /* FIXME: reserve a pool */
134 memset(page_address(page), 0xff, PAGE_SIZE); 128 SetPageUptodate(page);
129 memset(page_address(page), 0xff, PAGE_CACHE_SIZE);
135 SetPagePrivate(page); 130 SetPagePrivate(page);
136 page_cache_release(page); 131 page_cache_release(page);
132 index++;
133 no_indizes--;
137 } 134 }
138} 135}
139 136
140/* 137/*
138 * bdev_writeseg will write full pages. Memset the tail to prevent data leaks.
139 * Also make sure we allocate (and memset) all pages for final writeout.
140 */
141static void pad_wbuf(struct logfs_area *area, int final)
142{
143 pad_partial_page(area);
144 if (final)
145 pad_full_pages(area);
146}
147
148/*
141 * We have to be careful with the alias tree. Since lookup is done by bix, 149 * We have to be careful with the alias tree. Since lookup is done by bix,
142 * it needs to be normalized, so 14, 15, 16, etc. all match when dealing with 150 * it needs to be normalized, so 14, 15, 16, etc. all match when dealing with
143 * indirect blocks. So always use it through accessor functions. 151 * indirect blocks. So always use it through accessor functions.
@@ -684,7 +692,7 @@ int logfs_segment_delete(struct inode *inode, struct logfs_shadow *shadow)
684 return 0; 692 return 0;
685} 693}
686 694
687static void freeseg(struct super_block *sb, u32 segno) 695void freeseg(struct super_block *sb, u32 segno)
688{ 696{
689 struct logfs_super *super = logfs_super(sb); 697 struct logfs_super *super = logfs_super(sb);
690 struct address_space *mapping = super->s_mapping_inode->i_mapping; 698 struct address_space *mapping = super->s_mapping_inode->i_mapping;