Changeset 36c2679 in mainline
- Timestamp:
- 2011-08-02T20:21:03Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f6641d2
- Parents:
- 8c18b7a
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/exfat/exfat_ops.c
r8c18b7a r36c2679 947 947 } 948 948 949 void exfat_read(ipc_callid_t rid, ipc_call_t *request) 950 { 951 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 952 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 953 aoff64_t pos = 954 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 955 fs_node_t *fn; 956 exfat_node_t *nodep; 957 exfat_bs_t *bs; 958 size_t bytes=0; 959 block_t *b; 960 int rc; 961 962 rc = exfat_node_get(&fn, devmap_handle, index); 963 if (rc != EOK) { 964 async_answer_0(rid, rc); 965 return; 966 } 967 if (!fn) { 968 async_answer_0(rid, ENOENT); 969 return; 970 } 971 nodep = EXFAT_NODE(fn); 972 973 ipc_callid_t callid; 974 size_t len; 975 if (!async_data_read_receive(&callid, &len)) { 976 exfat_node_put(fn); 977 async_answer_0(callid, EINVAL); 978 async_answer_0(rid, EINVAL); 979 return; 980 } 981 982 bs = block_bb_get(devmap_handle); 983 984 if (nodep->type == EXFAT_FILE) { 985 /* 986 * Our strategy for regular file reads is to read one block at 987 * most and make use of the possibility to return less data than 988 * requested. This keeps the code very simple. 989 */ 990 if (pos >= nodep->size) { 991 /* reading beyond the EOF */ 992 bytes = 0; 993 (void) async_data_read_finalize(callid, NULL, 0); 994 } else { 995 bytes = min(len, BPS(bs) - pos % BPS(bs)); 996 bytes = min(bytes, nodep->size - pos); 997 rc = exfat_block_get(&b, bs, nodep, pos / BPS(bs), 998 BLOCK_FLAGS_NONE); 999 if (rc != EOK) { 1000 exfat_node_put(fn); 1001 async_answer_0(callid, rc); 1002 async_answer_0(rid, rc); 1003 return; 1004 } 1005 (void) async_data_read_finalize(callid, 1006 b->data + pos % BPS(bs), bytes); 1007 rc = block_put(b); 1008 if (rc != EOK) { 1009 exfat_node_put(fn); 1010 async_answer_0(rid, rc); 1011 return; 1012 } 1013 } 1014 } else { 1015 if (nodep->type != EXFAT_DIRECTORY) { 1016 async_answer_0(callid, ENOTSUP); 1017 async_answer_0(rid, ENOTSUP); 1018 return; 1019 } 1020 1021 aoff64_t spos = pos; 1022 char name[EXFAT_FILENAME_LEN+1]; 1023 exfat_file_dentry_t df; 1024 exfat_stream_dentry_t ds; 1025 1026 assert(nodep->size % BPS(bs) == 0); 1027 assert(BPS(bs) % sizeof(exfat_dentry_t) == 0); 1028 1029 exfat_directory_t di; 1030 rc = exfat_directory_open(nodep, &di); 1031 if (rc != EOK) goto err; 1032 rc = exfat_directory_seek(&di, pos); 1033 if (rc != EOK) { 1034 (void) exfat_directory_close(&di); 1035 goto err; 1036 } 1037 1038 rc = exfat_directory_read_file(&di, name, EXFAT_FILENAME_LEN, &df, &ds); 1039 if (rc == EOK) goto hit; 1040 if (rc == ENOENT) goto miss; 1041 1042 err: 1043 (void) exfat_node_put(fn); 1044 async_answer_0(callid, rc); 1045 async_answer_0(rid, rc); 1046 return; 1047 1048 miss: 1049 rc = exfat_directory_close(&di); 1050 if (rc!=EOK) 1051 goto err; 1052 rc = exfat_node_put(fn); 1053 async_answer_0(callid, rc != EOK ? rc : ENOENT); 1054 async_answer_1(rid, rc != EOK ? rc : ENOENT, 0); 1055 return; 1056 1057 hit: 1058 pos = di.pos; 1059 rc = exfat_directory_close(&di); 1060 if (rc!=EOK) 1061 goto err; 1062 (void) async_data_read_finalize(callid, name, str_size(name) + 1); 1063 bytes = (pos - spos)+1; 1064 } 1065 1066 rc = exfat_node_put(fn); 1067 async_answer_1(rid, rc, (sysarg_t)bytes); 1068 } 949 1069 950 1070 /**
Note:
See TracChangeset
for help on using the changeset viewer.