Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 2b88074b in mainline for uspace/srv/vfs/vfs_ops.c


Ignore:
Timestamp:
2009-10-29T22:06:46Z (12 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master
Children:
2e983c7
Parents:
14ecd6c
Message:

vfs: file descriptors housekeeping changes

  • add support for allocating new file descriptors from the end of the fd range (O_DESC)
  • add support for assigning of an already opened file to a free file descriptor

vfs: VFS_OUT_CLOSE is called only when the file reference count is about to drop to zero
vfs: implement VFS_IN_DUP

libc: optimize current working directory housekeeping

  • using opendir() was an overkill
  • allocate current working directory file descriptor from the end of the fd range using O_DESC (so it doesn't mess with the well-known descriptors 0, 1 and 2)

libc: implement dup2() (via VFS_IN_DUP)

getvc: change stdin/stdout/stderr by a slightly more elegant way (using dup2())

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/vfs/vfs_ops.c

    r14ecd6c r2b88074b  
    543543         * structure.
    544544         */
    545         int fd = vfs_fd_alloc();
     545        int fd = vfs_fd_alloc((oflag & O_DESC) != 0);
    546546        if (fd < 0) {
    547547                vfs_node_put(node);
     
    620620         * structure.
    621621         */
    622         int fd = vfs_fd_alloc();
     622        int fd = vfs_fd_alloc((oflag & O_DESC) != 0);
    623623        if (fd < 0) {
    624624                vfs_node_put(node);
     
    679679}
    680680
     681static int vfs_close_internal(vfs_file_t *file)
     682{
     683        /*
     684         * Lock the open file structure so that no other thread can manipulate
     685         * the same open file at a time.
     686         */
     687        fibril_mutex_lock(&file->lock);
     688       
     689        if (file->refcnt <= 1) {
     690                /* Only close the file on the destination FS server
     691                   if there are no more file descriptors (except the
     692                   present one) pointing to this file. */
     693               
     694                int fs_phone = vfs_grab_phone(file->node->fs_handle);
     695               
     696                /* Make a VFS_OUT_CLOSE request at the destination FS server. */
     697                aid_t msg;
     698                ipc_call_t answer;
     699                msg = async_send_2(fs_phone, VFS_OUT_CLOSE, file->node->dev_handle,
     700                    file->node->index, &answer);
     701               
     702                /* Wait for reply from the FS server. */
     703                ipcarg_t rc;
     704                async_wait_for(msg, &rc);
     705               
     706                vfs_release_phone(fs_phone);
     707                fibril_mutex_unlock(&file->lock);
     708               
     709                return IPC_GET_ARG1(answer);
     710        }
     711       
     712        fibril_mutex_unlock(&file->lock);
     713        return EOK;
     714}
     715
    681716void vfs_close(ipc_callid_t rid, ipc_call_t *request)
    682717{
     
    690725        }
    691726       
    692         /*
    693          * Lock the open file structure so that no other thread can manipulate
    694          * the same open file at a time.
    695          */
    696         fibril_mutex_lock(&file->lock);
    697         int fs_phone = vfs_grab_phone(file->node->fs_handle);
    698        
    699         /* Make a VFS_OUT_CLOSE request at the destination FS server. */
    700         aid_t msg;
    701         ipc_call_t answer;
    702         msg = async_send_2(fs_phone, VFS_OUT_CLOSE, file->node->dev_handle,
    703             file->node->index, &answer);
    704 
    705         /* Wait for reply from the FS server. */
    706         ipcarg_t rc;
    707         async_wait_for(msg, &rc);
    708 
    709         vfs_release_phone(fs_phone);
    710         fibril_mutex_unlock(&file->lock);
    711        
    712         int retval = IPC_GET_ARG1(answer);
    713         if (retval != EOK)
    714                 ipc_answer_0(rid, retval);
    715        
    716         retval = vfs_fd_free(fd);
    717         ipc_answer_0(rid, retval);
     727        int ret = vfs_close_internal(file);
     728        if (ret != EOK)
     729                ipc_answer_0(rid, ret);
     730       
     731        ret = vfs_fd_free(fd);
     732        ipc_answer_0(rid, ret);
    718733}
    719734
     
    13101325}
    13111326
     1327void vfs_dup(ipc_callid_t rid, ipc_call_t *request)
     1328{
     1329        int oldfd = IPC_GET_ARG1(*request);
     1330        int newfd = IPC_GET_ARG2(*request);
     1331       
     1332        /* Lookup the file structure corresponding to oldfd. */
     1333        vfs_file_t *oldfile = vfs_file_get(oldfd);
     1334        if (!oldfile) {
     1335                ipc_answer_0(rid, EBADF);
     1336                return;
     1337        }
     1338       
     1339        /* If the file descriptors are the same, do nothing. */
     1340        if (oldfd == newfd) {
     1341                ipc_answer_1(rid, EOK, newfd);
     1342                return;
     1343        }
     1344       
     1345        /*
     1346         * Lock the open file structure so that no other thread can manipulate
     1347         * the same open file at a time.
     1348         */
     1349        fibril_mutex_lock(&oldfile->lock);
     1350       
     1351        /* Lookup an open file structure possibly corresponding to newfd. */
     1352        vfs_file_t *newfile = vfs_file_get(newfd);
     1353        if (newfile) {
     1354                /* Close the originally opened file. */
     1355                int ret = vfs_close_internal(newfile);
     1356                if (ret != EOK) {
     1357                        ipc_answer_0(rid, ret);
     1358                        return;
     1359                }
     1360               
     1361                ret = vfs_fd_free(newfd);
     1362                if (ret != EOK) {
     1363                        ipc_answer_0(rid, ret);
     1364                        return;
     1365                }
     1366        }
     1367       
     1368        /* Assign the old file to newfd. */
     1369        int ret = vfs_fd_assign(oldfile, newfd);
     1370        fibril_mutex_unlock(&oldfile->lock);
     1371       
     1372        if (ret != EOK)
     1373                ipc_answer_0(rid, ret);
     1374        else
     1375                ipc_answer_1(rid, EOK, newfd);
     1376}
     1377
    13121378/**
    13131379 * @}
Note: See TracChangeset for help on using the changeset viewer.