1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** FileX Component */
16 /** */
17 /** Media */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22 #define FX_SOURCE_CODE
23
24
25 /* Include necessary system files. */
26
27 #include "fx_api.h"
28 #include "fx_system.h"
29 #include "fx_media.h"
30 #include "fx_file.h"
31 #include "fx_utility.h"
32
33
34 /**************************************************************************/
35 /* */
36 /* FUNCTION RELEASE */
37 /* */
38 /* _fx_media_abort PORTABLE C */
39 /* 6.1 */
40 /* AUTHOR */
41 /* */
42 /* William E. Lamie, Microsoft Corporation */
43 /* */
44 /* DESCRIPTION */
45 /* */
46 /* This function marks all open files for the specified media as */
47 /* aborted and then removes the media control block from the open */
48 /* media list and marks it as aborted as well. */
49 /* */
50 /* INPUT */
51 /* */
52 /* media_ptr Media control block pointer */
53 /* */
54 /* OUTPUT */
55 /* */
56 /* return status */
57 /* */
58 /* CALLS */
59 /* */
60 /* tx_mutex_delete Delete the mutex */
61 /* */
62 /* CALLED BY */
63 /* */
64 /* Application Code */
65 /* */
66 /* RELEASE HISTORY */
67 /* */
68 /* DATE NAME DESCRIPTION */
69 /* */
70 /* 05-19-2020 William E. Lamie Initial Version 6.0 */
71 /* 09-30-2020 William E. Lamie Modified comment(s), */
72 /* resulting in version 6.1 */
73 /* */
74 /**************************************************************************/
_fx_media_abort(FX_MEDIA * media_ptr)75 UINT _fx_media_abort(FX_MEDIA *media_ptr)
76 {
77
78 FX_INT_SAVE_AREA
79 ULONG open_count;
80 FX_FILE *file_ptr;
81
82
83 #ifndef FX_MEDIA_STATISTICS_DISABLE
84
85 /* Increment the number of times this service has been called. */
86 media_ptr -> fx_media_aborts++;
87 #endif
88
89 /* Check the media to make sure it is open. */
90 if (media_ptr -> fx_media_id != FX_MEDIA_ID)
91 {
92
93 /* Return the media not opened error. */
94 return(FX_MEDIA_NOT_OPEN);
95 }
96
97 /* If trace is enabled, insert this event into the trace buffer. */
98 FX_TRACE_IN_LINE_INSERT(FX_TRACE_MEDIA_ABORT, media_ptr, 0, 0, 0, FX_TRACE_MEDIA_EVENTS, 0, 0)
99
100 /* Protect against other threads accessing the media. */
101 FX_PROTECT
102
103 /* Loop through the media's open files. */
104 open_count = media_ptr -> fx_media_opened_file_count;
105 file_ptr = media_ptr -> fx_media_opened_file_list;
106 while (open_count)
107 {
108
109 /* Mark the file as aborted. */
110 file_ptr -> fx_file_id = FX_FILE_ABORTED_ID;
111
112 /* Adjust the pointer and decrement the file opened count. */
113 file_ptr = file_ptr -> fx_file_opened_next;
114 open_count--;
115 }
116
117 /* Build the "abort" I/O driver request. */
118 media_ptr -> fx_media_driver_request = FX_DRIVER_ABORT;
119 media_ptr -> fx_media_driver_status = FX_IO_ERROR;
120
121 /* If trace is enabled, insert this event into the trace buffer. */
122 FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_ABORT, media_ptr, 0, 0, 0, FX_TRACE_INTERNAL_EVENTS, 0, 0)
123
124 /* Call the specified I/O driver with the abort request. */
125 (media_ptr -> fx_media_driver_entry) (media_ptr);
126
127 /* Now remove this media from the open list. */
128
129 /* Lockout interrupts for media removal. */
130 FX_DISABLE_INTS
131
132 /* See if the media is the only one on the media opened list. */
133 if (_fx_system_media_opened_count == ((ULONG) 1))
134 {
135
136 /* Only opened media, just set the opened list to NULL. */
137 _fx_system_media_opened_ptr = FX_NULL;
138 }
139 else
140 {
141
142 /* Otherwise, not the only opened media, link-up the neighbors. */
143 (media_ptr -> fx_media_opened_next) -> fx_media_opened_previous =
144 media_ptr -> fx_media_opened_previous;
145 (media_ptr -> fx_media_opened_previous) -> fx_media_opened_next =
146 media_ptr -> fx_media_opened_next;
147
148 /* See if we have to update the opened list head pointer. */
149 if (_fx_system_media_opened_ptr == media_ptr)
150 {
151
152 /* Yes, move the head pointer to the next opened media. */
153 _fx_system_media_opened_ptr = media_ptr -> fx_media_opened_next;
154 }
155 }
156
157 /* Decrement the opened media counter. */
158 _fx_system_media_opened_count--;
159
160 /* Finally, Indicate that this media is aborted. */
161 media_ptr -> fx_media_id = FX_MEDIA_ABORTED_ID;
162
163 /* Restore interrupt posture. */
164 FX_RESTORE_INTS
165
166 /* Delete the media protection structure if FX_SINGLE_THREAD is not
167 defined. */
168 #ifndef FX_SINGLE_THREAD
169
170 #ifndef FX_DONT_CREATE_MUTEX
171
172 /* Note that the protection is never released. The mutex delete
173 service will handle all threads waiting access to this media
174 control block. */
175 tx_mutex_delete(& (media_ptr -> fx_media_protect));
176 #endif
177 #endif
178
179 #ifdef FX_DONT_CREATE_MUTEX
180
181 /* Release media protection. */
182 FX_UNPROTECT
183 #endif
184
185 /* Return status to the caller. */
186 return(FX_SUCCESS);
187 }
188
189