2 * linux/fs/ufs/ufs_dir.c
5 * Adrian Rodriguez (adrian@franklins-tower.rutgers.edu)
6 * Laboratory for Computer Science Research Computing Facility
7 * Rutgers, The State University of New Jersey
9 * swab support by Francois-Rene Rideau <fare@tunes.org> 19970406
11 * 4.4BSD (FreeBSD) support added on February 1st 1998 by
12 * Niels Kristian Bech Jensen <nkbj@image.dk> partially based
13 * on code by Martin von Loewis <martin@mira.isdn.cs.tu-berlin.de>.
16 #include <linux/time.h>
18 #include <linux/ufs_fs.h>
19 #include <linux/smp_lock.h>
20 #include <linux/buffer_head.h>
21 #include <linux/sched.h>
29 #define UFSD(x) printk("(%s, %d), %s: ", __FILE__, __LINE__, __FUNCTION__); printk x;
35 ufs_check_dir_entry (const char *, struct inode
*, struct ufs_dir_entry
*,
36 struct buffer_head
*, unsigned long);
40 * NOTE! unlike strncmp, ufs_match returns 1 for success, 0 for failure.
42 * len <= UFS_MAXNAMLEN and de != NULL are guaranteed by caller.
44 static inline int ufs_match(struct super_block
*sb
, int len
,
45 const char * const name
, struct ufs_dir_entry
* de
)
47 if (len
!= ufs_get_de_namlen(sb
, de
))
51 return !memcmp(name
, de
->d_name
, len
);
55 * This is blatantly stolen from ext2fs
58 ufs_readdir (struct file
* filp
, void * dirent
, filldir_t filldir
)
60 struct inode
*inode
= filp
->f_dentry
->d_inode
;
62 unsigned long offset
, lblk
;
64 struct buffer_head
* bh
;
65 struct ufs_dir_entry
* de
;
66 struct super_block
* sb
;
74 flags
= UFS_SB(sb
)->s_flags
;
76 UFSD(("ENTER, ino %lu f_pos %lu\n", inode
->i_ino
, (unsigned long) filp
->f_pos
))
80 offset
= filp
->f_pos
& (sb
->s_blocksize
- 1);
82 while (!error
&& !stored
&& filp
->f_pos
< inode
->i_size
) {
83 lblk
= (filp
->f_pos
) >> sb
->s_blocksize_bits
;
84 blk
= ufs_frag_map(inode
, lblk
);
85 if (!blk
|| !(bh
= sb_bread(sb
, blk
))) {
86 /* XXX - error - skip to the next block */
87 printk("ufs_readdir: "
88 "dir inode %lu has a hole at offset %lu\n",
89 inode
->i_ino
, (unsigned long int)filp
->f_pos
);
90 filp
->f_pos
+= sb
->s_blocksize
- offset
;
95 /* If the dir block has changed since the last call to
96 * readdir(2), then we might be pointing to an invalid
97 * dirent right now. Scan from the start of the block
99 if (filp
->f_version
!= inode
->i_version
) {
100 for (i
= 0; i
< sb
->s_blocksize
&& i
< offset
; ) {
101 de
= (struct ufs_dir_entry
*)(bh
->b_data
+ i
);
102 /* It's too expensive to do a full
103 * dirent test each time round this
104 * loop, but we do have to test at
105 * least that it is non-zero. A
106 * failure will be detected in the
107 * dirent test below. */
108 de_reclen
= fs16_to_cpu(sb
, de
->d_reclen
);
114 filp
->f_pos
= (filp
->f_pos
& ~(sb
->s_blocksize
- 1))
116 filp
->f_version
= inode
->i_version
;
119 while (!error
&& filp
->f_pos
< inode
->i_size
120 && offset
< sb
->s_blocksize
) {
121 de
= (struct ufs_dir_entry
*) (bh
->b_data
+ offset
);
122 /* XXX - put in a real ufs_check_dir_entry() */
123 if ((de
->d_reclen
== 0) || (ufs_get_de_namlen(sb
, de
) == 0)) {
124 filp
->f_pos
= (filp
->f_pos
&
125 (sb
->s_blocksize
- 1)) +
131 if (!ufs_check_dir_entry ("ufs_readdir", inode
, de
,
133 /* On error, skip the f_pos to the
135 filp
->f_pos
= (filp
->f_pos
|
136 (sb
->s_blocksize
- 1)) +
142 offset
+= fs16_to_cpu(sb
, de
->d_reclen
);
144 /* We might block in the next section
145 * if the data destination is
146 * currently swapped out. So, use a
147 * version stamp to detect whether or
148 * not the directory has been modified
149 * during the copy operation. */
150 unsigned long version
= filp
->f_version
;
151 unsigned char d_type
= DT_UNKNOWN
;
153 UFSD(("filldir(%s,%u)\n", de
->d_name
,
154 fs32_to_cpu(sb
, de
->d_ino
)))
155 UFSD(("namlen %u\n", ufs_get_de_namlen(sb
, de
)))
157 if ((flags
& UFS_DE_MASK
) == UFS_DE_44BSD
)
158 d_type
= de
->d_u
.d_44
.d_type
;
159 error
= filldir(dirent
, de
->d_name
,
160 ufs_get_de_namlen(sb
, de
), filp
->f_pos
,
161 fs32_to_cpu(sb
, de
->d_ino
), d_type
);
164 if (version
!= filp
->f_version
)
168 filp
->f_pos
+= fs16_to_cpu(sb
, de
->d_reclen
);
178 * define how far ahead to read directories while searching them.
180 #define NAMEI_RA_CHUNKS 2
181 #define NAMEI_RA_BLOCKS 4
182 #define NAMEI_RA_SIZE (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
183 #define NAMEI_RA_INDEX(c,b) (((c) * NAMEI_RA_BLOCKS) + (b))
188 * finds an entry in the specified directory with the wanted name. It
189 * returns the cache buffer in which the entry was found, and the entry
190 * itself (as a parameter - res_bh). It does NOT read the inode of the
191 * entry - you'll have to do that yourself if you want to.
193 struct ufs_dir_entry
* ufs_find_entry (struct dentry
*dentry
,
194 struct buffer_head
** res_bh
)
196 struct super_block
* sb
;
197 struct buffer_head
* bh_use
[NAMEI_RA_SIZE
];
198 struct buffer_head
* bh_read
[NAMEI_RA_SIZE
];
199 unsigned long offset
;
200 int block
, toread
, i
, err
;
201 struct inode
*dir
= dentry
->d_parent
->d_inode
;
202 const char *name
= dentry
->d_name
.name
;
203 int namelen
= dentry
->d_name
.len
;
205 UFSD(("ENTER, dir_ino %lu, name %s, namlen %u\n", dir
->i_ino
, name
, namelen
))
211 if (namelen
> UFS_MAXNAMLEN
)
214 memset (bh_use
, 0, sizeof (bh_use
));
216 for (block
= 0; block
< NAMEI_RA_SIZE
; ++block
) {
217 struct buffer_head
* bh
;
219 if ((block
<< sb
->s_blocksize_bits
) >= dir
->i_size
)
221 bh
= ufs_getfrag (dir
, block
, 0, &err
);
223 if (bh
&& !buffer_uptodate(bh
))
224 bh_read
[toread
++] = bh
;
227 for (block
= 0, offset
= 0; offset
< dir
->i_size
; block
++) {
228 struct buffer_head
* bh
;
229 struct ufs_dir_entry
* de
;
232 if ((block
% NAMEI_RA_BLOCKS
) == 0 && toread
) {
233 ll_rw_block (READ
, toread
, bh_read
);
236 bh
= bh_use
[block
% NAMEI_RA_SIZE
];
238 ufs_error (sb
, "ufs_find_entry",
239 "directory #%lu contains a hole at offset %lu",
241 offset
+= sb
->s_blocksize
;
245 if (!buffer_uptodate(bh
)) {
247 * read error: all bets are off
252 de
= (struct ufs_dir_entry
*) bh
->b_data
;
253 dlimit
= bh
->b_data
+ sb
->s_blocksize
;
254 while ((char *) de
< dlimit
&& offset
< dir
->i_size
) {
255 /* this code is executed quadratically often */
256 /* do minimal checking by hand */
259 if ((char *) de
+ namelen
<= dlimit
&&
260 ufs_match(sb
, namelen
, name
, de
)) {
262 just to be sure, do a full check */
263 if (!ufs_check_dir_entry("ufs_find_entry",
264 dir
, de
, bh
, offset
))
266 for (i
= 0; i
< NAMEI_RA_SIZE
; ++i
) {
273 /* prevent looping on a bad block */
274 de_len
= fs16_to_cpu(sb
, de
->d_reclen
);
278 de
= (struct ufs_dir_entry
*) ((char *) de
+ de_len
);
282 if (((block
+ NAMEI_RA_SIZE
) << sb
->s_blocksize_bits
) >=
286 bh
= ufs_getfrag (dir
, block
+ NAMEI_RA_SIZE
, 0, &err
);
287 bh_use
[block
% NAMEI_RA_SIZE
] = bh
;
288 if (bh
&& !buffer_uptodate(bh
))
289 bh_read
[toread
++] = bh
;
293 for (i
= 0; i
< NAMEI_RA_SIZE
; ++i
) brelse (bh_use
[i
]);
299 ufs_check_dir_entry (const char *function
, struct inode
*dir
,
300 struct ufs_dir_entry
*de
, struct buffer_head
*bh
,
301 unsigned long offset
)
303 struct super_block
*sb
= dir
->i_sb
;
304 const char *error_msg
= NULL
;
305 int rlen
= fs16_to_cpu(sb
, de
->d_reclen
);
307 if (rlen
< UFS_DIR_REC_LEN(1))
308 error_msg
= "reclen is smaller than minimal";
309 else if (rlen
% 4 != 0)
310 error_msg
= "reclen % 4 != 0";
311 else if (rlen
< UFS_DIR_REC_LEN(ufs_get_de_namlen(sb
, de
)))
312 error_msg
= "reclen is too small for namlen";
313 else if (((char *) de
- bh
->b_data
) + rlen
> dir
->i_sb
->s_blocksize
)
314 error_msg
= "directory entry across blocks";
315 else if (fs32_to_cpu(sb
, de
->d_ino
) > (UFS_SB(sb
)->s_uspi
->s_ipg
*
316 UFS_SB(sb
)->s_uspi
->s_ncg
))
317 error_msg
= "inode out of bounds";
319 if (error_msg
!= NULL
)
320 ufs_error (sb
, function
, "bad entry in directory #%lu, size %Lu: %s - "
321 "offset=%lu, inode=%lu, reclen=%d, namlen=%d",
322 dir
->i_ino
, dir
->i_size
, error_msg
, offset
,
323 (unsigned long)fs32_to_cpu(sb
, de
->d_ino
),
324 rlen
, ufs_get_de_namlen(sb
, de
));
326 return (error_msg
== NULL
? 1 : 0);
329 struct ufs_dir_entry
*ufs_dotdot(struct inode
*dir
, struct buffer_head
**p
)
332 struct buffer_head
*bh
= ufs_bread (dir
, 0, 0, &err
);
333 struct ufs_dir_entry
*res
= NULL
;
336 res
= (struct ufs_dir_entry
*) bh
->b_data
;
337 res
= (struct ufs_dir_entry
*)((char *)res
+
338 fs16_to_cpu(dir
->i_sb
, res
->d_reclen
));
343 ino_t
ufs_inode_by_name(struct inode
* dir
, struct dentry
*dentry
)
346 struct ufs_dir_entry
* de
;
347 struct buffer_head
*bh
;
349 de
= ufs_find_entry (dentry
, &bh
);
351 res
= fs32_to_cpu(dir
->i_sb
, de
->d_ino
);
357 void ufs_set_link(struct inode
*dir
, struct ufs_dir_entry
*de
,
358 struct buffer_head
*bh
, struct inode
*inode
)
361 de
->d_ino
= cpu_to_fs32(dir
->i_sb
, inode
->i_ino
);
362 mark_buffer_dirty(bh
);
364 sync_dirty_buffer(bh
);
371 * adds a file entry to the specified directory, using the same
372 * semantics as ufs_find_entry(). It returns NULL if it failed.
374 int ufs_add_link(struct dentry
*dentry
, struct inode
*inode
)
376 struct super_block
* sb
;
377 struct ufs_sb_private_info
* uspi
;
378 unsigned long offset
;
380 unsigned short rec_len
;
381 struct buffer_head
* bh
;
382 struct ufs_dir_entry
* de
, * de1
;
383 struct inode
*dir
= dentry
->d_parent
->d_inode
;
384 const char *name
= dentry
->d_name
.name
;
385 int namelen
= dentry
->d_name
.len
;
388 UFSD(("ENTER, name %s, namelen %u\n", name
, namelen
))
391 uspi
= UFS_SB(sb
)->s_uspi
;
395 bh
= ufs_bread (dir
, 0, 0, &err
);
398 rec_len
= UFS_DIR_REC_LEN(namelen
);
400 de
= (struct ufs_dir_entry
*) bh
->b_data
;
402 if ((char *)de
>= UFS_SECTOR_SIZE
+ bh
->b_data
) {
403 fragoff
= offset
& ~uspi
->s_fmask
;
404 if (fragoff
!= 0 && fragoff
!= UFS_SECTOR_SIZE
)
405 ufs_error (sb
, "ufs_add_entry", "internal error"
406 " fragoff %u", fragoff
);
409 bh
= ufs_bread (dir
, offset
>> sb
->s_blocksize_bits
, 1, &err
);
413 if (dir
->i_size
<= offset
) {
414 if (dir
->i_size
== 0) {
418 de
= (struct ufs_dir_entry
*) (bh
->b_data
+ fragoff
);
420 de
->d_reclen
= cpu_to_fs16(sb
, UFS_SECTOR_SIZE
);
421 ufs_set_de_namlen(sb
, de
, 0);
422 dir
->i_size
= offset
+ UFS_SECTOR_SIZE
;
423 mark_inode_dirty(dir
);
425 de
= (struct ufs_dir_entry
*) bh
->b_data
;
428 if (!ufs_check_dir_entry ("ufs_add_entry", dir
, de
, bh
, offset
)) {
432 if (ufs_match(sb
, namelen
, name
, de
)) {
436 if (de
->d_ino
== 0 && fs16_to_cpu(sb
, de
->d_reclen
) >= rec_len
)
439 if (fs16_to_cpu(sb
, de
->d_reclen
) >=
440 UFS_DIR_REC_LEN(ufs_get_de_namlen(sb
, de
)) + rec_len
)
442 offset
+= fs16_to_cpu(sb
, de
->d_reclen
);
443 de
= (struct ufs_dir_entry
*) ((char *) de
+ fs16_to_cpu(sb
, de
->d_reclen
));
447 de1
= (struct ufs_dir_entry
*) ((char *) de
+
448 UFS_DIR_REC_LEN(ufs_get_de_namlen(sb
, de
)));
450 cpu_to_fs16(sb
, fs16_to_cpu(sb
, de
->d_reclen
) -
451 UFS_DIR_REC_LEN(ufs_get_de_namlen(sb
, de
)));
453 cpu_to_fs16(sb
, UFS_DIR_REC_LEN(ufs_get_de_namlen(sb
, de
)));
457 ufs_set_de_namlen(sb
, de
, namelen
);
458 memcpy (de
->d_name
, name
, namelen
+ 1);
459 de
->d_ino
= cpu_to_fs32(sb
, inode
->i_ino
);
460 ufs_set_de_type(sb
, de
, inode
->i_mode
);
461 mark_buffer_dirty(bh
);
463 sync_dirty_buffer(bh
);
465 dir
->i_mtime
= dir
->i_ctime
= CURRENT_TIME_SEC
;
467 mark_inode_dirty(dir
);
474 * ufs_delete_entry deletes a directory entry by merging it with the
477 int ufs_delete_entry (struct inode
* inode
, struct ufs_dir_entry
* dir
,
478 struct buffer_head
* bh
)
481 struct super_block
* sb
;
482 struct ufs_dir_entry
* de
, * pde
;
490 de
= (struct ufs_dir_entry
*) bh
->b_data
;
492 UFSD(("ino %u, reclen %u, namlen %u, name %s\n",
493 fs32_to_cpu(sb
, de
->d_ino
),
494 fs16_to_cpu(sb
, de
->d_reclen
),
495 ufs_get_de_namlen(sb
, de
), de
->d_name
))
497 while (i
< bh
->b_size
) {
498 if (!ufs_check_dir_entry ("ufs_delete_entry", inode
, de
, bh
, i
)) {
504 fs16_add(sb
, &pde
->d_reclen
,
505 fs16_to_cpu(sb
, dir
->d_reclen
));
508 inode
->i_ctime
= inode
->i_mtime
= CURRENT_TIME_SEC
;
509 mark_inode_dirty(inode
);
510 mark_buffer_dirty(bh
);
511 if (IS_DIRSYNC(inode
))
512 sync_dirty_buffer(bh
);
517 i
+= fs16_to_cpu(sb
, de
->d_reclen
);
518 if (i
== UFS_SECTOR_SIZE
) pde
= NULL
;
520 de
= (struct ufs_dir_entry
*)
521 ((char *) de
+ fs16_to_cpu(sb
, de
->d_reclen
));
522 if (i
== UFS_SECTOR_SIZE
&& de
->d_reclen
== 0)
530 int ufs_make_empty(struct inode
* inode
, struct inode
*dir
)
532 struct super_block
* sb
= dir
->i_sb
;
533 struct buffer_head
* dir_block
;
534 struct ufs_dir_entry
* de
;
537 dir_block
= ufs_bread (inode
, 0, 1, &err
);
541 inode
->i_blocks
= sb
->s_blocksize
/ UFS_SECTOR_SIZE
;
542 de
= (struct ufs_dir_entry
*) dir_block
->b_data
;
543 de
->d_ino
= cpu_to_fs32(sb
, inode
->i_ino
);
544 ufs_set_de_type(sb
, de
, inode
->i_mode
);
545 ufs_set_de_namlen(sb
, de
, 1);
546 de
->d_reclen
= cpu_to_fs16(sb
, UFS_DIR_REC_LEN(1));
547 strcpy (de
->d_name
, ".");
548 de
= (struct ufs_dir_entry
*)
549 ((char *)de
+ fs16_to_cpu(sb
, de
->d_reclen
));
550 de
->d_ino
= cpu_to_fs32(sb
, dir
->i_ino
);
551 ufs_set_de_type(sb
, de
, dir
->i_mode
);
552 de
->d_reclen
= cpu_to_fs16(sb
, UFS_SECTOR_SIZE
- UFS_DIR_REC_LEN(1));
553 ufs_set_de_namlen(sb
, de
, 2);
554 strcpy (de
->d_name
, "..");
555 mark_buffer_dirty(dir_block
);
557 mark_inode_dirty(inode
);
562 * routine to check that the specified directory is empty (for rmdir)
564 int ufs_empty_dir (struct inode
* inode
)
566 struct super_block
* sb
;
567 unsigned long offset
;
568 struct buffer_head
* bh
;
569 struct ufs_dir_entry
* de
, * de1
;
574 if (inode
->i_size
< UFS_DIR_REC_LEN(1) + UFS_DIR_REC_LEN(2) ||
575 !(bh
= ufs_bread (inode
, 0, 0, &err
))) {
576 ufs_warning (inode
->i_sb
, "empty_dir",
577 "bad directory (dir #%lu) - no data block",
581 de
= (struct ufs_dir_entry
*) bh
->b_data
;
582 de1
= (struct ufs_dir_entry
*)
583 ((char *)de
+ fs16_to_cpu(sb
, de
->d_reclen
));
584 if (fs32_to_cpu(sb
, de
->d_ino
) != inode
->i_ino
|| de1
->d_ino
== 0 ||
585 strcmp (".", de
->d_name
) || strcmp ("..", de1
->d_name
)) {
586 ufs_warning (inode
->i_sb
, "empty_dir",
587 "bad directory (dir #%lu) - no `.' or `..'",
591 offset
= fs16_to_cpu(sb
, de
->d_reclen
) + fs16_to_cpu(sb
, de1
->d_reclen
);
592 de
= (struct ufs_dir_entry
*)
593 ((char *)de1
+ fs16_to_cpu(sb
, de1
->d_reclen
));
594 while (offset
< inode
->i_size
) {
595 if (!bh
|| (void *) de
>= (void *) (bh
->b_data
+ sb
->s_blocksize
)) {
597 bh
= ufs_bread (inode
, offset
>> sb
->s_blocksize_bits
, 1, &err
);
599 ufs_error (sb
, "empty_dir",
600 "directory #%lu contains a hole at offset %lu",
601 inode
->i_ino
, offset
);
602 offset
+= sb
->s_blocksize
;
605 de
= (struct ufs_dir_entry
*) bh
->b_data
;
607 if (!ufs_check_dir_entry ("empty_dir", inode
, de
, bh
, offset
)) {
615 offset
+= fs16_to_cpu(sb
, de
->d_reclen
);
616 de
= (struct ufs_dir_entry
*)
617 ((char *)de
+ fs16_to_cpu(sb
, de
->d_reclen
));
623 struct file_operations ufs_dir_operations
= {
624 .read
= generic_read_dir
,
625 .readdir
= ufs_readdir
,