@@ -126,7 +126,7 @@ int vfs_truncate(const struct path *path, loff_t length)
126126}
127127EXPORT_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
152152SYSCALL_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
158158COMPAT_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
211209SYSCALL_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
217215COMPAT_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
225223SYSCALL_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
230228SYSCALL_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,
245243COMPAT_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
0 commit comments