3051 |
return ret; |
return ret; |
3052 |
\end{verbatim} |
\end{verbatim} |
3053 |
|
|
3054 |
swapfile.c |
\subsection{Function swap\_writepage()} |
3055 |
swap\_state.c |
\textit{File: }\url{mm/swap_state.c}\\ |
3056 |
|
\textit{Prototype: } |
3057 |
|
\begin{verbatim} |
3058 |
|
static int swap_writepage(struct page *page) |
3059 |
|
\end{verbatim} |
3060 |
|
|
3061 |
|
\begin{verbatim} |
3062 |
|
if (remove_exclusive_swap_page(page)) { |
3063 |
|
UnlockPage(page); |
3064 |
|
return 0; |
3065 |
|
} |
3066 |
|
rw_swap_page(WRITE, page); |
3067 |
|
return 0; |
3068 |
|
\end{verbatim} |
3069 |
|
|
3070 |
|
\subsection{Function add\_to\_swap\_cache()} |
3071 |
|
\textit{File: }\url{mm/swap_state.c}\\ |
3072 |
|
\textit{Prototype: } |
3073 |
|
\begin{verbatim} |
3074 |
|
int add_to_swap_cache(struct page *page, swp_entry_t entry) |
3075 |
|
\end{verbatim} |
3076 |
|
|
3077 |
|
\begin{verbatim} |
3078 |
|
if (page->mapping) |
3079 |
|
BUG(); |
3080 |
|
if (!swap_duplicate(entry)) { |
3081 |
|
INC_CACHE_INFO(noent_race); |
3082 |
|
return -ENOENT; |
3083 |
|
} |
3084 |
|
if (add_to_page_cache_unique(page, &swapper_space, entry.val, |
3085 |
|
page_hash(&swapper_space, entry.val)) != 0) { |
3086 |
|
swap_free(entry); |
3087 |
|
INC_CACHE_INFO(exist_race); |
3088 |
|
return -EEXIST; |
3089 |
|
} |
3090 |
|
if (!PageLocked(page)) |
3091 |
|
BUG(); |
3092 |
|
if (!PageSwapCache(page)) |
3093 |
|
BUG(); |
3094 |
|
INC_CACHE_INFO(add_total); |
3095 |
|
return 0; |
3096 |
|
\end{verbatim} |
3097 |
|
|
3098 |
|
\subsection{Function \_\_delete\_from\_swap\_cache()} |
3099 |
|
\textit{File: }\url{mm/swap_state.c}\\ |
3100 |
|
\textit{Prototype: } |
3101 |
|
\begin{verbatim} |
3102 |
|
void __delete_from_swap_cache(struct page *page) |
3103 |
|
\end{verbatim} |
3104 |
|
|
3105 |
|
\begin{verbatim} |
3106 |
|
if (!PageLocked(page)) |
3107 |
|
BUG(); |
3108 |
|
if (!PageSwapCache(page)) |
3109 |
|
BUG(); |
3110 |
|
ClearPageDirty(page); |
3111 |
|
__remove_inode_page(page); |
3112 |
|
INC_CACHE_INFO(del_total); |
3113 |
|
\end{verbatim} |
3114 |
|
|
3115 |
|
\subsection{Function delete\_from\_swap\_cache()} |
3116 |
|
\textit{File: }\url{mm/swap_state.c}\\ |
3117 |
|
\textit{Prototype: } |
3118 |
|
\begin{verbatim} |
3119 |
|
void delete_from_swap_cache(struct page *page) |
3120 |
|
\end{verbatim} |
3121 |
|
|
3122 |
|
\begin{verbatim} |
3123 |
|
swp_entry_t entry; |
3124 |
|
|
3125 |
|
if (!PageLocked(page)) |
3126 |
|
BUG(); |
3127 |
|
|
3128 |
|
block_flushpage(page, 0); |
3129 |
|
|
3130 |
|
entry.val = page->index; |
3131 |
|
|
3132 |
|
spin_lock(&pagecache_lock); |
3133 |
|
__delete_from_swap_cache(page); |
3134 |
|
spin_unlock(&pagecache_lock); |
3135 |
|
|
3136 |
|
swap_free(entry); |
3137 |
|
page_cache_release(page); |
3138 |
|
\end{verbatim} |
3139 |
|
|
3140 |
|
\subsection{Function free\_page\_and\_swap\_cache()} |
3141 |
|
\textit{File: }\url{mm/swap_state.c}\\ |
3142 |
|
\textit{Prototype: } |
3143 |
|
\begin{verbatim} |
3144 |
|
void free_page_and_swap_cache(struct page *page) |
3145 |
|
\end{verbatim} |
3146 |
|
|
3147 |
|
\begin{verbatim} |
3148 |
|
/* |
3149 |
|
* If we are the only user, then try to free up the swap cache. |
3150 |
|
* |
3151 |
|
* Its ok to check for PageSwapCache without the page lock |
3152 |
|
* here because we are going to recheck again inside |
3153 |
|
* exclusive_swap_page() _with_ the lock. |
3154 |
|
* - Marcelo |
3155 |
|
*/ |
3156 |
|
if (PageSwapCache(page) && !TryLockPage(page)) { |
3157 |
|
remove_exclusive_swap_page(page); |
3158 |
|
UnlockPage(page); |
3159 |
|
} |
3160 |
|
page_cache_release(page); |
3161 |
|
\end{verbatim} |
3162 |
|
|
3163 |
|
\subsection{Function lookup\_swap\_cache()} |
3164 |
|
\textit{File: }\url{mm/swap_state.c}\\ |
3165 |
|
\textit{Prototype: } |
3166 |
|
\begin{verbatim} |
3167 |
|
struct page * lookup_swap_cache(swp_entry_t entry) |
3168 |
|
\end{verbatim} |
3169 |
|
|
3170 |
|
\begin{verbatim} |
3171 |
|
struct page *found; |
3172 |
|
|
3173 |
|
found = find_get_page(&swapper_space, entry.val); |
3174 |
|
/* |
3175 |
|
* Unsafe to assert PageSwapCache and mapping on page found: |
3176 |
|
* if SMP nothing prevents swapoff from deleting this page from |
3177 |
|
* the swap cache at this moment. find_lock_page would prevent |
3178 |
|
* that, but no need to change: we _have_ got the right page. |
3179 |
|
*/ |
3180 |
|
INC_CACHE_INFO(find_total); |
3181 |
|
if (found) |
3182 |
|
INC_CACHE_INFO(find_success); |
3183 |
|
return found; |
3184 |
|
\end{verbatim} |
3185 |
|
|
3186 |
|
\subsection{Function read\_swap\_cache\_async()} |
3187 |
|
\textit{File: }\url{mm/swap_state.c}\\ |
3188 |
|
\textit{Prototype: } |
3189 |
|
\begin{verbatim} |
3190 |
|
struct page * read_swap_cache_async(swp_entry_t entry) |
3191 |
|
\end{verbatim} |
3192 |
|
|
3193 |
|
\begin{verbatim} |
3194 |
|
struct page *found_page, *new_page = NULL; |
3195 |
|
int err; |
3196 |
|
|
3197 |
|
do { |
3198 |
|
/* |
3199 |
|
* First check the swap cache. Since this is normally |
3200 |
|
* called after lookup_swap_cache() failed, re-calling |
3201 |
|
* that would confuse statistics: use find_get_page() |
3202 |
|
* directly. |
3203 |
|
*/ |
3204 |
|
found_page = find_get_page(&swapper_space, entry.val); |
3205 |
|
if (found_page) |
3206 |
|
break; |
3207 |
|
|
3208 |
|
/* |
3209 |
|
* Get a new page to read into from swap. |
3210 |
|
*/ |
3211 |
|
if (!new_page) { |
3212 |
|
new_page = alloc_page(GFP_HIGHUSER); |
3213 |
|
if (!new_page) |
3214 |
|
break; /* Out of memory */ |
3215 |
|
} |
3216 |
|
|
3217 |
|
/* |
3218 |
|
* Associate the page with swap entry in the swap cache. |
3219 |
|
* May fail (-ENOENT) if swap entry has been freed since |
3220 |
|
* our caller observed it. May fail (-EEXIST) if there |
3221 |
|
* is already a page associated with this entry in the |
3222 |
|
* swap cache: added by a racing read_swap_cache_async, |
3223 |
|
* or by try_to_swap_out (or shmem_writepage) re-using |
3224 |
|
* the just freed swap entry for an existing page. |
3225 |
|
*/ |
3226 |
|
err = add_to_swap_cache(new_page, entry); |
3227 |
|
if (!err) { |
3228 |
|
/* |
3229 |
|
* Initiate read into locked page and return. |
3230 |
|
*/ |
3231 |
|
rw_swap_page(READ, new_page); |
3232 |
|
return new_page; |
3233 |
|
} |
3234 |
|
} while (err != -ENOENT); |
3235 |
|
|
3236 |
|
if (new_page) |
3237 |
|
page_cache_release(new_page); |
3238 |
|
return found_page; |
3239 |
|
\end{verbatim} |