SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len) { struct fd f = fdget(fd); int error = -EBADF; if (f.file) { error = do_fallocate(f.file, mode, offset, len); fdput(f); } return error; }
SYSCALL_DEFINE(fallocate)(int fd, int mode, loff_t offset, loff_t len) { struct file *file; int error = -EBADF; file = fget(fd); if (file) { error = do_fallocate(file, mode, offset, len); fput(file); } return error; }
static int pre_allocate(struct file *f) { int prealloc_size = 0; if (!f->f_op->fallocate || !(f->f_mode & FMODE_WRITE)) return 0; if (f->f_path.dentry->d_parent && !strcmp(f->f_path.dentry->d_parent->d_name.name, "htclog")) prealloc_size = get_logfile_prealloc_size(); if (prealloc_size) do_fallocate(f, FALLOC_FL_KEEP_SIZE, 0, prealloc_size); return 0; }
/* * This provides compatibility with legacy XFS pre-allocation ioctls * which predate the fallocate syscall. * * Only the l_start, l_len and l_whence fields of the 'struct space_resv' * are used here, rest are ignored. */ int ioctl_preallocate(struct file *filp, void __user *argp) { struct inode *inode = file_inode(filp); struct space_resv sr; if (copy_from_user(&sr, argp, sizeof(sr))) return -EFAULT; switch (sr.l_whence) { case SEEK_SET: break; case SEEK_CUR: sr.l_start += filp->f_pos; break; case SEEK_END: sr.l_start += i_size_read(inode); break; default: return -EINVAL; } return do_fallocate(filp, FALLOC_FL_KEEP_SIZE, sr.l_start, sr.l_len); }
/* Copy a file. If ofd < 0, copy_file unlinks and opens the "dest" file. * Otherwise, it just writes to and closes the provided file descriptor. * In either case, if --xattrs are being preserved, the dest file will * have its xattrs set from the source file. * * This is used in conjunction with the --temp-dir, --backup, and * --copy-dest options. */ int copy_file(const char *source, const char *dest, int ofd, mode_t mode) { int ifd; char buf[1024 * 8]; int len; /* Number of bytes read into `buf'. */ #ifdef PREALLOCATE_NEEDS_TRUNCATE OFF_T preallocated_len = 0, offset = 0; #endif if ((ifd = do_open(source, O_RDONLY, 0)) < 0) { int save_errno = errno; rsyserr(FERROR_XFER, errno, "open %s", full_fname(source)); errno = save_errno; return -1; } if (ofd < 0) { if (robust_unlink(dest) && errno != ENOENT) { int save_errno = errno; rsyserr(FERROR_XFER, errno, "unlink %s", full_fname(dest)); errno = save_errno; return -1; } #ifdef SUPPORT_XATTRS if (preserve_xattrs) mode |= S_IWUSR; #endif mode &= INITACCESSPERMS; if ((ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode)) < 0) { int save_errno = errno; rsyserr(FERROR_XFER, save_errno, "open %s", full_fname(dest)); close(ifd); errno = save_errno; return -1; } } #ifdef SUPPORT_PREALLOCATION if (preallocate_files) { STRUCT_STAT srcst; /* Try to preallocate enough space for file's eventual length. Can * reduce fragmentation on filesystems like ext4, xfs, and NTFS. */ if (do_fstat(ifd, &srcst) < 0) rsyserr(FWARNING, errno, "fstat %s", full_fname(source)); else if (srcst.st_size > 0) { if (do_fallocate(ofd, 0, srcst.st_size) == 0) { #ifdef PREALLOCATE_NEEDS_TRUNCATE preallocated_len = srcst.st_size; #endif } else rsyserr(FWARNING, errno, "do_fallocate %s", full_fname(dest)); } } #endif while ((len = safe_read(ifd, buf, sizeof buf)) > 0) { if (full_write(ofd, buf, len) < 0) { int save_errno = errno; rsyserr(FERROR_XFER, errno, "write %s", full_fname(dest)); close(ifd); close(ofd); errno = save_errno; return -1; } #ifdef PREALLOCATE_NEEDS_TRUNCATE offset += len; #endif } if (len < 0) { int save_errno = errno; rsyserr(FERROR_XFER, errno, "read %s", full_fname(source)); close(ifd); close(ofd); errno = save_errno; return -1; } if (close(ifd) < 0) { rsyserr(FWARNING, errno, "close failed on %s", full_fname(source)); } #ifdef PREALLOCATE_NEEDS_TRUNCATE /* Source file might have shrunk since we fstatted it. * Cut off any extra preallocated zeros from dest file. */ if (offset < preallocated_len && do_ftruncate(ofd, offset) < 0) { /* If we fail to truncate, the dest file may be wrong, so we * must trigger the "partial transfer" error. */ rsyserr(FERROR_XFER, errno, "ftruncate %s", full_fname(dest)); } #endif if (close(ofd) < 0) { int save_errno = errno; rsyserr(FERROR_XFER, errno, "close failed on %s", full_fname(dest)); errno = save_errno; return -1; } #ifdef SUPPORT_XATTRS if (preserve_xattrs) copy_xattrs(source, dest); #endif return 0; }