Skip to content

Commit d37d7fc

Browse files
author
Fox Snowpatch
committed
1 parent 4f37907 commit d37d7fc

10 files changed

Lines changed: 32 additions & 44 deletions

File tree

arch/arm64/kernel/sys32.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ COMPAT_SYSCALL_DEFINE4(aarch32_truncate64, const char __user *, pathname,
8989
COMPAT_SYSCALL_DEFINE4(aarch32_ftruncate64, unsigned int, fd, u32, __pad,
9090
arg_u32p(length))
9191
{
92-
return ksys_ftruncate(fd, arg_u64(length));
92+
return ksys_ftruncate(fd, arg_u64(length), FTRUNCATE_LFS);
9393
}
9494

9595
COMPAT_SYSCALL_DEFINE5(aarch32_readahead, int, fd, u32, __pad,

arch/mips/kernel/linux32.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ SYSCALL_DEFINE4(32_truncate64, const char __user *, path,
6060
SYSCALL_DEFINE4(32_ftruncate64, unsigned long, fd, unsigned long, __dummy,
6161
unsigned long, a2, unsigned long, a3)
6262
{
63-
return ksys_ftruncate(fd, merge_64(a2, a3));
63+
return ksys_ftruncate(fd, merge_64(a2, a3), FTRUNCATE_LFS);
6464
}
6565

6666
SYSCALL_DEFINE5(32_llseek, unsigned int, fd, unsigned int, offset_high,

arch/parisc/kernel/sys_parisc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ asmlinkage long parisc_truncate64(const char __user * path,
216216
asmlinkage long parisc_ftruncate64(unsigned int fd,
217217
unsigned int high, unsigned int low)
218218
{
219-
return ksys_ftruncate(fd, (long)high << 32 | low);
219+
return ksys_ftruncate(fd, (long)high << 32 | low, FTRUNCATE_LFS);
220220
}
221221

222222
/* stubs for the benefit of the syscall_table since truncate64 and truncate
@@ -227,7 +227,7 @@ asmlinkage long sys_truncate64(const char __user * path, unsigned long length)
227227
}
228228
asmlinkage long sys_ftruncate64(unsigned int fd, unsigned long length)
229229
{
230-
return ksys_ftruncate(fd, length);
230+
return ksys_ftruncate(fd, length, FTRUNCATE_LFS);
231231
}
232232
asmlinkage long sys_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg)
233233
{

arch/powerpc/kernel/sys_ppc32.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ PPC32_SYSCALL_DEFINE4(ppc_ftruncate64,
101101
unsigned int, fd, u32, reg4,
102102
unsigned long, len1, unsigned long, len2)
103103
{
104-
return ksys_ftruncate(fd, merge_64(len1, len2));
104+
return ksys_ftruncate(fd, merge_64(len1, len2), FTRUNCATE_LFS);
105105
}
106106

107107
PPC32_SYSCALL_DEFINE6(ppc32_fadvise64,

arch/sparc/kernel/sys_sparc32.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ COMPAT_SYSCALL_DEFINE3(truncate64, const char __user *, path, u32, high, u32, lo
5858

5959
COMPAT_SYSCALL_DEFINE3(ftruncate64, unsigned int, fd, u32, high, u32, low)
6060
{
61-
return ksys_ftruncate(fd, ((u64)high << 32) | low);
61+
return ksys_ftruncate(fd, ((u64)high << 32) | low, FTRUNCATE_LFS);
6262
}
6363

6464
static int cp_compat_stat64(struct kstat *stat,

arch/x86/kernel/sys_ia32.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ SYSCALL_DEFINE3(ia32_truncate64, const char __user *, filename,
6161
SYSCALL_DEFINE3(ia32_ftruncate64, unsigned int, fd,
6262
unsigned long, offset_low, unsigned long, offset_high)
6363
{
64-
return ksys_ftruncate(fd, ((loff_t) offset_high << 32) | offset_low);
64+
return ksys_ftruncate(fd, ((loff_t) offset_high << 32) | offset_low,
65+
FTRUNCATE_LFS);
6566
}
6667

6768
/* warning: next two assume little endian */

fs/internal.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,7 @@ extern struct open_how build_open_how(int flags, umode_t mode);
198198
extern int build_open_flags(const struct open_how *how, struct open_flags *op);
199199
struct file *file_close_fd_locked(struct files_struct *files, unsigned fd);
200200

201-
int do_ftruncate(struct file *file, loff_t length, int small);
202-
int do_sys_ftruncate(unsigned int fd, loff_t length, int small);
201+
int do_ftruncate(struct file *file, loff_t length, unsigned int flags);
203202
int chmod_common(const struct path *path, umode_t mode);
204203
int do_fchownat(int dfd, const char __user *filename, uid_t user, gid_t group,
205204
int flag);

fs/open.c

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ int vfs_truncate(const struct path *path, loff_t length)
126126
}
127127
EXPORT_SYMBOL_GPL(vfs_truncate);
128128

129-
int do_sys_truncate(const char __user *pathname, loff_t length)
129+
int ksys_truncate(const char __user *pathname, loff_t length)
130130
{
131131
unsigned int lookup_flags = LOOKUP_FOLLOW;
132132
struct path path;
@@ -151,33 +151,31 @@ int do_sys_truncate(const char __user *pathname, loff_t length)
151151

152152
SYSCALL_DEFINE2(truncate, const char __user *, path, long, length)
153153
{
154-
return do_sys_truncate(path, length);
154+
return ksys_truncate(path, length);
155155
}
156156

157157
#ifdef CONFIG_COMPAT
158158
COMPAT_SYSCALL_DEFINE2(truncate, const char __user *, path, compat_off_t, length)
159159
{
160-
return do_sys_truncate(path, length);
160+
return ksys_truncate(path, length);
161161
}
162162
#endif
163163

164-
int do_ftruncate(struct file *file, loff_t length, int small)
164+
int do_ftruncate(struct file *file, loff_t length, unsigned int flags)
165165
{
166-
struct inode *inode;
167-
struct dentry *dentry;
166+
struct dentry *dentry = file->f_path.dentry;
167+
struct inode *inode = dentry->d_inode;
168168
int error;
169169

170-
/* explicitly opened as large or we are on 64-bit box */
171-
if (file->f_flags & O_LARGEFILE)
172-
small = 0;
173-
174-
dentry = file->f_path.dentry;
175-
inode = dentry->d_inode;
176170
if (!S_ISREG(inode->i_mode) || !(file->f_mode & FMODE_WRITE))
177171
return -EINVAL;
178172

179-
/* Cannot ftruncate over 2^31 bytes without large file support */
180-
if (small && length > MAX_NON_LFS)
173+
/*
174+
* Cannot ftruncate over 2^31 bytes without large file support, either
175+
* through opening with O_LARGEFILE or by using ftruncate64().
176+
*/
177+
if (length > MAX_NON_LFS &&
178+
!(file->f_flags & O_LARGEFILE) && !(flags & FTRUNCATE_LFS))
181179
return -EINVAL;
182180

183181
/* Check IS_APPEND on real upper inode */
@@ -197,39 +195,39 @@ int do_ftruncate(struct file *file, loff_t length, int small)
197195
ATTR_MTIME | ATTR_CTIME, file);
198196
}
199197

200-
int do_sys_ftruncate(unsigned int fd, loff_t length, int small)
198+
int ksys_ftruncate(unsigned int fd, loff_t length, unsigned int flags)
201199
{
202200
if (length < 0)
203201
return -EINVAL;
204202
CLASS(fd, f)(fd);
205203
if (fd_empty(f))
206204
return -EBADF;
207205

208-
return do_ftruncate(fd_file(f), length, small);
206+
return do_ftruncate(fd_file(f), length, flags);
209207
}
210208

211209
SYSCALL_DEFINE2(ftruncate, unsigned int, fd, off_t, length)
212210
{
213-
return do_sys_ftruncate(fd, length, 1);
211+
return ksys_ftruncate(fd, length, 0);
214212
}
215213

216214
#ifdef CONFIG_COMPAT
217215
COMPAT_SYSCALL_DEFINE2(ftruncate, unsigned int, fd, compat_off_t, length)
218216
{
219-
return do_sys_ftruncate(fd, length, 1);
217+
return ksys_ftruncate(fd, length, 0);
220218
}
221219
#endif
222220

223221
/* LFS versions of truncate are only needed on 32 bit machines */
224222
#if BITS_PER_LONG == 32
225223
SYSCALL_DEFINE2(truncate64, const char __user *, path, loff_t, length)
226224
{
227-
return do_sys_truncate(path, length);
225+
return ksys_truncate(path, length);
228226
}
229227

230228
SYSCALL_DEFINE2(ftruncate64, unsigned int, fd, loff_t, length)
231229
{
232-
return do_sys_ftruncate(fd, length, 0);
230+
return ksys_ftruncate(fd, length, FTRUNCATE_LFS);
233231
}
234232
#endif /* BITS_PER_LONG == 32 */
235233

@@ -245,7 +243,7 @@ COMPAT_SYSCALL_DEFINE3(truncate64, const char __user *, pathname,
245243
COMPAT_SYSCALL_DEFINE3(ftruncate64, unsigned int, fd,
246244
compat_arg_u64_dual(length))
247245
{
248-
return ksys_ftruncate(fd, compat_arg_u64_glue(length));
246+
return ksys_ftruncate(fd, compat_arg_u64_glue(length), FTRUNCATE_LFS);
249247
}
250248
#endif
251249

include/linux/syscalls.h

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,19 +1283,9 @@ static inline long ksys_lchown(const char __user *filename, uid_t user,
12831283
AT_SYMLINK_NOFOLLOW);
12841284
}
12851285

1286-
int do_sys_ftruncate(unsigned int fd, loff_t length, int small);
1287-
1288-
static inline long ksys_ftruncate(unsigned int fd, loff_t length)
1289-
{
1290-
return do_sys_ftruncate(fd, length, 1);
1291-
}
1292-
1293-
int do_sys_truncate(const char __user *pathname, loff_t length);
1294-
1295-
static inline long ksys_truncate(const char __user *pathname, loff_t length)
1296-
{
1297-
return do_sys_truncate(pathname, length);
1298-
}
1286+
#define FTRUNCATE_LFS (1u << 0) /* allow truncating > 32-bit */
1287+
int ksys_ftruncate(unsigned int fd, loff_t length, unsigned int flags);
1288+
int ksys_truncate(const char __user *pathname, loff_t length);
12991289

13001290
static inline unsigned int ksys_personality(unsigned int personality)
13011291
{

io_uring/truncate.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ int io_ftruncate(struct io_kiocb *req, unsigned int issue_flags)
4141

4242
WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK);
4343

44-
ret = do_ftruncate(req->file, ft->len, 1);
44+
ret = do_ftruncate(req->file, ft->len, 0);
4545

4646
io_req_set_res(req, ret, 0);
4747
return IOU_COMPLETE;

0 commit comments

Comments
 (0)