1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  *  linux/fs/hpfs/namei.c
4  *
5  *  Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
6  *
7  *  adding & removing files & directories
8  */
9 #include <linux/sched.h>
10 #include "hpfs_fn.h"
11 
hpfs_update_directory_times(struct inode * dir)12 static void hpfs_update_directory_times(struct inode *dir)
13 {
14 	time64_t t = local_to_gmt(dir->i_sb, local_get_seconds(dir->i_sb));
15 	if (t == dir->i_mtime.tv_sec &&
16 	    t == dir->i_ctime.tv_sec)
17 		return;
18 	dir->i_mtime.tv_sec = dir->i_ctime.tv_sec = t;
19 	dir->i_mtime.tv_nsec = dir->i_ctime.tv_nsec = 0;
20 	hpfs_write_inode_nolock(dir);
21 }
22 
hpfs_mkdir(struct user_namespace * mnt_userns,struct inode * dir,struct dentry * dentry,umode_t mode)23 static int hpfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
24 		      struct dentry *dentry, umode_t mode)
25 {
26 	const unsigned char *name = dentry->d_name.name;
27 	unsigned len = dentry->d_name.len;
28 	struct quad_buffer_head qbh0;
29 	struct buffer_head *bh;
30 	struct hpfs_dirent *de;
31 	struct fnode *fnode;
32 	struct dnode *dnode;
33 	struct inode *result;
34 	fnode_secno fno;
35 	dnode_secno dno;
36 	int r;
37 	struct hpfs_dirent dee;
38 	int err;
39 	if ((err = hpfs_chk_name(name, &len))) return err==-ENOENT ? -EINVAL : err;
40 	hpfs_lock(dir->i_sb);
41 	err = -ENOSPC;
42 	fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
43 	if (!fnode)
44 		goto bail;
45 	dnode = hpfs_alloc_dnode(dir->i_sb, fno, &dno, &qbh0);
46 	if (!dnode)
47 		goto bail1;
48 	memset(&dee, 0, sizeof dee);
49 	dee.directory = 1;
50 	if (!(mode & 0222)) dee.read_only = 1;
51 	/*dee.archive = 0;*/
52 	dee.hidden = name[0] == '.';
53 	dee.fnode = cpu_to_le32(fno);
54 	dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
55 	result = new_inode(dir->i_sb);
56 	if (!result)
57 		goto bail2;
58 	hpfs_init_inode(result);
59 	result->i_ino = fno;
60 	hpfs_i(result)->i_parent_dir = dir->i_ino;
61 	hpfs_i(result)->i_dno = dno;
62 	result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, le32_to_cpu(dee.creation_date));
63 	result->i_ctime.tv_nsec = 0;
64 	result->i_mtime.tv_nsec = 0;
65 	result->i_atime.tv_nsec = 0;
66 	hpfs_i(result)->i_ea_size = 0;
67 	result->i_mode |= S_IFDIR;
68 	result->i_op = &hpfs_dir_iops;
69 	result->i_fop = &hpfs_dir_ops;
70 	result->i_blocks = 4;
71 	result->i_size = 2048;
72 	set_nlink(result, 2);
73 	if (dee.read_only)
74 		result->i_mode &= ~0222;
75 
76 	r = hpfs_add_dirent(dir, name, len, &dee);
77 	if (r == 1)
78 		goto bail3;
79 	if (r == -1) {
80 		err = -EEXIST;
81 		goto bail3;
82 	}
83 	fnode->len = len;
84 	memcpy(fnode->name, name, len > 15 ? 15 : len);
85 	fnode->up = cpu_to_le32(dir->i_ino);
86 	fnode->flags |= FNODE_dir;
87 	fnode->btree.n_free_nodes = 7;
88 	fnode->btree.n_used_nodes = 1;
89 	fnode->btree.first_free = cpu_to_le16(0x14);
90 	fnode->u.external[0].disk_secno = cpu_to_le32(dno);
91 	fnode->u.external[0].file_secno = cpu_to_le32(-1);
92 	dnode->root_dnode = 1;
93 	dnode->up = cpu_to_le32(fno);
94 	de = hpfs_add_de(dir->i_sb, dnode, "\001\001", 2, 0);
95 	de->creation_date = de->write_date = de->read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
96 	if (!(mode & 0222)) de->read_only = 1;
97 	de->first = de->directory = 1;
98 	/*de->hidden = de->system = 0;*/
99 	de->fnode = cpu_to_le32(fno);
100 	mark_buffer_dirty(bh);
101 	brelse(bh);
102 	hpfs_mark_4buffers_dirty(&qbh0);
103 	hpfs_brelse4(&qbh0);
104 	inc_nlink(dir);
105 	insert_inode_hash(result);
106 
107 	if (!uid_eq(result->i_uid, current_fsuid()) ||
108 	    !gid_eq(result->i_gid, current_fsgid()) ||
109 	    result->i_mode != (mode | S_IFDIR)) {
110 		result->i_uid = current_fsuid();
111 		result->i_gid = current_fsgid();
112 		result->i_mode = mode | S_IFDIR;
113 		hpfs_write_inode_nolock(result);
114 	}
115 	hpfs_update_directory_times(dir);
116 	d_instantiate(dentry, result);
117 	hpfs_unlock(dir->i_sb);
118 	return 0;
119 bail3:
120 	iput(result);
121 bail2:
122 	hpfs_brelse4(&qbh0);
123 	hpfs_free_dnode(dir->i_sb, dno);
124 bail1:
125 	brelse(bh);
126 	hpfs_free_sectors(dir->i_sb, fno, 1);
127 bail:
128 	hpfs_unlock(dir->i_sb);
129 	return err;
130 }
131 
hpfs_create(struct user_namespace * mnt_userns,struct inode * dir,struct dentry * dentry,umode_t mode,bool excl)132 static int hpfs_create(struct user_namespace *mnt_userns, struct inode *dir,
133 		       struct dentry *dentry, umode_t mode, bool excl)
134 {
135 	const unsigned char *name = dentry->d_name.name;
136 	unsigned len = dentry->d_name.len;
137 	struct inode *result = NULL;
138 	struct buffer_head *bh;
139 	struct fnode *fnode;
140 	fnode_secno fno;
141 	int r;
142 	struct hpfs_dirent dee;
143 	int err;
144 	if ((err = hpfs_chk_name(name, &len)))
145 		return err==-ENOENT ? -EINVAL : err;
146 	hpfs_lock(dir->i_sb);
147 	err = -ENOSPC;
148 	fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
149 	if (!fnode)
150 		goto bail;
151 	memset(&dee, 0, sizeof dee);
152 	if (!(mode & 0222)) dee.read_only = 1;
153 	dee.archive = 1;
154 	dee.hidden = name[0] == '.';
155 	dee.fnode = cpu_to_le32(fno);
156 	dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
157 
158 	result = new_inode(dir->i_sb);
159 	if (!result)
160 		goto bail1;
161 
162 	hpfs_init_inode(result);
163 	result->i_ino = fno;
164 	result->i_mode |= S_IFREG;
165 	result->i_mode &= ~0111;
166 	result->i_op = &hpfs_file_iops;
167 	result->i_fop = &hpfs_file_ops;
168 	set_nlink(result, 1);
169 	hpfs_i(result)->i_parent_dir = dir->i_ino;
170 	result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, le32_to_cpu(dee.creation_date));
171 	result->i_ctime.tv_nsec = 0;
172 	result->i_mtime.tv_nsec = 0;
173 	result->i_atime.tv_nsec = 0;
174 	hpfs_i(result)->i_ea_size = 0;
175 	if (dee.read_only)
176 		result->i_mode &= ~0222;
177 	result->i_blocks = 1;
178 	result->i_size = 0;
179 	result->i_data.a_ops = &hpfs_aops;
180 	hpfs_i(result)->mmu_private = 0;
181 
182 	r = hpfs_add_dirent(dir, name, len, &dee);
183 	if (r == 1)
184 		goto bail2;
185 	if (r == -1) {
186 		err = -EEXIST;
187 		goto bail2;
188 	}
189 	fnode->len = len;
190 	memcpy(fnode->name, name, len > 15 ? 15 : len);
191 	fnode->up = cpu_to_le32(dir->i_ino);
192 	mark_buffer_dirty(bh);
193 	brelse(bh);
194 
195 	insert_inode_hash(result);
196 
197 	if (!uid_eq(result->i_uid, current_fsuid()) ||
198 	    !gid_eq(result->i_gid, current_fsgid()) ||
199 	    result->i_mode != (mode | S_IFREG)) {
200 		result->i_uid = current_fsuid();
201 		result->i_gid = current_fsgid();
202 		result->i_mode = mode | S_IFREG;
203 		hpfs_write_inode_nolock(result);
204 	}
205 	hpfs_update_directory_times(dir);
206 	d_instantiate(dentry, result);
207 	hpfs_unlock(dir->i_sb);
208 	return 0;
209 
210 bail2:
211 	iput(result);
212 bail1:
213 	brelse(bh);
214 	hpfs_free_sectors(dir->i_sb, fno, 1);
215 bail:
216 	hpfs_unlock(dir->i_sb);
217 	return err;
218 }
219 
hpfs_mknod(struct user_namespace * mnt_userns,struct inode * dir,struct dentry * dentry,umode_t mode,dev_t rdev)220 static int hpfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
221 		      struct dentry *dentry, umode_t mode, dev_t rdev)
222 {
223 	const unsigned char *name = dentry->d_name.name;
224 	unsigned len = dentry->d_name.len;
225 	struct buffer_head *bh;
226 	struct fnode *fnode;
227 	fnode_secno fno;
228 	int r;
229 	struct hpfs_dirent dee;
230 	struct inode *result = NULL;
231 	int err;
232 	if ((err = hpfs_chk_name(name, &len))) return err==-ENOENT ? -EINVAL : err;
233 	if (hpfs_sb(dir->i_sb)->sb_eas < 2) return -EPERM;
234 	hpfs_lock(dir->i_sb);
235 	err = -ENOSPC;
236 	fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
237 	if (!fnode)
238 		goto bail;
239 	memset(&dee, 0, sizeof dee);
240 	if (!(mode & 0222)) dee.read_only = 1;
241 	dee.archive = 1;
242 	dee.hidden = name[0] == '.';
243 	dee.fnode = cpu_to_le32(fno);
244 	dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
245 
246 	result = new_inode(dir->i_sb);
247 	if (!result)
248 		goto bail1;
249 
250 	hpfs_init_inode(result);
251 	result->i_ino = fno;
252 	hpfs_i(result)->i_parent_dir = dir->i_ino;
253 	result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, le32_to_cpu(dee.creation_date));
254 	result->i_ctime.tv_nsec = 0;
255 	result->i_mtime.tv_nsec = 0;
256 	result->i_atime.tv_nsec = 0;
257 	hpfs_i(result)->i_ea_size = 0;
258 	result->i_uid = current_fsuid();
259 	result->i_gid = current_fsgid();
260 	set_nlink(result, 1);
261 	result->i_size = 0;
262 	result->i_blocks = 1;
263 	init_special_inode(result, mode, rdev);
264 
265 	r = hpfs_add_dirent(dir, name, len, &dee);
266 	if (r == 1)
267 		goto bail2;
268 	if (r == -1) {
269 		err = -EEXIST;
270 		goto bail2;
271 	}
272 	fnode->len = len;
273 	memcpy(fnode->name, name, len > 15 ? 15 : len);
274 	fnode->up = cpu_to_le32(dir->i_ino);
275 	mark_buffer_dirty(bh);
276 
277 	insert_inode_hash(result);
278 
279 	hpfs_write_inode_nolock(result);
280 	hpfs_update_directory_times(dir);
281 	d_instantiate(dentry, result);
282 	brelse(bh);
283 	hpfs_unlock(dir->i_sb);
284 	return 0;
285 bail2:
286 	iput(result);
287 bail1:
288 	brelse(bh);
289 	hpfs_free_sectors(dir->i_sb, fno, 1);
290 bail:
291 	hpfs_unlock(dir->i_sb);
292 	return err;
293 }
294 
hpfs_symlink(struct user_namespace * mnt_userns,struct inode * dir,struct dentry * dentry,const char * symlink)295 static int hpfs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
296 			struct dentry *dentry, const char *symlink)
297 {
298 	const unsigned char *name = dentry->d_name.name;
299 	unsigned len = dentry->d_name.len;
300 	struct buffer_head *bh;
301 	struct fnode *fnode;
302 	fnode_secno fno;
303 	int r;
304 	struct hpfs_dirent dee;
305 	struct inode *result;
306 	int err;
307 	if ((err = hpfs_chk_name(name, &len))) return err==-ENOENT ? -EINVAL : err;
308 	hpfs_lock(dir->i_sb);
309 	if (hpfs_sb(dir->i_sb)->sb_eas < 2) {
310 		hpfs_unlock(dir->i_sb);
311 		return -EPERM;
312 	}
313 	err = -ENOSPC;
314 	fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
315 	if (!fnode)
316 		goto bail;
317 	memset(&dee, 0, sizeof dee);
318 	dee.archive = 1;
319 	dee.hidden = name[0] == '.';
320 	dee.fnode = cpu_to_le32(fno);
321 	dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
322 
323 	result = new_inode(dir->i_sb);
324 	if (!result)
325 		goto bail1;
326 	result->i_ino = fno;
327 	hpfs_init_inode(result);
328 	hpfs_i(result)->i_parent_dir = dir->i_ino;
329 	result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, le32_to_cpu(dee.creation_date));
330 	result->i_ctime.tv_nsec = 0;
331 	result->i_mtime.tv_nsec = 0;
332 	result->i_atime.tv_nsec = 0;
333 	hpfs_i(result)->i_ea_size = 0;
334 	result->i_mode = S_IFLNK | 0777;
335 	result->i_uid = current_fsuid();
336 	result->i_gid = current_fsgid();
337 	result->i_blocks = 1;
338 	set_nlink(result, 1);
339 	result->i_size = strlen(symlink);
340 	inode_nohighmem(result);
341 	result->i_op = &page_symlink_inode_operations;
342 	result->i_data.a_ops = &hpfs_symlink_aops;
343 
344 	r = hpfs_add_dirent(dir, name, len, &dee);
345 	if (r == 1)
346 		goto bail2;
347 	if (r == -1) {
348 		err = -EEXIST;
349 		goto bail2;
350 	}
351 	fnode->len = len;
352 	memcpy(fnode->name, name, len > 15 ? 15 : len);
353 	fnode->up = cpu_to_le32(dir->i_ino);
354 	hpfs_set_ea(result, fnode, "SYMLINK", symlink, strlen(symlink));
355 	mark_buffer_dirty(bh);
356 	brelse(bh);
357 
358 	insert_inode_hash(result);
359 
360 	hpfs_write_inode_nolock(result);
361 	hpfs_update_directory_times(dir);
362 	d_instantiate(dentry, result);
363 	hpfs_unlock(dir->i_sb);
364 	return 0;
365 bail2:
366 	iput(result);
367 bail1:
368 	brelse(bh);
369 	hpfs_free_sectors(dir->i_sb, fno, 1);
370 bail:
371 	hpfs_unlock(dir->i_sb);
372 	return err;
373 }
374 
hpfs_unlink(struct inode * dir,struct dentry * dentry)375 static int hpfs_unlink(struct inode *dir, struct dentry *dentry)
376 {
377 	const unsigned char *name = dentry->d_name.name;
378 	unsigned len = dentry->d_name.len;
379 	struct quad_buffer_head qbh;
380 	struct hpfs_dirent *de;
381 	struct inode *inode = d_inode(dentry);
382 	dnode_secno dno;
383 	int r;
384 	int err;
385 
386 	hpfs_lock(dir->i_sb);
387 	hpfs_adjust_length(name, &len);
388 
389 	err = -ENOENT;
390 	de = map_dirent(dir, hpfs_i(dir)->i_dno, name, len, &dno, &qbh);
391 	if (!de)
392 		goto out;
393 
394 	err = -EPERM;
395 	if (de->first)
396 		goto out1;
397 
398 	err = -EISDIR;
399 	if (de->directory)
400 		goto out1;
401 
402 	r = hpfs_remove_dirent(dir, dno, de, &qbh, 1);
403 	switch (r) {
404 	case 1:
405 		hpfs_error(dir->i_sb, "there was error when removing dirent");
406 		err = -EFSERROR;
407 		break;
408 	case 2:		/* no space for deleting */
409 		err = -ENOSPC;
410 		break;
411 	default:
412 		drop_nlink(inode);
413 		err = 0;
414 	}
415 	goto out;
416 
417 out1:
418 	hpfs_brelse4(&qbh);
419 out:
420 	if (!err)
421 		hpfs_update_directory_times(dir);
422 	hpfs_unlock(dir->i_sb);
423 	return err;
424 }
425 
hpfs_rmdir(struct inode * dir,struct dentry * dentry)426 static int hpfs_rmdir(struct inode *dir, struct dentry *dentry)
427 {
428 	const unsigned char *name = dentry->d_name.name;
429 	unsigned len = dentry->d_name.len;
430 	struct quad_buffer_head qbh;
431 	struct hpfs_dirent *de;
432 	struct inode *inode = d_inode(dentry);
433 	dnode_secno dno;
434 	int n_items = 0;
435 	int err;
436 	int r;
437 
438 	hpfs_adjust_length(name, &len);
439 	hpfs_lock(dir->i_sb);
440 	err = -ENOENT;
441 	de = map_dirent(dir, hpfs_i(dir)->i_dno, name, len, &dno, &qbh);
442 	if (!de)
443 		goto out;
444 
445 	err = -EPERM;
446 	if (de->first)
447 		goto out1;
448 
449 	err = -ENOTDIR;
450 	if (!de->directory)
451 		goto out1;
452 
453 	hpfs_count_dnodes(dir->i_sb, hpfs_i(inode)->i_dno, NULL, NULL, &n_items);
454 	err = -ENOTEMPTY;
455 	if (n_items)
456 		goto out1;
457 
458 	r = hpfs_remove_dirent(dir, dno, de, &qbh, 1);
459 	switch (r) {
460 	case 1:
461 		hpfs_error(dir->i_sb, "there was error when removing dirent");
462 		err = -EFSERROR;
463 		break;
464 	case 2:
465 		err = -ENOSPC;
466 		break;
467 	default:
468 		drop_nlink(dir);
469 		clear_nlink(inode);
470 		err = 0;
471 	}
472 	goto out;
473 out1:
474 	hpfs_brelse4(&qbh);
475 out:
476 	if (!err)
477 		hpfs_update_directory_times(dir);
478 	hpfs_unlock(dir->i_sb);
479 	return err;
480 }
481 
hpfs_symlink_read_folio(struct file * file,struct folio * folio)482 static int hpfs_symlink_read_folio(struct file *file, struct folio *folio)
483 {
484 	struct page *page = &folio->page;
485 	char *link = page_address(page);
486 	struct inode *i = page->mapping->host;
487 	struct fnode *fnode;
488 	struct buffer_head *bh;
489 	int err;
490 
491 	err = -EIO;
492 	hpfs_lock(i->i_sb);
493 	if (!(fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh)))
494 		goto fail;
495 	err = hpfs_read_ea(i->i_sb, fnode, "SYMLINK", link, PAGE_SIZE);
496 	brelse(bh);
497 	if (err)
498 		goto fail;
499 	hpfs_unlock(i->i_sb);
500 	SetPageUptodate(page);
501 	unlock_page(page);
502 	return 0;
503 
504 fail:
505 	hpfs_unlock(i->i_sb);
506 	SetPageError(page);
507 	unlock_page(page);
508 	return err;
509 }
510 
511 const struct address_space_operations hpfs_symlink_aops = {
512 	.read_folio	= hpfs_symlink_read_folio
513 };
514 
hpfs_rename(struct user_namespace * mnt_userns,struct inode * old_dir,struct dentry * old_dentry,struct inode * new_dir,struct dentry * new_dentry,unsigned int flags)515 static int hpfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
516 		       struct dentry *old_dentry, struct inode *new_dir,
517 		       struct dentry *new_dentry, unsigned int flags)
518 {
519 	const unsigned char *old_name = old_dentry->d_name.name;
520 	unsigned old_len = old_dentry->d_name.len;
521 	const unsigned char *new_name = new_dentry->d_name.name;
522 	unsigned new_len = new_dentry->d_name.len;
523 	struct inode *i = d_inode(old_dentry);
524 	struct inode *new_inode = d_inode(new_dentry);
525 	struct quad_buffer_head qbh, qbh1;
526 	struct hpfs_dirent *dep, *nde;
527 	struct hpfs_dirent de;
528 	dnode_secno dno;
529 	int r;
530 	struct buffer_head *bh;
531 	struct fnode *fnode;
532 	int err;
533 
534 	if (flags & ~RENAME_NOREPLACE)
535 		return -EINVAL;
536 
537 	if ((err = hpfs_chk_name(new_name, &new_len))) return err;
538 	err = 0;
539 	hpfs_adjust_length(old_name, &old_len);
540 
541 	hpfs_lock(i->i_sb);
542 	/* order doesn't matter, due to VFS exclusion */
543 
544 	/* Erm? Moving over the empty non-busy directory is perfectly legal */
545 	if (new_inode && S_ISDIR(new_inode->i_mode)) {
546 		err = -EINVAL;
547 		goto end1;
548 	}
549 
550 	if (!(dep = map_dirent(old_dir, hpfs_i(old_dir)->i_dno, old_name, old_len, &dno, &qbh))) {
551 		hpfs_error(i->i_sb, "lookup succeeded but map dirent failed");
552 		err = -ENOENT;
553 		goto end1;
554 	}
555 	copy_de(&de, dep);
556 	de.hidden = new_name[0] == '.';
557 
558 	if (new_inode) {
559 		int r;
560 		if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 1)) != 2) {
561 			if ((nde = map_dirent(new_dir, hpfs_i(new_dir)->i_dno, new_name, new_len, NULL, &qbh1))) {
562 				clear_nlink(new_inode);
563 				copy_de(nde, &de);
564 				memcpy(nde->name, new_name, new_len);
565 				hpfs_mark_4buffers_dirty(&qbh1);
566 				hpfs_brelse4(&qbh1);
567 				goto end;
568 			}
569 			hpfs_error(new_dir->i_sb, "hpfs_rename: could not find dirent");
570 			err = -EFSERROR;
571 			goto end1;
572 		}
573 		err = -ENOSPC;
574 		goto end1;
575 	}
576 
577 	if (new_dir == old_dir) hpfs_brelse4(&qbh);
578 
579 	if ((r = hpfs_add_dirent(new_dir, new_name, new_len, &de))) {
580 		if (r == -1) hpfs_error(new_dir->i_sb, "hpfs_rename: dirent already exists!");
581 		err = r == 1 ? -ENOSPC : -EFSERROR;
582 		if (new_dir != old_dir) hpfs_brelse4(&qbh);
583 		goto end1;
584 	}
585 
586 	if (new_dir == old_dir)
587 		if (!(dep = map_dirent(old_dir, hpfs_i(old_dir)->i_dno, old_name, old_len, &dno, &qbh))) {
588 			hpfs_error(i->i_sb, "lookup succeeded but map dirent failed at #2");
589 			err = -ENOENT;
590 			goto end1;
591 		}
592 
593 	if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 0))) {
594 		hpfs_error(i->i_sb, "hpfs_rename: could not remove dirent");
595 		err = r == 2 ? -ENOSPC : -EFSERROR;
596 		goto end1;
597 	}
598 
599 end:
600 	hpfs_i(i)->i_parent_dir = new_dir->i_ino;
601 	if (S_ISDIR(i->i_mode)) {
602 		inc_nlink(new_dir);
603 		drop_nlink(old_dir);
604 	}
605 	if ((fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) {
606 		fnode->up = cpu_to_le32(new_dir->i_ino);
607 		fnode->len = new_len;
608 		memcpy(fnode->name, new_name, new_len>15?15:new_len);
609 		if (new_len < 15) memset(&fnode->name[new_len], 0, 15 - new_len);
610 		mark_buffer_dirty(bh);
611 		brelse(bh);
612 	}
613 end1:
614 	if (!err) {
615 		hpfs_update_directory_times(old_dir);
616 		hpfs_update_directory_times(new_dir);
617 	}
618 	hpfs_unlock(i->i_sb);
619 	return err;
620 }
621 
622 const struct inode_operations hpfs_dir_iops =
623 {
624 	.create		= hpfs_create,
625 	.lookup		= hpfs_lookup,
626 	.unlink		= hpfs_unlink,
627 	.symlink	= hpfs_symlink,
628 	.mkdir		= hpfs_mkdir,
629 	.rmdir		= hpfs_rmdir,
630 	.mknod		= hpfs_mknod,
631 	.rename		= hpfs_rename,
632 	.setattr	= hpfs_setattr,
633 };
634