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