Subversion Repositories HelenOS

Rev

Rev 4420 | Rev 4537 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4420 Rev 4439
Line 72... Line 72...
72
 * This rwlock prevents the race between a triplet-to-VFS-node resolution and a
72
 * This rwlock prevents the race between a triplet-to-VFS-node resolution and a
73
 * concurrent VFS operation which modifies the file system namespace.
73
 * concurrent VFS operation which modifies the file system namespace.
74
 */
74
 */
75
RWLOCK_INITIALIZE(namespace_rwlock);
75
RWLOCK_INITIALIZE(namespace_rwlock);
76
 
76
 
77
futex_t rootfs_futex = FUTEX_INITIALIZER;
-
 
78
vfs_pair_t rootfs = {
77
vfs_pair_t rootfs = {
79
    .fs_handle = 0,
78
    .fs_handle = 0,
80
    .dev_handle = 0
79
    .dev_handle = 0
81
};
80
};
82
 
81
 
Line 93... Line 92...
93
    ipcarg_t rc;
92
    ipcarg_t rc;
94
    int phone;
93
    int phone;
95
    aid_t msg;
94
    aid_t msg;
96
    ipc_call_t answer;
95
    ipc_call_t answer;
97
           
96
           
98
 
-
 
99
    /* Resolve the path to the mountpoint. */
97
    /* Resolve the path to the mountpoint. */
100
    futex_down(&rootfs_futex);
98
    rwlock_write_lock(&namespace_rwlock);
