Changeset 20c071d in mainline for uspace/srv/vfs/vfs_ops.c


Ignore:
Timestamp:
2013-07-25T12:28:48Z (12 years ago)
Author:
Ji?? Z?rev?cky <zarevucky.jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d18c404
Parents:
fadc76f
Message:

Implement server side of unlink2().

File:
1 edited

Legend:

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

    rfadc76f r20c071d  
    10991099}
    11001100
     1101void vfs_unlink2(ipc_callid_t rid, ipc_call_t *request)
     1102{
     1103        int rc;
     1104        char *path;
     1105        vfs_file_t *parent = NULL;
     1106        vfs_file_t *expect = NULL;
     1107        vfs_pair_t *parent_node = NULL;
     1108       
     1109        int parentfd = IPC_GET_ARG1(*request);
     1110        int expectfd = IPC_GET_ARG2(*request);
     1111        int wflag = IPC_GET_ARG3(*request);
     1112       
     1113        rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL);
     1114        if (rc != EOK) {
     1115                async_answer_0(rid, rc);
     1116                return;
     1117        }
     1118       
     1119        fibril_rwlock_write_lock(&namespace_rwlock);
     1120       
     1121        int lflag = (wflag&WALK_DIRECTORY) ? L_DIRECTORY: 0;
     1122
     1123        if (parentfd >= 0) {
     1124                parent = vfs_file_get(parentfd);
     1125                if (!parent) {
     1126                        rc = ENOENT;
     1127                        goto exit;
     1128                }
     1129                parent_node = (vfs_pair_t *)parent->node;
     1130        }
     1131       
     1132        if (expectfd >= 0) {
     1133                expect = vfs_file_get(expectfd);
     1134                if (!expect) {
     1135                        rc = ENOENT;
     1136                        goto exit;
     1137                }
     1138               
     1139                vfs_lookup_res_t lr;
     1140                rc = vfs_lookup_internal(path, lflag, &lr, parent_node);
     1141                if (rc != EOK) {
     1142                        goto exit;
     1143                }
     1144               
     1145                if (__builtin_memcmp(&lr.triplet, expect->node, sizeof(vfs_triplet_t)) != 0) {
     1146                        rc = ENOENT;
     1147                        goto exit;
     1148                }
     1149               
     1150                vfs_file_put(expect);
     1151                expect = NULL;
     1152        }
     1153       
     1154        vfs_lookup_res_t lr;
     1155        rc = vfs_lookup_internal(path, lflag | L_UNLINK, &lr, parent_node);
     1156        if (rc != EOK) {
     1157                goto exit;
     1158        }
     1159
     1160        /*
     1161         * The name has already been unlinked by vfs_lookup_internal().
     1162         * We have to get and put the VFS node to ensure that it is
     1163         * VFS_OUT_DESTROY'ed after the last reference to it is dropped.
     1164         */
     1165        vfs_node_t *node = vfs_node_get(&lr);
     1166        vfs_node_delref(node);
     1167        vfs_node_put(node);
     1168
     1169exit:
     1170        if (path) {
     1171                free(path);
     1172        }
     1173        if (parent) {
     1174                vfs_file_put(parent);
     1175        }
     1176        if (expect) {
     1177                vfs_file_put(expect);
     1178        }
     1179        fibril_rwlock_write_unlock(&namespace_rwlock);
     1180        async_answer_0(rid, rc);
     1181}
     1182
    11011183void vfs_rename(ipc_callid_t rid, ipc_call_t *request)
    11021184{
Note: See TracChangeset for help on using the changeset viewer.