2 * linux/fs/umsdos/namei.c
4 * Written 1993 by Jacques Gelinas
5 * Inspired from linux/fs/msdos/... by Werner Almesberger
7 * Maintain and access the --linux alternate directory file.
10 #include <linux/errno.h>
11 #include <linux/kernel.h>
12 #include <linux/sched.h>
13 #include <linux/types.h>
14 #include <linux/fcntl.h>
15 #include <linux/stat.h>
16 #include <linux/string.h>
17 #include <linux/msdos_fs.h>
18 #include <linux/umsdos_fs.h>
19 #include <linux/malloc.h>
23 * Wait for creation exclusivity.
24 * Return 0 if the dir was already available.
25 * Return 1 if a wait was necessary.
26 * When 1 is return, it means a wait was done. It does not
27 * mean the directory is available.
29 static int umsdos_waitcreate (struct inode
*dir
)
33 if (dir
->u
.umsdos_i
.u
.dir_info
.creating
34 && dir
->u
.umsdos_i
.u
.dir_info
.pid
!= current
->pid
) {
35 sleep_on (&dir
->u
.umsdos_i
.u
.dir_info
.p
);
42 * Wait for any lookup process to finish
44 static void umsdos_waitlookup (struct inode
*dir
)
46 while (dir
->u
.umsdos_i
.u
.dir_info
.looking
) {
47 sleep_on (&dir
->u
.umsdos_i
.u
.dir_info
.p
);
52 * Lock all other process out of this directory.
54 /* #Specification: file creation / not atomic
55 * File creation is a two step process. First we create (allocate)
56 * an entry in the EMD file and then (using the entry offset) we
57 * build a unique name for MSDOS. We create this name in the msdos
60 * We have to use semaphore (sleep_on/wake_up) to prevent lookup
61 * into a directory when we create a file or directory and to
62 * prevent creation while a lookup is going on. Since many lookup
63 * may happen at the same time, the semaphore is a counter.
65 * Only one creation is allowed at the same time. This protection
66 * may not be necessary. The problem arise mainly when a lookup
67 * or a readdir is done while a file is partially created. The
68 * lookup process see that as a "normal" problem and silently
69 * erase the file from the EMD file. Normal because a file
70 * may be erased during a MSDOS session, but not removed from
73 * The locking is done on a directory per directory basis. Each
74 * directory inode has its wait_queue.
76 * For some operation like hard link, things even get worse. Many
77 * creation must occur at once (atomic). To simplify the design
78 * a process is allowed to recursively lock the directory for
79 * creation. The pid of the locking process is kept along with
80 * a counter so a second level of locking is granted or not.
82 void umsdos_lockcreate (struct inode
*dir
)
85 * Wait for any creation process to finish except
86 * if we (the process) own the lock
88 while (umsdos_waitcreate (dir
) != 0);
89 dir
->u
.umsdos_i
.u
.dir_info
.creating
++;
90 dir
->u
.umsdos_i
.u
.dir_info
.pid
= current
->pid
;
91 umsdos_waitlookup (dir
);
95 * Lock all other process out of those two directories.
97 static void umsdos_lockcreate2 (struct inode
*dir1
, struct inode
*dir2
)
100 * We must check that both directory are available before
101 * locking anyone of them. This is to avoid some deadlock.
102 * Thanks to dglaude@is1.vub.ac.be (GLAUDE DAVID) for pointing
106 if (umsdos_waitcreate (dir1
) == 0
107 && umsdos_waitcreate (dir2
) == 0) {
108 /* We own both now */
109 dir1
->u
.umsdos_i
.u
.dir_info
.creating
++;
110 dir1
->u
.umsdos_i
.u
.dir_info
.pid
= current
->pid
;
111 dir2
->u
.umsdos_i
.u
.dir_info
.creating
++;
112 dir2
->u
.umsdos_i
.u
.dir_info
.pid
= current
->pid
;
116 umsdos_waitlookup (dir1
);
117 umsdos_waitlookup (dir2
);
121 * Wait until creation is finish in this directory.
123 void umsdos_startlookup (struct inode
*dir
)
125 while (umsdos_waitcreate (dir
) != 0);
126 dir
->u
.umsdos_i
.u
.dir_info
.looking
++;
130 * Unlock the directory.
132 void umsdos_unlockcreate (struct inode
*dir
)
134 dir
->u
.umsdos_i
.u
.dir_info
.creating
--;
135 if (dir
->u
.umsdos_i
.u
.dir_info
.creating
< 0) {
136 printk ("UMSDOS: dir->u.umsdos_i.u.dir_info.creating < 0: %d"
137 ,dir
->u
.umsdos_i
.u
.dir_info
.creating
);
139 wake_up (&dir
->u
.umsdos_i
.u
.dir_info
.p
);
143 * Tell directory lookup is over.
145 void umsdos_endlookup (struct inode
*dir
)
147 dir
->u
.umsdos_i
.u
.dir_info
.looking
--;
148 if (dir
->u
.umsdos_i
.u
.dir_info
.looking
< 0) {
149 printk ("UMSDOS: dir->u.umsdos_i.u.dir_info.looking < 0: %d"
150 ,dir
->u
.umsdos_i
.u
.dir_info
.looking
);
152 wake_up (&dir
->u
.umsdos_i
.u
.dir_info
.p
);
156 static void umsdos_lockcreate (struct inode
*dir
)
159 static void umsdos_lockcreate2 (struct inode
*dir1
, struct inode
*dir2
)
162 void umsdos_startlookup (struct inode
*dir
)
165 static void umsdos_unlockcreate (struct inode
*dir
)
168 void umsdos_endlookup (struct inode
*dir
)
175 * Check whether we can delete from the directory.
177 static int is_sticky(struct inode
*dir
, int uid
)
179 return !((dir
->i_mode
& S_ISVTX
) == 0 ||
180 current
->fsuid
== uid
||
181 current
->fsuid
== dir
->i_uid
||
182 capable (CAP_FOWNER
));
186 static int umsdos_nevercreat (struct inode
*dir
, struct dentry
*dentry
,
191 if (umsdos_is_pseudodos (dir
, dentry
)) {
192 /* #Specification: pseudo root / any file creation /DOS
193 * The pseudo sub-directory /DOS can't be created!
194 * EEXIST is returned.
196 * The pseudo sub-directory /DOS can't be removed!
205 * Add a new file (ordinary or special) into the alternate directory.
206 * The file is added to the real MSDOS directory. If successful, it
207 * is then added to the EMD file.
209 * Return the status of the operation. 0 mean success.
211 * #Specification: create / file exists in DOS
212 * Here is a situation: we are trying to create a file with
213 * UMSDOS. The file is unknown to UMSDOS but already
214 * exists in the DOS directory.
216 * Here is what we are NOT doing:
218 * We could silently assume that everything is fine
219 * and allows the creation to succeed.
221 * It is possible not all files in the partition
222 * are meant to be visible from linux. By trying to create
223 * those file in some directory, one user may get access
224 * to those file without proper permissions. Looks like
225 * a security hole to me. Off course sharing a file system
226 * with DOS is some kind of security hole :-)
230 * We return EEXIST in this case.
231 * The same is true for directory creation.
233 static int umsdos_create_any (struct inode
*dir
, struct dentry
*dentry
,
234 int mode
, int rdev
, char flags
)
239 struct umsdos_info info
;
241 ret
= umsdos_nevercreat (dir
, dentry
, -EEXIST
);
245 ret
= umsdos_parse (dentry
->d_name
.name
, dentry
->d_name
.len
, &info
);
249 info
.entry
.mode
= mode
;
250 info
.entry
.rdev
= rdev
;
251 info
.entry
.flags
= flags
;
252 info
.entry
.uid
= current
->fsuid
;
253 info
.entry
.gid
= (dir
->i_mode
& S_ISGID
) ? dir
->i_gid
: current
->fsgid
;
254 info
.entry
.ctime
= info
.entry
.atime
= info
.entry
.mtime
= CURRENT_TIME
;
255 info
.entry
.nlink
= 1;
256 ret
= umsdos_newentry (dentry
->d_parent
, &info
);
260 /* do a real lookup to get the short name dentry */
261 fake
= umsdos_lookup_dentry(dentry
->d_parent
, info
.fake
.fname
,
267 /* keep the short name anonymous ... */
271 /* should not exist yet ... */
274 goto out_remove_dput
;
276 ret
= msdos_create (dir
, fake
, S_IFREG
| 0777);
278 goto out_remove_dput
;
280 inode
= fake
->d_inode
;
282 * Note! The long and short name might be the same,
283 * so check first before doing the instantiate ...
285 if (dentry
!= fake
) {
287 d_instantiate (dentry
, inode
);
290 if (inode
->i_count
> 1) {
292 "umsdos_create_any: %s/%s, ino=%ld, icount=%d??\n",
293 dentry
->d_parent
->d_name
.name
, dentry
->d_name
.name
,
294 inode
->i_ino
, inode
->i_count
);
296 umsdos_lookup_patch_new(dentry
, &info
);
301 /* Creation failed ... remove the EMD entry */
306 printk(KERN_WARNING
"UMSDOS: out of sync, deleting %s/%s\n",
307 dentry
->d_parent
->d_name
.name
, info
.fake
.fname
);
308 umsdos_delentry (dentry
->d_parent
, &info
, S_ISDIR (info
.entry
.mode
));
313 * Add a new file into the alternate directory.
314 * The file is added to the real MSDOS directory. If successful, it
315 * is then added to the EMD file.
317 * Return the status of the operation. 0 mean success.
319 int UMSDOS_create (struct inode
*dir
, struct dentry
*dentry
, int mode
)
321 return umsdos_create_any (dir
, dentry
, mode
, 0, 0);
326 * Initialise the new_entry from the old for a rename operation.
327 * (Only useful for umsdos_rename_f() below).
329 static void umsdos_ren_init (struct umsdos_info
*new_info
,
330 struct umsdos_info
*old_info
)
332 new_info
->entry
.mode
= old_info
->entry
.mode
;
333 new_info
->entry
.rdev
= old_info
->entry
.rdev
;
334 new_info
->entry
.uid
= old_info
->entry
.uid
;
335 new_info
->entry
.gid
= old_info
->entry
.gid
;
336 new_info
->entry
.ctime
= old_info
->entry
.ctime
;
337 new_info
->entry
.atime
= old_info
->entry
.atime
;
338 new_info
->entry
.mtime
= old_info
->entry
.mtime
;
339 new_info
->entry
.flags
= old_info
->entry
.flags
;
340 new_info
->entry
.nlink
= old_info
->entry
.nlink
;
345 if (STACK_MAGIC != *(unsigned long *)current->kernel_stack_page){\
346 printk(KERN_ALERT "UMSDOS: %s magic %x != %lx ligne %d\n" \
347 , current->comm,STACK_MAGIC \
348 ,*(unsigned long *)current->kernel_stack_page \
353 #define chkstk() do { } while (0);
357 * Rename a file (move) in the file system.
360 static int umsdos_rename_f (struct inode
*old_dir
, struct dentry
*old_dentry
,
361 struct inode
*new_dir
, struct dentry
*new_dentry
,
364 struct inode
*old_inode
= old_dentry
->d_inode
;
365 struct dentry
*old
, *new, *old_emd
;
366 int err
, ret
, rehash
= 0;
367 struct umsdos_info old_info
;
368 struct umsdos_info new_info
;
371 err
= umsdos_parse (old_dentry
->d_name
.name
,
372 old_dentry
->d_name
.len
, &old_info
);
375 err
= umsdos_parse (new_dentry
->d_name
.name
,
376 new_dentry
->d_name
.len
, &new_info
);
380 /* Get the EMD dentry for the old parent */
381 old_emd
= umsdos_get_emd_dentry(old_dentry
->d_parent
);
382 ret
= PTR_ERR(old_emd
);
386 umsdos_lockcreate2 (old_dir
, new_dir
);
388 ret
= umsdos_findentry(old_emd
->d_parent
, &old_info
, 0);
391 "umsdos_rename_f: old entry %s/%s not in EMD, ret=%d\n",
392 old_dentry
->d_parent
->d_name
.name
, old_info
.entry
.name
,
397 /* check sticky bit on old_dir */
399 if (is_sticky(old_dir
, old_info
.entry
.uid
)) {
400 printk("umsdos_rename_f: %s/%s old sticky bit, fsuid=%d, uid=%d, dir=%d\n",
401 old_dentry
->d_parent
->d_name
.name
, old_info
.entry
.name
,
402 current
->fsuid
, old_info
.entry
.uid
, old_dir
->i_uid
);
407 * Check whether the new_name already exists, and
408 * if so whether we're allowed to replace it.
410 err
= umsdos_findentry(new_dentry
->d_parent
, &new_info
, 0);
412 /* Are we allowed to replace it? */
413 if (is_sticky(new_dir
, new_info
.entry
.uid
)) {
414 Printk (("sticky set on new "));
417 /* check whether it _really_ exists ... */
419 if (new_dentry
->d_inode
)
422 /* bogus lookup? complain and fix up the EMD ... */
424 "umsdos_rename_f: entry %s/%s exists, inode NULL??\n",
425 new_dentry
->d_parent
->d_name
.name
, new_info
.entry
.name
);
426 err
= umsdos_delentry(new_dentry
->d_parent
, &new_info
,
427 S_ISDIR(new_info
.entry
.mode
));
430 Printk (("new newentry "));
431 /* create the new entry ... */
432 umsdos_ren_init (&new_info
, &old_info
);
434 new_info
.entry
.flags
= flags
;
435 ret
= umsdos_newentry (new_dentry
->d_parent
, &new_info
);
438 "umsdos_rename_f: newentry %s/%s failed, ret=%d\n",
439 new_dentry
->d_parent
->d_name
.name
, new_info
.entry
.name
,
444 /* If we're moving a hardlink, drop it first */
445 if (old_info
.entry
.flags
& UMSDOS_HLINK
) {
446 rehash
= !list_empty(&old_dentry
->d_hash
);
448 printk("umsdos_rename_f: moving hardlink %s/%s, rehash=%d\n",
449 old_dentry
->d_parent
->d_name
.name
, old_info
.entry
.name
, rehash
);
452 /* Do a real lookup to get the old short name dentry */
453 old
= umsdos_lookup_dentry(old_dentry
->d_parent
, old_info
.fake
.fname
,
454 old_info
.fake
.len
, 1);
458 "umsdos_rename_f: lookup old dentry %s/%s, ret=%d\n",
459 old_dentry
->d_parent
->d_name
.name
, old_info
.fake
.fname
,
463 /* short and long name dentries match? */
464 if (old
== old_dentry
)
467 /* make sure it's the same inode! */
469 if (old
->d_inode
!= old_inode
)
472 * A cross-directory move with different short and long
473 * names has nasty complications: msdos-fs will need to
474 * change inodes, so we must check whether the original
475 * dentry is busy, and if the rename succeeds the short
476 * dentry will come back with a different inode.
478 * To handle this, we drop the dentry and free the inode,
479 * and then pick up the new inode after the rename.
481 if (old_dir
!= new_dir
) {
483 if (old_dentry
->d_count
> 1) {
484 printk("umsdos_rename_f: old dentry %s/%s busy, d_count=%d\n",
485 old_dentry
->d_parent
->d_name
.name
, old_dentry
->d_name
.name
,old_dentry
->d_count
);
489 d_delete(old_dentry
);
490 printk("umsdos_rename_f: cross-dir move, %s/%s dropped\n",
491 old_dentry
->d_parent
->d_name
.name
, old_dentry
->d_name
.name
);
495 new = umsdos_lookup_dentry(new_dentry
->d_parent
, new_info
.fake
.fname
,
496 new_info
.fake
.len
, 1);
500 "umsdos_rename_f: lookup new dentry %s/%s, ret=%d\n",
501 new_dentry
->d_parent
->d_name
.name
, new_info
.fake
.fname
,
505 #ifdef UMSDOS_PARANOIA
506 if (new->d_inode
!= new_dentry
->d_inode
)
507 printk("umsdos_rename_f: new %s/%s, inode %p!=%p??\n",
508 new->d_parent
->d_name
.name
, new->d_name
.name
, new->d_inode
,new_dentry
->d_inode
);
510 /* short and long name dentries match? */
511 if (new == new_dentry
)
514 #ifdef UMSDOS_DEBUG_VERBOSE
515 printk("umsdos_rename_f: msdos_rename %s/%s(%ld) to %s/%s(%ld)\n",
516 old
->d_parent
->d_name
.name
, old
->d_name
.name
, old
->d_inode
->i_ino
,
517 new->d_parent
->d_name
.name
, new->d_name
.name
,
518 new->d_inode
? new->d_inode
->i_ino
: 0);
520 /* Do the msdos-level rename */
521 ret
= msdos_rename (old_dir
, old
, new_dir
, new);
522 Printk(("umsdos_rename_f: now %s/%s, ret=%d\n",
523 old
->d_parent
->d_name
.name
, old
->d_name
.name
, ret
));
525 if (new != new_dentry
)
528 /* If the rename failed, remove the new EMD entry */
530 Printk(("umsdos_rename_f: rename failed, ret=%d, removing %s/%s\n",
531 ret
, new_dentry
->d_parent
->d_name
.name
, new_info
.entry
.name
));
532 umsdos_delentry (new_dentry
->d_parent
, &new_info
,
533 S_ISDIR (new_info
.entry
.mode
));
538 * Rename successful ... remove the old name from the EMD.
539 * Note that we use the EMD parent here, as the old dentry
540 * may have moved to a new parent ...
542 err
= umsdos_delentry (old_emd
->d_parent
, &old_info
,
543 S_ISDIR (old_info
.entry
.mode
));
545 /* Failed? Complain a bit, but don't fail the operation */
547 "umsdos_rename_f: delentry %s/%s failed, error=%d\n",
548 old_emd
->d_parent
->d_name
.name
, old_info
.entry
.name
,
553 * Check whether to update the dcache ... if both
554 * old and new dentries match, it's already correct.
555 * If the targets were aliases, the old short-name
556 * dentry has the original target name.
558 if (old_dentry
!= old
) {
559 if (!old_dentry
->d_inode
) {
560 struct inode
*inode
= old
->d_inode
;
562 d_instantiate(old_dentry
, inode
);
563 printk("umsdos_rename_f: %s/%s gets new ino=%ld\n",
564 old_dentry
->d_parent
->d_name
.name
, old_dentry
->d_name
.name
, inode
->i_ino
);
566 if (new_dentry
== new)
569 } else if (new_dentry
!= new) {
571 /* this will rehash the dentry ... */
572 d_move(old_dentry
, new_dentry
);
574 /* Check whether the old inode changed ... */
575 if (old_dentry
->d_inode
!= old_inode
) {
576 umsdos_lookup_patch_new(old_dentry
, &new_info
);
580 * Update f_pos so notify_change will succeed
581 * if the file was already in use.
583 umsdos_set_dirinfo_new(old_dentry
, new_info
.f_pos
);
585 /* dput() the dentry if we haven't already */
587 if (old_dentry
!= old
)
592 umsdos_unlockcreate (old_dir
);
593 umsdos_unlockcreate (new_dir
);
596 Printk ((" _ret=%d\n", ret
));
601 * Setup a Symbolic link or a (pseudo) hard link
602 * Return a negative error code or 0 if OK.
604 /* #Specification: symbolic links / strategy
605 * A symbolic link is simply a file which holds a path. It is
606 * implemented as a normal MSDOS file (not very space efficient :-()
608 * I see two different ways to do this: One is to place the link data
609 * in unused entries of the EMD file; the other is to have a separate
610 * file dedicated to hold all symbolic links data.
612 * Let's go for simplicity...
615 extern struct inode_operations umsdos_symlink_inode_operations
;
617 static int umsdos_symlink_x (struct inode
*dir
, struct dentry
*dentry
,
618 const char *symname
, int mode
, char flags
)
623 Printk(("umsdos_symlink: %s/%s to %s\n",
624 dentry
->d_parent
->d_name
.name
, dentry
->d_name
.name
, symname
));
626 ret
= umsdos_create_any (dir
, dentry
, mode
, 0, flags
);
629 "umsdos_symlink: create failed, ret=%d\n", ret
);
633 fill_new_filp (&filp
, dentry
);
634 len
= strlen (symname
);
635 ret
= umsdos_file_write_kmem_real (&filp
, symname
, len
);
647 printk(KERN_WARNING
"umsdos_symlink: write failed, unlinking\n");
648 UMSDOS_unlink (dir
, dentry
);
653 * Setup a Symbolic link.
654 * Return a negative error code or 0 if OK.
656 int UMSDOS_symlink ( struct inode
*dir
, struct dentry
*dentry
,
659 return umsdos_symlink_x (dir
, dentry
, symname
, S_IFLNK
| 0777, 0);
663 * Add a link to an inode in a directory
665 int UMSDOS_link (struct dentry
*olddentry
, struct inode
*dir
,
666 struct dentry
*dentry
)
668 struct inode
*oldinode
= olddentry
->d_inode
;
669 struct inode
*olddir
= olddentry
->d_parent
->d_inode
;
672 unsigned long buffer
;
674 struct umsdos_info old_info
;
675 struct umsdos_info hid_info
;
677 #ifdef UMSDOS_DEBUG_VERBOSE
678 printk("umsdos_link: new %s%s -> %s/%s\n",
679 dentry
->d_parent
->d_name
.name
, dentry
->d_name
.name
,
680 olddentry
->d_parent
->d_name
.name
, olddentry
->d_name
.name
);
684 if (S_ISDIR (oldinode
->i_mode
))
687 ret
= umsdos_nevercreat (dir
, dentry
, -EPERM
);
692 buffer
= get_free_page(GFP_KERNEL
);
697 * Lock the link parent if it's not the same directory.
701 if (atomic_read(&olddir
->i_sem
.count
) < 1)
703 down(&olddir
->i_sem
);
707 * Parse the name and get the visible directory entry.
709 ret
= umsdos_parse (olddentry
->d_name
.name
, olddentry
->d_name
.len
,
713 ret
= umsdos_findentry (olddentry
->d_parent
, &old_info
, 1);
715 printk("UMSDOS_link: %s/%s not in EMD, ret=%d\n",
716 olddentry
->d_parent
->d_name
.name
, olddentry
->d_name
.name
, ret
);
721 * If the visible dentry is a pseudo-hardlink, the original
722 * file must be already hidden.
724 if (!(old_info
.entry
.flags
& UMSDOS_HLINK
)) {
727 /* create a hidden link name */
728 ret
= umsdos_newhidden (olddentry
->d_parent
, &hid_info
);
730 printk("umsdos_link: can't make hidden %s/%s, ret=%d\n",
731 olddentry
->d_parent
->d_name
.name
, hid_info
.entry
.name
, ret
);
736 * Make a dentry and rename the original file ...
738 temp
= umsdos_lookup_dentry(olddentry
->d_parent
,
740 hid_info
.entry
.name_len
, 0);
743 printk("umsdos_link: lookup %s/%s failed, ret=%d\n",
744 dentry
->d_parent
->d_name
.name
, hid_info
.entry
.name
, ret
);
747 /* rename the link to the hidden location ... */
748 ret
= umsdos_rename_f (olddir
, olddentry
, olddir
, temp
,
752 printk("umsdos_link: rename to %s/%s failed, ret=%d\n",
753 temp
->d_parent
->d_name
.name
, temp
->d_name
.name
, ret
);
756 /* mark the inode as a hardlink */
757 oldinode
->u
.umsdos_i
.i_is_hlink
= 1;
760 * Capture the path to the hidden link.
762 path
= umsdos_d_path(olddentry
, (char *) buffer
, PAGE_SIZE
);
763 Printk(("umsdos_link: hidden link path=%s\n", path
));
766 * Recreate a dentry for the original name and symlink it,
767 * then symlink the new dentry. Don't give up if one fails,
768 * or we'll lose the file completely!
770 * Note: this counts as the "original" reference, so we
771 * don't increment i_nlink for this one.
773 temp
= umsdos_lookup_dentry(olddentry
->d_parent
,
775 old_info
.entry
.name_len
, 0);
778 ret
= umsdos_symlink_x (olddir
, temp
, path
,
779 S_IFREG
| 0777, UMSDOS_HLINK
);
783 /* This symlink increments i_nlink (see below.) */
784 err
= umsdos_symlink_x (dir
, dentry
, path
,
785 S_IFREG
| 0777, UMSDOS_HLINK
);
786 /* fold the two errors */
791 /* creation failed ... remove the link entry */
793 printk("umsdos_link: link failed, ret=%d, removing %s/%s\n",
794 ret
, olddentry
->d_parent
->d_name
.name
, hid_info
.entry
.name
);
795 err
= umsdos_delentry(olddentry
->d_parent
, &hid_info
, 0);
799 Printk(("UMSDOS_link: %s/%s already hidden\n",
800 olddentry
->d_parent
->d_name
.name
, olddentry
->d_name
.name
));
802 * The original file is already hidden, and we need to get
803 * the dentry for its real name, not the visible name.
804 * N.B. make sure it's the hidden inode ...
806 if (!oldinode
->u
.umsdos_i
.i_is_hlink
)
807 printk("UMSDOS_link: %s/%s hidden, ino=%ld not hlink??\n",
808 olddentry
->d_parent
->d_name
.name
,
809 olddentry
->d_name
.name
, oldinode
->i_ino
);
812 * In order to get the correct (real) inode, we just drop
813 * the original dentry.
816 Printk(("UMSDOS_link: hard link %s/%s, fake=%s\n",
817 olddentry
->d_parent
->d_name
.name
, olddentry
->d_name
.name
, old_info
.fake
.fname
));
819 /* Do a real lookup to get the short name dentry */
820 temp
= umsdos_lookup_dentry(olddentry
->d_parent
,
822 old_info
.fake
.len
, 1);
827 /* now resolve the link ... */
828 temp
= umsdos_solve_hlink(temp
);
832 path
= umsdos_d_path(temp
, (char *) buffer
, PAGE_SIZE
);
834 Printk(("umsdos_link: %s/%s already hidden, path=%s\n",
835 olddentry
->d_parent
->d_name
.name
, olddentry
->d_name
.name
, path
));
837 /* finally we can symlink it ... */
838 ret
= umsdos_symlink_x (dir
, dentry
, path
, S_IFREG
| 0777,UMSDOS_HLINK
);
841 /* remain locked for the call to notify_change ... */
843 struct iattr newattrs
;
845 #ifdef UMSDOS_PARANOIA
846 if (!oldinode
->u
.umsdos_i
.i_is_hlink
)
847 printk("UMSDOS_link: %s/%s, ino=%ld, not marked as hlink!\n",
848 olddentry
->d_parent
->d_name
.name
, olddentry
->d_name
.name
, oldinode
->i_ino
);
851 Printk(("UMSDOS_link: linked %s/%s, ino=%ld, nlink=%d\n",
852 olddentry
->d_parent
->d_name
.name
, olddentry
->d_name
.name
,
853 oldinode
->i_ino
, oldinode
->i_nlink
));
854 newattrs
.ia_valid
= 0;
855 ret
= umsdos_notify_change_locked(olddentry
, &newattrs
);
863 Printk (("umsdos_link %d\n", ret
));
869 * Add a sub-directory in a directory
871 /* #Specification: mkdir / Directory already exist in DOS
872 * We do the same thing as for file creation.
873 * For all user it is an error.
875 /* #Specification: mkdir / umsdos directory / create EMD
876 * When we created a new sub-directory in a UMSDOS
877 * directory (one with full UMSDOS semantics), we
878 * create immediately an EMD file in the new
879 * sub-directory so it inherits UMSDOS semantics.
881 int UMSDOS_mkdir (struct inode
*dir
, struct dentry
*dentry
, int mode
)
886 struct umsdos_info info
;
888 ret
= umsdos_nevercreat (dir
, dentry
, -EEXIST
);
892 ret
= umsdos_parse (dentry
->d_name
.name
, dentry
->d_name
.len
, &info
);
896 info
.entry
.mode
= mode
| S_IFDIR
;
898 info
.entry
.uid
= current
->fsuid
;
899 info
.entry
.gid
= (dir
->i_mode
& S_ISGID
) ? dir
->i_gid
: current
->fsgid
;
900 info
.entry
.ctime
= info
.entry
.atime
= info
.entry
.mtime
= CURRENT_TIME
;
901 info
.entry
.flags
= 0;
902 info
.entry
.nlink
= 1;
903 ret
= umsdos_newentry (dentry
->d_parent
, &info
);
907 /* lookup the short name dentry */
908 temp
= umsdos_lookup_dentry(dentry
->d_parent
, info
.fake
.fname
,
914 /* Keep the short name dentry anonymous */
918 /* Make sure the short name doesn't exist */
921 printk("umsdos_mkdir: short name %s/%s exists\n",
922 dentry
->d_parent
->d_name
.name
, info
.fake
.fname
);
923 goto out_remove_dput
;
926 ret
= msdos_mkdir (dir
, temp
, mode
);
928 goto out_remove_dput
;
931 * Lock the inode to protect the EMD creation ...
933 inode
= temp
->d_inode
;
937 * Note! The long and short name might be the same,
938 * so check first before doing the instantiate ...
940 if (dentry
!= temp
) {
942 printk("umsdos_mkdir: dentry not negative!\n");
944 d_instantiate(dentry
, inode
);
946 /* N.B. this should have an option to create the EMD ... */
947 umsdos_lookup_patch_new(dentry
, &info
);
950 * Create the EMD file, and set up the dir so it is
951 * promoted to EMD with the EMD file invisible.
953 * N.B. error return if EMD fails?
955 err
= umsdos_make_emd(dentry
);
956 umsdos_setup_dir(dentry
);
962 Printk(("umsdos_mkdir: %s/%s, ret=%d\n",
963 dentry
->d_parent
->d_name
.name
, dentry
->d_name
.name
, ret
));
966 /* an error occurred ... remove EMD entry. */
970 umsdos_delentry (dentry
->d_parent
, &info
, 1);
975 * Add a new device special file into a directory.
977 * #Specification: Special files / strategy
978 * Device special file, pipes, etc ... are created like normal
979 * file in the msdos file system. Of course they remain empty.
981 * One strategy was to create those files only in the EMD file
982 * since they were not important for MSDOS. The problem with
983 * that, is that there were not getting inode number allocated.
984 * The MSDOS filesystems is playing a nice game to fake inode
985 * number, so why not use it.
987 * The absence of inode number compatible with those allocated
988 * for ordinary files was causing major trouble with hard link
989 * in particular and other parts of the kernel I guess.
991 int UMSDOS_mknod (struct inode
*dir
, struct dentry
*dentry
,
994 return umsdos_create_any (dir
, dentry
, mode
, rdev
, 0);
998 * Remove a sub-directory.
1000 int UMSDOS_rmdir (struct inode
*dir
, struct dentry
*dentry
)
1002 struct dentry
*temp
;
1003 int ret
, err
, empty
;
1004 struct umsdos_info info
;
1006 ret
= umsdos_nevercreat (dir
, dentry
, -EPERM
);
1011 if (!list_empty(&dentry
->d_hash
))
1014 /* check whether the EMD is empty */
1016 empty
= umsdos_isempty (dentry
);
1018 /* Have to remove the EMD file? */
1020 struct dentry
*demd
;
1022 demd
= umsdos_get_emd_dentry(dentry
);
1023 if (!IS_ERR(demd
)) {
1026 err
= msdos_unlink (dentry
->d_inode
, demd
);
1027 Printk (("UMSDOS_rmdir: unlinking empty EMD err=%d", err
));
1028 #ifdef UMSDOS_PARANOIA
1030 printk("umsdos_rmdir: EMD %s/%s unlink failed, err=%d\n",
1031 demd
->d_parent
->d_name
.name
, demd
->d_name
.name
, err
);
1037 } else if (empty
== 2)
1042 umsdos_parse (dentry
->d_name
.name
, dentry
->d_name
.len
, &info
);
1043 /* Call findentry to complete the mangling */
1044 umsdos_findentry (dentry
->d_parent
, &info
, 2);
1045 temp
= umsdos_lookup_dentry(dentry
->d_parent
, info
.fake
.fname
,
1047 ret
= PTR_ERR(temp
);
1051 * If the short name is an alias, dput() it now;
1052 * otherwise d_drop() it to keep it anonymous.
1060 * Attempt to remove the msdos name.
1062 ret
= msdos_rmdir (dir
, temp
);
1063 if (ret
&& ret
!= -ENOENT
)
1066 /* OK so far ... remove the name from the EMD */
1067 ret
= umsdos_delentry (dentry
->d_parent
, &info
, 1);
1068 #ifdef UMSDOS_PARANOIA
1070 printk("umsdos_rmdir: delentry %s failed, ret=%d\n", info
.entry
.name
, ret
);
1073 /* dput() temp if we didn't do it above */
1079 Printk (("umsdos_rmdir %d\n", ret
));
1085 * Remove a file from the directory.
1087 * #Specification: hard link / deleting a link
1088 * When we delete a file and this file is a link,
1089 * we must subtract 1 from the nlink field of the
1092 * If the count goes to 0, we delete this hidden
1095 int UMSDOS_unlink (struct inode
*dir
, struct dentry
*dentry
)
1097 struct dentry
*temp
, *link
= NULL
;
1098 struct inode
*inode
;
1099 int ret
, rehash
= 0;
1100 struct umsdos_info info
;
1102 Printk(("UMSDOS_unlink: entering %s/%s\n",
1103 dentry
->d_parent
->d_name
.name
, dentry
->d_name
.name
));
1105 ret
= umsdos_nevercreat (dir
, dentry
, -EPERM
);
1109 ret
= umsdos_parse (dentry
->d_name
.name
, dentry
->d_name
.len
, &info
);
1113 umsdos_lockcreate (dir
);
1114 ret
= umsdos_findentry (dentry
->d_parent
, &info
, 1);
1116 printk("UMSDOS_unlink: %s/%s not in EMD, ret=%d\n",
1117 dentry
->d_parent
->d_name
.name
, dentry
->d_name
.name
, ret
);
1121 Printk (("UMSDOS_unlink %.*s ", info
.fake
.len
, info
.fake
.fname
));
1124 /* check sticky bit */
1125 if (is_sticky(dir
, info
.entry
.uid
)) {
1126 printk("umsdos_unlink: %s/%s is sticky\n",
1127 dentry
->d_parent
->d_name
.name
, dentry
->d_name
.name
);
1132 * Note! If this is a hardlink and the names are aliased,
1133 * the short-name lookup will return the hardlink dentry.
1134 * In order to get the correct (real) inode, we just drop
1135 * the original dentry.
1137 if (info
.entry
.flags
& UMSDOS_HLINK
) {
1138 rehash
= !list_empty(&dentry
->d_hash
);
1140 Printk(("UMSDOS_unlink: hard link %s/%s, fake=%s, rehash=%d\n",
1141 dentry
->d_parent
->d_name
.name
, dentry
->d_name
.name
, info
.fake
.fname
, rehash
));
1144 /* Do a real lookup to get the short name dentry */
1145 temp
= umsdos_lookup_dentry(dentry
->d_parent
, info
.fake
.fname
,
1147 ret
= PTR_ERR(temp
);
1152 * Resolve hardlinks now, but defer processing until later.
1154 if (info
.entry
.flags
& UMSDOS_HLINK
) {
1155 link
= umsdos_solve_hlink(dget(temp
));
1159 * If the short and long names are aliased,
1160 * dput() it now so the dentry isn't busy.
1165 /* Delete the EMD entry */
1166 ret
= umsdos_delentry (dentry
->d_parent
, &info
, 0);
1167 if (ret
&& ret
!= -ENOENT
) {
1168 printk(KERN_WARNING
"UMSDOS_unlink: delentry %s, error=%d\n",
1169 info
.entry
.name
, ret
);
1173 ret
= msdos_unlink_umsdos (dir
, temp
);
1174 #ifdef UMSDOS_PARANOIA
1176 printk("umsdos_unlink: %s/%s unlink failed, ret=%d\n",
1177 temp
->d_parent
->d_name
.name
, temp
->d_name
.name
, ret
);
1180 /* dput() temp if we didn't do it above */
1182 if (temp
!= dentry
) {
1190 umsdos_unlockcreate (dir
);
1193 * Now check for deferred handling of a hardlink.
1199 printk("umsdos_unlink: failed to resolve %s/%s\n",
1200 dentry
->d_parent
->d_name
.name
, dentry
->d_name
.name
);
1202 ret
= PTR_ERR(link
);
1206 Printk(("umsdos_unlink: link %s/%s deferred, pending ret=%d\n",
1207 link
->d_parent
->d_name
.name
, link
->d_name
.name
, ret
));
1209 /* already have an error? */
1213 /* make sure the link exists ... */
1214 inode
= link
->d_inode
;
1216 printk(KERN_WARNING
"umsdos_unlink: hard link not found\n");
1221 * If this was the last linked reference, delete it now.
1223 * N.B. Deadlock problem? We should be holding the lock
1224 * for the hardlink's parent, but another process might
1225 * be holding that lock waiting for us to finish ...
1227 if (inode
->i_nlink
<= 1) {
1228 ret
= UMSDOS_unlink (link
->d_parent
->d_inode
, link
);
1231 "umsdos_unlink: link removal failed, ret=%d\n",
1235 struct iattr newattrs
;
1237 newattrs
.ia_valid
= 0;
1238 ret
= umsdos_notify_change_locked(link
, &newattrs
);
1246 Printk (("umsdos_unlink %d\n", ret
));
1252 * Rename (move) a file.
1254 int UMSDOS_rename (struct inode
*old_dir
, struct dentry
*old_dentry
,
1255 struct inode
*new_dir
, struct dentry
*new_dentry
)
1257 struct dentry
*new_target
;
1260 #ifdef UMSDOS_DEBUG_VERBOSE
1261 printk("umsdos_rename: enter, %s/%s(%ld) to %s/%s(%ld)\n",
1262 old_dentry
->d_parent
->d_name
.name
, old_dentry
->d_name
.name
,
1263 old_dentry
->d_inode
->i_ino
,
1264 new_dentry
->d_parent
->d_name
.name
, new_dentry
->d_name
.name
,
1265 new_dentry
->d_inode
? new_dentry
->d_inode
->i_ino
: 0);
1267 ret
= umsdos_nevercreat (new_dir
, new_dentry
, -EEXIST
);
1272 * If the target already exists, delete it first.
1274 if (new_dentry
->d_inode
) {
1275 if (S_ISDIR(new_dentry
->d_inode
->i_mode
))
1276 ret
= UMSDOS_rmdir (new_dir
, new_dentry
);
1278 ret
= UMSDOS_unlink (new_dir
, new_dentry
);
1284 * If we didn't get a negative dentry, make a copy and hash it.
1286 new_target
= new_dentry
;
1287 if (new_dentry
->d_inode
) {
1288 printk("umsdos_rename: %s/%s not negative, hash=%d\n",
1289 new_dentry
->d_parent
->d_name
.name
, new_dentry
->d_name
.name
,
1290 !list_empty(&new_dentry
->d_hash
));
1292 new_target
= d_alloc(new_dentry
->d_parent
, &new_dentry
->d_name
);
1295 d_add(new_target
, NULL
);
1297 ret
= umsdos_rename_f(old_dir
, old_dentry
, new_dir
, new_target
, 0);
1298 if (new_target
!= new_dentry
)