[a9fa9b7] | 1 | /* |
---|
| 2 | * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org> |
---|
| 3 | * |
---|
[3b7c123] | 4 | * Modifications to support reference counting in the file system are |
---|
| 5 | * Copyright (c) 2012 embedded brains GmbH. |
---|
| 6 | * |
---|
[a9fa9b7] | 7 | * The license and distribution terms for this file may be |
---|
| 8 | * found in the file LICENSE in this distribution or at |
---|
| 9 | * http://www.rtems.com/license/LICENSE. |
---|
| 10 | */ |
---|
| 11 | /** |
---|
| 12 | * @file |
---|
| 13 | * |
---|
| 14 | * @ingroup rtems-rfs |
---|
| 15 | * |
---|
| 16 | * RTEMS File System Interface for RTEMS. |
---|
| 17 | */ |
---|
| 18 | |
---|
[355b0544] | 19 | #if HAVE_CONFIG_H |
---|
| 20 | #include "config.h" |
---|
| 21 | #endif |
---|
| 22 | |
---|
[6d537a3] | 23 | #include <inttypes.h> |
---|
[a9fa9b7] | 24 | #include <stdlib.h> |
---|
| 25 | |
---|
[6d537a3] | 26 | #if SIZEOF_MODE_T == 8 |
---|
| 27 | #define PRIomode_t PRIo64 |
---|
| 28 | #elif SIZEOF_MODE_T == 4 |
---|
| 29 | #define PRIomode_t PRIo32 |
---|
| 30 | #else |
---|
| 31 | #error "unsupport size of mode_t" |
---|
| 32 | #endif |
---|
| 33 | |
---|
[a9fa9b7] | 34 | #include <rtems/rfs/rtems-rfs-file.h> |
---|
| 35 | #include <rtems/rfs/rtems-rfs-dir.h> |
---|
| 36 | #include <rtems/rfs/rtems-rfs-link.h> |
---|
| 37 | #include "rtems-rfs-rtems.h" |
---|
| 38 | |
---|
[3b7c123] | 39 | static bool |
---|
| 40 | rtems_rfs_rtems_eval_perms (rtems_filesystem_eval_path_context_t *ctx, |
---|
| 41 | int eval_flags, |
---|
| 42 | rtems_rfs_inode_handle* inode) |
---|
[a9fa9b7] | 43 | { |
---|
[3b7c123] | 44 | return rtems_filesystem_eval_path_check_access( |
---|
| 45 | ctx, |
---|
| 46 | eval_flags, |
---|
| 47 | rtems_rfs_inode_get_mode (inode), |
---|
| 48 | rtems_rfs_inode_get_uid (inode), |
---|
| 49 | rtems_rfs_inode_get_gid (inode) |
---|
| 50 | ); |
---|
| 51 | } |
---|
[66b8047] | 52 | |
---|
[3b7c123] | 53 | static rtems_filesystem_node_types_t |
---|
| 54 | rtems_rfs_rtems_node_type_by_inode (rtems_rfs_inode_handle* inode) |
---|
| 55 | { |
---|
[a9fa9b7] | 56 | /* |
---|
[3b7c123] | 57 | * Do not return RTEMS_FILESYSTEM_HARD_LINK because this would result in an |
---|
| 58 | * eval link which does not make sense in the case of the RFS file |
---|
| 59 | * system. All directory entries are links to an inode. A link such as a HARD |
---|
| 60 | * link is actually the normal path to a regular file, directory, device |
---|
| 61 | * etc's inode. Links to inodes can be considered "the real" one, yet they |
---|
| 62 | * are all links. |
---|
[a9fa9b7] | 63 | */ |
---|
[3b7c123] | 64 | uint16_t mode = rtems_rfs_inode_get_mode (inode); |
---|
| 65 | if (RTEMS_RFS_S_ISDIR (mode)) |
---|
| 66 | return RTEMS_FILESYSTEM_DIRECTORY; |
---|
| 67 | else if (RTEMS_RFS_S_ISLNK (mode)) |
---|
| 68 | return RTEMS_FILESYSTEM_SYM_LINK; |
---|
| 69 | else if (RTEMS_RFS_S_ISBLK (mode) || RTEMS_RFS_S_ISCHR (mode)) |
---|
| 70 | return RTEMS_FILESYSTEM_DEVICE; |
---|
| 71 | else |
---|
| 72 | return RTEMS_FILESYSTEM_MEMORY_FILE; |
---|
| 73 | } |
---|
[a9fa9b7] | 74 | |
---|
[3b7c123] | 75 | static void |
---|
| 76 | rtems_rfs_rtems_lock_by_mt_entry (rtems_filesystem_mount_table_entry_t *mt_entry) |
---|
| 77 | { |
---|
| 78 | rtems_rfs_file_system* fs = mt_entry->fs_info; |
---|
[66b8047] | 79 | |
---|
[3b7c123] | 80 | rtems_rfs_rtems_lock (fs); |
---|
| 81 | } |
---|
[a9fa9b7] | 82 | |
---|
[3b7c123] | 83 | static void |
---|
| 84 | rtems_rfs_rtems_unlock_by_mt_entry (rtems_filesystem_mount_table_entry_t *mt_entry) |
---|
| 85 | { |
---|
| 86 | rtems_rfs_file_system* fs = mt_entry->fs_info; |
---|
[66b8047] | 87 | |
---|
[a9fa9b7] | 88 | rtems_rfs_rtems_unlock (fs); |
---|
| 89 | } |
---|
| 90 | |
---|
[3b7c123] | 91 | static bool |
---|
| 92 | rtems_rfs_rtems_is_directory( |
---|
| 93 | rtems_filesystem_eval_path_context_t *ctx, |
---|
| 94 | void *arg |
---|
| 95 | ) |
---|
[a9fa9b7] | 96 | { |
---|
[3b7c123] | 97 | rtems_rfs_inode_handle* inode = arg; |
---|
[a9fa9b7] | 98 | |
---|
[3b7c123] | 99 | return rtems_rfs_rtems_node_type_by_inode (inode) |
---|
| 100 | == RTEMS_FILESYSTEM_DIRECTORY; |
---|
| 101 | } |
---|
[66b8047] | 102 | |
---|
[3b7c123] | 103 | static void rtems_rfs_rtems_follow_link( |
---|
| 104 | rtems_filesystem_eval_path_context_t* ctx, |
---|
| 105 | rtems_rfs_file_system* fs, |
---|
| 106 | rtems_rfs_ino ino |
---|
| 107 | ) |
---|
| 108 | { |
---|
| 109 | size_t len = MAXPATHLEN; |
---|
| 110 | char *link = malloc(len + 1); |
---|
[66b8047] | 111 | |
---|
[3b7c123] | 112 | if (link != NULL) { |
---|
| 113 | int rc = rtems_rfs_symlink_read (fs, ino, link, len, &len); |
---|
[a9fa9b7] | 114 | |
---|
[3b7c123] | 115 | if (rc == 0) { |
---|
| 116 | rtems_filesystem_eval_path_recursive (ctx, link, len); |
---|
| 117 | } else { |
---|
| 118 | rtems_filesystem_eval_path_error (ctx, 0); |
---|
[a9fa9b7] | 119 | } |
---|
[66b8047] | 120 | |
---|
[3b7c123] | 121 | free(link); |
---|
| 122 | } else { |
---|
| 123 | rtems_filesystem_eval_path_error (ctx, ENOMEM); |
---|
| 124 | } |
---|
| 125 | } |
---|
[a9fa9b7] | 126 | |
---|
[3b7c123] | 127 | static rtems_filesystem_eval_path_generic_status |
---|
| 128 | rtems_rfs_rtems_eval_token( |
---|
| 129 | rtems_filesystem_eval_path_context_t *ctx, |
---|
| 130 | void *arg, |
---|
| 131 | const char *token, |
---|
| 132 | size_t tokenlen |
---|
| 133 | ) |
---|
| 134 | { |
---|
| 135 | rtems_filesystem_eval_path_generic_status status = |
---|
| 136 | RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE; |
---|
| 137 | rtems_rfs_inode_handle* inode = arg; |
---|
[2563410] | 138 | bool access_ok = rtems_rfs_rtems_eval_perms (ctx, RTEMS_FS_PERMS_EXEC, inode); |
---|
[3b7c123] | 139 | |
---|
| 140 | if (access_ok) { |
---|
| 141 | if (rtems_filesystem_is_current_directory (token, tokenlen)) { |
---|
| 142 | rtems_filesystem_eval_path_clear_token (ctx); |
---|
| 143 | } else { |
---|
| 144 | rtems_filesystem_location_info_t *currentloc = |
---|
| 145 | rtems_filesystem_eval_path_get_currentloc( ctx ); |
---|
| 146 | rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (currentloc); |
---|
| 147 | rtems_rfs_ino entry_ino; |
---|
| 148 | uint32_t entry_doff; |
---|
| 149 | int rc = rtems_rfs_dir_lookup_ino ( |
---|
| 150 | fs, |
---|
| 151 | inode, |
---|
| 152 | token, |
---|
| 153 | tokenlen, |
---|
| 154 | &entry_ino, |
---|
| 155 | &entry_doff |
---|
| 156 | ); |
---|
| 157 | |
---|
| 158 | if (rc == 0) { |
---|
| 159 | rc = rtems_rfs_inode_close (fs, inode); |
---|
| 160 | if (rc == 0) { |
---|
| 161 | rc = rtems_rfs_inode_open (fs, entry_ino, inode, true); |
---|
| 162 | } |
---|
| 163 | |
---|
| 164 | if (rc != 0) { |
---|
| 165 | /* |
---|
| 166 | * This prevents the rtems_rfs_inode_close() from doing something in |
---|
| 167 | * rtems_rfs_rtems_eval_path(). |
---|
| 168 | */ |
---|
| 169 | memset (inode, 0, sizeof(*inode)); |
---|
| 170 | } |
---|
| 171 | } else { |
---|
| 172 | status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_NO_ENTRY; |
---|
| 173 | rc = -1; |
---|
[a9fa9b7] | 174 | } |
---|
[66b8047] | 175 | |
---|
[3b7c123] | 176 | if (rc == 0) { |
---|
| 177 | bool is_sym_link = rtems_rfs_rtems_node_type_by_inode (inode) |
---|
| 178 | == RTEMS_FILESYSTEM_SYM_LINK; |
---|
| 179 | int eval_flags = rtems_filesystem_eval_path_get_flags (ctx); |
---|
[2563410] | 180 | bool follow_sym_link = (eval_flags & RTEMS_FS_FOLLOW_SYM_LINK) != 0; |
---|
[3b7c123] | 181 | bool terminal = !rtems_filesystem_eval_path_has_path (ctx); |
---|
| 182 | |
---|
| 183 | rtems_filesystem_eval_path_clear_token (ctx); |
---|
| 184 | |
---|
| 185 | if (is_sym_link && (follow_sym_link || !terminal)) { |
---|
| 186 | rtems_rfs_rtems_follow_link (ctx, fs, entry_ino); |
---|
| 187 | } else { |
---|
| 188 | rc = rtems_rfs_rtems_set_handlers (currentloc, inode) ? 0 : EIO; |
---|
| 189 | if (rc == 0) { |
---|
| 190 | rtems_rfs_rtems_set_pathloc_ino (currentloc, entry_ino); |
---|
| 191 | rtems_rfs_rtems_set_pathloc_doff (currentloc, entry_doff); |
---|
| 192 | |
---|
| 193 | if (!terminal) { |
---|
| 194 | status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE; |
---|
| 195 | } |
---|
| 196 | } else { |
---|
| 197 | rtems_filesystem_eval_path_error ( |
---|
| 198 | ctx, |
---|
| 199 | rtems_rfs_rtems_error ("eval_path: set handlers", rc) |
---|
| 200 | ); |
---|
| 201 | } |
---|
| 202 | } |
---|
[a9fa9b7] | 203 | } |
---|
[66b8047] | 204 | } |
---|
[a9fa9b7] | 205 | } |
---|
| 206 | |
---|
[3b7c123] | 207 | return status; |
---|
| 208 | } |
---|
[a9fa9b7] | 209 | |
---|
[3b7c123] | 210 | static const rtems_filesystem_eval_path_generic_config |
---|
| 211 | rtems_rfs_rtems_eval_config = { |
---|
| 212 | .is_directory = rtems_rfs_rtems_is_directory, |
---|
| 213 | .eval_token = rtems_rfs_rtems_eval_token |
---|
| 214 | }; |
---|
[66b8047] | 215 | |
---|
[3b7c123] | 216 | static void |
---|
| 217 | rtems_rfs_rtems_eval_path (rtems_filesystem_eval_path_context_t *ctx) |
---|
| 218 | { |
---|
| 219 | rtems_filesystem_location_info_t *currentloc = |
---|
| 220 | rtems_filesystem_eval_path_get_currentloc (ctx); |
---|
| 221 | rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (currentloc); |
---|
| 222 | rtems_rfs_ino ino = rtems_rfs_rtems_get_pathloc_ino (currentloc); |
---|
| 223 | rtems_rfs_inode_handle inode; |
---|
| 224 | int rc; |
---|
[a9fa9b7] | 225 | |
---|
[3b7c123] | 226 | rc = rtems_rfs_inode_open (fs, ino, &inode, true); |
---|
| 227 | if (rc == 0) { |
---|
| 228 | rtems_filesystem_eval_path_generic ( |
---|
| 229 | ctx, |
---|
| 230 | &inode, |
---|
| 231 | &rtems_rfs_rtems_eval_config |
---|
| 232 | ); |
---|
| 233 | rc = rtems_rfs_inode_close (fs, &inode); |
---|
| 234 | if (rc != 0) { |
---|
| 235 | rtems_filesystem_eval_path_error ( |
---|
| 236 | ctx, |
---|
| 237 | rtems_rfs_rtems_error ("eval_path: closing inode", rc) |
---|
| 238 | ); |
---|
| 239 | } |
---|
| 240 | } else { |
---|
| 241 | rtems_filesystem_eval_path_error ( |
---|
| 242 | ctx, |
---|
| 243 | rtems_rfs_rtems_error ("eval_path: opening inode", rc) |
---|
| 244 | ); |
---|
[a9fa9b7] | 245 | } |
---|
| 246 | } |
---|
| 247 | |
---|
| 248 | /** |
---|
| 249 | * The following rouine creates a new link node under parent with the name |
---|
[3b7c123] | 250 | * given in name. The link node is set to point to the node at targetloc. |
---|
[a9fa9b7] | 251 | */ |
---|
[d0fcd0b] | 252 | static int |
---|
[3b7c123] | 253 | rtems_rfs_rtems_link (const rtems_filesystem_location_info_t *parentloc, |
---|
| 254 | const rtems_filesystem_location_info_t *targetloc, |
---|
| 255 | const char *name, |
---|
| 256 | size_t namelen) |
---|
[a9fa9b7] | 257 | { |
---|
[3b7c123] | 258 | rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (targetloc); |
---|
| 259 | rtems_rfs_ino target = rtems_rfs_rtems_get_pathloc_ino (targetloc); |
---|
| 260 | rtems_rfs_ino parent = rtems_rfs_rtems_get_pathloc_ino (parentloc); |
---|
[a9fa9b7] | 261 | int rc; |
---|
| 262 | |
---|
| 263 | if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_LINK)) |
---|
[6d537a3] | 264 | printf ("rtems-rfs-rtems: link: in: parent:%" PRId32 " target:%" PRId32 "\n", |
---|
[a9fa9b7] | 265 | parent, target); |
---|
[66b8047] | 266 | |
---|
[3b7c123] | 267 | rc = rtems_rfs_link (fs, name, namelen, parent, target, false); |
---|
[a9fa9b7] | 268 | if (rc) |
---|
| 269 | { |
---|
| 270 | return rtems_rfs_rtems_error ("link: linking", rc); |
---|
| 271 | } |
---|
| 272 | |
---|
[66b8047] | 273 | |
---|
[a9fa9b7] | 274 | return 0; |
---|
| 275 | } |
---|
| 276 | |
---|
| 277 | /** |
---|
| 278 | * The following verifies that and returns the type of node that the loc refers |
---|
| 279 | * to. |
---|
| 280 | * |
---|
| 281 | * @param pathloc |
---|
| 282 | * @return rtems_filesystem_node_types_t |
---|
| 283 | */ |
---|
| 284 | |
---|
[d0fcd0b] | 285 | static rtems_filesystem_node_types_t |
---|
[3b7c123] | 286 | rtems_rfs_rtems_node_type (const rtems_filesystem_location_info_t* pathloc) |
---|
[a9fa9b7] | 287 | { |
---|
| 288 | rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc); |
---|
| 289 | rtems_rfs_ino ino = rtems_rfs_rtems_get_pathloc_ino (pathloc); |
---|
| 290 | rtems_filesystem_node_types_t type; |
---|
| 291 | rtems_rfs_inode_handle inode; |
---|
| 292 | int rc; |
---|
| 293 | |
---|
| 294 | rc = rtems_rfs_inode_open (fs, ino, &inode, true); |
---|
| 295 | if (rc > 0) |
---|
| 296 | { |
---|
| 297 | return rtems_rfs_rtems_error ("node_type: opening inode", rc); |
---|
| 298 | } |
---|
[66b8047] | 299 | |
---|
[3b7c123] | 300 | type = rtems_rfs_rtems_node_type_by_inode (&inode); |
---|
[a9fa9b7] | 301 | |
---|
| 302 | rc = rtems_rfs_inode_close (fs, &inode); |
---|
| 303 | if (rc > 0) |
---|
| 304 | { |
---|
| 305 | return rtems_rfs_rtems_error ("node_type: closing inode", rc); |
---|
| 306 | } |
---|
[66b8047] | 307 | |
---|
[a9fa9b7] | 308 | return type; |
---|
| 309 | } |
---|
| 310 | |
---|
| 311 | /** |
---|
| 312 | * This routine is the implementation of the chown() system call for the |
---|
| 313 | * RFS. |
---|
| 314 | * |
---|
| 315 | * @param pathloc |
---|
| 316 | * @param owner |
---|
| 317 | * @param group |
---|
| 318 | * return int |
---|
| 319 | */ |
---|
| 320 | |
---|
| 321 | static int |
---|
[3b7c123] | 322 | rtems_rfs_rtems_chown (const rtems_filesystem_location_info_t *pathloc, |
---|
| 323 | uid_t owner, |
---|
| 324 | gid_t group) |
---|
[a9fa9b7] | 325 | { |
---|
| 326 | rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc); |
---|
| 327 | rtems_rfs_ino ino = rtems_rfs_rtems_get_pathloc_ino (pathloc); |
---|
| 328 | rtems_rfs_inode_handle inode; |
---|
| 329 | #if defined (RTEMS_POSIX_API) |
---|
| 330 | uid_t uid; |
---|
| 331 | #endif |
---|
| 332 | int rc; |
---|
[66b8047] | 333 | |
---|
[a9fa9b7] | 334 | if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_CHOWN)) |
---|
[6d537a3] | 335 | printf ("rtems-rfs-rtems: chown: in: ino:%" PRId32 " uid:%d gid:%d\n", |
---|
[a9fa9b7] | 336 | ino, owner, group); |
---|
[66b8047] | 337 | |
---|
[a9fa9b7] | 338 | rc = rtems_rfs_inode_open (fs, ino, &inode, true); |
---|
| 339 | if (rc > 0) |
---|
| 340 | { |
---|
| 341 | return rtems_rfs_rtems_error ("chown: opening inode", rc); |
---|
| 342 | } |
---|
[66b8047] | 343 | |
---|
[a9fa9b7] | 344 | /* |
---|
| 345 | * Verify I am the owner of the node or the super user. |
---|
| 346 | */ |
---|
| 347 | |
---|
| 348 | #if defined (RTEMS_POSIX_API) |
---|
| 349 | uid = geteuid(); |
---|
| 350 | |
---|
| 351 | if ((uid != rtems_rfs_inode_get_uid (&inode)) && (uid != 0)) |
---|
| 352 | { |
---|
| 353 | rtems_rfs_inode_close (fs, &inode); |
---|
| 354 | return rtems_rfs_rtems_error ("chown: not able", EPERM); |
---|
| 355 | } |
---|
| 356 | #endif |
---|
| 357 | |
---|
| 358 | rtems_rfs_inode_set_uid_gid (&inode, owner, group); |
---|
| 359 | |
---|
| 360 | rc = rtems_rfs_inode_close (fs, &inode); |
---|
| 361 | if (rc) |
---|
| 362 | { |
---|
| 363 | return rtems_rfs_rtems_error ("chown: closing inode", rc); |
---|
| 364 | } |
---|
| 365 | |
---|
| 366 | return 0; |
---|
| 367 | } |
---|
| 368 | |
---|
| 369 | /** |
---|
| 370 | * This routine is the implementation of the utime() system call for the |
---|
| 371 | * RFS. |
---|
| 372 | * |
---|
| 373 | * @param pathloc |
---|
| 374 | * @param atime |
---|
| 375 | * @param mtime |
---|
| 376 | * return int |
---|
| 377 | */ |
---|
| 378 | |
---|
[d0fcd0b] | 379 | static int |
---|
[3b7c123] | 380 | rtems_rfs_rtems_utime(const rtems_filesystem_location_info_t* pathloc, |
---|
| 381 | time_t atime, |
---|
| 382 | time_t mtime) |
---|
[a9fa9b7] | 383 | { |
---|
| 384 | rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc); |
---|
| 385 | rtems_rfs_ino ino = rtems_rfs_rtems_get_pathloc_ino (pathloc); |
---|
| 386 | rtems_rfs_inode_handle inode; |
---|
| 387 | int rc; |
---|
| 388 | |
---|
| 389 | rc = rtems_rfs_inode_open (fs, ino, &inode, true); |
---|
| 390 | if (rc) |
---|
| 391 | { |
---|
| 392 | return rtems_rfs_rtems_error ("utime: read inode", rc); |
---|
| 393 | } |
---|
| 394 | |
---|
| 395 | rtems_rfs_inode_set_atime (&inode, atime); |
---|
| 396 | rtems_rfs_inode_set_mtime (&inode, mtime); |
---|
| 397 | |
---|
| 398 | rc = rtems_rfs_inode_close (fs, &inode); |
---|
| 399 | if (rc) |
---|
| 400 | { |
---|
| 401 | return rtems_rfs_rtems_error ("utime: closing inode", rc); |
---|
| 402 | } |
---|
[66b8047] | 403 | |
---|
[a9fa9b7] | 404 | return 0; |
---|
| 405 | } |
---|
| 406 | |
---|
| 407 | /** |
---|
[3b7c123] | 408 | * The following routine creates a new symbolic link node under parent with the |
---|
| 409 | * name given in node_name. |
---|
[a9fa9b7] | 410 | */ |
---|
| 411 | |
---|
[d0fcd0b] | 412 | static int |
---|
[3b7c123] | 413 | rtems_rfs_rtems_symlink (const rtems_filesystem_location_info_t* parent_loc, |
---|
| 414 | const char* node_name, |
---|
| 415 | size_t node_name_len, |
---|
| 416 | const char* target) |
---|
[a9fa9b7] | 417 | { |
---|
| 418 | rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (parent_loc); |
---|
| 419 | rtems_rfs_ino parent = rtems_rfs_rtems_get_pathloc_ino (parent_loc); |
---|
| 420 | int rc; |
---|
| 421 | |
---|
[3b7c123] | 422 | rc = rtems_rfs_symlink (fs, node_name, node_name_len, |
---|
| 423 | target, strlen (target), |
---|
| 424 | geteuid(), getegid(), parent); |
---|
[a9fa9b7] | 425 | if (rc) |
---|
| 426 | { |
---|
| 427 | return rtems_rfs_rtems_error ("symlink: linking", rc); |
---|
| 428 | } |
---|
[66b8047] | 429 | |
---|
[a9fa9b7] | 430 | return 0; |
---|
| 431 | } |
---|
| 432 | |
---|
| 433 | /** |
---|
| 434 | * The following rouine puts the symblic links destination name into buf. |
---|
| 435 | */ |
---|
| 436 | |
---|
[d0fcd0b] | 437 | static ssize_t |
---|
[3b7c123] | 438 | rtems_rfs_rtems_readlink (const rtems_filesystem_location_info_t* pathloc, |
---|
| 439 | char* buf, |
---|
| 440 | size_t bufsize) |
---|
[a9fa9b7] | 441 | { |
---|
| 442 | rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc); |
---|
| 443 | rtems_rfs_ino ino = rtems_rfs_rtems_get_pathloc_ino (pathloc); |
---|
| 444 | size_t length; |
---|
| 445 | int rc; |
---|
[66b8047] | 446 | |
---|
[a9fa9b7] | 447 | if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_READLINK)) |
---|
[6d537a3] | 448 | printf ("rtems-rfs-rtems: readlink: in: ino:%" PRId32 "\n", ino); |
---|
[66b8047] | 449 | |
---|
[a9fa9b7] | 450 | rc = rtems_rfs_symlink_read (fs, ino, buf, bufsize, &length); |
---|
| 451 | if (rc) |
---|
| 452 | { |
---|
| 453 | return rtems_rfs_rtems_error ("readlink: reading link", rc); |
---|
| 454 | } |
---|
| 455 | |
---|
[3b7c123] | 456 | return (ssize_t) length; |
---|
[a9fa9b7] | 457 | } |
---|
| 458 | |
---|
[3b7c123] | 459 | static int |
---|
| 460 | rtems_rfs_rtems_fchmod (const rtems_filesystem_location_info_t* pathloc, |
---|
| 461 | mode_t mode) |
---|
[a9fa9b7] | 462 | { |
---|
| 463 | rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc); |
---|
| 464 | rtems_rfs_ino ino = rtems_rfs_rtems_get_pathloc_ino (pathloc); |
---|
| 465 | rtems_rfs_inode_handle inode; |
---|
[59762469] | 466 | uint16_t imode; |
---|
| 467 | #if defined (RTEMS_POSIX_API) |
---|
| 468 | uid_t uid; |
---|
| 469 | #endif |
---|
[a9fa9b7] | 470 | int rc; |
---|
| 471 | |
---|
| 472 | if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FCHMOD)) |
---|
[6d537a3] | 473 | printf ("rtems-rfs-rtems: fchmod: in: ino:%" PRId32 " mode:%06" PRIomode_t "\n", |
---|
| 474 | ino, mode); |
---|
[66b8047] | 475 | |
---|
[a9fa9b7] | 476 | rc = rtems_rfs_inode_open (fs, ino, &inode, true); |
---|
| 477 | if (rc) |
---|
| 478 | { |
---|
| 479 | return rtems_rfs_rtems_error ("fchmod: opening inode", rc); |
---|
| 480 | } |
---|
| 481 | |
---|
[59762469] | 482 | imode = rtems_rfs_inode_get_mode (&inode); |
---|
[66b8047] | 483 | |
---|
[59762469] | 484 | /* |
---|
| 485 | * Verify I am the owner of the node or the super user. |
---|
| 486 | */ |
---|
| 487 | #if defined (RTEMS_POSIX_API) |
---|
| 488 | uid = geteuid(); |
---|
| 489 | |
---|
| 490 | if ((uid != rtems_rfs_inode_get_uid (&inode)) && (uid != 0)) |
---|
[a9fa9b7] | 491 | { |
---|
| 492 | rtems_rfs_inode_close (fs, &inode); |
---|
[59762469] | 493 | return rtems_rfs_rtems_error ("fchmod: checking uid", EPERM); |
---|
[a9fa9b7] | 494 | } |
---|
[59762469] | 495 | #endif |
---|
| 496 | |
---|
| 497 | imode &= ~(S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX); |
---|
| 498 | imode |= mode & (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX); |
---|
| 499 | |
---|
| 500 | rtems_rfs_inode_set_mode (&inode, imode); |
---|
[66b8047] | 501 | |
---|
[a9fa9b7] | 502 | rc = rtems_rfs_inode_close (fs, &inode); |
---|
| 503 | if (rc > 0) |
---|
| 504 | { |
---|
| 505 | return rtems_rfs_rtems_error ("fchmod: closing inode", rc); |
---|
| 506 | } |
---|
[66b8047] | 507 | |
---|
[a9fa9b7] | 508 | return 0; |
---|
| 509 | } |
---|
| 510 | |
---|
| 511 | int |
---|
[3b7c123] | 512 | rtems_rfs_rtems_fstat (const rtems_filesystem_location_info_t* pathloc, |
---|
| 513 | struct stat* buf) |
---|
[a9fa9b7] | 514 | { |
---|
[59762469] | 515 | rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc); |
---|
| 516 | rtems_rfs_ino ino = rtems_rfs_rtems_get_pathloc_ino (pathloc); |
---|
| 517 | rtems_rfs_inode_handle inode; |
---|
[d0fcd0b] | 518 | rtems_rfs_file_shared* shared; |
---|
| 519 | uint16_t mode; |
---|
[59762469] | 520 | int rc; |
---|
[a9fa9b7] | 521 | |
---|
| 522 | if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_STAT)) |
---|
[59762469] | 523 | printf ("rtems-rfs-rtems: stat: in: ino:%" PRId32 "\n", ino); |
---|
[a9fa9b7] | 524 | |
---|
[59762469] | 525 | rc = rtems_rfs_inode_open (fs, ino, &inode, true); |
---|
| 526 | if (rc) |
---|
| 527 | { |
---|
| 528 | return rtems_rfs_rtems_error ("stat: opening inode", rc); |
---|
| 529 | } |
---|
| 530 | |
---|
| 531 | mode = rtems_rfs_inode_get_mode (&inode); |
---|
[66b8047] | 532 | |
---|
[a9fa9b7] | 533 | if (RTEMS_RFS_S_ISCHR (mode) || RTEMS_RFS_S_ISBLK (mode)) |
---|
| 534 | { |
---|
[66b8047] | 535 | buf->st_rdev = |
---|
[59762469] | 536 | rtems_filesystem_make_dev_t (rtems_rfs_inode_get_block (&inode, 0), |
---|
| 537 | rtems_rfs_inode_get_block (&inode, 1)); |
---|
[a9fa9b7] | 538 | } |
---|
[66b8047] | 539 | |
---|
[a9fa9b7] | 540 | buf->st_dev = rtems_rfs_fs_device (fs); |
---|
[59762469] | 541 | buf->st_ino = rtems_rfs_inode_ino (&inode); |
---|
[a9fa9b7] | 542 | buf->st_mode = rtems_rfs_rtems_mode (mode); |
---|
[59762469] | 543 | buf->st_nlink = rtems_rfs_inode_get_links (&inode); |
---|
| 544 | buf->st_uid = rtems_rfs_inode_get_uid (&inode); |
---|
| 545 | buf->st_gid = rtems_rfs_inode_get_gid (&inode); |
---|
[a9fa9b7] | 546 | |
---|
| 547 | /* |
---|
| 548 | * Need to check is the ino is an open file. If so we take the values from |
---|
| 549 | * the open file rather than the inode. |
---|
| 550 | */ |
---|
[59762469] | 551 | shared = rtems_rfs_file_get_shared (fs, rtems_rfs_inode_ino (&inode)); |
---|
[a9fa9b7] | 552 | |
---|
| 553 | if (shared) |
---|
| 554 | { |
---|
| 555 | buf->st_atime = rtems_rfs_file_shared_get_atime (shared); |
---|
| 556 | buf->st_mtime = rtems_rfs_file_shared_get_mtime (shared); |
---|
| 557 | buf->st_ctime = rtems_rfs_file_shared_get_ctime (shared); |
---|
| 558 | buf->st_blocks = rtems_rfs_file_shared_get_block_count (shared); |
---|
| 559 | |
---|
| 560 | if (S_ISLNK (buf->st_mode)) |
---|
| 561 | buf->st_size = rtems_rfs_file_shared_get_block_offset (shared); |
---|
| 562 | else |
---|
| 563 | buf->st_size = rtems_rfs_file_shared_get_size (fs, shared); |
---|
| 564 | } |
---|
| 565 | else |
---|
| 566 | { |
---|
[59762469] | 567 | buf->st_atime = rtems_rfs_inode_get_atime (&inode); |
---|
| 568 | buf->st_mtime = rtems_rfs_inode_get_mtime (&inode); |
---|
| 569 | buf->st_ctime = rtems_rfs_inode_get_ctime (&inode); |
---|
| 570 | buf->st_blocks = rtems_rfs_inode_get_block_count (&inode); |
---|
[a9fa9b7] | 571 | |
---|
| 572 | if (S_ISLNK (buf->st_mode)) |
---|
[59762469] | 573 | buf->st_size = rtems_rfs_inode_get_block_offset (&inode); |
---|
[a9fa9b7] | 574 | else |
---|
[59762469] | 575 | buf->st_size = rtems_rfs_inode_get_size (fs, &inode); |
---|
[a9fa9b7] | 576 | } |
---|
[66b8047] | 577 | |
---|
[a9fa9b7] | 578 | buf->st_blksize = rtems_rfs_fs_block_size (fs); |
---|
[66b8047] | 579 | |
---|
[a9fa9b7] | 580 | rc = rtems_rfs_inode_close (fs, &inode); |
---|
| 581 | if (rc > 0) |
---|
| 582 | { |
---|
| 583 | return rtems_rfs_rtems_error ("stat: closing inode", rc); |
---|
| 584 | } |
---|
[66b8047] | 585 | |
---|
[a9fa9b7] | 586 | return 0; |
---|
| 587 | } |
---|
| 588 | |
---|
| 589 | /** |
---|
| 590 | * Routine to create a node in the RFS file system. |
---|
| 591 | */ |
---|
| 592 | |
---|
[d0fcd0b] | 593 | static int |
---|
[3b7c123] | 594 | rtems_rfs_rtems_mknod (const rtems_filesystem_location_info_t *parentloc, |
---|
| 595 | const char *name, |
---|
| 596 | size_t namelen, |
---|
| 597 | mode_t mode, |
---|
| 598 | dev_t dev) |
---|
[a9fa9b7] | 599 | { |
---|
[3b7c123] | 600 | rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (parentloc); |
---|
| 601 | rtems_rfs_ino parent = rtems_rfs_rtems_get_pathloc_ino (parentloc); |
---|
[a9fa9b7] | 602 | rtems_rfs_ino ino; |
---|
| 603 | rtems_rfs_inode_handle inode; |
---|
| 604 | uid_t uid; |
---|
| 605 | gid_t gid; |
---|
| 606 | int rc; |
---|
| 607 | |
---|
| 608 | #if defined(RTEMS_POSIX_API) |
---|
| 609 | uid = geteuid (); |
---|
| 610 | gid = getegid (); |
---|
| 611 | #else |
---|
| 612 | uid = 0; |
---|
| 613 | gid = 0; |
---|
| 614 | #endif |
---|
| 615 | |
---|
[3b7c123] | 616 | rc = rtems_rfs_inode_create (fs, parent, name, namelen, |
---|
[a9fa9b7] | 617 | rtems_rfs_rtems_imode (mode), |
---|
| 618 | 1, uid, gid, &ino); |
---|
| 619 | if (rc > 0) |
---|
| 620 | { |
---|
| 621 | return rtems_rfs_rtems_error ("mknod: inode create", rc); |
---|
| 622 | } |
---|
| 623 | |
---|
| 624 | rc = rtems_rfs_inode_open (fs, ino, &inode, true); |
---|
| 625 | if (rc > 0) |
---|
| 626 | { |
---|
| 627 | return rtems_rfs_rtems_error ("mknod: inode open", rc); |
---|
| 628 | } |
---|
[66b8047] | 629 | |
---|
[a9fa9b7] | 630 | if (S_ISDIR(mode) || S_ISREG(mode)) |
---|
| 631 | { |
---|
| 632 | } |
---|
| 633 | else if (S_ISCHR (mode) || S_ISBLK (mode)) |
---|
| 634 | { |
---|
| 635 | int major; |
---|
| 636 | int minor; |
---|
| 637 | rtems_filesystem_split_dev_t (dev, major, minor); |
---|
| 638 | rtems_rfs_inode_set_block (&inode, 0, major); |
---|
| 639 | rtems_rfs_inode_set_block (&inode, 1, minor); |
---|
| 640 | } |
---|
[66b8047] | 641 | else |
---|
[a9fa9b7] | 642 | { |
---|
| 643 | rtems_rfs_inode_close (fs, &inode); |
---|
| 644 | return rtems_rfs_rtems_error ("mknod: bad mode", EINVAL); |
---|
| 645 | } |
---|
| 646 | |
---|
| 647 | rc = rtems_rfs_inode_close (fs, &inode); |
---|
| 648 | if (rc > 0) |
---|
| 649 | { |
---|
| 650 | return rtems_rfs_rtems_error ("mknod: closing inode", rc); |
---|
| 651 | } |
---|
[66b8047] | 652 | |
---|
[a9fa9b7] | 653 | return 0; |
---|
| 654 | } |
---|
| 655 | |
---|
| 656 | /** |
---|
| 657 | * Routine to remove a node from the RFS file system. |
---|
| 658 | * |
---|
| 659 | * @param parent_pathloc |
---|
| 660 | * @param pathloc |
---|
[66b8047] | 661 | * @return int |
---|
[a9fa9b7] | 662 | */ |
---|
| 663 | int |
---|
[3b7c123] | 664 | rtems_rfs_rtems_rmnod (const rtems_filesystem_location_info_t* parent_pathloc, |
---|
| 665 | const rtems_filesystem_location_info_t* pathloc) |
---|
[a9fa9b7] | 666 | { |
---|
| 667 | rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc); |
---|
| 668 | rtems_rfs_ino parent = rtems_rfs_rtems_get_pathloc_ino (parent_pathloc); |
---|
| 669 | rtems_rfs_ino ino = rtems_rfs_rtems_get_pathloc_ino (pathloc); |
---|
| 670 | uint32_t doff = rtems_rfs_rtems_get_pathloc_doff (pathloc); |
---|
| 671 | int rc; |
---|
| 672 | |
---|
| 673 | if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_RMNOD)) |
---|
[6d537a3] | 674 | printf ("rtems-rfs: rmnod: parent:%" PRId32 " doff:%" PRIu32 ", ino:%" PRId32 "\n", |
---|
[a9fa9b7] | 675 | parent, doff, ino); |
---|
| 676 | |
---|
[3b7c123] | 677 | if (ino == RTEMS_RFS_ROOT_INO) |
---|
| 678 | return rtems_rfs_rtems_error ("rmnod: root inode", EBUSY); |
---|
[66b8047] | 679 | |
---|
[3b7c123] | 680 | rc = rtems_rfs_unlink (fs, parent, ino, doff, rtems_rfs_unlink_dir_if_empty); |
---|
[a9fa9b7] | 681 | if (rc) |
---|
| 682 | { |
---|
| 683 | return rtems_rfs_rtems_error ("rmnod: unlinking", rc); |
---|
| 684 | } |
---|
| 685 | |
---|
| 686 | return 0; |
---|
| 687 | } |
---|
| 688 | |
---|
| 689 | /** |
---|
| 690 | * The following routine does a sync on an inode node. Currently it flushes |
---|
| 691 | * everything related to this device. |
---|
| 692 | * |
---|
| 693 | * @param iop |
---|
[66b8047] | 694 | * @return int |
---|
[a9fa9b7] | 695 | */ |
---|
| 696 | int |
---|
| 697 | rtems_rfs_rtems_fdatasync (rtems_libio_t* iop) |
---|
| 698 | { |
---|
| 699 | int rc; |
---|
[66b8047] | 700 | |
---|
[a9fa9b7] | 701 | rc = rtems_rfs_buffer_sync (rtems_rfs_rtems_pathloc_dev (&iop->pathinfo)); |
---|
| 702 | if (rc) |
---|
| 703 | return rtems_rfs_rtems_error ("fdatasync: sync", rc); |
---|
| 704 | |
---|
| 705 | return 0; |
---|
| 706 | } |
---|
| 707 | |
---|
[8ec7abb] | 708 | /** |
---|
| 709 | * Rename the node. |
---|
| 710 | */ |
---|
[d0fcd0b] | 711 | static int |
---|
[3b7c123] | 712 | rtems_rfs_rtems_rename(const rtems_filesystem_location_info_t* old_parent_loc, |
---|
| 713 | const rtems_filesystem_location_info_t* old_loc, |
---|
| 714 | const rtems_filesystem_location_info_t* new_parent_loc, |
---|
| 715 | const char* new_name, |
---|
| 716 | size_t new_name_len) |
---|
[8ec7abb] | 717 | { |
---|
| 718 | rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (old_loc); |
---|
| 719 | rtems_rfs_ino old_parent; |
---|
| 720 | rtems_rfs_ino new_parent; |
---|
| 721 | rtems_rfs_ino ino; |
---|
| 722 | uint32_t doff; |
---|
| 723 | int rc; |
---|
[66b8047] | 724 | |
---|
[8ec7abb] | 725 | old_parent = rtems_rfs_rtems_get_pathloc_ino (old_parent_loc); |
---|
| 726 | new_parent = rtems_rfs_rtems_get_pathloc_ino (new_parent_loc); |
---|
| 727 | |
---|
| 728 | ino = rtems_rfs_rtems_get_pathloc_ino (old_loc); |
---|
| 729 | doff = rtems_rfs_rtems_get_pathloc_doff (old_loc); |
---|
| 730 | |
---|
| 731 | if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_RENAME)) |
---|
[3b7c123] | 732 | printf ("rtems-rfs: rename: ino:%" PRId32 " doff:%" PRIu32 ", new parent:%" PRId32 "\n", |
---|
| 733 | ino, doff, new_parent); |
---|
[8ec7abb] | 734 | |
---|
| 735 | /* |
---|
| 736 | * Link to the inode before unlinking so the inode is not erased when |
---|
| 737 | * unlinked. |
---|
| 738 | */ |
---|
[3b7c123] | 739 | rc = rtems_rfs_link (fs, new_name, new_name_len, new_parent, ino, true); |
---|
[8ec7abb] | 740 | if (rc) |
---|
| 741 | { |
---|
| 742 | return rtems_rfs_rtems_error ("rename: linking", rc); |
---|
| 743 | } |
---|
[66b8047] | 744 | |
---|
[8ec7abb] | 745 | /* |
---|
| 746 | * Unlink all inodes even directories with the dir option as false because a |
---|
| 747 | * directory may not be empty. |
---|
| 748 | */ |
---|
| 749 | rc = rtems_rfs_unlink (fs, old_parent, ino, doff, |
---|
| 750 | rtems_rfs_unlink_dir_allowed); |
---|
| 751 | if (rc) |
---|
| 752 | { |
---|
| 753 | return rtems_rfs_rtems_error ("rename: unlinking", rc); |
---|
| 754 | } |
---|
| 755 | |
---|
| 756 | return 0; |
---|
| 757 | } |
---|
| 758 | |
---|
[a9fa9b7] | 759 | /** |
---|
| 760 | * Return the file system stat data. |
---|
| 761 | * |
---|
| 762 | * @param pathloc |
---|
| 763 | * @param sb |
---|
| 764 | * @return int |
---|
| 765 | */ |
---|
[d0fcd0b] | 766 | static int |
---|
[3b7c123] | 767 | rtems_rfs_rtems_statvfs (const rtems_filesystem_location_info_t* pathloc, |
---|
| 768 | struct statvfs* sb) |
---|
[a9fa9b7] | 769 | { |
---|
| 770 | rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc); |
---|
[59762963] | 771 | size_t blocks; |
---|
| 772 | size_t inodes; |
---|
[a9fa9b7] | 773 | |
---|
[59762963] | 774 | rtems_rfs_group_usage (fs, &blocks, &inodes); |
---|
[66b8047] | 775 | |
---|
[59762963] | 776 | sb->f_bsize = rtems_rfs_fs_block_size (fs); |
---|
| 777 | sb->f_frsize = rtems_rfs_fs_media_block_size (fs); |
---|
| 778 | sb->f_blocks = rtems_rfs_fs_media_blocks (fs); |
---|
| 779 | sb->f_bfree = rtems_rfs_fs_blocks (fs) - blocks; |
---|
| 780 | sb->f_bavail = sb->f_bfree; |
---|
[5027104] | 781 | sb->f_files = rtems_rfs_fs_inodes (fs); |
---|
| 782 | sb->f_ffree = rtems_rfs_fs_inodes (fs) - inodes; |
---|
| 783 | sb->f_favail = sb->f_ffree; |
---|
[59762963] | 784 | sb->f_fsid = RTEMS_RFS_SB_MAGIC; |
---|
| 785 | sb->f_flag = rtems_rfs_fs_flags (fs); |
---|
[a9fa9b7] | 786 | sb->f_namemax = rtems_rfs_fs_max_name (fs); |
---|
[66b8047] | 787 | |
---|
[a9fa9b7] | 788 | return 0; |
---|
| 789 | } |
---|
| 790 | |
---|
| 791 | /** |
---|
| 792 | * Handler table for RFS link nodes |
---|
| 793 | */ |
---|
| 794 | const rtems_filesystem_file_handlers_r rtems_rfs_rtems_link_handlers = |
---|
| 795 | { |
---|
[dace9ed1] | 796 | .open_h = rtems_filesystem_default_open, |
---|
| 797 | .close_h = rtems_filesystem_default_close, |
---|
| 798 | .read_h = rtems_filesystem_default_read, |
---|
| 799 | .write_h = rtems_filesystem_default_write, |
---|
| 800 | .ioctl_h = rtems_filesystem_default_ioctl, |
---|
| 801 | .lseek_h = rtems_filesystem_default_lseek, |
---|
[d0fcd0b] | 802 | .fstat_h = rtems_rfs_rtems_fstat, |
---|
[dace9ed1] | 803 | .ftruncate_h = rtems_filesystem_default_ftruncate, |
---|
[4116fce6] | 804 | .fsync_h = rtems_filesystem_default_fsync_or_fdatasync, |
---|
| 805 | .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, |
---|
[3b7c123] | 806 | .fcntl_h = rtems_filesystem_default_fcntl |
---|
[a9fa9b7] | 807 | }; |
---|
| 808 | |
---|
| 809 | /** |
---|
| 810 | * Forward decl for the ops table. |
---|
| 811 | */ |
---|
| 812 | |
---|
[29e92b0] | 813 | int rtems_rfs_rtems_initialise (rtems_filesystem_mount_table_entry_t *mt_entry, |
---|
| 814 | const void *data); |
---|
[3b7c123] | 815 | void rtems_rfs_rtems_shutdown (rtems_filesystem_mount_table_entry_t *mt_entry); |
---|
[a9fa9b7] | 816 | |
---|
| 817 | /** |
---|
[8ec7abb] | 818 | * RFS file system operations table. |
---|
[a9fa9b7] | 819 | */ |
---|
| 820 | const rtems_filesystem_operations_table rtems_rfs_ops = |
---|
| 821 | { |
---|
[3b7c123] | 822 | .lock_h = rtems_rfs_rtems_lock_by_mt_entry, |
---|
| 823 | .unlock_h = rtems_rfs_rtems_unlock_by_mt_entry, |
---|
| 824 | .are_nodes_equal_h = rtems_filesystem_default_are_nodes_equal, |
---|
| 825 | .eval_path_h = rtems_rfs_rtems_eval_path, |
---|
[a9fa9b7] | 826 | .link_h = rtems_rfs_rtems_link, |
---|
| 827 | .node_type_h = rtems_rfs_rtems_node_type, |
---|
[3b7c123] | 828 | .fchmod_h = rtems_rfs_rtems_fchmod, |
---|
[a9fa9b7] | 829 | .mknod_h = rtems_rfs_rtems_mknod, |
---|
[3b7c123] | 830 | .rmnod_h = rtems_rfs_rtems_rmnod, |
---|
[a9fa9b7] | 831 | .chown_h = rtems_rfs_rtems_chown, |
---|
[3b7c123] | 832 | .clonenod_h = rtems_filesystem_default_clonenode, |
---|
[8f7b8f7b] | 833 | .freenod_h = rtems_filesystem_default_freenode, |
---|
[dace9ed1] | 834 | .mount_h = rtems_filesystem_default_mount, |
---|
[a9fa9b7] | 835 | .fsmount_me_h = rtems_rfs_rtems_initialise, |
---|
[dace9ed1] | 836 | .unmount_h = rtems_filesystem_default_unmount, |
---|
[a9fa9b7] | 837 | .fsunmount_me_h = rtems_rfs_rtems_shutdown, |
---|
| 838 | .utime_h = rtems_rfs_rtems_utime, |
---|
| 839 | .symlink_h = rtems_rfs_rtems_symlink, |
---|
| 840 | .readlink_h = rtems_rfs_rtems_readlink, |
---|
[8ec7abb] | 841 | .rename_h = rtems_rfs_rtems_rename, |
---|
[a9fa9b7] | 842 | .statvfs_h = rtems_rfs_rtems_statvfs |
---|
| 843 | }; |
---|
| 844 | |
---|
| 845 | /** |
---|
| 846 | * Open the file system. |
---|
| 847 | */ |
---|
| 848 | |
---|
| 849 | int |
---|
[29e92b0] | 850 | rtems_rfs_rtems_initialise (rtems_filesystem_mount_table_entry_t* mt_entry, |
---|
| 851 | const void* data) |
---|
[a9fa9b7] | 852 | { |
---|
| 853 | rtems_rfs_rtems_private* rtems; |
---|
| 854 | rtems_rfs_file_system* fs; |
---|
[97ae192a] | 855 | uint32_t flags = 0; |
---|
| 856 | uint32_t max_held_buffers = RTEMS_RFS_FS_MAX_HELD_BUFFERS; |
---|
| 857 | const char* options = data; |
---|
[a9fa9b7] | 858 | int rc; |
---|
| 859 | |
---|
[97ae192a] | 860 | /* |
---|
| 861 | * Parse the options the user specifiies. |
---|
| 862 | */ |
---|
| 863 | while (options) |
---|
| 864 | { |
---|
| 865 | printf ("options=%s\n", options); |
---|
| 866 | if (strncmp (options, "hold-bitmaps", |
---|
| 867 | sizeof ("hold-bitmaps") - 1) == 0) |
---|
| 868 | flags |= RTEMS_RFS_FS_BITMAPS_HOLD; |
---|
| 869 | else if (strncmp (options, "no-local-cache", |
---|
| 870 | sizeof ("no-local-cache") - 1) == 0) |
---|
| 871 | flags |= RTEMS_RFS_FS_NO_LOCAL_CACHE; |
---|
| 872 | else if (strncmp (options, "max-held-bufs", |
---|
| 873 | sizeof ("max-held-bufs") - 1) == 0) |
---|
| 874 | { |
---|
| 875 | max_held_buffers = strtoul (options + sizeof ("max-held-bufs"), 0, 0); |
---|
| 876 | } |
---|
| 877 | else |
---|
| 878 | return rtems_rfs_rtems_error ("initialise: invalid option", EINVAL); |
---|
| 879 | |
---|
| 880 | options = strchr (options, ','); |
---|
| 881 | if (options) |
---|
| 882 | { |
---|
| 883 | ++options; |
---|
| 884 | if (*options == '\0') |
---|
| 885 | options = NULL; |
---|
| 886 | } |
---|
| 887 | } |
---|
[66b8047] | 888 | |
---|
[a9fa9b7] | 889 | rtems = malloc (sizeof (rtems_rfs_rtems_private)); |
---|
| 890 | if (!rtems) |
---|
| 891 | return rtems_rfs_rtems_error ("initialise: local data", ENOMEM); |
---|
| 892 | |
---|
| 893 | memset (rtems, 0, sizeof (rtems_rfs_rtems_private)); |
---|
[66b8047] | 894 | |
---|
[a9fa9b7] | 895 | rc = rtems_rfs_mutex_create (&rtems->access); |
---|
| 896 | if (rc > 0) |
---|
| 897 | { |
---|
| 898 | free (rtems); |
---|
| 899 | return rtems_rfs_rtems_error ("initialise: cannot create mutex", rc); |
---|
| 900 | } |
---|
| 901 | |
---|
| 902 | rc = rtems_rfs_mutex_lock (&rtems->access); |
---|
| 903 | if (rc > 0) |
---|
| 904 | { |
---|
| 905 | rtems_rfs_mutex_destroy (&rtems->access); |
---|
| 906 | free (rtems); |
---|
| 907 | return rtems_rfs_rtems_error ("initialise: cannot lock access mutex", rc); |
---|
| 908 | } |
---|
[66b8047] | 909 | |
---|
[97ae192a] | 910 | rc = rtems_rfs_fs_open (mt_entry->dev, rtems, flags, max_held_buffers, &fs); |
---|
[a9fa9b7] | 911 | if (rc) |
---|
| 912 | { |
---|
| 913 | free (rtems); |
---|
| 914 | return rtems_rfs_rtems_error ("initialise: open", rc); |
---|
| 915 | } |
---|
[66b8047] | 916 | |
---|
[a9fa9b7] | 917 | mt_entry->fs_info = fs; |
---|
| 918 | |
---|
[3b7c123] | 919 | mt_entry->mt_fs_root->location.node_access = (void*) RTEMS_RFS_ROOT_INO; |
---|
| 920 | mt_entry->mt_fs_root->location.handlers = &rtems_rfs_rtems_dir_handlers; |
---|
| 921 | mt_entry->mt_fs_root->location.ops = &rtems_rfs_ops; |
---|
[a9fa9b7] | 922 | |
---|
| 923 | rtems_rfs_rtems_unlock (fs); |
---|
[66b8047] | 924 | |
---|
[a9fa9b7] | 925 | return 0; |
---|
| 926 | } |
---|
| 927 | |
---|
| 928 | /** |
---|
| 929 | * Shutdown the file system. |
---|
| 930 | */ |
---|
[3b7c123] | 931 | void |
---|
[a9fa9b7] | 932 | rtems_rfs_rtems_shutdown (rtems_filesystem_mount_table_entry_t* mt_entry) |
---|
| 933 | { |
---|
| 934 | rtems_rfs_file_system* fs = mt_entry->fs_info; |
---|
| 935 | rtems_rfs_rtems_private* rtems; |
---|
| 936 | |
---|
| 937 | rtems = rtems_rfs_fs_user (fs); |
---|
[66b8047] | 938 | |
---|
[3b7c123] | 939 | /* FIXME: Return value? */ |
---|
| 940 | rtems_rfs_fs_close(fs); |
---|
[66b8047] | 941 | |
---|
[a9fa9b7] | 942 | rtems_rfs_mutex_destroy (&rtems->access); |
---|
| 943 | free (rtems); |
---|
| 944 | } |
---|