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;
37 * NOTE! unlike strncmp, ufs_match returns 1 for success, 0 for failure.
39 * len <= UFS_MAXNAMLEN and de != NULL are guaranteed by caller.
41 static inline int ufs_match(struct super_block
*sb
, int len
,
42 const char * const name
, struct ufs_dir_entry
* de
)
44 if (len
!= ufs_get_de_namlen(sb
, de
))
48 return !memcmp(name
, de
->d_name
, len
);
52 * This is blatantly stolen from ext2fs
55 ufs_readdir (struct file
* filp
, void * dirent
, filldir_t filldir
)
57 struct inode
*inode
= filp
->f_dentry
->d_inode
;
59 unsigned long offset
, lblk
, blk
;
61 struct buffer_head
* bh
;
62 struct ufs_dir_entry
* de
;
63 struct super_block
* sb
;
70 flags
= UFS_SB(sb
)->s_flags
;
72 UFSD(("ENTER, ino %lu f_pos %lu\n", inode
->i_ino
, (unsigned long) filp
->f_pos
))
76 offset
= filp
->f_pos
& (sb
->s_blocksize
- 1);
78 while (!error
&& !stored
&& filp
->f_pos
< inode
->i_size
) {
79 lblk
= (filp
->f_pos
) >> sb
->s_blocksize_bits
;
80 blk
= ufs_frag_map(inode
, lblk
);
81 if (!blk
|| !(bh
= sb_bread(sb
, blk
))) {
82 /* XXX - error - skip to the next block */
83 printk("ufs_readdir: "
84 "dir inode %lu has a hole at offset %lu\n",
85 inode
->i_ino
, (unsigned long int)filp
->f_pos
);
86 filp
->f_pos
+= sb
->s_blocksize
- offset
;
91 /* If the dir block has changed since the last call to
92 * readdir(2), then we might be pointing to an invalid
93 * dirent right now. Scan from the start of the block
95 if (filp
->f_version
!= inode
->i_version
) {
96 for (i
= 0; i
< sb
->s_blocksize
&& i
< offset
; ) {
97 de
= (struct ufs_dir_entry
*)(bh
->b_data
+ i
);
98 /* It's too expensive to do a full
99 * dirent test each time round this
100 * loop, but we do have to test at
101 * least that it is non-zero. A
102 * failure will be detected in the
103 * dirent test below. */
104 de_reclen
= fs16_to_cpu(sb
, de
->d_reclen
);
110 filp
->f_pos
= (filp
->f_pos
& ~(sb
->s_blocksize
- 1))
112 filp
->f_version
= inode
->i_version
;
115 while (!error
&& filp
->f_pos
< inode
->i_size
116 && offset
< sb
->s_blocksize
) {
117 de
= (struct ufs_dir_entry
*) (bh
->b_data
+ offset
);
118 /* XXX - put in a real ufs_check_dir_entry() */
119 if ((de
->d_reclen
== 0) || (ufs_get_de_namlen(sb
, de
) == 0)) {
120 filp
->f_pos
= (filp
->f_pos
&
121 (sb
->s_blocksize
- 1)) +
127 if (!ufs_check_dir_entry ("ufs_readdir", inode
, de
,
129 /* On error, skip the f_pos to the
131 filp
->f_pos
= (filp
->f_pos
|
132 (sb
->s_blocksize
- 1)) +
138 offset
+= fs16_to_cpu(sb
, de
->d_reclen
);
140 /* We might block in the next section
141 * if the data destination is
142 * currently swapped out. So, use a
143 * version stamp to detect whether or
144 * not the directory has been modified
145 * during the copy operation. */
146 unsigned long version
= filp
->f_version
;
147 unsigned char d_type
= DT_UNKNOWN
;
149 UFSD(("filldir(%s,%u)\n", de
->d_name
,
150 fs32_to_cpu(sb
, de
->d_ino
)))
151 UFSD(("namlen %u\n", ufs_get_de_namlen(sb
, de
)))
153 if ((flags
& UFS_DE_MASK
) == UFS_DE_44BSD
)
154 d_type
= de
->d_u
.d_44
.d_type
;
155 error
= filldir(dirent
, de
->d_name
,
156 ufs_get_de_namlen(sb
, de
), filp
->f_pos
,
157 fs32_to_cpu(sb
, de
->d_ino
), d_type
);
160 if (version
!= filp
->f_version
)
164 filp
->f_pos
+= fs16_to_cpu(sb
, de
->d_reclen
);
175 * define how far ahead to read directories while searching them.
177 #define NAMEI_RA_CHUNKS 2
178 #define NAMEI_RA_BLOCKS 4
179 #define NAMEI_RA_SIZE (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
180 #define NAMEI_RA_INDEX(c,b) (((c) * NAMEI_RA_BLOCKS) + (b))
185 * finds an entry in the specified directory with the wanted name. It
186 * returns the cache buffer in which the entry was found, and the entry
187 * itself (as a parameter - res_bh). It does NOT read the inode of the
188 * entry - you'll have to do that yourself if you want to.
190 struct ufs_dir_entry
* ufs_find_entry (struct dentry
*dentry
,
191 struct buffer_head
** res_bh
)
193 struct super_block
* sb
;
194 struct buffer_head
* bh_use
[NAMEI_RA_SIZE
];
195 struct buffer_head
* bh_read
[NAMEI_RA_SIZE
];
196 unsigned long offset
;
197 int block
, toread
, i
, err
;
198 struct inode
*dir
= dentry
->d_parent
->d_inode
;
199 const char *name
= dentry
->d_name
.name
;
200 int namelen
= dentry
->d_name
.len
;
202 UFSD(("ENTER, dir_ino %lu, name %s, namlen %u\n", dir
->i_ino
, name
, namelen
))
208 if (namelen
> UFS_MAXNAMLEN
)
211 memset (bh_use
, 0, sizeof (bh_use
));
213 for (block
= 0; block
< NAMEI_RA_SIZE
; ++block
) {
214 struct buffer_head
* bh
;
216 if ((block
<< sb
->s_blocksize_bits
) >= dir
->i_size
)
218 bh
= ufs_getfrag (dir
, block
, 0, &err
);
220 if (bh
&& !buffer_uptodate(bh
))
221 bh_read
[toread
++] = bh
;
224 for (block
= 0, offset
= 0; offset
< dir
->i_size
; block
++) {
225 struct buffer_head
* bh
;
226 struct ufs_dir_entry
* de
;
229 if ((block
% NAMEI_RA_BLOCKS
) == 0 && toread
) {
230 ll_rw_block (READ
, toread
, bh_read
);
233 bh
= bh_use
[block
% NAMEI_RA_SIZE
];
235 ufs_error (sb
, "ufs_find_entry",
236 "directory #%lu contains a hole at offset %lu",
238 offset
+= sb
->s_blocksize
;
242 if (!buffer_uptodate(bh
)) {
244 * read error: all bets are off
249 de
= (struct ufs_dir_entry
*) bh
->b_data
;
250 dlimit
= bh
->b_data
+ sb
->s_blocksize
;
251 while ((char *) de
< dlimit
&& offset
< dir
->i_size
) {
252 /* this code is executed quadratically often */
253 /* do minimal checking by hand */
256 if ((char *) de
+ namelen
<= dlimit
&&
257 ufs_match(sb
, namelen
, name
, de
)) {
259 just to be sure, do a full check */
260 if (!ufs_check_dir_entry("ufs_find_entry",
261 dir
, de
, bh
, offset
))
263 for (i
= 0; i
< NAMEI_RA_SIZE
; ++i
) {
270 /* prevent looping on a bad block */
271 de_len
= fs16_to_cpu(sb
, de
->d_reclen
);
275 de
= (struct ufs_dir_entry
*) ((char *) de
+ de_len
);
279 if (((block
+ NAMEI_RA_SIZE
) << sb
->s_blocksize_bits
) >=
283 bh
= ufs_getfrag (dir
, block
+ NAMEI_RA_SIZE
, 0, &err
);
284 bh_use
[block
% NAMEI_RA_SIZE
] = bh
;
285 if (bh
&& !buffer_uptodate(bh
))
286 bh_read
[toread
++] = bh
;
290 for (i
= 0; i
< NAMEI_RA_SIZE
; ++i
) brelse (bh_use
[i
]);
295 int ufs_check_dir_entry (const char * function
, struct inode
* dir
,
296 struct ufs_dir_entry
* de
, struct buffer_head
* bh
,
297 unsigned long offset
)
299 struct super_block
*sb
= dir
->i_sb
;
300 const char *error_msg
= NULL
;
301 int rlen
= fs16_to_cpu(sb
, de
->d_reclen
);
303 if (rlen
< UFS_DIR_REC_LEN(1))
304 error_msg
= "reclen is smaller than minimal";
305 else if (rlen
% 4 != 0)
306 error_msg
= "reclen % 4 != 0";
307 else if (rlen
< UFS_DIR_REC_LEN(ufs_get_de_namlen(sb
, de
)))
308 error_msg
= "reclen is too small for namlen";
309 else if (((char *) de
- bh
->b_data
) + rlen
> dir
->i_sb
->s_blocksize
)
310 error_msg
= "directory entry across blocks";
311 else if (fs32_to_cpu(sb
, de
->d_ino
) > (UFS_SB(sb
)->s_uspi
->s_ipg
*
312 UFS_SB(sb
)->s_uspi
->s_ncg
))
313 error_msg
= "inode out of bounds";
315 if (error_msg
!= NULL
)
316 ufs_error (sb
, function
, "bad entry in directory #%lu, size %Lu: %s - "
317 "offset=%lu, inode=%lu, reclen=%d, namlen=%d",
318 dir
->i_ino
, dir
->i_size
, error_msg
, offset
,
319 (unsigned long)fs32_to_cpu(sb
, de
->d_ino
),
320 rlen
, ufs_get_de_namlen(sb
, de
));
322 return (error_msg
== NULL
? 1 : 0);
325 struct ufs_dir_entry
*ufs_dotdot(struct inode
*dir
, struct buffer_head
**p
)
328 struct buffer_head
*bh
= ufs_bread (dir
, 0, 0, &err
);
329 struct ufs_dir_entry
*res
= NULL
;
332 res
= (struct ufs_dir_entry
*) bh
->b_data
;
333 res
= (struct ufs_dir_entry
*)((char *)res
+
334 fs16_to_cpu(dir
->i_sb
, res
->d_reclen
));
339 ino_t
ufs_inode_by_name(struct inode
* dir
, struct dentry
*dentry
)
342 struct ufs_dir_entry
* de
;
343 struct buffer_head
*bh
;
345 de
= ufs_find_entry (dentry
, &bh
);
347 res
= fs32_to_cpu(dir
->i_sb
, de
->d_ino
);
353 void ufs_set_link(struct inode
*dir
, struct ufs_dir_entry
*de
,
354 struct buffer_head
*bh
, struct inode
*inode
)
357 de
->d_ino
= cpu_to_fs32(dir
->i_sb
, inode
->i_ino
);
358 mark_buffer_dirty(bh
);
360 sync_dirty_buffer(bh
);
367 * adds a file entry to the specified directory, using the same
368 * semantics as ufs_find_entry(). It returns NULL if it failed.
370 int ufs_add_link(struct dentry
*dentry
, struct inode
*inode
)
372 struct super_block
* sb
;
373 struct ufs_sb_private_info
* uspi
;
374 unsigned long offset
;
376 unsigned short rec_len
;
377 struct buffer_head
* bh
;
378 struct ufs_dir_entry
* de
, * de1
;
379 struct inode
*dir
= dentry
->d_parent
->d_inode
;
380 const char *name
= dentry
->d_name
.name
;
381 int namelen
= dentry
->d_name
.len
;
384 UFSD(("ENTER, name %s, namelen %u\n", name
, namelen
))
387 uspi
= UFS_SB(sb
)->s_uspi
;
391 bh
= ufs_bread (dir
, 0, 0, &err
);
394 rec_len
= UFS_DIR_REC_LEN(namelen
);
396 de
= (struct ufs_dir_entry
*) bh
->b_data
;
398 if ((char *)de
>= UFS_SECTOR_SIZE
+ bh
->b_data
) {
399 fragoff
= offset
& ~uspi
->s_fmask
;
400 if (fragoff
!= 0 && fragoff
!= UFS_SECTOR_SIZE
)
401 ufs_error (sb
, "ufs_add_entry", "internal error"
402 " fragoff %u", fragoff
);
405 bh
= ufs_bread (dir
, offset
>> sb
->s_blocksize_bits
, 1, &err
);
409 if (dir
->i_size
<= offset
) {
410 if (dir
->i_size
== 0) {
414 de
= (struct ufs_dir_entry
*) (bh
->b_data
+ fragoff
);
416 de
->d_reclen
= cpu_to_fs16(sb
, UFS_SECTOR_SIZE
);
417 ufs_set_de_namlen(sb
, de
, 0);
418 dir
->i_size
= offset
+ UFS_SECTOR_SIZE
;
419 mark_inode_dirty(dir
);
421 de
= (struct ufs_dir_entry
*) bh
->b_data
;
424 if (!ufs_check_dir_entry ("ufs_add_entry", dir
, de
, bh
, offset
)) {
428 if (ufs_match(sb
, namelen
, name
, de
)) {
432 if (de
->d_ino
== 0 && fs16_to_cpu(sb
, de
->d_reclen
) >= rec_len
)
435 if (fs16_to_cpu(sb
, de
->d_reclen
) >=
436 UFS_DIR_REC_LEN(ufs_get_de_namlen(sb
, de
)) + rec_len
)
438 offset
+= fs16_to_cpu(sb
, de
->d_reclen
);
439 de
= (struct ufs_dir_entry
*) ((char *) de
+ fs16_to_cpu(sb
, de
->d_reclen
));
443 de1
= (struct ufs_dir_entry
*) ((char *) de
+
444 UFS_DIR_REC_LEN(ufs_get_de_namlen(sb
, de
)));
446 cpu_to_fs16(sb
, fs16_to_cpu(sb
, de
->d_reclen
) -
447 UFS_DIR_REC_LEN(ufs_get_de_namlen(sb
, de
)));
449 cpu_to_fs16(sb
, UFS_DIR_REC_LEN(ufs_get_de_namlen(sb
, de
)));
453 ufs_set_de_namlen(sb
, de
, namelen
);
454 memcpy (de
->d_name
, name
, namelen
+ 1);
455 de
->d_ino
= cpu_to_fs32(sb
, inode
->i_ino
);
456 ufs_set_de_type(sb
, de
, inode
->i_mode
);
457 mark_buffer_dirty(bh
);
459 sync_dirty_buffer(bh
);
461 dir
->i_mtime
= dir
->i_ctime
= CURRENT_TIME
;
463 mark_inode_dirty(dir
);
470 * ufs_delete_entry deletes a directory entry by merging it with the
473 int ufs_delete_entry (struct inode
* inode
, struct ufs_dir_entry
* dir
,
474 struct buffer_head
* bh
)
477 struct super_block
* sb
;
478 struct ufs_dir_entry
* de
, * pde
;
486 de
= (struct ufs_dir_entry
*) bh
->b_data
;
488 UFSD(("ino %u, reclen %u, namlen %u, name %s\n",
489 fs32_to_cpu(sb
, de
->d_ino
),
490 fs16to_cpu(sb
, de
->d_reclen
),
491 ufs_get_de_namlen(sb
, de
), de
->d_name
))
493 while (i
< bh
->b_size
) {
494 if (!ufs_check_dir_entry ("ufs_delete_entry", inode
, de
, bh
, i
)) {
500 fs16_add(sb
, &pde
->d_reclen
,
501 fs16_to_cpu(sb
, dir
->d_reclen
));
504 inode
->i_ctime
= inode
->i_mtime
= CURRENT_TIME
;
505 mark_inode_dirty(inode
);
506 mark_buffer_dirty(bh
);
507 if (IS_DIRSYNC(inode
))
508 sync_dirty_buffer(bh
);
513 i
+= fs16_to_cpu(sb
, de
->d_reclen
);
514 if (i
== UFS_SECTOR_SIZE
) pde
= NULL
;
516 de
= (struct ufs_dir_entry
*)
517 ((char *) de
+ fs16_to_cpu(sb
, de
->d_reclen
));
518 if (i
== UFS_SECTOR_SIZE
&& de
->d_reclen
== 0)
526 int ufs_make_empty(struct inode
* inode
, struct inode
*dir
)
528 struct super_block
* sb
= dir
->i_sb
;
529 struct buffer_head
* dir_block
;
530 struct ufs_dir_entry
* de
;
533 dir_block
= ufs_bread (inode
, 0, 1, &err
);
537 inode
->i_blocks
= sb
->s_blocksize
/ UFS_SECTOR_SIZE
;
538 de
= (struct ufs_dir_entry
*) dir_block
->b_data
;
539 de
->d_ino
= cpu_to_fs32(sb
, inode
->i_ino
);
540 ufs_set_de_type(sb
, de
, inode
->i_mode
);
541 ufs_set_de_namlen(sb
, de
, 1);
542 de
->d_reclen
= cpu_to_fs16(sb
, UFS_DIR_REC_LEN(1));
543 strcpy (de
->d_name
, ".");
544 de
= (struct ufs_dir_entry
*)
545 ((char *)de
+ fs16_to_cpu(sb
, de
->d_reclen
));
546 de
->d_ino
= cpu_to_fs32(sb
, dir
->i_ino
);
547 ufs_set_de_type(sb
, de
, dir
->i_mode
);
548 de
->d_reclen
= cpu_to_fs16(sb
, UFS_SECTOR_SIZE
- UFS_DIR_REC_LEN(1));
549 ufs_set_de_namlen(sb
, de
, 2);
550 strcpy (de
->d_name
, "..");
551 mark_buffer_dirty(dir_block
);
553 mark_inode_dirty(inode
);
558 * routine to check that the specified directory is empty (for rmdir)
560 int ufs_empty_dir (struct inode
* inode
)
562 struct super_block
* sb
;
563 unsigned long offset
;
564 struct buffer_head
* bh
;
565 struct ufs_dir_entry
* de
, * de1
;
570 if (inode
->i_size
< UFS_DIR_REC_LEN(1) + UFS_DIR_REC_LEN(2) ||
571 !(bh
= ufs_bread (inode
, 0, 0, &err
))) {
572 ufs_warning (inode
->i_sb
, "empty_dir",
573 "bad directory (dir #%lu) - no data block",
577 de
= (struct ufs_dir_entry
*) bh
->b_data
;
578 de1
= (struct ufs_dir_entry
*)
579 ((char *)de
+ fs16_to_cpu(sb
, de
->d_reclen
));
580 if (fs32_to_cpu(sb
, de
->d_ino
) != inode
->i_ino
|| de1
->d_ino
== 0 ||
581 strcmp (".", de
->d_name
) || strcmp ("..", de1
->d_name
)) {
582 ufs_warning (inode
->i_sb
, "empty_dir",
583 "bad directory (dir #%lu) - no `.' or `..'",
587 offset
= fs16_to_cpu(sb
, de
->d_reclen
) + fs16_to_cpu(sb
, de1
->d_reclen
);
588 de
= (struct ufs_dir_entry
*)
589 ((char *)de1
+ fs16_to_cpu(sb
, de1
->d_reclen
));
590 while (offset
< inode
->i_size
) {
591 if (!bh
|| (void *) de
>= (void *) (bh
->b_data
+ sb
->s_blocksize
)) {
593 bh
= ufs_bread (inode
, offset
>> sb
->s_blocksize_bits
, 1, &err
);
595 ufs_error (sb
, "empty_dir",
596 "directory #%lu contains a hole at offset %lu",
597 inode
->i_ino
, offset
);
598 offset
+= sb
->s_blocksize
;
601 de
= (struct ufs_dir_entry
*) bh
->b_data
;
603 if (!ufs_check_dir_entry ("empty_dir", inode
, de
, bh
, offset
)) {
611 offset
+= fs16_to_cpu(sb
, de
->d_reclen
);
612 de
= (struct ufs_dir_entry
*)
613 ((char *)de
+ fs16_to_cpu(sb
, de
->d_reclen
));
619 struct file_operations ufs_dir_operations
= {
620 .read
= generic_read_dir
,
621 .readdir
= ufs_readdir
,