revert-mm-fix-blkdev-size-calculation-in-generic_write_checks
[linux-2.6/linux-trees-mm.git] / fs / reiser4 / vfs_ops.c
blob31afd3e49358897dd3a8a10f17fd9c4a48d536f4
1 /* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by
2 * reiser4/README */
4 /* Interface to VFS. Reiser4 {super|export|dentry}_operations are defined
5 here. */
7 #include "forward.h"
8 #include "debug.h"
9 #include "dformat.h"
10 #include "coord.h"
11 #include "plugin/item/item.h"
12 #include "plugin/file/file.h"
13 #include "plugin/security/perm.h"
14 #include "plugin/disk_format/disk_format.h"
15 #include "plugin/plugin.h"
16 #include "plugin/plugin_set.h"
17 #include "plugin/object.h"
18 #include "txnmgr.h"
19 #include "jnode.h"
20 #include "znode.h"
21 #include "block_alloc.h"
22 #include "tree.h"
23 #include "vfs_ops.h"
24 #include "inode.h"
25 #include "page_cache.h"
26 #include "ktxnmgrd.h"
27 #include "super.h"
28 #include "reiser4.h"
29 #include "entd.h"
30 #include "status_flags.h"
31 #include "flush.h"
32 #include "dscale.h"
34 #include <linux/profile.h>
35 #include <linux/types.h>
36 #include <linux/mount.h>
37 #include <linux/vfs.h>
38 #include <linux/mm.h>
39 #include <linux/buffer_head.h>
40 #include <linux/dcache.h>
41 #include <linux/list.h>
42 #include <linux/pagemap.h>
43 #include <linux/slab.h>
44 #include <linux/seq_file.h>
45 #include <linux/init.h>
46 #include <linux/module.h>
47 #include <linux/writeback.h>
48 #include <linux/blkdev.h>
49 #include <linux/quotaops.h>
50 #include <linux/security.h>
51 #include <linux/reboot.h>
52 #include <linux/rcupdate.h>
54 /* update inode stat-data by calling plugin */
55 int reiser4_update_sd(struct inode *object)
57 file_plugin *fplug;
59 assert("nikita-2338", object != NULL);
60 /* check for read-only file system. */
61 if (IS_RDONLY(object))
62 return 0;
64 fplug = inode_file_plugin(object);
65 assert("nikita-2339", fplug != NULL);
66 return fplug->write_sd_by_inode(object);
69 /* helper function: increase inode nlink count and call plugin method to save
70 updated stat-data.
72 Used by link/create and during creation of dot and dotdot in mkdir
74 int reiser4_add_nlink(struct inode *object /* object to which link is added */ ,
75 struct inode *parent /* parent where new entry will be */
77 int write_sd_p /* true if stat-data has to be
78 * updated */ )
80 file_plugin *fplug;
81 int result;
83 assert("nikita-1351", object != NULL);
85 fplug = inode_file_plugin(object);
86 assert("nikita-1445", fplug != NULL);
88 /* ask plugin whether it can add yet another link to this
89 object */
90 if (!fplug->can_add_link(object))
91 return RETERR(-EMLINK);
93 assert("nikita-2211", fplug->add_link != NULL);
94 /* call plugin to do actual addition of link */
95 result = fplug->add_link(object, parent);
97 /* optionally update stat data */
98 if (result == 0 && write_sd_p)
99 result = fplug->write_sd_by_inode(object);
100 return result;
103 /* helper function: decrease inode nlink count and call plugin method to save
104 updated stat-data.
106 Used by unlink/create
108 int reiser4_del_nlink(struct inode *object /* object from which link is
109 * removed */ ,
110 struct inode *parent /* parent where entry was */ ,
111 int write_sd_p /* true is stat-data has to be
112 * updated */ )
114 file_plugin *fplug;
115 int result;
117 assert("nikita-1349", object != NULL);
119 fplug = inode_file_plugin(object);
120 assert("nikita-1350", fplug != NULL);
121 assert("nikita-1446", object->i_nlink > 0);
122 assert("nikita-2210", fplug->rem_link != NULL);
124 /* call plugin to do actual deletion of link */
125 result = fplug->rem_link(object, parent);
127 /* optionally update stat data */
128 if (result == 0 && write_sd_p)
129 result = fplug->write_sd_by_inode(object);
130 return result;
133 /* Release reiser4 dentry. This is d_op->d_release() method. */
134 static void reiser4_d_release(struct dentry *dentry /* dentry released */ )
136 reiser4_free_dentry_fsdata(dentry);
140 * Called by reiser4_sync_inodes(), during speculative write-back (through
141 * pdflush, or balance_dirty_pages()).
143 void reiser4_writeout(struct super_block *sb, struct writeback_control *wbc)
145 long written = 0;
146 int repeats = 0;
147 int result;
148 struct address_space *mapping;
151 * Performs early flushing, trying to free some memory. If there is
152 * nothing to flush, commits some atoms.
155 /* Commit all atoms if reiser4_writepages() is called from sys_sync() or
156 sys_fsync(). */
157 if (wbc->sync_mode != WB_SYNC_NONE) {
158 txnmgr_force_commit_all(sb, 0);
159 return;
162 BUG_ON(reiser4_get_super_fake(sb) == NULL);
163 mapping = reiser4_get_super_fake(sb)->i_mapping;
164 do {
165 long nr_submitted = 0;
166 jnode *node = NULL;
168 /* do not put more requests to overload write queue */
169 if (wbc->nonblocking &&
170 bdi_write_congested(mapping->backing_dev_info)) {
171 blk_run_address_space(mapping);
172 wbc->encountered_congestion = 1;
173 break;
175 repeats++;
176 BUG_ON(wbc->nr_to_write <= 0);
178 if (get_current_context()->entd) {
179 entd_context *ent = get_entd_context(sb);
181 if (ent->cur_request->node)
183 * this is ent thread and it managed to capture
184 * requested page itself - start flush from
185 * that page
187 node = jref(ent->cur_request->node);
190 result = flush_some_atom(node, &nr_submitted, wbc,
191 JNODE_FLUSH_WRITE_BLOCKS);
192 if (result != 0)
193 warning("nikita-31001", "Flush failed: %i", result);
194 if (node)
195 jput(node);
196 if (!nr_submitted)
197 break;
199 wbc->nr_to_write -= nr_submitted;
200 written += nr_submitted;
201 } while (wbc->nr_to_write > 0);
204 void reiser4_throttle_write(struct inode *inode)
206 reiser4_txn_restart_current();
207 balance_dirty_pages_ratelimited(inode->i_mapping);
210 const char *REISER4_SUPER_MAGIC_STRING = "ReIsEr4";
211 const int REISER4_MAGIC_OFFSET = 16 * 4096; /* offset to magic string from the
212 * beginning of device */
215 * Reiser4 initialization/shutdown.
217 * Code below performs global reiser4 initialization that is done either as
218 * part of kernel initialization (when reiser4 is statically built-in), or
219 * during reiser4 module load (when compiled as module).
222 void reiser4_handle_error(void)
224 struct super_block *sb = reiser4_get_current_sb();
226 if (!sb)
227 return;
228 reiser4_status_write(REISER4_STATUS_DAMAGED, 0,
229 "Filesystem error occured");
230 switch (get_super_private(sb)->onerror) {
231 case 0:
232 reiser4_panic("foobar-42", "Filesystem error occured\n");
233 case 1:
234 default:
235 if (sb->s_flags & MS_RDONLY)
236 return;
237 sb->s_flags |= MS_RDONLY;
238 break;
242 struct dentry_operations reiser4_dentry_operations = {
243 .d_revalidate = NULL,
244 .d_hash = NULL,
245 .d_compare = NULL,
246 .d_delete = NULL,
247 .d_release = reiser4_d_release,
248 .d_iput = NULL,
251 /* Make Linus happy.
252 Local variables:
253 c-indentation-style: "K&R"
254 mode-name: "LC"
255 c-basic-offset: 8
256 tab-width: 8
257 fill-column: 120
258 End: