+#ifdef EFS
+ if (efsinode(ip)) {
+ dev_t ndev = ip->i_rdev;
+
+ iput(ip);
+ efschown(ndev);
+ if (u.u_error != EEXIST)
+ return;
+ u.u_error = 0;
+ u.u_dirp = (caddr_t)u.u_arg[0];
+ ip = owner(0);
+ }
+#endif
+#if QUOTA
+ /*
+ * This doesn't allow for holes in files (which hopefully don't
+ * happen often in files that we chown), and is not accurate anyway
+ * (eg: it totally ignores 3 level indir blk files - but hopefully
+ * noone who can make a file that big will have a quota)
+ */
+ if (ip->i_uid == uap->uid)
+ change = 0;
+ else {
+ register struct fs *fs = ip->i_fs;
+
+ if (ip->i_size > (change = NDADDR * fs->fs_bsize)) {
+ register off_t size;
+
+ size = blkroundup(fs, ip->i_size) - change;
+ change += size;
+ change += fs->fs_bsize;
+ /* This assumes NIADDR <= 2 */
+ if (size > NINDIR(fs) * fs->fs_bsize)
+ change += fs->fs_bsize;
+ } else
+ change = fragroundup(fs, ip->i_size);
+ change /= DEV_BSIZE;
+ }
+ chkdq(ip, -change, 1);
+ chkiq(ip->i_dev, ip, ip->i_uid, 1);
+ dqrele(ip->i_dquot);
+#endif
+ /*
+ * keep uid/gid's in sane range - no err, so chown(file, uid, -1)
+ * will do something useful
+ */
+ if (uap->uid >= 0 && uap->uid <= 32767) /* should have a const */
+ ip->i_uid = uap->uid;
+ if (uap->gid >= 0 && uap->gid <= 32767) /* same here */
+ ip->i_gid = uap->gid;