revert-mm-fix-blkdev-size-calculation-in-generic_write_checks
[linux-2.6/linux-trees-mm.git] / fs / reiser4 / plugin / fibration.c
blob690dac4b83a131c0b280c46a7791c15d44906139
1 /* Copyright 2004 by Hans Reiser, licensing governed by
2 * reiser4/README */
4 /* Directory fibrations */
6 /*
7 * Suppose we have a directory tree with sources of some project. During
8 * compilation .o files are created within this tree. This makes access
9 * to the original source files less efficient, because source files are
10 * now "diluted" by object files: default directory plugin uses prefix
11 * of a file name as a part of the key for directory entry (and this
12 * part is also inherited by the key of file body). This means that
13 * foo.o will be located close to foo.c and foo.h in the tree.
15 * To avoid this effect directory plugin fill highest 7 (unused
16 * originally) bits of the second component of the directory entry key
17 * by bit-pattern depending on the file name (see
18 * fs/reiser4/kassign.c:build_entry_key_common()). These bits are called
19 * "fibre". Fibre of the file name key is inherited by key of stat data
20 * and keys of file body (in the case of REISER4_LARGE_KEY).
22 * Fibre for a given file is chosen by per-directory fibration
23 * plugin. Names within given fibre are ordered lexicographically.
26 #include "../debug.h"
27 #include "plugin_header.h"
28 #include "plugin.h"
29 #include "../super.h"
30 #include "../inode.h"
32 #include <linux/types.h>
34 static const int fibre_shift = 57;
36 #define FIBRE_NO(n) (((__u64)(n)) << fibre_shift)
39 * Trivial fibration: all files of directory are just ordered
40 * lexicographically.
42 static __u64 fibre_trivial(const struct inode *dir, const char *name, int len)
44 return FIBRE_NO(0);
48 * dot-o fibration: place .o files after all others.
50 static __u64 fibre_dot_o(const struct inode *dir, const char *name, int len)
52 /* special treatment for .*\.o */
53 if (len > 2 && name[len - 1] == 'o' && name[len - 2] == '.')
54 return FIBRE_NO(1);
55 else
56 return FIBRE_NO(0);
60 * ext.1 fibration: subdivide directory into 128 fibrations one for each
61 * 7bit extension character (file "foo.h" goes into fibre "h"), plus
62 * default fibre for the rest.
64 static __u64 fibre_ext_1(const struct inode *dir, const char *name, int len)
66 if (len > 2 && name[len - 2] == '.')
67 return FIBRE_NO(name[len - 1]);
68 else
69 return FIBRE_NO(0);
73 * ext.3 fibration: try to separate files with different 3-character
74 * extensions from each other.
76 static __u64 fibre_ext_3(const struct inode *dir, const char *name, int len)
78 if (len > 4 && name[len - 4] == '.')
79 return FIBRE_NO(name[len - 3] + name[len - 2] + name[len - 1]);
80 else
81 return FIBRE_NO(0);
84 static int change_fibration(struct inode *inode,
85 reiser4_plugin * plugin,
86 pset_member memb)
88 int result;
90 assert("nikita-3503", inode != NULL);
91 assert("nikita-3504", plugin != NULL);
93 assert("nikita-3505", is_reiser4_inode(inode));
94 assert("nikita-3506", inode_dir_plugin(inode) != NULL);
95 assert("nikita-3507",
96 plugin->h.type_id == REISER4_FIBRATION_PLUGIN_TYPE);
98 result = 0;
99 if (inode_fibration_plugin(inode) == NULL ||
100 inode_fibration_plugin(inode)->h.id != plugin->h.id) {
101 if (is_dir_empty(inode) == 0)
102 result = aset_set_unsafe(&reiser4_inode_data(inode)->pset,
103 PSET_FIBRATION, plugin);
104 else
105 result = RETERR(-ENOTEMPTY);
108 return result;
111 static reiser4_plugin_ops fibration_plugin_ops = {
112 .init = NULL,
113 .load = NULL,
114 .save_len = NULL,
115 .save = NULL,
116 .change = change_fibration
119 /* fibration plugins */
120 fibration_plugin fibration_plugins[LAST_FIBRATION_ID] = {
121 [FIBRATION_LEXICOGRAPHIC] = {
122 .h = {
123 .type_id = REISER4_FIBRATION_PLUGIN_TYPE,
124 .id = FIBRATION_LEXICOGRAPHIC,
125 .pops = &fibration_plugin_ops,
126 .label = "lexicographic",
127 .desc = "no fibration",
128 .linkage = {NULL, NULL}
130 .fibre = fibre_trivial
132 [FIBRATION_DOT_O] = {
133 .h = {
134 .type_id = REISER4_FIBRATION_PLUGIN_TYPE,
135 .id = FIBRATION_DOT_O,
136 .pops = &fibration_plugin_ops,
137 .label = "dot-o",
138 .desc = "fibrate .o files separately",
139 .linkage = {NULL, NULL}
141 .fibre = fibre_dot_o
143 [FIBRATION_EXT_1] = {
144 .h = {
145 .type_id = REISER4_FIBRATION_PLUGIN_TYPE,
146 .id = FIBRATION_EXT_1,
147 .pops = &fibration_plugin_ops,
148 .label = "ext-1",
149 .desc = "fibrate file by single character extension",
150 .linkage = {NULL, NULL}
152 .fibre = fibre_ext_1
154 [FIBRATION_EXT_3] = {
155 .h = {
156 .type_id = REISER4_FIBRATION_PLUGIN_TYPE,
157 .id = FIBRATION_EXT_3,
158 .pops = &fibration_plugin_ops,
159 .label = "ext-3",
160 .desc = "fibrate file by three character extension",
161 .linkage = {NULL, NULL}
163 .fibre = fibre_ext_3
168 * Local variables:
169 * c-indentation-style: "K&R"
170 * mode-name: "LC"
171 * c-basic-offset: 8
172 * tab-width: 8
173 * fill-column: 79
174 * End: