4 * Copyright (C) 1991, 1992 Linus Torvalds
6 * minix directory handling functions
8 * Updated to filesystem version 3 by Daniel Aragones
12 #include <linux/buffer_head.h>
13 #include <linux/highmem.h>
14 #include <linux/swap.h>
16 typedef struct minix_dir_entry minix_dirent
;
17 typedef struct minix3_dir_entry minix3_dirent
;
19 static int minix_readdir(struct file
*, struct dir_context
*);
21 const struct file_operations minix_dir_operations
= {
22 .llseek
= generic_file_llseek
,
23 .read
= generic_read_dir
,
24 .iterate
= minix_readdir
,
25 .fsync
= generic_file_fsync
,
28 static inline void dir_put_page(struct page
*page
)
31 page_cache_release(page
);
35 * Return the offset into page `page_nr' of the last valid
36 * byte in that page, plus one.
39 minix_last_byte(struct inode
*inode
, unsigned long page_nr
)
41 unsigned last_byte
= PAGE_CACHE_SIZE
;
43 if (page_nr
== (inode
->i_size
>> PAGE_CACHE_SHIFT
))
44 last_byte
= inode
->i_size
& (PAGE_CACHE_SIZE
- 1);
48 static int dir_commit_chunk(struct page
*page
, loff_t pos
, unsigned len
)
50 struct address_space
*mapping
= page
->mapping
;
51 struct inode
*dir
= mapping
->host
;
53 block_write_end(NULL
, mapping
, pos
, len
, len
, page
, NULL
);
55 if (pos
+len
> dir
->i_size
) {
56 i_size_write(dir
, pos
+len
);
57 mark_inode_dirty(dir
);
60 err
= write_one_page(page
, 1);
66 static struct page
* dir_get_page(struct inode
*dir
, unsigned long n
)
68 struct address_space
*mapping
= dir
->i_mapping
;
69 struct page
*page
= read_mapping_page(mapping
, n
, NULL
);
75 static inline void *minix_next_entry(void *de
, struct minix_sb_info
*sbi
)
77 return (void*)((char*)de
+ sbi
->s_dirsize
);
80 static int minix_readdir(struct file
*file
, struct dir_context
*ctx
)
82 struct inode
*inode
= file_inode(file
);
83 struct super_block
*sb
= inode
->i_sb
;
84 struct minix_sb_info
*sbi
= minix_sb(sb
);
85 unsigned chunk_size
= sbi
->s_dirsize
;
86 unsigned long npages
= dir_pages(inode
);
87 unsigned long pos
= ctx
->pos
;
91 ctx
->pos
= pos
= ALIGN(pos
, chunk_size
);
92 if (pos
>= inode
->i_size
)
95 offset
= pos
& ~PAGE_CACHE_MASK
;
96 n
= pos
>> PAGE_CACHE_SHIFT
;
98 for ( ; n
< npages
; n
++, offset
= 0) {
99 char *p
, *kaddr
, *limit
;
100 struct page
*page
= dir_get_page(inode
, n
);
104 kaddr
= (char *)page_address(page
);
106 limit
= kaddr
+ minix_last_byte(inode
, n
) - chunk_size
;
107 for ( ; p
<= limit
; p
= minix_next_entry(p
, sbi
)) {
110 if (sbi
->s_version
== MINIX_V3
) {
111 minix3_dirent
*de3
= (minix3_dirent
*)p
;
113 inumber
= de3
->inode
;
115 minix_dirent
*de
= (minix_dirent
*)p
;
120 unsigned l
= strnlen(name
, sbi
->s_namelen
);
121 if (!dir_emit(ctx
, name
, l
,
122 inumber
, DT_UNKNOWN
)) {
127 ctx
->pos
+= chunk_size
;
134 static inline int namecompare(int len
, int maxlen
,
135 const char * name
, const char * buffer
)
137 if (len
< maxlen
&& buffer
[len
])
139 return !memcmp(name
, buffer
, len
);
145 * finds an entry in the specified directory with the wanted name. It
146 * returns the cache buffer in which the entry was found, and the entry
147 * itself (as a parameter - res_dir). It does NOT read the inode of the
148 * entry - you'll have to do that yourself if you want to.
150 minix_dirent
*minix_find_entry(struct dentry
*dentry
, struct page
**res_page
)
152 const char * name
= dentry
->d_name
.name
;
153 int namelen
= dentry
->d_name
.len
;
154 struct inode
* dir
= d_inode(dentry
->d_parent
);
155 struct super_block
* sb
= dir
->i_sb
;
156 struct minix_sb_info
* sbi
= minix_sb(sb
);
158 unsigned long npages
= dir_pages(dir
);
159 struct page
*page
= NULL
;
166 for (n
= 0; n
< npages
; n
++) {
169 page
= dir_get_page(dir
, n
);
173 kaddr
= (char*)page_address(page
);
174 limit
= kaddr
+ minix_last_byte(dir
, n
) - sbi
->s_dirsize
;
175 for (p
= kaddr
; p
<= limit
; p
= minix_next_entry(p
, sbi
)) {
176 if (sbi
->s_version
== MINIX_V3
) {
177 minix3_dirent
*de3
= (minix3_dirent
*)p
;
179 inumber
= de3
->inode
;
181 minix_dirent
*de
= (minix_dirent
*)p
;
187 if (namecompare(namelen
, sbi
->s_namelen
, name
, namx
))
196 return (minix_dirent
*)p
;
199 int minix_add_link(struct dentry
*dentry
, struct inode
*inode
)
201 struct inode
*dir
= d_inode(dentry
->d_parent
);
202 const char * name
= dentry
->d_name
.name
;
203 int namelen
= dentry
->d_name
.len
;
204 struct super_block
* sb
= dir
->i_sb
;
205 struct minix_sb_info
* sbi
= minix_sb(sb
);
206 struct page
*page
= NULL
;
207 unsigned long npages
= dir_pages(dir
);
218 * We take care of directory expansion in the same loop
219 * This code plays outside i_size, so it locks the page
220 * to protect that region.
222 for (n
= 0; n
<= npages
; n
++) {
223 char *limit
, *dir_end
;
225 page
= dir_get_page(dir
, n
);
230 kaddr
= (char*)page_address(page
);
231 dir_end
= kaddr
+ minix_last_byte(dir
, n
);
232 limit
= kaddr
+ PAGE_CACHE_SIZE
- sbi
->s_dirsize
;
233 for (p
= kaddr
; p
<= limit
; p
= minix_next_entry(p
, sbi
)) {
234 de
= (minix_dirent
*)p
;
235 de3
= (minix3_dirent
*)p
;
236 if (sbi
->s_version
== MINIX_V3
) {
238 inumber
= de3
->inode
;
245 if (sbi
->s_version
== MINIX_V3
)
254 if (namecompare(namelen
, sbi
->s_namelen
, name
, namx
))
264 pos
= page_offset(page
) + p
- (char *)page_address(page
);
265 err
= minix_prepare_chunk(page
, pos
, sbi
->s_dirsize
);
268 memcpy (namx
, name
, namelen
);
269 if (sbi
->s_version
== MINIX_V3
) {
270 memset (namx
+ namelen
, 0, sbi
->s_dirsize
- namelen
- 4);
271 de3
->inode
= inode
->i_ino
;
273 memset (namx
+ namelen
, 0, sbi
->s_dirsize
- namelen
- 2);
274 de
->inode
= inode
->i_ino
;
276 err
= dir_commit_chunk(page
, pos
, sbi
->s_dirsize
);
277 dir
->i_mtime
= dir
->i_ctime
= CURRENT_TIME_SEC
;
278 mark_inode_dirty(dir
);
288 int minix_delete_entry(struct minix_dir_entry
*de
, struct page
*page
)
290 struct inode
*inode
= page
->mapping
->host
;
291 char *kaddr
= page_address(page
);
292 loff_t pos
= page_offset(page
) + (char*)de
- kaddr
;
293 struct minix_sb_info
*sbi
= minix_sb(inode
->i_sb
);
294 unsigned len
= sbi
->s_dirsize
;
298 err
= minix_prepare_chunk(page
, pos
, len
);
300 if (sbi
->s_version
== MINIX_V3
)
301 ((minix3_dirent
*) de
)->inode
= 0;
304 err
= dir_commit_chunk(page
, pos
, len
);
309 inode
->i_ctime
= inode
->i_mtime
= CURRENT_TIME_SEC
;
310 mark_inode_dirty(inode
);
314 int minix_make_empty(struct inode
*inode
, struct inode
*dir
)
316 struct page
*page
= grab_cache_page(inode
->i_mapping
, 0);
317 struct minix_sb_info
*sbi
= minix_sb(inode
->i_sb
);
323 err
= minix_prepare_chunk(page
, 0, 2 * sbi
->s_dirsize
);
329 kaddr
= kmap_atomic(page
);
330 memset(kaddr
, 0, PAGE_CACHE_SIZE
);
332 if (sbi
->s_version
== MINIX_V3
) {
333 minix3_dirent
*de3
= (minix3_dirent
*)kaddr
;
335 de3
->inode
= inode
->i_ino
;
336 strcpy(de3
->name
, ".");
337 de3
= minix_next_entry(de3
, sbi
);
338 de3
->inode
= dir
->i_ino
;
339 strcpy(de3
->name
, "..");
341 minix_dirent
*de
= (minix_dirent
*)kaddr
;
343 de
->inode
= inode
->i_ino
;
344 strcpy(de
->name
, ".");
345 de
= minix_next_entry(de
, sbi
);
346 de
->inode
= dir
->i_ino
;
347 strcpy(de
->name
, "..");
349 kunmap_atomic(kaddr
);
351 err
= dir_commit_chunk(page
, 0, 2 * sbi
->s_dirsize
);
353 page_cache_release(page
);
358 * routine to check that the specified directory is empty (for rmdir)
360 int minix_empty_dir(struct inode
* inode
)
362 struct page
*page
= NULL
;
363 unsigned long i
, npages
= dir_pages(inode
);
364 struct minix_sb_info
*sbi
= minix_sb(inode
->i_sb
);
368 for (i
= 0; i
< npages
; i
++) {
369 char *p
, *kaddr
, *limit
;
371 page
= dir_get_page(inode
, i
);
375 kaddr
= (char *)page_address(page
);
376 limit
= kaddr
+ minix_last_byte(inode
, i
) - sbi
->s_dirsize
;
377 for (p
= kaddr
; p
<= limit
; p
= minix_next_entry(p
, sbi
)) {
378 if (sbi
->s_version
== MINIX_V3
) {
379 minix3_dirent
*de3
= (minix3_dirent
*)p
;
381 inumber
= de3
->inode
;
383 minix_dirent
*de
= (minix_dirent
*)p
;
389 /* check for . and .. */
393 if (inumber
!= inode
->i_ino
)
395 } else if (name
[1] != '.')
410 /* Releases the page */
411 void minix_set_link(struct minix_dir_entry
*de
, struct page
*page
,
414 struct inode
*dir
= page
->mapping
->host
;
415 struct minix_sb_info
*sbi
= minix_sb(dir
->i_sb
);
416 loff_t pos
= page_offset(page
) +
417 (char *)de
-(char*)page_address(page
);
422 err
= minix_prepare_chunk(page
, pos
, sbi
->s_dirsize
);
424 if (sbi
->s_version
== MINIX_V3
)
425 ((minix3_dirent
*) de
)->inode
= inode
->i_ino
;
427 de
->inode
= inode
->i_ino
;
428 err
= dir_commit_chunk(page
, pos
, sbi
->s_dirsize
);
433 dir
->i_mtime
= dir
->i_ctime
= CURRENT_TIME_SEC
;
434 mark_inode_dirty(dir
);
437 struct minix_dir_entry
* minix_dotdot (struct inode
*dir
, struct page
**p
)
439 struct page
*page
= dir_get_page(dir
, 0);
440 struct minix_sb_info
*sbi
= minix_sb(dir
->i_sb
);
441 struct minix_dir_entry
*de
= NULL
;
444 de
= minix_next_entry(page_address(page
), sbi
);
450 ino_t
minix_inode_by_name(struct dentry
*dentry
)
453 struct minix_dir_entry
*de
= minix_find_entry(dentry
, &page
);
457 struct address_space
*mapping
= page
->mapping
;
458 struct inode
*inode
= mapping
->host
;
459 struct minix_sb_info
*sbi
= minix_sb(inode
->i_sb
);
461 if (sbi
->s_version
== MINIX_V3
)
462 res
= ((minix3_dirent
*) de
)->inode
;