Beispiel #1
0
asmlinkage int sys_ftruncate64(unsigned int fd, unsigned int high,
			       unsigned int low)
{
	if ((int)high < 0)
		return -EINVAL;
	return sys_ftruncate(fd, ((long) high << 32) | low);
}
Beispiel #2
0
asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned long low)
{
	if ((int)high < 0)
		return -EINVAL;
	else
		return sys_ftruncate(fd, (high << 32) | low);
}
Beispiel #3
0
static int
fd_truncate(struct lwp *l, int fd, struct flock *flp, register_t *retval)
{
	file_t *fp;
	off_t start, length;
	vnode_t *vp;
	struct vattr vattr;
	int error;
	struct sys_ftruncate_args ft;

	/*
	 * We only support truncating the file.
	 */
	if ((fp = fd_getfile(fd)) == NULL)
		return EBADF;

	vp = fp->f_data;
	if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) {
		fd_putfile(fd);
		return ESPIPE;
	}
	if ((error = VOP_GETATTR(vp, &vattr, l->l_cred)) != 0) {
		fd_putfile(fd);
		return error;
	}

	length = vattr.va_size;

	switch (flp->l_whence) {
	case SEEK_CUR:
		start = fp->f_offset + flp->l_start;
		break;

	case SEEK_END:
		start = flp->l_start + length;
		break;

	case SEEK_SET:
		start = flp->l_start;
		break;

	default:
		fd_putfile(fd);
		return EINVAL;
	}

	if (start + flp->l_len < length) {
		/* We don't support free'ing in the middle of the file */
		fd_putfile(fd);
		return EINVAL;
	}

	SCARG(&ft, fd) = fd;
	SCARG(&ft, length) = start;

	error = sys_ftruncate(l, &ft, retval);
	fd_putfile(fd);
	return error;
}
int
compat_43_netbsd32_oftruncate(struct lwp *l, const struct compat_43_netbsd32_oftruncate_args *uap, register_t *retval)
{
	/* {
		syscallarg(int) fd;
		syscallarg(netbsd32_long) length;
	} */
	struct sys_ftruncate_args ua;

	NETBSD32TO64_UAP(fd);
	NETBSD32TO64_UAP(length);
	return (sys_ftruncate(l, &ua, retval));
}
Beispiel #5
0
static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T len)
{
	SMB_STRUCT_STAT st;
	SMB_OFF_T currpos = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR);
	unsigned char zero_space[4096];
	SMB_OFF_T space_to_write;

	if (currpos == -1)
		return -1;

	if (SMB_VFS_FSTAT(fsp, fd, &st) == -1)
		return -1;

	space_to_write = len - st.st_size;

#ifdef S_ISFIFO
	if (S_ISFIFO(st.st_mode))
		return 0;
#endif

	if (st.st_size == len)
		return 0;

	/* Shrink - just ftruncate. */
	if (st.st_size > len)
		return sys_ftruncate(fd, len);

	/* Write out the real space on disk. */
	if (SMB_VFS_LSEEK(fsp, fd, st.st_size, SEEK_SET) != st.st_size)
		return -1;

	space_to_write = len - st.st_size;

	memset(zero_space, '\0', sizeof(zero_space));
	while ( space_to_write > 0) {
		SMB_OFF_T retlen;
		SMB_OFF_T current_len_to_write = MIN(sizeof(zero_space),space_to_write);

		retlen = SMB_VFS_WRITE(fsp,fsp->fh->fd,(char *)zero_space,current_len_to_write);
		if (retlen <= 0)
			return -1;

		space_to_write -= retlen;
	}

	/* Seek to where we were */
	if (SMB_VFS_LSEEK(fsp, fd, currpos, SEEK_SET) != currpos)
		return -1;

	return 0;
}
int
linux32_sys_ftruncate64(struct lwp *l, const struct linux32_sys_ftruncate64_args *uap, register_t *retval)
{
	/* {
		syscallarg(unsigned int) fd;
		syscallarg(off_t) length;
	} */
	struct sys_ftruncate_args ua;

	/* Linux doesn't have the 'pad' pseudo-parameter */
	NETBSD32TO64_UAP(fd);
	SCARG(&ua, PAD) = 0;
	SCARG(&ua, length) = ((off_t)SCARG(uap, lenhi) << 32) + SCARG(uap, lenlo);
	return sys_ftruncate(l, &ua, retval);
}
Beispiel #7
0
int
linux_sys_ftruncate64(struct lwp *l, const struct linux_sys_ftruncate64_args *uap, register_t *retval)
{
	/* {
		syscallarg(unsigned int) fd;
		syscallarg(off_t) length;
	} */
	struct sys_ftruncate_args ta;

	/* Linux doesn't have the 'pad' pseudo-parameter */
	SCARG(&ta, fd) = SCARG(uap, fd);
	SCARG(&ta, pad) = 0;
	SCARG(&ta, length) = SCARG(uap, length);

	return sys_ftruncate(l, &ta, retval);
}
/* ARGSUSED */
int
compat_43_sys_ftruncate(struct lwp *l, const struct compat_43_sys_ftruncate_args *uap, register_t *retval)
{
	/* {
		syscallarg(int) fd;
		syscallarg(long) length;
	} */
	struct sys_ftruncate_args /* {
		syscallarg(int) fd;
		syscallarg(int) pad;
		syscallarg(off_t) length;
	} */ nuap;

	SCARG(&nuap, fd) = SCARG(uap, fd);
	SCARG(&nuap, length) = SCARG(uap, length);
	return (sys_ftruncate(l, &nuap, retval));
}
Beispiel #9
0
asmlinkage long
sys32_ftruncate64(unsigned int fd, unsigned long offset_low, unsigned long offset_high)
{
       return sys_ftruncate(fd, ((loff_t) offset_high << 32) | offset_low);
}
Beispiel #10
0
long compat_sys_ftruncate64(unsigned int fd, u32 dummy, u32 low, u32 high)
{
	return sys_ftruncate(fd, ((loff_t)high << 32) | low);
}
Beispiel #11
0
asmlinkage int compat_sys_ftruncate64(unsigned int fd, u32 reg4, unsigned long high,
				 unsigned long low)
{
	return sys_ftruncate(fd, (high << 32) | low);
}
Beispiel #12
0
int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T len)
{
	int result = -1;
	SMB_STRUCT_STAT st;
	char c = 0;
	SMB_OFF_T currpos;

	START_PROFILE(syscall_ftruncate);

	if (lp_strict_allocate(SNUM(fsp->conn))) {
		result = strict_allocate_ftruncate(handle, fsp, fd, len);
		END_PROFILE(syscall_ftruncate);
		return result;
	}

	/* we used to just check HAVE_FTRUNCATE_EXTEND and only use
	   sys_ftruncate if the system supports it. Then I discovered that
	   you can have some filesystems that support ftruncate
	   expansion and some that don't! On Linux fat can't do
	   ftruncate extend but ext2 can. */

	result = sys_ftruncate(fd, len);
	if (result == 0)
		goto done;

	/* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
	   extend a file with ftruncate. Provide alternate implementation
	   for this */
	currpos = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR);
	if (currpos == -1) {
		goto done;
	}

	/* Do an fstat to see if the file is longer than the requested
	   size in which case the ftruncate above should have
	   succeeded or shorter, in which case seek to len - 1 and
	   write 1 byte of zero */
	if (SMB_VFS_FSTAT(fsp, fd, &st) == -1) {
		goto done;
	}