101
    if (rootfs.fs_handle) {
99
    if (rootfs.fs_handle) {
102
        /* We already have the root FS. */
100
        /* We already have the root FS. */
103
        rwlock_write_lock(&namespace_rwlock);
-
 
104
        if (str_cmp(mp, "/") == 0) {
101
        if (str_cmp(mp, "/") == 0) {
105
            /* Trying to mount root FS over root FS */
102
            /* Trying to mount root FS over root FS */
106
            rwlock_write_unlock(&namespace_rwlock);
-
 
107
            futex_up(&rootfs_futex);
-
 
108
            ipc_answer_0(rid, EBUSY);
103
            ipc_answer_0(rid, EBUSY);
-
 
104
            rwlock_write_unlock(&namespace_rwlock);
109
            return;
105
            return;
110
        }
106
        }
111
       
107
       
112
        rc = vfs_lookup_internal(mp, L_DIRECTORY, &mp_res, NULL);
108
        rc = vfs_lookup_internal(mp, L_DIRECTORY, &mp_res, NULL);
113
        if (rc != EOK) {
109
        if (rc != EOK) {
114
            /* The lookup failed for some reason. */
110
            /* The lookup failed for some reason. */
115
            rwlock_write_unlock(&namespace_rwlock);
-
 
116
            futex_up(&rootfs_futex);
-
 
117
            ipc_answer_0(rid, rc);
111
            ipc_answer_0(rid, rc);
-
 
112
            rwlock_write_unlock(&namespace_rwlock);
118
            return;
113
            return;
119
        }
114
        }
120
       
115
       
121
        mp_node = vfs_node_get(&mp_res);
116
        mp_node = vfs_node_get(&mp_res);
122
        if (!mp_node) {
117
        if (!mp_node) {
123
            rwlock_write_unlock(&namespace_rwlock);
-
 
124
            futex_up(&rootfs_futex);
-
 
125
            ipc_answer_0(rid, ENOMEM);
118
            ipc_answer_0(rid, ENOMEM);
-
 
119
            rwlock_write_unlock(&namespace_rwlock);
126
            return;
120
            return;
127
        }
121
        }
128
       
122
       
129
        /*
123
        /*
130
         * Now we hold a reference to mp_node.
124
         * Now we hold a reference to mp_node.
131
         * It will be dropped upon the corresponding VFS_UNMOUNT.
125
         * It will be dropped upon the corresponding VFS_UNMOUNT.
132
         * This prevents the mount point from being deleted.
126
         * This prevents the mount point from being deleted.
133
         */
127
         */
134
        rwlock_write_unlock(&namespace_rwlock);
-
 
135
    } else {
128
    } else {
136
        /* We still don't have the root file system mounted. */
129
        /* We still don't have the root file system mounted. */
137
        if (str_cmp(mp, "/") == 0) {
130
        if (str_cmp(mp, "/") == 0) {
138
            /*
131
            /*
139
             * For this simple, but important case,
132
             * For this simple, but important case,
Line 148... Line 141...
148
            rc = ipc_data_write_start(phone, (void *)opts,
141
            rc = ipc_data_write_start(phone, (void *)opts,
149
                str_size(opts));
142
                str_size(opts));
150
            if (rc != EOK) {
143
            if (rc != EOK) {
151
                async_wait_for(msg, NULL);
144
                async_wait_for(msg, NULL);
152
                vfs_release_phone(phone);
145
                vfs_release_phone(phone);
153
                futex_up(&rootfs_futex);
-
 
154
                ipc_answer_0(rid, rc);
146
                ipc_answer_0(rid, rc);
-
 
147
                rwlock_write_unlock(&namespace_rwlock);
155
                return;
148
                return;
156
            }
149
            }
157
            async_wait_for(msg, &rc);
150
            async_wait_for(msg, &rc);
158
            vfs_release_phone(phone);
151
            vfs_release_phone(phone);
159
           
152
           
160
            if (rc != EOK) {
153
            if (rc != EOK) {
161
                futex_up(&rootfs_futex);
-
 
162
                ipc_answer_0(rid, rc);
154
                ipc_answer_0(rid, rc);
-
 
155
                rwlock_write_unlock(&namespace_rwlock);
163
                return;
156
                return;
164
            }
157
            }
165
 
158
 
166
            rindex = (fs_index_t) IPC_GET_ARG1(answer);
159
            rindex = (fs_index_t) IPC_GET_ARG1(answer);
167
            rsize = (size_t) IPC_GET_ARG2(answer);
160
            rsize = (size_t) IPC_GET_ARG2(answer);
Line 174... Line 167...
174
            mr_res.lnkcnt = rlnkcnt;
167
            mr_res.lnkcnt = rlnkcnt;
175
            mr_res.type = VFS_NODE_DIRECTORY;
168
            mr_res.type = VFS_NODE_DIRECTORY;
176
           
169
           
177
            rootfs.fs_handle = fs_handle;
170
            rootfs.fs_handle = fs_handle;
178
            rootfs.dev_handle = dev_handle;
171
            rootfs.dev_handle = dev_handle;
179
            futex_up(&rootfs_futex);
-
 
180
           
172
           
181
            /* Add reference to the mounted root. */
173
            /* Add reference to the mounted root. */
182
            mr_node = vfs_node_get(&mr_res);
174
            mr_node = vfs_node_get(&mr_res);
183
            assert(mr_node);
175
            assert(mr_node);
184
           
176
           
185
            ipc_answer_0(rid, rc);
177
            ipc_answer_0(rid, rc);
-
 
178
            rwlock_write_unlock(&namespace_rwlock);
186
            return;
179
            return;
187
        } else {
180
        } else {
188
            /*
181
            /*
189
             * We can't resolve this without the root filesystem
182
             * We can't resolve this without the root filesystem
190
             * being mounted first.
183
             * being mounted first.
191
             */
184
             */
192
            futex_up(&rootfs_futex);
-
 
193
            ipc_answer_0(rid, ENOENT);
185
            ipc_answer_0(rid, ENOENT);
-
 
186
            rwlock_write_unlock(&namespace_rwlock);
194
            return;
187
            return;
195
        }
188
        }
196
    }
189
    }
197
    futex_up(&rootfs_futex);
-
 
198
   
190
   
199
    /*
191
    /*
200
     * At this point, we have all necessary pieces: file system and device
192
     * At this point, we have all necessary pieces: file system and device
201
     * handles, and we know the mount point VFS node.
193
     * handles, and we know the mount point VFS node.
202
     */
194
     */
Line 219... Line 211...
219
        vfs_release_phone(phone);
211
        vfs_release_phone(phone);
220
        /* Mount failed, drop reference to mp_node. */
212
        /* Mount failed, drop reference to mp_node. */
221
        if (mp_node)
213
        if (mp_node)
222
            vfs_node_put(mp_node);
214
            vfs_node_put(mp_node);
223
        ipc_answer_0(rid, rc);
215
        ipc_answer_0(rid, rc);
-
 
216
        rwlock_write_unlock(&namespace_rwlock);
224
        return;
217
        return;
225
    }
218
    }
226
   
219
   
227
    /* send the mount options */
220
    /* send the mount options */
228
    rc = ipc_data_write_start(phone, (void *)opts, str_size(opts));
