revert-mm-fix-blkdev-size-calculation-in-generic_write_checks
[linux-2.6/linux-trees-mm.git] / fs / reiser4 / plugin / item / sde.c
blob27f2400a7ad26c3b750464e8f3c9e35b30b2a829
1 /* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */
3 /* Directory entry implementation */
4 #include "../../forward.h"
5 #include "../../debug.h"
6 #include "../../dformat.h"
7 #include "../../kassign.h"
8 #include "../../coord.h"
9 #include "sde.h"
10 #include "item.h"
11 #include "../plugin.h"
12 #include "../../znode.h"
13 #include "../../carry.h"
14 #include "../../tree.h"
15 #include "../../inode.h"
17 #include <linux/fs.h> /* for struct inode */
18 #include <linux/dcache.h> /* for struct dentry */
19 #include <linux/quotaops.h>
21 /* ->extract_key() method of simple directory item plugin. */
22 int extract_key_de(const coord_t * coord /* coord of item */ ,
23 reiser4_key * key /* resulting key */ )
25 directory_entry_format *dent;
27 assert("nikita-1458", coord != NULL);
28 assert("nikita-1459", key != NULL);
30 dent = (directory_entry_format *) item_body_by_coord(coord);
31 assert("nikita-1158", item_length_by_coord(coord) >= (int)sizeof *dent);
32 return extract_key_from_id(&dent->id, key);
35 int
36 update_key_de(const coord_t * coord, const reiser4_key * key,
37 lock_handle * lh UNUSED_ARG)
39 directory_entry_format *dent;
40 obj_key_id obj_id;
41 int result;
43 assert("nikita-2342", coord != NULL);
44 assert("nikita-2343", key != NULL);
46 dent = (directory_entry_format *) item_body_by_coord(coord);
47 result = build_obj_key_id(key, &obj_id);
48 if (result == 0) {
49 dent->id = obj_id;
50 znode_make_dirty(coord->node);
52 return 0;
55 char *extract_dent_name(const coord_t * coord, directory_entry_format * dent,
56 char *buf)
58 reiser4_key key;
60 unit_key_by_coord(coord, &key);
61 if (get_key_type(&key) != KEY_FILE_NAME_MINOR)
62 reiser4_print_address("oops", znode_get_block(coord->node));
63 if (!is_longname_key(&key)) {
64 if (is_dot_key(&key))
65 return (char *)".";
66 else
67 return extract_name_from_key(&key, buf);
68 } else
69 return (char *)dent->name;
72 /* ->extract_name() method of simple directory item plugin. */
73 char *extract_name_de(const coord_t * coord /* coord of item */ , char *buf)
75 directory_entry_format *dent;
77 assert("nikita-1460", coord != NULL);
79 dent = (directory_entry_format *) item_body_by_coord(coord);
80 return extract_dent_name(coord, dent, buf);
83 /* ->extract_file_type() method of simple directory item plugin. */
84 unsigned extract_file_type_de(const coord_t * coord UNUSED_ARG /* coord of
85 * item */ )
87 assert("nikita-1764", coord != NULL);
88 /* we don't store file type in the directory entry yet.
90 But see comments at kassign.h:obj_key_id
92 return DT_UNKNOWN;
95 int add_entry_de(struct inode *dir /* directory of item */ ,
96 coord_t * coord /* coord of item */ ,
97 lock_handle * lh /* insertion lock handle */ ,
98 const struct dentry *de /* name to add */ ,
99 reiser4_dir_entry_desc * entry /* parameters of new directory
100 * entry */ )
102 reiser4_item_data data;
103 directory_entry_format *dent;
104 int result;
105 const char *name;
106 int len;
107 int longname;
109 name = de->d_name.name;
110 len = de->d_name.len;
111 assert("nikita-1163", strlen(name) == len);
113 longname = is_longname(name, len);
115 data.length = sizeof *dent;
116 if (longname)
117 data.length += len + 1;
118 data.data = NULL;
119 data.user = 0;
120 data.iplug = item_plugin_by_id(SIMPLE_DIR_ENTRY_ID);
122 /* NOTE-NIKITA quota plugin */
123 if (DQUOT_ALLOC_SPACE_NODIRTY(dir, data.length))
124 return -EDQUOT;
126 result = insert_by_coord(coord, &data, &entry->key, lh, 0 /*flags */ );
127 if (result != 0)
128 return result;
130 dent = (directory_entry_format *) item_body_by_coord(coord);
131 build_inode_key_id(entry->obj, &dent->id);
132 if (longname) {
133 memcpy(dent->name, name, len);
134 put_unaligned(0, &dent->name[len]);
136 return 0;
139 int rem_entry_de(struct inode *dir /* directory of item */ ,
140 const struct qstr *name UNUSED_ARG,
141 coord_t * coord /* coord of item */ ,
142 lock_handle * lh UNUSED_ARG /* lock handle for
143 * removal */ ,
144 reiser4_dir_entry_desc * entry UNUSED_ARG /* parameters of
145 * directory entry
146 * being removed */ )
148 coord_t shadow;
149 int result;
150 int length;
152 length = item_length_by_coord(coord);
153 if (inode_get_bytes(dir) < length) {
154 warning("nikita-2627", "Dir is broke: %llu: %llu",
155 (unsigned long long)get_inode_oid(dir),
156 inode_get_bytes(dir));
158 return RETERR(-EIO);
161 /* cut_node() is supposed to take pointers to _different_
162 coords, because it will modify them without respect to
163 possible aliasing. To work around this, create temporary copy
164 of @coord.
166 coord_dup(&shadow, coord);
167 result =
168 kill_node_content(coord, &shadow, NULL, NULL, NULL, NULL, NULL, 0);
169 if (result == 0) {
170 /* NOTE-NIKITA quota plugin */
171 DQUOT_FREE_SPACE_NODIRTY(dir, length);
173 return result;
176 int max_name_len_de(const struct inode *dir)
178 return reiser4_tree_by_inode(dir)->nplug->max_item_size() -
179 sizeof(directory_entry_format) - 2;
182 /* Make Linus happy.
183 Local variables:
184 c-indentation-style: "K&R"
185 mode-name: "LC"
186 c-basic-offset: 8
187 tab-width: 8
188 fill-column: 120
189 End: