On Tue, Nov 06, 2007 at 02:33:53AM -0800, akpm@linux-foundation.org wrote:
[mmotm.git] / fs / reiser4 / as_ops.c
blob8d8a37d744fbffb093b8082d2acfd49f9e48bb4a
1 /* Copyright 2003 by Hans Reiser, licensing governed by reiser4/README */
3 /* Interface to VFS. Reiser4 address_space_operations are defined here. */
5 #include "forward.h"
6 #include "debug.h"
7 #include "dformat.h"
8 #include "coord.h"
9 #include "plugin/item/item.h"
10 #include "plugin/file/file.h"
11 #include "plugin/security/perm.h"
12 #include "plugin/disk_format/disk_format.h"
13 #include "plugin/plugin.h"
14 #include "plugin/plugin_set.h"
15 #include "plugin/object.h"
16 #include "txnmgr.h"
17 #include "jnode.h"
18 #include "znode.h"
19 #include "block_alloc.h"
20 #include "tree.h"
21 #include "vfs_ops.h"
22 #include "inode.h"
23 #include "page_cache.h"
24 #include "ktxnmgrd.h"
25 #include "super.h"
26 #include "reiser4.h"
27 #include "entd.h"
29 #include <linux/profile.h>
30 #include <linux/types.h>
31 #include <linux/mount.h>
32 #include <linux/vfs.h>
33 #include <linux/mm.h>
34 #include <linux/buffer_head.h>
35 #include <linux/dcache.h>
36 #include <linux/list.h>
37 #include <linux/pagemap.h>
38 #include <linux/slab.h>
39 #include <linux/seq_file.h>
40 #include <linux/init.h>
41 #include <linux/module.h>
42 #include <linux/writeback.h>
43 #include <linux/backing-dev.h>
44 #include <linux/quotaops.h>
45 #include <linux/security.h>
47 /* address space operations */
49 /**
50 * reiser4_set_page_dirty - set dirty bit, tag in page tree, dirty accounting
51 * @page: page to be dirtied
53 * Operation of struct address_space_operations. This implementation is used by
54 * unix and cryptcompress file plugins.
56 * This is called when reiser4 page gets dirtied outside of reiser4, for
57 * example, when dirty bit is moved from pte to physical page.
59 * Tags page in the mapping's page tree with special tag so that it is possible
60 * to do all the reiser4 specific work wrt dirty pages (jnode creation,
61 * capturing by an atom) later because it can not be done in the contexts where
62 * set_page_dirty is called.
64 int reiser4_set_page_dirty(struct page *page)
66 /* this page can be unformatted only */
67 assert("vs-1734", (page->mapping &&
68 page->mapping->host &&
69 reiser4_get_super_fake(page->mapping->host->i_sb) !=
70 page->mapping->host &&
71 reiser4_get_cc_fake(page->mapping->host->i_sb) !=
72 page->mapping->host &&
73 reiser4_get_bitmap_fake(page->mapping->host->i_sb) !=
74 page->mapping->host));
75 return __set_page_dirty_nobuffers(page);
78 /* ->invalidatepage method for reiser4 */
81 * this is called for each truncated page from
82 * truncate_inode_pages()->truncate_{complete,partial}_page().
84 * At the moment of call, page is under lock, and outstanding io (if any) has
85 * completed.
88 /**
89 * reiser4_invalidatepage
90 * @page: page to invalidate
91 * @offset: starting offset for partial invalidation
94 void reiser4_invalidatepage(struct page *page, unsigned long offset)
96 int ret = 0;
97 reiser4_context *ctx;
98 struct inode *inode;
99 jnode *node;
102 * This is called to truncate file's page.
104 * Originally, reiser4 implemented truncate in a standard way
105 * (vmtruncate() calls ->invalidatepage() on all truncated pages
106 * first, then file system ->truncate() call-back is invoked).
108 * This lead to the problem when ->invalidatepage() was called on a
109 * page with jnode that was captured into atom in ASTAGE_PRE_COMMIT
110 * process. That is, truncate was bypassing transactions. To avoid
111 * this, try_capture_page_to_invalidate() call was added here.
113 * After many troubles with vmtruncate() based truncate (including
114 * races with flush, tail conversion, etc.) it was re-written in the
115 * top-to-bottom style: items are killed in reiser4_cut_tree_object()
116 * and pages belonging to extent are invalidated in kill_hook_extent().
117 * So probably now additional call to capture is not needed here.
120 assert("nikita-3137", PageLocked(page));
121 assert("nikita-3138", !PageWriteback(page));
122 inode = page->mapping->host;
125 * ->invalidatepage() should only be called for the unformatted
126 * jnodes. Destruction of all other types of jnodes is performed
127 * separately. But, during some corner cases (like handling errors
128 * during mount) it is simpler to let ->invalidatepage to be called on
129 * them. Check for this, and do nothing.
131 if (reiser4_get_super_fake(inode->i_sb) == inode)
132 return;
133 if (reiser4_get_cc_fake(inode->i_sb) == inode)
134 return;
135 if (reiser4_get_bitmap_fake(inode->i_sb) == inode)
136 return;
137 assert("vs-1426", PagePrivate(page));
138 assert("vs-1427",
139 page->mapping == jnode_get_mapping(jnode_by_page(page)));
140 assert("", jprivate(page) != NULL);
141 assert("", ergo(inode_file_plugin(inode) !=
142 file_plugin_by_id(CRYPTCOMPRESS_FILE_PLUGIN_ID),
143 offset == 0));
145 ctx = reiser4_init_context(inode->i_sb);
146 if (IS_ERR(ctx))
147 return;
149 node = jprivate(page);
150 spin_lock_jnode(node);
151 if (!(node->state & ((1 << JNODE_DIRTY) | (1 << JNODE_FLUSH_QUEUED) |
152 (1 << JNODE_WRITEBACK) | (1 << JNODE_OVRWR)))) {
153 /* there is not need to capture */
154 jref(node);
155 JF_SET(node, JNODE_HEARD_BANSHEE);
156 page_clear_jnode(page, node);
157 reiser4_uncapture_jnode(node);
158 unhash_unformatted_jnode(node);
159 jput(node);
160 reiser4_exit_context(ctx);
161 return;
163 spin_unlock_jnode(node);
165 /* capture page being truncated. */
166 ret = try_capture_page_to_invalidate(page);
167 if (ret != 0)
168 warning("nikita-3141", "Cannot capture: %i", ret);
170 if (offset == 0) {
171 /* remove jnode from transaction and detach it from page. */
172 jref(node);
173 JF_SET(node, JNODE_HEARD_BANSHEE);
174 /* page cannot be detached from jnode concurrently, because it
175 * is locked */
176 reiser4_uncapture_page(page);
178 /* this detaches page from jnode, so that jdelete will not try
179 * to lock page which is already locked */
180 spin_lock_jnode(node);
181 page_clear_jnode(page, node);
182 spin_unlock_jnode(node);
183 unhash_unformatted_jnode(node);
185 jput(node);
188 reiser4_exit_context(ctx);
191 /* help function called from reiser4_releasepage(). It returns true if jnode
192 * can be detached from its page and page released. */
193 int jnode_is_releasable(jnode * node/* node to check */)
195 assert("nikita-2781", node != NULL);
196 assert_spin_locked(&(node->guard));
197 assert_spin_locked(&(node->load));
199 /* is some thread is currently using jnode page, later cannot be
200 * detached */
201 if (atomic_read(&node->d_count) != 0)
202 return 0;
204 assert("vs-1214", !jnode_is_loaded(node));
207 * can only release page if real block number is assigned to it. Simple
208 * check for ->atom wouldn't do, because it is possible for node to be
209 * clean, not it atom yet, and still having fake block number. For
210 * example, node just created in jinit_new().
212 if (reiser4_blocknr_is_fake(jnode_get_block(node)))
213 return 0;
216 * pages prepared for write can not be released anyway, so avoid
217 * detaching jnode from the page
219 if (JF_ISSET(node, JNODE_WRITE_PREPARED))
220 return 0;
223 * dirty jnode cannot be released. It can however be submitted to disk
224 * as part of early flushing, but only after getting flush-prepped.
226 if (JF_ISSET(node, JNODE_DIRTY))
227 return 0;
229 /* overwrite set is only written by log writer. */
230 if (JF_ISSET(node, JNODE_OVRWR))
231 return 0;
233 /* jnode is already under writeback */
234 if (JF_ISSET(node, JNODE_WRITEBACK))
235 return 0;
237 /* don't flush bitmaps or journal records */
238 if (!jnode_is_znode(node) && !jnode_is_unformatted(node))
239 return 0;
241 return 1;
245 * ->releasepage method for reiser4
247 * This is called by VM scanner when it comes across clean page. What we have
248 * to do here is to check whether page can really be released (freed that is)
249 * and if so, detach jnode from it and remove page from the page cache.
251 * Check for releasability is done by releasable() function.
253 int reiser4_releasepage(struct page *page, gfp_t gfp UNUSED_ARG)
255 jnode *node;
257 assert("nikita-2257", PagePrivate(page));
258 assert("nikita-2259", PageLocked(page));
259 assert("nikita-2892", !PageWriteback(page));
260 assert("nikita-3019", reiser4_schedulable());
262 /* NOTE-NIKITA: this can be called in the context of reiser4 call. It
263 is not clear what to do in this case. A lot of deadlocks seems be
264 possible. */
266 node = jnode_by_page(page);
267 assert("nikita-2258", node != NULL);
268 assert("reiser4-4", page->mapping != NULL);
269 assert("reiser4-5", page->mapping->host != NULL);
271 if (PageDirty(page))
272 return 0;
274 /* extra page reference is used by reiser4 to protect
275 * jnode<->page link from this ->releasepage(). */
276 if (page_count(page) > 3)
277 return 0;
279 /* releasable() needs jnode lock, because it looks at the jnode fields
280 * and we need jload_lock here to avoid races with jload(). */
281 spin_lock_jnode(node);
282 spin_lock(&(node->load));
283 if (jnode_is_releasable(node)) {
284 struct address_space *mapping;
286 mapping = page->mapping;
287 jref(node);
288 /* there is no need to synchronize against
289 * jnode_extent_write() here, because pages seen by
290 * jnode_extent_write() are !releasable(). */
291 page_clear_jnode(page, node);
292 spin_unlock(&(node->load));
293 spin_unlock_jnode(node);
295 /* we are under memory pressure so release jnode also. */
296 jput(node);
298 return 1;
299 } else {
300 spin_unlock(&(node->load));
301 spin_unlock_jnode(node);
302 assert("nikita-3020", reiser4_schedulable());
303 return 0;
307 int reiser4_readpage(struct file *file, struct page *page)
309 assert("edward-1533", PageLocked(page));
310 assert("edward-1534", !PageUptodate(page));
311 assert("edward-1535", page->mapping && page->mapping->host);
313 return inode_file_plugin(page->mapping->host)->readpage(file, page);
316 int reiser4_readpages(struct file *file, struct address_space *mapping,
317 struct list_head *pages, unsigned nr_pages)
319 return inode_file_plugin(mapping->host)->readpages(file, mapping,
320 pages, nr_pages);
323 int reiser4_writepages(struct address_space *mapping,
324 struct writeback_control *wbc)
326 return inode_file_plugin(mapping->host)->writepages(mapping, wbc);
329 /* Make Linus happy.
330 Local variables:
331 c-indentation-style: "K&R"
332 mode-name: "LC"
333 c-basic-offset: 8
334 tab-width: 8
335 fill-column: 120
336 End: