函数源码

Linux Kernel

v5.5.9

Brick Technologies Co., Ltd

Source File:mm\swapfile.c Create Date:2022-07-27 16:49:14
首页 Copyright©Brick

2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
/*
 * A `swap extent' is a simple thing which maps a contiguous range of pages
 * onto a contiguous range of disk blocks.  An ordered list of swap extents
 * is built at swapon time and is then used at swap_writepage/swap_readpage
 * time for locating where on disk a page belongs.
 *
 * If the swapfile is an S_ISBLK block device, a single extent is installed.
 * This is done so that the main operating code can treat S_ISBLK and S_ISREG
 * swap files identically.
 *
 * Whether the swapdev is an S_ISREG file or an S_ISBLK blockdev, the swap
 * extent list operates in PAGE_SIZE disk blocks.  Both S_ISREG and S_ISBLK
 * swapfiles are handled *identically* after swapon time.
 *
 * For S_ISREG swapfiles, setup_swap_extents() will walk all the file's blocks
 * and will parse them into an ordered extent list, in PAGE_SIZE chunks.  If
 * some stray blocks are found which do not fall within the PAGE_SIZE alignment
 * requirements, they are simply tossed out - we will never use those blocks
 * for swapping.
 *
 * For all swap devices we set S_SWAPFILE across the life of the swapon.  This
 * prevents users from writing to the swap device, which will corrupt memory.
 *
 * The amount of disk space which a single swap extent represents varies.
 * Typically it is in the 1-4 megabyte range.  So we can have hundreds of
 * extents in the list.  To avoid much list walking, we cache the previous
 * search location in `curr_swap_extent', and start new searches from there.
 * This is extremely effective.  The average number of iterations in
 * map_swap_page() has been measured at about 0.3 per page.  - akpm.
 */
static int setup_swap_extents(struct swap_info_struct *sis, sector_t *span)
{
    struct file *swap_file = sis->swap_file;
    struct address_space *mapping = swap_file->f_mapping;
    struct inode *inode = mapping->host;
    int ret;
 
    if (S_ISBLK(inode->i_mode)) {
        ret = add_swap_extent(sis, 0, sis->max, 0);
        *span = sis->pages;
        return ret;
    }
 
    if (mapping->a_ops->swap_activate) {
        ret = mapping->a_ops->swap_activate(sis, swap_file, span);
        if (ret >= 0)
            sis->flags |= SWP_ACTIVATED;
        if (!ret) {
            sis->flags |= SWP_FS;
            ret = add_swap_extent(sis, 0, sis->max, 0);
            *span = sis->pages;
        }
        return ret;
    }
 
    return generic_swapfile_activate(sis, swap_file, span);
}