03/15/85 file_manager_ The file_manager_ subroutine is the interface between the data storage and retrieval services of data management and Multics file access and control mechanisms. It also ensures concurrency and recovery protection by invoking data management integrity services when protected data management (DM) files are accessed or modified. As a direct user interface, the file_manager_ subroutine makes the protection and recovery capabilities of integrity services available to users who write applications using their own data storage and retrieval software. Entry points in file_manager_: (List is generated by the help command) :Entry: close: 03/15/85 file_manager_$close Function: This entry point closes a DM file in the current process. The file to be closed is designated by its opening identifier. Syntax: declare file_manager_$close entry (bit(36) aligned, fixed bin(35)); call file_manager_$close (oid, code); Arguments: oid is the file opening identifier of the file to be closed. (Input/Output) It is set to zero by this entry point in order to indicate that it is no longer valid. code is a standard status code. (Output) Notes: If the file is opened more than once in the process, this operation decreases the number of openings by one. See the description of the open entry for more details. The user process does not have to be in transaction mode to close a DM file. Aborting a transaction does not cause the file to be reopened, even if it was closed by a delete_close operation and the deletion was rolled back. :Entry: create: 03/15/85 file_manager_$create Function: This entry point creates a DM file. The caller specifies its pathname and attributes, and must specify whether the file is protected; see "Notes" below. Syntax: declare file_manager_$create (char(*), char(*), ptr, fixed bin(35)); call file_manager_$create (dir_path, entry_name, file_create_info_ptr, code); Arguments: dir_path is the absolute pathname of a directory. (Input) The file will be added to this directory. entry_name is the name of the file. (Input) file_create_info_ptr points to the file_create_info structure. (Input) If this pointer is null, a protected file is created with the default attribute values. code is a standard status code. (Output) Access required: You cannot create a DM file in your home directory unless you have the proper access to the directory above the containing directory, and, in any event, you must have sufficient access to add an entry to the containing directory. The file is created with read and write access for the caller and the DM daemon (Data_Management.Daemon). Notes: In the current implementation, file attributes specified in the file_create_info structure such as ring brackets and blocking factor cannot be changed. :Entry: create_open: 03/15/85 file_manager_$create_open Function: Calling this entry point has the effect of calling the create and open entries, but is more efficient. If the file already exists, it is opened and code is dm_error_$file_already_exists. If the file already exists and is already open, the opening identifier is returned and code is dm_error_$file_already_open. Syntax: declare file_manager_$create_open entry (char(*), char(*), ptr, bit(36) aligned, fixed bin(35)); call file_manager_$create_open (dir_path, entry_name, file_create_info_ptr, oid, code); Arguments: dir_path is the absolute pathname of a directory. (Input) The file is added to this directory. entry_name is the name of the file. (Input) file_create_info_ptr is a pointer to a file_create_info structure into which the file attributes are to be placed. (Input) This structure may in turn be used to create a new DM file into which to copy the old DM file. The structure is defined in dm_fm_create_info.incl.pl1. oid is the opening identifier assigned to the file. (Output) If it is not zero, the oid is valid and can be used, regardless of the value of code. If the transaction aborts and the file is deleted, it still needs to be closed, since openings are not undone by rollback. code is a standard status code. (Output) If it is dm_error_$file_already_exists or dm_error_$file_already_open, the operation is considered successful and oid is usable. :Entry: delete_close: 03/15/85 file_manager_$delete_close Function: Calling this entry point has the same effect as calling the delete and close entries, but is more efficient. It deletes a file that is already open. Syntax: declare file_manager_$delete_close entry (bit(36) aligned, fixed bin(35)); call file_manager_$delete_close (oid, code); Arguments: oid is the file opening identifier of the file to be deleted and closed. (Input/Output) It is set to zero by this entry point in order to indicate that it is no longer valid. The file remains closed even if the transaction is aborted, negating the delete operation. code is a standard status code. (Output) :Entry: free: 03/15/85 file_manager_$free Function: This entry point frees disk space allocated to control intervals. The set of consecutive control intervals is specified by the number of the first control interval and the number of consecutive control intervals starting at the first one. After the disk space for a control interval has been freed, its content is effectively zero. This operation has a high fixed overhead, so it should not be called for one control interval at a time. If any or all of the control intervals are already free, code is set to dm_error_$ci_already_free. The operation is, nevertheless, successful. Syntax: declare file_manager_$free entry (bit(36) aligned, fixed bin(27), fixed bin(27), fixed bin(35)); call file_manager_$free (oid, first_ci, n_ci, code); Arguments: oid is a file opening identifier. (Input) first_ci is the control interval number of the first control interval of the set whose physical space is to be freed. (Input) n_ci is the number of consecutive control intervals whose physical space is to be freed. (Input) code is a standard status code. (Output) If it is dm_error_$ci_already_free, the operation can still be considered a success. Access required: The user must have write access to the file. Notes: If the file is protected, the caller must be in transaction mode and the free operation is done under the auspices of the integrity services. If the transaction aborts, the control intervals are reallocated and their contents restored. :Entry: get: 03/15/85 file_manager_$get Function: This entry point reads data from a control interval. The caller may specify one or several parts. Each part is described by its byte offset relative to the beginning of the addressable portion of the control interval and its length in bytes. Each part has a pointer to a buffer provided by the caller. If the control interval does not exist, the buffers provided by the caller are filled with zeros and code is set to zero. Syntax: declare file_manager_$get entry (bit(36) aligned, fixed bin(27), ptr, fixed bin(35)); call file_manager_$get (oid, ci_num, ci_parts_ptr, code); Arguments: oid is a file opening identifier. (Input) ci_num is a control interval number. (Input) ci_parts_ptr points to the ci_parts structure declared in dm_ci_parts.incl.pl1. (Input) code is a standard status code. (Output) Notes: If the file is protected, the process must be in transaction mode, and unless no_concurrency is specified, get locks the control interval in share mode. It is kept locked until the end of the transaction. This assures that no other transaction can put anything into the control interval, free it, or delete the file during the current transaction. If the control interval is locked in exclusive mode by another transaction, get waits until it finishes. If waiting is pointless because the current transaction is deadlocked with another transaction, the transaction_deadlock condition is signaled. Access required: The calling process must have read access to call the get entry. :Entry: get_ci_header: 03/15/85 file_manager_$get_ci_header Function: This entry reads the 4-word control interval header. The header tells whether a control interval is allocated when it was last modified, and what the unique identifier of the DM file is. Protection and access are the same as for the get entry. If the control interval does not exist, this entry returns the header that it would have had, with zero in the time_modified field and code set to zero. It does not create the control interval. Syntax: declare file_manager_$get_ci_header entry (bit(36) aligned, fixed bin(27), 1 like ci_header aligned, fixed bin(35)); call file_manager_$get_ci_header (oid, ci_num, ci_header, code); Arguments: oid is a file opening identifier. (Input) ci_num is a control interval number. (Input) ci_header is the ci_header structure, declared in dm_ci_header.incl.pl1. (Input/Output) code is a standard status code. (Output) :Entry: get_ci_ptr: 03/15/85 file_manager_$get_ci_ptr Function: This entry point returns a pointer to the addressable portion of a control interval. Pointers to control intervals should be used only in well defined and contained situations to enhance the performance of accessing data in a control interval for retrieval purposes. This entry is helpful when it is known beforehand that several pieces of data are to be read from the same control interval, but they cannot be read by specifying several parts to the get entry (e.g., the offset of one is dependent on the value of another). Unlike other entries which get data, it is not valid to get a control interval pointer to a control interval that is not allocated. Syntax: declare file_manager_$get_ci_ptr entry (bit(36) aligned, fixed bin(27), ptr, fixed bin(35)); call file_manager_$get_ci_ptr (oid, ci_num, ci_ptr, code); Arguments: oid is a file opening identifier. (Input) ci_num is a control interval number. (Input) ci_ptr points to the addressable portion of the control interval. (Input/Output) The addressable portion begins immediately after the control interval header. A null value is returned for this pointer if there is a error and the returned code is not zero. code is a standard status code. (Output) It can be dm_error_$ci_not_allocated if the specified control interval has not been allocated. ci_ptr is set to null. Notes: In order to make it possible to look at control intervals via a pointer, the create entry sets the ring brackets on file components to: ,,. If the file is protected, the process must be in transaction mode, and unless no_concurrency is specified, get_ci_ptr locks the control interval in share mode. It is kept locked until the end of the transaction. This assures that no other transaction can put anything into the control interval, free it, or delete the file during the current transaction. If the control interval is locked in exclusive mode by another transaction, get_ci_ptr waits until it finishes. If waiting is pointless because the current transaction is deadlocked with another transaction, the transaction_deadlock condition is signaled. If the control interval does not exist, an error code of value dm_error_$ci_not_allocated is returned. Access required: The calling process must have read access to call the get_ci_ptr entry. :Entry: get_exclusive: 03/15/85 file_manager_$get_exclusive Function: This entry point is the same as get entry except that it locks the control interval exclusively, preventing other transactions from even obtaining the share lock necessary to do a normal get operation. Syntax: declare file_manager_$get_exclusive entry (bit(36) aligned, fixed bin(27), ptr, fixed bin(35)); call file_manager_$get_exclusive (oid, ci_num, ci_parts_ptr, code); Arguments: oid is a file opening identifier. (Input) ci_num is a control interval number. (Input) ci_parts_ptr points to the ci_parts structure declared in dm_ci_parts.incl.pl1. (Input) code is a standard status code. (Output) Notes: This entry is useful for applications that are going to do a put operation into the same control interval. Obtaining an exclusive lock on a control interval effectively reduces concurrency, so this entry should be used advisedly. :Entry: get_stream: 03/15/85 file_manager_$get_stream Function: This entry point returns a specified number of bytes from a DM file, given an opening identifier, a file offset, and a buffer in which to place the bytes. This entry treats the DM file as a stream of bytes consisting of the concatenation of the addressable portion of all control intervals in the DM file. Syntax: declare file_manager_$get_stream entry (bit(36) aligned, fixed bin(48), ptr, fixed bin(21)); call file_manager_$get_stream (oid, file_offset_in_bytes, buf_ptr, buf_length_in_bytes); Arguments: oid is the opening identifier of the DM file to be read from. (Input) file_offset_in_bytes is the offset given in bytes, from the beginning of the logical address space of the DM file given in bytes with an offset of zero representing the beginning of the file. (Input) buf_ptr is a pointer to a buffer where the bytes read from the DM file may be placed. (Input) buf_length_in_bytes is the number of bytes that are to be read from the DM file. (Input) Notes: If the DM file is protected, the process must be in transaction mode and unless concurrency is specified, get_stream locks in share mode the control intervals in which the specified stream of bytes resides. Access required: The calling process must have read access to the DM file to call the get_stream entry. :Entry: lock_advice: 03/15/85 file_manager_$lock_advice Function: This entry point permits applications to give the file manager advice about locking granularity. For example, if an application is to modify every control interval in a file, it can request the file manager to lock the entire file and save the overhead of locking individual control intervals. Syntax: declare file_manager_$lock_advice entry (bit(36) aligned, fixed bin, fixed bin(35)); call file_manager_$lock_advice (oid, lock_mode, code); Arguments: oid is a file opening identifier. (Input) lock_mode is the finest and weakest lock mode to use on this file for the remainder of the opening. (Input) It must be one of the five following modes: 4 (LOCK_MODE_IS), 5 (LOCK_MODE_IX), 6 (LOCK_MODE_SIX), 2 (LOCK_MODE_S), or 3 (LOCK_MODE_X) which are declared in dm_lock_modes.incl.pl1. code is a standard status code. (Output) Notes: Lock advice never abridges protection against concurrent file access by other processes. If no lock advice is given, file manager uses the weakest lock necessary to provide concurrency protection, and the finest granularity available, which is the control interval. Lock advice always causes file manager to use a stronger lock or coarser granularity than absolutely necessary. This reduces concurrency in order to reduce locking overhead. Lock advice applies to protected files unless the no_concurrency attribute is present. Since it is an attribute of the opening and not of the file, it can be given to any open file, regardless of whether a transaction is in progress. The first time the file is referenced in each transaction, the advice tells the file manager what kind of a global file lock to acquire. If the lock advice is given after the first time the file is referenced, it will not be used until the next transaction. The lock advice is retained until it is changed, or the file is closed. The advice concerns the type of lock to use at the file level. The only way to control the type of lock used on a control interval is to call get_exclusive instead of get. If no advice is given, IS (intention shared) is presumed. IS is strong enough for get and get_ci_header which lock control intervals in S (share) mode. Put, allocate, and free require that the file lock be upgraded to the stronger IX (intention exclusive) mode, because they lock control intervals in X (exclusive) mode. Create and delete lock the file in X mode, regardless. If advice is given, then all operations lock the file in the advised mode unless it is too weak for the operation. The SIX (shared and intention exclusive) mode means only lock the control intervals that are modified. SIX saves the overhead of locking individual control intervals for get operations because it prevents other transactions from getting anything but an IS lock on the file. :Entry: open: 03/15/85 file_manager_$open Function: This entry point makes a DM file accessible within a process. The file is specified by its pathname. The file is assigned an opening identifier in the current process, by which it is designated in all subsequent calls to file_manager_. Syntax: declare file_manager_$open entry (char(*), char(*), bit(36) aligned, fixed bin(35)); call file_manager_$open (dir_path, entry_name, oid, code); Arguments: dir_path is the absolute pathname of the directory which contains the file. (Input) entry_name is the entry name of the file. (Input) oid is the file opening identifier assigned to the file and returned to the caller. (Output) If it is not zero, it is usable, regardless of code. code is a standard status code. (Output) If it is dm_error_$file_already_open, the operation is considered successful and oid is usable. Notes: If the file was already opened in the current process, the open entry does not assign a new opening identifier, but rather returns the opening identifier that was already assigned and sets code to dm_error_$file_already_open. The file manager keeps track of the number of opens and closes. The opening identifier remains valid as long as there are more opens than closes. If all subsystems within a process close a file the same number of times they open it, they will not invalidate each others openings. There is no requirement for the process to be in transaction mode when opening a file, protected or not. Aborting a transaction has no effect on file openings, even if create_open was called and the create is rolled back. Attempts to use such an opening will result in dm_error_$file_doesnt_exist. The same thing happens if a file is opened and then deleted. Close is the only operation allowed on a file which has been deleted. :Entry: put: 03/15/85 file_manager_$put Function: This entry point writes data into a control interval. The caller can specify one or several parts of the control interval to be written. If the control interval does not exist, it is automatically allocated and the content of its addressable portion is initialized to zero. Syntax: declare file_manager_$put entry (bit(36) aligned, fixed bin(27), ptr, fixed bin(35)); call file_manager$put (oid, ci_num, ci_parts_ptr, code); Arguments: oid is a file opening identifier. (Input) ci_num is a control interval number. (Input) ci_parts_ptr points to the ci_parts structure declared in dm_ci_parts.incl.pl1. (Input) code is a standard status code. (Output) Notes: If the file is protected, the process must be in transaction mode, and unless no_concurrency is specified, put locks the control interval in exclusive mode. It is kept locked until the end of the transaction. This assures that no other transaction can put anything into the control interval, get anything from it, free it, or delete the file during the current transaction. If the control interval is locked by another transaction, the put operation must wait until it finishes. If waiting is pointless because the current transaction is deadlocked with another transaction, the transaction_deadlock condition is signaled. Unless the file is unprotected or has the no_rollback attribute, a put operation causes a before image of data in the control interval to be journalized before actually modifying it. If the transaction should abort, the before journal manager will undo its modifications by restoring the before images. The modified control interval can not be written to disk until its before image is on disk, because there must be enough information on disk to roll back the transaction even if main memory fails. If the modified control interval were written first and the system failed before the transaction finished and the content of main memory could not be flushed to disk, the modification could not be undone and rollback of the transaction would be incomplete. The data management system holds modified control intervals in main memory until the associated before images are written to disk. The Multics clock value in the control interval header is used for this purpose. The put request is rejected if either of the following is true: - The user does not have write permission on the file. - The file is protected but the process is not in a transaction mode. :Entry: put_stream: 03/15/85 file_manager_$put_stream Function: This entry point writes a specified number of bytes in a DM file at a given offset in the logical address space. This entry treats the DM file as a stream of bytes made up of the concatenation of the addressable portion of all control intervals in the DM file. Syntax: declare file_manager_$put_stream entry (bit(36) aligned, fixed bin(48), ptr, fixed bin(21), fixed bin(35)); call file_manager_$put (oid, file_offset_in_bytes, buf_ptr, buf_length_in_bytes, code); Arguments: oid is the opening identifier of the DM file. (Input) file_offset_in_bytes is the offset in bytes into the logical address space of the DM file where the supplied bytes will be placed. (Input) buf_ptr is a pointer to the buffer containing the bytes to be written to the DM file. (Input) buf_length_in_bytes is the number of bytes to be written into the DM file from the buffer. (Input) code is a standard system status code. (Input) Notes: If the DM file is protected, the process must be in transaction mode, and unless concurrency is specified, put_stream locks the control intervals in which the specified stream of bytes resides. Access required: The calling process must have write access to the DM file to call the put_stream entry. :Entry: raw_get: 03/15/85 file_manager_$raw_get Function: This entry point resembles the get entry, except that it treats the file as if it were unprotected. It does not require that the process be in transaction mode. Syntax: declare file_manager_$raw_get entry (bit(36) aligned, fixed bin(27), ptr, fixed bin(35)); call file_manager_$raw_get (oid, ci_num, ci_parts_ptr, code); Arguments: oid is a file opening identifier. (Input) ci_num is a control interval number. (Input) ci_parts_ptr points to a ci_parts structure declared in dm_ci_parts.incl.pl1. (Input) code is a standard status code. (Output) :Entry: raw_put: 03/15/85 file_manager_$raw_put Function: This entry point resembles the put entry, except that it treats the file as if it were unprotected. Also, the time_modified stamp in the control interval header is not updated. This operation is intended for applications that need to update protected files in an unprotected manner. It does not require that the process be in transaction mode. Syntax: declare file_manager_$raw_put entry (bit(36) aligned, fixed bin(27), ptr, fixed bin(35)); call file_manager_$raw_put (oid, ci_num, ci_parts_ptr, code); Arguments: oid is a file opening identifier. (Input) ci_num is a control interval number. (Input) ci_parts_ptr points to a ci_parts structure declared in dm_ci_parts.incl.pl1. (Input) code is a standard status code. (Output) :Entry: simple_get: 03/15/85 file_manager_$simple_get Function: This entry point is used to get a sequence of bytes from a DM file, given an opening identifier, a control interval number, and control interval offset. The sequence is placed in a caller-supplied buffer. This entry point differs from the get entry in that it can only get bytes from one location within a control interval, and a ci_parts structure does not have to exist to make the call. Syntax: declare file_manager_$simple_get entry (bit(36) aligned, fixed bin(27), fixed bin(21), ptr, fixed bin(21)); call file_manager_$simple_get (oid, ci_num, ci_offset_in_bytes, buf_ptr, buf_length_in_bytes); Arguments: oid is the opening identifier of the DM file. (Input) ci_num is the control interval in the DM file that contains the data to be fetched. (Input) ci_offset_in_bytes is the offset from the beginning of the control interval to the beginning of the data, expressed in bytes. (Input) buf_ptr is a pointer to a caller supplied buffer where the data is to be placed. (Input) buf_length_in_bytes is the length in bytes of the caller supplied buffer. (Input) This also specifies the number of bytes to be fetched. The sum of ci_offset_in_bytes and buf_length_in_bytes must not exceed the length of a control interval. code is a standard system status code. (Output) :Entry: simple_put: 03/15/85 file_manager_$simple_put Function: This entry point places a given sequence of bytes into a DM file, given an open id, a control interval number, and a control interval offset. This entry differs from the put entry point in that it places bytes only at one given location within a control interval, so no ci_parts structure is required. Syntax: declare file_manager_$simple_put entry (bit(36) aligned, fixed bin(27), fixed bin(21), ptr, fixed bin(21)); call file_manager_$simple_put (oid, ci_num, ci_offset_in_bytes, buf_ptr, buf_length_in_bytes); Arguments: oid is the opening identifier of the DM file. (Input) ci_num is the control interval in the DM file where the data is to be placed. (Input) ci_offset_in_bytes is the offset from the beginning of the control interval to the beginning of where the data is to be placed. (Input) buf_ptr is a pointer to the buffer containing the data. (Input) buf_length_in_bytes is the number of bytes that are to be placed into the DM file. (Input) code is a standard system status code. (Output) :Entry: status: 03/15/85 file_manager_$status Function: This entry point returns status information on a DM file. Syntax: declare file_manager_$status entry (bit(36), ptr, fixed bin(35)); call file_manager_$status (oid, file_status_ptr, code); Arguments: oid is the opening identifier of the DM file. (Input) file_status_ptr is a pointer to a file_status structure to be filled in by this entry. (Input) See the include file dm_file_status.incl.pl1. code is a standard system status code. (Output) Notes: The structure that lists the information returned by file_manager_$status to describe a DM file is declared in dm_file_status.incl.pl1. :Entry: terminate_ci_ptr: 03/15/85 file_manager_$terminate_ci_ptr Function: This entry point releases a control interval pointer to a specific control interval of a DM file retrieved through the get_ci_ptr entry point. This entry must be called for each call to get_ci_ptr. Syntax: declare file_manager_$terminate_ci_ptr entry (bit(36) aligned, fixed bin(27), ptr, fixed bin(35)); call file_manager_$terminate_ci_ptr (oid, ci_num, ci_ptr, code); Arguments: oid is the opening identifier of the DM file. (Input) ci_num is the number of the control interval that ci_ptr points to. (Input) ci_ptr is the control interval pointer to be terminated. (Input) code is a standard system status code. (Output) ----------------------------------------------------------- Historical Background This edition of the Multics software materials and documentation is provided and donated to Massachusetts Institute of Technology by Group BULL including BULL HN Information Systems Inc. as a contribution to computer science knowledge. This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell BULL Inc., Groupe BULL and BULL HN Information Systems Inc. to the development of this operating system. Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture for managing computer hardware properly and for executing programs. Many subsequent operating systems incorporated Multics principles. Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . ----------------------------------------------------------- Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without fee is hereby granted,provided that the below copyright notice and historical background appear in all copies and that both the copyright notice and historical background and this permission notice appear in supporting documentation, and that the names of MIT, HIS, BULL or BULL HN not be used in advertising or publicity pertaining to distribution of the programs without specific prior written permission. Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. Copyright 2006 by BULL HN Information Systems Inc. Copyright 2006 by Bull SAS All Rights Reserved