1 /* Copyright 2004 by Hans Reiser, licensing governed by
4 /* Directory fibrations */
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.
27 #include "plugin_header.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
42 static __u64
fibre_trivial(const struct inode
*dir
, const char *name
, int len
)
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] == '.')
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]);
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]);
84 static int change_fibration(struct inode
*inode
,
85 reiser4_plugin
* plugin
,
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
);
96 plugin
->h
.type_id
== REISER4_FIBRATION_PLUGIN_TYPE
);
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
);
105 result
= RETERR(-ENOTEMPTY
);
111 static reiser4_plugin_ops fibration_plugin_ops
= {
116 .change
= change_fibration
119 /* fibration plugins */
120 fibration_plugin fibration_plugins
[LAST_FIBRATION_ID
] = {
121 [FIBRATION_LEXICOGRAPHIC
] = {
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
] = {
134 .type_id
= REISER4_FIBRATION_PLUGIN_TYPE
,
135 .id
= FIBRATION_DOT_O
,
136 .pops
= &fibration_plugin_ops
,
138 .desc
= "fibrate .o files separately",
139 .linkage
= {NULL
, NULL
}
143 [FIBRATION_EXT_1
] = {
145 .type_id
= REISER4_FIBRATION_PLUGIN_TYPE
,
146 .id
= FIBRATION_EXT_1
,
147 .pops
= &fibration_plugin_ops
,
149 .desc
= "fibrate file by single character extension",
150 .linkage
= {NULL
, NULL
}
154 [FIBRATION_EXT_3
] = {
156 .type_id
= REISER4_FIBRATION_PLUGIN_TYPE
,
157 .id
= FIBRATION_EXT_3
,
158 .pops
= &fibration_plugin_ops
,
160 .desc
= "fibrate file by three character extension",
161 .linkage
= {NULL
, NULL
}
169 * c-indentation-style: "K&R"