221
    rc = ipc_data_write_start(phone, (void *)opts, str_size(opts));
Line 231... Line 224...
231
        vfs_release_phone(phone);
224
        vfs_release_phone(phone);
232
        /* Mount failed, drop reference to mp_node. */
225
        /* Mount failed, drop reference to mp_node. */
233
        if (mp_node)
226
        if (mp_node)
234
            vfs_node_put(mp_node);
227
            vfs_node_put(mp_node);
235
        ipc_answer_0(rid, rc);
228
        ipc_answer_0(rid, rc);
-
 
229
        rwlock_write_unlock(&namespace_rwlock);
236
        return;
230
        return;
237
    }
231
    }
238
    async_wait_for(msg, &rc);
232
    async_wait_for(msg, &rc);
239
    vfs_release_phone(phone);
233
    vfs_release_phone(phone);
240
   
234
   
241
    if (rc != EOK) {
235
    if (rc == EOK) {
-
 
236
        rindex = (fs_index_t) IPC_GET_ARG1(answer);
-
 
237
        rsize = (size_t) IPC_GET_ARG2(answer);
-
 
238
        rlnkcnt = (unsigned) IPC_GET_ARG3(answer);
-
 
239
   
-
 
240
        mr_res.triplet.fs_handle = fs_handle;
-
 
241
        mr_res.triplet.dev_handle = dev_handle;
-
 
242
        mr_res.triplet.index = rindex;
-
 
243
        mr_res.size = rsize;
-
 
244
        mr_res.lnkcnt = rlnkcnt;
-
 
245
        mr_res.type = VFS_NODE_DIRECTORY;
-
 
246
   
-
 
247
        /* Add reference to the mounted root. */
-
 
248
        mr_node = vfs_node_get(&mr_res);
-
 
249
        assert(mr_node);
-
 
250
    } else {
242
        /* Mount failed, drop reference to mp_node. */
251
        /* Mount failed, drop reference to mp_node. */
243
        if (mp_node)
252
        if (mp_node)
244
            vfs_node_put(mp_node);
253
            vfs_node_put(mp_node);
245
    }
254
    }
246
   
-
 
247
    rindex = (fs_index_t) IPC_GET_ARG1(answer);
-
 
248
    rsize = (size_t) IPC_GET_ARG2(answer);
-
 
249
    rlnkcnt = (unsigned) IPC_GET_ARG3(answer);
-
 
250
   
-
 
251
    mr_res.triplet.fs_handle = fs_handle;
-
 
252
    mr_res.triplet.dev_handle = dev_handle;
-
 
253
    mr_res.triplet.index = rindex;
-
 
254
    mr_res.size = rsize;
-
 
255
    mr_res.lnkcnt = rlnkcnt;
-
 
256
    mr_res.type = VFS_NODE_DIRECTORY;
-
 
257
   
-
 
258
    /* Add reference to the mounted root. */
-
 
259
    mr_node = vfs_node_get(&mr_res);
-
 
260
    assert(mr_node);
-
 
261
 
255
 
262
    ipc_answer_0(rid, rc);
256
    ipc_answer_0(rid, rc);
-
 
257
    rwlock_write_unlock(&namespace_rwlock);
263
}
258
}
264
 
259
 
265
/** Process pending mount requests */
260
/** Process pending mount requests */
266
void vfs_process_pending_mount()
261
void vfs_process_pending_mount(void)
267
{
262
{
268
    link_t *cur;
263
    link_t *cur;
269
   
264
   
270
loop:
265
loop:
271
    for (cur = pending_req.next; cur != &pending_req; cur = cur->next) {
266
    for (cur = pending_req.next; cur != &pending_req; cur = cur->next) {
Line 1028... Line 1023...
1028
        ipc_answer_0(rid, rc);
1023
        ipc_answer_0(rid, rc);
1029
        free(old);
1024
        free(old);
1030
        free(new);
1025
        free(new);
1031
        return;
1026
        return;
1032
    }
1027
    }
1033
    char *lastsl = str_rchr(parentc + 1, L'/');
1028
    char *lastsl = str_rchr(parentc + 1, '/');
1034
    if (lastsl)
1029
    if (lastsl)
1035
        *lastsl = '\0';
1030
        *lastsl = '\0';
1036
    else
1031
    else
1037
        parentc[1] = '\0';
1032
        parentc[1] = '\0';
1038
    /* Lookup parent of the new file name. */
1033
    /* Lookup parent of the new file name. */