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 * You are in the maze of twisted functions - half of them shouldn't
14 #include <linux/errno.h>
15 #include <linux/kernel.h>
16 #include <linux/sched.h>
17 #include <linux/types.h>
18 #include <linux/fcntl.h>
19 #include <linux/stat.h>
20 #include <linux/string.h>
21 #include <linux/msdos_fs.h>
22 #include <linux/umsdos_fs.h>
23 #include <linux/malloc.h>
27 * Wait for creation exclusivity.
28 * Return 0 if the dir was already available.
29 * Return 1 if a wait was necessary.
30 * When 1 is return, it means a wait was done. It does not
31 * mean the directory is available.
33 static int umsdos_waitcreate (struct inode
*dir
)
37 if (dir
->u
.umsdos_i
.u
.dir_info
.creating
38 && dir
->u
.umsdos_i
.u
.dir_info
.pid
!= current
->pid
) {
39 sleep_on (&dir
->u
.umsdos_i
.u
.dir_info
.p
);
46 * Wait for any lookup process to finish
48 static void umsdos_waitlookup (struct inode
*dir
)
50 while (dir
->u
.umsdos_i
.u
.dir_info
.looking
) {
51 sleep_on (&dir
->u
.umsdos_i
.u
.dir_info
.p
);
56 * Lock all other process out of this directory.
58 /* #Specification: file creation / not atomic
59 * File creation is a two step process. First we create (allocate)
60 * an entry in the EMD file and then (using the entry offset) we
61 * build a unique name for MSDOS. We create this name in the msdos
64 * We have to use semaphore (sleep_on/wake_up) to prevent lookup
65 * into a directory when we create a file or directory and to
66 * prevent creation while a lookup is going on. Since many lookup
67 * may happen at the same time, the semaphore is a counter.
69 * Only one creation is allowed at the same time. This protection
70 * may not be necessary. The problem arise mainly when a lookup
71 * or a readdir is done while a file is partially created. The
72 * lookup process see that as a "normal" problem and silently
73 * erase the file from the EMD file. Normal because a file
74 * may be erased during a MSDOS session, but not removed from
77 * The locking is done on a directory per directory basis. Each
78 * directory inode has its wait_queue.
80 * For some operation like hard link, things even get worse. Many
81 * creation must occur at once (atomic). To simplify the design
82 * a process is allowed to recursively lock the directory for
83 * creation. The pid of the locking process is kept along with
84 * a counter so a second level of locking is granted or not.
86 void umsdos_lockcreate (struct inode
*dir
)
89 * Wait for any creation process to finish except
90 * if we (the process) own the lock
92 while (umsdos_waitcreate (dir
) != 0);
93 dir
->u
.umsdos_i
.u
.dir_info
.creating
++;
94 dir
->u
.umsdos_i
.u
.dir_info
.pid
= current
->pid
;
95 umsdos_waitlookup (dir
);
99 * Lock all other process out of those two directories.
101 static void umsdos_lockcreate2 (struct inode
*dir1
, struct inode
*dir2
)
104 * We must check that both directory are available before
105 * locking anyone of them. This is to avoid some deadlock.
106 * Thanks to dglaude@is1.vub.ac.be (GLAUDE DAVID) for pointing
110 if (umsdos_waitcreate (dir1
) == 0
111 && umsdos_waitcreate (dir2
) == 0) {
112 /* We own both now */
113 dir1
->u
.umsdos_i
.u
.dir_info
.creating
++;
114 dir1
->u
.umsdos_i
.u
.dir_info
.pid
= current
->pid
;
115 dir2
->u
.umsdos_i
.u
.dir_info
.creating
++;
116 dir2
->u
.umsdos_i
.u
.dir_info
.pid
= current
->pid
;
120 umsdos_waitlookup (dir1
);
121 umsdos_waitlookup (dir2
);
125 * Wait until creation is finish in this directory.
127 void umsdos_startlookup (struct inode
*dir
)
129 while (umsdos_waitcreate (dir
) != 0);
130 dir
->u
.umsdos_i
.u
.dir_info
.looking
++;
134 * Unlock the directory.
136 void umsdos_unlockcreate (struct inode
*dir
)
138 dir
->u
.umsdos_i
.u
.dir_info
.creating
--;
139 if (dir
->u
.umsdos_i
.u
.dir_info
.creating
< 0) {
140 printk ("UMSDOS: dir->u.umsdos_i.u.dir_info.creating < 0: %d"
141 ,dir
->u
.umsdos_i
.u
.dir_info
.creating
);
143 wake_up (&dir
->u
.umsdos_i
.u
.dir_info
.p
);
147 * Tell directory lookup is over.
149 void umsdos_endlookup (struct inode
*dir
)
151 dir
->u
.umsdos_i
.u
.dir_info
.looking
--;
152 if (dir
->u
.umsdos_i
.u
.dir_info
.looking
< 0) {
153 printk ("UMSDOS: dir->u.umsdos_i.u.dir_info.looking < 0: %d"
154 ,dir
->u
.umsdos_i
.u
.dir_info
.looking
);
156 wake_up (&dir
->u
.umsdos_i
.u
.dir_info
.p
);
160 static void umsdos_lockcreate (struct inode
*dir
)
163 static void umsdos_lockcreate2 (struct inode
*dir1
, struct inode
*dir2
)
166 void umsdos_startlookup (struct inode
*dir
)
169 static void umsdos_unlockcreate (struct inode
*dir
)
172 void umsdos_endlookup (struct inode
*dir
)
178 static int umsdos_nevercreat (struct inode
*dir
, struct dentry
*dentry
,
183 if (umsdos_is_pseudodos (dir
, dentry
)) {
184 /* #Specification: pseudo root / any file creation /DOS
185 * The pseudo sub-directory /DOS can't be created!
186 * EEXIST is returned.
188 * The pseudo sub-directory /DOS can't be removed!
197 * Add a new file (ordinary or special) into the alternate directory.
198 * The file is added to the real MSDOS directory. If successful, it
199 * is then added to the EMD file.
201 * Return the status of the operation. 0 mean success.
203 * #Specification: create / file exists in DOS
204 * Here is a situation: we are trying to create a file with
205 * UMSDOS. The file is unknown to UMSDOS but already
206 * exists in the DOS directory.
208 * Here is what we are NOT doing:
210 * We could silently assume that everything is fine
211 * and allows the creation to succeed.
213 * It is possible not all files in the partition
214 * are meant to be visible from linux. By trying to create
215 * those file in some directory, one user may get access
216 * to those file without proper permissions. Looks like
217 * a security hole to me. Off course sharing a file system
218 * with DOS is some kind of security hole :-)
222 * We return EEXIST in this case.
223 * The same is true for directory creation.
225 static int umsdos_create_any (struct inode
*dir
, struct dentry
*dentry
,
226 int mode
, int rdev
, char flags
)
231 struct umsdos_info info
;
233 ret
= umsdos_nevercreat (dir
, dentry
, -EEXIST
);
237 ret
= umsdos_parse (dentry
->d_name
.name
, dentry
->d_name
.len
, &info
);
241 info
.entry
.mode
= mode
;
242 info
.entry
.rdev
= rdev
;
243 info
.entry
.flags
= flags
;
244 info
.entry
.uid
= current
->fsuid
;
245 info
.entry
.gid
= (dir
->i_mode
& S_ISGID
) ? dir
->i_gid
: current
->fsgid
;
246 info
.entry
.ctime
= info
.entry
.atime
= info
.entry
.mtime
= CURRENT_TIME
;
247 info
.entry
.nlink
= 1;
248 ret
= umsdos_newentry (dentry
->d_parent
, &info
);
252 /* do a real lookup to get the short name dentry */
253 fake
= umsdos_covered(dentry
->d_parent
, info
.fake
.fname
, info
.fake
.len
);
258 /* should not exist yet ... */
261 goto out_remove_dput
;
263 ret
= msdos_create (dir
, fake
, S_IFREG
| 0777);
265 goto out_remove_dput
;
267 inode
= fake
->d_inode
;
269 d_instantiate (dentry
, inode
);
271 if (inode
->i_count
> 1) {
273 "umsdos_create_any: %s/%s, ino=%ld, icount=%d??\n",
274 dentry
->d_parent
->d_name
.name
, dentry
->d_name
.name
,
275 inode
->i_ino
, inode
->i_count
);
277 umsdos_lookup_patch_new(dentry
, &info
);
282 /* Creation failed ... remove the EMD entry */
287 printk(KERN_WARNING
"UMSDOS: out of sync, deleting %s/%s\n",
288 dentry
->d_parent
->d_name
.name
, info
.fake
.fname
);
289 umsdos_delentry (dentry
->d_parent
, &info
, S_ISDIR (info
.entry
.mode
));
294 * Add a new file into the alternate directory.
295 * The file is added to the real MSDOS directory. If successful, it
296 * is then added to the EMD file.
298 * Return the status of the operation. 0 mean success.
300 int UMSDOS_create (struct inode
*dir
, struct dentry
*dentry
, int mode
)
302 return umsdos_create_any (dir
, dentry
, mode
, 0, 0);
307 * Initialise the new_entry from the old for a rename operation.
308 * (Only useful for umsdos_rename_f() below).
310 static void umsdos_ren_init (struct umsdos_info
*new_info
,
311 struct umsdos_info
*old_info
)
313 new_info
->entry
.mode
= old_info
->entry
.mode
;
314 new_info
->entry
.rdev
= old_info
->entry
.rdev
;
315 new_info
->entry
.uid
= old_info
->entry
.uid
;
316 new_info
->entry
.gid
= old_info
->entry
.gid
;
317 new_info
->entry
.ctime
= old_info
->entry
.ctime
;
318 new_info
->entry
.atime
= old_info
->entry
.atime
;
319 new_info
->entry
.mtime
= old_info
->entry
.mtime
;
320 new_info
->entry
.flags
= old_info
->entry
.flags
;
321 new_info
->entry
.nlink
= old_info
->entry
.nlink
;
326 if (STACK_MAGIC != *(unsigned long *)current->kernel_stack_page){\
327 printk(KERN_ALERT "UMSDOS: %s magic %x != %lx ligne %d\n" \
328 , current->comm,STACK_MAGIC \
329 ,*(unsigned long *)current->kernel_stack_page \
334 #define chkstk() do { } while (0);
338 * Rename a file (move) in the file system.
341 static int umsdos_rename_f (struct inode
*old_dir
, struct dentry
*old_dentry
,
342 struct inode
*new_dir
, struct dentry
*new_dentry
,
345 struct inode
*old_inode
= old_dentry
->d_inode
;
346 struct dentry
*old
, *new, *old_emd
;
348 struct umsdos_info old_info
;
349 struct umsdos_info new_info
;
352 err
= umsdos_parse (old_dentry
->d_name
.name
,
353 old_dentry
->d_name
.len
, &old_info
);
356 err
= umsdos_parse (new_dentry
->d_name
.name
,
357 new_dentry
->d_name
.len
, &new_info
);
361 /* Get the EMD dentry for the old parent */
362 old_emd
= umsdos_get_emd_dentry(old_dentry
->d_parent
);
363 ret
= PTR_ERR(old_emd
);
367 umsdos_lockcreate2 (old_dir
, new_dir
);
369 ret
= umsdos_findentry(old_emd
->d_parent
, &old_info
, 0);
373 err
= umsdos_findentry(new_dentry
->d_parent
, &new_info
, 0);
375 /* check whether it _really_ exists ... */
377 if (new_dentry
->d_inode
)
380 /* bogus lookup? complain and fix up the EMD ... */
382 "umsdos_rename_f: entry %s/%s exists, inode NULL??\n",
383 new_dentry
->d_parent
->d_name
.name
, new_info
.entry
.name
);
384 err
= umsdos_delentry(new_dentry
->d_parent
, &new_info
,
385 S_ISDIR(new_info
.entry
.mode
));
388 umsdos_ren_init (&new_info
, &old_info
);
390 new_info
.entry
.flags
= flags
;
391 ret
= umsdos_newentry (new_dentry
->d_parent
, &new_info
);
395 /* If we're moving a hardlink, drop it first */
396 if (old_info
.entry
.flags
& UMSDOS_HLINK
) {
400 old
= umsdos_covered(old_dentry
->d_parent
, old_info
.fake
.fname
,
405 /* make sure it's the same inode! */
407 if (old
->d_inode
!= old_inode
)
410 new = umsdos_covered(new_dentry
->d_parent
, new_info
.fake
.fname
,
416 /* Do the msdos-level rename */
417 ret
= msdos_rename (old_dir
, old
, new_dir
, new);
421 /* If the rename failed, remove the new EMD entry */
423 umsdos_delentry (new_dentry
->d_parent
, &new_info
,
424 S_ISDIR (new_info
.entry
.mode
));
429 * Rename successful ... remove the old name from the EMD.
430 * Note that we use the EMD parent here, as the old dentry
431 * may have moved to a new parent ...
433 err
= umsdos_delentry (old_emd
->d_parent
, &old_info
,
434 S_ISDIR (old_info
.entry
.mode
));
436 /* Failed? Complain a bit, but don't fail the operation */
438 "umsdos_rename_f: delentry %s/%s failed, error=%d\n",
439 old_emd
->d_parent
->d_name
.name
, old_info
.entry
.name
,
444 * Update f_pos so notify_change will succeed
445 * if the file was already in use.
447 umsdos_set_dirinfo_new(old_dentry
, new_info
.f_pos
);
449 /* dput() the dentry if we haven't already */
455 umsdos_unlockcreate (old_dir
);
456 umsdos_unlockcreate (new_dir
);
459 Printk ((" _ret=%d\n", ret
));
464 * Setup a Symbolic link or a (pseudo) hard link
465 * Return a negative error code or 0 if OK.
467 /* #Specification: symbolic links / strategy
468 * A symbolic link is simply a file which holds a path. It is
469 * implemented as a normal MSDOS file (not very space efficient :-()
471 * I see two different ways to do this: One is to place the link data
472 * in unused entries of the EMD file; the other is to have a separate
473 * file dedicated to hold all symbolic links data.
475 * Let's go for simplicity...
478 extern struct inode_operations umsdos_symlink_inode_operations
;
481 * AV. Should be called with dir->i_sem down.
483 static int umsdos_symlink_x (struct inode
*dir
, struct dentry
*dentry
,
484 const char *symname
, int mode
, char flags
)
489 Printk(("umsdos_symlink: %s/%s to %s\n",
490 dentry
->d_parent
->d_name
.name
, dentry
->d_name
.name
, symname
));
492 ret
= umsdos_create_any (dir
, dentry
, mode
, 0, flags
);
495 "umsdos_symlink: create failed, ret=%d\n", ret
);
499 fill_new_filp (&filp
, dentry
);
500 len
= strlen (symname
);
501 ret
= umsdos_file_write_kmem_real (&filp
, symname
, len
);
513 printk(KERN_WARNING
"umsdos_symlink: write failed, unlinking\n");
514 UMSDOS_unlink (dir
, dentry
);
519 * Setup a Symbolic link.
520 * Return a negative error code or 0 if OK.
522 int UMSDOS_symlink ( struct inode
*dir
, struct dentry
*dentry
,
525 return umsdos_symlink_x (dir
, dentry
, symname
, S_IFLNK
| 0777, 0);
529 * Add a link to an inode in a directory
531 int UMSDOS_link (struct dentry
*olddentry
, struct inode
*dir
,
532 struct dentry
*dentry
)
534 struct inode
*oldinode
= olddentry
->d_inode
;
535 struct inode
*olddir
= olddentry
->d_parent
->d_inode
;
538 unsigned long buffer
;
540 struct umsdos_info old_info
;
541 struct umsdos_info hid_info
;
543 #ifdef UMSDOS_DEBUG_VERBOSE
544 printk("umsdos_link: new %s%s -> %s/%s\n",
545 dentry
->d_parent
->d_name
.name
, dentry
->d_name
.name
,
546 olddentry
->d_parent
->d_name
.name
, olddentry
->d_name
.name
);
550 if (S_ISDIR (oldinode
->i_mode
))
553 ret
= umsdos_nevercreat (dir
, dentry
, -EPERM
);
558 buffer
= get_free_page(GFP_KERNEL
);
563 * Lock the link parent if it's not the same directory.
567 if (atomic_read(&olddir
->i_sem
.count
) < 1)
569 down(&olddir
->i_sem
);
573 * Parse the name and get the visible directory entry.
575 ret
= umsdos_parse (olddentry
->d_name
.name
, olddentry
->d_name
.len
,
579 ret
= umsdos_findentry (olddentry
->d_parent
, &old_info
, 1);
581 printk("UMSDOS_link: %s/%s not in EMD, ret=%d\n",
582 olddentry
->d_parent
->d_name
.name
, olddentry
->d_name
.name
, ret
);
587 * If the visible dentry is a pseudo-hardlink, the original
588 * file must be already hidden.
590 if (!(old_info
.entry
.flags
& UMSDOS_HLINK
)) {
593 /* create a hidden link name */
594 ret
= umsdos_newhidden (olddentry
->d_parent
, &hid_info
);
596 printk("umsdos_link: can't make hidden %s/%s, ret=%d\n",
597 olddentry
->d_parent
->d_name
.name
, hid_info
.entry
.name
, ret
);
602 * Make a dentry and rename the original file ...
604 temp
= umsdos_lookup_dentry(olddentry
->d_parent
,
606 hid_info
.entry
.name_len
, 0);
609 printk("umsdos_link: lookup %s/%s failed, ret=%d\n",
610 dentry
->d_parent
->d_name
.name
, hid_info
.entry
.name
, ret
);
613 /* rename the link to the hidden location ... */
614 ret
= umsdos_rename_f(olddir
, olddentry
, olddir
, temp
,
616 d_move(olddentry
, temp
);
619 printk("umsdos_link: rename to %s/%s failed, ret=%d\n",
620 temp
->d_parent
->d_name
.name
, temp
->d_name
.name
, ret
);
623 /* mark the inode as a hardlink */
624 oldinode
->u
.umsdos_i
.i_is_hlink
= 1;
627 * Capture the path to the hidden link.
629 path
= umsdos_d_path(olddentry
, (char *) buffer
, PAGE_SIZE
);
630 Printk(("umsdos_link: hidden link path=%s\n", path
));
633 * Recreate a dentry for the original name and symlink it,
634 * then symlink the new dentry. Don't give up if one fails,
635 * or we'll lose the file completely!
637 * Note: this counts as the "original" reference, so we
638 * don't increment i_nlink for this one.
640 temp
= umsdos_lookup_dentry(olddentry
->d_parent
,
642 old_info
.entry
.name_len
, 0);
645 ret
= umsdos_symlink_x (olddir
, temp
, path
,
646 S_IFREG
| 0777, UMSDOS_HLINK
);
650 /* This symlink increments i_nlink (see below.) */
651 err
= umsdos_symlink_x (dir
, dentry
, path
,
652 S_IFREG
| 0777, UMSDOS_HLINK
);
653 /* fold the two errors */
658 /* creation failed ... remove the link entry */
660 printk("umsdos_link: link failed, ret=%d, removing %s/%s\n",
661 ret
, olddentry
->d_parent
->d_name
.name
, hid_info
.entry
.name
);
662 err
= umsdos_delentry(olddentry
->d_parent
, &hid_info
, 0);
666 Printk(("UMSDOS_link: %s/%s already hidden\n",
667 olddentry
->d_parent
->d_name
.name
, olddentry
->d_name
.name
));
669 * The original file is already hidden, and we need to get
670 * the dentry for its real name, not the visible name.
671 * N.B. make sure it's the hidden inode ...
673 if (!oldinode
->u
.umsdos_i
.i_is_hlink
)
674 printk("UMSDOS_link: %s/%s hidden, ino=%ld not hlink??\n",
675 olddentry
->d_parent
->d_name
.name
,
676 olddentry
->d_name
.name
, oldinode
->i_ino
);
679 * In order to get the correct (real) inode, we just drop
680 * the original dentry.
683 Printk(("UMSDOS_link: hard link %s/%s, fake=%s\n",
684 olddentry
->d_parent
->d_name
.name
, olddentry
->d_name
.name
, old_info
.fake
.fname
));
686 /* Do a real lookup to get the short name dentry */
687 temp
= umsdos_covered(olddentry
->d_parent
, old_info
.fake
.fname
,
693 /* now resolve the link ... */
694 temp
= umsdos_solve_hlink(temp
);
698 path
= umsdos_d_path(temp
, (char *) buffer
, PAGE_SIZE
);
700 Printk(("umsdos_link: %s/%s already hidden, path=%s\n",
701 olddentry
->d_parent
->d_name
.name
, olddentry
->d_name
.name
, path
));
703 /* finally we can symlink it ... */
704 ret
= umsdos_symlink_x (dir
, dentry
, path
, S_IFREG
| 0777,UMSDOS_HLINK
);
707 /* remain locked for the call to notify_change ... */
709 struct iattr newattrs
;
711 #ifdef UMSDOS_PARANOIA
712 if (!oldinode
->u
.umsdos_i
.i_is_hlink
)
713 printk("UMSDOS_link: %s/%s, ino=%ld, not marked as hlink!\n",
714 olddentry
->d_parent
->d_name
.name
, olddentry
->d_name
.name
, oldinode
->i_ino
);
717 Printk(("UMSDOS_link: linked %s/%s, ino=%ld, nlink=%d\n",
718 olddentry
->d_parent
->d_name
.name
, olddentry
->d_name
.name
,
719 oldinode
->i_ino
, oldinode
->i_nlink
));
720 newattrs
.ia_valid
= 0;
721 ret
= umsdos_notify_change_locked(olddentry
, &newattrs
);
729 Printk (("umsdos_link %d\n", ret
));
735 * Add a sub-directory in a directory
737 /* #Specification: mkdir / Directory already exist in DOS
738 * We do the same thing as for file creation.
739 * For all user it is an error.
741 /* #Specification: mkdir / umsdos directory / create EMD
742 * When we created a new sub-directory in a UMSDOS
743 * directory (one with full UMSDOS semantics), we
744 * create immediately an EMD file in the new
745 * sub-directory so it inherits UMSDOS semantics.
747 int UMSDOS_mkdir (struct inode
*dir
, struct dentry
*dentry
, int mode
)
752 struct umsdos_info info
;
754 ret
= umsdos_nevercreat (dir
, dentry
, -EEXIST
);
758 ret
= umsdos_parse (dentry
->d_name
.name
, dentry
->d_name
.len
, &info
);
762 info
.entry
.mode
= mode
| S_IFDIR
;
764 info
.entry
.uid
= current
->fsuid
;
765 info
.entry
.gid
= (dir
->i_mode
& S_ISGID
) ? dir
->i_gid
: current
->fsgid
;
766 info
.entry
.ctime
= info
.entry
.atime
= info
.entry
.mtime
= CURRENT_TIME
;
767 info
.entry
.flags
= 0;
768 info
.entry
.nlink
= 1;
769 ret
= umsdos_newentry (dentry
->d_parent
, &info
);
773 /* lookup the short name dentry */
774 temp
= umsdos_covered(dentry
->d_parent
, info
.fake
.fname
, info
.fake
.len
);
779 /* Make sure the short name doesn't exist */
782 printk("umsdos_mkdir: short name %s/%s exists\n",
783 dentry
->d_parent
->d_name
.name
, info
.fake
.fname
);
784 goto out_remove_dput
;
787 ret
= msdos_mkdir (dir
, temp
, mode
);
789 goto out_remove_dput
;
792 * Lock the inode to protect the EMD creation ...
794 inode
= temp
->d_inode
;
798 d_instantiate(dentry
, inode
);
800 /* N.B. this should have an option to create the EMD ... */
801 umsdos_lookup_patch_new(dentry
, &info
);
804 * Create the EMD file, and set up the dir so it is
805 * promoted to EMD with the EMD file invisible.
807 * N.B. error return if EMD fails?
809 err
= umsdos_make_emd(dentry
);
810 umsdos_setup_dir(dentry
);
816 Printk(("umsdos_mkdir: %s/%s, ret=%d\n",
817 dentry
->d_parent
->d_name
.name
, dentry
->d_name
.name
, ret
));
820 /* an error occurred ... remove EMD entry. */
824 umsdos_delentry (dentry
->d_parent
, &info
, 1);
829 * Add a new device special file into a directory.
831 * #Specification: Special files / strategy
832 * Device special file, pipes, etc ... are created like normal
833 * file in the msdos file system. Of course they remain empty.
835 * One strategy was to create those files only in the EMD file
836 * since they were not important for MSDOS. The problem with
837 * that, is that there were not getting inode number allocated.
838 * The MSDOS filesystems is playing a nice game to fake inode
839 * number, so why not use it.
841 * The absence of inode number compatible with those allocated
842 * for ordinary files was causing major trouble with hard link
843 * in particular and other parts of the kernel I guess.
845 int UMSDOS_mknod (struct inode
*dir
, struct dentry
*dentry
,
848 return umsdos_create_any (dir
, dentry
, mode
, rdev
, 0);
852 * Remove a sub-directory.
854 int UMSDOS_rmdir (struct inode
*dir
, struct dentry
*dentry
)
858 struct umsdos_info info
;
860 ret
= umsdos_nevercreat (dir
, dentry
, -EPERM
);
865 if (!list_empty(&dentry
->d_hash
))
868 /* check whether the EMD is empty */
870 empty
= umsdos_isempty (dentry
);
872 /* Have to remove the EMD file? */
876 demd
= umsdos_get_emd_dentry(dentry
);
880 err
= msdos_unlink (dentry
->d_inode
, demd
);
881 Printk (("UMSDOS_rmdir: unlinking empty EMD err=%d", err
));
882 #ifdef UMSDOS_PARANOIA
884 printk("umsdos_rmdir: EMD %s/%s unlink failed, err=%d\n",
885 demd
->d_parent
->d_name
.name
, demd
->d_name
.name
, err
);
891 } else if (empty
== 2)
896 umsdos_parse (dentry
->d_name
.name
, dentry
->d_name
.len
, &info
);
897 /* Call findentry to complete the mangling */
898 umsdos_findentry (dentry
->d_parent
, &info
, 2);
899 temp
= umsdos_covered(dentry
->d_parent
, info
.fake
.fname
, info
.fake
.len
);
904 * Attempt to remove the msdos name.
906 ret
= msdos_rmdir (dir
, temp
);
907 if (ret
&& ret
!= -ENOENT
)
910 /* OK so far ... remove the name from the EMD */
911 ret
= umsdos_delentry (dentry
->d_parent
, &info
, 1);
912 #ifdef UMSDOS_PARANOIA
914 printk("umsdos_rmdir: delentry %s failed, ret=%d\n", info
.entry
.name
, ret
);
917 /* dput() temp if we didn't do it above */
922 Printk (("umsdos_rmdir %d\n", ret
));
928 * Remove a file from the directory.
930 * #Specification: hard link / deleting a link
931 * When we delete a file and this file is a link,
932 * we must subtract 1 from the nlink field of the
935 * If the count goes to 0, we delete this hidden
938 int UMSDOS_unlink (struct inode
*dir
, struct dentry
*dentry
)
940 struct dentry
*temp
, *link
= NULL
;
943 struct umsdos_info info
;
945 Printk(("UMSDOS_unlink: entering %s/%s\n",
946 dentry
->d_parent
->d_name
.name
, dentry
->d_name
.name
));
948 ret
= umsdos_nevercreat (dir
, dentry
, -EPERM
);
952 ret
= umsdos_parse (dentry
->d_name
.name
, dentry
->d_name
.len
, &info
);
956 umsdos_lockcreate (dir
);
957 ret
= umsdos_findentry (dentry
->d_parent
, &info
, 1);
959 printk("UMSDOS_unlink: %s/%s not in EMD, ret=%d\n",
960 dentry
->d_parent
->d_name
.name
, dentry
->d_name
.name
, ret
);
964 Printk (("UMSDOS_unlink %.*s ", info
.fake
.len
, info
.fake
.fname
));
967 * Note! If this is a hardlink and the names are aliased,
968 * the short-name lookup will return the hardlink dentry.
969 * In order to get the correct (real) inode, we just drop
970 * the original dentry.
972 if (info
.entry
.flags
& UMSDOS_HLINK
) {
976 /* Do a real lookup to get the short name dentry */
977 temp
= umsdos_covered(dentry
->d_parent
, info
.fake
.fname
, info
.fake
.len
);
983 * Resolve hardlinks now, but defer processing until later.
985 if (info
.entry
.flags
& UMSDOS_HLINK
) {
986 link
= umsdos_solve_hlink(dget(temp
));
989 /* Delete the EMD entry */
990 ret
= umsdos_delentry (dentry
->d_parent
, &info
, 0);
991 if (ret
&& ret
!= -ENOENT
) {
992 printk(KERN_WARNING
"UMSDOS_unlink: delentry %s, error=%d\n",
993 info
.entry
.name
, ret
);
997 ret
= msdos_unlink(dir
, temp
);
998 #ifdef UMSDOS_PARANOIA
1000 printk("umsdos_unlink: %s/%s unlink failed, ret=%d\n",
1001 temp
->d_parent
->d_name
.name
, temp
->d_name
.name
, ret
);
1004 /* dput() temp if we didn't do it above */
1011 umsdos_unlockcreate (dir
);
1014 * Now check for deferred handling of a hardlink.
1020 printk("umsdos_unlink: failed to resolve %s/%s\n",
1021 dentry
->d_parent
->d_name
.name
, dentry
->d_name
.name
);
1023 ret
= PTR_ERR(link
);
1027 Printk(("umsdos_unlink: link %s/%s deferred, pending ret=%d\n",
1028 link
->d_parent
->d_name
.name
, link
->d_name
.name
, ret
));
1030 /* already have an error? */
1034 /* make sure the link exists ... */
1035 inode
= link
->d_inode
;
1037 printk(KERN_WARNING
"umsdos_unlink: hard link not found\n");
1042 * If this was the last linked reference, delete it now.
1044 * N.B. Deadlock problem? We should be holding the lock
1045 * for the hardlink's parent, but another process might
1046 * be holding that lock waiting for us to finish ...
1048 if (inode
->i_nlink
<= 1) {
1049 ret
= UMSDOS_unlink (link
->d_parent
->d_inode
, link
);
1052 "umsdos_unlink: link removal failed, ret=%d\n",
1056 struct iattr newattrs
;
1058 newattrs
.ia_valid
= 0;
1059 ret
= umsdos_notify_change_locked(link
, &newattrs
);
1067 Printk (("umsdos_unlink %d\n", ret
));
1072 * Rename (move) a file.
1074 int UMSDOS_rename (struct inode
*old_dir
, struct dentry
*old_dentry
,
1075 struct inode
*new_dir
, struct dentry
*new_dentry
)
1079 ret
= umsdos_nevercreat (new_dir
, new_dentry
, -EEXIST
);
1084 * If the target already exists, delete it first.
1086 if (new_dentry
->d_inode
) {
1087 new_dentry
->d_count
++;
1088 if (S_ISDIR(old_dentry
->d_inode
->i_mode
))
1089 ret
= UMSDOS_rmdir (new_dir
, new_dentry
);
1091 ret
= UMSDOS_unlink (new_dir
, new_dentry
);
1096 ret
= umsdos_rename_f(old_dir
, old_dentry
, new_dir
, new_dentry
, 0);