From: Jie Liu <jeff.liu@xxxxxxxxxx> Consolidate lseek(2) SEEK_DATA/SEEK_HOLE according to the implementation of VFS lseek_execute(): - if end up with a negative offset, return EINVAL if file is not huge. - if end up with an offset larger than s_maxbytes, return EINVAL as well. - reset file version to 0 if end up with an offset that is not equal to the current file offset. Signed-off-by: Jie Liu <jeff.liu@xxxxxxxxxx> --- fs/xfs/xfs_file.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index a5f2042..dc42751 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -1270,8 +1270,19 @@ xfs_seek_data( } out: - if (offset != file->f_pos) + if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET)) { + error = EINVAL; + goto out_unlock; + } + if (offset > inode->i_sb->s_maxbytes) { + error = EINVAL; + goto out_unlock; + } + + if (offset != file->f_pos) { file->f_pos = offset; + file->f_version = 0; + } out_unlock: xfs_iunlock_map_shared(ip, lock); @@ -1372,6 +1383,15 @@ xfs_seek_hole( } out: + if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET)) { + error = EINVAL; + goto out_unlock; + } + if (offset > inode->i_sb->s_maxbytes) { + error = EINVAL; + goto out_unlock; + } + /* * At this point, we must have found a hole. However, the returned * offset may be bigger than the file size as it may be aligned to @@ -1379,8 +1399,10 @@ out: * situation in particular. */ offset = min_t(loff_t, offset, isize); - if (offset != file->f_pos) + if (offset != file->f_pos) { file->f_pos = offset; + file->f_version = 0; + } out_unlock: xfs_iunlock_map_shared(ip, lock); -- 1.7.9.5 _______________________________________________ xfs mailing list xfs@xxxxxxxxxxx http://oss.sgi.com/mailman/listinfo/xfs