162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * High-level sync()-related operations 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#include <linux/blkdev.h> 762306a36Sopenharmony_ci#include <linux/kernel.h> 862306a36Sopenharmony_ci#include <linux/file.h> 962306a36Sopenharmony_ci#include <linux/fs.h> 1062306a36Sopenharmony_ci#include <linux/slab.h> 1162306a36Sopenharmony_ci#include <linux/export.h> 1262306a36Sopenharmony_ci#include <linux/namei.h> 1362306a36Sopenharmony_ci#include <linux/sched.h> 1462306a36Sopenharmony_ci#include <linux/writeback.h> 1562306a36Sopenharmony_ci#include <linux/syscalls.h> 1662306a36Sopenharmony_ci#include <linux/linkage.h> 1762306a36Sopenharmony_ci#include <linux/pagemap.h> 1862306a36Sopenharmony_ci#include <linux/quotaops.h> 1962306a36Sopenharmony_ci#include <linux/backing-dev.h> 2062306a36Sopenharmony_ci#include "internal.h" 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#define VALID_FLAGS (SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| \ 2362306a36Sopenharmony_ci SYNC_FILE_RANGE_WAIT_AFTER) 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci/* 2662306a36Sopenharmony_ci * Write out and wait upon all dirty data associated with this 2762306a36Sopenharmony_ci * superblock. Filesystem data as well as the underlying block 2862306a36Sopenharmony_ci * device. Takes the superblock lock. 2962306a36Sopenharmony_ci */ 3062306a36Sopenharmony_ciint sync_filesystem(struct super_block *sb) 3162306a36Sopenharmony_ci{ 3262306a36Sopenharmony_ci int ret = 0; 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci /* 3562306a36Sopenharmony_ci * We need to be protected against the filesystem going from 3662306a36Sopenharmony_ci * r/o to r/w or vice versa. 3762306a36Sopenharmony_ci */ 3862306a36Sopenharmony_ci WARN_ON(!rwsem_is_locked(&sb->s_umount)); 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci /* 4162306a36Sopenharmony_ci * No point in syncing out anything if the filesystem is read-only. 4262306a36Sopenharmony_ci */ 4362306a36Sopenharmony_ci if (sb_rdonly(sb)) 4462306a36Sopenharmony_ci return 0; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci /* 4762306a36Sopenharmony_ci * Do the filesystem syncing work. For simple filesystems 4862306a36Sopenharmony_ci * writeback_inodes_sb(sb) just dirties buffers with inodes so we have 4962306a36Sopenharmony_ci * to submit I/O for these buffers via sync_blockdev(). This also 5062306a36Sopenharmony_ci * speeds up the wait == 1 case since in that case write_inode() 5162306a36Sopenharmony_ci * methods call sync_dirty_buffer() and thus effectively write one block 5262306a36Sopenharmony_ci * at a time. 5362306a36Sopenharmony_ci */ 5462306a36Sopenharmony_ci writeback_inodes_sb(sb, WB_REASON_SYNC); 5562306a36Sopenharmony_ci if (sb->s_op->sync_fs) { 5662306a36Sopenharmony_ci ret = sb->s_op->sync_fs(sb, 0); 5762306a36Sopenharmony_ci if (ret) 5862306a36Sopenharmony_ci return ret; 5962306a36Sopenharmony_ci } 6062306a36Sopenharmony_ci ret = sync_blockdev_nowait(sb->s_bdev); 6162306a36Sopenharmony_ci if (ret) 6262306a36Sopenharmony_ci return ret; 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci sync_inodes_sb(sb); 6562306a36Sopenharmony_ci if (sb->s_op->sync_fs) { 6662306a36Sopenharmony_ci ret = sb->s_op->sync_fs(sb, 1); 6762306a36Sopenharmony_ci if (ret) 6862306a36Sopenharmony_ci return ret; 6962306a36Sopenharmony_ci } 7062306a36Sopenharmony_ci return sync_blockdev(sb->s_bdev); 7162306a36Sopenharmony_ci} 7262306a36Sopenharmony_ciEXPORT_SYMBOL(sync_filesystem); 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_cistatic void sync_inodes_one_sb(struct super_block *sb, void *arg) 7562306a36Sopenharmony_ci{ 7662306a36Sopenharmony_ci if (!sb_rdonly(sb)) 7762306a36Sopenharmony_ci sync_inodes_sb(sb); 7862306a36Sopenharmony_ci} 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_cistatic void sync_fs_one_sb(struct super_block *sb, void *arg) 8162306a36Sopenharmony_ci{ 8262306a36Sopenharmony_ci if (!sb_rdonly(sb) && !(sb->s_iflags & SB_I_SKIP_SYNC) && 8362306a36Sopenharmony_ci sb->s_op->sync_fs) 8462306a36Sopenharmony_ci sb->s_op->sync_fs(sb, *(int *)arg); 8562306a36Sopenharmony_ci} 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci/* 8862306a36Sopenharmony_ci * Sync everything. We start by waking flusher threads so that most of 8962306a36Sopenharmony_ci * writeback runs on all devices in parallel. Then we sync all inodes reliably 9062306a36Sopenharmony_ci * which effectively also waits for all flusher threads to finish doing 9162306a36Sopenharmony_ci * writeback. At this point all data is on disk so metadata should be stable 9262306a36Sopenharmony_ci * and we tell filesystems to sync their metadata via ->sync_fs() calls. 9362306a36Sopenharmony_ci * Finally, we writeout all block devices because some filesystems (e.g. ext2) 9462306a36Sopenharmony_ci * just write metadata (such as inodes or bitmaps) to block device page cache 9562306a36Sopenharmony_ci * and do not sync it on their own in ->sync_fs(). 9662306a36Sopenharmony_ci */ 9762306a36Sopenharmony_civoid ksys_sync(void) 9862306a36Sopenharmony_ci{ 9962306a36Sopenharmony_ci int nowait = 0, wait = 1; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci wakeup_flusher_threads(WB_REASON_SYNC); 10262306a36Sopenharmony_ci iterate_supers(sync_inodes_one_sb, NULL); 10362306a36Sopenharmony_ci iterate_supers(sync_fs_one_sb, &nowait); 10462306a36Sopenharmony_ci iterate_supers(sync_fs_one_sb, &wait); 10562306a36Sopenharmony_ci sync_bdevs(false); 10662306a36Sopenharmony_ci sync_bdevs(true); 10762306a36Sopenharmony_ci if (unlikely(laptop_mode)) 10862306a36Sopenharmony_ci laptop_sync_completion(); 10962306a36Sopenharmony_ci} 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ciSYSCALL_DEFINE0(sync) 11262306a36Sopenharmony_ci{ 11362306a36Sopenharmony_ci ksys_sync(); 11462306a36Sopenharmony_ci return 0; 11562306a36Sopenharmony_ci} 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_cistatic void do_sync_work(struct work_struct *work) 11862306a36Sopenharmony_ci{ 11962306a36Sopenharmony_ci int nowait = 0; 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci /* 12262306a36Sopenharmony_ci * Sync twice to reduce the possibility we skipped some inodes / pages 12362306a36Sopenharmony_ci * because they were temporarily locked 12462306a36Sopenharmony_ci */ 12562306a36Sopenharmony_ci iterate_supers(sync_inodes_one_sb, &nowait); 12662306a36Sopenharmony_ci iterate_supers(sync_fs_one_sb, &nowait); 12762306a36Sopenharmony_ci sync_bdevs(false); 12862306a36Sopenharmony_ci iterate_supers(sync_inodes_one_sb, &nowait); 12962306a36Sopenharmony_ci iterate_supers(sync_fs_one_sb, &nowait); 13062306a36Sopenharmony_ci sync_bdevs(false); 13162306a36Sopenharmony_ci printk("Emergency Sync complete\n"); 13262306a36Sopenharmony_ci kfree(work); 13362306a36Sopenharmony_ci} 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_civoid emergency_sync(void) 13662306a36Sopenharmony_ci{ 13762306a36Sopenharmony_ci struct work_struct *work; 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci work = kmalloc(sizeof(*work), GFP_ATOMIC); 14062306a36Sopenharmony_ci if (work) { 14162306a36Sopenharmony_ci INIT_WORK(work, do_sync_work); 14262306a36Sopenharmony_ci schedule_work(work); 14362306a36Sopenharmony_ci } 14462306a36Sopenharmony_ci} 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci/* 14762306a36Sopenharmony_ci * sync a single super 14862306a36Sopenharmony_ci */ 14962306a36Sopenharmony_ciSYSCALL_DEFINE1(syncfs, int, fd) 15062306a36Sopenharmony_ci{ 15162306a36Sopenharmony_ci struct fd f = fdget(fd); 15262306a36Sopenharmony_ci struct super_block *sb; 15362306a36Sopenharmony_ci int ret, ret2; 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci if (!f.file) 15662306a36Sopenharmony_ci return -EBADF; 15762306a36Sopenharmony_ci sb = f.file->f_path.dentry->d_sb; 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci down_read(&sb->s_umount); 16062306a36Sopenharmony_ci ret = sync_filesystem(sb); 16162306a36Sopenharmony_ci up_read(&sb->s_umount); 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci ret2 = errseq_check_and_advance(&sb->s_wb_err, &f.file->f_sb_err); 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci fdput(f); 16662306a36Sopenharmony_ci return ret ? ret : ret2; 16762306a36Sopenharmony_ci} 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_ci/** 17062306a36Sopenharmony_ci * vfs_fsync_range - helper to sync a range of data & metadata to disk 17162306a36Sopenharmony_ci * @file: file to sync 17262306a36Sopenharmony_ci * @start: offset in bytes of the beginning of data range to sync 17362306a36Sopenharmony_ci * @end: offset in bytes of the end of data range (inclusive) 17462306a36Sopenharmony_ci * @datasync: perform only datasync 17562306a36Sopenharmony_ci * 17662306a36Sopenharmony_ci * Write back data in range @start..@end and metadata for @file to disk. If 17762306a36Sopenharmony_ci * @datasync is set only metadata needed to access modified file data is 17862306a36Sopenharmony_ci * written. 17962306a36Sopenharmony_ci */ 18062306a36Sopenharmony_ciint vfs_fsync_range(struct file *file, loff_t start, loff_t end, int datasync) 18162306a36Sopenharmony_ci{ 18262306a36Sopenharmony_ci struct inode *inode = file->f_mapping->host; 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci if (!file->f_op->fsync) 18562306a36Sopenharmony_ci return -EINVAL; 18662306a36Sopenharmony_ci if (!datasync && (inode->i_state & I_DIRTY_TIME)) 18762306a36Sopenharmony_ci mark_inode_dirty_sync(inode); 18862306a36Sopenharmony_ci return file->f_op->fsync(file, start, end, datasync); 18962306a36Sopenharmony_ci} 19062306a36Sopenharmony_ciEXPORT_SYMBOL(vfs_fsync_range); 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci/** 19362306a36Sopenharmony_ci * vfs_fsync - perform a fsync or fdatasync on a file 19462306a36Sopenharmony_ci * @file: file to sync 19562306a36Sopenharmony_ci * @datasync: only perform a fdatasync operation 19662306a36Sopenharmony_ci * 19762306a36Sopenharmony_ci * Write back data and metadata for @file to disk. If @datasync is 19862306a36Sopenharmony_ci * set only metadata needed to access modified file data is written. 19962306a36Sopenharmony_ci */ 20062306a36Sopenharmony_ciint vfs_fsync(struct file *file, int datasync) 20162306a36Sopenharmony_ci{ 20262306a36Sopenharmony_ci return vfs_fsync_range(file, 0, LLONG_MAX, datasync); 20362306a36Sopenharmony_ci} 20462306a36Sopenharmony_ciEXPORT_SYMBOL(vfs_fsync); 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_cistatic int do_fsync(unsigned int fd, int datasync) 20762306a36Sopenharmony_ci{ 20862306a36Sopenharmony_ci struct fd f = fdget(fd); 20962306a36Sopenharmony_ci int ret = -EBADF; 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci if (f.file) { 21262306a36Sopenharmony_ci ret = vfs_fsync(f.file, datasync); 21362306a36Sopenharmony_ci fdput(f); 21462306a36Sopenharmony_ci } 21562306a36Sopenharmony_ci return ret; 21662306a36Sopenharmony_ci} 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ciSYSCALL_DEFINE1(fsync, unsigned int, fd) 21962306a36Sopenharmony_ci{ 22062306a36Sopenharmony_ci return do_fsync(fd, 0); 22162306a36Sopenharmony_ci} 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ciSYSCALL_DEFINE1(fdatasync, unsigned int, fd) 22462306a36Sopenharmony_ci{ 22562306a36Sopenharmony_ci return do_fsync(fd, 1); 22662306a36Sopenharmony_ci} 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ciint sync_file_range(struct file *file, loff_t offset, loff_t nbytes, 22962306a36Sopenharmony_ci unsigned int flags) 23062306a36Sopenharmony_ci{ 23162306a36Sopenharmony_ci int ret; 23262306a36Sopenharmony_ci struct address_space *mapping; 23362306a36Sopenharmony_ci loff_t endbyte; /* inclusive */ 23462306a36Sopenharmony_ci umode_t i_mode; 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci ret = -EINVAL; 23762306a36Sopenharmony_ci if (flags & ~VALID_FLAGS) 23862306a36Sopenharmony_ci goto out; 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci endbyte = offset + nbytes; 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci if ((s64)offset < 0) 24362306a36Sopenharmony_ci goto out; 24462306a36Sopenharmony_ci if ((s64)endbyte < 0) 24562306a36Sopenharmony_ci goto out; 24662306a36Sopenharmony_ci if (endbyte < offset) 24762306a36Sopenharmony_ci goto out; 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci if (sizeof(pgoff_t) == 4) { 25062306a36Sopenharmony_ci if (offset >= (0x100000000ULL << PAGE_SHIFT)) { 25162306a36Sopenharmony_ci /* 25262306a36Sopenharmony_ci * The range starts outside a 32 bit machine's 25362306a36Sopenharmony_ci * pagecache addressing capabilities. Let it "succeed" 25462306a36Sopenharmony_ci */ 25562306a36Sopenharmony_ci ret = 0; 25662306a36Sopenharmony_ci goto out; 25762306a36Sopenharmony_ci } 25862306a36Sopenharmony_ci if (endbyte >= (0x100000000ULL << PAGE_SHIFT)) { 25962306a36Sopenharmony_ci /* 26062306a36Sopenharmony_ci * Out to EOF 26162306a36Sopenharmony_ci */ 26262306a36Sopenharmony_ci nbytes = 0; 26362306a36Sopenharmony_ci } 26462306a36Sopenharmony_ci } 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci if (nbytes == 0) 26762306a36Sopenharmony_ci endbyte = LLONG_MAX; 26862306a36Sopenharmony_ci else 26962306a36Sopenharmony_ci endbyte--; /* inclusive */ 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci i_mode = file_inode(file)->i_mode; 27262306a36Sopenharmony_ci ret = -ESPIPE; 27362306a36Sopenharmony_ci if (!S_ISREG(i_mode) && !S_ISBLK(i_mode) && !S_ISDIR(i_mode) && 27462306a36Sopenharmony_ci !S_ISLNK(i_mode)) 27562306a36Sopenharmony_ci goto out; 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci mapping = file->f_mapping; 27862306a36Sopenharmony_ci ret = 0; 27962306a36Sopenharmony_ci if (flags & SYNC_FILE_RANGE_WAIT_BEFORE) { 28062306a36Sopenharmony_ci ret = file_fdatawait_range(file, offset, endbyte); 28162306a36Sopenharmony_ci if (ret < 0) 28262306a36Sopenharmony_ci goto out; 28362306a36Sopenharmony_ci } 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci if (flags & SYNC_FILE_RANGE_WRITE) { 28662306a36Sopenharmony_ci int sync_mode = WB_SYNC_NONE; 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci if ((flags & SYNC_FILE_RANGE_WRITE_AND_WAIT) == 28962306a36Sopenharmony_ci SYNC_FILE_RANGE_WRITE_AND_WAIT) 29062306a36Sopenharmony_ci sync_mode = WB_SYNC_ALL; 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci ret = __filemap_fdatawrite_range(mapping, offset, endbyte, 29362306a36Sopenharmony_ci sync_mode); 29462306a36Sopenharmony_ci if (ret < 0) 29562306a36Sopenharmony_ci goto out; 29662306a36Sopenharmony_ci } 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_ci if (flags & SYNC_FILE_RANGE_WAIT_AFTER) 29962306a36Sopenharmony_ci ret = file_fdatawait_range(file, offset, endbyte); 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ciout: 30262306a36Sopenharmony_ci return ret; 30362306a36Sopenharmony_ci} 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_ci/* 30662306a36Sopenharmony_ci * ksys_sync_file_range() permits finely controlled syncing over a segment of 30762306a36Sopenharmony_ci * a file in the range offset .. (offset+nbytes-1) inclusive. If nbytes is 30862306a36Sopenharmony_ci * zero then ksys_sync_file_range() will operate from offset out to EOF. 30962306a36Sopenharmony_ci * 31062306a36Sopenharmony_ci * The flag bits are: 31162306a36Sopenharmony_ci * 31262306a36Sopenharmony_ci * SYNC_FILE_RANGE_WAIT_BEFORE: wait upon writeout of all pages in the range 31362306a36Sopenharmony_ci * before performing the write. 31462306a36Sopenharmony_ci * 31562306a36Sopenharmony_ci * SYNC_FILE_RANGE_WRITE: initiate writeout of all those dirty pages in the 31662306a36Sopenharmony_ci * range which are not presently under writeback. Note that this may block for 31762306a36Sopenharmony_ci * significant periods due to exhaustion of disk request structures. 31862306a36Sopenharmony_ci * 31962306a36Sopenharmony_ci * SYNC_FILE_RANGE_WAIT_AFTER: wait upon writeout of all pages in the range 32062306a36Sopenharmony_ci * after performing the write. 32162306a36Sopenharmony_ci * 32262306a36Sopenharmony_ci * Useful combinations of the flag bits are: 32362306a36Sopenharmony_ci * 32462306a36Sopenharmony_ci * SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE: ensures that all pages 32562306a36Sopenharmony_ci * in the range which were dirty on entry to ksys_sync_file_range() are placed 32662306a36Sopenharmony_ci * under writeout. This is a start-write-for-data-integrity operation. 32762306a36Sopenharmony_ci * 32862306a36Sopenharmony_ci * SYNC_FILE_RANGE_WRITE: start writeout of all dirty pages in the range which 32962306a36Sopenharmony_ci * are not presently under writeout. This is an asynchronous flush-to-disk 33062306a36Sopenharmony_ci * operation. Not suitable for data integrity operations. 33162306a36Sopenharmony_ci * 33262306a36Sopenharmony_ci * SYNC_FILE_RANGE_WAIT_BEFORE (or SYNC_FILE_RANGE_WAIT_AFTER): wait for 33362306a36Sopenharmony_ci * completion of writeout of all pages in the range. This will be used after an 33462306a36Sopenharmony_ci * earlier SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE operation to wait 33562306a36Sopenharmony_ci * for that operation to complete and to return the result. 33662306a36Sopenharmony_ci * 33762306a36Sopenharmony_ci * SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE|SYNC_FILE_RANGE_WAIT_AFTER 33862306a36Sopenharmony_ci * (a.k.a. SYNC_FILE_RANGE_WRITE_AND_WAIT): 33962306a36Sopenharmony_ci * a traditional sync() operation. This is a write-for-data-integrity operation 34062306a36Sopenharmony_ci * which will ensure that all pages in the range which were dirty on entry to 34162306a36Sopenharmony_ci * ksys_sync_file_range() are written to disk. It should be noted that disk 34262306a36Sopenharmony_ci * caches are not flushed by this call, so there are no guarantees here that the 34362306a36Sopenharmony_ci * data will be available on disk after a crash. 34462306a36Sopenharmony_ci * 34562306a36Sopenharmony_ci * 34662306a36Sopenharmony_ci * SYNC_FILE_RANGE_WAIT_BEFORE and SYNC_FILE_RANGE_WAIT_AFTER will detect any 34762306a36Sopenharmony_ci * I/O errors or ENOSPC conditions and will return those to the caller, after 34862306a36Sopenharmony_ci * clearing the EIO and ENOSPC flags in the address_space. 34962306a36Sopenharmony_ci * 35062306a36Sopenharmony_ci * It should be noted that none of these operations write out the file's 35162306a36Sopenharmony_ci * metadata. So unless the application is strictly performing overwrites of 35262306a36Sopenharmony_ci * already-instantiated disk blocks, there are no guarantees here that the data 35362306a36Sopenharmony_ci * will be available after a crash. 35462306a36Sopenharmony_ci */ 35562306a36Sopenharmony_ciint ksys_sync_file_range(int fd, loff_t offset, loff_t nbytes, 35662306a36Sopenharmony_ci unsigned int flags) 35762306a36Sopenharmony_ci{ 35862306a36Sopenharmony_ci int ret; 35962306a36Sopenharmony_ci struct fd f; 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_ci ret = -EBADF; 36262306a36Sopenharmony_ci f = fdget(fd); 36362306a36Sopenharmony_ci if (f.file) 36462306a36Sopenharmony_ci ret = sync_file_range(f.file, offset, nbytes, flags); 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci fdput(f); 36762306a36Sopenharmony_ci return ret; 36862306a36Sopenharmony_ci} 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_ciSYSCALL_DEFINE4(sync_file_range, int, fd, loff_t, offset, loff_t, nbytes, 37162306a36Sopenharmony_ci unsigned int, flags) 37262306a36Sopenharmony_ci{ 37362306a36Sopenharmony_ci return ksys_sync_file_range(fd, offset, nbytes, flags); 37462306a36Sopenharmony_ci} 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_ci#if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_SYNC_FILE_RANGE) 37762306a36Sopenharmony_ciCOMPAT_SYSCALL_DEFINE6(sync_file_range, int, fd, compat_arg_u64_dual(offset), 37862306a36Sopenharmony_ci compat_arg_u64_dual(nbytes), unsigned int, flags) 37962306a36Sopenharmony_ci{ 38062306a36Sopenharmony_ci return ksys_sync_file_range(fd, compat_arg_u64_glue(offset), 38162306a36Sopenharmony_ci compat_arg_u64_glue(nbytes), flags); 38262306a36Sopenharmony_ci} 38362306a36Sopenharmony_ci#endif 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ci/* It would be nice if people remember that not all the world's an i386 38662306a36Sopenharmony_ci when they introduce new system calls */ 38762306a36Sopenharmony_ciSYSCALL_DEFINE4(sync_file_range2, int, fd, unsigned int, flags, 38862306a36Sopenharmony_ci loff_t, offset, loff_t, nbytes) 38962306a36Sopenharmony_ci{ 39062306a36Sopenharmony_ci return ksys_sync_file_range(fd, offset, nbytes, flags); 39162306a36Sopenharmony_ci} 392