2 * linux/fs/umsdos/emd.c
4 * Written 1993 by Jacques Gelinas
6 * Extended MS-DOS directory handling functions
9 #include <linux/types.h>
10 #include <linux/fcntl.h>
11 #include <linux/kernel.h>
12 #include <linux/time.h>
13 #include <linux/errno.h>
14 #include <linux/string.h>
15 #include <linux/msdos_fs.h>
16 #include <linux/umsdos_fs.h>
17 #include <linux/dcache.h>
18 #include <linux/pagemap.h>
19 #include <linux/delay.h>
21 void put_entry (struct umsdos_dirent
*p
, struct umsdos_dirent
*q
)
23 p
->name_len
= q
->name_len
;
25 p
->nlink
= cpu_to_le16(q
->nlink
);
26 p
->uid
= cpu_to_le16(q
->uid
);
27 p
->gid
= cpu_to_le16(q
->gid
);
28 p
->atime
= cpu_to_le32(q
->atime
);
29 p
->mtime
= cpu_to_le32(q
->mtime
);
30 p
->ctime
= cpu_to_le32(q
->ctime
);
31 p
->rdev
= cpu_to_le16(q
->rdev
);
32 p
->mode
= cpu_to_le16(q
->mode
);
35 static void get_entry(struct umsdos_dirent
*p
, struct umsdos_dirent
*q
)
37 p
->name_len
= q
->name_len
;
38 p
->name
[p
->name_len
]='\0';
40 p
->nlink
= le16_to_cpu (q
->nlink
);
41 /* FIXME -- 32bit UID/GID issues */
42 p
->uid
= le16_to_cpu (q
->uid
);
43 p
->gid
= le16_to_cpu (q
->gid
);
44 p
->atime
= le32_to_cpu (q
->atime
);
45 p
->mtime
= le32_to_cpu (q
->mtime
);
46 p
->ctime
= le32_to_cpu (q
->ctime
);
47 p
->rdev
= le16_to_cpu (q
->rdev
);
48 p
->mode
= le16_to_cpu (q
->mode
);
52 * Lookup the EMD dentry for a directory.
54 * Note: the caller must hold a lock on the parent directory.
56 struct dentry
*umsdos_get_emd_dentry(struct dentry
*parent
)
60 demd
= umsdos_lookup_dentry(parent
, UMSDOS_EMD_FILE
,
61 UMSDOS_EMD_NAMELEN
, 1);
66 * Check whether a directory has an EMD file.
68 * Note: the caller must hold a lock on the parent directory.
70 int umsdos_have_emd(struct dentry
*dir
)
72 struct dentry
*demd
= umsdos_get_emd_dentry (dir
);
84 * Create the EMD file for a directory if it doesn't
85 * already exist. Returns 0 or an error code.
87 * Note: the caller must hold a lock on the parent directory.
89 int umsdos_make_emd(struct dentry
*parent
)
91 struct dentry
*demd
= umsdos_get_emd_dentry(parent
);
92 int err
= PTR_ERR(demd
);
95 printk("umsdos_make_emd: can't get dentry in %s, err=%d\n",
96 parent
->d_name
.name
, err
);
100 /* already created? */
105 Printk(("umsdos_make_emd: creating EMD %s/%s\n",
106 parent
->d_name
.name
, demd
->d_name
.name
));
108 err
= msdos_create(parent
->d_inode
, demd
, S_IFREG
| 0777, NULL
);
111 "umsdos_make_emd: create %s/%s failed, err=%d\n",
112 parent
->d_name
.name
, demd
->d_name
.name
, err
);
122 * Read an entry from the EMD file.
123 * Support variable length record.
124 * Return -EIO if error, 0 if OK.
126 * does not change {d,i}_count
129 int umsdos_emd_dir_readentry (struct dentry
*demd
, loff_t
*pos
, struct umsdos_dirent
*entry
)
131 struct address_space
*mapping
= demd
->d_inode
->i_mapping
;
133 struct umsdos_dirent
*p
;
134 int offs
= *pos
& ~PAGE_CACHE_MASK
;
138 page
= read_cache_page(mapping
, *pos
>>PAGE_CACHE_SHIFT
,
139 (filler_t
*)mapping
->a_ops
->readpage
, NULL
);
142 wait_on_page_locked(page
);
143 if (!PageUptodate(page
))
145 p
= (struct umsdos_dirent
*)(kmap(page
)+offs
);
147 /* if this is an invalid entry (invalid name length), ignore it */
148 if( p
->name_len
> UMSDOS_MAXNAME
)
150 printk (KERN_WARNING
"Ignoring invalid EMD entry with size %d\n", entry
->name_len
);
152 ret
= -ENAMETOOLONG
; /* notify umssync(8) code that something is wrong */
153 /* FIXME: does not work if we did 'ls -l' before 'udosctl uls' ?! */
156 recsize
= umsdos_evalrecsize(p
->name_len
);
157 if (offs
+ recsize
> PAGE_CACHE_SIZE
) {
159 int part
= (char *)(page_address(page
) + PAGE_CACHE_SIZE
) - p
->spare
;
160 page2
= read_cache_page(mapping
, 1+(*pos
>>PAGE_CACHE_SHIFT
),
161 (filler_t
*)mapping
->a_ops
->readpage
, NULL
);
164 page_cache_release(page
);
168 wait_on_page_locked(page2
);
169 if (!PageUptodate(page2
)) {
171 page_cache_release(page2
);
174 memcpy(entry
->spare
,p
->spare
,part
);
175 memcpy(entry
->spare
+part
,kmap(page2
),
176 recsize
+offs
-PAGE_CACHE_SIZE
);
178 page_cache_release(page2
);
180 memcpy(entry
->spare
,p
->spare
,((char*)p
+recsize
)-p
->spare
);
183 page_cache_release(page
);
187 page_cache_release(page
);
188 page
= ERR_PTR(-EIO
);
190 return PTR_ERR(page
);
195 * Write an entry in the EMD file.
196 * Return 0 if OK, -EIO if some error.
198 * Note: the caller must hold a lock on the parent directory.
200 int umsdos_writeentry (struct dentry
*parent
, struct umsdos_info
*info
,
203 struct inode
*dir
= parent
->d_inode
;
204 struct umsdos_dirent
*entry
= &info
->entry
;
205 struct dentry
*emd_dentry
;
207 struct umsdos_dirent entry0
,*p
;
208 struct address_space
*mapping
;
209 struct page
*page
, *page2
= NULL
;
212 emd_dentry
= umsdos_get_emd_dentry(parent
);
213 ret
= PTR_ERR(emd_dentry
);
214 if (IS_ERR(emd_dentry
))
216 /* make sure there's an EMD file */
218 if (!emd_dentry
->d_inode
) {
220 "umsdos_writeentry: no EMD file in %s/%s\n",
221 parent
->d_parent
->d_name
.name
, parent
->d_name
.name
);
226 /* #Specification: EMD file / empty entries
227 * Unused entries in the EMD file are identified
228 * by the name_len field equal to 0. However to
229 * help future extension (or bug correction :-( ),
230 * empty entries are filled with 0.
232 memset (&entry0
, 0, sizeof (entry0
));
234 } else if (entry
->name_len
> 0) {
235 memset (entry
->name
+ entry
->name_len
, '\0',
236 sizeof (entry
->name
) - entry
->name_len
);
237 /* #Specification: EMD file / spare bytes
238 * 10 bytes are unused in each record of the EMD. They
239 * are set to 0 all the time, so it will be possible
240 * to do new stuff and rely on the state of those
241 * bytes in old EMD files.
243 memset (entry
->spare
, 0, sizeof (entry
->spare
));
246 /* write the entry and update the parent timestamps */
247 mapping
= emd_dentry
->d_inode
->i_mapping
;
248 offs
= info
->f_pos
& ~PAGE_CACHE_MASK
;
250 page
= grab_cache_page(mapping
, info
->f_pos
>>PAGE_CACHE_SHIFT
);
253 p
= (struct umsdos_dirent
*) (page_address(page
) + offs
);
254 if (offs
+ info
->recsize
> PAGE_CACHE_SIZE
) {
255 ret
= mapping
->a_ops
->prepare_write(NULL
,page
,offs
,
259 page2
= grab_cache_page(mapping
,
260 (info
->f_pos
>>PAGE_CACHE_SHIFT
)+1);
263 ret
= mapping
->a_ops
->prepare_write(NULL
,page2
,0,
264 offs
+info
->recsize
-PAGE_CACHE_SIZE
);
267 put_entry (p
, entry
);
268 memcpy(p
->spare
,entry
->spare
,
269 (char *)(page_address(page
) + PAGE_CACHE_SIZE
) - p
->spare
);
270 memcpy(page_address(page2
),
271 ((char*)entry
)+PAGE_CACHE_SIZE
-offs
,
272 offs
+info
->recsize
-PAGE_CACHE_SIZE
);
273 ret
= mapping
->a_ops
->commit_write(NULL
,page2
,0,
274 offs
+info
->recsize
-PAGE_CACHE_SIZE
);
277 ret
= mapping
->a_ops
->commit_write(NULL
,page
,offs
,
280 page_cache_release(page2
);
284 ret
= mapping
->a_ops
->prepare_write(NULL
,page
,offs
,
285 offs
+ info
->recsize
);
288 put_entry (p
, entry
);
289 memcpy(p
->spare
,entry
->spare
,((char*)p
+info
->recsize
)-p
->spare
);
290 ret
= mapping
->a_ops
->commit_write(NULL
,page
,offs
,
291 offs
+ info
->recsize
);
296 page_cache_release(page
);
298 dir
->i_ctime
= dir
->i_mtime
= CURRENT_TIME
;
299 mark_inode_dirty(dir
);
304 Printk (("umsdos_writeentry /mn/: returning %d...\n", ret
));
308 page_cache_release(page2
);
310 ClearPageUptodate(page
);
314 page_cache_release(page
);
315 printk ("UMSDOS: problem with EMD file: can't write\n");
320 * General search, locate a name in the EMD file or an empty slot to
321 * store it. if info->entry.name_len == 0, search the first empty
322 * slot (of the proper size).
324 * Return 0 if found, -ENOENT if not found, another error code if
327 * So this routine is used to either find an existing entry or to
328 * create a new one, while making sure it is a new one. After you
329 * get -ENOENT, you make sure the entry is stuffed correctly and
330 * call umsdos_writeentry().
332 * To delete an entry, you find it, zero out the entry (memset)
333 * and call umsdos_writeentry().
335 * All this to say that umsdos_writeentry must be called after this
336 * function since it relies on the f_pos field of info.
338 * Note: the caller must hold a lock on the parent directory.
340 /* #Specification: EMD file structure
341 * The EMD file uses a fairly simple layout. It is made of records
342 * (UMSDOS_REC_SIZE == 64). When a name can't be written in a single
343 * record, multiple contiguous records are allocated.
346 static int umsdos_find (struct dentry
*demd
, struct umsdos_info
*info
)
348 struct umsdos_dirent
*entry
= &info
->entry
;
349 int recsize
= info
->recsize
;
350 struct inode
*emd_dir
;
353 off_t posok
; /* Position available to store the entry */
354 off_t one
; /* One empty position -> maybe <- large enough */
358 struct address_space
*mapping
;
360 struct page
*page
= NULL
;
362 int offs
= PAGE_CACHE_SIZE
,max_offs
= PAGE_CACHE_SIZE
;
366 /* make sure there's an EMD file ... */
368 emd_dir
= demd
->d_inode
;
371 mapping
= emd_dir
->i_mapping
;
372 readpage
= (filler_t
*)mapping
->a_ops
->readpage
;
374 empty
.posok
= emd_dir
->i_size
;
376 struct umsdos_dirent
*rentry
;
379 if (offs
>= max_offs
) {
382 page_cache_release(page
);
385 if (pos
>= emd_dir
->i_size
) {
386 info
->f_pos
= empty
.posok
;
389 if (++index
== (emd_dir
->i_size
>>PAGE_CACHE_SHIFT
))
390 max_offs
= emd_dir
->i_size
& ~PAGE_CACHE_MASK
;
391 offs
-= PAGE_CACHE_SIZE
;
392 page
= read_cache_page(mapping
,index
,readpage
,NULL
);
395 wait_on_page_locked(page
);
396 if (!PageUptodate(page
))
401 rentry
= (struct umsdos_dirent
*)(p
+offs
);
403 if (rentry
->name_len
== 0) {
404 /* We are looking for an empty section at least */
405 /* as large as recsize. */
406 if (entry
->name_len
== 0) {
411 offs
+= UMSDOS_REC_SIZE
;
412 pos
+= UMSDOS_REC_SIZE
;
416 empty
.one
= pos
-UMSDOS_REC_SIZE
;
417 empty_size
+= UMSDOS_REC_SIZE
;
418 if (empty_size
== recsize
) {
419 /* Here is a large enough section. */
420 empty
.posok
= empty
.one
;
426 entry_size
= umsdos_evalrecsize(rentry
->name_len
);
427 if (entry_size
> PAGE_CACHE_SIZE
)
430 if (entry
->name_len
!= rentry
->name_len
)
433 if (entry_size
+ offs
> PAGE_CACHE_SIZE
) {
434 /* Sucker spans the page boundary */
435 int len
= (p
+PAGE_CACHE_SIZE
)-rentry
->name
;
436 struct page
*next_page
;
438 next_page
= read_cache_page(mapping
,index
+1,readpage
,NULL
);
439 if (IS_ERR(next_page
)) {
440 page_cache_release(page
);
444 wait_on_page_locked(next_page
);
445 if (!PageUptodate(next_page
)) {
446 page_cache_release(page
);
451 if (memcmp(entry
->name
, rentry
->name
, len
) ||
452 memcmp(entry
->name
+len
, q
, entry
->name_len
-len
)) {
454 page_cache_release(next_page
);
458 page_cache_release(next_page
);
459 } else if (memcmp (entry
->name
, rentry
->name
, entry
->name_len
))
463 get_entry(entry
, rentry
);
472 page_cache_release(page
);
474 umsdos_manglename (info
);
481 page_cache_release(page
);
482 page
= ERR_PTR(-EIO
);
484 return PTR_ERR(page
);
489 * Add a new entry in the EMD file.
490 * Return 0 if OK or a negative error code.
491 * Return -EEXIST if the entry already exists.
493 * Complete the information missing in info.
495 * N.B. What if the EMD file doesn't exist?
498 int umsdos_newentry (struct dentry
*parent
, struct umsdos_info
*info
)
500 int err
, ret
= -EEXIST
;
501 struct dentry
*demd
= umsdos_get_emd_dentry(parent
);
506 err
= umsdos_find (demd
, info
);
507 if (err
&& err
== -ENOENT
) {
508 ret
= umsdos_writeentry (parent
, info
, 0);
509 Printk (("umsdos_writeentry EMD ret = %d\n", ret
));
517 * Create a new hidden link.
518 * Return 0 if OK, an error code if not.
521 /* #Specification: hard link / hidden name
522 * When a hard link is created, the original file is renamed
523 * to a hidden name. The name is "..LINKNNN" where NNN is a
524 * number define from the entry offset in the EMD file.
526 int umsdos_newhidden (struct dentry
*parent
, struct umsdos_info
*info
)
529 struct dentry
*demd
= umsdos_get_emd_dentry(parent
);
534 umsdos_parse ("..LINK", 6, info
);
535 info
->entry
.name_len
= 0;
536 ret
= umsdos_find (demd
, info
);
537 if (ret
== -ENOENT
|| ret
== 0) {
538 info
->entry
.name_len
= sprintf (info
->entry
.name
,
539 "..LINK%ld", info
->f_pos
);
548 * Remove an entry from the EMD file.
549 * Return 0 if OK, a negative error code otherwise.
551 * Complete the information missing in info.
554 int umsdos_delentry (struct dentry
*parent
, struct umsdos_info
*info
, int isdir
)
557 struct dentry
*demd
= umsdos_get_emd_dentry(parent
);
562 ret
= umsdos_find (demd
, info
);
565 if (info
->entry
.name_len
== 0)
568 if ((isdir
!= 0) != (S_ISDIR (info
->entry
.mode
) != 0)) {
569 if (S_ISDIR (info
->entry
.mode
)) {
576 ret
= umsdos_writeentry (parent
, info
, 1);
584 * Verify that an EMD directory is empty.
587 * 1 if empty (except for EMD file),
588 * 2 if empty or no EMD file.
591 int umsdos_isempty (struct dentry
*dentry
)
597 demd
= umsdos_get_emd_dentry(dentry
);
600 /* If the EMD file does not exist, it is certainly empty. :-) */
605 while (pos
< demd
->d_inode
->i_size
) {
606 struct umsdos_dirent entry
;
608 if (umsdos_emd_dir_readentry (demd
, &pos
, &entry
) != 0) {
612 if (entry
.name_len
!= 0) {
625 * Locate an entry in a EMD directory.
626 * Return 0 if OK, error code if not, generally -ENOENT.
634 int umsdos_findentry (struct dentry
*parent
, struct umsdos_info
*info
,
638 struct dentry
*demd
= umsdos_get_emd_dentry(parent
);
643 ret
= umsdos_find (demd
, info
);
649 if (S_ISDIR (info
->entry
.mode
))
653 if (!S_ISDIR (info
->entry
.mode
))
658 Printk (("umsdos_findentry: returning %d\n", ret
));