sysirix.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:51k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * sysirix.c: IRIX system call emulation.
  3.  *
  4.  * Copyright (C) 1996 David S. Miller
  5.  * Copyright (C) 1997 Miguel de Icaza
  6.  * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle
  7.  */
  8. #include <linux/kernel.h>
  9. #include <linux/sched.h>
  10. #include <linux/pagemap.h>
  11. #include <linux/mm.h>
  12. #include <linux/mman.h>
  13. #include <linux/slab.h>
  14. #include <linux/swap.h>
  15. #include <linux/errno.h>
  16. #include <linux/timex.h>
  17. #include <linux/times.h>
  18. #include <linux/elf.h>
  19. #include <linux/msg.h>
  20. #include <linux/shm.h>
  21. #include <linux/smp.h>
  22. #include <linux/smp_lock.h>
  23. #include <linux/utsname.h>
  24. #include <linux/file.h>
  25. #include <asm/ptrace.h>
  26. #include <asm/page.h>
  27. #include <asm/pgalloc.h>
  28. #include <asm/uaccess.h>
  29. #include <asm/inventory.h>
  30. /* 2,191 lines of complete and utter shit coming up... */
  31. extern int max_threads;
  32. /* The sysmp commands supported thus far. */
  33. #define MP_NPROCS        1 /* # processor in complex */
  34. #define MP_NAPROCS       2 /* # active processors in complex */
  35. #define MP_PGSIZE            14 /* Return system page size in v1. */
  36. asmlinkage int irix_sysmp(struct pt_regs *regs)
  37. {
  38. unsigned long cmd;
  39. int base = 0;
  40. int error = 0;
  41. if(regs->regs[2] == 1000)
  42. base = 1;
  43. cmd = regs->regs[base + 4];
  44. switch(cmd) {
  45. case MP_PGSIZE:
  46. error = PAGE_SIZE;
  47. break;
  48. case MP_NPROCS:
  49. case MP_NAPROCS:
  50. error = smp_num_cpus;
  51. break;
  52. default:
  53. printk("SYSMP[%s:%d]: Unsupported opcode %dn",
  54.        current->comm, current->pid, (int)cmd);
  55. error = -EINVAL;
  56. break;
  57. }
  58. return error;
  59. }
  60. /* The prctl commands. */
  61. #define PR_MAXPROCS          1 /* Tasks/user. */
  62. #define PR_ISBLOCKED         2 /* If blocked, return 1. */
  63. #define PR_SETSTACKSIZE      3 /* Set largest task stack size. */
  64. #define PR_GETSTACKSIZE      4 /* Get largest task stack size. */
  65. #define PR_MAXPPROCS         5 /* Num parallel tasks. */
  66. #define PR_UNBLKONEXEC       6 /* When task exec/exit's, unblock. */
  67. #define PR_SETEXITSIG        8 /* When task exit's, set signal. */
  68. #define PR_RESIDENT          9 /* Make task unswappable. */
  69. #define PR_ATTACHADDR       10 /* (Re-)Connect a vma to a task. */
  70. #define PR_DETACHADDR       11 /* Disconnect a vma from a task. */
  71. #define PR_TERMCHILD        12 /* When parent sleeps with fishes, kill child. */
  72. #define PR_GETSHMASK        13 /* Get the sproc() share mask. */
  73. #define PR_GETNSHARE        14 /* Number of share group members. */
  74. #define PR_COREPID          15 /* Add task pid to name when it core. */
  75. #define PR_ATTACHADDRPERM   16 /* (Re-)Connect vma, with specified prot. */
  76. #define PR_PTHREADEXIT      17 /* Kill a pthread without prejudice. */
  77. asmlinkage int irix_prctl(struct pt_regs *regs)
  78. {
  79. unsigned long cmd;
  80. int error = 0, base = 0;
  81. if (regs->regs[2] == 1000)
  82. base = 1;
  83. cmd = regs->regs[base + 4];
  84. switch (cmd) {
  85. case PR_MAXPROCS:
  86. printk("irix_prctl[%s:%d]: Wants PR_MAXPROCSn",
  87.        current->comm, current->pid);
  88. error = max_threads;
  89. break;
  90. case PR_ISBLOCKED: {
  91. struct task_struct *task;
  92. printk("irix_prctl[%s:%d]: Wants PR_ISBLOCKEDn",
  93.        current->comm, current->pid);
  94. read_lock(&tasklist_lock);
  95. task = find_task_by_pid(regs->regs[base + 5]);
  96. error = -ESRCH;
  97. if (error)
  98. error = (task->run_list.next != NULL);
  99. read_unlock(&tasklist_lock);
  100. /* Can _your_ OS find this out that fast? */
  101. break;
  102. }
  103. case PR_SETSTACKSIZE: {
  104. long value = regs->regs[base + 5];
  105. printk("irix_prctl[%s:%d]: Wants PR_SETSTACKSIZE<%08lx>n",
  106.        current->comm, current->pid, (unsigned long) value);
  107. if (value > RLIM_INFINITY)
  108. value = RLIM_INFINITY;
  109. if (capable(CAP_SYS_ADMIN)) {
  110. current->rlim[RLIMIT_STACK].rlim_max =
  111. current->rlim[RLIMIT_STACK].rlim_cur = value;
  112. error = value;
  113. break;
  114. }
  115. if (value > current->rlim[RLIMIT_STACK].rlim_max) {
  116. error = -EINVAL;
  117. break;
  118. }
  119. current->rlim[RLIMIT_STACK].rlim_cur = value;
  120. error = value;
  121. break;
  122. }
  123. case PR_GETSTACKSIZE:
  124. printk("irix_prctl[%s:%d]: Wants PR_GETSTACKSIZEn",
  125.        current->comm, current->pid);
  126. error = current->rlim[RLIMIT_STACK].rlim_cur;
  127. break;
  128. case PR_MAXPPROCS:
  129. printk("irix_prctl[%s:%d]: Wants PR_MAXPROCSn",
  130.        current->comm, current->pid);
  131. error = 1;
  132. break;
  133. case PR_UNBLKONEXEC:
  134. printk("irix_prctl[%s:%d]: Wants PR_UNBLKONEXECn",
  135.        current->comm, current->pid);
  136. error = -EINVAL;
  137. break;
  138. case PR_SETEXITSIG:
  139. printk("irix_prctl[%s:%d]: Wants PR_SETEXITSIGn",
  140.        current->comm, current->pid);
  141. /* We can probably play some game where we set the task
  142.  * exit_code to some non-zero value when this is requested,
  143.  * and check whether exit_code is already set in do_exit().
  144.  */
  145. error = -EINVAL;
  146. break;
  147. case PR_RESIDENT:
  148. printk("irix_prctl[%s:%d]: Wants PR_RESIDENTn",
  149.        current->comm, current->pid);
  150. error = 0; /* Compatibility indeed. */
  151. break;
  152. case PR_ATTACHADDR:
  153. printk("irix_prctl[%s:%d]: Wants PR_ATTACHADDRn",
  154.        current->comm, current->pid);
  155. error = -EINVAL;
  156. break;
  157. case PR_DETACHADDR:
  158. printk("irix_prctl[%s:%d]: Wants PR_DETACHADDRn",
  159.        current->comm, current->pid);
  160. error = -EINVAL;
  161. break;
  162. case PR_TERMCHILD:
  163. printk("irix_prctl[%s:%d]: Wants PR_TERMCHILDn",
  164.        current->comm, current->pid);
  165. error = -EINVAL;
  166. break;
  167. case PR_GETSHMASK:
  168. printk("irix_prctl[%s:%d]: Wants PR_GETSHMASKn",
  169.        current->comm, current->pid);
  170. error = -EINVAL; /* Until I have the sproc() stuff in. */
  171. break;
  172. case PR_GETNSHARE:
  173. error = 0;       /* Until I have the sproc() stuff in. */
  174. break;
  175. case PR_COREPID:
  176. printk("irix_prctl[%s:%d]: Wants PR_COREPIDn",
  177.        current->comm, current->pid);
  178. error = -EINVAL;
  179. break;
  180. case PR_ATTACHADDRPERM:
  181. printk("irix_prctl[%s:%d]: Wants PR_ATTACHADDRPERMn",
  182.        current->comm, current->pid);
  183. error = -EINVAL;
  184. break;
  185. case PR_PTHREADEXIT:
  186. printk("irix_prctl[%s:%d]: Wants PR_PTHREADEXITn",
  187.        current->comm, current->pid);
  188. do_exit(regs->regs[base + 5]);
  189. default:
  190. printk("irix_prctl[%s:%d]: Non-existant opcode %dn",
  191.        current->comm, current->pid, (int)cmd);
  192. error = -EINVAL;
  193. break;
  194. }
  195. return error;
  196. }
  197. #undef DEBUG_PROCGRPS
  198. extern unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt);
  199. extern asmlinkage int sys_setpgid(pid_t pid, pid_t pgid);
  200. extern void sys_sync(void);
  201. extern asmlinkage int sys_getsid(pid_t pid);
  202. extern asmlinkage long sys_write (unsigned int fd, const char *buf, unsigned long count);
  203. extern asmlinkage long sys_lseek (unsigned int fd, off_t offset, unsigned int origin);
  204. extern asmlinkage int sys_getgroups(int gidsetsize, gid_t *grouplist);
  205. extern asmlinkage int sys_setgroups(int gidsetsize, gid_t *grouplist);
  206. extern int getrusage(struct task_struct *p, int who, struct rusage *ru);
  207. extern char *prom_getenv(char *name);
  208. extern long prom_setenv(char *name, char *value);
  209. /* The syssgi commands supported thus far. */
  210. #define SGI_SYSID         1       /* Return unique per-machine identifier. */
  211. #define SGI_INVENT        5       /* Fetch inventory  */
  212. #   define SGI_INV_SIZEOF 1
  213. #   define SGI_INV_READ   2
  214. #define SGI_RDNAME        6       /* Return string name of a process. */
  215. #define SGI_SETNVRAM   8   /* Set PROM variable. */
  216. #define SGI_GETNVRAM   9   /* Get PROM variable. */
  217. #define SGI_SETPGID      21       /* Set process group id. */
  218. #define SGI_SYSCONF      22       /* POSIX sysconf garbage. */
  219. #define SGI_PATHCONF     24       /* POSIX sysconf garbage. */
  220. #define SGI_SETGROUPS    40       /* POSIX sysconf garbage. */
  221. #define SGI_GETGROUPS    41       /* POSIX sysconf garbage. */
  222. #define SGI_RUSAGE       56       /* BSD style rusage(). */
  223. #define SGI_SSYNC        62       /* Synchronous fs sync. */
  224. #define SGI_GETSID       65       /* SysVr4 get session id. */
  225. #define SGI_ELFMAP       68       /* Map an elf image. */
  226. #define SGI_TOSSTSAVE   108       /* Toss saved vma's. */
  227. #define SGI_FP_BCOPY    129       /* Should FPU bcopy be used on this machine? */
  228. #define SGI_PHYSP      1011       /* Translate virtual into physical page. */
  229. asmlinkage int irix_syssgi(struct pt_regs *regs)
  230. {
  231. unsigned long cmd;
  232. int retval, base = 0;
  233. if (regs->regs[2] == 1000)
  234. base = 1;
  235. cmd = regs->regs[base + 4];
  236. switch(cmd) {
  237. case SGI_SYSID: {
  238. char *buf = (char *) regs->regs[base + 5];
  239. /* XXX Use ethernet addr.... */
  240. retval = clear_user(buf, 64);
  241. break;
  242. }
  243. #if 0
  244. case SGI_RDNAME: {
  245. int pid = (int) regs->regs[base + 5];
  246. char *buf = (char *) regs->regs[base + 6];
  247. struct task_struct *p;
  248. char comm[16];
  249. retval = verify_area(VERIFY_WRITE, buf, 16);
  250. if (retval)
  251. break;
  252. read_lock(&tasklist_lock);
  253. p = find_task_by_pid(pid);
  254. if (!p) {
  255. read_unlock(&tasklist_lock);
  256. retval = -ESRCH;
  257. break;
  258. }
  259. memcpy(comm, p->comm, 16);
  260. read_unlock(&tasklist_lock);
  261. /* XXX Need to check sizes. */
  262. copy_to_user(buf, p->comm, 16);
  263. retval = 0;
  264. break;
  265. }
  266. case SGI_GETNVRAM: {
  267. char *name = (char *) regs->regs[base+5];
  268. char *buf = (char *) regs->regs[base+6];
  269. char *value;
  270. return -EINVAL; /* til I fix it */
  271. retval = verify_area(VERIFY_WRITE, buf, 128);
  272. if (retval)
  273. break;
  274. value = prom_getenv(name); /* PROM lock?  */
  275. if (!value) {
  276. retval = -EINVAL;
  277. break;
  278. }
  279. /* Do I strlen() for the length? */
  280. copy_to_user(buf, value, 128);
  281. retval = 0;
  282. break;
  283. }
  284. case SGI_SETNVRAM: {
  285. char *name = (char *) regs->regs[base+5];
  286. char *value = (char *) regs->regs[base+6];
  287. return -EINVAL; /* til I fix it */
  288. retval = prom_setenv(name, value);
  289. /* XXX make sure retval conforms to syssgi(2) */
  290. printk("[%s:%d] setnvram("%s", "%s"): retval %d",
  291.        current->comm, current->pid, name, value, retval);
  292. /* if (retval == PROM_ENOENT)
  293.    retval = -ENOENT; */
  294. break;
  295. }
  296. #endif
  297. case SGI_SETPGID: {
  298. #ifdef DEBUG_PROCGRPS
  299. printk("[%s:%d] setpgid(%d, %d) ",
  300.        current->comm, current->pid,
  301.        (int) regs->regs[base + 5], (int)regs->regs[base + 6]);
  302. #endif
  303. retval = sys_setpgid(regs->regs[base + 5], regs->regs[base + 6]);
  304. #ifdef DEBUG_PROCGRPS
  305. printk("retval=%dn", retval);
  306. #endif
  307. }
  308. case SGI_SYSCONF: {
  309. switch(regs->regs[base + 5]) {
  310. case 1:
  311. retval = (MAX_ARG_PAGES >> 4); /* XXX estimate... */
  312. goto out;
  313. case 2:
  314. retval = max_threads;
  315. goto out;
  316. case 3:
  317. retval = HZ;
  318. goto out;
  319. case 4:
  320. retval = NGROUPS;
  321. goto out;
  322. case 5:
  323. retval = NR_OPEN;
  324. goto out;
  325. case 6:
  326. retval = 1;
  327. goto out;
  328. case 7:
  329. retval = 1;
  330. goto out;
  331. case 8:
  332. retval = 199009;
  333. goto out;
  334. case 11:
  335. retval = PAGE_SIZE;
  336. goto out;
  337. case 12:
  338. retval = 4;
  339. goto out;
  340. case 25:
  341. case 26:
  342. case 27:
  343. case 28:
  344. case 29:
  345. case 30:
  346. retval = 0;
  347. goto out;
  348. case 31:
  349. retval = 32;
  350. goto out;
  351. default:
  352. retval = -EINVAL;
  353. goto out;
  354. };
  355. }
  356. case SGI_SETGROUPS:
  357. retval = sys_setgroups((int) regs->regs[base + 5],
  358.                        (gid_t *) regs->regs[base + 6]);
  359. break;
  360. case SGI_GETGROUPS:
  361. retval = sys_getgroups((int) regs->regs[base + 5],
  362.                        (gid_t *) regs->regs[base + 6]);
  363. break;
  364. case SGI_RUSAGE: {
  365. struct rusage *ru = (struct rusage *) regs->regs[base + 6];
  366. switch((int) regs->regs[base + 5]) {
  367. case 0:
  368. /* rusage self */
  369. retval = getrusage(current, RUSAGE_SELF, ru);
  370. goto out;
  371. case -1:
  372. /* rusage children */
  373. retval = getrusage(current, RUSAGE_CHILDREN, ru);
  374. goto out;
  375. default:
  376. retval = -EINVAL;
  377. goto out;
  378. };
  379. }
  380. case SGI_SSYNC:
  381. sys_sync();
  382. retval = 0;
  383. break;
  384. case SGI_GETSID:
  385. #ifdef DEBUG_PROCGRPS
  386. printk("[%s:%d] getsid(%d) ", current->comm, current->pid,
  387.        (int) regs->regs[base + 5]);
  388. #endif
  389. retval = sys_getsid(regs->regs[base + 5]);
  390. #ifdef DEBUG_PROCGRPS
  391. printk("retval=%dn", retval);
  392. #endif
  393. break;
  394. case SGI_ELFMAP:
  395. retval = irix_mapelf((int) regs->regs[base + 5],
  396.      (struct elf_phdr *) regs->regs[base + 6],
  397.      (int) regs->regs[base + 7]);
  398. break;
  399. case SGI_TOSSTSAVE:
  400. /* XXX We don't need to do anything? */
  401. retval = 0;
  402. break;
  403. case SGI_FP_BCOPY:
  404. retval = 0;
  405. break;
  406. case SGI_PHYSP: {
  407. unsigned long addr = regs->regs[base + 5];
  408. int *pageno = (int *) (regs->regs[base + 6]);
  409. struct mm_struct *mm = current->mm;
  410. pgd_t *pgdp;
  411. pmd_t *pmdp;
  412. pte_t *ptep;
  413. retval = verify_area(VERIFY_WRITE, pageno, sizeof(int));
  414. if (retval)
  415. return retval;
  416. down_read(&mm->mmap_sem);
  417. pgdp = pgd_offset(mm, addr);
  418. pmdp = pmd_offset(pgdp, addr);
  419. ptep = pte_offset(pmdp, addr);
  420. retval = -EINVAL;
  421. if (ptep) {
  422. pte_t pte = *ptep;
  423. if (pte_val(pte) & (_PAGE_VALID | _PAGE_PRESENT)) {
  424. retval =  put_user((pte_val(pte) & PAGE_MASK) >>
  425.                    PAGE_SHIFT, pageno);
  426. }
  427. }
  428. up_read(&mm->mmap_sem);
  429. break;
  430. }
  431. case SGI_INVENT: {
  432. int  arg1    = (int)    regs->regs [base + 5];
  433. void *buffer = (void *) regs->regs [base + 6];
  434. int  count   = (int)    regs->regs [base + 7];
  435. switch (arg1) {
  436. case SGI_INV_SIZEOF:
  437. retval = sizeof (inventory_t);
  438. break;
  439. case SGI_INV_READ:
  440. retval = dump_inventory_to_user (buffer, count);
  441. break;
  442. default:
  443. retval = -EINVAL;
  444. }
  445. break;
  446. }
  447. default:
  448. printk("irix_syssgi: Unsupported command %dn", (int)cmd);
  449. retval = -EINVAL;
  450. break;
  451. };
  452. out:
  453. return retval;
  454. }
  455. asmlinkage int irix_gtime(struct pt_regs *regs)
  456. {
  457. return CURRENT_TIME;
  458. }
  459. int vm_enough_memory(long pages);
  460. /*
  461.  * IRIX is completely broken... it returns 0 on success, otherwise
  462.  * ENOMEM.
  463.  */
  464. asmlinkage int irix_brk(unsigned long brk)
  465. {
  466. unsigned long rlim;
  467. unsigned long newbrk, oldbrk;
  468. struct mm_struct *mm = current->mm;
  469. int ret;
  470. down_write(&mm->mmap_sem);
  471. if (brk < mm->end_code) {
  472. ret = -ENOMEM;
  473. goto out;
  474. }
  475. newbrk = PAGE_ALIGN(brk);
  476. oldbrk = PAGE_ALIGN(mm->brk);
  477. if (oldbrk == newbrk) {
  478. mm->brk = brk;
  479. ret = 0;
  480. goto out;
  481. }
  482. /*
  483.  * Always allow shrinking brk
  484.  */
  485. if (brk <= mm->brk) {
  486. mm->brk = brk;
  487. do_munmap(mm, newbrk, oldbrk-newbrk);
  488. ret = 0;
  489. goto out;
  490. }
  491. /*
  492.  * Check against rlimit and stack..
  493.  */
  494. rlim = current->rlim[RLIMIT_DATA].rlim_cur;
  495. if (rlim >= RLIM_INFINITY)
  496. rlim = ~0;
  497. if (brk - mm->end_code > rlim) {
  498. ret = -ENOMEM;
  499. goto out;
  500. }
  501. /*
  502.  * Check against existing mmap mappings.
  503.  */
  504. if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE)) {
  505. ret = -ENOMEM;
  506. goto out;
  507. }
  508. /*
  509.  * Check if we have enough memory..
  510.  */
  511. if (!vm_enough_memory((newbrk-oldbrk) >> PAGE_SHIFT)) {
  512. ret = -ENOMEM;
  513. goto out;
  514. }
  515. /*
  516.  * Ok, looks good - let it rip.
  517.  */
  518. mm->brk = brk;
  519. do_brk(oldbrk, newbrk-oldbrk);
  520. ret = 0;
  521. out:
  522. up_write(&mm->mmap_sem);
  523. return ret;
  524. }
  525. asmlinkage int irix_getpid(struct pt_regs *regs)
  526. {
  527. regs->regs[3] = current->p_opptr->pid;
  528. return current->pid;
  529. }
  530. asmlinkage int irix_getuid(struct pt_regs *regs)
  531. {
  532. regs->regs[3] = current->euid;
  533. return current->uid;
  534. }
  535. asmlinkage int irix_getgid(struct pt_regs *regs)
  536. {
  537. regs->regs[3] = current->egid;
  538. return current->gid;
  539. }
  540. extern rwlock_t xtime_lock;
  541. asmlinkage int irix_stime(int value)
  542. {
  543. if (!capable(CAP_SYS_TIME))
  544. return -EPERM;
  545. write_lock_irq(&xtime_lock);
  546. xtime.tv_sec = value;
  547. xtime.tv_usec = 0;
  548. time_maxerror = MAXPHASE;
  549. time_esterror = MAXPHASE;
  550. write_unlock_irq(&xtime_lock);
  551. return 0;
  552. }
  553. extern int do_setitimer(int which, struct itimerval *value,
  554.                         struct itimerval *ovalue);
  555. static inline void jiffiestotv(unsigned long jiffies, struct timeval *value)
  556. {
  557. value->tv_usec = (jiffies % HZ) * (1000000 / HZ);
  558. value->tv_sec = jiffies / HZ;
  559. }
  560. static inline void getitimer_real(struct itimerval *value)
  561. {
  562. register unsigned long val, interval;
  563. interval = current->it_real_incr;
  564. val = 0;
  565. if (del_timer(&current->real_timer)) {
  566. unsigned long now = jiffies;
  567. val = current->real_timer.expires;
  568. add_timer(&current->real_timer);
  569. /* look out for negative/zero itimer.. */
  570. if (val <= now)
  571. val = now+1;
  572. val -= now;
  573. }
  574. jiffiestotv(val, &value->it_value);
  575. jiffiestotv(interval, &value->it_interval);
  576. }
  577. asmlinkage unsigned int irix_alarm(unsigned int seconds)
  578. {
  579. struct itimerval it_new, it_old;
  580. unsigned int oldalarm;
  581. if (!seconds) {
  582. getitimer_real(&it_old);
  583. del_timer(&current->real_timer);
  584. } else {
  585. it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0;
  586. it_new.it_value.tv_sec = seconds;
  587. it_new.it_value.tv_usec = 0;
  588. do_setitimer(ITIMER_REAL, &it_new, &it_old);
  589. }
  590. oldalarm = it_old.it_value.tv_sec;
  591. /*
  592.  * ehhh.. We can't return 0 if we have an alarm pending ...
  593.  * And we'd better return too much than too little anyway
  594.  */
  595. if (it_old.it_value.tv_usec)
  596. oldalarm++;
  597. return oldalarm;
  598. }
  599. asmlinkage int irix_pause(void)
  600. {
  601. current->state = TASK_INTERRUPTIBLE;
  602. schedule();
  603. return -EINTR;
  604. }
  605. extern asmlinkage long sys_mount(char * dev_name, char * dir_name, char * type,
  606. unsigned long new_flags, void * data);
  607. /* XXX need more than this... */
  608. asmlinkage int irix_mount(char *dev_name, char *dir_name, unsigned long flags,
  609.   char *type, void *data, int datalen)
  610. {
  611. printk("[%s:%d] irix_mount(%p,%p,%08lx,%p,%p,%d)n",
  612.        current->comm, current->pid,
  613.        dev_name, dir_name, flags, type, data, datalen);
  614. return sys_mount(dev_name, dir_name, type, flags, data);
  615. }
  616. struct irix_statfs {
  617. short f_type;
  618.         long  f_bsize, f_frsize, f_blocks, f_bfree, f_files, f_ffree;
  619. char  f_fname[6], f_fpack[6];
  620. };
  621. asmlinkage int irix_statfs(const char *path, struct irix_statfs *buf,
  622.    int len, int fs_type)
  623. {
  624. struct nameidata nd;
  625. struct statfs kbuf;
  626. int error, i;
  627. /* We don't support this feature yet. */
  628. if (fs_type) {
  629. error = -EINVAL;
  630. goto out;
  631. }
  632. error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statfs));
  633. if (error)
  634. goto out;
  635. error = user_path_walk(path, &nd);
  636. if (error)
  637. goto out;
  638. error = vfs_statfs(nd.dentry->d_inode->i_sb, &kbuf);
  639. if (error)
  640. goto dput_and_out;
  641. __put_user(kbuf.f_type, &buf->f_type);
  642. __put_user(kbuf.f_bsize, &buf->f_bsize);
  643. __put_user(kbuf.f_frsize, &buf->f_frsize);
  644. __put_user(kbuf.f_blocks, &buf->f_blocks);
  645. __put_user(kbuf.f_bfree, &buf->f_bfree);
  646. __put_user(kbuf.f_files, &buf->f_files);
  647. __put_user(kbuf.f_ffree, &buf->f_ffree);
  648. for (i = 0; i < 6; i++) {
  649. __put_user(0, &buf->f_fname[i]);
  650. __put_user(0, &buf->f_fpack[i]);
  651. }
  652. error = 0;
  653. dput_and_out:
  654. path_release(&nd);
  655. out:
  656. return error;
  657. }
  658. asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs *buf)
  659. {
  660. struct statfs kbuf;
  661. struct file *file;
  662. int error, i;
  663. error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statfs));
  664. if (error)
  665. goto out;
  666. if (!(file = fget(fd))) {
  667. error = -EBADF;
  668. goto out;
  669. }
  670. error = vfs_statfs(file->f_dentry->d_inode->i_sb, &kbuf);
  671. if (error)
  672. goto out_f;
  673. __put_user(kbuf.f_type, &buf->f_type);
  674. __put_user(kbuf.f_bsize, &buf->f_bsize);
  675. __put_user(kbuf.f_frsize, &buf->f_frsize);
  676. __put_user(kbuf.f_blocks, &buf->f_blocks);
  677. __put_user(kbuf.f_bfree, &buf->f_bfree);
  678. __put_user(kbuf.f_files, &buf->f_files);
  679. __put_user(kbuf.f_ffree, &buf->f_ffree);
  680. for(i = 0; i < 6; i++) {
  681. __put_user(0, &buf->f_fname[i]);
  682. __put_user(0, &buf->f_fpack[i]);
  683. }
  684. out_f:
  685. fput(file);
  686. out:
  687. return error;
  688. }
  689. extern asmlinkage int sys_setpgid(pid_t pid, pid_t pgid);
  690. extern asmlinkage int sys_setsid(void);
  691. asmlinkage int irix_setpgrp(int flags)
  692. {
  693. int error;
  694. #ifdef DEBUG_PROCGRPS
  695. printk("[%s:%d] setpgrp(%d) ", current->comm, current->pid, flags);
  696. #endif
  697. if(!flags)
  698. error = current->pgrp;
  699. else
  700. error = sys_setsid();
  701. #ifdef DEBUG_PROCGRPS
  702. printk("returning %dn", current->pgrp);
  703. #endif
  704. return error;
  705. }
  706. asmlinkage int irix_times(struct tms * tbuf)
  707. {
  708. int err = 0;
  709. if (tbuf) {
  710. err = verify_area(VERIFY_WRITE,tbuf,sizeof *tbuf);
  711. if (err)
  712. return err;
  713. err |= __put_user(current->times.tms_utime,&tbuf->tms_utime);
  714. err |= __put_user(current->times.tms_stime,&tbuf->tms_stime);
  715. err |= __put_user(current->times.tms_cutime,&tbuf->tms_cutime);
  716. err |= __put_user(current->times.tms_cstime,&tbuf->tms_cstime);
  717. }
  718. return err;
  719. }
  720. asmlinkage int irix_exec(struct pt_regs *regs)
  721. {
  722. int error, base = 0;
  723. char *filename;
  724. if(regs->regs[2] == 1000)
  725. base = 1;
  726. filename = getname((char *) (long)regs->regs[base + 4]);
  727. error = PTR_ERR(filename);
  728. if (IS_ERR(filename))
  729. return error;
  730. error = do_execve(filename, (char **) (long)regs->regs[base + 5],
  731.                   (char **) 0, regs);
  732. putname(filename);
  733. return error;
  734. }
  735. asmlinkage int irix_exece(struct pt_regs *regs)
  736. {
  737. int error, base = 0;
  738. char *filename;
  739. if (regs->regs[2] == 1000)
  740. base = 1;
  741. filename = getname((char *) (long)regs->regs[base + 4]);
  742. error = PTR_ERR(filename);
  743. if (IS_ERR(filename))
  744. return error;
  745. error = do_execve(filename, (char **) (long)regs->regs[base + 5],
  746.                   (char **) (long)regs->regs[base + 6], regs);
  747. putname(filename);
  748. return error;
  749. }
  750. asmlinkage unsigned long irix_gethostid(void)
  751. {
  752. printk("[%s:%d]: irix_gethostid() called...n",
  753.        current->comm, current->pid);
  754. return -EINVAL;
  755. }
  756. asmlinkage unsigned long irix_sethostid(unsigned long val)
  757. {
  758. printk("[%s:%d]: irix_sethostid(%08lx) called...n",
  759.        current->comm, current->pid, val);
  760. return -EINVAL;
  761. }
  762. extern asmlinkage int sys_socket(int family, int type, int protocol);
  763. asmlinkage int irix_socket(int family, int type, int protocol)
  764. {
  765. switch(type) {
  766. case 1:
  767. type = SOCK_DGRAM;
  768. break;
  769. case 2:
  770. type = SOCK_STREAM;
  771. break;
  772. case 3:
  773. type = 9; /* Invalid... */
  774. break;
  775. case 4:
  776. type = SOCK_RAW;
  777. break;
  778. case 5:
  779. type = SOCK_RDM;
  780. break;
  781. case 6:
  782. type = SOCK_SEQPACKET;
  783. break;
  784. default:
  785. break;
  786. }
  787. return sys_socket(family, type, protocol);
  788. }
  789. asmlinkage int irix_getdomainname(char *name, int len)
  790. {
  791. int error;
  792. error = verify_area(VERIFY_WRITE, name, len);
  793. if (error)
  794. return error;
  795. down_read(&uts_sem);
  796. if(len > (__NEW_UTS_LEN - 1))
  797. len = __NEW_UTS_LEN - 1;
  798. error = 0;
  799. if (copy_to_user(name, system_utsname.domainname, len))
  800. error = -EFAULT;
  801. up_read(&uts_sem);
  802. return error;
  803. }
  804. asmlinkage unsigned long irix_getpagesize(void)
  805. {
  806. return PAGE_SIZE;
  807. }
  808. asmlinkage int irix_msgsys(int opcode, unsigned long arg0, unsigned long arg1,
  809.    unsigned long arg2, unsigned long arg3,
  810.    unsigned long arg4)
  811. {
  812. switch (opcode) {
  813. case 0:
  814. return sys_msgget((key_t) arg0, (int) arg1);
  815. case 1:
  816. return sys_msgctl((int) arg0, (int) arg1, (struct msqid_ds *)arg2);
  817. case 2:
  818. return sys_msgrcv((int) arg0, (struct msgbuf *) arg1,
  819.   (size_t) arg2, (long) arg3, (int) arg4);
  820. case 3:
  821. return sys_msgsnd((int) arg0, (struct msgbuf *) arg1,
  822.   (size_t) arg2, (int) arg3);
  823. default:
  824. return -EINVAL;
  825. }
  826. }
  827. asmlinkage int irix_shmsys(int opcode, unsigned long arg0, unsigned long arg1,
  828.    unsigned long arg2, unsigned long arg3)
  829. {
  830. switch (opcode) {
  831. case 0:
  832. return sys_shmat((int) arg0, (char *)arg1, (int) arg2,
  833.  (unsigned long *) arg3);
  834. case 1:
  835. return sys_shmctl((int)arg0, (int)arg1, (struct shmid_ds *)arg2);
  836. case 2:
  837. return sys_shmdt((char *)arg0);
  838. case 3:
  839. return sys_shmget((key_t) arg0, (int) arg1, (int) arg2);
  840. default:
  841. return -EINVAL;
  842. }
  843. }
  844. asmlinkage int irix_semsys(int opcode, unsigned long arg0, unsigned long arg1,
  845.    unsigned long arg2, int arg3)
  846. {
  847. switch (opcode) {
  848. case 0:
  849. return sys_semctl((int) arg0, (int) arg1, (int) arg2,
  850.   (union semun) arg3);
  851. case 1:
  852. return sys_semget((key_t) arg0, (int) arg1, (int) arg2);
  853. case 2:
  854. return sys_semop((int) arg0, (struct sembuf *)arg1,
  855.  (unsigned int) arg2);
  856. default:
  857. return -EINVAL;
  858. }
  859. }
  860. static inline loff_t llseek(struct file *file, loff_t offset, int origin)
  861. {
  862. loff_t (*fn)(struct file *, loff_t, int);
  863. loff_t retval;
  864. fn = default_llseek;
  865. if (file->f_op && file->f_op->llseek)
  866.         fn = file->f_op->llseek;
  867. lock_kernel();
  868. retval = fn(file, offset, origin);
  869. unlock_kernel();
  870. return retval;
  871. }
  872. asmlinkage int irix_lseek64(int fd, int _unused, int offhi, int offlow,
  873.                             int origin)
  874. {
  875. int retval;
  876. struct file * file;
  877. loff_t offset;
  878. retval = -EBADF;
  879. file = fget(fd);
  880. if (!file)
  881. goto bad;
  882. retval = -EINVAL;
  883. if (origin > 2)
  884. goto out_putf;
  885. offset = llseek(file, ((loff_t) offhi << 32) | offlow, origin);
  886. retval = (int) offset;
  887. out_putf:
  888. fput(file);
  889. bad:
  890. return retval;
  891. }
  892. asmlinkage int irix_sginap(int ticks)
  893. {
  894. current->state = TASK_INTERRUPTIBLE;
  895. schedule_timeout(ticks);
  896. return 0;
  897. }
  898. asmlinkage int irix_sgikopt(char *istring, char *ostring, int len)
  899. {
  900. return -EINVAL;
  901. }
  902. asmlinkage int irix_gettimeofday(struct timeval *tv)
  903. {
  904. int retval;
  905. retval = copy_to_user(tv, &xtime, sizeof(*tv)) ? -EFAULT : 0;
  906. return retval;
  907. }
  908. #define IRIX_MAP_AUTOGROW 0x40
  909. asmlinkage unsigned long irix_mmap32(unsigned long addr, size_t len, int prot,
  910.      int flags, int fd, off_t offset)
  911. {
  912. struct file *file = NULL;
  913. unsigned long retval;
  914. if (!(flags & MAP_ANONYMOUS)) {
  915. if (!(file = fget(fd)))
  916. return -EBADF;
  917. /* Ok, bad taste hack follows, try to think in something else
  918.  * when reading this.  */
  919. if (flags & IRIX_MAP_AUTOGROW) {
  920. unsigned long old_pos;
  921. long max_size = offset + len;
  922. if (max_size > file->f_dentry->d_inode->i_size) {
  923. old_pos = sys_lseek (fd, max_size - 1, 0);
  924. sys_write (fd, "", 1);
  925. sys_lseek (fd, old_pos, 0);
  926. }
  927. }
  928. }
  929. flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
  930. down_write(&current->mm->mmap_sem);
  931. retval = do_mmap(file, addr, len, prot, flags, offset);
  932. up_write(&current->mm->mmap_sem);
  933. if (file)
  934. fput(file);
  935. return retval;
  936. }
  937. asmlinkage int irix_madvise(unsigned long addr, int len, int behavior)
  938. {
  939. printk("[%s:%d] Wheee.. irix_madvise(%08lx,%d,%d)n",
  940.        current->comm, current->pid, addr, len, behavior);
  941. return -EINVAL;
  942. }
  943. asmlinkage int irix_pagelock(char *addr, int len, int op)
  944. {
  945. printk("[%s:%d] Wheee.. irix_pagelock(%p,%d,%d)n",
  946.        current->comm, current->pid, addr, len, op);
  947. return -EINVAL;
  948. }
  949. asmlinkage int irix_quotactl(struct pt_regs *regs)
  950. {
  951. printk("[%s:%d] Wheee.. irix_quotactl()n",
  952.        current->comm, current->pid);
  953. return -EINVAL;
  954. }
  955. asmlinkage int irix_BSDsetpgrp(int pid, int pgrp)
  956. {
  957. int error;
  958. #ifdef DEBUG_PROCGRPS
  959. printk("[%s:%d] BSDsetpgrp(%d, %d) ", current->comm, current->pid,
  960.        pid, pgrp);
  961. #endif
  962. if(!pid)
  963. pid = current->pid;
  964. /* Wheee, weird sysv thing... */
  965. if ((pgrp == 0) && (pid == current->pid))
  966. error = sys_setsid();
  967. else
  968. error = sys_setpgid(pid, pgrp);
  969. #ifdef DEBUG_PROCGRPS
  970. printk("error = %dn", error);
  971. #endif
  972. return error;
  973. }
  974. asmlinkage int irix_systeminfo(int cmd, char *buf, int cnt)
  975. {
  976. printk("[%s:%d] Wheee.. irix_systeminfo(%d,%p,%d)n",
  977.        current->comm, current->pid, cmd, buf, cnt);
  978. return -EINVAL;
  979. }
  980. struct iuname {
  981. char sysname[257], nodename[257], release[257];
  982. char version[257], machine[257];
  983. char m_type[257], base_rel[257];
  984. char _unused0[257], _unused1[257], _unused2[257];
  985. char _unused3[257], _unused4[257], _unused5[257];
  986. };
  987. asmlinkage int irix_uname(struct iuname *buf)
  988. {
  989. down_read(&uts_sem);
  990. if (copy_to_user(system_utsname.sysname, buf->sysname, 65)
  991.     || copy_to_user(system_utsname.nodename, buf->nodename, 65)
  992.     || copy_to_user(system_utsname.release, buf->release, 65)
  993.     || copy_to_user(system_utsname.version, buf->version, 65)
  994.     || copy_to_user(system_utsname.machine, buf->machine, 65)) {
  995. return -EFAULT;
  996. }
  997. up_read(&uts_sem);
  998. return 1;
  999. }
  1000. #undef DEBUG_XSTAT
  1001. static inline u32
  1002. linux_to_irix_dev_t (dev_t t)
  1003. {
  1004. return MAJOR (t) << 18 | MINOR (t);
  1005. }
  1006. static inline int irix_xstat32_xlate(struct stat *kb, void *ubuf)
  1007. {
  1008. struct xstat32 {
  1009. u32 st_dev, st_pad1[3], st_ino, st_mode, st_nlink, st_uid, st_gid;
  1010. u32 st_rdev, st_pad2[2], st_size, st_pad3;
  1011. u32 st_atime0, st_atime1;
  1012. u32 st_mtime0, st_mtime1;
  1013. u32 st_ctime0, st_ctime1;
  1014. u32 st_blksize, st_blocks;
  1015. char st_fstype[16];
  1016. u32 st_pad4[8];
  1017. } ub;
  1018. ub.st_dev     = linux_to_irix_dev_t (kb->st_dev);
  1019. ub.st_ino     = kb->st_ino;
  1020. ub.st_mode    = kb->st_mode;
  1021. ub.st_nlink   = kb->st_nlink;
  1022. ub.st_uid     = kb->st_uid;
  1023. ub.st_gid     = kb->st_gid;
  1024. ub.st_rdev    = linux_to_irix_dev_t (kb->st_rdev);
  1025. ub.st_size    = kb->st_size;
  1026. ub.st_atime0  = kb->st_atime;
  1027. ub.st_atime1  = 0;
  1028. ub.st_mtime0  = kb->st_mtime;
  1029. ub.st_mtime1  = 0;
  1030. ub.st_ctime0  = kb->st_ctime;
  1031. ub.st_ctime1  = 0;
  1032. ub.st_blksize = kb->st_blksize;
  1033. ub.st_blocks  = kb->st_blocks;
  1034. strcpy (ub.st_fstype, "efs");
  1035. return copy_to_user(ubuf, &ub, sizeof(ub)) ? -EFAULT : 0;
  1036. }
  1037. static inline void irix_xstat64_xlate(struct stat *sb)
  1038. {
  1039. struct xstat64 {
  1040. u32 st_dev; s32 st_pad1[3];
  1041. unsigned long long st_ino;
  1042. u32 st_mode;
  1043. u32 st_nlink; s32 st_uid; s32 st_gid; u32 st_rdev;
  1044. s32 st_pad2[2];
  1045. long long st_size;
  1046. s32 st_pad3;
  1047. struct { s32 tv_sec, tv_nsec; } st_atime, st_mtime, st_ctime;
  1048. s32 st_blksize;
  1049. long long  st_blocks;
  1050. char st_fstype[16];
  1051. s32 st_pad4[8];
  1052. } ks;
  1053. ks.st_dev = linux_to_irix_dev_t (sb->st_dev);
  1054. ks.st_pad1[0] = ks.st_pad1[1] = ks.st_pad1[2] = 0;
  1055. ks.st_ino = (unsigned long long) sb->st_ino;
  1056. ks.st_mode = (u32) sb->st_mode;
  1057. ks.st_nlink = (u32) sb->st_nlink;
  1058. ks.st_uid = (s32) sb->st_uid;
  1059. ks.st_gid = (s32) sb->st_gid;
  1060. ks.st_rdev = linux_to_irix_dev_t (sb->st_rdev);
  1061. ks.st_pad2[0] = ks.st_pad2[1] = 0;
  1062. ks.st_size = (long long) sb->st_size;
  1063. ks.st_pad3 = 0;
  1064. /* XXX hackety hack... */
  1065. ks.st_atime.tv_sec = (s32) sb->st_atime; ks.st_atime.tv_nsec = 0;
  1066. ks.st_mtime.tv_sec = (s32) sb->st_atime; ks.st_mtime.tv_nsec = 0;
  1067. ks.st_ctime.tv_sec = (s32) sb->st_atime; ks.st_ctime.tv_nsec = 0;
  1068. ks.st_blksize = (s32) sb->st_blksize;
  1069. ks.st_blocks = (long long) sb->st_blocks;
  1070. memset(ks.st_fstype, 0, 16);
  1071. ks.st_pad4[0] = ks.st_pad4[1] = ks.st_pad4[2] = ks.st_pad4[3] = 0;
  1072. ks.st_pad4[4] = ks.st_pad4[5] = ks.st_pad4[6] = ks.st_pad4[7] = 0;
  1073. /* Now write it all back. */
  1074. copy_to_user(sb, &ks, sizeof(struct xstat64));
  1075. }
  1076. extern asmlinkage int sys_newstat(char * filename, struct stat * statbuf);
  1077. asmlinkage int irix_xstat(int version, char *filename, struct stat *statbuf)
  1078. {
  1079. int retval;
  1080. #ifdef DEBUG_XSTAT
  1081. printk("[%s:%d] Wheee.. irix_xstat(%d,%s,%p) ",
  1082.        current->comm, current->pid, version, filename, statbuf);
  1083. #endif
  1084. switch(version) {
  1085. case 2: {
  1086. struct stat kb;
  1087. mm_segment_t old_fs;
  1088. old_fs = get_fs(); set_fs(get_ds());
  1089. retval = sys_newstat(filename, &kb);
  1090. set_fs(old_fs);
  1091. #ifdef DEBUG_XSTAT
  1092. printk("retval[%d]n", retval);
  1093. #endif
  1094. if(retval)
  1095. goto out;
  1096. retval = irix_xstat32_xlate(&kb, statbuf);
  1097. goto out;
  1098. }
  1099. case 3: {
  1100. retval = sys_newstat(filename, statbuf);
  1101. #ifdef DEBUG_XSTAT
  1102. printk("retval[%d]n", retval);
  1103. #endif
  1104. if(retval)
  1105. goto out;
  1106. irix_xstat64_xlate(statbuf);
  1107. retval = 0;
  1108. break;
  1109. }
  1110. default:
  1111. retval = -EINVAL;
  1112. break;
  1113. }
  1114. out:
  1115. return retval;
  1116. }
  1117. extern asmlinkage int sys_newlstat(char * filename, struct stat * statbuf);
  1118. asmlinkage int irix_lxstat(int version, char *filename, struct stat *statbuf)
  1119. {
  1120. int error;
  1121. #ifdef DEBUG_XSTAT
  1122. printk("[%s:%d] Wheee.. irix_lxstat(%d,%s,%p) ",
  1123.        current->comm, current->pid, version, filename, statbuf);
  1124. #endif
  1125. switch(version) {
  1126. case 2: {
  1127. struct stat kb;
  1128. mm_segment_t old_fs;
  1129. old_fs = get_fs(); set_fs(get_ds());
  1130. error = sys_newlstat(filename, &kb);
  1131. set_fs(old_fs);
  1132. #ifdef DEBUG_XSTAT
  1133. printk("error[%d]n", error);
  1134. #endif
  1135. if(error)
  1136. goto out;
  1137. error = irix_xstat32_xlate(&kb, statbuf);
  1138. goto out;
  1139. }
  1140. case 3: {
  1141. error = sys_newlstat(filename, statbuf);
  1142. #ifdef DEBUG_XSTAT
  1143. printk("error[%d]n", error);
  1144. #endif
  1145. if(error)
  1146. goto out;
  1147. irix_xstat64_xlate(statbuf);
  1148. error = 0;
  1149. goto out;
  1150. }
  1151. default:
  1152. error = -EINVAL;
  1153. goto out;
  1154. }
  1155. out:
  1156. return error;
  1157. }
  1158. extern asmlinkage int sys_newfstat(unsigned int fd, struct stat * statbuf);
  1159. asmlinkage int irix_fxstat(int version, int fd, struct stat *statbuf)
  1160. {
  1161. int error;
  1162. #ifdef DEBUG_XSTAT
  1163. printk("[%s:%d] Wheee.. irix_fxstat(%d,%d,%p) ",
  1164.        current->comm, current->pid, version, fd, statbuf);
  1165. #endif
  1166. switch(version) {
  1167. case 2: {
  1168. struct stat kb;
  1169. mm_segment_t old_fs;
  1170. old_fs = get_fs(); set_fs(get_ds());
  1171. error = sys_newfstat(fd, &kb);
  1172. set_fs(old_fs);
  1173. #ifdef DEBUG_XSTAT
  1174. printk("error[%d]n", error);
  1175. #endif
  1176. if(error)
  1177. goto out;
  1178. error = irix_xstat32_xlate(&kb, statbuf);
  1179. goto out;
  1180. }
  1181. case 3: {
  1182. error = sys_newfstat(fd, statbuf);
  1183. #ifdef DEBUG_XSTAT
  1184. printk("error[%d]n", error);
  1185. #endif
  1186. if(error)
  1187. goto out;
  1188. irix_xstat64_xlate(statbuf);
  1189. error = 0;
  1190. goto out;
  1191. }
  1192. default:
  1193. error = -EINVAL;
  1194. goto out;
  1195. }
  1196. out:
  1197. return error;
  1198. }
  1199. extern asmlinkage int sys_mknod(const char * filename, int mode, dev_t dev);
  1200. asmlinkage int irix_xmknod(int ver, char *filename, int mode, dev_t dev)
  1201. {
  1202. int retval;
  1203. printk("[%s:%d] Wheee.. irix_xmknod(%d,%s,%x,%x)n",
  1204.        current->comm, current->pid, ver, filename, mode, (int) dev);
  1205. switch(ver) {
  1206. case 2:
  1207. retval = sys_mknod(filename, mode, dev);
  1208. break;
  1209. default:
  1210. retval = -EINVAL;
  1211. break;
  1212. };
  1213. return retval;
  1214. }
  1215. asmlinkage int irix_swapctl(int cmd, char *arg)
  1216. {
  1217. printk("[%s:%d] Wheee.. irix_swapctl(%d,%p)n",
  1218.        current->comm, current->pid, cmd, arg);
  1219. return -EINVAL;
  1220. }
  1221. struct irix_statvfs {
  1222. u32 f_bsize; u32 f_frsize; u32 f_blocks;
  1223. u32 f_bfree; u32 f_bavail; u32 f_files; u32 f_ffree; u32 f_favail;
  1224. u32 f_fsid; char f_basetype[16];
  1225. u32 f_flag; u32 f_namemax;
  1226. char f_fstr[32]; u32 f_filler[16];
  1227. };
  1228. asmlinkage int irix_statvfs(char *fname, struct irix_statvfs *buf)
  1229. {
  1230. struct nameidata nd;
  1231. struct statfs kbuf;
  1232. int error, i;
  1233. printk("[%s:%d] Wheee.. irix_statvfs(%s,%p)n",
  1234.        current->comm, current->pid, fname, buf);
  1235. error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
  1236. if (error)
  1237. goto out;
  1238. error = user_path_walk(fname, &nd);
  1239. if (error)
  1240. goto out;
  1241. error = vfs_statfs(nd.dentry->d_inode->i_sb, &kbuf);
  1242. if (error)
  1243. goto dput_and_out;
  1244. __put_user(kbuf.f_bsize, &buf->f_bsize);
  1245. __put_user(kbuf.f_frsize, &buf->f_frsize);
  1246. __put_user(kbuf.f_blocks, &buf->f_blocks);
  1247. __put_user(kbuf.f_bfree, &buf->f_bfree);
  1248. __put_user(kbuf.f_bfree, &buf->f_bavail);  /* XXX hackety hack... */
  1249. __put_user(kbuf.f_files, &buf->f_files);
  1250. __put_user(kbuf.f_ffree, &buf->f_ffree);
  1251. __put_user(kbuf.f_ffree, &buf->f_favail);  /* XXX hackety hack... */
  1252. #ifdef __MIPSEB__
  1253. __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
  1254. #else
  1255. __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
  1256. #endif
  1257. for (i = 0; i < 16; i++)
  1258. __put_user(0, &buf->f_basetype[i]);
  1259. __put_user(0, &buf->f_flag);
  1260. __put_user(kbuf.f_namelen, &buf->f_namemax);
  1261. for (i = 0; i < 32; i++)
  1262. __put_user(0, &buf->f_fstr[i]);
  1263. error = 0;
  1264. dput_and_out:
  1265. path_release(&nd);
  1266. out:
  1267. return error;
  1268. }
  1269. asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs *buf)
  1270. {
  1271. struct statfs kbuf;
  1272. struct file *file;
  1273. int error, i;
  1274. printk("[%s:%d] Wheee.. irix_fstatvfs(%d,%p)n",
  1275.        current->comm, current->pid, fd, buf);
  1276. error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
  1277. if (error)
  1278. goto out;
  1279. if (!(file = fget(fd))) {
  1280. error = -EBADF;
  1281. goto out;
  1282. }
  1283. error = vfs_statfs(file->f_dentry->d_inode->i_sb, &kbuf);
  1284. if (error)
  1285. goto out_f;
  1286. __put_user(kbuf.f_bsize, &buf->f_bsize);
  1287. __put_user(kbuf.f_frsize, &buf->f_frsize);
  1288. __put_user(kbuf.f_blocks, &buf->f_blocks);
  1289. __put_user(kbuf.f_bfree, &buf->f_bfree);
  1290. __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */
  1291. __put_user(kbuf.f_files, &buf->f_files);
  1292. __put_user(kbuf.f_ffree, &buf->f_ffree);
  1293. __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */
  1294. #ifdef __MIPSEB__
  1295. __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
  1296. #else
  1297. __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
  1298. #endif
  1299. for(i = 0; i < 16; i++)
  1300. __put_user(0, &buf->f_basetype[i]);
  1301. __put_user(0, &buf->f_flag);
  1302. __put_user(kbuf.f_namelen, &buf->f_namemax);
  1303. __clear_user(&buf->f_fstr, sizeof(buf->f_fstr));
  1304. out_f:
  1305. fput(file);
  1306. out:
  1307. return error;
  1308. }
  1309. asmlinkage int irix_priocntl(struct pt_regs *regs)
  1310. {
  1311. printk("[%s:%d] Wheee.. irix_priocntl()n",
  1312.        current->comm, current->pid);
  1313. return -EINVAL;
  1314. }
  1315. asmlinkage int irix_sigqueue(int pid, int sig, int code, int val)
  1316. {
  1317. printk("[%s:%d] Wheee.. irix_sigqueue(%d,%d,%d,%d)n",
  1318.        current->comm, current->pid, pid, sig, code, val);
  1319. return -EINVAL;
  1320. }
  1321. extern asmlinkage int sys_truncate(const char * path, unsigned long length);
  1322. extern asmlinkage int sys_ftruncate(unsigned int fd, unsigned long length);
  1323. asmlinkage int irix_truncate64(char *name, int pad, int size1, int size2)
  1324. {
  1325. int retval;
  1326. if (size1) {
  1327. retval = -EINVAL;
  1328. goto out;
  1329. }
  1330. retval = sys_truncate(name, size2);
  1331. out:
  1332. return retval;
  1333. }
  1334. asmlinkage int irix_ftruncate64(int fd, int pad, int size1, int size2)
  1335. {
  1336. int retval;
  1337. if (size1) {
  1338. retval = -EINVAL;
  1339. goto out;
  1340. }
  1341. retval = sys_ftruncate(fd, size2);
  1342. out:
  1343. return retval;
  1344. }
  1345. extern asmlinkage unsigned long
  1346. sys_mmap(unsigned long addr, size_t len, int prot, int flags, int fd,
  1347.          off_t offset);
  1348. asmlinkage int irix_mmap64(struct pt_regs *regs)
  1349. {
  1350. int len, prot, flags, fd, off1, off2, error, base = 0;
  1351. unsigned long addr, pgoff, *sp;
  1352. struct file *file = NULL;
  1353. if (regs->regs[2] == 1000)
  1354. base = 1;
  1355. sp = (unsigned long *) (regs->regs[29] + 16);
  1356. addr = regs->regs[base + 4];
  1357. len = regs->regs[base + 5];
  1358. prot = regs->regs[base + 6];
  1359. if (!base) {
  1360. flags = regs->regs[base + 7];
  1361. error = verify_area(VERIFY_READ, sp, (4 * sizeof(unsigned long)));
  1362. if(error)
  1363. goto out;
  1364. fd = sp[0];
  1365. __get_user(off1, &sp[1]);
  1366. __get_user(off2, &sp[2]);
  1367. } else {
  1368. error = verify_area(VERIFY_READ, sp, (5 * sizeof(unsigned long)));
  1369. if(error)
  1370. goto out;
  1371. __get_user(flags, &sp[0]);
  1372. __get_user(fd, &sp[1]);
  1373. __get_user(off1, &sp[2]);
  1374. __get_user(off2, &sp[3]);
  1375. }
  1376. if (off1 & PAGE_MASK) {
  1377. error = -EOVERFLOW;
  1378. goto out;
  1379. }
  1380. pgoff = (off1 << (32 - PAGE_SHIFT)) | (off2 >> PAGE_SHIFT);
  1381. if (!(flags & MAP_ANONYMOUS)) {
  1382. if (!(file = fget(fd))) {
  1383. error = -EBADF;
  1384. goto out;
  1385. }
  1386. /* Ok, bad taste hack follows, try to think in something else
  1387.    when reading this */
  1388. if (flags & IRIX_MAP_AUTOGROW) {
  1389. unsigned long old_pos;
  1390. long max_size = off2 + len;
  1391. if (max_size > file->f_dentry->d_inode->i_size) {
  1392. old_pos = sys_lseek (fd, max_size - 1, 0);
  1393. sys_write (fd, "", 1);
  1394. sys_lseek (fd, old_pos, 0);
  1395. }
  1396. }
  1397. }
  1398. flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
  1399. down_write(&current->mm->mmap_sem);
  1400. error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
  1401. up_write(&current->mm->mmap_sem);
  1402. if (file)
  1403. fput(file);
  1404. out:
  1405. return error;
  1406. }
  1407. asmlinkage int irix_dmi(struct pt_regs *regs)
  1408. {
  1409. printk("[%s:%d] Wheee.. irix_dmi()n",
  1410.        current->comm, current->pid);
  1411. return -EINVAL;
  1412. }
  1413. asmlinkage int irix_pread(int fd, char *buf, int cnt, int off64,
  1414.   int off1, int off2)
  1415. {
  1416. printk("[%s:%d] Wheee.. irix_pread(%d,%p,%d,%d,%d,%d)n",
  1417.        current->comm, current->pid, fd, buf, cnt, off64, off1, off2);
  1418. return -EINVAL;
  1419. }
  1420. asmlinkage int irix_pwrite(int fd, char *buf, int cnt, int off64,
  1421.    int off1, int off2)
  1422. {
  1423. printk("[%s:%d] Wheee.. irix_pwrite(%d,%p,%d,%d,%d,%d)n",
  1424.        current->comm, current->pid, fd, buf, cnt, off64, off1, off2);
  1425. return -EINVAL;
  1426. }
  1427. asmlinkage int irix_sgifastpath(int cmd, unsigned long arg0, unsigned long arg1,
  1428. unsigned long arg2, unsigned long arg3,
  1429. unsigned long arg4, unsigned long arg5)
  1430. {
  1431. printk("[%s:%d] Wheee.. irix_fastpath(%d,%08lx,%08lx,%08lx,%08lx,"
  1432.        "%08lx,%08lx)n",
  1433.        current->comm, current->pid, cmd, arg0, arg1, arg2,
  1434.        arg3, arg4, arg5);
  1435. return -EINVAL;
  1436. }
  1437. struct irix_statvfs64 {
  1438. u32  f_bsize; u32 f_frsize;
  1439. u64  f_blocks; u64 f_bfree; u64 f_bavail;
  1440. u64  f_files; u64 f_ffree; u64 f_favail;
  1441. u32  f_fsid;
  1442. char f_basetype[16];
  1443. u32  f_flag; u32 f_namemax;
  1444. char f_fstr[32];
  1445. u32  f_filler[16];
  1446. };
  1447. asmlinkage int irix_statvfs64(char *fname, struct irix_statvfs64 *buf)
  1448. {
  1449. struct nameidata nd;
  1450. struct statfs kbuf;
  1451. int error, i;
  1452. printk("[%s:%d] Wheee.. irix_statvfs(%s,%p)n",
  1453.        current->comm, current->pid, fname, buf);
  1454. error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
  1455. if(error)
  1456. goto out;
  1457. error = user_path_walk(fname, &nd);
  1458. if (error)
  1459. goto out;
  1460. error = vfs_statfs(nd.dentry->d_inode->i_sb, &kbuf);
  1461. if (error)
  1462. goto dput_and_out;
  1463. __put_user(kbuf.f_bsize, &buf->f_bsize);
  1464. __put_user(kbuf.f_frsize, &buf->f_frsize);
  1465. __put_user(kbuf.f_blocks, &buf->f_blocks);
  1466. __put_user(kbuf.f_bfree, &buf->f_bfree);
  1467. __put_user(kbuf.f_bfree, &buf->f_bavail);  /* XXX hackety hack... */
  1468. __put_user(kbuf.f_files, &buf->f_files);
  1469. __put_user(kbuf.f_ffree, &buf->f_ffree);
  1470. __put_user(kbuf.f_ffree, &buf->f_favail);  /* XXX hackety hack... */
  1471. #ifdef __MIPSEB__
  1472. __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
  1473. #else
  1474. __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
  1475. #endif
  1476. for(i = 0; i < 16; i++)
  1477. __put_user(0, &buf->f_basetype[i]);
  1478. __put_user(0, &buf->f_flag);
  1479. __put_user(kbuf.f_namelen, &buf->f_namemax);
  1480. for(i = 0; i < 32; i++)
  1481. __put_user(0, &buf->f_fstr[i]);
  1482. error = 0;
  1483. dput_and_out:
  1484. path_release(&nd);
  1485. out:
  1486. return error;
  1487. }
  1488. asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs *buf)
  1489. {
  1490. struct statfs kbuf;
  1491. struct file *file;
  1492. int error, i;
  1493. printk("[%s:%d] Wheee.. irix_fstatvfs(%d,%p)n",
  1494.        current->comm, current->pid, fd, buf);
  1495. error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
  1496. if (error)
  1497. goto out;
  1498. if (!(file = fget(fd))) {
  1499. error = -EBADF;
  1500. goto out;
  1501. }
  1502. error = vfs_statfs(file->f_dentry->d_inode->i_sb, &kbuf);
  1503. if (error)
  1504. goto out_f;
  1505. __put_user(kbuf.f_bsize, &buf->f_bsize);
  1506. __put_user(kbuf.f_frsize, &buf->f_frsize);
  1507. __put_user(kbuf.f_blocks, &buf->f_blocks);
  1508. __put_user(kbuf.f_bfree, &buf->f_bfree);
  1509. __put_user(kbuf.f_bfree, &buf->f_bavail);  /* XXX hackety hack... */
  1510. __put_user(kbuf.f_files, &buf->f_files);
  1511. __put_user(kbuf.f_ffree, &buf->f_ffree);
  1512. __put_user(kbuf.f_ffree, &buf->f_favail);  /* XXX hackety hack... */
  1513. #ifdef __MIPSEB__
  1514. __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
  1515. #else
  1516. __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
  1517. #endif
  1518. for(i = 0; i < 16; i++)
  1519. __put_user(0, &buf->f_basetype[i]);
  1520. __put_user(0, &buf->f_flag);
  1521. __put_user(kbuf.f_namelen, &buf->f_namemax);
  1522. __clear_user(buf->f_fstr, sizeof(buf->f_fstr[i]));
  1523. out_f:
  1524. fput(file);
  1525. out:
  1526. return error;
  1527. }
  1528. asmlinkage int irix_getmountid(char *fname, unsigned long *midbuf)
  1529. {
  1530. int err;
  1531. printk("[%s:%d] irix_getmountid(%s, %p)n",
  1532.        current->comm, current->pid, fname, midbuf);
  1533. err = verify_area(VERIFY_WRITE, midbuf, (sizeof(unsigned long) * 4));
  1534. if (err)
  1535. return err;
  1536. /*
  1537.  * The idea with this system call is that when trying to determine
  1538.  * 'pwd' and it's a toss-up for some reason, userland can use the
  1539.  * fsid of the filesystem to try and make the right decision, but
  1540.  * we don't have this so for now. XXX
  1541.  */
  1542. err |= __put_user(0, &midbuf[0]);
  1543. err |= __put_user(0, &midbuf[1]);
  1544. err |= __put_user(0, &midbuf[2]);
  1545. err |= __put_user(0, &midbuf[3]);
  1546. return err;
  1547. }
  1548. asmlinkage int irix_nsproc(unsigned long entry, unsigned long mask,
  1549.    unsigned long arg, unsigned long sp, int slen)
  1550. {
  1551. printk("[%s:%d] Wheee.. irix_nsproc(%08lx,%08lx,%08lx,%08lx,%d)n",
  1552.        current->comm, current->pid, entry, mask, arg, sp, slen);
  1553. return -EINVAL;
  1554. }
  1555. #undef DEBUG_GETDENTS
  1556. struct irix_dirent32 {
  1557. u32  d_ino;
  1558. u32  d_off;
  1559. unsigned short  d_reclen;
  1560. char d_name[1];
  1561. };
  1562. struct irix_dirent32_callback {
  1563. struct irix_dirent32 *current_dir;
  1564. struct irix_dirent32 *previous;
  1565. int count;
  1566. int error;
  1567. };
  1568. #define NAME_OFFSET32(de) ((int) ((de)->d_name - (char *) (de)))
  1569. #define ROUND_UP32(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
  1570. static int irix_filldir32(void *__buf, const char *name, int namlen,
  1571.                           loff_t offset, ino_t ino, unsigned int d_type)
  1572. {
  1573. struct irix_dirent32 *dirent;
  1574. struct irix_dirent32_callback *buf =
  1575.  (struct irix_dirent32_callback *)__buf;
  1576. unsigned short reclen = ROUND_UP32(NAME_OFFSET32(dirent) + namlen + 1);
  1577. #ifdef DEBUG_GETDENTS
  1578. printk("nirix_filldir32[reclen<%d>namlen<%d>count<%d>]",
  1579.        reclen, namlen, buf->count);
  1580. #endif
  1581. buf->error = -EINVAL; /* only used if we fail.. */
  1582. if (reclen > buf->count)
  1583. return -EINVAL;
  1584. dirent = buf->previous;
  1585. if (dirent)
  1586. __put_user(offset, &dirent->d_off);
  1587. dirent = buf->current_dir;
  1588. buf->previous = dirent;
  1589. __put_user(ino, &dirent->d_ino);
  1590. __put_user(reclen, &dirent->d_reclen);
  1591. copy_to_user(dirent->d_name, name, namlen);
  1592. __put_user(0, &dirent->d_name[namlen]);
  1593. ((char *) dirent) += reclen;
  1594. buf->current_dir = dirent;
  1595. buf->count -= reclen;
  1596. return 0;
  1597. }
  1598. asmlinkage int irix_ngetdents(unsigned int fd, void * dirent,
  1599. unsigned int count, int *eob)
  1600. {
  1601. struct file *file;
  1602. struct irix_dirent32 *lastdirent;
  1603. struct irix_dirent32_callback buf;
  1604. int error;
  1605. #ifdef DEBUG_GETDENTS
  1606. printk("[%s:%d] ngetdents(%d, %p, %d, %p) ", current->comm,
  1607.        current->pid, fd, dirent, count, eob);
  1608. #endif
  1609. error = -EBADF;
  1610. file = fget(fd);
  1611. if (!file)
  1612. goto out;
  1613. buf.current_dir = (struct irix_dirent32 *) dirent;
  1614. buf.previous = NULL;
  1615. buf.count = count;
  1616. buf.error = 0;
  1617. error = vfs_readdir(file, irix_filldir32, &buf);
  1618. if (error < 0)
  1619. goto out_putf;
  1620. error = buf.error;
  1621. lastdirent = buf.previous;
  1622. if (lastdirent) {
  1623. put_user(file->f_pos, &lastdirent->d_off);
  1624. error = count - buf.count;
  1625. }
  1626. if (put_user(0, eob) < 0) {
  1627. error = -EFAULT;
  1628. goto out_putf;
  1629. }
  1630. #ifdef DEBUG_GETDENTS
  1631. printk("eob=%d returning %dn", *eob, count - buf.count);
  1632. #endif
  1633. error = count - buf.count;
  1634. out_putf:
  1635. fput(file);
  1636. out:
  1637. return error;
  1638. }
  1639. struct irix_dirent64 {
  1640. u64            d_ino;
  1641. u64            d_off;
  1642. unsigned short d_reclen;
  1643. char           d_name[1];
  1644. };
  1645. struct irix_dirent64_callback {
  1646. struct irix_dirent64 *curr;
  1647. struct irix_dirent64 *previous;
  1648. int count;
  1649. int error;
  1650. };
  1651. #define NAME_OFFSET64(de) ((int) ((de)->d_name - (char *) (de)))
  1652. #define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1))
  1653. static int irix_filldir64(void * __buf, const char * name, int namlen,
  1654.   loff_t offset, ino_t ino, unsigned int d_type)
  1655. {
  1656. struct irix_dirent64 *dirent;
  1657. struct irix_dirent64_callback * buf =
  1658. (struct irix_dirent64_callback *) __buf;
  1659. unsigned short reclen = ROUND_UP64(NAME_OFFSET64(dirent) + namlen + 1);
  1660. buf->error = -EINVAL; /* only used if we fail.. */
  1661. if (reclen > buf->count)
  1662. return -EINVAL;
  1663. dirent = buf->previous;
  1664. if (dirent)
  1665. __put_user(offset, &dirent->d_off);
  1666. dirent = buf->curr;
  1667. buf->previous = dirent;
  1668. __put_user(ino, &dirent->d_ino);
  1669. __put_user(reclen, &dirent->d_reclen);
  1670. __copy_to_user(dirent->d_name, name, namlen);
  1671. __put_user(0, &dirent->d_name[namlen]);
  1672. ((char *) dirent) += reclen;
  1673. buf->curr = dirent;
  1674. buf->count -= reclen;
  1675. return 0;
  1676. }
  1677. asmlinkage int irix_getdents64(int fd, void *dirent, int cnt)
  1678. {
  1679. struct file *file;
  1680. struct irix_dirent64 *lastdirent;
  1681. struct irix_dirent64_callback buf;
  1682. int error;
  1683. #ifdef DEBUG_GETDENTS
  1684. printk("[%s:%d] getdents64(%d, %p, %d) ", current->comm,
  1685.        current->pid, fd, dirent, cnt);
  1686. #endif
  1687. error = -EBADF;
  1688. if (!(file = fget(fd)))
  1689. goto out;
  1690. error = -EFAULT;
  1691. if (!access_ok(VERIFY_WRITE, dirent, cnt))
  1692. goto out_f;
  1693. error = -EINVAL;
  1694. if (cnt < (sizeof(struct irix_dirent64) + 255))
  1695. goto out_f;
  1696. buf.curr = (struct irix_dirent64 *) dirent;
  1697. buf.previous = NULL;
  1698. buf.count = cnt;
  1699. buf.error = 0;
  1700. error = vfs_readdir(file, irix_filldir64, &buf);
  1701. if (error < 0)
  1702. goto out_f;
  1703. lastdirent = buf.previous;
  1704. if (!lastdirent) {
  1705. error = buf.error;
  1706. goto out_f;
  1707. }
  1708. lastdirent->d_off = (u64) file->f_pos;
  1709. #ifdef DEBUG_GETDENTS
  1710. printk("returning %dn", cnt - buf.count);
  1711. #endif
  1712. error = cnt - buf.count;
  1713. out_f:
  1714. fput(file);
  1715. out:
  1716. return error;
  1717. }
  1718. asmlinkage int irix_ngetdents64(int fd, void *dirent, int cnt, int *eob)
  1719. {
  1720. struct file *file;
  1721. struct irix_dirent64 *lastdirent;
  1722. struct irix_dirent64_callback buf;
  1723. int error;
  1724. #ifdef DEBUG_GETDENTS
  1725. printk("[%s:%d] ngetdents64(%d, %p, %d) ", current->comm,
  1726.        current->pid, fd, dirent, cnt);
  1727. #endif
  1728. error = -EBADF;
  1729. if (!(file = fget(fd)))
  1730. goto out;
  1731. error = -EFAULT;
  1732. if (!access_ok(VERIFY_WRITE, dirent, cnt) ||
  1733.     !access_ok(VERIFY_WRITE, eob, sizeof(*eob)))
  1734. goto out_f;
  1735. error = -EINVAL;
  1736. if (cnt < (sizeof(struct irix_dirent64) + 255))
  1737. goto out_f;
  1738. *eob = 0;
  1739. buf.curr = (struct irix_dirent64 *) dirent;
  1740. buf.previous = NULL;
  1741. buf.count = cnt;
  1742. buf.error = 0;
  1743. error = vfs_readdir(file, irix_filldir64, &buf);
  1744. if (error < 0)
  1745. goto out_f;
  1746. lastdirent = buf.previous;
  1747. if (!lastdirent) {
  1748. error = buf.error;
  1749. goto out_f;
  1750. }
  1751. lastdirent->d_off = (u64) file->f_pos;
  1752. #ifdef DEBUG_GETDENTS
  1753. printk("eob=%d returning %dn", *eob, cnt - buf.count);
  1754. #endif
  1755. error = cnt - buf.count;
  1756. out_f:
  1757. fput(file);
  1758. out:
  1759. return error;
  1760. }
  1761. asmlinkage int irix_uadmin(unsigned long op, unsigned long func, unsigned long arg)
  1762. {
  1763. int retval;
  1764. switch (op) {
  1765. case 1:
  1766. /* Reboot */
  1767. printk("[%s:%d] irix_uadmin: Wants to reboot...n",
  1768.        current->comm, current->pid);
  1769. retval = -EINVAL;
  1770. goto out;
  1771. case 2:
  1772. /* Shutdown */
  1773. printk("[%s:%d] irix_uadmin: Wants to shutdown...n",
  1774.        current->comm, current->pid);
  1775. retval = -EINVAL;
  1776. goto out;
  1777. case 4:
  1778. /* Remount-root */
  1779. printk("[%s:%d] irix_uadmin: Wants to remount root...n",
  1780.        current->comm, current->pid);
  1781. retval = -EINVAL;
  1782. goto out;
  1783. case 8:
  1784. /* Kill all tasks. */
  1785. printk("[%s:%d] irix_uadmin: Wants to kill all tasks...n",
  1786.        current->comm, current->pid);
  1787. retval = -EINVAL;
  1788. goto out;
  1789. case 256:
  1790. /* Set magic mushrooms... */
  1791. printk("[%s:%d] irix_uadmin: Wants to set magic mushroom[%d]...n",
  1792.        current->comm, current->pid, (int) func);
  1793. retval = -EINVAL;
  1794. goto out;
  1795. default:
  1796. printk("[%s:%d] irix_uadmin: Unknown operation [%d]...n",
  1797.        current->comm, current->pid, (int) op);
  1798. retval = -EINVAL;
  1799. goto out;
  1800. };
  1801. out:
  1802. return retval;
  1803. }
  1804. asmlinkage int irix_utssys(char *inbuf, int arg, int type, char *outbuf)
  1805. {
  1806. int retval;
  1807. switch(type) {
  1808. case 0:
  1809. /* uname() */
  1810. retval = irix_uname((struct iuname *)inbuf);
  1811. goto out;
  1812. case 2:
  1813. /* ustat() */
  1814. printk("[%s:%d] irix_utssys: Wants to do ustat()n",
  1815.        current->comm, current->pid);
  1816. retval = -EINVAL;
  1817. goto out;
  1818. case 3:
  1819. /* fusers() */
  1820. printk("[%s:%d] irix_utssys: Wants to do fusers()n",
  1821.        current->comm, current->pid);
  1822. retval = -EINVAL;
  1823. goto out;
  1824. default:
  1825. printk("[%s:%d] irix_utssys: Wants to do unknown type[%d]n",
  1826.        current->comm, current->pid, (int) type);
  1827. retval = -EINVAL;
  1828. goto out;
  1829. }
  1830. out:
  1831. return retval;
  1832. }
  1833. #undef DEBUG_FCNTL
  1834. extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd,
  1835.  unsigned long arg);
  1836. #define IRIX_F_ALLOCSP 10
  1837. asmlinkage int irix_fcntl(int fd, int cmd, int arg)
  1838. {
  1839. int retval;
  1840. #ifdef DEBUG_FCNTL
  1841. printk("[%s:%d] irix_fcntl(%d, %d, %d) ", current->comm,
  1842.        current->pid, fd, cmd, arg);
  1843. #endif
  1844. if (cmd == IRIX_F_ALLOCSP){
  1845. return 0;
  1846. }
  1847. retval = sys_fcntl(fd, cmd, arg);
  1848. #ifdef DEBUG_FCNTL
  1849. printk("%dn", retval);
  1850. #endif
  1851. return retval;
  1852. }
  1853. asmlinkage int irix_ulimit(int cmd, int arg)
  1854. {
  1855. int retval;
  1856. switch(cmd) {
  1857. case 1:
  1858. printk("[%s:%d] irix_ulimit: Wants to get file size limit.n",
  1859.        current->comm, current->pid);
  1860. retval = -EINVAL;
  1861. goto out;
  1862. case 2:
  1863. printk("[%s:%d] irix_ulimit: Wants to set file size limit.n",
  1864.        current->comm, current->pid);
  1865. retval = -EINVAL;
  1866. goto out;
  1867. case 3:
  1868. printk("[%s:%d] irix_ulimit: Wants to get brk limit.n",
  1869.        current->comm, current->pid);
  1870. retval = -EINVAL;
  1871. goto out;
  1872. case 4:
  1873. #if 0
  1874. printk("[%s:%d] irix_ulimit: Wants to get fd limit.n",
  1875.        current->comm, current->pid);
  1876. retval = -EINVAL;
  1877. goto out;
  1878. #endif
  1879. retval = current->rlim[RLIMIT_NOFILE].rlim_cur;
  1880. goto out;
  1881. case 5:
  1882. printk("[%s:%d] irix_ulimit: Wants to get txt offset.n",
  1883.        current->comm, current->pid);
  1884. retval = -EINVAL;
  1885. goto out;
  1886. default:
  1887. printk("[%s:%d] irix_ulimit: Unknown command [%d].n",
  1888.        current->comm, current->pid, cmd);
  1889. retval = -EINVAL;
  1890. goto out;
  1891. }
  1892. out:
  1893. return retval;
  1894. }
  1895. asmlinkage int irix_unimp(struct pt_regs *regs)
  1896. {
  1897. printk("irix_unimp [%s:%d] v0=%d v1=%d a0=%08lx a1=%08lx a2=%08lx "
  1898.        "a3=%08lxn", current->comm, current->pid,
  1899.        (int) regs->regs[2], (int) regs->regs[3],
  1900.        regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
  1901. return -ENOSYS;
  1902. }