Changed spinlock mechananisim
[tpg/acess2.git] / Kernel / vfs / mount.c
1 /* 
2  * Acess Micro - VFS Server version 1
3  */
4 #include <acess.h>
5 #include <vfs.h>
6 #include <vfs_int.h>
7 #include <fs_sysfs.h>
8
9 // === IMPORTS ===
10 extern int      giVFS_MountFileID;
11 extern char     *gsVFS_MountFile;
12
13 // === PROTOTYPES ===
14  int    VFS_Mount(char *Device, char *MountPoint, char *Filesystem, char *Options);
15 void    VFS_UpdateMountFile(void);
16
17 // === GLOBALS ===
18 tMutex  glVFS_MountList;
19 tVFS_Mount      *gVFS_Mounts;
20 tVFS_Mount      *gVFS_RootMount = NULL;
21
22 // === CODE ===
23 /**
24  * \brief Mount a device
25  * \param Device        Device string to mount
26  * \param MountPoint    Destination for the mount
27  * \param Filesystem    Filesystem to use for the mount
28  * \param Options               Options to be passed to the filesystem
29  * \return -1 on Invalid FS, -2 on No Mem, 0 on success
30  * 
31  * Mounts the filesystem on \a Device at \a MountPoint using the driver
32  * \a Filesystem. The options in the string \a Options is passed to the
33  * driver's mount.
34  */
35 int VFS_Mount(char *Device, char *MountPoint, char *Filesystem, char *Options)
36 {
37         tVFS_Mount      *mnt;
38         tVFS_Driver     *fs;
39          int    deviceLen = strlen(Device);
40          int    mountLen = strlen(MountPoint);
41          int    argLen = strlen(Options);
42         
43         // Get the filesystem
44         fs = VFS_GetFSByName(Filesystem);
45         if(!fs) {
46                 Log_Warning("VFS", "VFS_Mount - Unknown FS Type '%s'", Filesystem);
47                 return -1;
48         }
49         
50         // Create mount information
51         mnt = malloc( sizeof(tVFS_Mount)+deviceLen+1+mountLen+1+argLen+1 );
52         if(!mnt) {
53                 return -2;
54         }
55         
56         // HACK: Forces VFS_ParsePath to fall back on root  
57         if(mountLen == 1 && MountPoint[0] == '/')
58                 mnt->MountPointLen = 0;
59         else
60                 mnt->MountPointLen = mountLen;
61         
62         // Fill Structure
63         mnt->Filesystem = fs;
64         
65         mnt->Device = &mnt->StrData[0];
66         memcpy( mnt->Device, Device, deviceLen+1 );
67         
68         mnt->MountPoint = &mnt->StrData[deviceLen+1];
69         memcpy( mnt->MountPoint, MountPoint, mountLen+1 );
70         
71         mnt->Options = &mnt->StrData[deviceLen+1+mountLen+1];
72         memcpy( mnt->Options, Options, argLen+1 );
73         
74         // Initialise Volume
75         mnt->RootNode = fs->InitDevice(Device, NULL);   //&ArgString);
76         if(!mnt->RootNode) {
77                 free(mnt);
78                 return -2;
79         }
80         
81         // Set root
82         if(!gVFS_RootMount)     gVFS_RootMount = mnt;
83         
84         // Add to mount list
85         Mutex_Acquire( &glVFS_MountList );
86         {
87                 tVFS_Mount      *tmp;
88                 mnt->Next = NULL;
89                 if(gVFS_Mounts) {
90                         for( tmp = gVFS_Mounts; tmp->Next; tmp = tmp->Next );
91                         tmp->Next = mnt;
92                 }
93                 else {
94                         gVFS_Mounts = mnt;
95                 }
96         }
97         Mutex_Release( &glVFS_MountList );
98         
99         Log_Log("VFS", "Mounted '%s' to '%s' ('%s')", Device, MountPoint, Filesystem);
100         
101         VFS_UpdateMountFile();
102         
103         return 0;
104 }
105
106 /**
107  * \brief Updates the mount file buffer
108  * 
109  * Updates the ProcFS mounts file buffer to match the current mounts list.
110  */
111 void VFS_UpdateMountFile(void)
112 {
113          int    len = 0;
114         char    *buf;
115         tVFS_Mount      *mnt;
116         
117         // Format:
118         // <device>\t<location>\t<type>\t<options>\n
119         
120         for(mnt = gVFS_Mounts; mnt; mnt = mnt->Next)
121         {
122                 len += 4 + strlen(mnt->Device) + strlen(mnt->MountPoint)
123                         + strlen(mnt->Filesystem->Name) + strlen(mnt->Options);
124         }
125         
126         buf = malloc( len + 1 );
127         len = 0;
128         for(mnt = gVFS_Mounts; mnt; mnt = mnt->Next)
129         {
130                 strcpy( &buf[len], mnt->Device );
131                 len += strlen(mnt->Device);
132                 buf[len++] = '\t';
133                 
134                 strcpy( &buf[len], mnt->MountPoint );
135                 len += strlen(mnt->MountPoint);
136                 buf[len++] = '\t';
137                 
138                 strcpy( &buf[len], mnt->Filesystem->Name );
139                 len += strlen(mnt->Filesystem->Name);
140                 buf[len++] = '\t';
141                 
142                 strcpy( &buf[len], mnt->Options );
143                 len += strlen(mnt->Options);
144                 buf[len++] = '\n';
145         }
146         buf[len] = 0;
147         
148         SysFS_UpdateFile( giVFS_MountFileID, buf, len );
149         if( gsVFS_MountFile )   free( gsVFS_MountFile );
150         gsVFS_MountFile = buf;
151 }

UCC git Repository :: git.ucc.asn.au