Skip to content

Commit 46a1c2c

Browse files
pibrochAl Viro
authored andcommitted
vfs: export lseek_execute() to modules
For those file systems(btrfs/ext4/ocfs2/tmpfs) that support SEEK_DATA/SEEK_HOLE functions, we end up handling the similar matter in lseek_execute() to update the current file offset to the desired offset if it is valid, ceph also does the simliar things at ceph_llseek(). To reduce the duplications, this patch make lseek_execute() public accessible so that we can call it directly from the underlying file systems. Thanks Dave Chinner for this suggestion. [AV: call it vfs_setpos(), don't bring the removed 'inode' argument back] v2->v1: - Add kernel-doc comments for lseek_execute() - Call lseek_execute() in ceph->llseek() Signed-off-by: Jie Liu <jeff.liu@oracle.com> Cc: Dave Chinner <dchinner@redhat.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Andi Kleen <andi@firstfloor.org> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Christoph Hellwig <hch@lst.de> Cc: Chris Mason <chris.mason@fusionio.com> Cc: Josef Bacik <jbacik@fusionio.com> Cc: Ben Myers <bpm@sgi.com> Cc: Ted Tso <tytso@mit.edu> Cc: Hugh Dickins <hughd@google.com> Cc: Mark Fasheh <mfasheh@suse.com> Cc: Joel Becker <jlbec@evilplan.org> Cc: Sage Weil <sage@inktank.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
1 parent 2142914 commit 46a1c2c

File tree

8 files changed

+25
-68
lines changed

8 files changed

+25
-68
lines changed

fs/btrfs/file.c

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2425,20 +2425,7 @@ static loff_t btrfs_file_llseek(struct file *file, loff_t offset, int whence)
24252425
}
24262426
}
24272427

2428-
if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET)) {
2429-
offset = -EINVAL;
2430-
goto out;
2431-
}
2432-
if (offset > inode->i_sb->s_maxbytes) {
2433-
offset = -EINVAL;
2434-
goto out;
2435-
}
2436-
2437-
/* Special lock needed here? */
2438-
if (offset != file->f_pos) {
2439-
file->f_pos = offset;
2440-
file->f_version = 0;
2441-
}
2428+
offset = vfs_setpos(file, offset, inode->i_sb->s_maxbytes);
24422429
out:
24432430
mutex_unlock(&inode->i_mutex);
24442431
return offset;

fs/ceph/file.c

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -866,16 +866,7 @@ static loff_t ceph_llseek(struct file *file, loff_t offset, int whence)
866866
break;
867867
}
868868

869-
if (offset < 0 || offset > inode->i_sb->s_maxbytes) {
870-
offset = -EINVAL;
871-
goto out;
872-
}
873-
874-
/* Special lock needed here? */
875-
if (offset != file->f_pos) {
876-
file->f_pos = offset;
877-
file->f_version = 0;
878-
}
869+
offset = vfs_setpos(file, offset, inode->i_sb->s_maxbytes);
879870

880871
out:
881872
mutex_unlock(&inode->i_mutex);

fs/ext4/file.c

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -494,17 +494,7 @@ static loff_t ext4_seek_data(struct file *file, loff_t offset, loff_t maxsize)
494494
if (dataoff > isize)
495495
return -ENXIO;
496496

497-
if (dataoff < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET))
498-
return -EINVAL;
499-
if (dataoff > maxsize)
500-
return -EINVAL;
501-
502-
if (dataoff != file->f_pos) {
503-
file->f_pos = dataoff;
504-
file->f_version = 0;
505-
}
506-
507-
return dataoff;
497+
return vfs_setpos(file, dataoff, maxsize);
508498
}
509499

