1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296
|
%
% Copyright (c) 1997-1999 University of Utah and the Flux Group.
% All rights reserved.
%
% The University of Utah grants you the right to copy and reproduce this
% document or portions thereof for academic, research, evaluation, and
% personal use only, provided that (1) the title page appears prominently,
% and (2) these copyright and permission notices are retained in all copies.
% To arrange for alternate terms, contact the University of Utah at
% csl-dist@cs.utah.edu or +1-801-585-3271.
%
% -*- LaTeX -*-
\label{fs}
\section{Introduction}
The \oskit{} file system framework has parallel goals to the \oskit{}
device driver framework; the framework provides a file system
interface specification designed to allow existing filesystem
implementations to be borrowed from well-established operating systems
in source form and used mostly unchanged to provide file system
support in new operating systems. The framework is also designed to
allow file systems to be implemented in diverse ways and then composed
together.
The \oskit{} file system framework encompasses a collection of COM
interfaces used by the client operating system to invoke the file
system libraries, and a collection of interfaces used by the file
system libraries to request services from the client operating system.
The individual file system libraries supply additional interfaces to
the client operating system for initialization, and may supply
additional interfaces for supporting extended features unique to
particular file system implementations.
The \oskit{} File,
Directory and Open File COM interfaces inherit from several general COM
interfaces, such as Stream, Absolute IO and POSIX IO. The inheritance
relationships among these COM interfaces are shown in Figure~\ref{fig-fs-hier}.
Refer to Section~\ref{com} for more details on COM interfaces.
\psfigure{fs-hier}{
Interface hierarchy.
Solid lines indicate that the child
interface directly inherits the methods of the parent interface.
Dashed lines indicate that the child interface may optionally support
the parent interface; this may be determined by querying the object.}
\apiintf{oskit_principal}{Principal Interface}
The {\tt oskit_principal} COM interface defines an interface for
obtaining identity information about a principal (aka subject or
client). The filesystem libraries obtain an {\tt oskit_principal} object for
the current client by invoking {\tt oskit_get_call_context} on
{\tt oskit_principal_iid}.
The {\tt oskit_principal} COM interface inherits from {\tt IUnknown},
and has one additional method:
\begin{icsymlist}
\item[getid]
Obtain identity attributes of principal.
\end{icsymlist}
\api{getid}{Get the identity attributes of this principal}
\begin{apisyn}
\cinclude{oskit/principal.h}
\funcproto oskit_error_t
oskit_principal_getid(oskit_principal_t *p,
\outparam oskit_identity_t *out_id);
\end{apisyn}
\fstoos
\begin{apidesc}
This method returns the identity attributes of this principal.
{\tt out_id} is a pointer to an {\tt oskit_identity_t} structure defined
as follows:
\cstruct{oskit_identity}{
oskit_uid_t uid; /* effective user id */
oskit_gid_t gid; /* effective group id */
oskit_u32_t ngroups; /* number of groups */
oskit_u32_t *groups; /* supplemental groups */
};
\end{apidesc}
\begin{apiparm}
\item[p]
The principal whose identity is desired.
\item[out_id]
The identity attributes of this principal.
\end{apiparm}
\begin{apiret}
Returns 0 on success, or an error code specified in
{\tt <oskit/error.h>}, on error.
\end{apiret}
\apiintf{oskit_filesystem}{File System Interface}
The {\tt oskit_filesystem} COM interface defines an interface for
operating on a filesystem, which is a logical collection of files and
a tree-structured namespace with a single root. The filesystem
itself exists independent of any given namespace,
for there is no notion of mounts in this interface.
That functionality must be implemented at a higher level.
The {\tt oskit_filesystem} COM interface inherits from {\tt IUnknown},
and has the following additional methods:
\begin{icsymlist}
\item[statfs]
Get attributes of this filesystem
\item[sync]
Write this filesystem's data to permanent storage
\item[getroot]
Get this filesystem's root directory
\item[remount]
Update this filesystem's mount flags
\item[unmount]
Forcibly unmount this filesystem
\item[lookupi]
Lookup a file by inode number
\end{icsymlist}
\api{statfs}{Get attributes of this filesystem}
\begin{apisyn}
\cinclude{oskit/fs/filesystem.h}
\funcproto oskit_error_t
oskit_filesystem_statfs(oskit_filesystem_t *f,
\outparam oskit_statfs_t *out_stats);
\end{apisyn}
\ostofs
\begin{apidesc}
This method returns the attributes of this filesystem.
{\tt out_stats} is a pointer to an {\tt oskit_statfs_t} structure
defined as follows:
\cstruct{oskit_statfs}{
oskit_u32_t bsize; /* file system block size */
oskit_u32_t frsize; /* fundamental file system block size */
oskit_u32_t blocks; /* total blocks in fs in units of frsize */
oskit_u32_t bfree; /* free blocks in fs */
oskit_u32_t bavail; /* free blocks avail to non-superuser */
oskit_u32_t files; /* total file nodes in file system */
oskit_u32_t ffree; /* free file nodes in fs */
oskit_u32_t favail; /* free file nodes avail to non-superuser */
oskit_u32_t fsid; /* file system id */
oskit_u32_t flag; /* mount flags */
oskit_u32_t namemax; /* max bytes in a file name */
};
\end{apidesc}
\begin{apiparm}
\item[f]
The filesystem whose attributes are desired.
\item[out_stats]
The attributes of the specified filesystem.
\end{apiparm}
\begin{apiret}
Returns 0 on success, or an error code specified in
{\tt <oskit/error.h>}, on error.
\end{apiret}
\api{sync}{Synchronize in-core filesystem data with permanent storage}
\begin{apisyn}
\cinclude{oskit/fs/filesystem.h}
\funcproto oskit_error_t
oskit_filesystem_sync(oskit_filesystem_t *f,
oskit_bool_t wait);
\end{apisyn}
\ostofs
\begin{apidesc}
This method writes all of this filesystem's data back to permanent
storage. If {\tt wait} is {\tt TRUE}, then the call does not return
until all pending data has been completely written.
\end{apidesc}
\begin{apiparm}
\item[f]
The filesystem to sync.
\item[wait]
{\tt TRUE} if the call should wait for completion.
\end{apiparm}
\begin{apiret}
Returns 0 on success, or an error code specified in
{\tt <oskit/error.h>}, on error.
\end{apiret}
\api{getroot}{Return a reference to the root directory of this filesystem}
\begin{apisyn}
\cinclude{oskit/fs/filesystem.h}
\funcproto oskit_error_t
oskit_filesystem_getroot(oskit_filesystem_t *f,
\outparam oskit_dir_t **out_dir);
\end{apisyn}
\ostofs
\begin{apidesc}
This method returns a reference to the root directory of
this filesystem. {\tt out_dir} is a pointer to the
{\tt oskit_dir} COM interface for the root directory.
\end{apidesc}
\begin{apiparm}
\item[f]
The filesystem whose root directory is desired.
\item[out_dir]
The {\tt oskit_dir} COM interface for the root directory.
\end{apiparm}
\begin{apiret}
Returns 0 on success, or an error code specified in
{\tt <oskit/error.h>}, on error.
\end{apiret}
\api{remount}{Update the mount flags of this filesystem}
\begin{apisyn}
\cinclude{oskit/fs/filesystem.h}
\funcproto oskit_error_t
oskit_filesystem_remount(oskit_filesystem_t *f,
oskit_u32_t flags);
\end{apisyn}
\ostofs
\begin{apidesc}
This method changes the mount flags associated
with this filesystem. For example,
this method might be used to change a filesystem
from read-only to read-write, or vice versa.
\end{apidesc}
\begin{apiparm}
\item[f]
The filesystem whose flags are to be changed.
\item[flags]
The new mount flags value.
\end{apiparm}
\begin{apiret}
Returns 0 on success, or an error code specified in
{\tt <oskit/error.h>}, on error.
\end{apiret}
\api{unmount}{Forcibly unmount this filesystem}
\begin{apisyn}
\cinclude{oskit/fs/filesystem.h}
\funcproto oskit_error_t
oskit_filesystem_unmount(oskit_filesystem_t *f);
\end{apisyn}
\ostofs
\begin{apidesc}
This method forcibly unmounts this
filesystem. Ordinarily, a filesystem is
unmounted when the last reference to it is
released; in contrast, this method forces
an unmount regardless of external references
to the filesystem, and is consequently unsafe.
Subsequent attempts to use references to the
filesystem or to use references to files within
the filesystem may yield undefined results.
\end{apidesc}
\begin{apiparm}
\item[f]
The filesystem to be forcibly unmounted.
\end{apiparm}
\begin{apiret}
Returns 0 on success, or an error code specified in
{\tt <oskit/error.h>}, on error.
\end{apiret}
\api{lookupi}{Lookup a file by inode number}
\begin{apisyn}
\cinclude{oskit/fs/filesystem.h}
\funcproto oskit_error_t
oskit_filesystem_lookupi(oskit_filesystem_t *f, oskit_ino_t ino,
\outparam oskit_file_t **out_file);
\end{apisyn}
\ostofs
\begin{apidesc}
This method looks up a file given its inode number.
If the inode number is invalid,
the behavior is undefined.
\end{apidesc}
\begin{apiparm}
\item[f]
The filesystem to find the inode in.
\item[ino]
The inode number of the file to find.
\item[out_file]
Upon success, will point to a oskit_file_t for the file.
\end{apiparm}
\begin{apiret}
Returns 0 on success, or an error code specified in
{\tt <oskit/error.h>}, on error.
\end{apiret}
\apiintf{oskit_file}{File Interface}
\label{oskit-file-intf}
The {\tt oskit_file} COM interface defines an interface for operating
on a file. The interface does not imply any per-open state; per-open
methods are defined by the {\tt oskit_openfile} COM interface.
The {\tt oskit_file} COM interface inherits from the {\tt oskit_posixio}
COM interface, and has the following additional methods:
\begin{icsymlist}
\item[sync]
Write this file's data and metadata to permanent storage.
\item[datasync]
Write this file's data to permanent storage.
\item[access]
Check accessibility of this file.
\item[readlink]
Read the contents of this symbolic link.
\item[open]
Create an open instance of this file.
\item[getfs]
Get the filesystem in which this file resides.
\end{icsymlist}
Additionally, an {\tt oskit_file} object may export a {\tt
oskit_absio} COM interface; this may be determined by querying the
object.
\api{sync}{Write this file's data and metadata to permanent storage}
\begin{apisyn}
\cinclude{oskit/fs/file.h}
\funcproto oskit_error_t
oskit_file_sync(oskit_file_t *f, oskit_bool_t wait);
\end{apisyn}
\ostofs
\begin{apidesc}
This method synchronizes the in-core copy of this
file's data and metadata with the on-disk copy.
If {\tt wait} is {\tt TRUE}, then the call does not return
until all pending data has been completely written.
\end{apidesc}
\begin{apiparm}
\item[f]
The file to sync.
\item[wait]
{\tt TRUE} if the call should wait for completion.
\end{apiparm}
\begin{apiret}
Returns 0 on success, or an error code specified in
{\tt <oskit/error.h>}, on error.
\end{apiret}
\api{datasync}{Write this file's data to permanent storage}
\begin{apisyn}
\cinclude{oskit/fs/file.h}
\funcproto oskit_error_t
oskit_file_datasync(oskit_file_t *f, oskit_bool_t wait);
\end{apisyn}
\ostofs
\begin{apidesc}
This method synchronizes the in-core copy of this
file's data with the on-disk copy. The file
metadata need not be sychronized by this method.
If {\tt wait} is {\tt TRUE}, then the call does not return
until all pending data has been completely written.
\end{apidesc}
\begin{apiparm}
\item[f]
The file to sync.
\item[wait]
{\tt TRUE} if the call should wait for completion.
\end{apiparm}
\begin{apiret}
Returns 0 on success, or an error code specified in
{\tt <oskit/error.h>}, on error.
\end{apiret}
\api{access}{Check accessibility of this file}
\begin{apisyn}
\cinclude{oskit/fs/file.h}
\funcproto oskit_error_t
oskit_file_access(oskit_file_t *f, oskit_amode_t mask);
\end{apisyn}
\ostofs
\begin{apidesc}
This method checks whether the form of access
specified by {\tt mask} would be granted.
{\tt mask} may be any combination of {\tt OSKIT_R_OK} (read access),
{\tt OSKIT_W_OK} (write access), or {\tt OSKIT_X_OK} (execute access).
If the access would not be granted, then this method will return
the error that would be returned if the actual access were attempted.
\end{apidesc}
\begin{apiparm}
\item[f]
The file whose accessibility is to be checked.
\item[mask]
The access mask.
\end{apiparm}
\begin{apiret}
Returns 0 on success, or an error code specified in
{\tt <oskit/error.h>}, on error.
\end{apiret}
\api{readlink}{Read the contents of this symbolic link}
\begin{apisyn}
\cinclude{oskit/fs/dir.h}
\funcproto oskit_error_t
oskit_file_readlink(oskit_file_t *f, char *buf, oskit_u32_t len,
\outparam oskit_u32_t *out_actual);
\end{apisyn}
\ostofs
\begin{apidesc}
If this file is a symbolic link, then this method
reads the contents of the symbolic link into {\tt buf}.
No more than {\tt len} bytes will be read. {\tt out_actual}
will be set to the actual number of bytes read.
\end{apidesc}
\begin{apiparm}
\item[f]
The symbolic link file.
\item[buf]
The buffer into which the contents are to be copied.
\item[len]
The maximum number of bytes to read.
\item[out_actual]
The actual bytes read from the symlink.
\end{apiparm}
\begin{apiret}
Returns 0 on success, or an error code specified in
{\tt <oskit/error.h>}, on error.
If the file is not a symbolic link, then {\tt OSKIT_E_NOTIMPL}
is returned.
\end{apiret}
\api{open}{Create an open instance of this file}
\label{fs-file-open}
\begin{apisyn}
\cinclude{oskit/fs/file.h}
\\
\cinclude{oskit/fs/openfile.h}
\funcproto oskit_error_t
oskit_file_open(oskit_file_t *f,
oskit_oflags_t flags,
\outparam oskit_openfile_t **out_openfile);
\end{apisyn}
\ostofs
\begin{apidesc}
This method returns an {\tt oskit_openfile} COM interface
for an open instance of this file.
{\tt flags } specifies the file open flags, as
defined in {\tt <oskit/fs/file.h>}. If {\tt OSKIT_O_TRUNC}
is specified, then the file will be truncated
to zero length.
This method may only be used on regular
files and directories. Directories
may not be opened with {\tt OSKIT_O_WRONLY},
{\tt OSKIT_O_RDWR} or {\tt OSKIT_O_TRUNC}.
This method may return success but set
{\tt *out_openfile} to {\tt NULL}, indicating that
the requested operation is allowed but the
filesystem does not support per-open state;
the client operating system must provide this
functionality.
\end{apidesc}
\begin{apiparm}
\item[f]
The file to open.
\item[flags]
The open flags.
\item[out_openfile]
The {\tt oskit_openfile} COM interface.
\end{apiparm}
\begin{apiret}
Returns 0 on success, or an error code specified in
{\tt <oskit/error.h>}, on error.
\end{apiret}
\api{getfs}{Get the filesystem in which this file resides}
\begin{apisyn}
\cinclude{oskit/fs/file.h}
\funcproto oskit_error_t
oskit_file_getfs(oskit_file_t *f,
\outparam oskit_filesystem_t **out_fs);
\end{apisyn}
\ostofs
\begin{apidesc}
Returns the {\tt oskit_filesystem} COM interface for
the filesystem in which this file resides.
\end{apidesc}
\begin{apiparm}
\item[f]
The file whose filesystem is desired.
\item[out_fs]
The filesystem in which the file resides.
\end{apiparm}
\begin{apiret}
Returns 0 on success, or an error code specified in
{\tt <oskit/error.h>}, on error.
\end{apiret}
\apiintf{oskit_dir}{Directory Interface}
The {\tt oskit_dir} COM interface defines an interface for operating
on a directory. The interface does not imply any per-open state; per-open
methods are defined by the {\tt oskit_openfile} COM interface.
The {\tt oskit_dir} COM interface inherits from the {\tt oskit_file} COM
interface, and has the following additional methods:
\begin{csymlist}
\item[lookup]
Lookup a file in this directory.
\item[create]
Create a regular file in this directory.
\item[link]
Link a file into this directory.
\item[unlink]
Unlink a file from this directory.
\item[rename]
Rename a file from this directory.
\item[mkdir]
Create a directory in this directory.
\item[rmdir]
Remove a directory from this directory.
\item[getdirentries]
Read entries from this directory.
\item[mknod]
Create a special file in this directory.
\item[symlink]
Create a symlink in this directory.
\item[reparent]
Create a virtual directory from this directory.
\end{csymlist}
Additionally, an {\tt oskit_dir} object may export a {\tt
oskit_absio} COM interface; this may be determined by querying the
object.
All name parameters to directory methods must be a single
component, ie an entry in one of the specified directories. With the
exception of {\tt rename}, name parameters always refer to entries in
the target directory itself.
\api{lookup}{Look up a file in this directory}
\begin{apisyn}
\cinclude{oskit/fs/dir.h}
\funcproto oskit_error_t
oskit_dir_lookup(oskit_dir_t *d, const~char *name,
\outparam oskit_file_t **out_file);
\end{apisyn}
\ostofs
\begin{apidesc}
This method returns the {\tt oskit_file} COM interface
for the file named by {\tt name} in this directory.
The {\tt name} may only be a single component;
multi-component lookups are not supported.
If the file is a symbolic link, then {\tt out_file}
will reference the symbolic link itself.
\end{apidesc}
\begin{apiparm}
\item[d]
The directory to search.
\item[name]
The name of the file.
\item[out_file]
The {\tt oskit_file} COM interface for the file.
\end{apiparm}
\begin{apiret}
Returns 0 on success, or an error code specified in
{\tt <oskit/error.h>}, on error.
\end{apiret}
\api{create}{Create a regular file in this directory}
\begin{apisyn}
\cinclude{oskit/fs/dir.h}
\funcproto oskit_error_t
oskit_dir_create(oskit_dir_t *d, const~char *name,
oskit_bool_t excl, oskit_mode_t mode,
\outparam oskit_file_t **out_file);
\end{apisyn}
\ostofs
\begin{apidesc}
This method is the same as {\tt oskit_dir_lookup}, except
that if the file does not exist, then a regular file
will be created with the specified {\tt name} and
{\tt mode}.
If a file with {\tt name} already exists, and
{\tt excl} is {\tt TRUE}, then {\tt OSKIT_EEXIST} will be
returned.
The {\tt name} may only be a single component;
multi-component lookups are not supported.
\end{apidesc}
\begin{apiparm}
\item[d]
The directory to search.
\item[name]
The name of the file.
\item[excl]
{\tt TRUE} if an error should be returned if the file exists
\item[mode]
The file mode to use if creating a new file.
\item[out_file]
The {\tt oskit_file} COM interface for the file.
\end{apiparm}
\begin{apiret}
Returns 0 on success, or an error code specified in
{\tt <oskit/error.h>}, on error.
\end{apiret}
\api{link}{Link a file into this directory}
\begin{apisyn}
\cinclude{oskit/fs/dir.h}
\funcproto oskit_error_t
oskit_dir_link(oskit_dir_t *d, const~char *name,
oskit_file_t *file);
\end{apisyn}
\ostofs
\begin{apidesc}
This method adds an entry for {\tt file} into this directory,
using {\tt name} for the new directory entry.
Typically, this is only supported if {\tt file}
resides in the same filesystem as {\tt d}.
{\tt file} may not be a symbolic link.
The {\tt name} may only be a single component;
multi-component lookups are not supported.
\end{apidesc}
\begin{apiparm}
\item[d]
The directory to search.
\item[name]
The name for the new link.
\item[file]
The file to be linked.
\end{apiparm}
\begin{apiret}
Returns 0 on success, or an error code specified in
{\tt <oskit/error.h>}, on error.
\end{apiret}
\api{unlink}{Unlink a file from this directory}
\begin{apisyn}
\cinclude{oskit/fs/dir.h}
\funcproto oskit_error_t
oskit_dir_unlink(oskit_dir_t *d, const~char *name);
\end{apisyn}
\ostofs
\begin{apidesc}
This method removes the directory entry for {\tt name}
from {\tt d}.
The {\tt name} may only be a single component;
multi-component lookups are not supported.
\end{apidesc}
\begin{apiparm}
\item[d]
The directory to search.
\item[name]
The name of the file to be unlinked.
\end{apiparm}
\begin{apiret}
Returns 0 on success, or an error code specified in
{\tt <oskit/error.h>}, on error.
\end{apiret}
\api{rename}{Rename a file from this directory}
\begin{apisyn}
\cinclude{oskit/fs/dir.h}
\funcproto oskit_error_t
oskit_dir_rename(oskit_dir_t *old_dir, const~char *old_name,
oskit_dir_t *new_dir, const~char *new_name);
\end{apisyn}
\ostofs
\begin{apidesc}
This method atomically links the file named by {\tt old_name} in
{\tt old_dir} into {\tt new_dir}, using {\tt new_name} for the
new directory entry, and unlinks {\tt old_name} from {\tt old_dir}.
If a file named {\tt new_name} already exists in {\tt new_dir},
then it is first removed. In this case, the source and target files
must either both be directories or both be non-directories,
and if the target file is a directory, it must be empty.
Typically, this is only supported if {\tt new_dir}
resides in the same filesystem as {\tt old_dir}.
The {\tt old_name} and {\tt new_name} may each only be
a single component; multi-component lookups are not supported.
\end{apidesc}
\begin{apiparm}
\item[old_dir]
This directory.
\item[old_name]
The name of the file to be renamed.
\item[new_dir]
The target directory.
\item[new_name]
The name for the new directory entry.
\end{apiparm}
\begin{apiret}
Returns 0 on success, or an error code specified in
{\tt <oskit/error.h>}, on error.
\end{apiret}
\api{mkdir}{Create a subdirectory in this directory}
\begin{apisyn}
\cinclude{oskit/fs/dir.h}
\funcproto oskit_error_t
oskit_dir_mkdir(oskit_dir_t *d, const~char *name,
oskit_mode_t mode);
\end{apisyn}
\ostofs
\begin{apidesc}
This method creates a new subdirectory in this directory,
with the specified {\tt name} and {\tt mode}.
The {\tt name} may only be a single component;
multi-component lookups are not supported.
\end{apidesc}
\begin{apiparm}
\item[dir]
The directory in which to create the subdirectory.
\item[name]
The name of the new subdirectory.
\item[mode]
The mode for the new subdirectory.
\end{apiparm}
\begin{apiret}
Returns 0 on success, or an error code specified in
{\tt <oskit/error.h>}, on error.
\end{apiret}
\api{rmdir}{Remove a subdirectory from this directory}
\begin{apisyn}
\cinclude{oskit/fs/dir.h}
\funcproto oskit_error_t
oskit_dir_rmdir(oskit_dir_t *d, const~char *name);
\end{apisyn}
\ostofs
\begin{apidesc}
This method removes the subdirectory named {\tt name}
from this directory. Typically, this is only
supported if the subdirectory is empty.
The {\tt name} may only be a single component;
multi-component lookups are not supported.
\end{apidesc}
\begin{apiparm}
\item[dir]
The directory in which the subdirectory resides.
\item[name]
The name of the subdirectory.
\end{apiparm}
\begin{apiret}
Returns 0 on success, or an error code specified in
{\tt <oskit/error.h>}, on error.
\end{apiret}
\api{getdirentries}{Read one or more entries from this directory}
\begin{apisyn}
\cinclude{oskit/fs/dir.h}
\cinclude{oskit/fs/dirents.h}
\funcproto oskit_error_t
oskit_dir_getdirentries(oskit_dir_t *d,
oskit_u32_t *inout_ofs,
oskit_u32_t nentries,
\outparam oskit_dirents_t **out_dirents);
\end{apisyn}
\ostofs
\begin{apidesc}
This method reads one or more entries from this
directory. On entry, {\tt inout_ofs} contains the
offset of the first entry to be read. Before
returning, this method updates the value at
{\tt inout_ofs} to contain the offset of the
next entry after the last entry returned in
{\tt out_dirents}. The returned value of
{\tt inout_ofs} is opaque; it should only be used
in subsequent calls to this method.
This method will return at least {\tt nentries}
entries if there are at least that many entries
remaining in the directory; however, this method
may return more entries.
The return value {\tt out_dirents} will contain a pointer to
an {\tt oskit_dirents_t} COM object, which holds the individual
directory entries. The number of actual entries returned can be
determined with the {\tt oskit_dirents_getcount} method. Each
successive directory entry is accessed using the
{\tt oskit_dirents_getnext} method. Once all the entries have
been read, the dirents COM object should be released with the
{\tt oskit_dirents_release} method.
The data structure to retrieve the individual entries is:
\cstruct{oskit_dirent}{
oskit_size_t namelen; /* name length */
oskit_ino_t ino; /* entry inode */
char name[0]; /* entry name */
};
The {\tt namelen} field should be initialized to the amount of
storage available for the name. Upon return from the getnext
method, {\tt namelen} will be set to the actual length of the
name. The pointer that is passed should obviously be large
enough to hold the size of the structure above, plus the
additional size of the character array.
\end{apidesc}
\begin{apiparm}
\item[d]
The directory to read.
\item[inout_ofs]
On entry, the offset of the first entry to read.
On exit, the offset of the next entry to read.
\item[nentries]
The minimum desired number of entries.
\item[out_dirents]
The directory entries oskit_dirents_t COM object.
\end{apiparm}
\begin{apiret}
Returns 0 on success, or an error code specified in
{\tt <oskit/error.h>}, on error.
\end{apiret}
\api{mknod}{Create a special file node in this directory}
\begin{apisyn}
\cinclude{oskit/fs/dir.h}
\funcproto oskit_error_t
oskit_dir_mknod(oskit_dir_t *d, const~char *name,
oskit_mode_t mode, oskit_dev_t dev);
\end{apisyn}
\ostofs
\begin{apidesc}
This method creates a device special file in this directory,
with the specified {\tt name} and file {\tt mode},
and with the specified device number {\tt dev}. The
device number is opaque to the filesystem library.
The {\tt name} may only be a single component;
multi-component lookups are not supported.
\end{apidesc}
\begin{apiparm}
\item[d]
The directory in which to create the node
\item[name]
The name of the new node.
\item[mode]
The mode for the new node.
\item[dev]
The device number for the new node.
\end{apiparm}
\begin{apiret}
Returns 0 on success, or an error code specified in
{\tt <oskit/error.h>}, on error.
\end{apiret}
\api{symlink}{Create a symbolic link in this directory}
\begin{apisyn}
\cinclude{oskit/fs/dir.h}
\funcproto oskit_error_t
oskit_dir_symlink(oskit_dir_t *d, const~char *link_name,
char *dest_name);
\end{apisyn}
\ostofs
\begin{apidesc}
This method creates a symbolic link in this directory,
named {\tt link_name}, with contents {\tt dest_name}.
The {\tt link_name} may only be a single component;
multi-component lookups are not supported.
\end{apidesc}
\begin{apiparm}
\item[d]
The directory in which to create the symlink.
\item[link_name]
The name of the new symlink.
\item[dest_name]
The contents of the new symlink.
\end{apiparm}
\begin{apiret}
Returns 0 on success, or an error code specified in
{\tt <oskit/error.h>}, on error.
\end{apiret}
\api{reparent}{Create a virtual directory from this directory}
\begin{apisyn}
\cinclude{oskit/fs/dir.h}
\funcproto oskit_error_t
oskit_dir_reparent(oskit_dir_t *d, oskit_dir_t *parent,
\outparam oskit_dir_t **out_dir);
\end{apisyn}
\ostofs
\begin{apidesc}
This method creates a virtual directory {\tt out_dir}
which refers to the same underlying directory as {\tt d},
but whose logical parent directory is {\tt parent}.
If {\tt parent} is {\tt NULL}, then the logical parent
directory of {\tt out_dir} will be itself.
Lookups of the parent directory entry ('..') in the virtual
directory will return a reference to the logical parent
directory.
This method may be used to provide equivalent
functionality to the Unix {\tt chroot} operation.
\end{apidesc}
\begin{apiparm}
\item[d]
The directory
\item[parent]
The logical parent directory
\item[out_dir]
The {\tt oskit_dir} COM interface for the virtual directory
\end{apiparm}
\begin{apiret}
Returns 0 on success, or an error code specified in
{\tt <oskit/error.h>}, on error.
\end{apiret}
\apiintf{oskit_openfile}{Open File Interface}
The {\tt oskit_openfile} COM interface defines an interface for
operating on an open instance of a file.
The {\tt oskit_openfile} COM interface inherits from the {\tt
oskit_stream} COM interface, and has the following additional method:
\begin{icsymlist}
\item[getfile]
Get the underlying file object to which this open file refers.
\end{icsymlist}
Additionally, an {\tt oskit_openfile} object may export a {\tt
oskit_absio} COM interface; this may be determined by querying the
object.
\api{getfile}{Get the underlying file object to which this open file refers}
\begin{apisyn}
\cinclude{oskit/fs/openfile.h}
\funcproto oskit_error_t
oskit_openfile_getfile(oskit_openfile_t *f,
\outparam oskit_file_t **out_file);
\end{apisyn}
\ostofs
\begin{apidesc}
This method returns the {\tt oskit_file} COM interface for
the underlying file object to which this open file refers.
\end{apidesc}
\begin{apiparm}
\item[f]
The open file whose underlying file is desired.
\item[out_file]
The {\tt oskit_file} COM interface for the underlying file.
\end{apiparm}
\begin{apiret}
Returns 0 on success, or an error code specified in
{\tt <oskit/error.h>}, on error.
\end{apiret}
\apisec{Dependencies on the Client Operating System}
This section describes the interfaces which must be provided
by the client operating system to the filesystem library.
These interfaces consist of:
\begin{icsymlist}
\item[oskit_get_call_context]
Obtain information about client context.
\item[fs_delay]
Wait for a period of time to elapse.
\item[fs_vprintf]
Generate formatted output to stdout.
\item[fs_vsprintf]
Generate formatted output to a string.
\item[fs_panic]
Perform any cleanup and exit.
\item[fs_gettime]
Obtain the current time.
\item[fs_tsleep]
Wait for a wakeup on a channel or a timeout.
\item[fs_wakeup]
Awaken any threads waiting on a channel.
\item[fs_malloc]
Allocate memory.
\item[fs_realloc]
Resize a chunk of allocated memory.
\item[fs_free]
Free memory.
\end{icsymlist}
Default implementations of the {\tt fs_*} functions are provided in
{\tt liboskit_fs}.
\api{oskit_get_call_context}{Get the caller's context}
\begin{apisyn}
\cinclude{oskit/com.h}
\funcproto oskit_error_t
oskit_get_call_context(oskit_guid_t *iid,
\outparam void **out_if);
\end{apisyn}
\fstoos
\begin{apidesc}
This function returns the requested COM interface
for the current caller.
Typically, this is used to obtain the {\tt oskit_principal}
object for the current client of the filesystem library.
\end{apidesc}
\begin{apiparm}
\item[iid]
The desired COM interface identifier.
\item[out_if]
The COM interface.
\end{apiparm}
\begin{apiret}
Returns 0 on success, or an error code specified in
{\tt <oskit/error.h>}, on error.
\end{apiret}
\api{fs_delay}{Wait for a period of time to elapse}
\begin{apisyn}
\cinclude{oskit/fs/fs.h}
\funcproto void
fs_delay(oskit_u32_t n);
\end{apisyn}
\fstoos
\begin{apidesc}
Wait for {\tt n} microseconds to elapse.
\end{apidesc}
\begin{apiparm}
\item[n]
The number of microseconds to delay.
\end{apiparm}
\api{fs_vprintf}{Generate formatted output to stdout}
\begin{apisyn}
\cinclude{oskit/fs/fs.h}
\funcproto void
fs_vprintf(char *fmt, __oskit_va_list ap);
\end{apisyn}
\fstoos
\begin{apidesc}
This function generates formatted output to {\tt stdout}.
The client operating system defines what is meant
by {\tt stdout}; the output may be displayed on the
console, directed to a log, returned to
the current client, etc.
\end{apidesc}
\begin{apiparm}
\item[fmt]
The format for the output.
\item[ap]
The list of arguments for the output.
\end{apiparm}
\api{fs_vsprintf}{Generate formatted output to a string}
\begin{apisyn}
\cinclude{oskit/fs/fs.h}
\funcproto void
fs_vsprintf(char *s,
char *fmt, __oskit_va_list ap);
\end{apisyn}
\fstoos
\begin{apidesc}
This function generates formatted output to a string.
\end{apidesc}
\begin{apiparm}
\item[s]
The string into which to copy the output.
\item[fmt]
The format for the output.
\item[ap]
The list of arguments for the output.
\end{apiparm}
\api{fs_panic}{Cleanup and exit}
\begin{apisyn}
\cinclude{oskit/fs/fs.h}
\funcproto void
fs_panic(void);
\end{apisyn}
\fstoos
\begin{apidesc}
This function cleans up and exits.
If this function returns rather than exiting,
the filesystem library may be very unhappy.
\end{apidesc}
\api{fs_gettime}{Get the current time}
\begin{apisyn}
\cinclude{oskit/fs/fs.h}
\funcproto oskit_error_t
fs_gettime(\outparam oskit_timespec_t *out_tsp);
\end{apisyn}
\fstoos
\begin{apidesc}
This function returns the current time.
{\tt out_tsp} is a pointer to an {\tt oskit_timespec_t} structure,
defined as follows:
\cstruct{oskit_timespec}{
oskit_time_t tv_sec; /* seconds */
oskit_s32_t tv_nsec; /* and nanoseconds */
};
\end{apidesc}
\begin{apiparm}
\item[out_tsp]
The current time.
\end{apiparm}
\begin{apiret}
Returns 0 on success, or an error code specified in
{\tt <oskit/error.h>}, on error.
\end{apiret}
\api{fs_tsleep}{Wait for a wakeup on a channel or for a timeout}
\begin{apisyn}
\cinclude{oskit/fs/fs.h}
\funcproto oskit_error_t
fs_tsleep(void *chan,
oskit_u32_t pri,
char *wmesg,
oskit_u32_t timo);
\end{apisyn}
\fstoos
\begin{apidesc}
This function waits for a wakeup to occur on sleep channel
{\tt chan} or until {\tt timo} microseconds have elapsed.
Upon waking up, the thread is assigned priority {\tt pri}. If
{\tt timo} is zero, then this function waits until a wakeup
occurs.
A sleep channel is simply an identifier for an event;
typically, {\tt chan} will be the address of some
variable used by the filesystem library.
\end{apidesc}
\begin{apiparm}
\item[chan]
The sleep channel.
\item[pri]
The priority upon wakeup.
\item[wmesg]
A description of the sleep state.
\item[timo]
The timeout for the sleep.
\end{apiparm}
\begin{apiret}
Returns 0 on success, or an error code specified in
{\tt <oskit/error.h>}, on error.
\end{apiret}
\api{fs_wakeup}{Wakeup any threads waiting on this channel}
\begin{apisyn}
\cinclude{oskit/fs/fs.h}
\funcproto void
fs_wakeup(void *chan);
\end{apisyn}
\fstoos
\begin{apidesc}
This function awakens any threads waiting on this sleep channel.
A sleep channel is simply an identifier for an event;
typically, {\tt chan} will be the address of some
variable used by the filesystem library.
\end{apidesc}
\begin{apiparm}
\item[chan]
The sleep channel.
\end{apiparm}
\api{fs_malloc}{Allocate memory from the heap}
\begin{apisyn}
\cinclude{oskit/fs/fs.h}
\funcproto void *fs_malloc(oskit_u32_t size);
\end{apisyn}
\fstoos
\begin{apidesc}
This function returns a pointer to a
chunk of contiguous memory of
at least {\tt size} bytes. The
client operating system need not
provide any alignment guarantees for
the chunk of memory.
\end{apidesc}
\begin{apiparm}
\item[size]
The desired number of bytes.
\end{apiparm}
\begin{apiret}
Returns a pointer to the chunk of memory, or NULL
on error.
\end{apiret}
\api{fs_realloc}{Resize a chunk of allocated memory}
\begin{apisyn}
\cinclude{oskit/fs/fs.h}
\funcproto void *fs_realloc(void *curaddr, oskit_u32_t newsize);
\end{apisyn}
\fstoos
\begin{apidesc}
This function resizes the chunk of allocated
memory referenced by {\tt curaddr} to be
at least {\tt newsize} bytes, and returns
a pointer to the new chunk. If successful,
the old chunk is freed.
The client operating system need not
provide any alignment guarantees for
the new chunk of memory.
\end{apidesc}
\begin{apiparm}
\item[curaddr]
The address of the old chunk.
\item[newsize]
The new size in bytes.
\end{apiparm}
\begin{apiret}
Returns a pointer to the new chunk of memory, or NULL
on error.
\end{apiret}
\api{fs_free}{Free a chunk of allocated memory}
\begin{apisyn}
\cinclude{oskit/fs/fs.h}
\funcproto void
fs_free(void *addr);
\end{apisyn}
\fstoos
\begin{apidesc}
This function frees a chunk of allocated
memory referenced by {\tt addr}.
{\tt addr} must be an address returned
previously by a call to {\tt fs_malloc} or
{\tt fs_realloc}.
\end{apidesc}
\begin{apiparm}
\item[addr]
The address of the chunk.
\end{apiparm}
|