mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-06 06:21:31 +00:00
fs: Add new pre-allocation ioctls to vfs for compatibility with legacy xfs ioctls
This patch adds ioctls to vfs for compatibility with legacy XFS pre-allocation ioctls (XFS_IOC_*RESVP*). The implementation effectively invokes sys_fallocate for the new ioctls. Also handles the compat_ioctl case. Note: These legacy ioctls are also implemented by OCFS2. [AV: folded fixes from hch] Signed-off-by: Ankit Jain <me@ankitjain.org> Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
01c031945f
commit
3e63cbb1ef
5 changed files with 139 additions and 29 deletions
58
fs/open.c
58
fs/open.c
|
@ -378,63 +378,63 @@ SYSCALL_ALIAS(sys_ftruncate64, SyS_ftruncate64);
|
|||
#endif
|
||||
#endif /* BITS_PER_LONG == 32 */
|
||||
|
||||
SYSCALL_DEFINE(fallocate)(int fd, int mode, loff_t offset, loff_t len)
|
||||
|
||||
int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
|
||||
{
|
||||
struct file *file;
|
||||
struct inode *inode;
|
||||
long ret = -EINVAL;
|
||||
struct inode *inode = file->f_path.dentry->d_inode;
|
||||
long ret;
|
||||
|
||||
if (offset < 0 || len <= 0)
|
||||
goto out;
|
||||
return -EINVAL;
|
||||
|
||||
/* Return error if mode is not supported */
|
||||
ret = -EOPNOTSUPP;
|
||||
if (mode && !(mode & FALLOC_FL_KEEP_SIZE))
|
||||
goto out;
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ret = -EBADF;
|
||||
file = fget(fd);
|
||||
if (!file)
|
||||
goto out;
|
||||
if (!(file->f_mode & FMODE_WRITE))
|
||||
goto out_fput;
|
||||
return -EBADF;
|
||||
/*
|
||||
* Revalidate the write permissions, in case security policy has
|
||||
* changed since the files were opened.
|
||||
*/
|
||||
ret = security_file_permission(file, MAY_WRITE);
|
||||
if (ret)
|
||||
goto out_fput;
|
||||
return ret;
|
||||
|
||||
inode = file->f_path.dentry->d_inode;
|
||||
|
||||
ret = -ESPIPE;
|
||||
if (S_ISFIFO(inode->i_mode))
|
||||
goto out_fput;
|
||||
return -ESPIPE;
|
||||
|
||||
ret = -ENODEV;
|
||||
/*
|
||||
* Let individual file system decide if it supports preallocation
|
||||
* for directories or not.
|
||||
*/
|
||||
if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode))
|
||||
goto out_fput;
|
||||
return -ENODEV;
|
||||
|
||||
ret = -EFBIG;
|
||||
/* Check for wrap through zero too */
|
||||
if (((offset + len) > inode->i_sb->s_maxbytes) || ((offset + len) < 0))
|
||||
goto out_fput;
|
||||
return -EFBIG;
|
||||
|
||||
if (inode->i_op->fallocate)
|
||||
ret = inode->i_op->fallocate(inode, mode, offset, len);
|
||||
else
|
||||
ret = -EOPNOTSUPP;
|
||||
if (!inode->i_op->fallocate)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
out_fput:
|
||||
fput(file);
|
||||
out:
|
||||
return ret;
|
||||
return inode->i_op->fallocate(inode, mode, offset, len);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
|
||||
asmlinkage long SyS_fallocate(long fd, long mode, loff_t offset, loff_t len)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue