1 /* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by
4 /* Interface to VFS. Reiser4 {super|export|dentry}_operations are defined
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"
21 #include "block_alloc.h"
25 #include "page_cache.h"
30 #include "status_flags.h"
34 #include <linux/profile.h>
35 #include <linux/types.h>
36 #include <linux/mount.h>
37 #include <linux/vfs.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
)
59 assert("nikita-2338", object
!= NULL
);
60 /* check for read-only file system. */
61 if (IS_RDONLY(object
))
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
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
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
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
);
103 /* helper function: decrease inode nlink count and call plugin method to save
106 Used by unlink/create
108 int reiser4_del_nlink(struct inode
*object
/* object from which link is
110 struct inode
*parent
/* parent where entry was */ ,
111 int write_sd_p
/* true is stat-data has to be
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
);
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
)
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
157 if (wbc
->sync_mode
!= WB_SYNC_NONE
) {
158 txnmgr_force_commit_all(sb
, 0);
162 BUG_ON(reiser4_get_super_fake(sb
) == NULL
);
163 mapping
= reiser4_get_super_fake(sb
)->i_mapping
;
165 long nr_submitted
= 0;
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;
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
187 node
= jref(ent
->cur_request
->node
);
190 result
= flush_some_atom(node
, &nr_submitted
, wbc
,
191 JNODE_FLUSH_WRITE_BLOCKS
);
193 warning("nikita-31001", "Flush failed: %i", result
);
199 wbc
->nr_to_write
-= nr_submitted
;
200 written
+= nr_submitted
;
201 } while (wbc
->nr_to_write
> 0);
204 /* tell VM how many pages were dirtied */
205 void reiser4_throttle_write(struct inode
*inode
, int nrpages
)
207 reiser4_context
*ctx
;
209 ctx
= get_current_context();
210 reiser4_txn_restart(ctx
);
211 current
->journal_info
= NULL
;
212 balance_dirty_pages_ratelimited_nr(inode
->i_mapping
, nrpages
);
213 current
->journal_info
= ctx
;
216 const char *REISER4_SUPER_MAGIC_STRING
= "ReIsEr4";
217 const int REISER4_MAGIC_OFFSET
= 16 * 4096; /* offset to magic string from the
218 * beginning of device */
221 * Reiser4 initialization/shutdown.
223 * Code below performs global reiser4 initialization that is done either as
224 * part of kernel initialization (when reiser4 is statically built-in), or
225 * during reiser4 module load (when compiled as module).
228 void reiser4_handle_error(void)
230 struct super_block
*sb
= reiser4_get_current_sb();
234 reiser4_status_write(REISER4_STATUS_DAMAGED
, 0,
235 "Filesystem error occured");
236 switch (get_super_private(sb
)->onerror
) {
238 reiser4_panic("foobar-42", "Filesystem error occured\n");
241 if (sb
->s_flags
& MS_RDONLY
)
243 sb
->s_flags
|= MS_RDONLY
;
248 struct dentry_operations reiser4_dentry_operations
= {
249 .d_revalidate
= NULL
,
253 .d_release
= reiser4_d_release
,
259 c-indentation-style: "K&R"