Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions drivers/block/loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,39 @@ static void loop_global_unlock(struct loop_device *lo, bool global)
static int max_part;
static int part_shift;

/**
* get_size - calculate the effective size of a loop device
* @offset: offset into the backing file
* @sizelimit: user-specified size limit
* @file: the backing file
*
* Calculate the effective size of the loop device
*
* Returns: size in 512-byte sectors, or 0 if invalid
*/
static loff_t get_size(loff_t offset, loff_t sizelimit, struct file *file)
{
struct kstat stat;
loff_t loopsize;
int ret;

/*
* Get file attributes for validation. We use vfs_getattr() to ensure
* we have up-to-date file size information.
*/
ret = vfs_getattr_nosec(&file->f_path, &stat, STATX_SIZE,
AT_STATX_SYNC_AS_STAT);
if (ret) {
/*
* If we can't get attributes, fall back to i_size_read()
* which should work for most cases.
*/
loopsize = i_size_read(file->f_mapping->host);
} else {
/* Use the size from getattr for consistency */
loopsize = stat.size;
}

/* Compute loopsize in bytes */
loopsize = i_size_read(file->f_mapping->host);
if (offset > 0)
loopsize -= offset;
/* offset is beyond i_size, weird but possible */
Expand Down
Loading