diff options
Diffstat (limited to 'fs/reiserfs/namei.c')
-rw-r--r-- | fs/reiserfs/namei.c | 2574 |
1 files changed, 1330 insertions, 1244 deletions
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index 4a333255f27a..a20bbc1642dc 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c | |||
@@ -25,86 +25,85 @@ | |||
25 | 25 | ||
26 | // directory item contains array of entry headers. This performs | 26 | // directory item contains array of entry headers. This performs |
27 | // binary search through that array | 27 | // binary search through that array |
28 | static int bin_search_in_dir_item (struct reiserfs_dir_entry * de, loff_t off) | 28 | static int bin_search_in_dir_item(struct reiserfs_dir_entry *de, loff_t off) |
29 | { | 29 | { |
30 | struct item_head * ih = de->de_ih; | 30 | struct item_head *ih = de->de_ih; |
31 | struct reiserfs_de_head * deh = de->de_deh; | 31 | struct reiserfs_de_head *deh = de->de_deh; |
32 | int rbound, lbound, j; | 32 | int rbound, lbound, j; |
33 | 33 | ||
34 | lbound = 0; | 34 | lbound = 0; |
35 | rbound = I_ENTRY_COUNT (ih) - 1; | 35 | rbound = I_ENTRY_COUNT(ih) - 1; |
36 | 36 | ||
37 | for (j = (rbound + lbound) / 2; lbound <= rbound; j = (rbound + lbound) / 2) { | 37 | for (j = (rbound + lbound) / 2; lbound <= rbound; |
38 | if (off < deh_offset (deh + j)) { | 38 | j = (rbound + lbound) / 2) { |
39 | rbound = j - 1; | 39 | if (off < deh_offset(deh + j)) { |
40 | continue; | 40 | rbound = j - 1; |
41 | continue; | ||
42 | } | ||
43 | if (off > deh_offset(deh + j)) { | ||
44 | lbound = j + 1; | ||
45 | continue; | ||
46 | } | ||
47 | // this is not name found, but matched third key component | ||
48 | de->de_entry_num = j; | ||
49 | return NAME_FOUND; | ||
41 | } | 50 | } |
42 | if (off > deh_offset (deh + j)) { | ||
43 | lbound = j + 1; | ||
44 | continue; | ||
45 | } | ||
46 | // this is not name found, but matched third key component | ||
47 | de->de_entry_num = j; | ||
48 | return NAME_FOUND; | ||
49 | } | ||
50 | 51 | ||
51 | de->de_entry_num = lbound; | 52 | de->de_entry_num = lbound; |
52 | return NAME_NOT_FOUND; | 53 | return NAME_NOT_FOUND; |
53 | } | 54 | } |
54 | 55 | ||
55 | |||
56 | // comment? maybe something like set de to point to what the path points to? | 56 | // comment? maybe something like set de to point to what the path points to? |
57 | static inline void set_de_item_location (struct reiserfs_dir_entry * de, struct path * path) | 57 | static inline void set_de_item_location(struct reiserfs_dir_entry *de, |
58 | struct path *path) | ||
58 | { | 59 | { |
59 | de->de_bh = get_last_bh (path); | 60 | de->de_bh = get_last_bh(path); |
60 | de->de_ih = get_ih (path); | 61 | de->de_ih = get_ih(path); |
61 | de->de_deh = B_I_DEH (de->de_bh, de->de_ih); | 62 | de->de_deh = B_I_DEH(de->de_bh, de->de_ih); |
62 | de->de_item_num = PATH_LAST_POSITION (path); | 63 | de->de_item_num = PATH_LAST_POSITION(path); |
63 | } | 64 | } |
64 | |||
65 | 65 | ||
66 | // de_bh, de_ih, de_deh (points to first element of array), de_item_num is set | 66 | // de_bh, de_ih, de_deh (points to first element of array), de_item_num is set |
67 | inline void set_de_name_and_namelen (struct reiserfs_dir_entry * de) | 67 | inline void set_de_name_and_namelen(struct reiserfs_dir_entry *de) |
68 | { | 68 | { |
69 | struct reiserfs_de_head * deh = de->de_deh + de->de_entry_num; | 69 | struct reiserfs_de_head *deh = de->de_deh + de->de_entry_num; |
70 | 70 | ||
71 | if (de->de_entry_num >= ih_entry_count (de->de_ih)) | 71 | if (de->de_entry_num >= ih_entry_count(de->de_ih)) |
72 | BUG (); | 72 | BUG(); |
73 | 73 | ||
74 | de->de_entrylen = entry_length (de->de_bh, de->de_ih, de->de_entry_num); | 74 | de->de_entrylen = entry_length(de->de_bh, de->de_ih, de->de_entry_num); |
75 | de->de_namelen = de->de_entrylen - (de_with_sd (deh) ? SD_SIZE : 0); | 75 | de->de_namelen = de->de_entrylen - (de_with_sd(deh) ? SD_SIZE : 0); |
76 | de->de_name = B_I_PITEM (de->de_bh, de->de_ih) + deh_location(deh); | 76 | de->de_name = B_I_PITEM(de->de_bh, de->de_ih) + deh_location(deh); |
77 | if (de->de_name[de->de_namelen - 1] == 0) | 77 | if (de->de_name[de->de_namelen - 1] == 0) |
78 | de->de_namelen = strlen (de->de_name); | 78 | de->de_namelen = strlen(de->de_name); |
79 | } | 79 | } |
80 | 80 | ||
81 | |||
82 | // what entry points to | 81 | // what entry points to |
83 | static inline void set_de_object_key (struct reiserfs_dir_entry * de) | 82 | static inline void set_de_object_key(struct reiserfs_dir_entry *de) |
84 | { | 83 | { |
85 | if (de->de_entry_num >= ih_entry_count (de->de_ih)) | 84 | if (de->de_entry_num >= ih_entry_count(de->de_ih)) |
86 | BUG (); | 85 | BUG(); |
87 | de->de_dir_id = deh_dir_id( &(de->de_deh[de->de_entry_num])); | 86 | de->de_dir_id = deh_dir_id(&(de->de_deh[de->de_entry_num])); |
88 | de->de_objectid = deh_objectid( &(de->de_deh[de->de_entry_num])); | 87 | de->de_objectid = deh_objectid(&(de->de_deh[de->de_entry_num])); |
89 | } | 88 | } |
90 | 89 | ||
91 | 90 | static inline void store_de_entry_key(struct reiserfs_dir_entry *de) | |
92 | static inline void store_de_entry_key (struct reiserfs_dir_entry * de) | ||
93 | { | 91 | { |
94 | struct reiserfs_de_head * deh = de->de_deh + de->de_entry_num; | 92 | struct reiserfs_de_head *deh = de->de_deh + de->de_entry_num; |
95 | 93 | ||
96 | if (de->de_entry_num >= ih_entry_count (de->de_ih)) | 94 | if (de->de_entry_num >= ih_entry_count(de->de_ih)) |
97 | BUG (); | 95 | BUG(); |
98 | 96 | ||
99 | /* store key of the found entry */ | 97 | /* store key of the found entry */ |
100 | de->de_entry_key.version = KEY_FORMAT_3_5; | 98 | de->de_entry_key.version = KEY_FORMAT_3_5; |
101 | de->de_entry_key.on_disk_key.k_dir_id = le32_to_cpu (de->de_ih->ih_key.k_dir_id); | 99 | de->de_entry_key.on_disk_key.k_dir_id = |
102 | de->de_entry_key.on_disk_key.k_objectid = le32_to_cpu (de->de_ih->ih_key.k_objectid); | 100 | le32_to_cpu(de->de_ih->ih_key.k_dir_id); |
103 | set_cpu_key_k_offset (&(de->de_entry_key), deh_offset (deh)); | 101 | de->de_entry_key.on_disk_key.k_objectid = |
104 | set_cpu_key_k_type (&(de->de_entry_key), TYPE_DIRENTRY); | 102 | le32_to_cpu(de->de_ih->ih_key.k_objectid); |
103 | set_cpu_key_k_offset(&(de->de_entry_key), deh_offset(deh)); | ||
104 | set_cpu_key_k_type(&(de->de_entry_key), TYPE_DIRENTRY); | ||
105 | } | 105 | } |
106 | 106 | ||
107 | |||
108 | /* We assign a key to each directory item, and place multiple entries | 107 | /* We assign a key to each directory item, and place multiple entries |
109 | in a single directory item. A directory item has a key equal to the | 108 | in a single directory item. A directory item has a key equal to the |
110 | key of the first directory entry in it. | 109 | key of the first directory entry in it. |
@@ -117,58 +116,60 @@ entry position in the item | |||
117 | */ | 116 | */ |
118 | 117 | ||
119 | /* The function is NOT SCHEDULE-SAFE! */ | 118 | /* The function is NOT SCHEDULE-SAFE! */ |
120 | int search_by_entry_key (struct super_block * sb, const struct cpu_key * key, | 119 | int search_by_entry_key(struct super_block *sb, const struct cpu_key *key, |
121 | struct path * path, struct reiserfs_dir_entry * de) | 120 | struct path *path, struct reiserfs_dir_entry *de) |
122 | { | 121 | { |
123 | int retval; | 122 | int retval; |
124 | 123 | ||
125 | retval = search_item (sb, key, path); | 124 | retval = search_item(sb, key, path); |
126 | switch (retval) { | 125 | switch (retval) { |
127 | case ITEM_NOT_FOUND: | 126 | case ITEM_NOT_FOUND: |
128 | if (!PATH_LAST_POSITION (path)) { | 127 | if (!PATH_LAST_POSITION(path)) { |
129 | reiserfs_warning (sb, "vs-7000: search_by_entry_key: search_by_key returned item position == 0"); | 128 | reiserfs_warning(sb, |
130 | pathrelse(path) ; | 129 | "vs-7000: search_by_entry_key: search_by_key returned item position == 0"); |
131 | return IO_ERROR ; | 130 | pathrelse(path); |
131 | return IO_ERROR; | ||
132 | } | ||
133 | PATH_LAST_POSITION(path)--; | ||
134 | |||
135 | case ITEM_FOUND: | ||
136 | break; | ||
137 | |||
138 | case IO_ERROR: | ||
139 | return retval; | ||
140 | |||
141 | default: | ||
142 | pathrelse(path); | ||
143 | reiserfs_warning(sb, | ||
144 | "vs-7002: search_by_entry_key: no path to here"); | ||
145 | return IO_ERROR; | ||
132 | } | 146 | } |
133 | PATH_LAST_POSITION (path) --; | ||
134 | |||
135 | case ITEM_FOUND: | ||
136 | break; | ||
137 | |||
138 | case IO_ERROR: | ||
139 | return retval; | ||
140 | 147 | ||
141 | default: | 148 | set_de_item_location(de, path); |
142 | pathrelse (path); | ||
143 | reiserfs_warning (sb, "vs-7002: search_by_entry_key: no path to here"); | ||
144 | return IO_ERROR; | ||
145 | } | ||
146 | |||
147 | set_de_item_location (de, path); | ||
148 | 149 | ||
149 | #ifdef CONFIG_REISERFS_CHECK | 150 | #ifdef CONFIG_REISERFS_CHECK |
150 | if (!is_direntry_le_ih (de->de_ih) || | 151 | if (!is_direntry_le_ih(de->de_ih) || |
151 | COMP_SHORT_KEYS (&(de->de_ih->ih_key), key)) { | 152 | COMP_SHORT_KEYS(&(de->de_ih->ih_key), key)) { |
152 | print_block (de->de_bh, 0, -1, -1); | 153 | print_block(de->de_bh, 0, -1, -1); |
153 | reiserfs_panic (sb, "vs-7005: search_by_entry_key: found item %h is not directory item or " | 154 | reiserfs_panic(sb, |
154 | "does not belong to the same directory as key %K", de->de_ih, key); | 155 | "vs-7005: search_by_entry_key: found item %h is not directory item or " |
155 | } | 156 | "does not belong to the same directory as key %K", |
156 | #endif /* CONFIG_REISERFS_CHECK */ | 157 | de->de_ih, key); |
157 | 158 | } | |
158 | /* binary search in directory item by third componen t of the | 159 | #endif /* CONFIG_REISERFS_CHECK */ |
159 | key. sets de->de_entry_num of de */ | 160 | |
160 | retval = bin_search_in_dir_item (de, cpu_key_k_offset (key)); | 161 | /* binary search in directory item by third componen t of the |
161 | path->pos_in_item = de->de_entry_num; | 162 | key. sets de->de_entry_num of de */ |
162 | if (retval != NAME_NOT_FOUND) { | 163 | retval = bin_search_in_dir_item(de, cpu_key_k_offset(key)); |
163 | // ugly, but rename needs de_bh, de_deh, de_name, de_namelen, de_objectid set | 164 | path->pos_in_item = de->de_entry_num; |
164 | set_de_name_and_namelen (de); | 165 | if (retval != NAME_NOT_FOUND) { |
165 | set_de_object_key (de); | 166 | // ugly, but rename needs de_bh, de_deh, de_name, de_namelen, de_objectid set |
166 | } | 167 | set_de_name_and_namelen(de); |
167 | return retval; | 168 | set_de_object_key(de); |
169 | } | ||
170 | return retval; | ||
168 | } | 171 | } |
169 | 172 | ||
170 | |||
171 | |||
172 | /* Keyed 32-bit hash function using TEA in a Davis-Meyer function */ | 173 | /* Keyed 32-bit hash function using TEA in a Davis-Meyer function */ |
173 | 174 | ||
174 | /* The third component is hashed, and you can choose from more than | 175 | /* The third component is hashed, and you can choose from more than |
@@ -176,197 +177,210 @@ int search_by_entry_key (struct super_block * sb, const struct cpu_key * key, | |||
176 | but are thought about. This function should be moved to hashes.c | 177 | but are thought about. This function should be moved to hashes.c |
177 | Jedi, please do so. -Hans */ | 178 | Jedi, please do so. -Hans */ |
178 | 179 | ||
179 | static __u32 get_third_component (struct super_block * s, | 180 | static __u32 get_third_component(struct super_block *s, |
180 | const char * name, int len) | 181 | const char *name, int len) |
181 | { | 182 | { |
182 | __u32 res; | 183 | __u32 res; |
183 | 184 | ||
184 | if (!len || (len == 1 && name[0] == '.')) | 185 | if (!len || (len == 1 && name[0] == '.')) |
185 | return DOT_OFFSET; | 186 | return DOT_OFFSET; |
186 | if (len == 2 && name[0] == '.' && name[1] == '.') | 187 | if (len == 2 && name[0] == '.' && name[1] == '.') |
187 | return DOT_DOT_OFFSET; | 188 | return DOT_DOT_OFFSET; |
188 | 189 | ||
189 | res = REISERFS_SB(s)->s_hash_function (name, len); | 190 | res = REISERFS_SB(s)->s_hash_function(name, len); |
190 | 191 | ||
191 | // take bits from 7-th to 30-th including both bounds | 192 | // take bits from 7-th to 30-th including both bounds |
192 | res = GET_HASH_VALUE(res); | 193 | res = GET_HASH_VALUE(res); |
193 | if (res == 0) | 194 | if (res == 0) |
194 | // needed to have no names before "." and ".." those have hash | 195 | // needed to have no names before "." and ".." those have hash |
195 | // value == 0 and generation conters 1 and 2 accordingly | 196 | // value == 0 and generation conters 1 and 2 accordingly |
196 | res = 128; | 197 | res = 128; |
197 | return res + MAX_GENERATION_NUMBER; | 198 | return res + MAX_GENERATION_NUMBER; |
198 | } | 199 | } |
199 | 200 | ||
200 | 201 | static int reiserfs_match(struct reiserfs_dir_entry *de, | |
201 | static int reiserfs_match (struct reiserfs_dir_entry * de, | 202 | const char *name, int namelen) |
202 | const char * name, int namelen) | ||
203 | { | 203 | { |
204 | int retval = NAME_NOT_FOUND; | 204 | int retval = NAME_NOT_FOUND; |
205 | 205 | ||
206 | if ((namelen == de->de_namelen) && | 206 | if ((namelen == de->de_namelen) && |
207 | !memcmp(de->de_name, name, de->de_namelen)) | 207 | !memcmp(de->de_name, name, de->de_namelen)) |
208 | retval = (de_visible (de->de_deh + de->de_entry_num) ? NAME_FOUND : NAME_FOUND_INVISIBLE); | 208 | retval = |
209 | (de_visible(de->de_deh + de->de_entry_num) ? NAME_FOUND : | ||
210 | NAME_FOUND_INVISIBLE); | ||
209 | 211 | ||
210 | return retval; | 212 | return retval; |
211 | } | 213 | } |
212 | 214 | ||
213 | |||
214 | /* de's de_bh, de_ih, de_deh, de_item_num, de_entry_num are set already */ | 215 | /* de's de_bh, de_ih, de_deh, de_item_num, de_entry_num are set already */ |
215 | 216 | ||
216 | /* used when hash collisions exist */ | 217 | /* used when hash collisions exist */ |
217 | 218 | ||
218 | 219 | static int linear_search_in_dir_item(struct cpu_key *key, | |
219 | static int linear_search_in_dir_item (struct cpu_key * key, struct reiserfs_dir_entry * de, | 220 | struct reiserfs_dir_entry *de, |
220 | const char * name, int namelen) | 221 | const char *name, int namelen) |
221 | { | 222 | { |
222 | struct reiserfs_de_head * deh = de->de_deh; | 223 | struct reiserfs_de_head *deh = de->de_deh; |
223 | int retval; | 224 | int retval; |
224 | int i; | 225 | int i; |
225 | 226 | ||
226 | i = de->de_entry_num; | 227 | i = de->de_entry_num; |
227 | 228 | ||
228 | if (i == I_ENTRY_COUNT (de->de_ih) || | 229 | if (i == I_ENTRY_COUNT(de->de_ih) || |
229 | GET_HASH_VALUE (deh_offset (deh + i)) != GET_HASH_VALUE (cpu_key_k_offset (key))) { | 230 | GET_HASH_VALUE(deh_offset(deh + i)) != |
230 | i --; | 231 | GET_HASH_VALUE(cpu_key_k_offset(key))) { |
231 | } | 232 | i--; |
233 | } | ||
232 | 234 | ||
233 | RFALSE( de->de_deh != B_I_DEH (de->de_bh, de->de_ih), | 235 | RFALSE(de->de_deh != B_I_DEH(de->de_bh, de->de_ih), |
234 | "vs-7010: array of entry headers not found"); | 236 | "vs-7010: array of entry headers not found"); |
235 | 237 | ||
236 | deh += i; | 238 | deh += i; |
237 | 239 | ||
238 | for (; i >= 0; i --, deh --) { | 240 | for (; i >= 0; i--, deh--) { |
239 | if (GET_HASH_VALUE (deh_offset (deh)) != | 241 | if (GET_HASH_VALUE(deh_offset(deh)) != |
240 | GET_HASH_VALUE (cpu_key_k_offset (key))) { | 242 | GET_HASH_VALUE(cpu_key_k_offset(key))) { |
241 | // hash value does not match, no need to check whole name | 243 | // hash value does not match, no need to check whole name |
242 | return NAME_NOT_FOUND; | 244 | return NAME_NOT_FOUND; |
243 | } | 245 | } |
244 | 246 | ||
245 | /* mark, that this generation number is used */ | 247 | /* mark, that this generation number is used */ |
246 | if (de->de_gen_number_bit_string) | 248 | if (de->de_gen_number_bit_string) |
247 | set_bit (GET_GENERATION_NUMBER (deh_offset (deh)), (unsigned long *)de->de_gen_number_bit_string); | 249 | set_bit(GET_GENERATION_NUMBER(deh_offset(deh)), |
250 | (unsigned long *)de->de_gen_number_bit_string); | ||
248 | 251 | ||
249 | // calculate pointer to name and namelen | 252 | // calculate pointer to name and namelen |
250 | de->de_entry_num = i; | 253 | de->de_entry_num = i; |
251 | set_de_name_and_namelen (de); | 254 | set_de_name_and_namelen(de); |
252 | 255 | ||
253 | if ((retval = reiserfs_match (de, name, namelen)) != NAME_NOT_FOUND) { | 256 | if ((retval = |
254 | // de's de_name, de_namelen, de_recordlen are set. Fill the rest: | 257 | reiserfs_match(de, name, namelen)) != NAME_NOT_FOUND) { |
258 | // de's de_name, de_namelen, de_recordlen are set. Fill the rest: | ||
255 | 259 | ||
256 | // key of pointed object | 260 | // key of pointed object |
257 | set_de_object_key (de); | 261 | set_de_object_key(de); |
258 | 262 | ||
259 | store_de_entry_key (de); | 263 | store_de_entry_key(de); |
260 | 264 | ||
261 | // retval can be NAME_FOUND or NAME_FOUND_INVISIBLE | 265 | // retval can be NAME_FOUND or NAME_FOUND_INVISIBLE |
262 | return retval; | 266 | return retval; |
267 | } | ||
263 | } | 268 | } |
264 | } | ||
265 | |||
266 | if (GET_GENERATION_NUMBER (le_ih_k_offset (de->de_ih)) == 0) | ||
267 | /* we have reached left most entry in the node. In common we | ||
268 | have to go to the left neighbor, but if generation counter | ||
269 | is 0 already, we know for sure, that there is no name with | ||
270 | the same hash value */ | ||
271 | // FIXME: this work correctly only because hash value can not | ||
272 | // be 0. Btw, in case of Yura's hash it is probably possible, | ||
273 | // so, this is a bug | ||
274 | return NAME_NOT_FOUND; | ||
275 | 269 | ||
276 | RFALSE( de->de_item_num, | 270 | if (GET_GENERATION_NUMBER(le_ih_k_offset(de->de_ih)) == 0) |
277 | "vs-7015: two diritems of the same directory in one node?"); | 271 | /* we have reached left most entry in the node. In common we |
272 | have to go to the left neighbor, but if generation counter | ||
273 | is 0 already, we know for sure, that there is no name with | ||
274 | the same hash value */ | ||
275 | // FIXME: this work correctly only because hash value can not | ||
276 | // be 0. Btw, in case of Yura's hash it is probably possible, | ||
277 | // so, this is a bug | ||
278 | return NAME_NOT_FOUND; | ||
278 | 279 | ||
279 | return GOTO_PREVIOUS_ITEM; | 280 | RFALSE(de->de_item_num, |
280 | } | 281 | "vs-7015: two diritems of the same directory in one node?"); |
281 | 282 | ||
283 | return GOTO_PREVIOUS_ITEM; | ||
284 | } | ||
282 | 285 | ||
283 | // may return NAME_FOUND, NAME_FOUND_INVISIBLE, NAME_NOT_FOUND | 286 | // may return NAME_FOUND, NAME_FOUND_INVISIBLE, NAME_NOT_FOUND |
284 | // FIXME: should add something like IOERROR | 287 | // FIXME: should add something like IOERROR |
285 | static int reiserfs_find_entry (struct inode * dir, const char * name, int namelen, | 288 | static int reiserfs_find_entry(struct inode *dir, const char *name, int namelen, |
286 | struct path * path_to_entry, struct reiserfs_dir_entry * de) | 289 | struct path *path_to_entry, |
290 | struct reiserfs_dir_entry *de) | ||
287 | { | 291 | { |
288 | struct cpu_key key_to_search; | 292 | struct cpu_key key_to_search; |
289 | int retval; | 293 | int retval; |
290 | 294 | ||
291 | 295 | if (namelen > REISERFS_MAX_NAME(dir->i_sb->s_blocksize)) | |
292 | if (namelen > REISERFS_MAX_NAME (dir->i_sb->s_blocksize)) | 296 | return NAME_NOT_FOUND; |
293 | return NAME_NOT_FOUND; | 297 | |
294 | 298 | /* we will search for this key in the tree */ | |
295 | /* we will search for this key in the tree */ | 299 | make_cpu_key(&key_to_search, dir, |
296 | make_cpu_key (&key_to_search, dir, | 300 | get_third_component(dir->i_sb, name, namelen), |
297 | get_third_component (dir->i_sb, name, namelen), TYPE_DIRENTRY, 3); | 301 | TYPE_DIRENTRY, 3); |
298 | 302 | ||
299 | while (1) { | 303 | while (1) { |
300 | retval = search_by_entry_key (dir->i_sb, &key_to_search, path_to_entry, de); | 304 | retval = |
301 | if (retval == IO_ERROR) { | 305 | search_by_entry_key(dir->i_sb, &key_to_search, |
302 | reiserfs_warning (dir->i_sb, "zam-7001: io error in %s", | 306 | path_to_entry, de); |
303 | __FUNCTION__); | 307 | if (retval == IO_ERROR) { |
304 | return IO_ERROR; | 308 | reiserfs_warning(dir->i_sb, "zam-7001: io error in %s", |
305 | } | 309 | __FUNCTION__); |
306 | 310 | return IO_ERROR; | |
307 | /* compare names for all entries having given hash value */ | 311 | } |
308 | retval = linear_search_in_dir_item (&key_to_search, de, name, namelen); | 312 | |
309 | if (retval != GOTO_PREVIOUS_ITEM) { | 313 | /* compare names for all entries having given hash value */ |
310 | /* there is no need to scan directory anymore. Given entry found or does not exist */ | 314 | retval = |
311 | path_to_entry->pos_in_item = de->de_entry_num; | 315 | linear_search_in_dir_item(&key_to_search, de, name, |
312 | return retval; | 316 | namelen); |
313 | } | 317 | if (retval != GOTO_PREVIOUS_ITEM) { |
314 | 318 | /* there is no need to scan directory anymore. Given entry found or does not exist */ | |
315 | /* there is left neighboring item of this directory and given entry can be there */ | 319 | path_to_entry->pos_in_item = de->de_entry_num; |
316 | set_cpu_key_k_offset (&key_to_search, le_ih_k_offset (de->de_ih) - 1); | 320 | return retval; |
317 | pathrelse (path_to_entry); | 321 | } |
318 | 322 | ||
319 | } /* while (1) */ | 323 | /* there is left neighboring item of this directory and given entry can be there */ |
324 | set_cpu_key_k_offset(&key_to_search, | ||
325 | le_ih_k_offset(de->de_ih) - 1); | ||
326 | pathrelse(path_to_entry); | ||
327 | |||
328 | } /* while (1) */ | ||
320 | } | 329 | } |
321 | 330 | ||
322 | 331 | static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry, | |
323 | static struct dentry * reiserfs_lookup (struct inode * dir, struct dentry * dentry, struct nameidata *nd) | 332 | struct nameidata *nd) |
324 | { | 333 | { |
325 | int retval; | 334 | int retval; |
326 | struct inode * inode = NULL; | 335 | struct inode *inode = NULL; |
327 | struct reiserfs_dir_entry de; | 336 | struct reiserfs_dir_entry de; |
328 | INITIALIZE_PATH (path_to_entry); | 337 | INITIALIZE_PATH(path_to_entry); |
329 | 338 | ||
330 | if (REISERFS_MAX_NAME (dir->i_sb->s_blocksize) < dentry->d_name.len) | 339 | if (REISERFS_MAX_NAME(dir->i_sb->s_blocksize) < dentry->d_name.len) |
331 | return ERR_PTR(-ENAMETOOLONG); | 340 | return ERR_PTR(-ENAMETOOLONG); |
332 | 341 | ||
333 | reiserfs_write_lock(dir->i_sb); | 342 | reiserfs_write_lock(dir->i_sb); |
334 | de.de_gen_number_bit_string = NULL; | 343 | de.de_gen_number_bit_string = NULL; |
335 | retval = reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path_to_entry, &de); | 344 | retval = |
336 | pathrelse (&path_to_entry); | 345 | reiserfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, |
337 | if (retval == NAME_FOUND) { | 346 | &path_to_entry, &de); |
338 | /* Hide the .reiserfs_priv directory */ | 347 | pathrelse(&path_to_entry); |
339 | if (reiserfs_xattrs (dir->i_sb) && | 348 | if (retval == NAME_FOUND) { |
340 | !old_format_only(dir->i_sb) && | 349 | /* Hide the .reiserfs_priv directory */ |
341 | REISERFS_SB(dir->i_sb)->priv_root && | 350 | if (reiserfs_xattrs(dir->i_sb) && |
342 | REISERFS_SB(dir->i_sb)->priv_root->d_inode && | 351 | !old_format_only(dir->i_sb) && |
343 | de.de_objectid == le32_to_cpu (INODE_PKEY(REISERFS_SB(dir->i_sb)->priv_root->d_inode)->k_objectid)) { | 352 | REISERFS_SB(dir->i_sb)->priv_root && |
344 | reiserfs_write_unlock (dir->i_sb); | 353 | REISERFS_SB(dir->i_sb)->priv_root->d_inode && |
345 | return ERR_PTR (-EACCES); | 354 | de.de_objectid == |
355 | le32_to_cpu(INODE_PKEY | ||
356 | (REISERFS_SB(dir->i_sb)->priv_root->d_inode)-> | ||
357 | k_objectid)) { | ||
358 | reiserfs_write_unlock(dir->i_sb); | ||
359 | return ERR_PTR(-EACCES); | ||
360 | } | ||
361 | |||
362 | inode = | ||
363 | reiserfs_iget(dir->i_sb, (struct cpu_key *)&(de.de_dir_id)); | ||
364 | if (!inode || IS_ERR(inode)) { | ||
365 | reiserfs_write_unlock(dir->i_sb); | ||
366 | return ERR_PTR(-EACCES); | ||
367 | } | ||
368 | |||
369 | /* Propogate the priv_object flag so we know we're in the priv tree */ | ||
370 | if (is_reiserfs_priv_object(dir)) | ||
371 | reiserfs_mark_inode_private(inode); | ||
372 | } | ||
373 | reiserfs_write_unlock(dir->i_sb); | ||
374 | if (retval == IO_ERROR) { | ||
375 | return ERR_PTR(-EIO); | ||
346 | } | 376 | } |
347 | 377 | ||
348 | inode = reiserfs_iget (dir->i_sb, (struct cpu_key *)&(de.de_dir_id)); | 378 | if (inode) |
349 | if (!inode || IS_ERR(inode)) { | 379 | return d_splice_alias(inode, dentry); |
350 | reiserfs_write_unlock(dir->i_sb); | ||
351 | return ERR_PTR(-EACCES); | ||
352 | } | ||
353 | |||
354 | /* Propogate the priv_object flag so we know we're in the priv tree */ | ||
355 | if (is_reiserfs_priv_object (dir)) | ||
356 | reiserfs_mark_inode_private (inode); | ||
357 | } | ||
358 | reiserfs_write_unlock(dir->i_sb); | ||
359 | if ( retval == IO_ERROR ) { | ||
360 | return ERR_PTR(-EIO); | ||
361 | } | ||
362 | |||
363 | if (inode) | ||
364 | return d_splice_alias(inode, dentry); | ||
365 | |||
366 | d_add(dentry, inode); | ||
367 | return NULL; | ||
368 | } | ||
369 | 380 | ||
381 | d_add(dentry, inode); | ||
382 | return NULL; | ||
383 | } | ||
370 | 384 | ||
371 | /* | 385 | /* |
372 | ** looks up the dentry of the parent directory for child. | 386 | ** looks up the dentry of the parent directory for child. |
@@ -374,40 +388,38 @@ static struct dentry * reiserfs_lookup (struct inode * dir, struct dentry * dent | |||
374 | */ | 388 | */ |
375 | struct dentry *reiserfs_get_parent(struct dentry *child) | 389 | struct dentry *reiserfs_get_parent(struct dentry *child) |
376 | { | 390 | { |
377 | int retval; | 391 | int retval; |
378 | struct inode * inode = NULL; | 392 | struct inode *inode = NULL; |
379 | struct reiserfs_dir_entry de; | 393 | struct reiserfs_dir_entry de; |
380 | INITIALIZE_PATH (path_to_entry); | 394 | INITIALIZE_PATH(path_to_entry); |
381 | struct dentry *parent; | 395 | struct dentry *parent; |
382 | struct inode *dir = child->d_inode ; | 396 | struct inode *dir = child->d_inode; |
383 | 397 | ||
384 | 398 | if (dir->i_nlink == 0) { | |
385 | if (dir->i_nlink == 0) { | 399 | return ERR_PTR(-ENOENT); |
386 | return ERR_PTR(-ENOENT); | 400 | } |
387 | } | 401 | de.de_gen_number_bit_string = NULL; |
388 | de.de_gen_number_bit_string = NULL; | 402 | |
389 | 403 | reiserfs_write_lock(dir->i_sb); | |
390 | reiserfs_write_lock(dir->i_sb); | 404 | retval = reiserfs_find_entry(dir, "..", 2, &path_to_entry, &de); |
391 | retval = reiserfs_find_entry (dir, "..", 2, &path_to_entry, &de); | 405 | pathrelse(&path_to_entry); |
392 | pathrelse (&path_to_entry); | 406 | if (retval != NAME_FOUND) { |
393 | if (retval != NAME_FOUND) { | 407 | reiserfs_write_unlock(dir->i_sb); |
408 | return ERR_PTR(-ENOENT); | ||
409 | } | ||
410 | inode = reiserfs_iget(dir->i_sb, (struct cpu_key *)&(de.de_dir_id)); | ||
394 | reiserfs_write_unlock(dir->i_sb); | 411 | reiserfs_write_unlock(dir->i_sb); |
395 | return ERR_PTR(-ENOENT); | ||
396 | } | ||
397 | inode = reiserfs_iget (dir->i_sb, (struct cpu_key *)&(de.de_dir_id)); | ||
398 | reiserfs_write_unlock(dir->i_sb); | ||
399 | |||
400 | if (!inode || IS_ERR(inode)) { | ||
401 | return ERR_PTR(-EACCES); | ||
402 | } | ||
403 | parent = d_alloc_anon(inode); | ||
404 | if (!parent) { | ||
405 | iput(inode); | ||
406 | parent = ERR_PTR(-ENOMEM); | ||
407 | } | ||
408 | return parent; | ||
409 | } | ||
410 | 412 | ||
413 | if (!inode || IS_ERR(inode)) { | ||
414 | return ERR_PTR(-EACCES); | ||
415 | } | ||
416 | parent = d_alloc_anon(inode); | ||
417 | if (!parent) { | ||
418 | iput(inode); | ||
419 | parent = ERR_PTR(-ENOMEM); | ||
420 | } | ||
421 | return parent; | ||
422 | } | ||
411 | 423 | ||
412 | /* add entry to the directory (entry can be hidden). | 424 | /* add entry to the directory (entry can be hidden). |
413 | 425 | ||
@@ -415,132 +427,143 @@ insert definition of when hidden directories are used here -Hans | |||
415 | 427 | ||
416 | Does not mark dir inode dirty, do it after successesfull call to it */ | 428 | Does not mark dir inode dirty, do it after successesfull call to it */ |
417 | 429 | ||
418 | static int reiserfs_add_entry (struct reiserfs_transaction_handle *th, struct inode * dir, | 430 | static int reiserfs_add_entry(struct reiserfs_transaction_handle *th, |
419 | const char * name, int namelen, struct inode * inode, | 431 | struct inode *dir, const char *name, int namelen, |
420 | int visible) | 432 | struct inode *inode, int visible) |
421 | { | 433 | { |
422 | struct cpu_key entry_key; | 434 | struct cpu_key entry_key; |
423 | struct reiserfs_de_head * deh; | 435 | struct reiserfs_de_head *deh; |
424 | INITIALIZE_PATH (path); | 436 | INITIALIZE_PATH(path); |
425 | struct reiserfs_dir_entry de; | 437 | struct reiserfs_dir_entry de; |
426 | int bit_string [MAX_GENERATION_NUMBER / (sizeof(int) * 8) + 1]; | 438 | int bit_string[MAX_GENERATION_NUMBER / (sizeof(int) * 8) + 1]; |
427 | int gen_number; | 439 | int gen_number; |
428 | char small_buf[32+DEH_SIZE] ; /* 48 bytes now and we avoid kmalloc | 440 | char small_buf[32 + DEH_SIZE]; /* 48 bytes now and we avoid kmalloc |
429 | if we create file with short name */ | 441 | if we create file with short name */ |
430 | char * buffer; | 442 | char *buffer; |
431 | int buflen, paste_size; | 443 | int buflen, paste_size; |
432 | int retval; | 444 | int retval; |
433 | 445 | ||
434 | BUG_ON (!th->t_trans_id); | 446 | BUG_ON(!th->t_trans_id); |
435 | 447 | ||
436 | /* cannot allow items to be added into a busy deleted directory */ | 448 | /* cannot allow items to be added into a busy deleted directory */ |
437 | if (!namelen) | 449 | if (!namelen) |
438 | return -EINVAL; | 450 | return -EINVAL; |
439 | 451 | ||
440 | if (namelen > REISERFS_MAX_NAME (dir->i_sb->s_blocksize)) | 452 | if (namelen > REISERFS_MAX_NAME(dir->i_sb->s_blocksize)) |
441 | return -ENAMETOOLONG; | 453 | return -ENAMETOOLONG; |
442 | 454 | ||
443 | /* each entry has unique key. compose it */ | 455 | /* each entry has unique key. compose it */ |
444 | make_cpu_key (&entry_key, dir, | 456 | make_cpu_key(&entry_key, dir, |
445 | get_third_component (dir->i_sb, name, namelen), TYPE_DIRENTRY, 3); | 457 | get_third_component(dir->i_sb, name, namelen), |
446 | 458 | TYPE_DIRENTRY, 3); | |
447 | /* get memory for composing the entry */ | 459 | |
448 | buflen = DEH_SIZE + ROUND_UP (namelen); | 460 | /* get memory for composing the entry */ |
449 | if (buflen > sizeof (small_buf)) { | 461 | buflen = DEH_SIZE + ROUND_UP(namelen); |
450 | buffer = reiserfs_kmalloc (buflen, GFP_NOFS, dir->i_sb); | 462 | if (buflen > sizeof(small_buf)) { |
451 | if (buffer == 0) | 463 | buffer = reiserfs_kmalloc(buflen, GFP_NOFS, dir->i_sb); |
452 | return -ENOMEM; | 464 | if (buffer == 0) |
453 | } else | 465 | return -ENOMEM; |
454 | buffer = small_buf; | 466 | } else |
455 | 467 | buffer = small_buf; | |
456 | paste_size = (get_inode_sd_version (dir) == STAT_DATA_V1) ? (DEH_SIZE + namelen) : buflen; | 468 | |
457 | 469 | paste_size = | |
458 | /* fill buffer : directory entry head, name[, dir objectid | , stat data | ,stat data, dir objectid ] */ | 470 | (get_inode_sd_version(dir) == |
459 | deh = (struct reiserfs_de_head *)buffer; | 471 | STAT_DATA_V1) ? (DEH_SIZE + namelen) : buflen; |
460 | deh->deh_location = 0; /* JDM Endian safe if 0 */ | 472 | |
461 | put_deh_offset( deh, cpu_key_k_offset( &entry_key ) ); | 473 | /* fill buffer : directory entry head, name[, dir objectid | , stat data | ,stat data, dir objectid ] */ |
462 | deh->deh_state = 0; /* JDM Endian safe if 0 */ | 474 | deh = (struct reiserfs_de_head *)buffer; |
463 | /* put key (ino analog) to de */ | 475 | deh->deh_location = 0; /* JDM Endian safe if 0 */ |
464 | deh->deh_dir_id = INODE_PKEY (inode)->k_dir_id; /* safe: k_dir_id is le */ | 476 | put_deh_offset(deh, cpu_key_k_offset(&entry_key)); |
465 | deh->deh_objectid = INODE_PKEY (inode)->k_objectid; /* safe: k_objectid is le */ | 477 | deh->deh_state = 0; /* JDM Endian safe if 0 */ |
466 | 478 | /* put key (ino analog) to de */ | |
467 | /* copy name */ | 479 | deh->deh_dir_id = INODE_PKEY(inode)->k_dir_id; /* safe: k_dir_id is le */ |
468 | memcpy ((char *)(deh + 1), name, namelen); | 480 | deh->deh_objectid = INODE_PKEY(inode)->k_objectid; /* safe: k_objectid is le */ |
469 | /* padd by 0s to the 4 byte boundary */ | 481 | |
470 | padd_item ((char *)(deh + 1), ROUND_UP (namelen), namelen); | 482 | /* copy name */ |
471 | 483 | memcpy((char *)(deh + 1), name, namelen); | |
472 | /* entry is ready to be pasted into tree, set 'visibility' and 'stat data in entry' attributes */ | 484 | /* padd by 0s to the 4 byte boundary */ |
473 | mark_de_without_sd (deh); | 485 | padd_item((char *)(deh + 1), ROUND_UP(namelen), namelen); |
474 | visible ? mark_de_visible (deh) : mark_de_hidden (deh); | 486 | |
475 | 487 | /* entry is ready to be pasted into tree, set 'visibility' and 'stat data in entry' attributes */ | |
476 | /* find the proper place for the new entry */ | 488 | mark_de_without_sd(deh); |
477 | memset (bit_string, 0, sizeof (bit_string)); | 489 | visible ? mark_de_visible(deh) : mark_de_hidden(deh); |
478 | de.de_gen_number_bit_string = (char *)bit_string; | 490 | |
479 | retval = reiserfs_find_entry (dir, name, namelen, &path, &de); | 491 | /* find the proper place for the new entry */ |
480 | if( retval != NAME_NOT_FOUND ) { | 492 | memset(bit_string, 0, sizeof(bit_string)); |
481 | if (buffer != small_buf) | 493 | de.de_gen_number_bit_string = (char *)bit_string; |
482 | reiserfs_kfree (buffer, buflen, dir->i_sb); | 494 | retval = reiserfs_find_entry(dir, name, namelen, &path, &de); |
483 | pathrelse (&path); | 495 | if (retval != NAME_NOT_FOUND) { |
496 | if (buffer != small_buf) | ||
497 | reiserfs_kfree(buffer, buflen, dir->i_sb); | ||
498 | pathrelse(&path); | ||
499 | |||
500 | if (retval == IO_ERROR) { | ||
501 | return -EIO; | ||
502 | } | ||
503 | |||
504 | if (retval != NAME_FOUND) { | ||
505 | reiserfs_warning(dir->i_sb, | ||
506 | "zam-7002:%s: \"reiserfs_find_entry\" " | ||
507 | "has returned unexpected value (%d)", | ||
508 | __FUNCTION__, retval); | ||
509 | } | ||
510 | |||
511 | return -EEXIST; | ||
512 | } | ||
484 | 513 | ||
485 | if ( retval == IO_ERROR ) { | 514 | gen_number = |
486 | return -EIO; | 515 | find_first_zero_bit((unsigned long *)bit_string, |
516 | MAX_GENERATION_NUMBER + 1); | ||
517 | if (gen_number > MAX_GENERATION_NUMBER) { | ||
518 | /* there is no free generation number */ | ||
519 | reiserfs_warning(dir->i_sb, | ||
520 | "reiserfs_add_entry: Congratulations! we have got hash function screwed up"); | ||
521 | if (buffer != small_buf) | ||
522 | reiserfs_kfree(buffer, buflen, dir->i_sb); | ||
523 | pathrelse(&path); | ||
524 | return -EBUSY; | ||
525 | } | ||
526 | /* adjust offset of directory enrty */ | ||
527 | put_deh_offset(deh, SET_GENERATION_NUMBER(deh_offset(deh), gen_number)); | ||
528 | set_cpu_key_k_offset(&entry_key, deh_offset(deh)); | ||
529 | |||
530 | /* update max-hash-collisions counter in reiserfs_sb_info */ | ||
531 | PROC_INFO_MAX(th->t_super, max_hash_collisions, gen_number); | ||
532 | |||
533 | if (gen_number != 0) { /* we need to re-search for the insertion point */ | ||
534 | if (search_by_entry_key(dir->i_sb, &entry_key, &path, &de) != | ||
535 | NAME_NOT_FOUND) { | ||
536 | reiserfs_warning(dir->i_sb, | ||
537 | "vs-7032: reiserfs_add_entry: " | ||
538 | "entry with this key (%K) already exists", | ||
539 | &entry_key); | ||
540 | |||
541 | if (buffer != small_buf) | ||
542 | reiserfs_kfree(buffer, buflen, dir->i_sb); | ||
543 | pathrelse(&path); | ||
544 | return -EBUSY; | ||
545 | } | ||
487 | } | 546 | } |
488 | 547 | ||
489 | if (retval != NAME_FOUND) { | 548 | /* perform the insertion of the entry that we have prepared */ |
490 | reiserfs_warning (dir->i_sb, "zam-7002:%s: \"reiserfs_find_entry\" " | 549 | retval = |
491 | "has returned unexpected value (%d)", | 550 | reiserfs_paste_into_item(th, &path, &entry_key, dir, buffer, |
492 | __FUNCTION__, retval); | 551 | paste_size); |
493 | } | 552 | if (buffer != small_buf) |
494 | 553 | reiserfs_kfree(buffer, buflen, dir->i_sb); | |
495 | return -EEXIST; | 554 | if (retval) { |
496 | } | 555 | reiserfs_check_path(&path); |
497 | 556 | return retval; | |
498 | gen_number = find_first_zero_bit ((unsigned long *)bit_string, MAX_GENERATION_NUMBER + 1); | ||
499 | if (gen_number > MAX_GENERATION_NUMBER) { | ||
500 | /* there is no free generation number */ | ||
501 | reiserfs_warning (dir->i_sb, "reiserfs_add_entry: Congratulations! we have got hash function screwed up"); | ||
502 | if (buffer != small_buf) | ||
503 | reiserfs_kfree (buffer, buflen, dir->i_sb); | ||
504 | pathrelse (&path); | ||
505 | return -EBUSY; | ||
506 | } | ||
507 | /* adjust offset of directory enrty */ | ||
508 | put_deh_offset(deh, SET_GENERATION_NUMBER(deh_offset(deh), gen_number)); | ||
509 | set_cpu_key_k_offset (&entry_key, deh_offset(deh)); | ||
510 | |||
511 | /* update max-hash-collisions counter in reiserfs_sb_info */ | ||
512 | PROC_INFO_MAX( th -> t_super, max_hash_collisions, gen_number ); | ||
513 | |||
514 | if (gen_number != 0) { /* we need to re-search for the insertion point */ | ||
515 | if (search_by_entry_key (dir->i_sb, &entry_key, &path, &de) != NAME_NOT_FOUND) { | ||
516 | reiserfs_warning (dir->i_sb, "vs-7032: reiserfs_add_entry: " | ||
517 | "entry with this key (%K) already exists", | ||
518 | &entry_key); | ||
519 | |||
520 | if (buffer != small_buf) | ||
521 | reiserfs_kfree (buffer, buflen, dir->i_sb); | ||
522 | pathrelse (&path); | ||
523 | return -EBUSY; | ||
524 | } | 557 | } |
525 | } | ||
526 | |||
527 | /* perform the insertion of the entry that we have prepared */ | ||
528 | retval = reiserfs_paste_into_item (th, &path, &entry_key, dir, buffer, paste_size); | ||
529 | if (buffer != small_buf) | ||
530 | reiserfs_kfree (buffer, buflen, dir->i_sb); | ||
531 | if (retval) { | ||
532 | reiserfs_check_path(&path) ; | ||
533 | return retval; | ||
534 | } | ||
535 | 558 | ||
536 | dir->i_size += paste_size; | 559 | dir->i_size += paste_size; |
537 | dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; | 560 | dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; |
538 | if (!S_ISDIR (inode->i_mode) && visible) | 561 | if (!S_ISDIR(inode->i_mode) && visible) |
539 | // reiserfs_mkdir or reiserfs_rename will do that by itself | 562 | // reiserfs_mkdir or reiserfs_rename will do that by itself |
540 | reiserfs_update_sd (th, dir); | 563 | reiserfs_update_sd(th, dir); |
541 | 564 | ||
542 | reiserfs_check_path(&path) ; | 565 | reiserfs_check_path(&path); |
543 | return 0; | 566 | return 0; |
544 | } | 567 | } |
545 | 568 | ||
546 | /* quota utility function, call if you've had to abort after calling | 569 | /* quota utility function, call if you've had to abort after calling |
@@ -548,12 +571,13 @@ static int reiserfs_add_entry (struct reiserfs_transaction_handle *th, struct in | |||
548 | ** This should only be called on inodes that do not have stat data | 571 | ** This should only be called on inodes that do not have stat data |
549 | ** inserted into the tree yet. | 572 | ** inserted into the tree yet. |
550 | */ | 573 | */ |
551 | static int drop_new_inode(struct inode *inode) { | 574 | static int drop_new_inode(struct inode *inode) |
552 | DQUOT_DROP(inode); | 575 | { |
553 | make_bad_inode(inode) ; | 576 | DQUOT_DROP(inode); |
554 | inode->i_flags |= S_NOQUOTA; | 577 | make_bad_inode(inode); |
555 | iput(inode) ; | 578 | inode->i_flags |= S_NOQUOTA; |
556 | return 0 ; | 579 | iput(inode); |
580 | return 0; | ||
557 | } | 581 | } |
558 | 582 | ||
559 | /* utility function that does setup for reiserfs_new_inode. | 583 | /* utility function that does setup for reiserfs_new_inode. |
@@ -561,905 +585,968 @@ static int drop_new_inode(struct inode *inode) { | |||
561 | ** outside of a transaction, so we had to pull some bits of | 585 | ** outside of a transaction, so we had to pull some bits of |
562 | ** reiserfs_new_inode out into this func. | 586 | ** reiserfs_new_inode out into this func. |
563 | */ | 587 | */ |
564 | static int new_inode_init(struct inode *inode, struct inode *dir, int mode) { | 588 | static int new_inode_init(struct inode *inode, struct inode *dir, int mode) |
565 | 589 | { | |
566 | /* the quota init calls have to know who to charge the quota to, so | 590 | |
567 | ** we have to set uid and gid here | 591 | /* the quota init calls have to know who to charge the quota to, so |
568 | */ | 592 | ** we have to set uid and gid here |
569 | inode->i_uid = current->fsuid; | 593 | */ |
570 | inode->i_mode = mode; | 594 | inode->i_uid = current->fsuid; |
571 | 595 | inode->i_mode = mode; | |
572 | if (dir->i_mode & S_ISGID) { | 596 | |
573 | inode->i_gid = dir->i_gid; | 597 | if (dir->i_mode & S_ISGID) { |
574 | if (S_ISDIR(mode)) | 598 | inode->i_gid = dir->i_gid; |
575 | inode->i_mode |= S_ISGID; | 599 | if (S_ISDIR(mode)) |
576 | } else { | 600 | inode->i_mode |= S_ISGID; |
577 | inode->i_gid = current->fsgid; | 601 | } else { |
578 | } | 602 | inode->i_gid = current->fsgid; |
579 | DQUOT_INIT(inode); | 603 | } |
580 | return 0 ; | 604 | DQUOT_INIT(inode); |
605 | return 0; | ||
581 | } | 606 | } |
582 | 607 | ||
583 | static int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode, | 608 | static int reiserfs_create(struct inode *dir, struct dentry *dentry, int mode, |
584 | struct nameidata *nd) | 609 | struct nameidata *nd) |
585 | { | 610 | { |
586 | int retval; | 611 | int retval; |
587 | struct inode * inode; | 612 | struct inode *inode; |
588 | /* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */ | 613 | /* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */ |
589 | int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb)+REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb)); | 614 | int jbegin_count = |
590 | struct reiserfs_transaction_handle th ; | 615 | JOURNAL_PER_BALANCE_CNT * 2 + |
591 | int locked; | 616 | 2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) + |
592 | 617 | REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb)); | |
593 | if (!(inode = new_inode(dir->i_sb))) { | 618 | struct reiserfs_transaction_handle th; |
594 | return -ENOMEM ; | 619 | int locked; |
595 | } | 620 | |
596 | new_inode_init(inode, dir, mode); | 621 | if (!(inode = new_inode(dir->i_sb))) { |
597 | 622 | return -ENOMEM; | |
598 | locked = reiserfs_cache_default_acl (dir); | 623 | } |
599 | 624 | new_inode_init(inode, dir, mode); | |
600 | reiserfs_write_lock(dir->i_sb); | ||
601 | |||
602 | if (locked) | ||
603 | reiserfs_write_lock_xattrs (dir->i_sb); | ||
604 | |||
605 | retval = journal_begin(&th, dir->i_sb, jbegin_count); | ||
606 | if (retval) { | ||
607 | drop_new_inode (inode); | ||
608 | goto out_failed; | ||
609 | } | ||
610 | |||
611 | retval = reiserfs_new_inode (&th, dir, mode, NULL, 0/*i_size*/, dentry, inode); | ||
612 | if (retval) | ||
613 | goto out_failed; | ||
614 | |||
615 | if (locked) { | ||
616 | reiserfs_write_unlock_xattrs (dir->i_sb); | ||
617 | locked = 0; | ||
618 | } | ||
619 | |||
620 | inode->i_op = &reiserfs_file_inode_operations; | ||
621 | inode->i_fop = &reiserfs_file_operations; | ||
622 | inode->i_mapping->a_ops = &reiserfs_address_space_operations ; | ||
623 | |||
624 | retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len, | ||
625 | inode, 1/*visible*/); | ||
626 | if (retval) { | ||
627 | int err; | ||
628 | inode->i_nlink--; | ||
629 | reiserfs_update_sd (&th, inode); | ||
630 | err = journal_end(&th, dir->i_sb, jbegin_count) ; | ||
631 | if (err) | ||
632 | retval = err; | ||
633 | iput (inode); | ||
634 | goto out_failed; | ||
635 | } | ||
636 | reiserfs_update_inode_transaction(inode) ; | ||
637 | reiserfs_update_inode_transaction(dir) ; | ||
638 | |||
639 | d_instantiate(dentry, inode); | ||
640 | retval = journal_end(&th, dir->i_sb, jbegin_count) ; | ||
641 | |||
642 | out_failed: | ||
643 | if (locked) | ||
644 | reiserfs_write_unlock_xattrs (dir->i_sb); | ||
645 | reiserfs_write_unlock(dir->i_sb); | ||
646 | return retval; | ||
647 | } | ||
648 | 625 | ||
626 | locked = reiserfs_cache_default_acl(dir); | ||
649 | 627 | ||
650 | static int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t rdev) | 628 | reiserfs_write_lock(dir->i_sb); |
651 | { | ||
652 | int retval; | ||
653 | struct inode * inode; | ||
654 | struct reiserfs_transaction_handle th ; | ||
655 | /* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */ | ||
656 | int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb)+REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb)); | ||
657 | int locked; | ||
658 | 629 | ||
659 | if (!new_valid_dev(rdev)) | 630 | if (locked) |
660 | return -EINVAL; | 631 | reiserfs_write_lock_xattrs(dir->i_sb); |
632 | |||
633 | retval = journal_begin(&th, dir->i_sb, jbegin_count); | ||
634 | if (retval) { | ||
635 | drop_new_inode(inode); | ||
636 | goto out_failed; | ||
637 | } | ||
638 | |||
639 | retval = | ||
640 | reiserfs_new_inode(&th, dir, mode, NULL, 0 /*i_size */ , dentry, | ||
641 | inode); | ||
642 | if (retval) | ||
643 | goto out_failed; | ||
644 | |||
645 | if (locked) { | ||
646 | reiserfs_write_unlock_xattrs(dir->i_sb); | ||
647 | locked = 0; | ||
648 | } | ||
649 | |||
650 | inode->i_op = &reiserfs_file_inode_operations; | ||
651 | inode->i_fop = &reiserfs_file_operations; | ||
652 | inode->i_mapping->a_ops = &reiserfs_address_space_operations; | ||
653 | |||
654 | retval = | ||
655 | reiserfs_add_entry(&th, dir, dentry->d_name.name, | ||
656 | dentry->d_name.len, inode, 1 /*visible */ ); | ||
657 | if (retval) { | ||
658 | int err; | ||
659 | inode->i_nlink--; | ||
660 | reiserfs_update_sd(&th, inode); | ||
661 | err = journal_end(&th, dir->i_sb, jbegin_count); | ||
662 | if (err) | ||
663 | retval = err; | ||
664 | iput(inode); | ||
665 | goto out_failed; | ||
666 | } | ||
667 | reiserfs_update_inode_transaction(inode); | ||
668 | reiserfs_update_inode_transaction(dir); | ||
661 | 669 | ||
662 | if (!(inode = new_inode(dir->i_sb))) { | 670 | d_instantiate(dentry, inode); |
663 | return -ENOMEM ; | 671 | retval = journal_end(&th, dir->i_sb, jbegin_count); |
664 | } | ||
665 | new_inode_init(inode, dir, mode); | ||
666 | 672 | ||
667 | locked = reiserfs_cache_default_acl (dir); | 673 | out_failed: |
674 | if (locked) | ||
675 | reiserfs_write_unlock_xattrs(dir->i_sb); | ||
676 | reiserfs_write_unlock(dir->i_sb); | ||
677 | return retval; | ||
678 | } | ||
668 | 679 | ||
669 | reiserfs_write_lock(dir->i_sb); | 680 | static int reiserfs_mknod(struct inode *dir, struct dentry *dentry, int mode, |
681 | dev_t rdev) | ||
682 | { | ||
683 | int retval; | ||
684 | struct inode *inode; | ||
685 | struct reiserfs_transaction_handle th; | ||
686 | /* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */ | ||
687 | int jbegin_count = | ||
688 | JOURNAL_PER_BALANCE_CNT * 3 + | ||
689 | 2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) + | ||
690 | REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb)); | ||
691 | int locked; | ||
692 | |||
693 | if (!new_valid_dev(rdev)) | ||
694 | return -EINVAL; | ||
695 | |||
696 | if (!(inode = new_inode(dir->i_sb))) { | ||
697 | return -ENOMEM; | ||
698 | } | ||
699 | new_inode_init(inode, dir, mode); | ||
670 | 700 | ||
671 | if (locked) | 701 | locked = reiserfs_cache_default_acl(dir); |
672 | reiserfs_write_lock_xattrs (dir->i_sb); | ||
673 | 702 | ||
674 | retval = journal_begin(&th, dir->i_sb, jbegin_count) ; | 703 | reiserfs_write_lock(dir->i_sb); |
675 | if (retval) { | ||
676 | drop_new_inode (inode); | ||
677 | goto out_failed; | ||
678 | } | ||
679 | 704 | ||
680 | retval = reiserfs_new_inode (&th, dir, mode, NULL, 0/*i_size*/, dentry, inode); | 705 | if (locked) |
681 | if (retval) { | 706 | reiserfs_write_lock_xattrs(dir->i_sb); |
682 | goto out_failed; | ||
683 | } | ||
684 | 707 | ||
685 | if (locked) { | 708 | retval = journal_begin(&th, dir->i_sb, jbegin_count); |
686 | reiserfs_write_unlock_xattrs (dir->i_sb); | 709 | if (retval) { |
687 | locked = 0; | 710 | drop_new_inode(inode); |
688 | } | 711 | goto out_failed; |
712 | } | ||
689 | 713 | ||
714 | retval = | ||
715 | reiserfs_new_inode(&th, dir, mode, NULL, 0 /*i_size */ , dentry, | ||
716 | inode); | ||
717 | if (retval) { | ||
718 | goto out_failed; | ||
719 | } | ||
690 | 720 | ||
691 | inode->i_op = &reiserfs_special_inode_operations; | 721 | if (locked) { |
692 | init_special_inode(inode, inode->i_mode, rdev) ; | 722 | reiserfs_write_unlock_xattrs(dir->i_sb); |
723 | locked = 0; | ||
724 | } | ||
693 | 725 | ||
694 | //FIXME: needed for block and char devices only | 726 | inode->i_op = &reiserfs_special_inode_operations; |
695 | reiserfs_update_sd (&th, inode); | 727 | init_special_inode(inode, inode->i_mode, rdev); |
728 | |||
729 | //FIXME: needed for block and char devices only | ||
730 | reiserfs_update_sd(&th, inode); | ||
731 | |||
732 | reiserfs_update_inode_transaction(inode); | ||
733 | reiserfs_update_inode_transaction(dir); | ||
734 | |||
735 | retval = | ||
736 | reiserfs_add_entry(&th, dir, dentry->d_name.name, | ||
737 | dentry->d_name.len, inode, 1 /*visible */ ); | ||
738 | if (retval) { | ||
739 | int err; | ||
740 | inode->i_nlink--; | ||
741 | reiserfs_update_sd(&th, inode); | ||
742 | err = journal_end(&th, dir->i_sb, jbegin_count); | ||
743 | if (err) | ||
744 | retval = err; | ||
745 | iput(inode); | ||
746 | goto out_failed; | ||
747 | } | ||
696 | 748 | ||
697 | reiserfs_update_inode_transaction(inode) ; | 749 | d_instantiate(dentry, inode); |
698 | reiserfs_update_inode_transaction(dir) ; | 750 | retval = journal_end(&th, dir->i_sb, jbegin_count); |
699 | 751 | ||
700 | retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len, | 752 | out_failed: |
701 | inode, 1/*visible*/); | 753 | if (locked) |
702 | if (retval) { | 754 | reiserfs_write_unlock_xattrs(dir->i_sb); |
703 | int err; | 755 | reiserfs_write_unlock(dir->i_sb); |
704 | inode->i_nlink--; | 756 | return retval; |
705 | reiserfs_update_sd (&th, inode); | ||
706 | err = journal_end(&th, dir->i_sb, jbegin_count) ; | ||
707 | if (err) | ||
708 | retval = err; | ||
709 | iput (inode); | ||
710 | goto out_failed; | ||
711 | } | ||
712 | |||
713 | d_instantiate(dentry, inode); | ||
714 | retval = journal_end(&th, dir->i_sb, jbegin_count) ; | ||
715 | |||
716 | out_failed: | ||
717 | if (locked) | ||
718 | reiserfs_write_unlock_xattrs (dir->i_sb); | ||
719 | reiserfs_write_unlock(dir->i_sb); | ||
720 | return retval; | ||
721 | } | 757 | } |
722 | 758 | ||
723 | 759 | static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |
724 | static int reiserfs_mkdir (struct inode * dir, struct dentry *dentry, int mode) | ||
725 | { | 760 | { |
726 | int retval; | 761 | int retval; |
727 | struct inode * inode; | 762 | struct inode *inode; |
728 | struct reiserfs_transaction_handle th ; | 763 | struct reiserfs_transaction_handle th; |
729 | /* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */ | 764 | /* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */ |
730 | int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb)+REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb)); | 765 | int jbegin_count = |
731 | int locked; | 766 | JOURNAL_PER_BALANCE_CNT * 3 + |
767 | 2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) + | ||
768 | REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb)); | ||
769 | int locked; | ||
732 | 770 | ||
733 | #ifdef DISPLACE_NEW_PACKING_LOCALITIES | 771 | #ifdef DISPLACE_NEW_PACKING_LOCALITIES |
734 | /* set flag that new packing locality created and new blocks for the content * of that directory are not displaced yet */ | 772 | /* set flag that new packing locality created and new blocks for the content * of that directory are not displaced yet */ |
735 | REISERFS_I(dir)->new_packing_locality = 1; | 773 | REISERFS_I(dir)->new_packing_locality = 1; |
736 | #endif | 774 | #endif |
737 | mode = S_IFDIR | mode; | 775 | mode = S_IFDIR | mode; |
738 | if (!(inode = new_inode(dir->i_sb))) { | 776 | if (!(inode = new_inode(dir->i_sb))) { |
739 | return -ENOMEM ; | 777 | return -ENOMEM; |
740 | } | 778 | } |
741 | new_inode_init(inode, dir, mode); | 779 | new_inode_init(inode, dir, mode); |
742 | 780 | ||
743 | locked = reiserfs_cache_default_acl (dir); | 781 | locked = reiserfs_cache_default_acl(dir); |
744 | 782 | ||
745 | reiserfs_write_lock(dir->i_sb); | 783 | reiserfs_write_lock(dir->i_sb); |
746 | if (locked) | 784 | if (locked) |
747 | reiserfs_write_lock_xattrs (dir->i_sb); | 785 | reiserfs_write_lock_xattrs(dir->i_sb); |
748 | 786 | ||
749 | retval = journal_begin(&th, dir->i_sb, jbegin_count) ; | 787 | retval = journal_begin(&th, dir->i_sb, jbegin_count); |
750 | if (retval) { | 788 | if (retval) { |
751 | drop_new_inode (inode); | 789 | drop_new_inode(inode); |
752 | goto out_failed; | 790 | goto out_failed; |
753 | } | 791 | } |
754 | |||
755 | |||
756 | /* inc the link count now, so another writer doesn't overflow it while | ||
757 | ** we sleep later on. | ||
758 | */ | ||
759 | INC_DIR_INODE_NLINK(dir) | ||
760 | |||
761 | retval = reiserfs_new_inode (&th, dir, mode, NULL/*symlink*/, | ||
762 | old_format_only (dir->i_sb) ? | ||
763 | EMPTY_DIR_SIZE_V1 : EMPTY_DIR_SIZE, | ||
764 | dentry, inode); | ||
765 | if (retval) { | ||
766 | dir->i_nlink-- ; | ||
767 | goto out_failed; | ||
768 | } | ||
769 | |||
770 | if (locked) { | ||
771 | reiserfs_write_unlock_xattrs (dir->i_sb); | ||
772 | locked = 0; | ||
773 | } | ||
774 | |||
775 | reiserfs_update_inode_transaction(inode) ; | ||
776 | reiserfs_update_inode_transaction(dir) ; | ||
777 | |||
778 | inode->i_op = &reiserfs_dir_inode_operations; | ||
779 | inode->i_fop = &reiserfs_dir_operations; | ||
780 | |||
781 | // note, _this_ add_entry will not update dir's stat data | ||
782 | retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len, | ||
783 | inode, 1/*visible*/); | ||
784 | if (retval) { | ||
785 | int err; | ||
786 | inode->i_nlink = 0; | ||
787 | DEC_DIR_INODE_NLINK(dir); | ||
788 | reiserfs_update_sd (&th, inode); | ||
789 | err = journal_end(&th, dir->i_sb, jbegin_count) ; | ||
790 | if (err) | ||
791 | retval = err; | ||
792 | iput (inode); | ||
793 | goto out_failed; | ||
794 | } | ||
795 | |||
796 | // the above add_entry did not update dir's stat data | ||
797 | reiserfs_update_sd (&th, dir); | ||
798 | |||
799 | d_instantiate(dentry, inode); | ||
800 | retval = journal_end(&th, dir->i_sb, jbegin_count) ; | ||
801 | out_failed: | ||
802 | if (locked) | ||
803 | reiserfs_write_unlock_xattrs (dir->i_sb); | ||
804 | reiserfs_write_unlock(dir->i_sb); | ||
805 | return retval; | ||
806 | } | ||
807 | 792 | ||
808 | static inline int reiserfs_empty_dir(struct inode *inode) { | 793 | /* inc the link count now, so another writer doesn't overflow it while |
809 | /* we can cheat because an old format dir cannot have | 794 | ** we sleep later on. |
810 | ** EMPTY_DIR_SIZE, and a new format dir cannot have | 795 | */ |
811 | ** EMPTY_DIR_SIZE_V1. So, if the inode is either size, | 796 | INC_DIR_INODE_NLINK(dir) |
812 | ** regardless of disk format version, the directory is empty. | 797 | |
813 | */ | 798 | retval = reiserfs_new_inode(&th, dir, mode, NULL /*symlink */ , |
814 | if (inode->i_size != EMPTY_DIR_SIZE && | 799 | old_format_only(dir->i_sb) ? |
815 | inode->i_size != EMPTY_DIR_SIZE_V1) { | 800 | EMPTY_DIR_SIZE_V1 : EMPTY_DIR_SIZE, |
816 | return 0 ; | 801 | dentry, inode); |
817 | } | 802 | if (retval) { |
818 | return 1 ; | 803 | dir->i_nlink--; |
804 | goto out_failed; | ||
805 | } | ||
806 | |||
807 | if (locked) { | ||
808 | reiserfs_write_unlock_xattrs(dir->i_sb); | ||
809 | locked = 0; | ||
810 | } | ||
811 | |||
812 | reiserfs_update_inode_transaction(inode); | ||
813 | reiserfs_update_inode_transaction(dir); | ||
814 | |||
815 | inode->i_op = &reiserfs_dir_inode_operations; | ||
816 | inode->i_fop = &reiserfs_dir_operations; | ||
817 | |||
818 | // note, _this_ add_entry will not update dir's stat data | ||
819 | retval = | ||
820 | reiserfs_add_entry(&th, dir, dentry->d_name.name, | ||
821 | dentry->d_name.len, inode, 1 /*visible */ ); | ||
822 | if (retval) { | ||
823 | int err; | ||
824 | inode->i_nlink = 0; | ||
825 | DEC_DIR_INODE_NLINK(dir); | ||
826 | reiserfs_update_sd(&th, inode); | ||
827 | err = journal_end(&th, dir->i_sb, jbegin_count); | ||
828 | if (err) | ||
829 | retval = err; | ||
830 | iput(inode); | ||
831 | goto out_failed; | ||
832 | } | ||
833 | // the above add_entry did not update dir's stat data | ||
834 | reiserfs_update_sd(&th, dir); | ||
835 | |||
836 | d_instantiate(dentry, inode); | ||
837 | retval = journal_end(&th, dir->i_sb, jbegin_count); | ||
838 | out_failed: | ||
839 | if (locked) | ||
840 | reiserfs_write_unlock_xattrs(dir->i_sb); | ||
841 | reiserfs_write_unlock(dir->i_sb); | ||
842 | return retval; | ||
819 | } | 843 | } |
820 | 844 | ||
821 | static int reiserfs_rmdir (struct inode * dir, struct dentry *dentry) | 845 | static inline int reiserfs_empty_dir(struct inode *inode) |
822 | { | 846 | { |
823 | int retval, err; | 847 | /* we can cheat because an old format dir cannot have |
824 | struct inode * inode; | 848 | ** EMPTY_DIR_SIZE, and a new format dir cannot have |
825 | struct reiserfs_transaction_handle th ; | 849 | ** EMPTY_DIR_SIZE_V1. So, if the inode is either size, |
826 | int jbegin_count; | 850 | ** regardless of disk format version, the directory is empty. |
827 | INITIALIZE_PATH (path); | 851 | */ |
828 | struct reiserfs_dir_entry de; | 852 | if (inode->i_size != EMPTY_DIR_SIZE && |
829 | 853 | inode->i_size != EMPTY_DIR_SIZE_V1) { | |
830 | 854 | return 0; | |
831 | /* we will be doing 2 balancings and update 2 stat data, we change quotas | 855 | } |
832 | * of the owner of the directory and of the owner of the parent directory. | 856 | return 1; |
833 | * The quota structure is possibly deleted only on last iput => outside | ||
834 | * of this transaction */ | ||
835 | jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2 + 4 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb); | ||
836 | |||
837 | reiserfs_write_lock(dir->i_sb); | ||
838 | retval = journal_begin(&th, dir->i_sb, jbegin_count) ; | ||
839 | if (retval) | ||
840 | goto out_rmdir; | ||
841 | |||
842 | de.de_gen_number_bit_string = NULL; | ||
843 | if ( (retval = reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path, &de)) == NAME_NOT_FOUND) { | ||
844 | retval = -ENOENT; | ||
845 | goto end_rmdir; | ||
846 | } else if ( retval == IO_ERROR) { | ||
847 | retval = -EIO; | ||
848 | goto end_rmdir; | ||
849 | } | ||
850 | |||
851 | inode = dentry->d_inode; | ||
852 | |||
853 | reiserfs_update_inode_transaction(inode) ; | ||
854 | reiserfs_update_inode_transaction(dir) ; | ||
855 | |||
856 | if (de.de_objectid != inode->i_ino) { | ||
857 | // FIXME: compare key of an object and a key found in the | ||
858 | // entry | ||
859 | retval = -EIO; | ||
860 | goto end_rmdir; | ||
861 | } | ||
862 | if (!reiserfs_empty_dir(inode)) { | ||
863 | retval = -ENOTEMPTY; | ||
864 | goto end_rmdir; | ||
865 | } | ||
866 | |||
867 | /* cut entry from dir directory */ | ||
868 | retval = reiserfs_cut_from_item (&th, &path, &(de.de_entry_key), dir, | ||
869 | NULL, /* page */ | ||
870 | 0/*new file size - not used here*/); | ||
871 | if (retval < 0) | ||
872 | goto end_rmdir; | ||
873 | |||
874 | if ( inode->i_nlink != 2 && inode->i_nlink != 1 ) | ||
875 | reiserfs_warning (inode->i_sb, "%s: empty directory has nlink " | ||
876 | "!= 2 (%d)", __FUNCTION__, inode->i_nlink); | ||
877 | |||
878 | inode->i_nlink = 0; | ||
879 | inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; | ||
880 | reiserfs_update_sd (&th, inode); | ||
881 | |||
882 | DEC_DIR_INODE_NLINK(dir) | ||
883 | dir->i_size -= (DEH_SIZE + de.de_entrylen); | ||
884 | reiserfs_update_sd (&th, dir); | ||
885 | |||
886 | /* prevent empty directory from getting lost */ | ||
887 | add_save_link (&th, inode, 0/* not truncate */); | ||
888 | |||
889 | retval = journal_end(&th, dir->i_sb, jbegin_count) ; | ||
890 | reiserfs_check_path(&path) ; | ||
891 | out_rmdir: | ||
892 | reiserfs_write_unlock(dir->i_sb); | ||
893 | return retval; | ||
894 | |||
895 | end_rmdir: | ||
896 | /* we must release path, because we did not call | ||
897 | reiserfs_cut_from_item, or reiserfs_cut_from_item does not | ||
898 | release path if operation was not complete */ | ||
899 | pathrelse (&path); | ||
900 | err = journal_end(&th, dir->i_sb, jbegin_count) ; | ||
901 | reiserfs_write_unlock(dir->i_sb); | ||
902 | return err ? err : retval; | ||
903 | } | 857 | } |
904 | 858 | ||
905 | static int reiserfs_unlink (struct inode * dir, struct dentry *dentry) | 859 | static int reiserfs_rmdir(struct inode *dir, struct dentry *dentry) |
906 | { | 860 | { |
907 | int retval, err; | 861 | int retval, err; |
908 | struct inode * inode; | 862 | struct inode *inode; |
909 | struct reiserfs_dir_entry de; | 863 | struct reiserfs_transaction_handle th; |
910 | INITIALIZE_PATH (path); | 864 | int jbegin_count; |
911 | struct reiserfs_transaction_handle th ; | 865 | INITIALIZE_PATH(path); |
912 | int jbegin_count; | 866 | struct reiserfs_dir_entry de; |
913 | unsigned long savelink; | 867 | |
914 | 868 | /* we will be doing 2 balancings and update 2 stat data, we change quotas | |
915 | inode = dentry->d_inode; | 869 | * of the owner of the directory and of the owner of the parent directory. |
916 | 870 | * The quota structure is possibly deleted only on last iput => outside | |
917 | /* in this transaction we can be doing at max two balancings and update | 871 | * of this transaction */ |
918 | * two stat datas, we change quotas of the owner of the directory and of | 872 | jbegin_count = |
919 | * the owner of the parent directory. The quota structure is possibly | 873 | JOURNAL_PER_BALANCE_CNT * 2 + 2 + |
920 | * deleted only on iput => outside of this transaction */ | 874 | 4 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb); |
921 | jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2 + 4 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb); | 875 | |
922 | 876 | reiserfs_write_lock(dir->i_sb); | |
923 | reiserfs_write_lock(dir->i_sb); | 877 | retval = journal_begin(&th, dir->i_sb, jbegin_count); |
924 | retval = journal_begin(&th, dir->i_sb, jbegin_count) ; | 878 | if (retval) |
925 | if (retval) | 879 | goto out_rmdir; |
926 | goto out_unlink; | 880 | |
927 | 881 | de.de_gen_number_bit_string = NULL; | |
928 | de.de_gen_number_bit_string = NULL; | 882 | if ((retval = |
929 | if ( (retval = reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path, &de)) == NAME_NOT_FOUND) { | 883 | reiserfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, |
930 | retval = -ENOENT; | 884 | &path, &de)) == NAME_NOT_FOUND) { |
931 | goto end_unlink; | 885 | retval = -ENOENT; |
932 | } else if (retval == IO_ERROR) { | 886 | goto end_rmdir; |
933 | retval = -EIO; | 887 | } else if (retval == IO_ERROR) { |
934 | goto end_unlink; | 888 | retval = -EIO; |
935 | } | 889 | goto end_rmdir; |
936 | 890 | } | |
937 | reiserfs_update_inode_transaction(inode) ; | 891 | |
938 | reiserfs_update_inode_transaction(dir) ; | 892 | inode = dentry->d_inode; |
939 | 893 | ||
940 | if (de.de_objectid != inode->i_ino) { | 894 | reiserfs_update_inode_transaction(inode); |
941 | // FIXME: compare key of an object and a key found in the | 895 | reiserfs_update_inode_transaction(dir); |
942 | // entry | 896 | |
943 | retval = -EIO; | 897 | if (de.de_objectid != inode->i_ino) { |
944 | goto end_unlink; | 898 | // FIXME: compare key of an object and a key found in the |
945 | } | 899 | // entry |
946 | 900 | retval = -EIO; | |
947 | if (!inode->i_nlink) { | 901 | goto end_rmdir; |
948 | reiserfs_warning (inode->i_sb, "%s: deleting nonexistent file " | 902 | } |
949 | "(%s:%lu), %d", __FUNCTION__, | 903 | if (!reiserfs_empty_dir(inode)) { |
950 | reiserfs_bdevname (inode->i_sb), inode->i_ino, | 904 | retval = -ENOTEMPTY; |
951 | inode->i_nlink); | 905 | goto end_rmdir; |
952 | inode->i_nlink = 1; | 906 | } |
953 | } | 907 | |
954 | 908 | /* cut entry from dir directory */ | |
955 | inode->i_nlink--; | 909 | retval = reiserfs_cut_from_item(&th, &path, &(de.de_entry_key), dir, NULL, /* page */ |
956 | 910 | 0 /*new file size - not used here */ ); | |
957 | /* | 911 | if (retval < 0) |
958 | * we schedule before doing the add_save_link call, save the link | 912 | goto end_rmdir; |
959 | * count so we don't race | 913 | |
960 | */ | 914 | if (inode->i_nlink != 2 && inode->i_nlink != 1) |
961 | savelink = inode->i_nlink; | 915 | reiserfs_warning(inode->i_sb, "%s: empty directory has nlink " |
962 | 916 | "!= 2 (%d)", __FUNCTION__, inode->i_nlink); | |
963 | 917 | ||
964 | retval = reiserfs_cut_from_item (&th, &path, &(de.de_entry_key), dir, NULL, 0); | 918 | inode->i_nlink = 0; |
965 | if (retval < 0) { | 919 | inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; |
966 | inode->i_nlink++; | 920 | reiserfs_update_sd(&th, inode); |
967 | goto end_unlink; | 921 | |
968 | } | 922 | DEC_DIR_INODE_NLINK(dir) |
969 | inode->i_ctime = CURRENT_TIME_SEC; | 923 | dir->i_size -= (DEH_SIZE + de.de_entrylen); |
970 | reiserfs_update_sd (&th, inode); | 924 | reiserfs_update_sd(&th, dir); |
971 | 925 | ||
972 | dir->i_size -= (de.de_entrylen + DEH_SIZE); | 926 | /* prevent empty directory from getting lost */ |
973 | dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; | 927 | add_save_link(&th, inode, 0 /* not truncate */ ); |
974 | reiserfs_update_sd (&th, dir); | 928 | |
975 | 929 | retval = journal_end(&th, dir->i_sb, jbegin_count); | |
976 | if (!savelink) | 930 | reiserfs_check_path(&path); |
977 | /* prevent file from getting lost */ | 931 | out_rmdir: |
978 | add_save_link (&th, inode, 0/* not truncate */); | 932 | reiserfs_write_unlock(dir->i_sb); |
979 | 933 | return retval; | |
980 | retval = journal_end(&th, dir->i_sb, jbegin_count) ; | 934 | |
981 | reiserfs_check_path(&path) ; | 935 | end_rmdir: |
982 | reiserfs_write_unlock(dir->i_sb); | 936 | /* we must release path, because we did not call |
983 | return retval; | 937 | reiserfs_cut_from_item, or reiserfs_cut_from_item does not |
984 | 938 | release path if operation was not complete */ | |
985 | end_unlink: | 939 | pathrelse(&path); |
986 | pathrelse (&path); | 940 | err = journal_end(&th, dir->i_sb, jbegin_count); |
987 | err = journal_end(&th, dir->i_sb, jbegin_count) ; | 941 | reiserfs_write_unlock(dir->i_sb); |
988 | reiserfs_check_path(&path) ; | 942 | return err ? err : retval; |
989 | if (err) | ||
990 | retval = err; | ||
991 | out_unlink: | ||
992 | reiserfs_write_unlock(dir->i_sb); | ||
993 | return retval; | ||
994 | } | 943 | } |
995 | 944 | ||
996 | static int reiserfs_symlink (struct inode * parent_dir, | 945 | static int reiserfs_unlink(struct inode *dir, struct dentry *dentry) |
997 | struct dentry * dentry, const char * symname) | ||
998 | { | 946 | { |
999 | int retval; | 947 | int retval, err; |
1000 | struct inode * inode; | 948 | struct inode *inode; |
1001 | char * name; | 949 | struct reiserfs_dir_entry de; |
1002 | int item_len; | 950 | INITIALIZE_PATH(path); |
1003 | struct reiserfs_transaction_handle th ; | 951 | struct reiserfs_transaction_handle th; |
1004 | int mode = S_IFLNK | S_IRWXUGO; | 952 | int jbegin_count; |
1005 | /* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */ | 953 | unsigned long savelink; |
1006 | int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 2 * (REISERFS_QUOTA_INIT_BLOCKS(parent_dir->i_sb)+REISERFS_QUOTA_TRANS_BLOCKS(parent_dir->i_sb)); | 954 | |
1007 | 955 | inode = dentry->d_inode; | |
1008 | if (!(inode = new_inode(parent_dir->i_sb))) { | 956 | |
1009 | return -ENOMEM ; | 957 | /* in this transaction we can be doing at max two balancings and update |
1010 | } | 958 | * two stat datas, we change quotas of the owner of the directory and of |
1011 | new_inode_init(inode, parent_dir, mode); | 959 | * the owner of the parent directory. The quota structure is possibly |
1012 | 960 | * deleted only on iput => outside of this transaction */ | |
1013 | reiserfs_write_lock(parent_dir->i_sb); | 961 | jbegin_count = |
1014 | item_len = ROUND_UP (strlen (symname)); | 962 | JOURNAL_PER_BALANCE_CNT * 2 + 2 + |
1015 | if (item_len > MAX_DIRECT_ITEM_LEN (parent_dir->i_sb->s_blocksize)) { | 963 | 4 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb); |
1016 | retval = -ENAMETOOLONG; | 964 | |
1017 | drop_new_inode(inode); | 965 | reiserfs_write_lock(dir->i_sb); |
1018 | goto out_failed; | 966 | retval = journal_begin(&th, dir->i_sb, jbegin_count); |
1019 | } | 967 | if (retval) |
1020 | 968 | goto out_unlink; | |
1021 | name = reiserfs_kmalloc (item_len, GFP_NOFS, parent_dir->i_sb); | 969 | |
1022 | if (!name) { | 970 | de.de_gen_number_bit_string = NULL; |
1023 | drop_new_inode(inode); | 971 | if ((retval = |
1024 | retval = -ENOMEM; | 972 | reiserfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, |
1025 | goto out_failed; | 973 | &path, &de)) == NAME_NOT_FOUND) { |
1026 | } | 974 | retval = -ENOENT; |
1027 | memcpy (name, symname, strlen (symname)); | 975 | goto end_unlink; |
1028 | padd_item (name, item_len, strlen (symname)); | 976 | } else if (retval == IO_ERROR) { |
1029 | 977 | retval = -EIO; | |
1030 | /* We would inherit the default ACL here, but symlinks don't get ACLs */ | 978 | goto end_unlink; |
1031 | 979 | } | |
1032 | retval = journal_begin(&th, parent_dir->i_sb, jbegin_count) ; | 980 | |
1033 | if (retval) { | 981 | reiserfs_update_inode_transaction(inode); |
1034 | drop_new_inode (inode); | 982 | reiserfs_update_inode_transaction(dir); |
1035 | reiserfs_kfree (name, item_len, parent_dir->i_sb); | 983 | |
1036 | goto out_failed; | 984 | if (de.de_objectid != inode->i_ino) { |
1037 | } | 985 | // FIXME: compare key of an object and a key found in the |
1038 | 986 | // entry | |
1039 | retval = reiserfs_new_inode (&th, parent_dir, mode, name, strlen (symname), | 987 | retval = -EIO; |
1040 | dentry, inode); | 988 | goto end_unlink; |
1041 | reiserfs_kfree (name, item_len, parent_dir->i_sb); | 989 | } |
1042 | if (retval) { /* reiserfs_new_inode iputs for us */ | 990 | |
1043 | goto out_failed; | 991 | if (!inode->i_nlink) { |
1044 | } | 992 | reiserfs_warning(inode->i_sb, "%s: deleting nonexistent file " |
1045 | 993 | "(%s:%lu), %d", __FUNCTION__, | |
1046 | reiserfs_update_inode_transaction(inode) ; | 994 | reiserfs_bdevname(inode->i_sb), inode->i_ino, |
1047 | reiserfs_update_inode_transaction(parent_dir) ; | 995 | inode->i_nlink); |
1048 | 996 | inode->i_nlink = 1; | |
1049 | inode->i_op = &reiserfs_symlink_inode_operations; | 997 | } |
1050 | inode->i_mapping->a_ops = &reiserfs_address_space_operations; | 998 | |
1051 | |||
1052 | // must be sure this inode is written with this transaction | ||
1053 | // | ||
1054 | //reiserfs_update_sd (&th, inode, READ_BLOCKS); | ||
1055 | |||
1056 | retval = reiserfs_add_entry (&th, parent_dir, dentry->d_name.name, | ||
1057 | dentry->d_name.len, inode, 1/*visible*/); | ||
1058 | if (retval) { | ||
1059 | int err; | ||
1060 | inode->i_nlink--; | 999 | inode->i_nlink--; |
1061 | reiserfs_update_sd (&th, inode); | 1000 | |
1062 | err = journal_end(&th, parent_dir->i_sb, jbegin_count) ; | 1001 | /* |
1002 | * we schedule before doing the add_save_link call, save the link | ||
1003 | * count so we don't race | ||
1004 | */ | ||
1005 | savelink = inode->i_nlink; | ||
1006 | |||
1007 | retval = | ||
1008 | reiserfs_cut_from_item(&th, &path, &(de.de_entry_key), dir, NULL, | ||
1009 | 0); | ||
1010 | if (retval < 0) { | ||
1011 | inode->i_nlink++; | ||
1012 | goto end_unlink; | ||
1013 | } | ||
1014 | inode->i_ctime = CURRENT_TIME_SEC; | ||
1015 | reiserfs_update_sd(&th, inode); | ||
1016 | |||
1017 | dir->i_size -= (de.de_entrylen + DEH_SIZE); | ||
1018 | dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; | ||
1019 | reiserfs_update_sd(&th, dir); | ||
1020 | |||
1021 | if (!savelink) | ||
1022 | /* prevent file from getting lost */ | ||
1023 | add_save_link(&th, inode, 0 /* not truncate */ ); | ||
1024 | |||
1025 | retval = journal_end(&th, dir->i_sb, jbegin_count); | ||
1026 | reiserfs_check_path(&path); | ||
1027 | reiserfs_write_unlock(dir->i_sb); | ||
1028 | return retval; | ||
1029 | |||
1030 | end_unlink: | ||
1031 | pathrelse(&path); | ||
1032 | err = journal_end(&th, dir->i_sb, jbegin_count); | ||
1033 | reiserfs_check_path(&path); | ||
1063 | if (err) | 1034 | if (err) |
1064 | retval = err; | 1035 | retval = err; |
1065 | iput (inode); | 1036 | out_unlink: |
1066 | goto out_failed; | 1037 | reiserfs_write_unlock(dir->i_sb); |
1067 | } | 1038 | return retval; |
1068 | |||
1069 | d_instantiate(dentry, inode); | ||
1070 | retval = journal_end(&th, parent_dir->i_sb, jbegin_count) ; | ||
1071 | out_failed: | ||
1072 | reiserfs_write_unlock(parent_dir->i_sb); | ||
1073 | return retval; | ||
1074 | } | 1039 | } |
1075 | 1040 | ||
1076 | static int reiserfs_link (struct dentry * old_dentry, struct inode * dir, struct dentry * dentry) | 1041 | static int reiserfs_symlink(struct inode *parent_dir, |
1042 | struct dentry *dentry, const char *symname) | ||
1077 | { | 1043 | { |
1078 | int retval; | 1044 | int retval; |
1079 | struct inode *inode = old_dentry->d_inode; | 1045 | struct inode *inode; |
1080 | struct reiserfs_transaction_handle th ; | 1046 | char *name; |
1081 | /* We need blocks for transaction + update of quotas for the owners of the directory */ | 1047 | int item_len; |
1082 | int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 2 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb); | 1048 | struct reiserfs_transaction_handle th; |
1083 | 1049 | int mode = S_IFLNK | S_IRWXUGO; | |
1084 | reiserfs_write_lock(dir->i_sb); | 1050 | /* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */ |
1085 | if (inode->i_nlink >= REISERFS_LINK_MAX) { | 1051 | int jbegin_count = |
1086 | //FIXME: sd_nlink is 32 bit for new files | 1052 | JOURNAL_PER_BALANCE_CNT * 3 + |
1087 | reiserfs_write_unlock(dir->i_sb); | 1053 | 2 * (REISERFS_QUOTA_INIT_BLOCKS(parent_dir->i_sb) + |
1088 | return -EMLINK; | 1054 | REISERFS_QUOTA_TRANS_BLOCKS(parent_dir->i_sb)); |
1089 | } | 1055 | |
1090 | if (inode->i_nlink == 0) { | 1056 | if (!(inode = new_inode(parent_dir->i_sb))) { |
1091 | reiserfs_write_unlock(dir->i_sb); | 1057 | return -ENOMEM; |
1092 | return -ENOENT; | 1058 | } |
1093 | } | 1059 | new_inode_init(inode, parent_dir, mode); |
1094 | 1060 | ||
1095 | /* inc before scheduling so reiserfs_unlink knows we are here */ | 1061 | reiserfs_write_lock(parent_dir->i_sb); |
1096 | inode->i_nlink++; | 1062 | item_len = ROUND_UP(strlen(symname)); |
1097 | 1063 | if (item_len > MAX_DIRECT_ITEM_LEN(parent_dir->i_sb->s_blocksize)) { | |
1098 | retval = journal_begin(&th, dir->i_sb, jbegin_count) ; | 1064 | retval = -ENAMETOOLONG; |
1099 | if (retval) { | 1065 | drop_new_inode(inode); |
1100 | inode->i_nlink--; | 1066 | goto out_failed; |
1101 | reiserfs_write_unlock (dir->i_sb); | 1067 | } |
1102 | return retval; | 1068 | |
1103 | } | 1069 | name = reiserfs_kmalloc(item_len, GFP_NOFS, parent_dir->i_sb); |
1104 | 1070 | if (!name) { | |
1105 | /* create new entry */ | 1071 | drop_new_inode(inode); |
1106 | retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len, | 1072 | retval = -ENOMEM; |
1107 | inode, 1/*visible*/); | 1073 | goto out_failed; |
1108 | 1074 | } | |
1109 | reiserfs_update_inode_transaction(inode) ; | 1075 | memcpy(name, symname, strlen(symname)); |
1110 | reiserfs_update_inode_transaction(dir) ; | 1076 | padd_item(name, item_len, strlen(symname)); |
1111 | 1077 | ||
1112 | if (retval) { | 1078 | /* We would inherit the default ACL here, but symlinks don't get ACLs */ |
1113 | int err; | 1079 | |
1114 | inode->i_nlink--; | 1080 | retval = journal_begin(&th, parent_dir->i_sb, jbegin_count); |
1115 | err = journal_end(&th, dir->i_sb, jbegin_count) ; | 1081 | if (retval) { |
1116 | reiserfs_write_unlock(dir->i_sb); | 1082 | drop_new_inode(inode); |
1117 | return err ? err : retval; | 1083 | reiserfs_kfree(name, item_len, parent_dir->i_sb); |
1118 | } | 1084 | goto out_failed; |
1085 | } | ||
1086 | |||
1087 | retval = | ||
1088 | reiserfs_new_inode(&th, parent_dir, mode, name, strlen(symname), | ||
1089 | dentry, inode); | ||
1090 | reiserfs_kfree(name, item_len, parent_dir->i_sb); | ||
1091 | if (retval) { /* reiserfs_new_inode iputs for us */ | ||
1092 | goto out_failed; | ||
1093 | } | ||
1119 | 1094 | ||
1120 | inode->i_ctime = CURRENT_TIME_SEC; | 1095 | reiserfs_update_inode_transaction(inode); |
1121 | reiserfs_update_sd (&th, inode); | 1096 | reiserfs_update_inode_transaction(parent_dir); |
1097 | |||
1098 | inode->i_op = &reiserfs_symlink_inode_operations; | ||
1099 | inode->i_mapping->a_ops = &reiserfs_address_space_operations; | ||
1100 | |||
1101 | // must be sure this inode is written with this transaction | ||
1102 | // | ||
1103 | //reiserfs_update_sd (&th, inode, READ_BLOCKS); | ||
1104 | |||
1105 | retval = reiserfs_add_entry(&th, parent_dir, dentry->d_name.name, | ||
1106 | dentry->d_name.len, inode, 1 /*visible */ ); | ||
1107 | if (retval) { | ||
1108 | int err; | ||
1109 | inode->i_nlink--; | ||
1110 | reiserfs_update_sd(&th, inode); | ||
1111 | err = journal_end(&th, parent_dir->i_sb, jbegin_count); | ||
1112 | if (err) | ||
1113 | retval = err; | ||
1114 | iput(inode); | ||
1115 | goto out_failed; | ||
1116 | } | ||
1122 | 1117 | ||
1123 | atomic_inc(&inode->i_count) ; | 1118 | d_instantiate(dentry, inode); |
1124 | d_instantiate(dentry, inode); | 1119 | retval = journal_end(&th, parent_dir->i_sb, jbegin_count); |
1125 | retval = journal_end(&th, dir->i_sb, jbegin_count) ; | 1120 | out_failed: |
1126 | reiserfs_write_unlock(dir->i_sb); | 1121 | reiserfs_write_unlock(parent_dir->i_sb); |
1127 | return retval; | 1122 | return retval; |
1128 | } | 1123 | } |
1129 | 1124 | ||
1125 | static int reiserfs_link(struct dentry *old_dentry, struct inode *dir, | ||
1126 | struct dentry *dentry) | ||
1127 | { | ||
1128 | int retval; | ||
1129 | struct inode *inode = old_dentry->d_inode; | ||
1130 | struct reiserfs_transaction_handle th; | ||
1131 | /* We need blocks for transaction + update of quotas for the owners of the directory */ | ||
1132 | int jbegin_count = | ||
1133 | JOURNAL_PER_BALANCE_CNT * 3 + | ||
1134 | 2 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb); | ||
1135 | |||
1136 | reiserfs_write_lock(dir->i_sb); | ||
1137 | if (inode->i_nlink >= REISERFS_LINK_MAX) { | ||
1138 | //FIXME: sd_nlink is 32 bit for new files | ||
1139 | reiserfs_write_unlock(dir->i_sb); | ||
1140 | return -EMLINK; | ||
1141 | } | ||
1142 | if (inode->i_nlink == 0) { | ||
1143 | reiserfs_write_unlock(dir->i_sb); | ||
1144 | return -ENOENT; | ||
1145 | } | ||
1146 | |||
1147 | /* inc before scheduling so reiserfs_unlink knows we are here */ | ||
1148 | inode->i_nlink++; | ||
1149 | |||
1150 | retval = journal_begin(&th, dir->i_sb, jbegin_count); | ||
1151 | if (retval) { | ||
1152 | inode->i_nlink--; | ||
1153 | reiserfs_write_unlock(dir->i_sb); | ||
1154 | return retval; | ||
1155 | } | ||
1156 | |||
1157 | /* create new entry */ | ||
1158 | retval = | ||
1159 | reiserfs_add_entry(&th, dir, dentry->d_name.name, | ||
1160 | dentry->d_name.len, inode, 1 /*visible */ ); | ||
1161 | |||
1162 | reiserfs_update_inode_transaction(inode); | ||
1163 | reiserfs_update_inode_transaction(dir); | ||
1164 | |||
1165 | if (retval) { | ||
1166 | int err; | ||
1167 | inode->i_nlink--; | ||
1168 | err = journal_end(&th, dir->i_sb, jbegin_count); | ||
1169 | reiserfs_write_unlock(dir->i_sb); | ||
1170 | return err ? err : retval; | ||
1171 | } | ||
1172 | |||
1173 | inode->i_ctime = CURRENT_TIME_SEC; | ||
1174 | reiserfs_update_sd(&th, inode); | ||
1175 | |||
1176 | atomic_inc(&inode->i_count); | ||
1177 | d_instantiate(dentry, inode); | ||
1178 | retval = journal_end(&th, dir->i_sb, jbegin_count); | ||
1179 | reiserfs_write_unlock(dir->i_sb); | ||
1180 | return retval; | ||
1181 | } | ||
1130 | 1182 | ||
1131 | // de contains information pointing to an entry which | 1183 | // de contains information pointing to an entry which |
1132 | static int de_still_valid (const char * name, int len, struct reiserfs_dir_entry * de) | 1184 | static int de_still_valid(const char *name, int len, |
1185 | struct reiserfs_dir_entry *de) | ||
1133 | { | 1186 | { |
1134 | struct reiserfs_dir_entry tmp = *de; | 1187 | struct reiserfs_dir_entry tmp = *de; |
1135 | 1188 | ||
1136 | // recalculate pointer to name and name length | 1189 | // recalculate pointer to name and name length |
1137 | set_de_name_and_namelen (&tmp); | 1190 | set_de_name_and_namelen(&tmp); |
1138 | // FIXME: could check more | 1191 | // FIXME: could check more |
1139 | if (tmp.de_namelen != len || memcmp (name, de->de_name, len)) | 1192 | if (tmp.de_namelen != len || memcmp(name, de->de_name, len)) |
1140 | return 0; | 1193 | return 0; |
1141 | return 1; | 1194 | return 1; |
1142 | } | 1195 | } |
1143 | 1196 | ||
1144 | 1197 | static int entry_points_to_object(const char *name, int len, | |
1145 | static int entry_points_to_object (const char * name, int len, struct reiserfs_dir_entry * de, struct inode * inode) | 1198 | struct reiserfs_dir_entry *de, |
1199 | struct inode *inode) | ||
1146 | { | 1200 | { |
1147 | if (!de_still_valid (name, len, de)) | 1201 | if (!de_still_valid(name, len, de)) |
1148 | return 0; | 1202 | return 0; |
1149 | 1203 | ||
1150 | if (inode) { | 1204 | if (inode) { |
1151 | if (!de_visible (de->de_deh + de->de_entry_num)) | 1205 | if (!de_visible(de->de_deh + de->de_entry_num)) |
1152 | reiserfs_panic (NULL, "vs-7042: entry_points_to_object: entry must be visible"); | 1206 | reiserfs_panic(NULL, |
1153 | return (de->de_objectid == inode->i_ino) ? 1 : 0; | 1207 | "vs-7042: entry_points_to_object: entry must be visible"); |
1154 | } | 1208 | return (de->de_objectid == inode->i_ino) ? 1 : 0; |
1209 | } | ||
1155 | 1210 | ||
1156 | /* this must be added hidden entry */ | 1211 | /* this must be added hidden entry */ |
1157 | if (de_visible (de->de_deh + de->de_entry_num)) | 1212 | if (de_visible(de->de_deh + de->de_entry_num)) |
1158 | reiserfs_panic (NULL, "vs-7043: entry_points_to_object: entry must be visible"); | 1213 | reiserfs_panic(NULL, |
1214 | "vs-7043: entry_points_to_object: entry must be visible"); | ||
1159 | 1215 | ||
1160 | return 1; | 1216 | return 1; |
1161 | } | 1217 | } |
1162 | 1218 | ||
1163 | |||
1164 | /* sets key of objectid the entry has to point to */ | 1219 | /* sets key of objectid the entry has to point to */ |
1165 | static void set_ino_in_dir_entry (struct reiserfs_dir_entry * de, struct reiserfs_key * key) | 1220 | static void set_ino_in_dir_entry(struct reiserfs_dir_entry *de, |
1221 | struct reiserfs_key *key) | ||
1166 | { | 1222 | { |
1167 | /* JDM These operations are endian safe - both are le */ | 1223 | /* JDM These operations are endian safe - both are le */ |
1168 | de->de_deh[de->de_entry_num].deh_dir_id = key->k_dir_id; | 1224 | de->de_deh[de->de_entry_num].deh_dir_id = key->k_dir_id; |
1169 | de->de_deh[de->de_entry_num].deh_objectid = key->k_objectid; | 1225 | de->de_deh[de->de_entry_num].deh_objectid = key->k_objectid; |
1170 | } | 1226 | } |
1171 | 1227 | ||
1172 | |||
1173 | /* | 1228 | /* |
1174 | * process, that is going to call fix_nodes/do_balance must hold only | 1229 | * process, that is going to call fix_nodes/do_balance must hold only |
1175 | * one path. If it holds 2 or more, it can get into endless waiting in | 1230 | * one path. If it holds 2 or more, it can get into endless waiting in |
1176 | * get_empty_nodes or its clones | 1231 | * get_empty_nodes or its clones |
1177 | */ | 1232 | */ |
1178 | static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry, | 1233 | static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry, |
1179 | struct inode * new_dir, struct dentry *new_dentry) | 1234 | struct inode *new_dir, struct dentry *new_dentry) |
1180 | { | 1235 | { |
1181 | int retval; | 1236 | int retval; |
1182 | INITIALIZE_PATH (old_entry_path); | 1237 | INITIALIZE_PATH(old_entry_path); |
1183 | INITIALIZE_PATH (new_entry_path); | 1238 | INITIALIZE_PATH(new_entry_path); |
1184 | INITIALIZE_PATH (dot_dot_entry_path); | 1239 | INITIALIZE_PATH(dot_dot_entry_path); |
1185 | struct item_head new_entry_ih, old_entry_ih, dot_dot_ih ; | 1240 | struct item_head new_entry_ih, old_entry_ih, dot_dot_ih; |
1186 | struct reiserfs_dir_entry old_de, new_de, dot_dot_de; | 1241 | struct reiserfs_dir_entry old_de, new_de, dot_dot_de; |
1187 | struct inode * old_inode, * new_dentry_inode; | 1242 | struct inode *old_inode, *new_dentry_inode; |
1188 | struct reiserfs_transaction_handle th ; | 1243 | struct reiserfs_transaction_handle th; |
1189 | int jbegin_count ; | 1244 | int jbegin_count; |
1190 | umode_t old_inode_mode; | 1245 | umode_t old_inode_mode; |
1191 | unsigned long savelink = 1; | 1246 | unsigned long savelink = 1; |
1192 | struct timespec ctime; | 1247 | struct timespec ctime; |
1193 | 1248 | ||
1194 | /* three balancings: (1) old name removal, (2) new name insertion | 1249 | /* three balancings: (1) old name removal, (2) new name insertion |
1195 | and (3) maybe "save" link insertion | 1250 | and (3) maybe "save" link insertion |
1196 | stat data updates: (1) old directory, | 1251 | stat data updates: (1) old directory, |
1197 | (2) new directory and (3) maybe old object stat data (when it is | 1252 | (2) new directory and (3) maybe old object stat data (when it is |
1198 | directory) and (4) maybe stat data of object to which new entry | 1253 | directory) and (4) maybe stat data of object to which new entry |
1199 | pointed initially and (5) maybe block containing ".." of | 1254 | pointed initially and (5) maybe block containing ".." of |
1200 | renamed directory | 1255 | renamed directory |
1201 | quota updates: two parent directories */ | 1256 | quota updates: two parent directories */ |
1202 | jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 5 + 4 * REISERFS_QUOTA_TRANS_BLOCKS(old_dir->i_sb); | 1257 | jbegin_count = |
1203 | 1258 | JOURNAL_PER_BALANCE_CNT * 3 + 5 + | |
1204 | old_inode = old_dentry->d_inode; | 1259 | 4 * REISERFS_QUOTA_TRANS_BLOCKS(old_dir->i_sb); |
1205 | new_dentry_inode = new_dentry->d_inode; | 1260 | |
1206 | 1261 | old_inode = old_dentry->d_inode; | |
1207 | // make sure, that oldname still exists and points to an object we | 1262 | new_dentry_inode = new_dentry->d_inode; |
1208 | // are going to rename | 1263 | |
1209 | old_de.de_gen_number_bit_string = NULL; | 1264 | // make sure, that oldname still exists and points to an object we |
1210 | reiserfs_write_lock(old_dir->i_sb); | 1265 | // are going to rename |
1211 | retval = reiserfs_find_entry (old_dir, old_dentry->d_name.name, old_dentry->d_name.len, | 1266 | old_de.de_gen_number_bit_string = NULL; |
1212 | &old_entry_path, &old_de); | 1267 | reiserfs_write_lock(old_dir->i_sb); |
1213 | pathrelse (&old_entry_path); | 1268 | retval = |
1214 | if (retval == IO_ERROR) { | 1269 | reiserfs_find_entry(old_dir, old_dentry->d_name.name, |
1215 | reiserfs_write_unlock(old_dir->i_sb); | 1270 | old_dentry->d_name.len, &old_entry_path, |
1216 | return -EIO; | 1271 | &old_de); |
1217 | } | 1272 | pathrelse(&old_entry_path); |
1218 | 1273 | if (retval == IO_ERROR) { | |
1219 | if (retval != NAME_FOUND || old_de.de_objectid != old_inode->i_ino) { | ||
1220 | reiserfs_write_unlock(old_dir->i_sb); | ||
1221 | return -ENOENT; | ||
1222 | } | ||
1223 | |||
1224 | old_inode_mode = old_inode->i_mode; | ||
1225 | if (S_ISDIR(old_inode_mode)) { | ||
1226 | // make sure, that directory being renamed has correct ".." | ||
1227 | // and that its new parent directory has not too many links | ||
1228 | // already | ||
1229 | |||
1230 | if (new_dentry_inode) { | ||
1231 | if (!reiserfs_empty_dir(new_dentry_inode)) { | ||
1232 | reiserfs_write_unlock(old_dir->i_sb); | 1274 | reiserfs_write_unlock(old_dir->i_sb); |
1233 | return -ENOTEMPTY; | 1275 | return -EIO; |
1234 | } | ||
1235 | } | 1276 | } |
1236 | 1277 | ||
1237 | /* directory is renamed, its parent directory will be changed, | 1278 | if (retval != NAME_FOUND || old_de.de_objectid != old_inode->i_ino) { |
1238 | ** so find ".." entry | 1279 | reiserfs_write_unlock(old_dir->i_sb); |
1239 | */ | 1280 | return -ENOENT; |
1240 | dot_dot_de.de_gen_number_bit_string = NULL; | ||
1241 | retval = reiserfs_find_entry (old_inode, "..", 2, &dot_dot_entry_path, &dot_dot_de); | ||
1242 | pathrelse (&dot_dot_entry_path); | ||
1243 | if (retval != NAME_FOUND) { | ||
1244 | reiserfs_write_unlock(old_dir->i_sb); | ||
1245 | return -EIO; | ||
1246 | } | 1281 | } |
1247 | 1282 | ||
1248 | /* inode number of .. must equal old_dir->i_ino */ | 1283 | old_inode_mode = old_inode->i_mode; |
1249 | if (dot_dot_de.de_objectid != old_dir->i_ino) { | 1284 | if (S_ISDIR(old_inode_mode)) { |
1250 | reiserfs_write_unlock(old_dir->i_sb); | 1285 | // make sure, that directory being renamed has correct ".." |
1251 | return -EIO; | 1286 | // and that its new parent directory has not too many links |
1287 | // already | ||
1288 | |||
1289 | if (new_dentry_inode) { | ||
1290 | if (!reiserfs_empty_dir(new_dentry_inode)) { | ||
1291 | reiserfs_write_unlock(old_dir->i_sb); | ||
1292 | return -ENOTEMPTY; | ||
1293 | } | ||
1294 | } | ||
1295 | |||
1296 | /* directory is renamed, its parent directory will be changed, | ||
1297 | ** so find ".." entry | ||
1298 | */ | ||
1299 | dot_dot_de.de_gen_number_bit_string = NULL; | ||
1300 | retval = | ||
1301 | reiserfs_find_entry(old_inode, "..", 2, &dot_dot_entry_path, | ||
1302 | &dot_dot_de); | ||
1303 | pathrelse(&dot_dot_entry_path); | ||
1304 | if (retval != NAME_FOUND) { | ||
1305 | reiserfs_write_unlock(old_dir->i_sb); | ||
1306 | return -EIO; | ||
1307 | } | ||
1308 | |||
1309 | /* inode number of .. must equal old_dir->i_ino */ | ||
1310 | if (dot_dot_de.de_objectid != old_dir->i_ino) { | ||
1311 | reiserfs_write_unlock(old_dir->i_sb); | ||
1312 | return -EIO; | ||
1313 | } | ||
1252 | } | 1314 | } |
1253 | } | 1315 | |
1254 | 1316 | retval = journal_begin(&th, old_dir->i_sb, jbegin_count); | |
1255 | retval = journal_begin(&th, old_dir->i_sb, jbegin_count) ; | 1317 | if (retval) { |
1256 | if (retval) { | 1318 | reiserfs_write_unlock(old_dir->i_sb); |
1257 | reiserfs_write_unlock (old_dir->i_sb); | 1319 | return retval; |
1258 | return retval; | ||
1259 | } | ||
1260 | |||
1261 | /* add new entry (or find the existing one) */ | ||
1262 | retval = reiserfs_add_entry (&th, new_dir, new_dentry->d_name.name, new_dentry->d_name.len, | ||
1263 | old_inode, 0); | ||
1264 | if (retval == -EEXIST) { | ||
1265 | if (!new_dentry_inode) { | ||
1266 | reiserfs_panic (old_dir->i_sb, | ||
1267 | "vs-7050: new entry is found, new inode == 0\n"); | ||
1268 | } | 1320 | } |
1269 | } else if (retval) { | 1321 | |
1270 | int err = journal_end(&th, old_dir->i_sb, jbegin_count) ; | 1322 | /* add new entry (or find the existing one) */ |
1271 | reiserfs_write_unlock(old_dir->i_sb); | 1323 | retval = |
1272 | return err ? err : retval; | 1324 | reiserfs_add_entry(&th, new_dir, new_dentry->d_name.name, |
1273 | } | 1325 | new_dentry->d_name.len, old_inode, 0); |
1274 | 1326 | if (retval == -EEXIST) { | |
1275 | reiserfs_update_inode_transaction(old_dir) ; | 1327 | if (!new_dentry_inode) { |
1276 | reiserfs_update_inode_transaction(new_dir) ; | 1328 | reiserfs_panic(old_dir->i_sb, |
1277 | 1329 | "vs-7050: new entry is found, new inode == 0\n"); | |
1278 | /* this makes it so an fsync on an open fd for the old name will | 1330 | } |
1279 | ** commit the rename operation | 1331 | } else if (retval) { |
1280 | */ | 1332 | int err = journal_end(&th, old_dir->i_sb, jbegin_count); |
1281 | reiserfs_update_inode_transaction(old_inode) ; | 1333 | reiserfs_write_unlock(old_dir->i_sb); |
1282 | 1334 | return err ? err : retval; | |
1283 | if (new_dentry_inode) | ||
1284 | reiserfs_update_inode_transaction(new_dentry_inode) ; | ||
1285 | |||
1286 | while (1) { | ||
1287 | // look for old name using corresponding entry key (found by reiserfs_find_entry) | ||
1288 | if ((retval = search_by_entry_key (new_dir->i_sb, &old_de.de_entry_key, | ||
1289 | &old_entry_path, &old_de)) != NAME_FOUND) { | ||
1290 | pathrelse(&old_entry_path); | ||
1291 | journal_end(&th, old_dir->i_sb, jbegin_count); | ||
1292 | reiserfs_write_unlock(old_dir->i_sb); | ||
1293 | return -EIO; | ||
1294 | } | 1335 | } |
1295 | 1336 | ||
1296 | copy_item_head(&old_entry_ih, get_ih(&old_entry_path)) ; | 1337 | reiserfs_update_inode_transaction(old_dir); |
1297 | 1338 | reiserfs_update_inode_transaction(new_dir); | |
1298 | reiserfs_prepare_for_journal(old_inode->i_sb, old_de.de_bh, 1) ; | 1339 | |
1299 | 1340 | /* this makes it so an fsync on an open fd for the old name will | |
1300 | // look for new name by reiserfs_find_entry | 1341 | ** commit the rename operation |
1301 | new_de.de_gen_number_bit_string = NULL; | 1342 | */ |
1302 | retval = reiserfs_find_entry (new_dir, new_dentry->d_name.name, new_dentry->d_name.len, | 1343 | reiserfs_update_inode_transaction(old_inode); |
1303 | &new_entry_path, &new_de); | 1344 | |
1304 | // reiserfs_add_entry should not return IO_ERROR, because it is called with essentially same parameters from | 1345 | if (new_dentry_inode) |
1305 | // reiserfs_add_entry above, and we'll catch any i/o errors before we get here. | 1346 | reiserfs_update_inode_transaction(new_dentry_inode); |
1306 | if (retval != NAME_FOUND_INVISIBLE && retval != NAME_FOUND) { | 1347 | |
1307 | pathrelse(&new_entry_path); | 1348 | while (1) { |
1308 | pathrelse(&old_entry_path); | 1349 | // look for old name using corresponding entry key (found by reiserfs_find_entry) |
1309 | journal_end(&th, old_dir->i_sb, jbegin_count); | 1350 | if ((retval = |
1310 | reiserfs_write_unlock(old_dir->i_sb); | 1351 | search_by_entry_key(new_dir->i_sb, &old_de.de_entry_key, |
1311 | return -EIO; | 1352 | &old_entry_path, |
1353 | &old_de)) != NAME_FOUND) { | ||
1354 | pathrelse(&old_entry_path); | ||
1355 | journal_end(&th, old_dir->i_sb, jbegin_count); | ||
1356 | reiserfs_write_unlock(old_dir->i_sb); | ||
1357 | return -EIO; | ||
1358 | } | ||
1359 | |||
1360 | copy_item_head(&old_entry_ih, get_ih(&old_entry_path)); | ||
1361 | |||
1362 | reiserfs_prepare_for_journal(old_inode->i_sb, old_de.de_bh, 1); | ||
1363 | |||
1364 | // look for new name by reiserfs_find_entry | ||
1365 | new_de.de_gen_number_bit_string = NULL; | ||
1366 | retval = | ||
1367 | reiserfs_find_entry(new_dir, new_dentry->d_name.name, | ||
1368 | new_dentry->d_name.len, &new_entry_path, | ||
1369 | &new_de); | ||
1370 | // reiserfs_add_entry should not return IO_ERROR, because it is called with essentially same parameters from | ||
1371 | // reiserfs_add_entry above, and we'll catch any i/o errors before we get here. | ||
1372 | if (retval != NAME_FOUND_INVISIBLE && retval != NAME_FOUND) { | ||
1373 | pathrelse(&new_entry_path); | ||
1374 | pathrelse(&old_entry_path); | ||
1375 | journal_end(&th, old_dir->i_sb, jbegin_count); | ||
1376 | reiserfs_write_unlock(old_dir->i_sb); | ||
1377 | return -EIO; | ||
1378 | } | ||
1379 | |||
1380 | copy_item_head(&new_entry_ih, get_ih(&new_entry_path)); | ||
1381 | |||
1382 | reiserfs_prepare_for_journal(old_inode->i_sb, new_de.de_bh, 1); | ||
1383 | |||
1384 | if (S_ISDIR(old_inode->i_mode)) { | ||
1385 | if ((retval = | ||
1386 | search_by_entry_key(new_dir->i_sb, | ||
1387 | &dot_dot_de.de_entry_key, | ||
1388 | &dot_dot_entry_path, | ||
1389 | &dot_dot_de)) != NAME_FOUND) { | ||
1390 | pathrelse(&dot_dot_entry_path); | ||
1391 | pathrelse(&new_entry_path); | ||
1392 | pathrelse(&old_entry_path); | ||
1393 | journal_end(&th, old_dir->i_sb, jbegin_count); | ||
1394 | reiserfs_write_unlock(old_dir->i_sb); | ||
1395 | return -EIO; | ||
1396 | } | ||
1397 | copy_item_head(&dot_dot_ih, | ||
1398 | get_ih(&dot_dot_entry_path)); | ||
1399 | // node containing ".." gets into transaction | ||
1400 | reiserfs_prepare_for_journal(old_inode->i_sb, | ||
1401 | dot_dot_de.de_bh, 1); | ||
1402 | } | ||
1403 | /* we should check seals here, not do | ||
1404 | this stuff, yes? Then, having | ||
1405 | gathered everything into RAM we | ||
1406 | should lock the buffers, yes? -Hans */ | ||
1407 | /* probably. our rename needs to hold more | ||
1408 | ** than one path at once. The seals would | ||
1409 | ** have to be written to deal with multi-path | ||
1410 | ** issues -chris | ||
1411 | */ | ||
1412 | /* sanity checking before doing the rename - avoid races many | ||
1413 | ** of the above checks could have scheduled. We have to be | ||
1414 | ** sure our items haven't been shifted by another process. | ||
1415 | */ | ||
1416 | if (item_moved(&new_entry_ih, &new_entry_path) || | ||
1417 | !entry_points_to_object(new_dentry->d_name.name, | ||
1418 | new_dentry->d_name.len, | ||
1419 | &new_de, new_dentry_inode) || | ||
1420 | item_moved(&old_entry_ih, &old_entry_path) || | ||
1421 | !entry_points_to_object(old_dentry->d_name.name, | ||
1422 | old_dentry->d_name.len, | ||
1423 | &old_de, old_inode)) { | ||
1424 | reiserfs_restore_prepared_buffer(old_inode->i_sb, | ||
1425 | new_de.de_bh); | ||
1426 | reiserfs_restore_prepared_buffer(old_inode->i_sb, | ||
1427 | old_de.de_bh); | ||
1428 | if (S_ISDIR(old_inode_mode)) | ||
1429 | reiserfs_restore_prepared_buffer(old_inode-> | ||
1430 | i_sb, | ||
1431 | dot_dot_de. | ||
1432 | de_bh); | ||
1433 | continue; | ||
1434 | } | ||
1435 | if (S_ISDIR(old_inode_mode)) { | ||
1436 | if (item_moved(&dot_dot_ih, &dot_dot_entry_path) || | ||
1437 | !entry_points_to_object("..", 2, &dot_dot_de, | ||
1438 | old_dir)) { | ||
1439 | reiserfs_restore_prepared_buffer(old_inode-> | ||
1440 | i_sb, | ||
1441 | old_de.de_bh); | ||
1442 | reiserfs_restore_prepared_buffer(old_inode-> | ||
1443 | i_sb, | ||
1444 | new_de.de_bh); | ||
1445 | reiserfs_restore_prepared_buffer(old_inode-> | ||
1446 | i_sb, | ||
1447 | dot_dot_de. | ||
1448 | de_bh); | ||
1449 | continue; | ||
1450 | } | ||
1451 | } | ||
1452 | |||
1453 | RFALSE(S_ISDIR(old_inode_mode) && | ||
1454 | !buffer_journal_prepared(dot_dot_de.de_bh), ""); | ||
1455 | |||
1456 | break; | ||
1312 | } | 1457 | } |
1313 | 1458 | ||
1314 | copy_item_head(&new_entry_ih, get_ih(&new_entry_path)) ; | 1459 | /* ok, all the changes can be done in one fell swoop when we |
1460 | have claimed all the buffers needed. */ | ||
1315 | 1461 | ||
1316 | reiserfs_prepare_for_journal(old_inode->i_sb, new_de.de_bh, 1) ; | 1462 | mark_de_visible(new_de.de_deh + new_de.de_entry_num); |
1463 | set_ino_in_dir_entry(&new_de, INODE_PKEY(old_inode)); | ||
1464 | journal_mark_dirty(&th, old_dir->i_sb, new_de.de_bh); | ||
1317 | 1465 | ||
1318 | if (S_ISDIR(old_inode->i_mode)) { | 1466 | mark_de_hidden(old_de.de_deh + old_de.de_entry_num); |
1319 | if ((retval = search_by_entry_key (new_dir->i_sb, &dot_dot_de.de_entry_key, | 1467 | journal_mark_dirty(&th, old_dir->i_sb, old_de.de_bh); |
1320 | &dot_dot_entry_path, &dot_dot_de)) != NAME_FOUND) { | 1468 | ctime = CURRENT_TIME_SEC; |
1321 | pathrelse(&dot_dot_entry_path); | 1469 | old_dir->i_ctime = old_dir->i_mtime = ctime; |
1322 | pathrelse(&new_entry_path); | 1470 | new_dir->i_ctime = new_dir->i_mtime = ctime; |
1323 | pathrelse(&old_entry_path); | 1471 | /* thanks to Alex Adriaanse <alex_a@caltech.edu> for patch which adds ctime update of |
1324 | journal_end(&th, old_dir->i_sb, jbegin_count); | 1472 | renamed object */ |
1325 | reiserfs_write_unlock(old_dir->i_sb); | 1473 | old_inode->i_ctime = ctime; |
1326 | return -EIO; | 1474 | |
1327 | } | 1475 | if (new_dentry_inode) { |
1328 | copy_item_head(&dot_dot_ih, get_ih(&dot_dot_entry_path)) ; | 1476 | // adjust link number of the victim |
1329 | // node containing ".." gets into transaction | 1477 | if (S_ISDIR(new_dentry_inode->i_mode)) { |
1330 | reiserfs_prepare_for_journal(old_inode->i_sb, dot_dot_de.de_bh, 1) ; | 1478 | new_dentry_inode->i_nlink = 0; |
1331 | } | 1479 | } else { |
1332 | /* we should check seals here, not do | 1480 | new_dentry_inode->i_nlink--; |
1333 | this stuff, yes? Then, having | 1481 | } |
1334 | gathered everything into RAM we | 1482 | new_dentry_inode->i_ctime = ctime; |
1335 | should lock the buffers, yes? -Hans */ | 1483 | savelink = new_dentry_inode->i_nlink; |
1336 | /* probably. our rename needs to hold more | ||
1337 | ** than one path at once. The seals would | ||
1338 | ** have to be written to deal with multi-path | ||
1339 | ** issues -chris | ||
1340 | */ | ||
1341 | /* sanity checking before doing the rename - avoid races many | ||
1342 | ** of the above checks could have scheduled. We have to be | ||
1343 | ** sure our items haven't been shifted by another process. | ||
1344 | */ | ||
1345 | if (item_moved(&new_entry_ih, &new_entry_path) || | ||
1346 | !entry_points_to_object(new_dentry->d_name.name, | ||
1347 | new_dentry->d_name.len, | ||
1348 | &new_de, new_dentry_inode) || | ||
1349 | item_moved(&old_entry_ih, &old_entry_path) || | ||
1350 | !entry_points_to_object (old_dentry->d_name.name, | ||
1351 | old_dentry->d_name.len, | ||
1352 | &old_de, old_inode)) { | ||
1353 | reiserfs_restore_prepared_buffer (old_inode->i_sb, new_de.de_bh); | ||
1354 | reiserfs_restore_prepared_buffer (old_inode->i_sb, old_de.de_bh); | ||
1355 | if (S_ISDIR(old_inode_mode)) | ||
1356 | reiserfs_restore_prepared_buffer (old_inode->i_sb, dot_dot_de.de_bh); | ||
1357 | continue; | ||
1358 | } | 1484 | } |
1485 | |||
1359 | if (S_ISDIR(old_inode_mode)) { | 1486 | if (S_ISDIR(old_inode_mode)) { |
1360 | if ( item_moved(&dot_dot_ih, &dot_dot_entry_path) || | 1487 | // adjust ".." of renamed directory |
1361 | !entry_points_to_object ( "..", 2, &dot_dot_de, old_dir) ) { | 1488 | set_ino_in_dir_entry(&dot_dot_de, INODE_PKEY(new_dir)); |
1362 | reiserfs_restore_prepared_buffer (old_inode->i_sb, old_de.de_bh); | 1489 | journal_mark_dirty(&th, new_dir->i_sb, dot_dot_de.de_bh); |
1363 | reiserfs_restore_prepared_buffer (old_inode->i_sb, new_de.de_bh); | 1490 | |
1364 | reiserfs_restore_prepared_buffer (old_inode->i_sb, dot_dot_de.de_bh); | 1491 | if (!new_dentry_inode) |
1365 | continue; | 1492 | /* there (in new_dir) was no directory, so it got new link |
1366 | } | 1493 | (".." of renamed directory) */ |
1494 | INC_DIR_INODE_NLINK(new_dir); | ||
1495 | |||
1496 | /* old directory lost one link - ".. " of renamed directory */ | ||
1497 | DEC_DIR_INODE_NLINK(old_dir); | ||
1367 | } | 1498 | } |
1499 | // looks like in 2.3.99pre3 brelse is atomic. so we can use pathrelse | ||
1500 | pathrelse(&new_entry_path); | ||
1501 | pathrelse(&dot_dot_entry_path); | ||
1368 | 1502 | ||
1369 | RFALSE( S_ISDIR(old_inode_mode) && | 1503 | // FIXME: this reiserfs_cut_from_item's return value may screw up |
1370 | !buffer_journal_prepared(dot_dot_de.de_bh), "" ); | 1504 | // anybody, but it will panic if will not be able to find the |
1371 | 1505 | // entry. This needs one more clean up | |
1372 | break; | 1506 | if (reiserfs_cut_from_item |
1373 | } | 1507 | (&th, &old_entry_path, &(old_de.de_entry_key), old_dir, NULL, |
1374 | 1508 | 0) < 0) | |
1375 | /* ok, all the changes can be done in one fell swoop when we | 1509 | reiserfs_warning(old_dir->i_sb, |
1376 | have claimed all the buffers needed.*/ | 1510 | "vs-7060: reiserfs_rename: couldn't not cut old name. Fsck later?"); |
1377 | 1511 | ||
1378 | mark_de_visible (new_de.de_deh + new_de.de_entry_num); | 1512 | old_dir->i_size -= DEH_SIZE + old_de.de_entrylen; |
1379 | set_ino_in_dir_entry (&new_de, INODE_PKEY (old_inode)); | 1513 | |
1380 | journal_mark_dirty (&th, old_dir->i_sb, new_de.de_bh); | 1514 | reiserfs_update_sd(&th, old_dir); |
1381 | 1515 | reiserfs_update_sd(&th, new_dir); | |
1382 | mark_de_hidden (old_de.de_deh + old_de.de_entry_num); | 1516 | reiserfs_update_sd(&th, old_inode); |
1383 | journal_mark_dirty (&th, old_dir->i_sb, old_de.de_bh); | 1517 | |
1384 | ctime = CURRENT_TIME_SEC; | 1518 | if (new_dentry_inode) { |
1385 | old_dir->i_ctime = old_dir->i_mtime = ctime; | 1519 | if (savelink == 0) |
1386 | new_dir->i_ctime = new_dir->i_mtime = ctime; | 1520 | add_save_link(&th, new_dentry_inode, |
1387 | /* thanks to Alex Adriaanse <alex_a@caltech.edu> for patch which adds ctime update of | 1521 | 0 /* not truncate */ ); |
1388 | renamed object */ | 1522 | reiserfs_update_sd(&th, new_dentry_inode); |
1389 | old_inode->i_ctime = ctime; | ||
1390 | |||
1391 | if (new_dentry_inode) { | ||
1392 | // adjust link number of the victim | ||
1393 | if (S_ISDIR(new_dentry_inode->i_mode)) { | ||
1394 | new_dentry_inode->i_nlink = 0; | ||
1395 | } else { | ||
1396 | new_dentry_inode->i_nlink--; | ||
1397 | } | 1523 | } |
1398 | new_dentry_inode->i_ctime = ctime; | 1524 | |
1399 | savelink = new_dentry_inode->i_nlink; | 1525 | retval = journal_end(&th, old_dir->i_sb, jbegin_count); |
1400 | } | 1526 | reiserfs_write_unlock(old_dir->i_sb); |
1401 | 1527 | return retval; | |
1402 | if (S_ISDIR(old_inode_mode)) { | ||
1403 | // adjust ".." of renamed directory | ||
1404 | set_ino_in_dir_entry (&dot_dot_de, INODE_PKEY (new_dir)); | ||
1405 | journal_mark_dirty (&th, new_dir->i_sb, dot_dot_de.de_bh); | ||
1406 | |||
1407 | if (!new_dentry_inode) | ||
1408 | /* there (in new_dir) was no directory, so it got new link | ||
1409 | (".." of renamed directory) */ | ||
1410 | INC_DIR_INODE_NLINK(new_dir); | ||
1411 | |||
1412 | /* old directory lost one link - ".. " of renamed directory */ | ||
1413 | DEC_DIR_INODE_NLINK(old_dir); | ||
1414 | } | ||
1415 | |||
1416 | // looks like in 2.3.99pre3 brelse is atomic. so we can use pathrelse | ||
1417 | pathrelse (&new_entry_path); | ||
1418 | pathrelse (&dot_dot_entry_path); | ||
1419 | |||
1420 | // FIXME: this reiserfs_cut_from_item's return value may screw up | ||
1421 | // anybody, but it will panic if will not be able to find the | ||
1422 | // entry. This needs one more clean up | ||
1423 | if (reiserfs_cut_from_item (&th, &old_entry_path, &(old_de.de_entry_key), old_dir, NULL, 0) < 0) | ||
1424 | reiserfs_warning (old_dir->i_sb, "vs-7060: reiserfs_rename: couldn't not cut old name. Fsck later?"); | ||
1425 | |||
1426 | old_dir->i_size -= DEH_SIZE + old_de.de_entrylen; | ||
1427 | |||
1428 | reiserfs_update_sd (&th, old_dir); | ||
1429 | reiserfs_update_sd (&th, new_dir); | ||
1430 | reiserfs_update_sd (&th, old_inode); | ||
1431 | |||
1432 | if (new_dentry_inode) { | ||
1433 | if (savelink == 0) | ||
1434 | add_save_link (&th, new_dentry_inode, 0/* not truncate */); | ||
1435 | reiserfs_update_sd (&th, new_dentry_inode); | ||
1436 | } | ||
1437 | |||
1438 | retval = journal_end(&th, old_dir->i_sb, jbegin_count) ; | ||
1439 | reiserfs_write_unlock(old_dir->i_sb); | ||
1440 | return retval; | ||
1441 | } | 1528 | } |
1442 | 1529 | ||
1443 | /* | 1530 | /* |
1444 | * directories can handle most operations... | 1531 | * directories can handle most operations... |
1445 | */ | 1532 | */ |
1446 | struct inode_operations reiserfs_dir_inode_operations = { | 1533 | struct inode_operations reiserfs_dir_inode_operations = { |
1447 | //&reiserfs_dir_operations, /* default_file_ops */ | 1534 | //&reiserfs_dir_operations, /* default_file_ops */ |
1448 | .create = reiserfs_create, | 1535 | .create = reiserfs_create, |
1449 | .lookup = reiserfs_lookup, | 1536 | .lookup = reiserfs_lookup, |
1450 | .link = reiserfs_link, | 1537 | .link = reiserfs_link, |
1451 | .unlink = reiserfs_unlink, | 1538 | .unlink = reiserfs_unlink, |
1452 | .symlink = reiserfs_symlink, | 1539 | .symlink = reiserfs_symlink, |
1453 | .mkdir = reiserfs_mkdir, | 1540 | .mkdir = reiserfs_mkdir, |
1454 | .rmdir = reiserfs_rmdir, | 1541 | .rmdir = reiserfs_rmdir, |
1455 | .mknod = reiserfs_mknod, | 1542 | .mknod = reiserfs_mknod, |
1456 | .rename = reiserfs_rename, | 1543 | .rename = reiserfs_rename, |
1457 | .setattr = reiserfs_setattr, | 1544 | .setattr = reiserfs_setattr, |
1458 | .setxattr = reiserfs_setxattr, | 1545 | .setxattr = reiserfs_setxattr, |
1459 | .getxattr = reiserfs_getxattr, | 1546 | .getxattr = reiserfs_getxattr, |
1460 | .listxattr = reiserfs_listxattr, | 1547 | .listxattr = reiserfs_listxattr, |
1461 | .removexattr = reiserfs_removexattr, | 1548 | .removexattr = reiserfs_removexattr, |
1462 | .permission = reiserfs_permission, | 1549 | .permission = reiserfs_permission, |
1463 | }; | 1550 | }; |
1464 | 1551 | ||
1465 | /* | 1552 | /* |
@@ -1467,28 +1554,27 @@ struct inode_operations reiserfs_dir_inode_operations = { | |||
1467 | * stuff added | 1554 | * stuff added |
1468 | */ | 1555 | */ |
1469 | struct inode_operations reiserfs_symlink_inode_operations = { | 1556 | struct inode_operations reiserfs_symlink_inode_operations = { |
1470 | .readlink = generic_readlink, | 1557 | .readlink = generic_readlink, |
1471 | .follow_link = page_follow_link_light, | 1558 | .follow_link = page_follow_link_light, |
1472 | .put_link = page_put_link, | 1559 | .put_link = page_put_link, |
1473 | .setattr = reiserfs_setattr, | 1560 | .setattr = reiserfs_setattr, |
1474 | .setxattr = reiserfs_setxattr, | 1561 | .setxattr = reiserfs_setxattr, |
1475 | .getxattr = reiserfs_getxattr, | 1562 | .getxattr = reiserfs_getxattr, |
1476 | .listxattr = reiserfs_listxattr, | 1563 | .listxattr = reiserfs_listxattr, |
1477 | .removexattr = reiserfs_removexattr, | 1564 | .removexattr = reiserfs_removexattr, |
1478 | .permission = reiserfs_permission, | 1565 | .permission = reiserfs_permission, |
1479 | 1566 | ||
1480 | }; | 1567 | }; |
1481 | 1568 | ||
1482 | |||
1483 | /* | 1569 | /* |
1484 | * special file operations.. just xattr/acl stuff | 1570 | * special file operations.. just xattr/acl stuff |
1485 | */ | 1571 | */ |
1486 | struct inode_operations reiserfs_special_inode_operations = { | 1572 | struct inode_operations reiserfs_special_inode_operations = { |
1487 | .setattr = reiserfs_setattr, | 1573 | .setattr = reiserfs_setattr, |
1488 | .setxattr = reiserfs_setxattr, | 1574 | .setxattr = reiserfs_setxattr, |
1489 | .getxattr = reiserfs_getxattr, | 1575 | .getxattr = reiserfs_getxattr, |
1490 | .listxattr = reiserfs_listxattr, | 1576 | .listxattr = reiserfs_listxattr, |
1491 | .removexattr = reiserfs_removexattr, | 1577 | .removexattr = reiserfs_removexattr, |
1492 | .permission = reiserfs_permission, | 1578 | .permission = reiserfs_permission, |
1493 | 1579 | ||
1494 | }; | 1580 | }; |