diff options
author | Tejun Heo <tj@kernel.org> | 2010-04-04 22:37:28 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2010-04-04 22:37:28 -0400 |
commit | 336f5899d287f06d8329e208fc14ce50f7ec9698 (patch) | |
tree | 9b762d450d5eb248a6ff8317badb7e223d93ed58 /fs/logfs/segment.c | |
parent | a4ab2773205e8b94c18625455f85e3b6bb9d7ad6 (diff) | |
parent | db217dece3003df0841bacf9556b5c06aa097dae (diff) |
Merge branch 'master' into export-slabh
Diffstat (limited to 'fs/logfs/segment.c')
-rw-r--r-- | fs/logfs/segment.c | 54 |
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 | /* | 97 | static void pad_partial_page(struct logfs_area *area) |
98 | * bdev_writeseg will write full pages. Memset the tail to prevent data leaks. | ||
99 | */ | ||
100 | static 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) | 115 | static 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 | */ | ||
141 | static 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 | ||
687 | static void freeseg(struct super_block *sb, u32 segno) | 695 | void 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; |