• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * JFFS2 -- Journalling Flash File System, Version 2.
3  *
4  * Copyright © 2001-2007 Red Hat, Inc.
5  * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
6  *
7  * Created by David Woodhouse <dwmw2@infradead.org>
8  *
9  * For licensing information, see the file 'LICENCE' in this directory.
10  *
11  */
12 
13 #include <dirent.h>
14 #include <linux/kernel.h>
15 #include <linux/slab.h>
16 #include <linux/fs.h>
17 #include "los_crc32.h"
18 #include "nodelist.h"
19 #include "vfs_jffs2.h"
20 #include "jffs2_hash.h"
21 
22 /* We keep the dirent list sorted in increasing order of name hash,
23    and we use the same hash function as the dentries. Makes this
24    nice and simple
25 */
jffs2_lookup(struct jffs2_inode * dir_i,const unsigned char * d_name,int namelen)26 struct jffs2_inode *jffs2_lookup(struct jffs2_inode *dir_i, const unsigned char *d_name, int namelen)
27 {
28 	struct jffs2_inode_info *dir_f;
29 	struct jffs2_full_dirent *fd = NULL, *fd_list;
30 	uint32_t ino = 0;
31 	uint32_t hash = full_name_hash(d_name, namelen);
32 	struct jffs2_inode *inode = NULL;
33 
34 	jffs2_dbg(1, "jffs2_lookup()\n");
35 
36 	if (namelen > JFFS2_MAX_NAME_LEN)
37 		return ERR_PTR(-ENAMETOOLONG);
38 
39 	dir_f = JFFS2_INODE_INFO(dir_i);
40 
41 	mutex_lock(&dir_f->sem);
42 
43 	/* NB: The 2.2 backport will need to explicitly check for '.' and '..' here */
44 	for (fd_list = dir_f->dents; fd_list && fd_list->nhash <= hash; fd_list = fd_list->next) {
45 		if (fd_list->nhash == hash &&
46 			(!fd || fd_list->version > fd->version) &&
47 			strlen((char *)fd_list->name) == namelen &&
48 			!strncmp((char *)fd_list->name, (char *)d_name, namelen)) {
49 			fd = fd_list;
50 		}
51 	}
52 	if (fd)
53 		ino = fd->ino;
54 	mutex_unlock(&dir_f->sem);
55 	if (ino) {
56 		inode = jffs2_iget(dir_i->i_sb, ino);
57 		if (IS_ERR(inode))
58 			pr_warn("iget() failed for ino #%u\n", ino);
59 	}
60 
61 	return inode;
62 }
63 
jffs2_unlink(struct jffs2_inode * dir_i,struct jffs2_inode * d_inode,const unsigned char * d_name)64 int jffs2_unlink(struct jffs2_inode *dir_i, struct jffs2_inode *d_inode, const unsigned char *d_name)
65 {
66 	struct jffs2_sb_info *c = JFFS2_SB_INFO(dir_i->i_sb);
67 	struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i);
68 	struct jffs2_inode_info *dead_f = JFFS2_INODE_INFO(d_inode);
69 	int ret;
70 	uint32_t now = Jffs2CurSec();
71 
72 	ret = jffs2_do_unlink(c, dir_f, (const char *)d_name,
73 		strlen((char *)d_name), dead_f, now);
74 	if (dead_f->inocache)
75 		d_inode->i_nlink = dead_f->inocache->pino_nlink;
76 	if (!ret)
77 		dir_i->i_mtime = dir_i->i_ctime = now;
78 	return ret;
79 }
80 
jffs2_link(struct jffs2_inode * old_d_inode,struct jffs2_inode * dir_i,const unsigned char * d_name)81 int jffs2_link(struct jffs2_inode *old_d_inode, struct jffs2_inode *dir_i, const unsigned char *d_name)
82 {
83 	struct jffs2_sb_info *c = JFFS2_SB_INFO(old_d_inode->i_sb);
84 	struct jffs2_inode_info *f = JFFS2_INODE_INFO(old_d_inode);
85 	struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i);
86 	int ret;
87 	uint8_t type;
88 	uint32_t now;
89 
90 	/* XXX: This is ugly */
91 	type = (old_d_inode->i_mode & S_IFMT) >> 12;
92 	if (!type) type = DT_REG;
93 
94 	now = Jffs2CurSec();
95 	ret = jffs2_do_link(c, dir_f, f->inocache->ino, type, (const char *)d_name,
96 						strlen((char *)d_name), now);
97 
98 	if (!ret) {
99 		mutex_lock(&f->sem);
100 		old_d_inode->i_nlink = ++f->inocache->pino_nlink;
101 		mutex_unlock(&f->sem);
102 		dir_i->i_mtime = dir_i->i_ctime = now;
103 	}
104 	return ret;
105 }
106 
jffs2_symlink(struct jffs2_inode * dir_i,struct jffs2_inode ** d_inode,const unsigned char * d_name,const char * target)107 int jffs2_symlink(struct jffs2_inode *dir_i, struct jffs2_inode **d_inode, const unsigned char *d_name, const char *target)
108 {
109 	struct jffs2_inode_info *f, *dir_f;
110 	struct jffs2_sb_info *c;
111 	struct jffs2_inode *inode;
112 	struct jffs2_raw_inode *ri;
113 	struct jffs2_raw_dirent *rd;
114 	struct jffs2_full_dnode *fn;
115 	struct jffs2_full_dirent *fd;
116 	int namelen;
117 	uint32_t alloclen;
118 	int ret, targetlen = strlen(target);
119 
120 	/* FIXME: If you care. We'd need to use frags for the target
121 	   if it grows much more than this */
122 	if (targetlen > 254)
123 		return -ENAMETOOLONG;
124 
125 	ri = jffs2_alloc_raw_inode();
126 
127 	if (!ri)
128 		return -ENOMEM;
129 
130 	c = JFFS2_SB_INFO(dir_i->i_sb);
131 
132 	/* Try to reserve enough space for both node and dirent.
133 	 * Just the node will do for now, though
134 	 */
135 	namelen = strlen((char *)d_name);
136 	ret = jffs2_reserve_space(c, sizeof(*ri) + targetlen, &alloclen,
137 				  ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
138 
139 	if (ret) {
140 		jffs2_free_raw_inode(ri);
141 		return ret;
142 	}
143 
144 	inode = jffs2_new_inode(dir_i, S_IFLNK | S_IRWXUGO, ri);
145 
146 	if (IS_ERR(inode)) {
147 		jffs2_free_raw_inode(ri);
148 		jffs2_complete_reservation(c);
149 		return PTR_ERR(inode);
150 	}
151 
152 	f = JFFS2_INODE_INFO(inode);
153 
154 	inode->i_size = targetlen;
155 	ri->isize = ri->dsize = ri->csize = cpu_to_je32(inode->i_size);
156 	ri->totlen = cpu_to_je32(sizeof(*ri) + inode->i_size);
157 	ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
158 
159 	ri->compr = JFFS2_COMPR_NONE;
160 	ri->data_crc = cpu_to_je32(crc32(0, target, targetlen));
161 	ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
162 
163 	fn = jffs2_write_dnode(c, f, ri, (const unsigned char *)target, targetlen, ALLOC_NORMAL);
164 
165 	jffs2_free_raw_inode(ri);
166 
167 	if (IS_ERR(fn)) {
168 		/* Eeek. Wave bye bye */
169 		mutex_unlock(&f->sem);
170 		jffs2_complete_reservation(c);
171 		ret = PTR_ERR(fn);
172 		goto fail;
173 	}
174 
175 	/* We use f->target field to store the target path. */
176 
177 	f->target = (unsigned char *)malloc(targetlen + 1);
178 	if (!f->target) {
179 		pr_warn("Can't allocate %d bytes of memory\n", targetlen + 1);
180 		mutex_unlock(&f->sem);
181 		jffs2_complete_reservation(c);
182 		ret = -ENOMEM;
183 		goto fail;
184 	}
185 
186 	ret = LOS_CopyToKernel((char *)f->target, targetlen + 1, target, targetlen + 1);
187 	if (ret != EOK) {
188 		(void)free(f->target);
189 		f->target = NULL;
190 		mutex_unlock(&f->sem);
191 		jffs2_complete_reservation(c);
192 		goto fail;
193 	}
194 
195 	jffs2_dbg(1, "%s(): symlink's target '%s' cached\n",
196 		  __func__, (char *)f->target);
197 
198 	/* No data here. Only a metadata node, which will be
199 	   obsoleted by the first data write
200 	*/
201 	f->metadata = fn;
202 	mutex_unlock(&f->sem);
203 
204 	jffs2_complete_reservation(c);
205 
206 	ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen,
207 				  ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
208 	if (ret)
209 		goto fail;
210 
211 	rd = jffs2_alloc_raw_dirent();
212 	if (!rd) {
213 		/* Argh. Now we treat it like a normal delete */
214 		jffs2_complete_reservation(c);
215 		ret = -ENOMEM;
216 		goto fail;
217 	}
218 
219 	dir_f = JFFS2_INODE_INFO(dir_i);
220 	mutex_lock(&dir_f->sem);
221 
222 	rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
223 	rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
224 	rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
225 	rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
226 
227 	rd->pino = cpu_to_je32(dir_i->i_ino);
228 	rd->version = cpu_to_je32(++dir_f->highest_version);
229 	rd->ino = cpu_to_je32(inode->i_ino);
230 	rd->mctime = cpu_to_je32(Jffs2CurSec());
231 	rd->nsize = namelen;
232 	rd->type = DT_LNK;
233 	rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
234 	rd->name_crc = cpu_to_je32(crc32(0, (const char *)d_name, namelen));
235 
236 	fd = jffs2_write_dirent(c, dir_f, rd, (const unsigned char *)d_name, namelen, ALLOC_NORMAL);
237 
238 	if (IS_ERR(fd)) {
239 		/* dirent failed to write. Delete the inode normally
240 		   as if it were the final unlink() */
241 		jffs2_complete_reservation(c);
242 		jffs2_free_raw_dirent(rd);
243 		mutex_unlock(&dir_f->sem);
244 		ret = PTR_ERR(fd);
245 		goto fail;
246 	}
247 
248 	dir_i->i_mtime = dir_i->i_ctime = je32_to_cpu(rd->mctime);
249 
250 	jffs2_free_raw_dirent(rd);
251 
252 	/* Link the fd into the inode's list, obsoleting an old
253 	   one if necessary. */
254 	jffs2_add_fd_to_list(c, fd, &dir_f->dents);
255 
256 	mutex_unlock(&dir_f->sem);
257 	jffs2_complete_reservation(c);
258 
259 	*d_inode = inode;
260 	return 0;
261 
262  fail:
263 	inode->i_nlink = 0;
264 	jffs2_iput(inode);
265 	return ret;
266 }
267 
jffs2_mkdir(struct jffs2_inode * dir_i,const unsigned char * d_name,int mode,struct jffs2_inode ** new_i)268 int jffs2_mkdir(struct jffs2_inode *dir_i, const unsigned char *d_name, int mode, struct jffs2_inode **new_i)
269 {
270 	struct jffs2_inode_info *f, *dir_f;
271 	struct jffs2_sb_info *c;
272 	struct jffs2_inode *inode;
273 	struct jffs2_raw_inode *ri;
274 	struct jffs2_raw_dirent *rd;
275 	struct jffs2_full_dnode *fn;
276 	struct jffs2_full_dirent *fd;
277 	int namelen;
278 	uint32_t alloclen;
279 	int ret;
280 	mode  &= ~S_IFMT;
281 	mode |= S_IFDIR;
282 
283 	ri = jffs2_alloc_raw_inode();
284 	if (!ri)
285 		return -ENOMEM;
286 
287 	c = JFFS2_SB_INFO(dir_i->i_sb);
288 
289 	/* Try to reserve enough space for both node and dirent.
290 	 * Just the node will do for now, though
291 	 */
292 	namelen = strlen((char *)d_name);
293 	ret = jffs2_reserve_space(c, sizeof(*ri), &alloclen, ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
294 
295 	if (ret) {
296 		jffs2_free_raw_inode(ri);
297 		return ret;
298 	}
299 
300 	inode = jffs2_new_inode(dir_i, mode, ri);
301 
302 	if (IS_ERR(inode)) {
303 		jffs2_free_raw_inode(ri);
304 		jffs2_complete_reservation(c);
305 		return PTR_ERR(inode);
306 	}
307 	f = JFFS2_INODE_INFO(inode);
308 
309 	/* but ic->pino_nlink is the parent ino# */
310 	f->inocache->pino_nlink = dir_i->i_ino;
311 
312 	ri->data_crc = cpu_to_je32(0);
313 	ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
314 
315 	fn = jffs2_write_dnode(c, f, ri, NULL, 0, ALLOC_NORMAL);
316 
317 	jffs2_free_raw_inode(ri);
318 
319 	if (IS_ERR(fn)) {
320 		/* Eeek. Wave bye bye */
321 		mutex_unlock(&f->sem);
322 		jffs2_complete_reservation(c);
323 
324 		ret = PTR_ERR(fn);
325 		goto fail;
326 	}
327 	/* No data here. Only a metadata node, which will be
328 	   obsoleted by the first data write
329 	*/
330 	f->metadata = fn;
331 	mutex_unlock(&f->sem);
332 
333 	jffs2_complete_reservation(c);
334 
335 	ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen,
336 				  ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
337 	if (ret)
338 		goto fail;
339 
340 	rd = jffs2_alloc_raw_dirent();
341 	if (!rd) {
342 		/* Argh. Now we treat it like a normal delete */
343 		jffs2_complete_reservation(c);
344 		ret = -ENOMEM;
345 		goto fail;
346 	}
347 
348 	dir_f = JFFS2_INODE_INFO(dir_i);
349 	mutex_lock(&dir_f->sem);
350 
351 	rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
352 	rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
353 	rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
354 	rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
355 
356 	rd->pino = cpu_to_je32(dir_i->i_ino);
357 	rd->version = cpu_to_je32(++dir_f->highest_version);
358 	rd->ino = cpu_to_je32(inode->i_ino);
359 	rd->mctime = cpu_to_je32(Jffs2CurSec());
360 	rd->nsize = namelen;
361 	rd->type = DT_DIR;
362 	rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
363 	rd->name_crc = cpu_to_je32(crc32(0, d_name, namelen));
364 
365 	fd = jffs2_write_dirent(c, dir_f, rd, d_name, namelen, ALLOC_NORMAL);
366 
367 	if (IS_ERR(fd)) {
368 		/* dirent failed to write. Delete the inode normally
369 		   as if it were the final unlink() */
370 		jffs2_complete_reservation(c);
371 		jffs2_free_raw_dirent(rd);
372 		mutex_unlock(&dir_f->sem);
373 		inode->i_nlink = 0;
374 		ret = PTR_ERR(fd);
375 		goto fail;
376 	}
377 
378 	dir_i->i_mtime = dir_i->i_ctime = je32_to_cpu(rd->mctime);
379 
380 	jffs2_free_raw_dirent(rd);
381 
382 	/* Link the fd into the inode's list, obsoleting an old
383 	   one if necessary. */
384 	jffs2_add_fd_to_list(c, fd, &dir_f->dents);
385 
386 	mutex_unlock(&dir_f->sem);
387 	jffs2_complete_reservation(c);
388 	*new_i = inode;
389 
390 	return 0;
391 
392  fail:
393 	inode->i_nlink = 0;
394 	jffs2_iput(inode);
395 	return ret;
396 }
397 
jffs2_rmdir(struct jffs2_inode * dir_i,struct jffs2_inode * d_inode,const unsigned char * d_name)398 int jffs2_rmdir (struct jffs2_inode *dir_i, struct jffs2_inode *d_inode, const unsigned char *d_name)
399 {
400 	struct jffs2_sb_info *c = JFFS2_SB_INFO(dir_i->i_sb);
401 	struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i);
402 	struct jffs2_inode_info *f = JFFS2_INODE_INFO(d_inode);
403 	struct jffs2_full_dirent *fd;
404 	int ret;
405 	uint32_t now = Jffs2CurSec();
406 
407 	for (fd = f->dents ; fd; fd = fd->next) {
408 		if (fd->ino) {
409 			PRINT_ERR("%s-%d: ret=%d\n", __FUNCTION__, __LINE__, ENOTEMPTY);
410 			return -ENOTEMPTY;
411 		}
412 	}
413 
414 	ret = jffs2_do_unlink(c, dir_f, (const char *)d_name,
415 						strlen((char *)d_name), f, now);
416 	if (f->inocache)
417 		d_inode->i_nlink = f->inocache->pino_nlink;
418 	if (!ret)
419 		dir_i->i_mtime = dir_i->i_ctime = now;
420 
421 	return ret;
422 }
423 
jffs2_rename(struct jffs2_inode * old_dir_i,struct jffs2_inode * d_inode,const unsigned char * old_d_name,struct jffs2_inode * new_dir_i,const unsigned char * new_d_name)424 int jffs2_rename (struct jffs2_inode *old_dir_i, struct jffs2_inode *d_inode, const unsigned char *old_d_name,
425 		struct jffs2_inode *new_dir_i, const unsigned char *new_d_name)
426 {
427 	int ret;
428 	struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb);
429 	uint8_t type;
430 	uint32_t now;
431 
432 	/* XXX: This is ugly */
433 	type = (d_inode->i_mode & S_IFMT) >> 12;
434 	if (!type) type = DT_REG;
435 
436 	now = Jffs2CurSec();
437 	ret = jffs2_do_link(c, JFFS2_INODE_INFO(new_dir_i),
438 				d_inode->i_ino, type,
439 				(const char *)new_d_name, strlen((char *)new_d_name), now);
440 
441 	if (ret)
442 		return ret;
443 
444 
445 	/* If it was a directory we moved, and there was no victim,
446 	   increase i_nlink on its new parent */
447 	if ((d_inode->i_mode & S_IFMT) == S_IFDIR) {
448 		new_dir_i->i_nlink++;
449 	}
450 
451 	/* Unlink the original */
452 	ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i),
453 				(const char *)old_d_name, strlen((char *)old_d_name), NULL, now);
454 
455 	/* We don't touch inode->i_nlink */
456 
457 	if (ret) {
458 		/* Oh shit. We really ought to make a single node which can do both atomically */
459 		struct jffs2_inode_info *f = JFFS2_INODE_INFO(d_inode);
460 		mutex_lock(&f->sem);
461 		if (f->inocache)
462 			d_inode->i_nlink = f->inocache->pino_nlink++;
463 		mutex_unlock(&f->sem);
464 
465 		pr_notice("%s(): Link succeeded, unlink failed (err %d). You now have a hard link\n",
466 			  __func__, ret);
467 		/* Might as well let the VFS know */
468 		new_dir_i->i_mtime = new_dir_i->i_ctime = now;
469 		return ret;
470 	}
471 
472 
473 	new_dir_i->i_mtime = new_dir_i->i_ctime = old_dir_i->i_mtime = old_dir_i->i_ctime = now;
474 
475 	return 0;
476 }
477 
jffs2_create(struct jffs2_inode * dir_i,const unsigned char * d_name,int mode,struct jffs2_inode ** new_i)478 int jffs2_create(struct jffs2_inode *dir_i, const unsigned char *d_name, int mode,
479 		struct jffs2_inode **new_i)
480 {
481 	struct jffs2_raw_inode *ri;
482 	struct jffs2_inode_info *f, *dir_f;
483 	struct jffs2_sb_info *c;
484 	struct jffs2_inode *inode;
485 	int ret;
486 	mode  &= ~S_IFMT;
487 	mode |= S_IFREG;
488 	ri = jffs2_alloc_raw_inode();
489 	if (!ri)
490 		return -ENOMEM;
491 
492 	c = JFFS2_SB_INFO(dir_i->i_sb);
493 
494 	D1(printk(KERN_DEBUG "jffs2_create()\n"));
495 	inode = jffs2_new_inode(dir_i, mode, ri);
496 
497 	if (IS_ERR(inode)) {
498 		D1(printk(KERN_DEBUG "jffs2_new_inode() failed, error:%ld\n", PTR_ERR(inode)));
499 		jffs2_free_raw_inode(ri);
500 		return PTR_ERR(inode);
501 	}
502 
503 	f = JFFS2_INODE_INFO(inode);
504 	dir_f = JFFS2_INODE_INFO(dir_i);
505 
506 	/* jffs2_do_create() will want to lock it, _after_ reserving
507 	   space and taking c-alloc_sem. If we keep it locked here,
508 	   lockdep gets unhappy (although it's a false positive;
509 	   nothing else will be looking at this inode yet so there's
510 	   no chance of AB-BA deadlock involving its f->sem). */
511 	mutex_unlock(&f->sem);
512 	ret = jffs2_do_create(c, dir_f, f, ri,
513 				(const char *)d_name,
514 				strlen((char *)d_name));
515 
516 	if (ret) {
517 		inode->i_nlink = 0;
518 		jffs2_iput(inode);
519 		jffs2_free_raw_inode(ri);
520 		return ret;
521 	}
522 
523 	jffs2_free_raw_inode(ri);
524 
525 	D1(printk(KERN_DEBUG "jffs2_create: Created ino #%lu with mode %o, nlink %d(%d)\n",
526 		inode->i_ino, inode->i_mode, inode->i_nlink, f->inocache->pino_nlink));
527 	*new_i = inode;
528 	return 0;
529 }
530 
fill_name(char * dst_name,int nlen,const unsigned char * name,int namlen)531 static __inline void fill_name(char *dst_name, int nlen, const unsigned char *name, int namlen)
532 {
533 	int len = nlen < namlen ? nlen : namlen;
534 	(void)memcpy_s(dst_name, nlen, name, len);
535 	dst_name[len] = '\0';
536 }
537 
jffs2_readdir(struct jffs2_inode * inode,off_t * offset,off_t * int_off,struct dirent * ent)538 int jffs2_readdir(struct jffs2_inode *inode, off_t *offset, off_t *int_off, struct dirent *ent)
539 {
540 	struct jffs2_inode_info *f;
541 	struct jffs2_full_dirent *fd;
542 	off_t curofs = 0;
543 
544 	f = JFFS2_INODE_INFO(inode);
545 
546 	mutex_lock(&f->sem);
547 	for (fd = f->dents; fd; fd = fd->next) {
548 		if (curofs++ < *int_off) {
549 			D2(printk
550 				(KERN_DEBUG
551 				"Skipping dirent: \"%s\", ino #%u, type %d, because curofs %ld < offset %ld\n",
552 				fd->name, fd->ino, fd->type, curofs, offset));
553 			continue;
554 		}
555 		if (!fd->ino) {
556 			D2(printk (KERN_DEBUG "Skipping deletion dirent \"%s\"\n", fd->name));
557 			(*int_off)++;
558 			continue;
559 		}
560 
561 		D2(printk
562 			(KERN_DEBUG "%s-%d: Dirent %ld: \"%s\", ino #%u, type %d\n", __FUNCTION__, __LINE__, offset,
563 			fd->name, fd->ino, fd->type));
564 		fill_name(ent->d_name, sizeof(ent->d_name) - 1, fd->name, strlen((char *)fd->name));
565 		ent->d_type = fd->type;
566 		ent->d_off = ++(*offset);
567 		ent->d_reclen = (uint16_t)sizeof(struct dirent);
568 
569 		(*int_off)++;
570 		break;
571 	}
572 
573 	mutex_unlock(&f->sem);
574 
575 	if (fd == NULL) {
576 		D2(printk(KERN_DEBUG "reached the end of the directory\n"));
577 		return ENOENT;
578 	}
579 
580 	return ENOERR;
581 }
582 
583