![Alexey Dobriyan](/assets/img/avatar_default.png)
Remove fs.h from mm.h. For this, 1) Uninline vma_wants_writenotify(). It's pretty huge anyway. 2) Add back fs.h or less bloated headers (err.h) to files that need it. As result, on x86_64 allyesconfig, fs.h dependencies cut down from 3929 files rebuilt down to 3444 (-12.3%). Cross-compile tested without regressions on my two usual configs and (sigh): alpha arm-mx1ads mips-bigsur powerpc-ebony alpha-allnoconfig arm-neponset mips-capcella powerpc-g5 alpha-defconfig arm-netwinder mips-cobalt powerpc-holly alpha-up arm-netx mips-db1000 powerpc-iseries arm arm-ns9xxx mips-db1100 powerpc-linkstation arm-assabet arm-omap_h2_1610 mips-db1200 powerpc-lite5200 arm-at91rm9200dk arm-onearm mips-db1500 powerpc-maple arm-at91rm9200ek arm-picotux200 mips-db1550 powerpc-mpc7448_hpc2 arm-at91sam9260ek arm-pleb mips-ddb5477 powerpc-mpc8272_ads arm-at91sam9261ek arm-pnx4008 mips-decstation powerpc-mpc8313_rdb arm-at91sam9263ek arm-pxa255-idp mips-e55 powerpc-mpc832x_mds arm-at91sam9rlek arm-realview mips-emma2rh powerpc-mpc832x_rdb arm-ateb9200 arm-realview-smp mips-excite powerpc-mpc834x_itx arm-badge4 arm-rpc mips-fulong powerpc-mpc834x_itxgp arm-carmeva arm-s3c2410 mips-ip22 powerpc-mpc834x_mds arm-cerfcube arm-shannon mips-ip27 powerpc-mpc836x_mds arm-clps7500 arm-shark mips-ip32 powerpc-mpc8540_ads arm-collie arm-simpad mips-jazz powerpc-mpc8544_ds arm-corgi arm-spitz mips-jmr3927 powerpc-mpc8560_ads arm-csb337 arm-trizeps4 mips-malta powerpc-mpc8568mds arm-csb637 arm-versatile mips-mipssim powerpc-mpc85xx_cds arm-ebsa110 i386 mips-mpc30x powerpc-mpc8641_hpcn arm-edb7211 i386-allnoconfig mips-msp71xx powerpc-mpc866_ads arm-em_x270 i386-defconfig mips-ocelot powerpc-mpc885_ads arm-ep93xx i386-up mips-pb1100 powerpc-pasemi arm-footbridge ia64 mips-pb1500 powerpc-pmac32 arm-fortunet ia64-allnoconfig mips-pb1550 powerpc-ppc64 arm-h3600 ia64-bigsur mips-pnx8550-jbs powerpc-prpmc2800 arm-h7201 ia64-defconfig mips-pnx8550-stb810 powerpc-ps3 arm-h7202 ia64-gensparse mips-qemu powerpc-pseries arm-hackkit ia64-sim mips-rbhma4200 powerpc-up arm-integrator ia64-sn2 mips-rbhma4500 s390 arm-iop13xx ia64-tiger mips-rm200 s390-allnoconfig arm-iop32x ia64-up mips-sb1250-swarm s390-defconfig arm-iop33x ia64-zx1 mips-sead s390-up arm-ixp2000 m68k mips-tb0219 sparc arm-ixp23xx m68k-amiga mips-tb0226 sparc-allnoconfig arm-ixp4xx m68k-apollo mips-tb0287 sparc-defconfig arm-jornada720 m68k-atari mips-workpad sparc-up arm-kafa m68k-bvme6000 mips-wrppmc sparc64 arm-kb9202 m68k-hp300 mips-yosemite sparc64-allnoconfig arm-ks8695 m68k-mac parisc sparc64-defconfig arm-lart m68k-mvme147 parisc-allnoconfig sparc64-up arm-lpd270 m68k-mvme16x parisc-defconfig um-x86_64 arm-lpd7a400 m68k-q40 parisc-up x86_64 arm-lpd7a404 m68k-sun3 powerpc x86_64-allnoconfig arm-lubbock m68k-sun3x powerpc-cell x86_64-defconfig arm-lusl7200 mips powerpc-celleb x86_64-up arm-mainstone mips-atlas powerpc-chrp32 Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
203 lines
4.9 KiB
C
203 lines
4.9 KiB
C
/*
|
|
* Implements HPUX syscalls.
|
|
*
|
|
* Copyright (C) 1999 Matthew Wilcox <willy with parisc-linux.org>
|
|
* Copyright (C) 2000 Michael Ang <mang with subcarrier.org>
|
|
* Copyright (C) 2000 John Marvin <jsm with parisc-linux.org>
|
|
* Copyright (C) 2000 Philipp Rumpf
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/mm.h>
|
|
#include <linux/fs.h>
|
|
#include <linux/sched.h>
|
|
#include <linux/file.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/ptrace.h>
|
|
#include <asm/errno.h>
|
|
#include <asm/uaccess.h>
|
|
|
|
int hpux_execve(struct pt_regs *regs)
|
|
{
|
|
int error;
|
|
char *filename;
|
|
|
|
filename = getname((char __user *) regs->gr[26]);
|
|
error = PTR_ERR(filename);
|
|
if (IS_ERR(filename))
|
|
goto out;
|
|
|
|
error = do_execve(filename, (char __user * __user *) regs->gr[25],
|
|
(char __user * __user *) regs->gr[24], regs);
|
|
|
|
if (error == 0) {
|
|
task_lock(current);
|
|
current->ptrace &= ~PT_DTRACE;
|
|
task_unlock(current);
|
|
}
|
|
putname(filename);
|
|
|
|
out:
|
|
return error;
|
|
}
|
|
|
|
struct hpux_dirent {
|
|
loff_t d_off;
|
|
ino_t d_ino;
|
|
short d_reclen;
|
|
short d_namlen;
|
|
char d_name[1];
|
|
};
|
|
|
|
struct getdents_callback {
|
|
struct hpux_dirent __user *current_dir;
|
|
struct hpux_dirent __user *previous;
|
|
int count;
|
|
int error;
|
|
};
|
|
|
|
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
|
|
|
|
static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
|
|
u64 ino, unsigned d_type)
|
|
{
|
|
struct hpux_dirent __user * dirent;
|
|
struct getdents_callback * buf = (struct getdents_callback *) __buf;
|
|
ino_t d_ino;
|
|
int reclen = ALIGN(NAME_OFFSET(dirent) + namlen + 1, sizeof(long));
|
|
|
|
buf->error = -EINVAL; /* only used if we fail.. */
|
|
if (reclen > buf->count)
|
|
return -EINVAL;
|
|
d_ino = ino;
|
|
if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
|
|
return -EOVERFLOW;
|
|
dirent = buf->previous;
|
|
if (dirent)
|
|
put_user(offset, &dirent->d_off);
|
|
dirent = buf->current_dir;
|
|
buf->previous = dirent;
|
|
put_user(d_ino, &dirent->d_ino);
|
|
put_user(reclen, &dirent->d_reclen);
|
|
put_user(namlen, &dirent->d_namlen);
|
|
copy_to_user(dirent->d_name, name, namlen);
|
|
put_user(0, dirent->d_name + namlen);
|
|
dirent = (void __user *)dirent + reclen;
|
|
buf->current_dir = dirent;
|
|
buf->count -= reclen;
|
|
return 0;
|
|
}
|
|
|
|
#undef NAME_OFFSET
|
|
|
|
int hpux_getdents(unsigned int fd, struct hpux_dirent __user *dirent, unsigned int count)
|
|
{
|
|
struct file * file;
|
|
struct hpux_dirent __user * lastdirent;
|
|
struct getdents_callback buf;
|
|
int error = -EBADF;
|
|
|
|
file = fget(fd);
|
|
if (!file)
|
|
goto out;
|
|
|
|
buf.current_dir = dirent;
|
|
buf.previous = NULL;
|
|
buf.count = count;
|
|
buf.error = 0;
|
|
|
|
error = vfs_readdir(file, filldir, &buf);
|
|
if (error < 0)
|
|
goto out_putf;
|
|
error = buf.error;
|
|
lastdirent = buf.previous;
|
|
if (lastdirent) {
|
|
put_user(file->f_pos, &lastdirent->d_off);
|
|
error = count - buf.count;
|
|
}
|
|
|
|
out_putf:
|
|
fput(file);
|
|
out:
|
|
return error;
|
|
}
|
|
|
|
int hpux_mount(const char *fs, const char *path, int mflag,
|
|
const char *fstype, const char *dataptr, int datalen)
|
|
{
|
|
return -ENOSYS;
|
|
}
|
|
|
|
static int cp_hpux_stat(struct kstat *stat, struct hpux_stat64 __user *statbuf)
|
|
{
|
|
struct hpux_stat64 tmp;
|
|
|
|
/* we probably want a different split here - is hpux 12:20? */
|
|
|
|
if (!new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev))
|
|
return -EOVERFLOW;
|
|
|
|
memset(&tmp, 0, sizeof(tmp));
|
|
tmp.st_dev = new_encode_dev(stat->dev);
|
|
tmp.st_ino = stat->ino;
|
|
tmp.st_mode = stat->mode;
|
|
tmp.st_nlink = stat->nlink;
|
|
tmp.st_uid = stat->uid;
|
|
tmp.st_gid = stat->gid;
|
|
tmp.st_rdev = new_encode_dev(stat->rdev);
|
|
tmp.st_size = stat->size;
|
|
tmp.st_atime = stat->atime.tv_sec;
|
|
tmp.st_mtime = stat->mtime.tv_sec;
|
|
tmp.st_ctime = stat->ctime.tv_sec;
|
|
tmp.st_blocks = stat->blocks;
|
|
tmp.st_blksize = stat->blksize;
|
|
return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
|
|
}
|
|
|
|
long hpux_stat64(char __user *filename, struct hpux_stat64 __user *statbuf)
|
|
{
|
|
struct kstat stat;
|
|
int error = vfs_stat(filename, &stat);
|
|
|
|
if (!error)
|
|
error = cp_hpux_stat(&stat, statbuf);
|
|
|
|
return error;
|
|
}
|
|
|
|
long hpux_fstat64(unsigned int fd, struct hpux_stat64 __user *statbuf)
|
|
{
|
|
struct kstat stat;
|
|
int error = vfs_fstat(fd, &stat);
|
|
|
|
if (!error)
|
|
error = cp_hpux_stat(&stat, statbuf);
|
|
|
|
return error;
|
|
}
|
|
|
|
long hpux_lstat64(char __user *filename, struct hpux_stat64 __user *statbuf)
|
|
{
|
|
struct kstat stat;
|
|
int error = vfs_lstat(filename, &stat);
|
|
|
|
if (!error)
|
|
error = cp_hpux_stat(&stat, statbuf);
|
|
|
|
return error;
|
|
}
|