1 |
/* main.c - FAT filesystem. |
/* dir.c - FAT filesystem. |
2 |
Copyright (C) 1997, 1998, 1999, 2002 Free Software Foundation, Inc. |
Copyright (C) 1997, 1998, 1999, 2002, 2003 Free Software Foundation, Inc. |
3 |
Written by Thomas Bushnell, n/BSG and Marcus Brinkmann. |
Written by Thomas Bushnell, n/BSG and Marcus Brinkmann. |
4 |
|
|
5 |
This file is part of the GNU Hurd. |
This file is part of the GNU Hurd. |
21 |
#include <ctype.h> |
#include <ctype.h> |
22 |
#include <string.h> |
#include <string.h> |
23 |
#include <dirent.h> |
#include <dirent.h> |
24 |
|
#include <hurd/fsys.h> |
25 |
|
|
26 |
#include "fatfs.h" |
#include "fatfs.h" |
27 |
|
|
28 |
/* The size of a directory block is usually just the cluster size. |
/* The size of a directory block is usually just the cluster size. |
619 |
munmap ((caddr_t) ds->mapbuf, ds->mapextent); |
munmap ((caddr_t) ds->mapbuf, ds->mapextent); |
620 |
return err; |
return err; |
621 |
} |
} |
622 |
} |
memset ((caddr_t) ds->mapbuf + oldsize, 0, bytes_per_cluster); |
623 |
|
} |
624 |
|
|
625 |
new = (struct dirrect *) ((char *) ds->mapbuf + oldsize); |
new = (struct dirrect *) ((char *) ds->mapbuf + oldsize); |
626 |
|
|
627 |
dp->dn_stat.st_size = oldsize + bytes_per_cluster; |
dp->dn_stat.st_size = oldsize + bytes_per_cluster; |
645 |
memcpy (new->name, " ", 11); |
memcpy (new->name, " ", 11); |
646 |
memcpy (new->name, name, namelen % 11); /* XXX */ |
memcpy (new->name, name, namelen % 11); /* XXX */ |
647 |
|
|
648 |
/* XXX We need to do much, much more here. */ |
write_word (new->first_cluster_low, np->dn->start_cluster & 0xffff); |
649 |
/* XXX What about creating . and .. for dirs? */ |
write_word (new->first_cluster_high, np->dn->start_cluster >> 16); |
650 |
|
write_dword (new->file_size, np->dn_stat.st_size); |
651 |
|
|
652 |
|
if (!(name[0] == '.' && (name[1] == '\0' |
653 |
|
|| (name[1] == '.' && name[2] =='\0')))) |
654 |
|
{ |
655 |
|
vi_key_t entry_key; |
656 |
|
|
657 |
|
entry_key.dir_inode = dp->cache_id; |
658 |
|
entry_key.dir_offset = ((int) ds->entry) - ((int) ds->mapbuf); |
659 |
|
|
660 |
|
/* Set the key for this inode now because it wasn't know when |
661 |
|
the inode was initialized. */ |
662 |
|
vi_change (vi_lookup (np->cache_id), entry_key); |
663 |
|
|
664 |
|
if (np->dn_stat.st_mode & S_IFDIR) |
665 |
|
new->attribute = FAT_DIR_ATTR_DIR; |
666 |
|
} |
667 |
|
else |
668 |
|
new->attribute = FAT_DIR_ATTR_DIR; |
669 |
|
|
670 |
/* Mark the directory inode has having been written. */ |
/* Mark the directory inode has having been written. */ |
671 |
dp->dn_set_mtime = 1; |
dp->dn_set_mtime = 1; |
714 |
error_t |
error_t |
715 |
diskfs_dirrewrite_hard (struct node *dp, struct node *np, struct dirstat *ds) |
diskfs_dirrewrite_hard (struct node *dp, struct node *np, struct dirstat *ds) |
716 |
{ |
{ |
717 |
|
error_t err; |
718 |
|
vi_key_t entry_key; |
719 |
|
mach_port_t control = MACH_PORT_NULL; |
720 |
|
struct node *oldnp; |
721 |
|
ino_t inode; |
722 |
|
inode_t vinode; |
723 |
|
|
724 |
|
/* We need the inode and vinode of the old node. */ |
725 |
|
entry_key.dir_inode = dp->cache_id; |
726 |
|
entry_key.dir_offset = ((int) ds->entry) - ((int) ds->mapbuf); |
727 |
|
err = vi_rlookup (entry_key, &inode, &vinode, 0); |
728 |
|
|
729 |
|
assert (err != EINVAL); |
730 |
|
|
731 |
|
/* Lookup the node, we already have a reference. */ |
732 |
|
oldnp = ifind (inode); |
733 |
|
|
734 |
assert (ds->type == RENAME); |
assert (ds->type == RENAME); |
735 |
assert (ds->stat == HERE_TIS); |
assert (ds->stat == HERE_TIS); |
736 |
|
|
737 |
assert (!diskfs_readonly); |
assert (!diskfs_readonly); |
738 |
|
|
739 |
/* XXX We have to reimplement rename completely. */ |
/* The link count must be 0 so the file will be removed and |
740 |
/* |
the node will be dropped. */ |
741 |
ds->entry->inode = np->cache_id; |
oldnp->dn_stat.st_nlink--; |
742 |
*/ |
assert (!oldnp->dn_stat.st_nlink); |
743 |
dp->dn_set_mtime = 1; |
|
744 |
|
/* Close the file, free the referenced held by clients. */ |
745 |
|
fshelp_fetch_control (&oldnp->transbox, &control); |
746 |
|
|
747 |
|
if (control) |
748 |
|
{ |
749 |
|
fsys_goaway (control, FSYS_GOAWAY_UNLINK); |
750 |
|
mach_port_deallocate (mach_task_self (), control); |
751 |
|
} |
752 |
|
|
753 |
|
/* Put the new key in the vinode. */ |
754 |
|
vi_change (vi_lookup (np->cache_id), entry_key); |
755 |
|
|
756 |
munmap ((caddr_t) ds->mapbuf, ds->mapextent); |
munmap ((caddr_t) ds->mapbuf, ds->mapextent); |
757 |
|
|
758 |
|
dp->dn_set_mtime = 1; |
759 |
diskfs_file_update (dp, 1); |
diskfs_file_update (dp, 1); |
760 |
|
|
761 |
return 0; |
return 0; |
792 |
|
|
793 |
if (entry->name[0] == FAT_DIR_NAME_LAST) |
if (entry->name[0] == FAT_DIR_NAME_LAST) |
794 |
break; |
break; |
795 |
if (!entry->name[0] == FAT_DIR_NAME_DELETED |
if ((char) entry->name[0] != FAT_DIR_NAME_DELETED |
796 |
&& memcmp (entry->name, FAT_DIR_NAME_DOT, 11) |
&& memcmp (entry->name, FAT_DIR_NAME_DOT, 11) |
797 |
&& memcmp (entry->name, FAT_DIR_NAME_DOTDOT, 11)) |
&& memcmp (entry->name, FAT_DIR_NAME_DOTDOT, 11)) |
798 |
hit = 1; |
hit = 1; |