1 /*
2  * Copyright 2000-2002 by Hans Reiser, licensing governed by reiserfs/README
3  */
4 
5 #include <linux/config.h>
6 #include <linux/sched.h>
7 #include <linux/bitops.h>
8 #include <linux/reiserfs_fs.h>
9 #include <linux/smp_lock.h>
10 
11 #define INC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) { i->i_nlink++; if (i->i_nlink >= REISERFS_LINK_MAX) i->i_nlink=1; }
12 #define DEC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) i->i_nlink--;
13 
14 // directory item contains array of entry headers. This performs
15 // binary search through that array
bin_search_in_dir_item(struct reiserfs_dir_entry * de,loff_t off)16 static int bin_search_in_dir_item (struct reiserfs_dir_entry * de, loff_t off)
17 {
18     struct item_head * ih = de->de_ih;
19     struct reiserfs_de_head * deh = de->de_deh;
20     int rbound, lbound, j;
21 
22     lbound = 0;
23     rbound = I_ENTRY_COUNT (ih) - 1;
24 
25     for (j = (rbound + lbound) / 2; lbound <= rbound; j = (rbound + lbound) / 2) {
26 	if (off < deh_offset (deh + j)) {
27 	    rbound = j - 1;
28 	    continue;
29 	}
30 	if (off > deh_offset (deh + j)) {
31 	    lbound = j + 1;
32 	    continue;
33 	}
34 	// this is not name found, but matched third key component
35 	de->de_entry_num = j;
36 	return NAME_FOUND;
37     }
38 
39     de->de_entry_num = lbound;
40     return NAME_NOT_FOUND;
41 }
42 
43 
44 // comment?  maybe something like set de to point to what the path points to?
set_de_item_location(struct reiserfs_dir_entry * de,struct path * path)45 static inline void set_de_item_location (struct reiserfs_dir_entry * de, struct path * path)
46 {
47     de->de_bh = get_last_bh (path);
48     de->de_ih = get_ih (path);
49     de->de_deh = B_I_DEH (de->de_bh, de->de_ih);
50     de->de_item_num = PATH_LAST_POSITION (path);
51 }
52 
53 
54 // de_bh, de_ih, de_deh (points to first element of array), de_item_num is set
set_de_name_and_namelen(struct reiserfs_dir_entry * de)55 inline void set_de_name_and_namelen (struct reiserfs_dir_entry * de)
56 {
57     struct reiserfs_de_head * deh = de->de_deh + de->de_entry_num;
58 
59     if (de->de_entry_num >= ih_entry_count (de->de_ih))
60 	BUG ();
61 
62     de->de_entrylen = entry_length (de->de_bh, de->de_ih, de->de_entry_num);
63     de->de_namelen = de->de_entrylen - (de_with_sd (deh) ? SD_SIZE : 0);
64     de->de_name = B_I_PITEM (de->de_bh, de->de_ih) + deh_location(deh);
65     if (de->de_name[de->de_namelen - 1] == 0)
66 	de->de_namelen = strlen (de->de_name);
67 }
68 
69 
70 // what entry points to
set_de_object_key(struct reiserfs_dir_entry * de)71 static inline void set_de_object_key (struct reiserfs_dir_entry * de)
72 {
73     if (de->de_entry_num >= ih_entry_count (de->de_ih))
74 	BUG ();
75     de->de_dir_id = deh_dir_id( &(de->de_deh[de->de_entry_num]));
76     de->de_objectid = deh_objectid( &(de->de_deh[de->de_entry_num]));
77 }
78 
79 
store_de_entry_key(struct reiserfs_dir_entry * de)80 static inline void store_de_entry_key (struct reiserfs_dir_entry * de)
81 {
82     struct reiserfs_de_head * deh = de->de_deh + de->de_entry_num;
83 
84     if (de->de_entry_num >= ih_entry_count (de->de_ih))
85 	BUG ();
86 
87     /* store key of the found entry */
88     de->de_entry_key.version = KEY_FORMAT_3_5;
89     de->de_entry_key.on_disk_key.k_dir_id = le32_to_cpu (de->de_ih->ih_key.k_dir_id);
90     de->de_entry_key.on_disk_key.k_objectid = le32_to_cpu (de->de_ih->ih_key.k_objectid);
91     set_cpu_key_k_offset (&(de->de_entry_key), deh_offset (deh));
92     set_cpu_key_k_type (&(de->de_entry_key), TYPE_DIRENTRY);
93 }
94 
95 
96 /* We assign a key to each directory item, and place multiple entries
97 in a single directory item.  A directory item has a key equal to the
98 key of the first directory entry in it.
99 
100 This function first calls search_by_key, then, if item whose first
101 entry matches is not found it looks for the entry inside directory
102 item found by search_by_key. Fills the path to the entry, and to the
103 entry position in the item
104 
105 */
106 
107 /* The function is NOT SCHEDULE-SAFE! */
search_by_entry_key(struct super_block * sb,const struct cpu_key * key,struct path * path,struct reiserfs_dir_entry * de)108 int search_by_entry_key (struct super_block * sb, const struct cpu_key * key,
109 			 struct path * path, struct reiserfs_dir_entry * de)
110 {
111     int retval;
112 
113     retval = search_item (sb, key, path);
114     switch (retval) {
115     case ITEM_NOT_FOUND:
116 	if (!PATH_LAST_POSITION (path)) {
117 	    reiserfs_warning (sb, "vs-7000: search_by_entry_key: search_by_key returned item position == 0\n");
118 	    pathrelse(path) ;
119 	    return IO_ERROR ;
120 	}
121 	PATH_LAST_POSITION (path) --;
122 
123     case ITEM_FOUND:
124 	break;
125 
126     case IO_ERROR:
127 	return retval;
128 
129     default:
130 	pathrelse (path);
131 	reiserfs_warning (sb, "vs-7002: search_by_entry_key: no path to here\n ");
132 	return IO_ERROR;
133     }
134 
135     set_de_item_location (de, path);
136 
137 #ifdef CONFIG_REISERFS_CHECK
138     if (!is_direntry_le_ih (de->de_ih) ||
139 	COMP_SHORT_KEYS (&(de->de_ih->ih_key), key)) {
140 	print_block (de->de_bh, 0, -1, -1);
141 	reiserfs_panic (sb, "vs-7005: search_by_entry_key: found item %h is not directory item or "
142                         "does not belong to the same directory as key %K", de->de_ih, key);
143     }
144 #endif /* CONFIG_REISERFS_CHECK */
145 
146     /* binary search in directory item by third componen t of the
147        key. sets de->de_entry_num of de */
148     retval = bin_search_in_dir_item (de, cpu_key_k_offset (key));
149     path->pos_in_item = de->de_entry_num;
150     if (retval != NAME_NOT_FOUND) {
151 	// ugly, but rename needs de_bh, de_deh, de_name, de_namelen, de_objectid set
152 	set_de_name_and_namelen (de);
153 	set_de_object_key (de);
154     }
155     return retval;
156 }
157 
158 
159 
160 /* Keyed 32-bit hash function using TEA in a Davis-Meyer function */
161 
162 /* The third component is hashed, and you can choose from more than
163    one hash function.  Per directory hashes are not yet implemented
164    but are thought about. This function should be moved to hashes.c
165    Jedi, please do so.  -Hans */
166 
get_third_component(struct super_block * s,const char * name,int len)167 static __u32 get_third_component (struct super_block * s,
168 				  const char * name, int len)
169 {
170     __u32 res;
171 
172     if (!len || (len == 1 && name[0] == '.'))
173 	return DOT_OFFSET;
174     if (len == 2 && name[0] == '.' && name[1] == '.')
175 	return DOT_DOT_OFFSET;
176 
177     res = s->u.reiserfs_sb.s_hash_function (name, len);
178 
179     // take bits from 7-th to 30-th including both bounds
180     res = GET_HASH_VALUE(res);
181     if (res == 0)
182 	// needed to have no names before "." and ".." those have hash
183 	// value == 0 and generation conters 1 and 2 accordingly
184 	res = 128;
185     return res + MAX_GENERATION_NUMBER;
186 }
187 
188 
reiserfs_match(struct reiserfs_dir_entry * de,const char * name,int namelen)189 static int reiserfs_match (struct reiserfs_dir_entry * de,
190 			   const char * name, int namelen)
191 {
192     int retval = NAME_NOT_FOUND;
193 
194     if ((namelen == de->de_namelen) &&
195 	!memcmp(de->de_name, name, de->de_namelen))
196 	retval = (de_visible (de->de_deh + de->de_entry_num) ? NAME_FOUND : NAME_FOUND_INVISIBLE);
197 
198     return retval;
199 }
200 
201 
202 /* de's de_bh, de_ih, de_deh, de_item_num, de_entry_num are set already */
203 
204 				/* used when hash collisions exist */
205 
206 
linear_search_in_dir_item(struct cpu_key * key,struct reiserfs_dir_entry * de,const char * name,int namelen)207 static int linear_search_in_dir_item (struct cpu_key * key, struct reiserfs_dir_entry * de,
208 				      const char * name, int namelen)
209 {
210     struct reiserfs_de_head * deh = de->de_deh;
211     int retval;
212     int i;
213 
214     i = de->de_entry_num;
215 
216     if (i == I_ENTRY_COUNT (de->de_ih) ||
217 	GET_HASH_VALUE (deh_offset (deh + i)) != GET_HASH_VALUE (cpu_key_k_offset (key))) {
218 	i --;
219     }
220 
221     RFALSE( de->de_deh != B_I_DEH (de->de_bh, de->de_ih),
222 	    "vs-7010: array of entry headers not found");
223 
224     deh += i;
225 
226     for (; i >= 0; i --, deh --) {
227 	if (GET_HASH_VALUE (deh_offset (deh)) !=
228 	    GET_HASH_VALUE (cpu_key_k_offset (key))) {
229 	    // hash value does not match, no need to check whole name
230 	    return NAME_NOT_FOUND;
231 	}
232 
233 	/* mark, that this generation number is used */
234 	if (de->de_gen_number_bit_string)
235 	    set_bit (GET_GENERATION_NUMBER (deh_offset (deh)), (unsigned long *)de->de_gen_number_bit_string);
236 
237 	// calculate pointer to name and namelen
238 	de->de_entry_num = i;
239 	set_de_name_and_namelen (de);
240 
241 	if ((retval = reiserfs_match (de, name, namelen)) != NAME_NOT_FOUND) {
242 	    // de's de_name, de_namelen, de_recordlen are set. Fill the rest:
243 
244 	    // key of pointed object
245 	    set_de_object_key (de);
246 
247 	    store_de_entry_key (de);
248 
249 	    // retval can be NAME_FOUND or NAME_FOUND_INVISIBLE
250 	    return retval;
251 	}
252     }
253 
254     if (GET_GENERATION_NUMBER (le_ih_k_offset (de->de_ih)) == 0)
255 	/* we have reached left most entry in the node. In common we
256            have to go to the left neighbor, but if generation counter
257            is 0 already, we know for sure, that there is no name with
258            the same hash value */
259 	// FIXME: this work correctly only because hash value can not
260 	// be 0. Btw, in case of Yura's hash it is probably possible,
261 	// so, this is a bug
262 	return NAME_NOT_FOUND;
263 
264     RFALSE( de->de_item_num,
265 	    "vs-7015: two diritems of the same directory in one node?");
266 
267     return GOTO_PREVIOUS_ITEM;
268 }
269 
270 
271 // may return NAME_FOUND, NAME_FOUND_INVISIBLE, NAME_NOT_FOUND
272 // FIXME: should add something like IOERROR
reiserfs_find_entry(struct inode * dir,const char * name,int namelen,struct path * path_to_entry,struct reiserfs_dir_entry * de)273 static int reiserfs_find_entry (struct inode * dir, const char * name, int namelen,
274 				struct path * path_to_entry, struct reiserfs_dir_entry * de)
275 {
276     struct cpu_key key_to_search;
277     int retval;
278 
279 
280     if (namelen > REISERFS_MAX_NAME (dir->i_sb->s_blocksize))
281 	return NAME_NOT_FOUND;
282 
283     /* we will search for this key in the tree */
284     make_cpu_key (&key_to_search, dir,
285 		  get_third_component (dir->i_sb, name, namelen), TYPE_DIRENTRY, 3);
286 
287     while (1) {
288 	retval = search_by_entry_key (dir->i_sb, &key_to_search, path_to_entry, de);
289 	if (retval == IO_ERROR) {
290 	    reiserfs_warning (dir->i_sb, "zam-7001: io error in %s\n", __FUNCTION__);
291 	    return IO_ERROR;
292 	}
293 
294 	/* compare names for all entries having given hash value */
295 	retval = linear_search_in_dir_item (&key_to_search, de, name, namelen);
296 	if (retval != GOTO_PREVIOUS_ITEM) {
297 	    /* there is no need to scan directory anymore. Given entry found or does not exist */
298 	    path_to_entry->pos_in_item = de->de_entry_num;
299 	    return retval;
300 	}
301 
302 	/* there is left neighboring item of this directory and given entry can be there */
303 	set_cpu_key_k_offset (&key_to_search, le_ih_k_offset (de->de_ih) - 1);
304 	pathrelse (path_to_entry);
305 
306     } /* while (1) */
307 }
308 
309 
reiserfs_lookup(struct inode * dir,struct dentry * dentry)310 static struct dentry * reiserfs_lookup (struct inode * dir, struct dentry * dentry)
311 {
312     int retval;
313     struct inode * inode = NULL;
314     struct reiserfs_dir_entry de;
315     INITIALIZE_PATH (path_to_entry);
316 
317     reiserfs_check_lock_depth("lookup") ;
318 
319     if (REISERFS_MAX_NAME (dir->i_sb->s_blocksize) < dentry->d_name.len)
320 	return ERR_PTR(-ENAMETOOLONG);
321 
322     de.de_gen_number_bit_string = 0;
323     retval = reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path_to_entry, &de);
324     pathrelse (&path_to_entry);
325     if (retval == NAME_FOUND) {
326 	inode = reiserfs_iget (dir->i_sb, (struct cpu_key *)&(de.de_dir_id));
327 	if (!inode || IS_ERR(inode)) {
328 	    return ERR_PTR(-EACCES);
329         }
330     }
331     if ( retval == IO_ERROR ) {
332 	return ERR_PTR(-EIO);
333     }
334 
335     d_add(dentry, inode);
336     return NULL;
337 }
338 
339 /* add entry to the directory (entry can be hidden).
340 
341 insert definition of when hidden directories are used here -Hans
342 
343  Does not mark dir   inode dirty, do it after successesfull call to it */
344 
reiserfs_add_entry(struct reiserfs_transaction_handle * th,struct inode * dir,const char * name,int namelen,struct inode * inode,int visible)345 static int reiserfs_add_entry (struct reiserfs_transaction_handle *th, struct inode * dir,
346                                const char * name, int namelen, struct inode * inode,
347 			       int visible)
348 {
349     struct cpu_key entry_key;
350     struct reiserfs_de_head * deh;
351     INITIALIZE_PATH (path);
352     struct reiserfs_dir_entry de;
353     int bit_string [MAX_GENERATION_NUMBER / (sizeof(int) * 8) + 1];
354     int gen_number;
355     char small_buf[32+DEH_SIZE] ; /* 48 bytes now and we avoid kmalloc
356                                      if we create file with short name */
357     char * buffer;
358     int buflen, paste_size;
359     int retval;
360 
361 
362     /* cannot allow items to be added into a busy deleted directory */
363     if (!namelen)
364 	return -EINVAL;
365 
366     if (namelen > REISERFS_MAX_NAME (dir->i_sb->s_blocksize))
367 	return -ENAMETOOLONG;
368 
369     /* each entry has unique key. compose it */
370     make_cpu_key (&entry_key, dir,
371 		  get_third_component (dir->i_sb, name, namelen), TYPE_DIRENTRY, 3);
372 
373     /* get memory for composing the entry */
374     buflen = DEH_SIZE + ROUND_UP (namelen);
375     if (buflen > sizeof (small_buf)) {
376 	buffer = reiserfs_kmalloc (buflen, GFP_NOFS, dir->i_sb);
377 	if (buffer == 0)
378 	    return -ENOMEM;
379     } else
380 	buffer = small_buf;
381 
382     paste_size = (get_inode_sd_version (dir) == STAT_DATA_V1) ? (DEH_SIZE + namelen) : buflen;
383 
384     /* fill buffer : directory entry head, name[, dir objectid | , stat data | ,stat data, dir objectid ] */
385     deh = (struct reiserfs_de_head *)buffer;
386     deh->deh_location = 0; /* JDM Endian safe if 0 */
387     put_deh_offset( deh, cpu_key_k_offset( &entry_key ) );
388     deh->deh_state = 0; /* JDM Endian safe if 0 */
389     /* put key (ino analog) to de */
390     deh->deh_dir_id = INODE_PKEY (inode)->k_dir_id; /* safe: k_dir_id is le */
391     deh->deh_objectid = INODE_PKEY (inode)->k_objectid; /* safe: k_objectid is le */
392 
393     /* copy name */
394     memcpy ((char *)(deh + 1), name, namelen);
395     /* padd by 0s to the 4 byte boundary */
396     padd_item ((char *)(deh + 1), ROUND_UP (namelen), namelen);
397 
398     /* entry is ready to be pasted into tree, set 'visibility' and 'stat data in entry' attributes */
399     mark_de_without_sd (deh);
400     visible ? mark_de_visible (deh) : mark_de_hidden (deh);
401 
402     /* find the proper place for the new entry */
403     memset (bit_string, 0, sizeof (bit_string));
404     de.de_gen_number_bit_string = (char *)bit_string;
405     retval = reiserfs_find_entry (dir, name, namelen, &path, &de);
406     if( retval != NAME_NOT_FOUND ) {
407 	if (buffer != small_buf)
408 	    reiserfs_kfree (buffer, buflen, dir->i_sb);
409 	pathrelse (&path);
410 
411 	if ( retval == IO_ERROR ) {
412 	    return -EIO;
413 	}
414 
415         if (retval != NAME_FOUND) {
416 	    reiserfs_warning (dir->i_sb, "zam-7002:%s: \"reiserfs_find_entry\" has returned"
417                               " unexpected value (%d)\n", __FUNCTION__, retval);
418        }
419 
420 	return -EEXIST;
421     }
422 
423     gen_number = find_first_zero_bit ((unsigned long *)bit_string, MAX_GENERATION_NUMBER + 1);
424     if (gen_number > MAX_GENERATION_NUMBER) {
425       /* there is no free generation number */
426       reiserfs_warning (dir->i_sb, "reiserfs_add_entry: Congratulations! we have got hash function screwed up\n");
427       if (buffer != small_buf)
428           reiserfs_kfree (buffer, buflen, dir->i_sb);
429       pathrelse (&path);
430 /*
431  * Trivial changes by Alan Cox to remove EHASHCOLLISION for compatibility
432  *
433  * Trivial Changes:
434  * Rights granted to Hans Reiser to redistribute under other terms providing
435  * he accepts all liability including but not limited to patent, fitness
436  * for purpose, and direct or indirect claims arising from failure to perform.
437  *
438  * NO WARRANTY
439  * This is one of two lines that this fix consist of.
440  */
441       return -EBUSY;
442       /* I think it was better to have an error code with a name that says
443 	 what it means, but I choose not to fight over it.  Persons porting to
444 	 other operating systems should consider keeping it as it was
445 	 (return -EHASHCOLLISION;). -Hans */
446     }
447     /* adjust offset of directory enrty */
448     put_deh_offset(deh, SET_GENERATION_NUMBER(deh_offset(deh), gen_number));
449     set_cpu_key_k_offset (&entry_key, deh_offset(deh));
450 
451     /* update max-hash-collisions counter in reiserfs_sb_info */
452     PROC_INFO_MAX( th -> t_super, max_hash_collisions, gen_number );
453 
454     if (gen_number != 0) {	/* we need to re-search for the insertion point */
455       if (search_by_entry_key (dir->i_sb, &entry_key, &path, &de) != NAME_NOT_FOUND) {
456             reiserfs_warning (dir->i_sb, "vs-7032: reiserfs_add_entry: "
457                             "entry with this key (%K) already exists\n", &entry_key);
458 
459 	    if (buffer != small_buf)
460 		reiserfs_kfree (buffer, buflen, dir->i_sb);
461 	    pathrelse (&path);
462 	    /* Following line is 2nd line touched by Alan Cox' trivial fix */
463 	    return -EBUSY;
464       /* I think it was better to have an error code with a name that says
465 	 what it means, but I choose not to fight over it.  Persons porting to
466 	 other operating systems should consider keeping it as it was
467 	 (return -EHASHCOLLISION;). -Hans */
468 	}
469     }
470 
471     /* perform the insertion of the entry that we have prepared */
472     retval = reiserfs_paste_into_item (th, &path, &entry_key, buffer, paste_size);
473     if (buffer != small_buf)
474 	reiserfs_kfree (buffer, buflen, dir->i_sb);
475     if (retval) {
476 	reiserfs_check_path(&path) ;
477 	return retval;
478     }
479 
480     dir->i_size += paste_size;
481     dir->i_blocks = ((dir->i_size + 511) >> 9);
482     dir->i_mtime = dir->i_ctime = CURRENT_TIME;
483     if (!S_ISDIR (inode->i_mode) && visible)
484 	// reiserfs_mkdir or reiserfs_rename will do that by itself
485 	reiserfs_update_sd (th, dir);
486 
487     reiserfs_check_path(&path) ;
488     return 0;
489 }
490 
491 /* quota utility function, call if you've had to abort after calling
492 ** new_inode_init, and have not called reiserfs_new_inode yet.
493 ** This should only be called on inodes that do not hav stat data
494 ** inserted into the tree yet.
495 */
drop_new_inode(struct inode * inode)496 static int drop_new_inode(struct inode *inode) {
497     make_bad_inode(inode) ;
498     iput(inode) ;
499     return 0 ;
500 }
501 
502 /* utility function that does setup for reiserfs_new_inode.
503 ** DQUOT_ALLOC_INODE cannot be called inside a transaction, so we had
504 ** to pull some bits of reiserfs_new_inode out into this func.
505 */
new_inode_init(struct inode * inode,struct inode * dir,int mode)506 static int new_inode_init(struct inode *inode, struct inode *dir, int mode) {
507 
508     /* the quota init calls have to know who to charge the quota to, so
509     ** we have to set uid and gid here
510     */
511     inode->i_uid = current->fsuid;
512     inode->i_mode = mode;
513 
514     if (dir->i_mode & S_ISGID) {
515         inode->i_gid = dir->i_gid;
516         if (S_ISDIR(mode))
517             inode->i_mode |= S_ISGID;
518     } else
519         inode->i_gid = current->fsgid;
520 
521     return 0 ;
522 }
523 
reiserfs_create(struct inode * dir,struct dentry * dentry,int mode)524 static int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode)
525 {
526     int retval;
527     struct inode * inode;
528     int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 ;
529     struct reiserfs_transaction_handle th ;
530 
531     if (!(inode = new_inode(dir->i_sb))) {
532 	return -ENOMEM ;
533     }
534     retval = new_inode_init(inode, dir, mode) ;
535     if (retval)
536 	return retval ;
537 
538     journal_begin(&th, dir->i_sb, jbegin_count) ;
539     th.t_caller = "create" ;
540     retval = reiserfs_new_inode (&th, dir, mode, 0, 0/*i_size*/, dentry, inode);
541     if (retval) {
542 	goto out_failed ;
543     }
544 
545     inode->i_op = &reiserfs_file_inode_operations;
546     inode->i_fop = &reiserfs_file_operations;
547     inode->i_mapping->a_ops = &reiserfs_address_space_operations ;
548 
549     retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len,
550 				inode, 1/*visible*/);
551     if (retval) {
552 	inode->i_nlink--;
553 	reiserfs_update_sd (&th, inode);
554 	journal_end(&th, dir->i_sb, jbegin_count) ;
555 	iput(inode) ;
556 	goto out_failed ;
557     }
558     reiserfs_update_inode_transaction(inode) ;
559     reiserfs_update_inode_transaction(dir) ;
560 
561     d_instantiate(dentry, inode);
562     journal_end(&th, dir->i_sb, jbegin_count) ;
563     return 0;
564 
565 out_failed:
566     return retval ;
567 }
568 
569 
reiserfs_mknod(struct inode * dir,struct dentry * dentry,int mode,int rdev)570 static int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev)
571 {
572     int retval;
573     struct inode * inode;
574     struct reiserfs_transaction_handle th ;
575     int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;
576 
577     if (!(inode = new_inode(dir->i_sb))) {
578 	return -ENOMEM ;
579     }
580     retval = new_inode_init(inode, dir, mode) ;
581     if (retval)
582         return retval ;
583 
584     journal_begin(&th, dir->i_sb, jbegin_count) ;
585 
586     retval = reiserfs_new_inode(&th, dir, mode, 0, 0/*i_size*/, dentry, inode);
587     if (retval) {
588 	goto out_failed;
589     }
590 
591     init_special_inode(inode, mode, rdev) ;
592 
593     //FIXME: needed for block and char devices only
594     reiserfs_update_sd (&th, inode);
595 
596     reiserfs_update_inode_transaction(inode) ;
597     reiserfs_update_inode_transaction(dir) ;
598 
599     retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len,
600 				 inode, 1/*visible*/);
601     if (retval) {
602 	inode->i_nlink--;
603 	reiserfs_update_sd (&th, inode);
604 	journal_end(&th, dir->i_sb, jbegin_count) ;
605 	iput(inode) ;
606         goto out_failed;
607     }
608 
609     d_instantiate(dentry, inode);
610     journal_end(&th, dir->i_sb, jbegin_count) ;
611     return 0;
612 
613 out_failed:
614     return retval ;
615 }
616 
617 
reiserfs_mkdir(struct inode * dir,struct dentry * dentry,int mode)618 static int reiserfs_mkdir (struct inode * dir, struct dentry *dentry, int mode)
619 {
620     int retval;
621     struct inode * inode;
622     struct reiserfs_transaction_handle th ;
623     int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;
624 
625     mode = S_IFDIR | mode;
626     if (!(inode = new_inode(dir->i_sb))) {
627 	return -ENOMEM ;
628     }
629     retval = new_inode_init(inode, dir, mode) ;
630     if (retval)
631 	return retval ;
632 
633     journal_begin(&th, dir->i_sb, jbegin_count) ;
634 
635     /* inc the link count now, so another writer doesn't overflow it while
636     ** we sleep later on.
637     */
638     INC_DIR_INODE_NLINK(dir)
639 
640 #ifdef DISPLACE_NEW_PACKING_LOCALITIES
641     /* set flag that new packing locality created and new blocks for the content     * of that directory are not displaced yet */
642     dir->u.reiserfs_i.new_packing_locality = 1;
643 #endif
644     retval = reiserfs_new_inode(&th, dir, mode, 0/*symlink*/,
645 				old_format_only (dir->i_sb) ?
646 				EMPTY_DIR_SIZE_V1 : EMPTY_DIR_SIZE,
647 				dentry, inode) ;
648     if (retval) {
649 	dir->i_nlink-- ;
650 	goto out_failed ;
651     }
652     reiserfs_update_inode_transaction(inode) ;
653     reiserfs_update_inode_transaction(dir) ;
654 
655     inode->i_op = &reiserfs_dir_inode_operations;
656     inode->i_fop = &reiserfs_dir_operations;
657 
658     // note, _this_ add_entry will not update dir's stat data
659     retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len,
660 				inode, 1/*visible*/);
661     if (retval) {
662 	inode->i_nlink = 0;
663 	DEC_DIR_INODE_NLINK(dir);
664 	reiserfs_update_sd (&th, inode);
665 	journal_end(&th, dir->i_sb, jbegin_count) ;
666 	iput(inode) ;
667 	goto out_failed ;
668     }
669 
670     // the above add_entry did not update dir's stat data
671     reiserfs_update_sd (&th, dir);
672 
673     d_instantiate(dentry, inode);
674     journal_end(&th, dir->i_sb, jbegin_count) ;
675     return 0;
676 
677 out_failed:
678     return retval ;
679 }
680 
reiserfs_empty_dir(struct inode * inode)681 static inline int reiserfs_empty_dir(struct inode *inode) {
682     /* we can cheat because an old format dir cannot have
683     ** EMPTY_DIR_SIZE, and a new format dir cannot have
684     ** EMPTY_DIR_SIZE_V1.  So, if the inode is either size,
685     ** regardless of disk format version, the directory is empty.
686     */
687     if (inode->i_size != EMPTY_DIR_SIZE &&
688         inode->i_size != EMPTY_DIR_SIZE_V1) {
689         return 0 ;
690     }
691     return 1 ;
692 }
693 
694 
reiserfs_rmdir(struct inode * dir,struct dentry * dentry)695 static int reiserfs_rmdir (struct inode * dir, struct dentry *dentry)
696 {
697     int retval;
698     struct inode * inode;
699     int windex ;
700     struct reiserfs_transaction_handle th ;
701     int jbegin_count;
702     INITIALIZE_PATH (path);
703     struct reiserfs_dir_entry de;
704 
705 
706     /* we will be doing 2 balancings and update 2 stat data */
707     jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2;
708 
709     journal_begin(&th, dir->i_sb, jbegin_count) ;
710     windex = push_journal_writer("reiserfs_rmdir") ;
711 
712     de.de_gen_number_bit_string = 0;
713     if ( (retval = reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path, &de)) == NAME_NOT_FOUND) {
714 	retval = -ENOENT;
715 	goto end_rmdir;
716     } else if ( retval == IO_ERROR) {
717 	retval = -EIO;
718 	goto end_rmdir;
719     }
720 
721     inode = dentry->d_inode;
722 
723     reiserfs_update_inode_transaction(inode) ;
724     reiserfs_update_inode_transaction(dir) ;
725 
726     if (de.de_objectid != inode->i_ino) {
727 	// FIXME: compare key of an object and a key found in the
728 	// entry
729 	retval = -EIO;
730 	goto end_rmdir;
731     }
732     if (!reiserfs_empty_dir(inode)) {
733 	retval = -ENOTEMPTY;
734 	goto end_rmdir;
735     }
736 
737     /* cut entry from dir directory */
738     retval = reiserfs_cut_from_item (&th, &path, &(de.de_entry_key), dir,
739                                      NULL, /* page */
740 				     0/*new file size - not used here*/);
741     if (retval < 0)
742 	goto end_rmdir;
743 
744     if ( inode->i_nlink != 2 && inode->i_nlink != 1 )
745 	reiserfs_warning ( inode->i_sb, "reiserfs_rmdir: empty directory has nlink != 2 (%d)\n", inode->i_nlink);
746 
747     inode->i_nlink = 0;
748     inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
749     reiserfs_update_sd (&th, inode);
750 
751     DEC_DIR_INODE_NLINK(dir)
752     dir->i_size -= (DEH_SIZE + de.de_entrylen);
753     dir->i_blocks = ((dir->i_size + 511) >> 9);
754     reiserfs_update_sd (&th, dir);
755 
756     /* prevent empty directory from getting lost */
757     add_save_link (&th, inode, 0/* not truncate */);
758 
759     pop_journal_writer(windex) ;
760     journal_end(&th, dir->i_sb, jbegin_count) ;
761     reiserfs_check_path(&path) ;
762     return 0;
763 
764  end_rmdir:
765     /* we must release path, because we did not call
766        reiserfs_cut_from_item, or reiserfs_cut_from_item does not
767        release path if operation was not complete */
768     pathrelse (&path);
769     pop_journal_writer(windex) ;
770     journal_end(&th, dir->i_sb, jbegin_count) ;
771     return retval;
772 }
773 
774 
reiserfs_unlink(struct inode * dir,struct dentry * dentry)775 static int reiserfs_unlink (struct inode * dir, struct dentry *dentry)
776 {
777     int retval;
778     struct inode * inode;
779     struct reiserfs_dir_entry de;
780     INITIALIZE_PATH (path);
781     int windex ;
782     struct reiserfs_transaction_handle th ;
783     int jbegin_count;
784     unsigned long savelink;
785 
786     inode = dentry->d_inode;
787 
788     /* in this transaction we can be doing at max two balancings and update
789        two stat datas */
790     jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2;
791 
792     journal_begin(&th, dir->i_sb, jbegin_count) ;
793     windex = push_journal_writer("reiserfs_unlink") ;
794 
795     de.de_gen_number_bit_string = 0;
796     if ( (retval = reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path, &de)) == NAME_NOT_FOUND) {
797 	retval = -ENOENT;
798 	goto end_unlink;
799     } else if (retval == IO_ERROR) {
800 	retval = -EIO;
801 	goto end_unlink;
802     }
803 
804     reiserfs_update_inode_transaction(inode) ;
805     reiserfs_update_inode_transaction(dir) ;
806 
807     if (de.de_objectid != inode->i_ino) {
808 	// FIXME: compare key of an object and a key found in the
809 	// entry
810 	retval = -EIO;
811 	goto end_unlink;
812     }
813 
814     if (!inode->i_nlink) {
815 	reiserfs_warning(inode->i_sb, "reiserfs_unlink: deleting nonexistent file (%s:%lu), %d\n",
816 	       kdevname(inode->i_dev), inode->i_ino, inode->i_nlink);
817 	inode->i_nlink = 1;
818     }
819 
820     inode->i_nlink--;
821 
822     /*
823      * we schedule before doing the add_save_link call, save the link
824      * count so we don't race
825      */
826     savelink = inode->i_nlink;
827 
828 
829     retval = reiserfs_cut_from_item (&th, &path, &(de.de_entry_key), dir, NULL, 0);
830     if (retval < 0) {
831 	inode->i_nlink++;
832 	goto end_unlink;
833     }
834     inode->i_ctime = CURRENT_TIME;
835     reiserfs_update_sd (&th, inode);
836 
837     dir->i_size -= (de.de_entrylen + DEH_SIZE);
838     dir->i_blocks = ((dir->i_size + 511) >> 9);
839     dir->i_ctime = dir->i_mtime = CURRENT_TIME;
840     reiserfs_update_sd (&th, dir);
841 
842     if (!savelink)
843        /* prevent file from getting lost */
844        add_save_link (&th, inode, 0/* not truncate */);
845 
846     pop_journal_writer(windex) ;
847     journal_end(&th, dir->i_sb, jbegin_count) ;
848     reiserfs_check_path(&path) ;
849     return 0;
850 
851  end_unlink:
852     pathrelse (&path);
853     pop_journal_writer(windex) ;
854     journal_end(&th, dir->i_sb, jbegin_count) ;
855     reiserfs_check_path(&path) ;
856     return retval;
857 }
858 
859 
reiserfs_symlink(struct inode * parent_dir,struct dentry * dentry,const char * symname)860 static int reiserfs_symlink (struct inode * parent_dir, struct dentry * dentry, const char * symname)
861 {
862     int retval;
863     struct inode * inode;
864     char * name;
865     int item_len;
866     int mode = S_IFLNK | S_IRWXUGO ;
867     struct reiserfs_transaction_handle th ;
868     int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;
869 
870 
871     if (!(inode = new_inode(parent_dir->i_sb))) {
872   	return -ENOMEM ;
873     }
874     retval = new_inode_init(inode, parent_dir, mode) ;
875     if (retval) {
876 	return retval ;
877     }
878 
879     item_len = ROUND_UP (strlen (symname));
880     if (item_len > MAX_DIRECT_ITEM_LEN (parent_dir->i_sb->s_blocksize)) {
881 	retval = -ENAMETOOLONG;
882 	drop_new_inode(inode) ;
883 	goto out_failed ;
884     }
885 
886     name = reiserfs_kmalloc (item_len, GFP_NOFS, parent_dir->i_sb);
887     if (!name) {
888 	retval = -ENOMEM;
889 	drop_new_inode(inode) ;
890 	goto out_failed ;
891     }
892     memcpy (name, symname, strlen (symname));
893     padd_item (name, item_len, strlen (symname));
894 
895     journal_begin(&th, parent_dir->i_sb, jbegin_count) ;
896 
897     retval = reiserfs_new_inode(&th, parent_dir, mode, name,
898 				strlen(symname), dentry, inode) ;
899     reiserfs_kfree (name, item_len, parent_dir->i_sb);
900     if (retval) {
901 	goto out_failed ;
902     }
903 
904     reiserfs_update_inode_transaction(inode) ;
905     reiserfs_update_inode_transaction(parent_dir) ;
906 
907     inode->i_op = &page_symlink_inode_operations;
908     inode->i_mapping->a_ops = &reiserfs_address_space_operations;
909 
910     // must be sure this inode is written with this transaction
911     //
912     //reiserfs_update_sd (&th, inode, READ_BLOCKS);
913 
914     retval = reiserfs_add_entry (&th, parent_dir, dentry->d_name.name, dentry->d_name.len,
915 				 inode, 1/*visible*/);
916     if (retval) {
917 	inode->i_nlink--;
918 	reiserfs_update_sd (&th, inode);
919 	journal_end(&th, parent_dir->i_sb, jbegin_count) ;
920 	iput(inode) ;
921 	goto out_failed ;
922     }
923 
924     d_instantiate(dentry, inode);
925     journal_end(&th, parent_dir->i_sb, jbegin_count) ;
926     return 0;
927 
928 out_failed:
929     return retval ;
930 }
931 
932 
reiserfs_link(struct dentry * old_dentry,struct inode * dir,struct dentry * dentry)933 static int reiserfs_link (struct dentry * old_dentry, struct inode * dir, struct dentry * dentry)
934 {
935     int retval;
936     struct inode *inode = old_dentry->d_inode;
937     int windex ;
938     struct reiserfs_transaction_handle th ;
939     int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;
940     time_t ctime;
941 
942 
943     if (S_ISDIR(inode->i_mode))
944 	return -EPERM;
945 
946     if (inode->i_nlink >= REISERFS_LINK_MAX) {
947 	//FIXME: sd_nlink is 32 bit for new files
948 	return -EMLINK;
949     }
950     if (inode->i_nlink == 0) {
951         return -ENOENT;
952     }
953 
954     /* inc before scheduling so reiserfs_unlink knows we are here */
955     inode->i_nlink++;
956 
957     journal_begin(&th, dir->i_sb, jbegin_count) ;
958     windex = push_journal_writer("reiserfs_link") ;
959 
960     /* create new entry */
961     retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len,
962 				 inode, 1/*visible*/);
963 
964     reiserfs_update_inode_transaction(inode) ;
965     reiserfs_update_inode_transaction(dir) ;
966 
967     if (retval) {
968 	inode->i_nlink--;
969 	pop_journal_writer(windex) ;
970 	journal_end(&th, dir->i_sb, jbegin_count) ;
971 	return retval;
972     }
973 
974     ctime = CURRENT_TIME;
975     inode->i_ctime = ctime;
976     reiserfs_update_sd (&th, inode);
977 
978     atomic_inc(&inode->i_count) ;
979     d_instantiate(dentry, inode);
980     pop_journal_writer(windex) ;
981     journal_end(&th, dir->i_sb, jbegin_count) ;
982     return 0;
983 }
984 
985 
986 // de contains information pointing to an entry which
de_still_valid(const char * name,int len,struct reiserfs_dir_entry * de)987 static int de_still_valid (const char * name, int len, struct reiserfs_dir_entry * de)
988 {
989     struct reiserfs_dir_entry tmp = *de;
990 
991     // recalculate pointer to name and name length
992     set_de_name_and_namelen (&tmp);
993     // FIXME: could check more
994     if (tmp.de_namelen != len || memcmp (name, de->de_name, len))
995 	return 0;
996     return 1;
997 }
998 
999 
entry_points_to_object(const char * name,int len,struct reiserfs_dir_entry * de,struct inode * inode)1000 static int entry_points_to_object (const char * name, int len, struct reiserfs_dir_entry * de, struct inode * inode)
1001 {
1002     if (!de_still_valid (name, len, de))
1003 	return 0;
1004 
1005     if (inode) {
1006 	if (!de_visible (de->de_deh + de->de_entry_num))
1007 	    reiserfs_panic (0, "vs-7042: entry_points_to_object: entry must be visible");
1008 	return (de->de_objectid == inode->i_ino) ? 1 : 0;
1009     }
1010 
1011     /* this must be added hidden entry */
1012     if (de_visible (de->de_deh + de->de_entry_num))
1013 	reiserfs_panic (0, "vs-7043: entry_points_to_object: entry must be visible");
1014 
1015     return 1;
1016 }
1017 
1018 
1019 /* sets key of objectid the entry has to point to */
set_ino_in_dir_entry(struct reiserfs_dir_entry * de,struct key * key)1020 static void set_ino_in_dir_entry (struct reiserfs_dir_entry * de, struct key * key)
1021 {
1022     /* JDM These operations are endian safe - both are le */
1023     de->de_deh[de->de_entry_num].deh_dir_id = key->k_dir_id;
1024     de->de_deh[de->de_entry_num].deh_objectid = key->k_objectid;
1025 }
1026 
1027 
1028 /*
1029  * process, that is going to call fix_nodes/do_balance must hold only
1030  * one path. If it holds 2 or more, it can get into endless waiting in
1031  * get_empty_nodes or its clones
1032  */
reiserfs_rename(struct inode * old_dir,struct dentry * old_dentry,struct inode * new_dir,struct dentry * new_dentry)1033 static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry,
1034 			    struct inode * new_dir, struct dentry *new_dentry)
1035 {
1036     int retval;
1037     INITIALIZE_PATH (old_entry_path);
1038     INITIALIZE_PATH (new_entry_path);
1039     INITIALIZE_PATH (dot_dot_entry_path);
1040     struct item_head new_entry_ih, old_entry_ih, dot_dot_ih ;
1041     struct reiserfs_dir_entry old_de, new_de, dot_dot_de;
1042     struct inode * old_inode, * new_dentry_inode;
1043     int windex ;
1044     struct reiserfs_transaction_handle th ;
1045     int jbegin_count ;
1046     umode_t old_inode_mode;
1047     time_t ctime;
1048     unsigned long savelink = 1;
1049 
1050 
1051     /* two balancings: old name removal, new name insertion or "save" link,
1052        stat data updates: old directory and new directory and maybe block
1053        containing ".." of renamed directory */
1054     jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 3;
1055 
1056     old_inode = old_dentry->d_inode;
1057     new_dentry_inode = new_dentry->d_inode;
1058 
1059     // make sure, that oldname still exists and points to an object we
1060     // are going to rename
1061     old_de.de_gen_number_bit_string = 0;
1062     retval = reiserfs_find_entry (old_dir, old_dentry->d_name.name, old_dentry->d_name.len,
1063 				  &old_entry_path, &old_de);
1064     pathrelse (&old_entry_path);
1065     if (retval == IO_ERROR)
1066 	return -EIO;
1067 
1068     if (retval != NAME_FOUND || old_de.de_objectid != old_inode->i_ino) {
1069 	return -ENOENT;
1070     }
1071 
1072     old_inode_mode = old_inode->i_mode;
1073     if (S_ISDIR(old_inode_mode)) {
1074 	// make sure, that directory being renamed has correct ".."
1075 	// and that its new parent directory has not too many links
1076 	// already
1077 
1078 	if (new_dentry_inode) {
1079 	    if (!reiserfs_empty_dir(new_dentry_inode)) {
1080 		return -ENOTEMPTY;
1081 	    }
1082 	}
1083 
1084 	/* directory is renamed, its parent directory will be changed,
1085 	** so find ".." entry
1086 	*/
1087 	dot_dot_de.de_gen_number_bit_string = 0;
1088 	retval = reiserfs_find_entry (old_inode, "..", 2, &dot_dot_entry_path, &dot_dot_de);
1089 	pathrelse (&dot_dot_entry_path);
1090 	if (retval != NAME_FOUND)
1091 	    return -EIO;
1092 
1093 	/* inode number of .. must equal old_dir->i_ino */
1094 	if (dot_dot_de.de_objectid != old_dir->i_ino)
1095 	    return -EIO;
1096     }
1097 
1098     journal_begin(&th, old_dir->i_sb, jbegin_count) ;
1099     windex = push_journal_writer("reiserfs_rename") ;
1100 
1101     /* add new entry (or find the existing one) */
1102     retval = reiserfs_add_entry (&th, new_dir, new_dentry->d_name.name, new_dentry->d_name.len,
1103 				 old_inode, 0);
1104     if (retval == -EEXIST) {
1105 	if (!new_dentry_inode) {
1106 	    reiserfs_panic (old_dir->i_sb,
1107 			    "vs-7050: new entry is found, new inode == 0\n");
1108 	}
1109     } else if (retval) {
1110 	pop_journal_writer(windex) ;
1111 	journal_end(&th, old_dir->i_sb, jbegin_count) ;
1112 	return retval;
1113     }
1114 
1115     reiserfs_update_inode_transaction(old_dir) ;
1116     reiserfs_update_inode_transaction(new_dir) ;
1117 
1118     /* this makes it so an fsync on an open fd for the old name will
1119     ** commit the rename operation
1120     */
1121     reiserfs_update_inode_transaction(old_inode) ;
1122 
1123     if (new_dentry_inode)
1124 	reiserfs_update_inode_transaction(new_dentry_inode) ;
1125 
1126     while (1) {
1127 	// look for old name using corresponding entry key (found by reiserfs_find_entry)
1128 	if (search_by_entry_key (new_dir->i_sb, &old_de.de_entry_key, &old_entry_path, &old_de) != NAME_FOUND)
1129 	    BUG ();
1130 
1131 	copy_item_head(&old_entry_ih, get_ih(&old_entry_path)) ;
1132 
1133 	reiserfs_prepare_for_journal(old_inode->i_sb, old_de.de_bh, 1) ;
1134 
1135 	// look for new name by reiserfs_find_entry
1136 	new_de.de_gen_number_bit_string = 0;
1137 	retval = reiserfs_find_entry (new_dir, new_dentry->d_name.name, new_dentry->d_name.len,
1138 				      &new_entry_path, &new_de);
1139 	// reiserfs_add_entry should not return IO_ERROR, because it is called with essentially same parameters from
1140         // reiserfs_add_entry above, and we'll catch any i/o errors before we get here.
1141 	if (retval != NAME_FOUND_INVISIBLE && retval != NAME_FOUND)
1142 	    BUG ();
1143 
1144 	copy_item_head(&new_entry_ih, get_ih(&new_entry_path)) ;
1145 
1146 	reiserfs_prepare_for_journal(old_inode->i_sb, new_de.de_bh, 1) ;
1147 
1148 	if (S_ISDIR(old_inode->i_mode)) {
1149 	    if (search_by_entry_key (new_dir->i_sb, &dot_dot_de.de_entry_key, &dot_dot_entry_path, &dot_dot_de) != NAME_FOUND)
1150 		BUG ();
1151 	    copy_item_head(&dot_dot_ih, get_ih(&dot_dot_entry_path)) ;
1152 	    // node containing ".." gets into transaction
1153 	    reiserfs_prepare_for_journal(old_inode->i_sb, dot_dot_de.de_bh, 1) ;
1154 	}
1155 				/* we should check seals here, not do
1156                                    this stuff, yes? Then, having
1157                                    gathered everything into RAM we
1158                                    should lock the buffers, yes?  -Hans */
1159 				/* probably.  our rename needs to hold more
1160 				** than one path at once.  The seals would
1161 				** have to be written to deal with multi-path
1162 				** issues -chris
1163 				*/
1164 	/* sanity checking before doing the rename - avoid races many
1165 	** of the above checks could have scheduled.  We have to be
1166 	** sure our items haven't been shifted by another process.
1167 	*/
1168 	if (item_moved(&new_entry_ih, &new_entry_path) ||
1169 	    !entry_points_to_object(new_dentry->d_name.name,
1170 	                            new_dentry->d_name.len,
1171 				    &new_de, new_dentry_inode) ||
1172 	    item_moved(&old_entry_ih, &old_entry_path) ||
1173 	    !entry_points_to_object (old_dentry->d_name.name,
1174 	                             old_dentry->d_name.len,
1175 				     &old_de, old_inode)) {
1176 	    reiserfs_restore_prepared_buffer (old_inode->i_sb, new_de.de_bh);
1177 	    reiserfs_restore_prepared_buffer (old_inode->i_sb, old_de.de_bh);
1178 	    if (S_ISDIR(old_inode_mode))
1179 		reiserfs_restore_prepared_buffer (old_inode->i_sb, dot_dot_de.de_bh);
1180 	    continue;
1181 	}
1182 	if (S_ISDIR(old_inode_mode)) {
1183 	    if ( item_moved(&dot_dot_ih, &dot_dot_entry_path) ||
1184 		 !entry_points_to_object ( "..", 2, &dot_dot_de, old_dir) ) {
1185 		reiserfs_restore_prepared_buffer (old_inode->i_sb, old_de.de_bh);
1186 		reiserfs_restore_prepared_buffer (old_inode->i_sb, new_de.de_bh);
1187 		reiserfs_restore_prepared_buffer (old_inode->i_sb, dot_dot_de.de_bh);
1188 		continue;
1189 	    }
1190 	}
1191 
1192 
1193 	RFALSE( S_ISDIR(old_inode_mode) &&
1194 		!reiserfs_buffer_prepared(dot_dot_de.de_bh), "" );
1195 
1196 	break;
1197     }
1198 
1199     /* ok, all the changes can be done in one fell swoop when we
1200        have claimed all the buffers needed.*/
1201 
1202     mark_de_visible (new_de.de_deh + new_de.de_entry_num);
1203     set_ino_in_dir_entry (&new_de, INODE_PKEY (old_inode));
1204     journal_mark_dirty (&th, old_dir->i_sb, new_de.de_bh);
1205 
1206     mark_de_hidden (old_de.de_deh + old_de.de_entry_num);
1207     journal_mark_dirty (&th, old_dir->i_sb, old_de.de_bh);
1208     old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
1209     new_dir->i_ctime = new_dir->i_mtime = CURRENT_TIME;
1210 
1211     if (new_dentry_inode) {
1212 	// adjust link number of the victim
1213 	if (S_ISDIR(new_dentry_inode->i_mode)) {
1214 	    new_dentry_inode->i_nlink  = 0;
1215 	} else {
1216 	    new_dentry_inode->i_nlink--;
1217 	}
1218 	ctime = CURRENT_TIME;
1219 	new_dentry_inode->i_ctime = ctime;
1220 	savelink = new_dentry_inode->i_nlink;
1221     }
1222 
1223     if (S_ISDIR(old_inode_mode)) {
1224 	// adjust ".." of renamed directory
1225 	set_ino_in_dir_entry (&dot_dot_de, INODE_PKEY (new_dir));
1226 	journal_mark_dirty (&th, new_dir->i_sb, dot_dot_de.de_bh);
1227 
1228         if (!new_dentry_inode)
1229 	    /* there (in new_dir) was no directory, so it got new link
1230 	       (".."  of renamed directory) */
1231 	    INC_DIR_INODE_NLINK(new_dir);
1232 
1233 	/* old directory lost one link - ".. " of renamed directory */
1234 	DEC_DIR_INODE_NLINK(old_dir);
1235     }
1236 
1237     // looks like in 2.3.99pre3 brelse is atomic. so we can use pathrelse
1238     pathrelse (&new_entry_path);
1239     pathrelse (&dot_dot_entry_path);
1240 
1241     // FIXME: this reiserfs_cut_from_item's return value may screw up
1242     // anybody, but it will panic if will not be able to find the
1243     // entry. This needs one more clean up
1244     if (reiserfs_cut_from_item (&th, &old_entry_path, &(old_de.de_entry_key), old_dir, NULL, 0) < 0)
1245 	reiserfs_warning ((&th)->t_super, "vs-7060: reiserfs_rename: couldn't not cut old name. Fsck later?\n");
1246 
1247     old_dir->i_size -= DEH_SIZE + old_de.de_entrylen;
1248     old_dir->i_blocks = ((old_dir->i_size + 511) >> 9);
1249 
1250     reiserfs_update_sd (&th, old_dir);
1251     reiserfs_update_sd (&th, new_dir);
1252 
1253     if (new_dentry_inode) {
1254 	if (savelink == 0)
1255 	    add_save_link (&th, new_dentry_inode, 0/* not truncate */);
1256 	reiserfs_update_sd (&th, new_dentry_inode);
1257     }
1258 
1259     pop_journal_writer(windex) ;
1260     journal_end(&th, old_dir->i_sb, jbegin_count) ;
1261     return 0;
1262 }
1263 
1264 
1265 
1266 /*
1267  * directories can handle most operations...
1268  */
1269 struct inode_operations reiserfs_dir_inode_operations = {
1270   //&reiserfs_dir_operations,	/* default_file_ops */
1271     create:	reiserfs_create,
1272     lookup:	reiserfs_lookup,
1273     link:	reiserfs_link,
1274     unlink:	reiserfs_unlink,
1275     symlink:	reiserfs_symlink,
1276     mkdir:	reiserfs_mkdir,
1277     rmdir:	reiserfs_rmdir,
1278     mknod:	reiserfs_mknod,
1279     rename:	reiserfs_rename,
1280 };
1281 
1282