cosmetics
[unix-history] / usr / src / sys / ufs / ffs / ffs_vnops.c
CommitLineData
64d3a787 1/* ffs_vnops.c 4.31 82/07/25 */
6459ebe0 2
d67a03eb
BJ
3#include "../h/param.h"
4#include "../h/systm.h"
d67a03eb
BJ
5#include "../h/dir.h"
6#include "../h/user.h"
d67a03eb 7#include "../h/file.h"
6459ebe0 8#include "../h/stat.h"
3e78e260 9#include "../h/inode.h"
6459ebe0 10#include "../h/fs.h"
3e78e260 11#include "../h/buf.h"
3e78e260 12#include "../h/proc.h"
0737b714 13#include "../h/inline.h"
f94ceb3b
BJ
14#ifdef EFS
15#include "../net/in.h"
16#include "../h/efs.h"
17#endif
0a77f278 18#include "../h/quota.h"
4147b3f6 19#include "../h/descrip.h"
3e78e260
BJ
20
21chdir()
22{
23
24 chdirec(&u.u_cdir);
25}
26
27chroot()
28{
29
30 if (suser())
31 chdirec(&u.u_rdir);
32}
33
34chdirec(ipp)
35register struct inode **ipp;
36{
37 register struct inode *ip;
38 struct a {
39 char *fname;
40 };
41
42 ip = namei(uchar, 0, 1);
43 if(ip == NULL)
44 return;
45 if((ip->i_mode&IFMT) != IFDIR) {
46 u.u_error = ENOTDIR;
47 goto bad;
48 }
49 if(access(ip, IEXEC))
50 goto bad;
ca91bded 51 iunlock(ip);
8eee8525
KM
52 if (*ipp)
53 irele(*ipp);
3e78e260
BJ
54 *ipp = ip;
55 return;
56
57bad:
58 iput(ip);
59}
60
61/*
62 * Open system call.
63 */
64open()
65{
66 register struct inode *ip;
67 register struct a {
68 char *fname;
69 int rwmode;
70 } *uap;
71
72 uap = (struct a *)u.u_ap;
73 ip = namei(uchar, 0, 1);
74 if (ip == NULL)
75 return;
76 open1(ip, ++uap->rwmode, 0);
77}
78
79/*
80 * Creat system call.
81 */
4147b3f6 82ocreat()
3e78e260
BJ
83{
84 register struct inode *ip;
85 register struct a {
86 char *fname;
87 int fmode;
88 } *uap;
89
90 uap = (struct a *)u.u_ap;
91 ip = namei(uchar, 1, 1);
92 if (ip == NULL) {
93 if (u.u_error)
94 return;
95 ip = maknode(uap->fmode&07777&(~ISVTX));
96 if (ip==NULL)
97 return;
98 open1(ip, FWRITE, 2);
99 } else
100 open1(ip, FWRITE, 1);
101}
102
103/*
104 * Common code for open and creat.
105 * Check permissions, allocate an open file structure,
106 * and call the device open routine if any.
107 */
108open1(ip, mode, trf)
109 register struct inode *ip;
110 register mode;
111{
112 register struct file *fp;
113 int i;
114
115 if (trf != 2) {
116 if (mode&FREAD)
117 (void) access(ip, IREAD);
118 if (mode&FWRITE) {
119 (void) access(ip, IWRITE);
120 if ((ip->i_mode&IFMT) == IFDIR)
121 u.u_error = EISDIR;
122 }
123 }
8eee8525
KM
124 if (u.u_error) {
125 iput(ip);
126 return;
127 }
3e78e260
BJ
128 if (trf == 1)
129 itrunc(ip);
ca91bded 130 iunlock(ip);
3e78e260
BJ
131 if ((fp = falloc()) == NULL)
132 goto out;
133 fp->f_flag = mode&(FREAD|FWRITE);
4147b3f6 134 fp->f_type = DTYPE_FILE;
3e78e260
BJ
135 i = u.u_r.r_val1;
136 fp->f_inode = ip;
f94ceb3b
BJ
137#ifdef EFS
138 openi(ip, mode&(FREAD|FWRITE), trf);
139#else
3e78e260 140 openi(ip, mode&(FREAD|FWRITE));
f94ceb3b 141#endif
3e78e260
BJ
142 if (u.u_error == 0)
143 return;
144 u.u_ofile[i] = NULL;
145 fp->f_count--;
146out:
8eee8525 147 irele(ip);
3e78e260
BJ
148}
149
150/*
151 * Mknod system call
152 */
153mknod()
154{
155 register struct inode *ip;
156 register struct a {
157 char *fname;
158 int fmode;
159 int dev;
160 } *uap;
161
162 uap = (struct a *)u.u_ap;
163 if (suser()) {
164 ip = namei(uchar, 1, 0);
165 if (ip != NULL) {
166 u.u_error = EEXIST;
167 goto out;
168 }
169 }
170 if (u.u_error)
171 return;
172 ip = maknode(uap->fmode);
173 if (ip == NULL)
174 return;
175 if (uap->dev) {
176 /*
177 * Want to be able to use this to make badblock
178 * inodes, so don't truncate the dev number.
179 */
6459ebe0 180 ip->i_rdev = uap->dev;
3e78e260
BJ
181 ip->i_flag |= IACC|IUPD|ICHG;
182 }
183
184out:
185 iput(ip);
186}
187
188/*
189 * link system call
190 */
191link()
192{
193 register struct inode *ip, *xp;
194 register struct a {
195 char *target;
196 char *linkname;
197 } *uap;
198
199 uap = (struct a *)u.u_ap;
200 ip = namei(uchar, 0, 1); /* well, this routine is doomed anyhow */
201 if (ip == NULL)
202 return;
f94ceb3b
BJ
203 if ((ip->i_mode&IFMT)==IFDIR && !suser()) {
204 iput(ip);
205 return;
206 }
3e78e260
BJ
207 ip->i_nlink++;
208 ip->i_flag |= ICHG;
209 iupdat(ip, &time, &time, 1);
ca91bded 210 iunlock(ip);
3e78e260
BJ
211 u.u_dirp = (caddr_t)uap->linkname;
212 xp = namei(uchar, 1, 0);
213 if (xp != NULL) {
214 u.u_error = EEXIST;
215 iput(xp);
216 goto out;
217 }
218 if (u.u_error)
219 goto out;
220 if (u.u_pdir->i_dev != ip->i_dev) {
221 iput(u.u_pdir);
222 u.u_error = EXDEV;
223 goto out;
224 }
64d3a787 225 direnter(ip);
3e78e260
BJ
226out:
227 if (u.u_error) {
228 ip->i_nlink--;
229 ip->i_flag |= ICHG;
230 }
231out1:
8eee8525 232 irele(ip);
3e78e260
BJ
233}
234
235/*
236 * symlink -- make a symbolic link
237 */
238symlink()
239{
240 register struct a {
241 char *target;
242 char *linkname;
243 } *uap;
244 register struct inode *ip;
245 register char *tp;
246 register c, nc;
247
248 uap = (struct a *)u.u_ap;
249 tp = uap->target;
250 nc = 0;
251 while (c = fubyte(tp)) {
252 if (c < 0) {
253 u.u_error = EFAULT;
254 return;
255 }
256 tp++;
257 nc++;
258 }
259 u.u_dirp = uap->linkname;
260 ip = namei(uchar, 1, 0);
261 if (ip) {
262 iput(ip);
263 u.u_error = EEXIST;
264 return;
265 }
266 if (u.u_error)
267 return;
268 ip = maknode(IFLNK | 0777);
269 if (ip == NULL)
270 return;
271 u.u_base = uap->target;
272 u.u_count = nc;
273 u.u_offset = 0;
274 u.u_segflg = 0;
275 writei(ip);
276 iput(ip);
277}
278
279/*
280 * Unlink system call.
281 * Hard to avoid races here, especially
282 * in unlinking directories.
283 */
284unlink()
285{
286 register struct inode *ip, *pp;
287 struct a {
288 char *fname;
289 };
6459ebe0
KM
290 struct fs *fs;
291 struct buf *bp;
292 int lbn, bn, base;
8eee8525 293 int unlinkingdot = 0;
3e78e260
BJ
294
295 pp = namei(uchar, 2, 0);
64d3a787 296 if (pp == NULL)
3e78e260 297 return;
f94ceb3b
BJ
298#ifdef EFS
299 /* divert to extended file system if off machine. */
300 if (efsinode(pp)) {
301 dev_t ndev = pp->i_rdev;
302
303 iput(pp); /* avoid recursive hang on inode */
304 efsunlink(ndev);
305 if (u.u_error != EEXIST)
306 return;
307
308 /*
309 * If a null pathname remainder, then do
310 * the unlink locally after restoring state.
311 */
312 u.u_error = 0;
313 u.u_dirp = (caddr_t)u.u_arg[0];
314 pp = namei(uchar, 2, 0);
315 }
316#endif
317
3e78e260
BJ
318 /*
319 * Check for unlink(".")
320 * to avoid hanging on the iget
321 */
322 if (pp->i_number == u.u_dent.d_ino) {
323 ip = pp;
324 ip->i_count++;
8eee8525 325 unlinkingdot++;
3e78e260 326 } else
6459ebe0 327 ip = iget(pp->i_dev, pp->i_fs, u.u_dent.d_ino);
3e78e260
BJ
328 if(ip == NULL)
329 goto out1;
330 if((ip->i_mode&IFMT)==IFDIR && !suser())
331 goto out;
332 /*
333 * Don't unlink a mounted file.
334 */
335 if (ip->i_dev != pp->i_dev) {
336 u.u_error = EBUSY;
337 goto out;
338 }
339 if (ip->i_flag&ITEXT)
340 xrele(ip); /* try once to free text */
64d3a787
BJ
341 if (dirremove()) {
342 ip->i_nlink--;
343 ip->i_flag |= ICHG;
6459ebe0 344 }
3e78e260 345out:
8eee8525
KM
346 if (unlinkingdot)
347 irele(ip);
348 else
349 iput(ip);
3e78e260
BJ
350out1:
351 iput(pp);
352}
353
354/*
355 * Seek system call
356 */
357seek()
358{
359 register struct file *fp;
360 register struct a {
361 int fdes;
362 off_t off;
363 int sbase;
364 } *uap;
365
366 uap = (struct a *)u.u_ap;
367 fp = getf(uap->fdes);
368 if (fp == NULL)
369 return;
4147b3f6 370 if (fp->f_type == DTYPE_SOCKET) {
3e78e260
BJ
371 u.u_error = ESPIPE;
372 return;
373 }
374 if (uap->sbase == 1)
375 uap->off += fp->f_offset;
f94ceb3b
BJ
376 else if (uap->sbase == 2) {
377#ifdef EFS
378 struct inode *ip = fp->f_inode;
379 uap->off += efsinode(ip) ? efsfilesize(fp) : ip->i_size;
380#else
3e78e260 381 uap->off += fp->f_inode->i_size;
f94ceb3b
BJ
382#endif
383 }
3e78e260
BJ
384 fp->f_offset = uap->off;
385 u.u_r.r_off = uap->off;
386}
387
388/*
389 * Access system call
390 */
391saccess()
392{
393 register svuid, svgid;
394 register struct inode *ip;
395 register struct a {
396 char *fname;
397 int fmode;
398 } *uap;
399
400 uap = (struct a *)u.u_ap;
401 svuid = u.u_uid;
402 svgid = u.u_gid;
403 u.u_uid = u.u_ruid;
404 u.u_gid = u.u_rgid;
405 ip = namei(uchar, 0, 1);
f94ceb3b
BJ
406#ifdef EFS
407 if (efsinode(ip)) {
408 dev_t ndev = ip->i_rdev;
409
410 iput(ip);
411 efssaccess(ndev);
412 if (u.u_error != EEXIST)
413 return;
414 u.u_error = 0;
415 u.u_dirp = (caddr_t)u.u_arg[0];
416 ip = namei(uchar, 0, 1);
417 }
418#endif
3e78e260
BJ
419 if (ip != NULL) {
420 if (uap->fmode&(IREAD>>6))
421 (void) access(ip, IREAD);
422 if (uap->fmode&(IWRITE>>6))
423 (void) access(ip, IWRITE);
424 if (uap->fmode&(IEXEC>>6))
425 (void) access(ip, IEXEC);
426 iput(ip);
427 }
428 u.u_uid = svuid;
429 u.u_gid = svgid;
430}
d67a03eb
BJ
431
432/*
433 * the fstat system call.
434 */
435fstat()
436{
437 register struct file *fp;
438 register struct a {
439 int fdes;
440 struct stat *sb;
441 } *uap;
442
443 uap = (struct a *)u.u_ap;
444 fp = getf(uap->fdes);
e92a04af 445 if (fp == NULL)
d67a03eb 446 return;
f94ceb3b
BJ
447#ifdef EFS
448 if (efsinode(fp->f_inode)) {
449 efsfstat(fp->f_inode->i_rdev, fp);
450 return;
451 }
452#endif
4147b3f6 453 if (fp->f_type == DTYPE_SOCKET)
cc15ab5d 454 u.u_error = sostat(fp->f_socket, uap->sb);
e92a04af
BJ
455 else
456 stat1(fp->f_inode, uap->sb);
d67a03eb
BJ
457}
458
459/*
6459ebe0 460 * Stat system call. This version follows links.
d67a03eb
BJ
461 */
462stat()
463{
464 register struct inode *ip;
465 register struct a {
466 char *fname;
467 struct stat *sb;
468 } *uap;
469
470 uap = (struct a *)u.u_ap;
66d4ba1b 471 ip = namei(uchar, 0, 1);
e92a04af 472 if (ip == NULL)
d67a03eb 473 return;
f94ceb3b
BJ
474#ifdef EFS
475 if (efsinode(ip)) {
476 dev_t ndev = ip->i_rdev;
477
478 iput(ip);
479 efsstat(ndev);
480 if (u.u_error != EEXIST)
481 return;
482 u.u_error = 0;
483 u.u_dirp = (caddr_t)u.u_arg[0];
484 ip = namei(uchar, 0, 1);
485 }
486#endif
a3aa7f92 487 stat1(ip, uap->sb);
d67a03eb
BJ
488 iput(ip);
489}
490
5485e062 491/*
6459ebe0 492 * Lstat system call. This version does not follow links.
5485e062
BJ
493 */
494lstat()
495{
496 register struct inode *ip;
497 register struct a {
498 char *fname;
499 struct stat *sb;
500 } *uap;
501
502 uap = (struct a *)u.u_ap;
66d4ba1b 503 ip = namei(uchar, 0, 0);
5485e062
BJ
504 if (ip == NULL)
505 return;
f94ceb3b
BJ
506#ifdef EFS
507 if (efsinode(ip)) {
508 dev_t ndev = ip->i_rdev;
509
510 iput(ip);
511 efslstat(ndev);
512 if (u.u_error != EEXIST)
513 return;
514 u.u_error = 0;
515 u.u_dirp = (caddr_t)u.u_arg[0];
516 ip = namei(uchar, 0, 0);
517 }
518#endif
019b08c9 519 stat1(ip, uap->sb);
5485e062
BJ
520 iput(ip);
521}
522
d67a03eb
BJ
523/*
524 * The basic routine for fstat and stat:
525 * get the inode and pass appropriate parts back.
526 */
a3aa7f92 527stat1(ip, ub)
e92a04af
BJ
528 register struct inode *ip;
529 struct stat *ub;
d67a03eb 530{
d67a03eb
BJ
531 struct stat ds;
532
c0bb1685 533 IUPDAT(ip, &time, &time, 0);
d67a03eb 534 /*
09c42945 535 * Copy from inode table
d67a03eb
BJ
536 */
537 ds.st_dev = ip->i_dev;
538 ds.st_ino = ip->i_number;
539 ds.st_mode = ip->i_mode;
540 ds.st_nlink = ip->i_nlink;
541 ds.st_uid = ip->i_uid;
542 ds.st_gid = ip->i_gid;
6459ebe0 543 ds.st_rdev = (dev_t)ip->i_rdev;
a3aa7f92 544 ds.st_size = ip->i_size;
6459ebe0
KM
545 ds.st_atime = ip->i_atime;
546 ds.st_mtime = ip->i_mtime;
547 ds.st_ctime = ip->i_ctime;
09c42945 548 ds.st_blksize = ip->i_fs->fs_bsize;
d67a03eb
BJ
549 if (copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds)) < 0)
550 u.u_error = EFAULT;
551}
552
553/*
5485e062
BJ
554 * Return target name of a symbolic link
555 */
556readlink()
557{
558 register struct inode *ip;
559 register struct a {
560 char *name;
561 char *buf;
562 int count;
563 } *uap;
564
565 ip = namei(uchar, 0, 0);
566 if (ip == NULL)
567 return;
f94ceb3b
BJ
568#ifdef EFS
569 if (efsinode(ip)) {
570 dev_t ndev = ip->i_rdev;
571
572 iput(ip);
573 efsreadlink(ndev);
574 if (u.u_error != EEXIST)
575 return;
576 u.u_error = 0;
577 u.u_dirp = (caddr_t)u.u_arg[0];
578 ip = namei(uchar, 0, 0);
579 return (0);
580 }
581#endif
5485e062
BJ
582 if ((ip->i_mode&IFMT) != IFLNK) {
583 u.u_error = ENXIO;
584 goto out;
585 }
586 uap = (struct a *)u.u_ap;
587 u.u_offset = 0;
588 u.u_base = uap->buf;
589 u.u_count = uap->count;
590 u.u_segflg = 0;
591 readi(ip);
592out:
593 iput(ip);
594 u.u_r.r_val1 = uap->count - u.u_count;
595}
596
3e78e260 597chmod()
5485e062 598{
3e78e260 599 register struct inode *ip;
5485e062 600 register struct a {
3e78e260
BJ
601 char *fname;
602 int fmode;
5485e062 603 } *uap;
5485e062
BJ
604
605 uap = (struct a *)u.u_ap;
3e78e260 606 if ((ip = owner(1)) == NULL)
5485e062 607 return;
f94ceb3b
BJ
608#ifdef EFS
609 if (efsinode(ip)) {
610 dev_t ndev = ip->i_rdev;
611
612 iput(ip);
613 efschmod(ndev);
614 if (u.u_error != EEXIST)
615 return;
616 u.u_error = 0;
617 u.u_dirp = (caddr_t)u.u_arg[0];
618 ip = owner(1);
619 }
620#endif
3e78e260 621 ip->i_mode &= ~07777;
f94ceb3b 622 if (u.u_uid) {
3e78e260 623 uap->fmode &= ~ISVTX;
f94ceb3b
BJ
624 if (ip->i_gid >= NGRPS ||
625 (u.u_grps[ip->i_gid/(sizeof(int)*8)] &
626 (1 << ip->i_gid%(sizeof(int)*8))) == 0)
627 uap->fmode &= ~ISGID;
0a77f278
RE
628#if MUSH
629 if (u.u_quota->q_syflags & QF_UMASK && u.u_uid != 0 &&
630 (ip->i_mode & IFMT) != IFCHR)
631 uap->fmode &= ~u.u_cmask;
632#endif
f94ceb3b 633 }
3e78e260
BJ
634 ip->i_mode |= uap->fmode&07777;
635 ip->i_flag |= ICHG;
636 if (ip->i_flag&ITEXT && (ip->i_mode&ISVTX)==0)
637 xrele(ip);
0a77f278
RE
638#ifdef MELB
639 if ((ip->i_mode & ISUID) && ip->i_uid == 0)
640 printf("%s: ino %d (%s) setuid root\n"
641 , getfs(ip->i_dev)->s_fsmnt
642 , ip->i_number
643 , u.u_dent.d_name
644 );
645#endif
5485e062
BJ
646 iput(ip);
647}
648
3e78e260 649chown()
d67a03eb 650{
3e78e260 651 register struct inode *ip;
d67a03eb 652 register struct a {
3e78e260
BJ
653 char *fname;
654 int uid;
655 int gid;
d67a03eb 656 } *uap;
0a77f278
RE
657#if QUOTA
658 register long change;
659#endif
d67a03eb
BJ
660
661 uap = (struct a *)u.u_ap;
3e78e260 662 if (!suser() || (ip = owner(0)) == NULL)
d67a03eb 663 return;
f94ceb3b
BJ
664#ifdef EFS
665 if (efsinode(ip)) {
666 dev_t ndev = ip->i_rdev;
667
668 iput(ip);
669 efschown(ndev);
670 if (u.u_error != EEXIST)
671 return;
672 u.u_error = 0;
673 u.u_dirp = (caddr_t)u.u_arg[0];
674 ip = owner(0);
675 }
0a77f278
RE
676#endif
677#if QUOTA
678 /*
679 * This doesn't allow for holes in files (which hopefully don't
680 * happen often in files that we chown), and is not accurate anyway
681 * (eg: it totally ignores 3 level indir blk files - but hopefully
682 * noone who can make a file that big will have a quota)
683 */
684 if (ip->i_uid == uap->uid)
685 change = 0;
686 else {
687 register struct fs *fs = ip->i_fs;
688
689 if (ip->i_size > (change = NDADDR * fs->fs_bsize)) {
690 register off_t size;
691
692 size = blkroundup(fs, ip->i_size) - change;
693 change += size;
694 change += fs->fs_bsize;
695 /* This assumes NIADDR <= 2 */
696 if (size > NINDIR(fs) * fs->fs_bsize)
697 change += fs->fs_bsize;
698 } else
699 change = fragroundup(fs, ip->i_size);
700 change /= DEV_BSIZE;
701 }
702 chkdq(ip, -change, 1);
703 chkiq(ip->i_dev, ip, ip->i_uid, 1);
704 dqrele(ip->i_dquot);
f94ceb3b
BJ
705#endif
706 /*
707 * keep uid/gid's in sane range - no err, so chown(file, uid, -1)
708 * will do something useful
709 */
710 if (uap->uid >= 0 && uap->uid <= 32767) /* should have a const */
711 ip->i_uid = uap->uid;
712 if (uap->gid >= 0 && uap->gid <= 32767) /* same here */
713 ip->i_gid = uap->gid;
3e78e260
BJ
714 ip->i_flag |= ICHG;
715 if (u.u_ruid != 0)
716 ip->i_mode &= ~(ISUID|ISGID);
0a77f278
RE
717#if QUOTA
718 ip->i_dquot = inoquota(ip);
719 chkdq(ip, change, 1);
720 chkiq(ip->i_dev, NULL, uap->uid, 1);
721#endif
3e78e260 722 iput(ip);
d67a03eb
BJ
723}
724
725/*
3e78e260
BJ
726 * Set IUPD and IACC times on file.
727 * Can't set ICHG.
d67a03eb 728 */
3e78e260 729utime()
e92a04af 730{
d67a03eb 731 register struct a {
3e78e260
BJ
732 char *fname;
733 time_t *tptr;
d67a03eb 734 } *uap;
3e78e260
BJ
735 register struct inode *ip;
736 time_t tv[2];
d67a03eb
BJ
737
738 uap = (struct a *)u.u_ap;
3e78e260 739 if ((ip = owner(1)) == NULL)
d67a03eb 740 return;
3e78e260
BJ
741 if (copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof(tv))) {
742 u.u_error = EFAULT;
743 } else {
f94ceb3b
BJ
744#ifdef EFS
745 if (efsinode(ip)) {
746 dev_t ndev = ip->i_rdev;
747
748 iput(ip);
749 efsutime(ndev, uap->fname, tv);
750 if (u.u_error != EEXIST)
751 return;
752 u.u_error = 0;
753 u.u_dirp = (caddr_t)u.u_arg[0];
754 ip = owner(1);
755 }
756#endif
3e78e260
BJ
757 ip->i_flag |= IACC|IUPD|ICHG;
758 iupdat(ip, &tv[0], &tv[1], 0);
d67a03eb 759 }
d67a03eb
BJ
760 iput(ip);
761}
762
3e78e260 763sync()
d67a03eb 764{
d67a03eb 765
68503f9a 766 update(0);
d67a03eb 767}
64d3a787
BJ
768
769/*
770 * Make a new file.
771 */
772struct inode *
773maknode(mode)
774 int mode;
775{
776 register struct inode *ip;
777 ino_t ipref;
778
779 if ((mode & IFMT) == IFDIR)
780 ipref = dirpref(u.u_pdir->i_fs);
781 else
782 ipref = u.u_pdir->i_number;
783 ip = ialloc(u.u_pdir, ipref, mode);
784 if (ip == NULL) {
785 iput(u.u_pdir);
786 return(NULL);
787 }
788#ifdef QUOTA
789 if (ip->i_dquot != NODQUOT)
790 panic("maknode: dquot");
791#endif
792 ip->i_flag |= IACC|IUPD|ICHG;
793 if ((mode & IFMT) == 0)
794 mode |= IFREG;
795 ip->i_mode = mode & ~u.u_cmask;
796 ip->i_nlink = 1;
797 ip->i_uid = u.u_uid;
798 ip->i_gid = u.u_pdir->i_gid;
799#ifdef QUOTA
800 ip->i_dquot = inoquota(ip);
801#endif
802
803 /*
804 * Make sure inode goes to disk before directory entry.
805 */
806 iupdat(ip, &time, &time, 1);
807 direnter(ip);
808 if (u.u_error) {
809 /*
810 * write error occurred trying to update directory
811 * so must deallocate the inode
812 */
813 ip->i_nlink = 0;
814 ip->i_flag |= ICHG;
815 iput(ip);
816 return(NULL);
817 }
818 return(ip);
819}