#ifdef S_ISFIFO
	if (S_ISFIFO(st.st_mode)) {
		result = 0;
		goto done;
	}
#endif

	if (st.st_size == len) {
		result = 0;
		goto done;
	}

	if (st.st_size > len) {
		/* the sys_ftruncate should have worked */
		goto done;
	}

	if (SMB_VFS_LSEEK(fsp, fd, len-1, SEEK_SET) != len -1)
		goto done;

	if (SMB_VFS_WRITE(fsp, fd, &c, 1)!=1)
		goto done;

	/* Seek to where we were */
	if (SMB_VFS_LSEEK(fsp, fd, currpos, SEEK_SET) != currpos)
		goto done;
	result = 0;

  done:

	END_PROFILE(syscall_ftruncate);
	return result;
}
long compat_sys_ftruncate(int fd, u32 length)
{
	/* sign extend length */
	return sys_ftruncate(fd, (int)length);
}
Beispiel #14
0
int svr4_fcntl(int fd, unsigned int cmd, unsigned long arg)
{
	int rval;

	switch (cmd) {
	case 0: /* F_DUPFD */
	case 1: /* F_GETFD */
	case 2: /* F_SETFD */
		return sys_fcntl(fd, cmd, arg);
	case 3: /* F_GETFL */
		rval = sys_fcntl(fd, cmd, arg);
		return map_flags(rval, fl_linux_to_svr4);
	case 4: /* F_SETFL */
		arg = map_flags(arg, fl_svr4_to_linux);
		return sys_fcntl(fd, cmd, arg);
	case 14: /* F_GETLK SVR4 */
		cmd = 5;
		/*FALLTHROUGH*/
	case 5: /* F_GETLK */
	case 6: /* F_SETLK */
	case 7: /* F_SETLKW */
		return svr4_fcntl_flock(fd, cmd, arg);
	case 10: /* F_ALLOCSP */
		/* Extend allocation for specified portion of file. */
		return 0;
	case 11: /* F_FREESP */
		/* Free a portion of a file. */
		return 0;

	/*
	 * These are intended to support the Xenix chsize() and
	 * rdchk() system calls. I don't know if these may be
	 * generated by applications or not.
	 */
	case 0x6000: /* F_CHSIZE */
		return sys_ftruncate(fd, arg);
	case 0x6001: /* F_RDCHK */
	    {
		mm_segment_t fs;
		int nbytes;
 
		fs = get_fs();
		set_fs(get_ds());
		rval = sys_ioctl(fd, FIONREAD, &nbytes);
		set_fs(fs);

		if (rval < 0)
			return rval;
		return (nbytes ? 1 : 0);
	    }

	case  8: /* F_CHKFL */
	    /*FALLTHROUGH*/

	/*
	 * These are made from the Xenix locking() system call.
	 * According to available documentation these would
	 * never be generated by an application - only by the
	 * kernel Xenix support.
	 */
	case 0x6300: /* F_LK_UNLCK */
	case 0x7200: /* F_LK_LOCK */
	case 0x6200: /* F_LK_NBLCK */
	case 0x7100: /* F_LK_RLCK */
	case 0x6100: /* F_LK_NBRLCK */
	    /*FALLTHROUGH*/

	default:
		abi_trace(ABI_TRACE_API,
			"unsupported fcntl 0x%x, arg 0x%lx\n", cmd, arg);
		return -EINVAL;
	}
}
Beispiel #15
0
long compat_sys_ftruncate(int fd, u32 length)
{
	
	return sys_ftruncate(fd, (int)length);
}
Beispiel #16
0
COMPAT_SYSCALL_DEFINE4(ftruncate64, unsigned int, fd, u32, dummy,
                       u32, low, u32, high)
{
	return sys_ftruncate(fd, ((loff_t)high << 32) | low);
}