函数源码

Linux Kernel

v5.5.9

Brick Technologies Co., Ltd

Source File:mm\filemap.c Create Date:2022-07-27 15:26:08
首页 Copyright©Brick

3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
/*
 * Performs necessary checks before doing a file copy
 *
 * Can adjust amount of bytes to copy via @req_count argument.
 * Returns appropriate error code that caller should return or
 * zero in case the copy should be allowed.
 */
int generic_copy_file_checks(struct file *file_in, loff_t pos_in,
                 struct file *file_out, loff_t pos_out,
                 size_t *req_count, unsigned int flags)
{
    struct inode *inode_in = file_inode(file_in);
    struct inode *inode_out = file_inode(file_out);
    uint64_t count = *req_count;
    loff_t size_in;
    int ret;
 
    ret = generic_file_rw_checks(file_in, file_out);
    if (ret)
        return ret;
 
    /* Don't touch certain kinds of inodes */
    if (IS_IMMUTABLE(inode_out))
        return -EPERM;
 
    if (IS_SWAPFILE(inode_in) || IS_SWAPFILE(inode_out))
        return -ETXTBSY;
 
    /* Ensure offsets don't wrap. */
    if (pos_in + count < pos_in || pos_out + count < pos_out)
        return -EOVERFLOW;
 
    /* Shorten the copy to EOF */
    size_in = i_size_read(inode_in);
    if (pos_in >= size_in)
        count = 0;
    else
        count = min(count, size_in - (uint64_t)pos_in);
 
    ret = generic_write_check_limits(file_out, pos_out, &count);
    if (ret)
        return ret;
 
    /* Don't allow overlapped copying within the same file. */
    if (inode_in == inode_out &&
        pos_out + count > pos_in &&
        pos_out < pos_in + count)
        return -EINVAL;
 
    *req_count = count;
    return 0;
}