510500
/*
@@ -580,17 +570,7 @@ static loff_t ext4_seek_hole(struct file *file, loff_t offset, loff_t maxsize)
580570
if (holeoff > isize)
581571
holeoff = isize;
582572

583-
if (holeoff < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET))
584-
return -EINVAL;
585-
if (holeoff > maxsize)
586-
return -EINVAL;
587-
588-
if (holeoff != file->f_pos) {
589-
file->f_pos = holeoff;
590-
file->f_version = 0;
591-
}
592-
593-
return holeoff;
573+
return vfs_setpos(file, holeoff, maxsize);
594574
}
595575

596576
/*

fs/ocfs2/file.c

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2646,17 +2646,7 @@ static loff_t ocfs2_file_llseek(struct file *file, loff_t offset, int whence)
26462646
goto out;
26472647
}
26482648

2649-
if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET))
2650-
ret = -EINVAL;
2651-
if (!ret && offset > inode->i_sb->s_maxbytes)
2652-
ret = -EINVAL;
2653-
if (ret)
2654-
goto out;
2655-
2656-
if (offset != file->f_pos) {
2657-
file->f_pos = offset;
2658-
file->f_version = 0;
2659-
}
2649+
offset = vfs_setpos(file, offset, inode->i_sb->s_maxbytes);
26602650

26612651
out:
26622652
mutex_unlock(&inode->i_mutex);

fs/read_write.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,19 @@ static inline int unsigned_offsets(struct file *file)
4141
return file->f_mode & FMODE_UNSIGNED_OFFSET;
4242
}
4343

44-
static loff_t lseek_execute(struct file *file, loff_t offset, loff_t maxsize)
44+
/**
45+
* vfs_setpos - update the file offset for lseek
46+
* @file: file structure in question
47+
* @offset: file offset to seek to
48+
* @maxsize: maximum file size
49+
*
50+
* This is a low-level filesystem helper for updating the file offset to
51+
* the value specified by @offset if the given offset is valid and it is
52+
* not equal to the current file offset.
53+
*
54+
* Return the specified offset on success and -EINVAL on invalid offset.
55+
*/
56+
loff_t vfs_setpos(struct file *file, loff_t offset, loff_t maxsize)
4557
{
4658
if (offset < 0 && !unsigned_offsets(file))
4759
return -EINVAL;
@@ -54,6 +66,7 @@ static loff_t lseek_execute(struct file *file, loff_t offset, loff_t maxsize)
5466
}
5567
return offset;
5668
}
69+
EXPORT_SYMBOL(vfs_setpos);
5770

5871
/**
5972
* generic_file_llseek_size - generic llseek implementation for regular files
@@ -94,7 +107,7 @@ generic_file_llseek_size(struct file *file, loff_t offset, int whence,
94107
* like SEEK_SET.
95108
*/
96109
spin_lock(&file->f_lock);
97-
offset = lseek_execute(file, file->f_pos + offset, maxsize);
110+
offset = vfs_setpos(file, file->f_pos + offset, maxsize);
98111
spin_unlock(&file->f_lock);
99112
return offset;
100113
case SEEK_DATA:
@@ -116,7 +129,7 @@ generic_file_llseek_size(struct file *file, loff_t offset, int whence,
116129
break;
117130
}
118131

119-
return lseek_execute(file, offset, maxsize);
132+
return vfs_setpos(file, offset, maxsize);
120133
}
121134
EXPORT_SYMBOL(generic_file_llseek_size);
122135

fs/xfs/xfs_file.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1268,8 +1268,7 @@ xfs_seek_data(
12681268
}
12691269

12701270
out:
1271-
if (offset != file->f_pos)
1272-
file->f_pos = offset;
1271+
offset = vfs_setpos(file, offset, inode->i_sb->s_maxbytes);
12731272

12741273
out_unlock:
12751274
xfs_iunlock_map_shared(ip, lock);
@@ -1377,8 +1376,7 @@ xfs_seek_hole(
13771376
* situation in particular.
13781377
*/
13791378
offset = min_t(loff_t, offset, isize);
1380-
if (offset != file->f_pos)
1381-
file->f_pos = offset;
1379+
offset = vfs_setpos(file, offset, inode->i_sb->s_maxbytes);
13821380

13831381
out_unlock:
13841382
xfs_iunlock_map_shared(ip, lock);

include/linux/fs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2426,6 +2426,7 @@ extern void
24262426
file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping);
24272427
extern loff_t noop_llseek(struct file *file, loff_t offset, int whence);
24282428
extern loff_t no_llseek(struct file *file, loff_t offset, int whence);
2429+
extern loff_t vfs_setpos(struct file *file, loff_t offset, loff_t maxsize);
24292430
extern loff_t generic_file_llseek(struct file *file, loff_t offset, int whence);
24302431
extern loff_t generic_file_llseek_size(struct file *file, loff_t offset,
24312432
int whence, loff_t maxsize, loff_t eof);

mm/shmem.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1798,10 +1798,7 @@ static loff_t shmem_file_llseek(struct file *file, loff_t offset, int whence)
17981798
}
17991799
}
18001800

1801-
if (offset >= 0 && offset != file->f_pos) {
1802-
file->f_pos = offset;
1803-
file->f_version = 0;
1804-
}
1801+
offset = vfs_setpos(file, offset, MAX_LFS_FILESIZE);
18051802
mutex_unlock(&inode->i_mutex);
18061803
return offset;
18071804
}

0 commit comments

Comments
 (0)