vfs_syscalls.c 65 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993
  1. /* $OpenBSD: vfs_syscalls.c,v 1.222 2015/07/20 21:31:57 deraadt Exp $ */
  2. /* $NetBSD: vfs_syscalls.c,v 1.71 1996/04/23 10:29:02 mycroft Exp $ */
  3. /*
  4. * Copyright (c) 1989, 1993
  5. * The Regents of the University of California. All rights reserved.
  6. * (c) UNIX System Laboratories, Inc.
  7. * All or some portions of this file are derived from material licensed
  8. * to the University of California by American Telephone and Telegraph
  9. * Co. or Unix System Laboratories, Inc. and are reproduced herein with
  10. * the permission of UNIX System Laboratories, Inc.
  11. *
  12. * Redistribution and use in source and binary forms, with or without
  13. * modification, are permitted provided that the following conditions
  14. * are met:
  15. * 1. Redistributions of source code must retain the above copyright
  16. * notice, this list of conditions and the following disclaimer.
  17. * 2. Redistributions in binary form must reproduce the above copyright
  18. * notice, this list of conditions and the following disclaimer in the
  19. * documentation and/or other materials provided with the distribution.
  20. * 3. Neither the name of the University nor the names of its contributors
  21. * may be used to endorse or promote products derived from this software
  22. * without specific prior written permission.
  23. *
  24. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34. * SUCH DAMAGE.
  35. *
  36. * @(#)vfs_syscalls.c 8.28 (Berkeley) 12/10/94
  37. */
  38. #include <sys/param.h>
  39. #include <sys/systm.h>
  40. #include <sys/namei.h>
  41. #include <sys/filedesc.h>
  42. #include <sys/kernel.h>
  43. #include <sys/sysctl.h>
  44. #include <sys/file.h>
  45. #include <sys/stat.h>
  46. #include <sys/lock.h>
  47. #include <sys/vnode.h>
  48. #include <sys/mount.h>
  49. #include <sys/proc.h>
  50. #include <sys/uio.h>
  51. #include <sys/malloc.h>
  52. #include <sys/pool.h>
  53. #include <sys/dkio.h>
  54. #include <sys/disklabel.h>
  55. #include <sys/ktrace.h>
  56. #include <sys/unistd.h>
  57. #include <sys/syscallargs.h>
  58. extern int suid_clear;
  59. int usermount = 0; /* sysctl: by default, users may not mount */
  60. static int change_dir(struct nameidata *, struct proc *);
  61. void checkdirs(struct vnode *);
  62. int copyout_statfs(struct statfs *, void *, struct proc *);
  63. int doopenat(struct proc *, int, const char *, int, mode_t, register_t *);
  64. int domknodat(struct proc *, int, const char *, mode_t, dev_t);
  65. int dolinkat(struct proc *, int, const char *, int, const char *, int);
  66. int dosymlinkat(struct proc *, const char *, int, const char *);
  67. int dounlinkat(struct proc *, int, const char *, int);
  68. int dofaccessat(struct proc *, int, const char *, int, int);
  69. int dofstatat(struct proc *, int, const char *, struct stat *, int);
  70. int doreadlinkat(struct proc *, int, const char *, char *, size_t,
  71. register_t *);
  72. int dochflagsat(struct proc *, int, const char *, u_int, int);
  73. int dovchflags(struct proc *, struct vnode *, u_int);
  74. int dofchmodat(struct proc *, int, const char *, mode_t, int);
  75. int dofchownat(struct proc *, int, const char *, uid_t, gid_t, int);
  76. int dorenameat(struct proc *, int, const char *, int, const char *);
  77. int domkdirat(struct proc *, int, const char *, mode_t);
  78. int doutimensat(struct proc *, int, const char *, struct timespec [2], int);
  79. int dovutimens(struct proc *, struct vnode *, struct timespec [2]);
  80. int dofutimens(struct proc *, int, struct timespec [2]);
  81. /*
  82. * Virtual File System System Calls
  83. */
  84. /*
  85. * Mount a file system.
  86. */
  87. /* ARGSUSED */
  88. int
  89. sys_mount(struct proc *p, void *v, register_t *retval)
  90. {
  91. struct sys_mount_args /* {
  92. syscallarg(const char *) type;
  93. syscallarg(const char *) path;
  94. syscallarg(int) flags;
  95. syscallarg(void *) data;
  96. } */ *uap = v;
  97. struct vnode *vp;
  98. struct mount *mp;
  99. int error, mntflag = 0;
  100. char fstypename[MFSNAMELEN];
  101. char fspath[MNAMELEN];
  102. struct vattr va;
  103. struct nameidata nd;
  104. struct vfsconf *vfsp;
  105. int flags = SCARG(uap, flags);
  106. if (usermount == 0 && (error = suser(p, 0)))
  107. return (error);
  108. /*
  109. * Mount points must fit in MNAMELEN, not MAXPATHLEN.
  110. */
  111. error = copyinstr(SCARG(uap, path), fspath, MNAMELEN, NULL);
  112. if (error)
  113. return(error);
  114. /*
  115. * Get vnode to be covered
  116. */
  117. NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, fspath, p);
  118. if ((error = namei(&nd)) != 0)
  119. return (error);
  120. vp = nd.ni_vp;
  121. if (flags & MNT_UPDATE) {
  122. if ((vp->v_flag & VROOT) == 0) {
  123. vput(vp);
  124. return (EINVAL);
  125. }
  126. mp = vp->v_mount;
  127. vfsp = mp->mnt_vfc;
  128. mntflag = mp->mnt_flag;
  129. /*
  130. * We only allow the filesystem to be reloaded if it
  131. * is currently mounted read-only.
  132. */
  133. if ((flags & MNT_RELOAD) &&
  134. ((mp->mnt_flag & MNT_RDONLY) == 0)) {
  135. vput(vp);
  136. return (EOPNOTSUPP); /* Needs translation */
  137. }
  138. /*
  139. * Only root, or the user that did the original mount is
  140. * permitted to update it.
  141. */
  142. if (mp->mnt_stat.f_owner != p->p_ucred->cr_uid &&
  143. (error = suser(p, 0))) {
  144. vput(vp);
  145. return (error);
  146. }
  147. /*
  148. * Do not allow NFS export by non-root users. Silently
  149. * enforce MNT_NOSUID and MNT_NODEV for non-root users, and
  150. * inherit MNT_NOEXEC from the mount point.
  151. */
  152. if (suser(p, 0) != 0) {
  153. if (flags & MNT_EXPORTED) {
  154. vput(vp);
  155. return (EPERM);
  156. }
  157. flags |= MNT_NOSUID | MNT_NODEV;
  158. if (mntflag & MNT_NOEXEC)
  159. flags |= MNT_NOEXEC;
  160. }
  161. if ((error = vfs_busy(mp, VB_READ|VB_NOWAIT)) != 0) {
  162. vput(vp);
  163. return (error);
  164. }
  165. mp->mnt_flag |= flags & (MNT_RELOAD | MNT_UPDATE);
  166. goto update;
  167. }
  168. /*
  169. * If the user is not root, ensure that they own the directory
  170. * onto which we are attempting to mount.
  171. */
  172. if ((error = VOP_GETATTR(vp, &va, p->p_ucred, p)) ||
  173. (va.va_uid != p->p_ucred->cr_uid &&
  174. (error = suser(p, 0)))) {
  175. vput(vp);
  176. return (error);
  177. }
  178. /*
  179. * Do not allow NFS export by non-root users. Silently
  180. * enforce MNT_NOSUID and MNT_NODEV for non-root users, and inherit
  181. * MNT_NOEXEC from the mount point.
  182. */
  183. if (suser(p, 0) != 0) {
  184. if (flags & MNT_EXPORTED) {
  185. vput(vp);
  186. return (EPERM);
  187. }
  188. flags |= MNT_NOSUID | MNT_NODEV;
  189. if (vp->v_mount->mnt_flag & MNT_NOEXEC)
  190. flags |= MNT_NOEXEC;
  191. }
  192. if ((error = vinvalbuf(vp, V_SAVE, p->p_ucred, p, 0, 0)) != 0) {
  193. vput(vp);
  194. return (error);
  195. }
  196. if (vp->v_type != VDIR) {
  197. vput(vp);
  198. return (ENOTDIR);
  199. }
  200. error = copyinstr(SCARG(uap, type), fstypename, MFSNAMELEN, NULL);
  201. if (error) {
  202. vput(vp);
  203. return (error);
  204. }
  205. for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) {
  206. if (!strcmp(vfsp->vfc_name, fstypename))
  207. break;
  208. }
  209. if (vfsp == NULL) {
  210. vput(vp);
  211. return (EOPNOTSUPP);
  212. }
  213. if (vp->v_mountedhere != NULL) {
  214. vput(vp);
  215. return (EBUSY);
  216. }
  217. /*
  218. * Allocate and initialize the file system.
  219. */
  220. mp = malloc(sizeof(*mp), M_MOUNT, M_WAITOK|M_ZERO);
  221. (void) vfs_busy(mp, VB_READ|VB_NOWAIT);
  222. mp->mnt_op = vfsp->vfc_vfsops;
  223. mp->mnt_vfc = vfsp;
  224. mp->mnt_flag |= (vfsp->vfc_flags & MNT_VISFLAGMASK);
  225. strncpy(mp->mnt_stat.f_fstypename, vfsp->vfc_name, MFSNAMELEN);
  226. mp->mnt_vnodecovered = vp;
  227. mp->mnt_stat.f_owner = p->p_ucred->cr_uid;
  228. update:
  229. /*
  230. * Set the mount level flags.
  231. */
  232. if (flags & MNT_RDONLY)
  233. mp->mnt_flag |= MNT_RDONLY;
  234. else if (mp->mnt_flag & MNT_RDONLY)
  235. mp->mnt_flag |= MNT_WANTRDWR;
  236. mp->mnt_flag &=~ (MNT_NOSUID | MNT_NOEXEC | MNT_NODEV |
  237. MNT_SYNCHRONOUS | MNT_ASYNC | MNT_SOFTDEP | MNT_NOATIME |
  238. MNT_FORCE);
  239. mp->mnt_flag |= flags & (MNT_NOSUID | MNT_NOEXEC |
  240. MNT_NODEV | MNT_SYNCHRONOUS | MNT_ASYNC | MNT_SOFTDEP |
  241. MNT_NOATIME | MNT_FORCE);
  242. /*
  243. * Mount the filesystem.
  244. */
  245. error = VFS_MOUNT(mp, fspath, SCARG(uap, data), &nd, p);
  246. if (!error) {
  247. mp->mnt_stat.f_ctime = time_second;
  248. }
  249. if (mp->mnt_flag & MNT_UPDATE) {
  250. vput(vp);
  251. if (mp->mnt_flag & MNT_WANTRDWR)
  252. mp->mnt_flag &= ~MNT_RDONLY;
  253. mp->mnt_flag &=~
  254. (MNT_UPDATE | MNT_RELOAD | MNT_FORCE | MNT_WANTRDWR);
  255. if (error)
  256. mp->mnt_flag = mntflag;
  257. if ((mp->mnt_flag & MNT_RDONLY) == 0) {
  258. if (mp->mnt_syncer == NULL)
  259. error = vfs_allocate_syncvnode(mp);
  260. } else {
  261. if (mp->mnt_syncer != NULL)
  262. vgone(mp->mnt_syncer);
  263. mp->mnt_syncer = NULL;
  264. }
  265. vfs_unbusy(mp);
  266. return (error);
  267. }
  268. vp->v_mountedhere = mp;
  269. /*
  270. * Put the new filesystem on the mount list after root.
  271. */
  272. cache_purge(vp);
  273. if (!error) {
  274. vfsp->vfc_refcount++;
  275. TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
  276. checkdirs(vp);
  277. VOP_UNLOCK(vp, 0, p);
  278. if ((mp->mnt_flag & MNT_RDONLY) == 0)
  279. error = vfs_allocate_syncvnode(mp);
  280. vfs_unbusy(mp);
  281. (void) VFS_STATFS(mp, &mp->mnt_stat, p);
  282. if ((error = VFS_START(mp, 0, p)) != 0)
  283. vrele(vp);
  284. } else {
  285. mp->mnt_vnodecovered->v_mountedhere = NULL;
  286. vfs_unbusy(mp);
  287. free(mp, M_MOUNT, sizeof(*mp));
  288. vput(vp);
  289. }
  290. return (error);
  291. }
  292. /*
  293. * Scan all active processes to see if any of them have a current
  294. * or root directory onto which the new filesystem has just been
  295. * mounted. If so, replace them with the new mount point, keeping
  296. * track of how many were replaced. That's the number of references
  297. * the old vnode had that we've replaced, so finish by vrele()'ing
  298. * it that many times. This puts off any possible sleeping until
  299. * we've finished walking the allproc list.
  300. */
  301. void
  302. checkdirs(struct vnode *olddp)
  303. {
  304. struct filedesc *fdp;
  305. struct vnode *newdp;
  306. struct proc *p;
  307. u_int free_count = 0;
  308. if (olddp->v_usecount == 1)
  309. return;
  310. if (VFS_ROOT(olddp->v_mountedhere, &newdp))
  311. panic("mount: lost mount");
  312. LIST_FOREACH(p, &allproc, p_list) {
  313. fdp = p->p_fd;
  314. if (fdp->fd_cdir == olddp) {
  315. free_count++;
  316. vref(newdp);
  317. fdp->fd_cdir = newdp;
  318. }
  319. if (fdp->fd_rdir == olddp) {
  320. free_count++;
  321. vref(newdp);
  322. fdp->fd_rdir = newdp;
  323. }
  324. }
  325. if (rootvnode == olddp) {
  326. free_count++;
  327. vref(newdp);
  328. rootvnode = newdp;
  329. }
  330. while (free_count-- > 0)
  331. vrele(olddp);
  332. vput(newdp);
  333. }
  334. /*
  335. * Unmount a file system.
  336. *
  337. * Note: unmount takes a path to the vnode mounted on as argument,
  338. * not special file (as before).
  339. */
  340. /* ARGSUSED */
  341. int
  342. sys_unmount(struct proc *p, void *v, register_t *retval)
  343. {
  344. struct sys_unmount_args /* {
  345. syscallarg(const char *) path;
  346. syscallarg(int) flags;
  347. } */ *uap = v;
  348. struct vnode *vp;
  349. struct mount *mp;
  350. int error;
  351. struct nameidata nd;
  352. NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
  353. SCARG(uap, path), p);
  354. if ((error = namei(&nd)) != 0)
  355. return (error);
  356. vp = nd.ni_vp;
  357. mp = vp->v_mount;
  358. /*
  359. * Only root, or the user that did the original mount is
  360. * permitted to unmount this filesystem.
  361. */
  362. if ((mp->mnt_stat.f_owner != p->p_ucred->cr_uid) &&
  363. (error = suser(p, 0))) {
  364. vput(vp);
  365. return (error);
  366. }
  367. /*
  368. * Don't allow unmounting the root file system.
  369. */
  370. if (mp->mnt_flag & MNT_ROOTFS) {
  371. vput(vp);
  372. return (EINVAL);
  373. }
  374. /*
  375. * Must be the root of the filesystem
  376. */
  377. if ((vp->v_flag & VROOT) == 0) {
  378. vput(vp);
  379. return (EINVAL);
  380. }
  381. vput(vp);
  382. if (vfs_busy(mp, VB_WRITE|VB_WAIT))
  383. return (EBUSY);
  384. return (dounmount(mp, SCARG(uap, flags), p, vp));
  385. }
  386. /*
  387. * Do the actual file system unmount.
  388. */
  389. int
  390. dounmount(struct mount *mp, int flags, struct proc *p, struct vnode *olddp)
  391. {
  392. struct vnode *coveredvp;
  393. int error;
  394. int hadsyncer = 0;
  395. mp->mnt_flag &=~ MNT_ASYNC;
  396. cache_purgevfs(mp); /* remove cache entries for this file sys */
  397. if (mp->mnt_syncer != NULL) {
  398. hadsyncer = 1;
  399. vgone(mp->mnt_syncer);
  400. mp->mnt_syncer = NULL;
  401. }
  402. if (((mp->mnt_flag & MNT_RDONLY) ||
  403. (error = VFS_SYNC(mp, MNT_WAIT, p->p_ucred, p)) == 0) ||
  404. (flags & MNT_FORCE))
  405. error = VFS_UNMOUNT(mp, flags, p);
  406. if (error && error != EIO && !(flags & MNT_DOOMED)) {
  407. if ((mp->mnt_flag & MNT_RDONLY) == 0 && hadsyncer)
  408. (void) vfs_allocate_syncvnode(mp);
  409. vfs_unbusy(mp);
  410. return (error);
  411. }
  412. TAILQ_REMOVE(&mountlist, mp, mnt_list);
  413. if ((coveredvp = mp->mnt_vnodecovered) != NULLVP) {
  414. coveredvp->v_mountedhere = NULL;
  415. vrele(coveredvp);
  416. }
  417. mp->mnt_vfc->vfc_refcount--;
  418. if (!LIST_EMPTY(&mp->mnt_vnodelist))
  419. panic("unmount: dangling vnode");
  420. vfs_unbusy(mp);
  421. free(mp, M_MOUNT, sizeof(*mp));
  422. return (0);
  423. }
  424. /*
  425. * Sync each mounted filesystem.
  426. */
  427. #ifdef DEBUG
  428. int syncprt = 0;
  429. struct ctldebug debug0 = { "syncprt", &syncprt };
  430. #endif
  431. /* ARGSUSED */
  432. int
  433. sys_sync(struct proc *p, void *v, register_t *retval)
  434. {
  435. struct mount *mp, *nmp;
  436. int asyncflag;
  437. TAILQ_FOREACH_REVERSE_SAFE(mp, &mountlist, mntlist, mnt_list, nmp) {
  438. if (vfs_busy(mp, VB_READ|VB_NOWAIT))
  439. continue;
  440. if ((mp->mnt_flag & MNT_RDONLY) == 0) {
  441. asyncflag = mp->mnt_flag & MNT_ASYNC;
  442. mp->mnt_flag &= ~MNT_ASYNC;
  443. uvm_vnp_sync(mp);
  444. VFS_SYNC(mp, MNT_NOWAIT, p->p_ucred, p);
  445. if (asyncflag)
  446. mp->mnt_flag |= MNT_ASYNC;
  447. }
  448. vfs_unbusy(mp);
  449. }
  450. return (0);
  451. }
  452. /*
  453. * Change filesystem quotas.
  454. */
  455. /* ARGSUSED */
  456. int
  457. sys_quotactl(struct proc *p, void *v, register_t *retval)
  458. {
  459. struct sys_quotactl_args /* {
  460. syscallarg(const char *) path;
  461. syscallarg(int) cmd;
  462. syscallarg(int) uid;
  463. syscallarg(char *) arg;
  464. } */ *uap = v;
  465. struct mount *mp;
  466. int error;
  467. struct nameidata nd;
  468. NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
  469. if ((error = namei(&nd)) != 0)
  470. return (error);
  471. mp = nd.ni_vp->v_mount;
  472. vrele(nd.ni_vp);
  473. return (VFS_QUOTACTL(mp, SCARG(uap, cmd), SCARG(uap, uid),
  474. SCARG(uap, arg), p));
  475. }
  476. int
  477. copyout_statfs(struct statfs *sp, void *uaddr, struct proc *p)
  478. {
  479. size_t co_sz1 = offsetof(struct statfs, f_fsid);
  480. size_t co_off2 = co_sz1 + sizeof(fsid_t);
  481. size_t co_sz2 = sizeof(struct statfs) - co_off2;
  482. char *s, *d;
  483. int error;
  484. /* Don't let non-root see filesystem id (for NFS security) */
  485. if (suser(p, 0)) {
  486. fsid_t fsid;
  487. s = (char *)sp;
  488. d = (char *)uaddr;
  489. memset(&fsid, 0, sizeof(fsid));
  490. if ((error = copyout(s, d, co_sz1)) != 0)
  491. return (error);
  492. if ((error = copyout(&fsid, d + co_sz1, sizeof(fsid))) != 0)
  493. return (error);
  494. return (copyout(s + co_off2, d + co_off2, co_sz2));
  495. }
  496. return (copyout(sp, uaddr, sizeof(*sp)));
  497. }
  498. /*
  499. * Get filesystem statistics.
  500. */
  501. /* ARGSUSED */
  502. int
  503. sys_statfs(struct proc *p, void *v, register_t *retval)
  504. {
  505. struct sys_statfs_args /* {
  506. syscallarg(const char *) path;
  507. syscallarg(struct statfs *) buf;
  508. } */ *uap = v;
  509. struct mount *mp;
  510. struct statfs *sp;
  511. int error;
  512. struct nameidata nd;
  513. NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
  514. if ((error = namei(&nd)) != 0)
  515. return (error);
  516. mp = nd.ni_vp->v_mount;
  517. sp = &mp->mnt_stat;
  518. vrele(nd.ni_vp);
  519. if ((error = VFS_STATFS(mp, sp, p)) != 0)
  520. return (error);
  521. sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
  522. return (copyout_statfs(sp, SCARG(uap, buf), p));
  523. }
  524. /*
  525. * Get filesystem statistics.
  526. */
  527. /* ARGSUSED */
  528. int
  529. sys_fstatfs(struct proc *p, void *v, register_t *retval)
  530. {
  531. struct sys_fstatfs_args /* {
  532. syscallarg(int) fd;
  533. syscallarg(struct statfs *) buf;
  534. } */ *uap = v;
  535. struct file *fp;
  536. struct mount *mp;
  537. struct statfs *sp;
  538. int error;
  539. if ((error = getvnode(p, SCARG(uap, fd), &fp)) != 0)
  540. return (error);
  541. mp = ((struct vnode *)fp->f_data)->v_mount;
  542. if (!mp) {
  543. FRELE(fp, p);
  544. return (ENOENT);
  545. }
  546. sp = &mp->mnt_stat;
  547. error = VFS_STATFS(mp, sp, p);
  548. FRELE(fp, p);
  549. if (error)
  550. return (error);
  551. sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
  552. return (copyout_statfs(sp, SCARG(uap, buf), p));
  553. }
  554. /*
  555. * Get statistics on all filesystems.
  556. */
  557. int
  558. sys_getfsstat(struct proc *p, void *v, register_t *retval)
  559. {
  560. struct sys_getfsstat_args /* {
  561. syscallarg(struct statfs *) buf;
  562. syscallarg(size_t) bufsize;
  563. syscallarg(int) flags;
  564. } */ *uap = v;
  565. struct mount *mp, *nmp;
  566. struct statfs *sp;
  567. struct statfs *sfsp;
  568. size_t count, maxcount;
  569. int error, flags = SCARG(uap, flags);
  570. maxcount = SCARG(uap, bufsize) / sizeof(struct statfs);
  571. sfsp = SCARG(uap, buf);
  572. count = 0;
  573. TAILQ_FOREACH_SAFE(mp, &mountlist, mnt_list, nmp) {
  574. if (vfs_busy(mp, VB_READ|VB_NOWAIT))
  575. continue;
  576. if (sfsp && count < maxcount) {
  577. sp = &mp->mnt_stat;
  578. /* Refresh stats unless MNT_NOWAIT is specified */
  579. if (flags != MNT_NOWAIT &&
  580. flags != MNT_LAZY &&
  581. (flags == MNT_WAIT ||
  582. flags == 0) &&
  583. (error = VFS_STATFS(mp, sp, p))) {
  584. vfs_unbusy(mp);
  585. continue;
  586. }
  587. sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
  588. #if notyet
  589. if (mp->mnt_flag & MNT_SOFTDEP)
  590. sp->f_eflags = STATFS_SOFTUPD;
  591. #endif
  592. error = (copyout_statfs(sp, sfsp, p));
  593. if (error) {
  594. vfs_unbusy(mp);
  595. return (error);
  596. }
  597. sfsp++;
  598. }
  599. count++;
  600. vfs_unbusy(mp);
  601. }
  602. if (sfsp && count > maxcount)
  603. *retval = maxcount;
  604. else
  605. *retval = count;
  606. return (0);
  607. }
  608. /*
  609. * Change current working directory to a given file descriptor.
  610. */
  611. /* ARGSUSED */
  612. int
  613. sys_fchdir(struct proc *p, void *v, register_t *retval)
  614. {
  615. struct sys_fchdir_args /* {
  616. syscallarg(int) fd;
  617. } */ *uap = v;
  618. struct filedesc *fdp = p->p_fd;
  619. struct vnode *vp, *tdp, *old_cdir;
  620. struct mount *mp;
  621. struct file *fp;
  622. int error;
  623. if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
  624. return (EBADF);
  625. vp = (struct vnode *)fp->f_data;
  626. if (fp->f_type != DTYPE_VNODE || vp->v_type != VDIR)
  627. return (ENOTDIR);
  628. vref(vp);
  629. vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
  630. error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p);
  631. while (!error && (mp = vp->v_mountedhere) != NULL) {
  632. if (vfs_busy(mp, VB_READ|VB_WAIT))
  633. continue;
  634. error = VFS_ROOT(mp, &tdp);
  635. vfs_unbusy(mp);
  636. if (error)
  637. break;
  638. vput(vp);
  639. vp = tdp;
  640. }
  641. if (error) {
  642. vput(vp);
  643. return (error);
  644. }
  645. VOP_UNLOCK(vp, 0, p);
  646. old_cdir = fdp->fd_cdir;
  647. fdp->fd_cdir = vp;
  648. vrele(old_cdir);
  649. return (0);
  650. }
  651. /*
  652. * Change current working directory (``.'').
  653. */
  654. /* ARGSUSED */
  655. int
  656. sys_chdir(struct proc *p, void *v, register_t *retval)
  657. {
  658. struct sys_chdir_args /* {
  659. syscallarg(const char *) path;
  660. } */ *uap = v;
  661. struct filedesc *fdp = p->p_fd;
  662. struct vnode *old_cdir;
  663. int error;
  664. struct nameidata nd;
  665. NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
  666. SCARG(uap, path), p);
  667. if ((error = change_dir(&nd, p)) != 0)
  668. return (error);
  669. old_cdir = fdp->fd_cdir;
  670. fdp->fd_cdir = nd.ni_vp;
  671. vrele(old_cdir);
  672. return (0);
  673. }
  674. /*
  675. * Change notion of root (``/'') directory.
  676. */
  677. /* ARGSUSED */
  678. int
  679. sys_chroot(struct proc *p, void *v, register_t *retval)
  680. {
  681. struct sys_chroot_args /* {
  682. syscallarg(const char *) path;
  683. } */ *uap = v;
  684. struct filedesc *fdp = p->p_fd;
  685. struct vnode *old_cdir, *old_rdir;
  686. int error;
  687. struct nameidata nd;
  688. if ((error = suser(p, 0)) != 0)
  689. return (error);
  690. NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
  691. SCARG(uap, path), p);
  692. if ((error = change_dir(&nd, p)) != 0)
  693. return (error);
  694. if (fdp->fd_rdir != NULL) {
  695. /*
  696. * A chroot() done inside a changed root environment does
  697. * an automatic chdir to avoid the out-of-tree experience.
  698. */
  699. vref(nd.ni_vp);
  700. old_rdir = fdp->fd_rdir;
  701. old_cdir = fdp->fd_cdir;
  702. fdp->fd_rdir = fdp->fd_cdir = nd.ni_vp;
  703. vrele(old_rdir);
  704. vrele(old_cdir);
  705. } else
  706. fdp->fd_rdir = nd.ni_vp;
  707. return (0);
  708. }
  709. /*
  710. * Common routine for chroot and chdir.
  711. */
  712. static int
  713. change_dir(struct nameidata *ndp, struct proc *p)
  714. {
  715. struct vnode *vp;
  716. int error;
  717. if ((error = namei(ndp)) != 0)
  718. return (error);
  719. vp = ndp->ni_vp;
  720. if (vp->v_type != VDIR)
  721. error = ENOTDIR;
  722. else
  723. error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p);
  724. if (error)
  725. vput(vp);
  726. else
  727. VOP_UNLOCK(vp, 0, p);
  728. return (error);
  729. }
  730. /*
  731. * Check permissions, allocate an open file structure,
  732. * and call the device open routine if any.
  733. */
  734. int
  735. sys_open(struct proc *p, void *v, register_t *retval)
  736. {
  737. struct sys_open_args /* {
  738. syscallarg(const char *) path;
  739. syscallarg(int) flags;
  740. syscallarg(mode_t) mode;
  741. } */ *uap = v;
  742. return (doopenat(p, AT_FDCWD, SCARG(uap, path), SCARG(uap, flags),
  743. SCARG(uap, mode), retval));
  744. }
  745. int
  746. sys_openat(struct proc *p, void *v, register_t *retval)
  747. {
  748. struct sys_openat_args /* {
  749. syscallarg(int) fd;
  750. syscallarg(const char *) path;
  751. syscallarg(int) flags;
  752. syscallarg(mode_t) mode;
  753. } */ *uap = v;
  754. return (doopenat(p, SCARG(uap, fd), SCARG(uap, path),
  755. SCARG(uap, flags), SCARG(uap, mode), retval));
  756. }
  757. int
  758. doopenat(struct proc *p, int fd, const char *path, int oflags, mode_t mode,
  759. register_t *retval)
  760. {
  761. struct filedesc *fdp = p->p_fd;
  762. struct file *fp;
  763. struct vnode *vp;
  764. struct vattr vattr;
  765. int flags, cmode;
  766. int type, indx, error, localtrunc = 0;
  767. struct flock lf;
  768. struct nameidata nd;
  769. switch (oflags & O_ACCMODE) {
  770. case O_WRONLY:
  771. case O_RDWR:
  772. p->p_tamenote |= TMN_WRITE;
  773. break;
  774. }
  775. if (oflags & O_CREAT)
  776. p->p_tamenote |= TMN_CREAT;
  777. fdplock(fdp);
  778. if ((error = falloc(p, &fp, &indx)) != 0)
  779. goto out;
  780. flags = FFLAGS(oflags);
  781. if (flags & O_CLOEXEC)
  782. fdp->fd_ofileflags[indx] |= UF_EXCLOSE;
  783. cmode = ((mode &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT;
  784. NDINITAT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, fd, path, p);
  785. p->p_dupfd = -1; /* XXX check for fdopen */
  786. if ((flags & O_TRUNC) && (flags & (O_EXLOCK | O_SHLOCK))) {
  787. localtrunc = 1;
  788. flags &= ~O_TRUNC; /* Must do truncate ourselves */
  789. }
  790. if ((error = vn_open(&nd, flags, cmode)) != 0) {
  791. if (error == ENODEV &&
  792. p->p_dupfd >= 0 && /* XXX from fdopen */
  793. (error =
  794. dupfdopen(fdp, indx, p->p_dupfd, flags)) == 0) {
  795. closef(fp, p);
  796. *retval = indx;
  797. goto out;
  798. }
  799. if (error == ERESTART)
  800. error = EINTR;
  801. fdremove(fdp, indx);
  802. closef(fp, p);
  803. goto out;
  804. }
  805. p->p_dupfd = 0;
  806. vp = nd.ni_vp;
  807. fp->f_flag = flags & FMASK;
  808. fp->f_type = DTYPE_VNODE;
  809. fp->f_ops = &vnops;
  810. fp->f_data = vp;
  811. if (flags & (O_EXLOCK | O_SHLOCK)) {
  812. lf.l_whence = SEEK_SET;
  813. lf.l_start = 0;
  814. lf.l_len = 0;
  815. if (flags & O_EXLOCK)
  816. lf.l_type = F_WRLCK;
  817. else
  818. lf.l_type = F_RDLCK;
  819. type = F_FLOCK;
  820. if ((flags & FNONBLOCK) == 0)
  821. type |= F_WAIT;
  822. VOP_UNLOCK(vp, 0, p);
  823. error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type);
  824. if (error) {
  825. /* closef will vn_close the file for us. */
  826. fdremove(fdp, indx);
  827. closef(fp, p);
  828. goto out;
  829. }
  830. vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
  831. fp->f_iflags |= FIF_HASLOCK;
  832. }
  833. if (localtrunc) {
  834. if ((fp->f_flag & FWRITE) == 0)
  835. error = EACCES;
  836. else if (vp->v_mount->mnt_flag & MNT_RDONLY)
  837. error = EROFS;
  838. else if (vp->v_type == VDIR)
  839. error = EISDIR;
  840. else if ((error = vn_writechk(vp)) == 0) {
  841. VATTR_NULL(&vattr);
  842. vattr.va_size = 0;
  843. error = VOP_SETATTR(vp, &vattr, fp->f_cred, p);
  844. }
  845. if (error) {
  846. VOP_UNLOCK(vp, 0, p);
  847. /* closef will close the file for us. */
  848. fdremove(fdp, indx);
  849. closef(fp, p);
  850. goto out;
  851. }
  852. }
  853. VOP_UNLOCK(vp, 0, p);
  854. *retval = indx;
  855. FILE_SET_MATURE(fp, p);
  856. out:
  857. fdpunlock(fdp);
  858. return (error);
  859. }
  860. /*
  861. * Get file handle system call
  862. */
  863. int
  864. sys_getfh(struct proc *p, void *v, register_t *retval)
  865. {
  866. struct sys_getfh_args /* {
  867. syscallarg(const char *) fname;
  868. syscallarg(fhandle_t *) fhp;
  869. } */ *uap = v;
  870. struct vnode *vp;
  871. fhandle_t fh;
  872. int error;
  873. struct nameidata nd;
  874. /*
  875. * Must be super user
  876. */
  877. error = suser(p, 0);
  878. if (error)
  879. return (error);
  880. NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
  881. SCARG(uap, fname), p);
  882. error = namei(&nd);
  883. if (error)
  884. return (error);
  885. vp = nd.ni_vp;
  886. memset(&fh, 0, sizeof(fh));
  887. fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid;
  888. error = VFS_VPTOFH(vp, &fh.fh_fid);
  889. vput(vp);
  890. if (error)
  891. return (error);
  892. error = copyout(&fh, SCARG(uap, fhp), sizeof(fh));
  893. return (error);
  894. }
  895. /*
  896. * Open a file given a file handle.
  897. *
  898. * Check permissions, allocate an open file structure,
  899. * and call the device open routine if any.
  900. */
  901. int
  902. sys_fhopen(struct proc *p, void *v, register_t *retval)
  903. {
  904. struct sys_fhopen_args /* {
  905. syscallarg(const fhandle_t *) fhp;
  906. syscallarg(int) flags;
  907. } */ *uap = v;
  908. struct filedesc *fdp = p->p_fd;
  909. struct file *fp;
  910. struct vnode *vp = NULL;
  911. struct mount *mp;
  912. struct ucred *cred = p->p_ucred;
  913. int flags;
  914. int type, indx, error=0;
  915. struct flock lf;
  916. struct vattr va;
  917. fhandle_t fh;
  918. /*
  919. * Must be super user
  920. */
  921. if ((error = suser(p, 0)))
  922. return (error);
  923. flags = FFLAGS(SCARG(uap, flags));
  924. if ((flags & (FREAD | FWRITE)) == 0)
  925. return (EINVAL);
  926. if ((flags & O_CREAT))
  927. return (EINVAL);
  928. fdplock(fdp);
  929. if ((error = falloc(p, &fp, &indx)) != 0) {
  930. fp = NULL;
  931. goto bad;
  932. }
  933. if (flags & O_CLOEXEC)
  934. fdp->fd_ofileflags[indx] |= UF_EXCLOSE;
  935. if ((error = copyin(SCARG(uap, fhp), &fh, sizeof(fhandle_t))) != 0)
  936. goto bad;
  937. if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) {
  938. error = ESTALE;
  939. goto bad;
  940. }
  941. if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp)) != 0) {
  942. vp = NULL; /* most likely unnecessary sanity for bad: */
  943. goto bad;
  944. }
  945. /* Now do an effective vn_open */
  946. if (vp->v_type == VSOCK) {
  947. error = EOPNOTSUPP;
  948. goto bad;
  949. }
  950. if ((flags & O_DIRECTORY) && vp->v_type != VDIR) {
  951. error = ENOTDIR;
  952. goto bad;
  953. }
  954. if (flags & FREAD) {
  955. if ((error = VOP_ACCESS(vp, VREAD, cred, p)) != 0)
  956. goto bad;
  957. }
  958. if (flags & (FWRITE | O_TRUNC)) {
  959. if (vp->v_type == VDIR) {
  960. error = EISDIR;
  961. goto bad;
  962. }
  963. if ((error = VOP_ACCESS(vp, VWRITE, cred, p)) != 0 ||
  964. (error = vn_writechk(vp)) != 0)
  965. goto bad;
  966. }
  967. if (flags & O_TRUNC) {
  968. VATTR_NULL(&va);
  969. va.va_size = 0;
  970. if ((error = VOP_SETATTR(vp, &va, cred, p)) != 0)
  971. goto bad;
  972. }
  973. if ((error = VOP_OPEN(vp, flags, cred, p)) != 0)
  974. goto bad;
  975. if (flags & FWRITE)
  976. vp->v_writecount++;
  977. /* done with modified vn_open, now finish what sys_open does. */
  978. fp->f_flag = flags & FMASK;
  979. fp->f_type = DTYPE_VNODE;
  980. fp->f_ops = &vnops;
  981. fp->f_data = vp;
  982. if (flags & (O_EXLOCK | O_SHLOCK)) {
  983. lf.l_whence = SEEK_SET;
  984. lf.l_start = 0;
  985. lf.l_len = 0;
  986. if (flags & O_EXLOCK)
  987. lf.l_type = F_WRLCK;
  988. else
  989. lf.l_type = F_RDLCK;
  990. type = F_FLOCK;
  991. if ((flags & FNONBLOCK) == 0)
  992. type |= F_WAIT;
  993. VOP_UNLOCK(vp, 0, p);
  994. error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type);
  995. if (error) {
  996. vp = NULL; /* closef will vn_close the file */
  997. goto bad;
  998. }
  999. vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
  1000. fp->f_iflags |= FIF_HASLOCK;
  1001. }
  1002. VOP_UNLOCK(vp, 0, p);
  1003. *retval = indx;
  1004. FILE_SET_MATURE(fp, p);
  1005. fdpunlock(fdp);
  1006. return (0);
  1007. bad:
  1008. if (fp) {
  1009. fdremove(fdp, indx);
  1010. closef(fp, p);
  1011. if (vp != NULL)
  1012. vput(vp);
  1013. }
  1014. fdpunlock(fdp);
  1015. return (error);
  1016. }
  1017. /* ARGSUSED */
  1018. int
  1019. sys_fhstat(struct proc *p, void *v, register_t *retval)
  1020. {
  1021. struct sys_fhstat_args /* {
  1022. syscallarg(const fhandle_t *) fhp;
  1023. syscallarg(struct stat *) sb;
  1024. } */ *uap = v;
  1025. struct stat sb;
  1026. int error;
  1027. fhandle_t fh;
  1028. struct mount *mp;
  1029. struct vnode *vp;
  1030. /*
  1031. * Must be super user
  1032. */
  1033. if ((error = suser(p, 0)))
  1034. return (error);
  1035. if ((error = copyin(SCARG(uap, fhp), &fh, sizeof(fhandle_t))) != 0)
  1036. return (error);
  1037. if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL)
  1038. return (ESTALE);
  1039. if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp)))
  1040. return (error);
  1041. error = vn_stat(vp, &sb, p);
  1042. vput(vp);
  1043. if (error)
  1044. return (error);
  1045. error = copyout(&sb, SCARG(uap, sb), sizeof(sb));
  1046. return (error);
  1047. }
  1048. /* ARGSUSED */
  1049. int
  1050. sys_fhstatfs(struct proc *p, void *v, register_t *retval)
  1051. {
  1052. struct sys_fhstatfs_args /* {
  1053. syscallarg(const fhandle_t *) fhp;
  1054. syscallarg(struct statfs *) buf;
  1055. } */ *uap = v;
  1056. struct statfs *sp;
  1057. fhandle_t fh;
  1058. struct mount *mp;
  1059. struct vnode *vp;
  1060. int error;
  1061. /*
  1062. * Must be super user
  1063. */
  1064. if ((error = suser(p, 0)))
  1065. return (error);
  1066. if ((error = copyin(SCARG(uap, fhp), &fh, sizeof(fhandle_t))) != 0)
  1067. return (error);
  1068. if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL)
  1069. return (ESTALE);
  1070. if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp)))
  1071. return (error);
  1072. mp = vp->v_mount;
  1073. sp = &mp->mnt_stat;
  1074. vput(vp);
  1075. if ((error = VFS_STATFS(mp, sp, p)) != 0)
  1076. return (error);
  1077. sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
  1078. return (copyout(sp, SCARG(uap, buf), sizeof(*sp)));
  1079. }
  1080. /*
  1081. * Create a special file or named pipe.
  1082. */
  1083. /* ARGSUSED */
  1084. int
  1085. sys_mknod(struct proc *p, void *v, register_t *retval)
  1086. {
  1087. struct sys_mknod_args /* {
  1088. syscallarg(const char *) path;
  1089. syscallarg(mode_t) mode;
  1090. syscallarg(int) dev;
  1091. } */ *uap = v;
  1092. p->p_tamenote |= TMN_IMODIFY;
  1093. return (domknodat(p, AT_FDCWD, SCARG(uap, path), SCARG(uap, mode),
  1094. SCARG(uap, dev)));
  1095. }
  1096. int
  1097. sys_mknodat(struct proc *p, void *v, register_t *retval)
  1098. {
  1099. struct sys_mknodat_args /* {
  1100. syscallarg(int) fd;
  1101. syscallarg(const char *) path;
  1102. syscallarg(mode_t) mode;
  1103. syscallarg(dev_t) dev;
  1104. } */ *uap = v;
  1105. return (domknodat(p, SCARG(uap, fd), SCARG(uap, path),
  1106. SCARG(uap, mode), SCARG(uap, dev)));
  1107. }
  1108. int
  1109. domknodat(struct proc *p, int fd, const char *path, mode_t mode, dev_t dev)
  1110. {
  1111. struct vnode *vp;
  1112. struct vattr vattr;
  1113. int error;
  1114. struct nameidata nd;
  1115. if (!S_ISFIFO(mode) || dev != 0) {
  1116. if ((error = suser(p, 0)) != 0)
  1117. return (error);
  1118. if (p->p_fd->fd_rdir)
  1119. return (EINVAL);
  1120. }
  1121. NDINITAT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, fd, path, p);
  1122. if ((error = namei(&nd)) != 0)
  1123. return (error);
  1124. vp = nd.ni_vp;
  1125. if (vp != NULL)
  1126. error = EEXIST;
  1127. else {
  1128. VATTR_NULL(&vattr);
  1129. vattr.va_mode = (mode & ALLPERMS) &~ p->p_fd->fd_cmask;
  1130. vattr.va_rdev = dev;
  1131. switch (mode & S_IFMT) {
  1132. case S_IFMT: /* used by badsect to flag bad sectors */
  1133. vattr.va_type = VBAD;
  1134. break;
  1135. case S_IFCHR:
  1136. vattr.va_type = VCHR;
  1137. break;
  1138. case S_IFBLK:
  1139. vattr.va_type = VBLK;
  1140. break;
  1141. case S_IFIFO:
  1142. #ifndef FIFO
  1143. return (EOPNOTSUPP);
  1144. #else
  1145. if (dev == 0) {
  1146. vattr.va_type = VFIFO;
  1147. break;
  1148. }
  1149. /* FALLTHROUGH */
  1150. #endif /* FIFO */
  1151. default:
  1152. error = EINVAL;
  1153. break;
  1154. }
  1155. }
  1156. if (!error) {
  1157. error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
  1158. } else {
  1159. VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
  1160. if (nd.ni_dvp == vp)
  1161. vrele(nd.ni_dvp);
  1162. else
  1163. vput(nd.ni_dvp);
  1164. if (vp)
  1165. vrele(vp);
  1166. }
  1167. return (error);
  1168. }
  1169. /*
  1170. * Create a named pipe.
  1171. */
  1172. /* ARGSUSED */
  1173. int
  1174. sys_mkfifo(struct proc *p, void *v, register_t *retval)
  1175. {
  1176. struct sys_mkfifo_args /* {
  1177. syscallarg(const char *) path;
  1178. syscallarg(mode_t) mode;
  1179. } */ *uap = v;
  1180. p->p_tamenote |= TMN_CREAT;
  1181. return (domknodat(p, AT_FDCWD, SCARG(uap, path),
  1182. (SCARG(uap, mode) & ALLPERMS) | S_IFIFO, 0));
  1183. }
  1184. int
  1185. sys_mkfifoat(struct proc *p, void *v, register_t *retval)
  1186. {
  1187. struct sys_mkfifoat_args /* {
  1188. syscallarg(int) fd;
  1189. syscallarg(const char *) path;
  1190. syscallarg(mode_t) mode;
  1191. } */ *uap = v;
  1192. return (domknodat(p, SCARG(uap, fd), SCARG(uap, path),
  1193. (SCARG(uap, mode) & ALLPERMS) | S_IFIFO, 0));
  1194. }
  1195. /*
  1196. * Make a hard file link.
  1197. */
  1198. /* ARGSUSED */
  1199. int
  1200. sys_link(struct proc *p, void *v, register_t *retval)
  1201. {
  1202. struct sys_link_args /* {
  1203. syscallarg(const char *) path;
  1204. syscallarg(const char *) link;
  1205. } */ *uap = v;
  1206. p->p_tamenote |= TMN_CREAT;
  1207. return (dolinkat(p, AT_FDCWD, SCARG(uap, path), AT_FDCWD,
  1208. SCARG(uap, link), AT_SYMLINK_FOLLOW));
  1209. }
  1210. int
  1211. sys_linkat(struct proc *p, void *v, register_t *retval)
  1212. {
  1213. struct sys_linkat_args /* {
  1214. syscallarg(int) fd1;
  1215. syscallarg(const char *) path1;
  1216. syscallarg(int) fd2;
  1217. syscallarg(const char *) path2;
  1218. syscallarg(int) flag;
  1219. } */ *uap = v;
  1220. return (dolinkat(p, SCARG(uap, fd1), SCARG(uap, path1),
  1221. SCARG(uap, fd2), SCARG(uap, path2), SCARG(uap, flag)));
  1222. }
  1223. int
  1224. dolinkat(struct proc *p, int fd1, const char *path1, int fd2,
  1225. const char *path2, int flag)
  1226. {
  1227. struct vnode *vp;
  1228. struct nameidata nd;
  1229. int error, follow;
  1230. int flags;
  1231. if (flag & ~AT_SYMLINK_FOLLOW)
  1232. return (EINVAL);
  1233. follow = (flag & AT_SYMLINK_FOLLOW) ? FOLLOW : NOFOLLOW;
  1234. NDINITAT(&nd, LOOKUP, follow, UIO_USERSPACE, fd1, path1, p);
  1235. if ((error = namei(&nd)) != 0)
  1236. return (error);
  1237. vp = nd.ni_vp;
  1238. flags = LOCKPARENT;
  1239. if (vp->v_type == VDIR) {
  1240. flags |= STRIPSLASHES;
  1241. }
  1242. NDINITAT(&nd, CREATE, flags, UIO_USERSPACE, fd2, path2, p);
  1243. if ((error = namei(&nd)) != 0)
  1244. goto out;
  1245. if (nd.ni_vp) {
  1246. VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
  1247. if (nd.ni_dvp == nd.ni_vp)
  1248. vrele(nd.ni_dvp);
  1249. else
  1250. vput(nd.ni_dvp);
  1251. vrele(nd.ni_vp);
  1252. error = EEXIST;
  1253. goto out;
  1254. }
  1255. error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd);
  1256. out:
  1257. vrele(vp);
  1258. return (error);
  1259. }
  1260. /*
  1261. * Make a symbolic link.
  1262. */
  1263. /* ARGSUSED */
  1264. int
  1265. sys_symlink(struct proc *p, void *v, register_t *retval)
  1266. {
  1267. struct sys_symlink_args /* {
  1268. syscallarg(const char *) path;
  1269. syscallarg(const char *) link;
  1270. } */ *uap = v;
  1271. p->p_tamenote |= TMN_CREAT;
  1272. return (dosymlinkat(p, SCARG(uap, path), AT_FDCWD, SCARG(uap, link)));
  1273. }
  1274. int
  1275. sys_symlinkat(struct proc *p, void *v, register_t *retval)
  1276. {
  1277. struct sys_symlinkat_args /* {
  1278. syscallarg(const char *) path;
  1279. syscallarg(int) fd;
  1280. syscallarg(const char *) link;
  1281. } */ *uap = v;
  1282. return (dosymlinkat(p, SCARG(uap, path), SCARG(uap, fd),
  1283. SCARG(uap, link)));
  1284. }
  1285. int
  1286. dosymlinkat(struct proc *p, const char *upath, int fd, const char *link)
  1287. {
  1288. struct vattr vattr;
  1289. char *path;
  1290. int error;
  1291. struct nameidata nd;
  1292. path = pool_get(&namei_pool, PR_WAITOK);
  1293. error = copyinstr(upath, path, MAXPATHLEN, NULL);
  1294. if (error)
  1295. goto out;
  1296. NDINITAT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, fd, link, p);
  1297. if ((error = namei(&nd)) != 0)
  1298. goto out;
  1299. if (nd.ni_vp) {
  1300. VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
  1301. if (nd.ni_dvp == nd.ni_vp)
  1302. vrele(nd.ni_dvp);
  1303. else
  1304. vput(nd.ni_dvp);
  1305. vrele(nd.ni_vp);
  1306. error = EEXIST;
  1307. goto out;
  1308. }
  1309. VATTR_NULL(&vattr);
  1310. vattr.va_mode = ACCESSPERMS &~ p->p_fd->fd_cmask;
  1311. error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, path);
  1312. out:
  1313. pool_put(&namei_pool, path);
  1314. return (error);
  1315. }
  1316. /*
  1317. * Delete a name from the filesystem.
  1318. */
  1319. /* ARGSUSED */
  1320. int
  1321. sys_unlink(struct proc *p, void *v, register_t *retval)
  1322. {
  1323. struct sys_unlink_args /* {
  1324. syscallarg(const char *) path;
  1325. } */ *uap = v;
  1326. p->p_tamenote |= TMN_CREAT;
  1327. return (dounlinkat(p, AT_FDCWD, SCARG(uap, path), 0));
  1328. }
  1329. int
  1330. sys_unlinkat(struct proc *p, void *v, register_t *retval)
  1331. {
  1332. struct sys_unlinkat_args /* {
  1333. syscallarg(int) fd;
  1334. syscallarg(const char *) path;
  1335. syscallarg(int) flag;
  1336. } */ *uap = v;
  1337. return (dounlinkat(p, SCARG(uap, fd), SCARG(uap, path),
  1338. SCARG(uap, flag)));
  1339. }
  1340. int
  1341. dounlinkat(struct proc *p, int fd, const char *path, int flag)
  1342. {
  1343. struct vnode *vp;
  1344. int error;
  1345. struct nameidata nd;
  1346. if (flag & ~AT_REMOVEDIR)
  1347. return (EINVAL);
  1348. NDINITAT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_USERSPACE,
  1349. fd, path, p);
  1350. if ((error = namei(&nd)) != 0)
  1351. return (error);
  1352. vp = nd.ni_vp;
  1353. if (flag & AT_REMOVEDIR) {
  1354. if (vp->v_type != VDIR) {
  1355. error = ENOTDIR;
  1356. goto out;
  1357. }
  1358. /*
  1359. * No rmdir "." please.
  1360. */
  1361. if (nd.ni_dvp == vp) {
  1362. error = EBUSY;
  1363. goto out;
  1364. }
  1365. }
  1366. /*
  1367. * The root of a mounted filesystem cannot be deleted.
  1368. */
  1369. if (vp->v_flag & VROOT)
  1370. error = EBUSY;
  1371. out:
  1372. if (!error) {
  1373. if (flag & AT_REMOVEDIR) {
  1374. error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
  1375. } else {
  1376. (void)uvm_vnp_uncache(vp);
  1377. error = VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
  1378. }
  1379. } else {
  1380. VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
  1381. if (nd.ni_dvp == vp)
  1382. vrele(nd.ni_dvp);
  1383. else
  1384. vput(nd.ni_dvp);
  1385. vput(vp);
  1386. }
  1387. return (error);
  1388. }
  1389. /*
  1390. * Reposition read/write file offset.
  1391. */
  1392. int
  1393. sys_lseek(struct proc *p, void *v, register_t *retval)
  1394. {
  1395. struct sys_lseek_args /* {
  1396. syscallarg(int) fd;
  1397. syscallarg(int) pad;
  1398. syscallarg(off_t) offset;
  1399. syscallarg(int) whence;
  1400. } */ *uap = v;
  1401. struct ucred *cred = p->p_ucred;
  1402. struct filedesc *fdp = p->p_fd;
  1403. struct file *fp;
  1404. struct vattr vattr;
  1405. struct vnode *vp;
  1406. off_t offarg, newoff;
  1407. int error, special;
  1408. if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
  1409. return (EBADF);
  1410. if (fp->f_type != DTYPE_VNODE)
  1411. return (ESPIPE);
  1412. vp = (struct vnode *)fp->f_data;
  1413. if (vp->v_type == VFIFO)
  1414. return (ESPIPE);
  1415. FREF(fp);
  1416. if (vp->v_type == VCHR)
  1417. special = 1;
  1418. else
  1419. special = 0;
  1420. offarg = SCARG(uap, offset);
  1421. switch (SCARG(uap, whence)) {
  1422. case SEEK_CUR:
  1423. newoff = fp->f_offset + offarg;
  1424. break;
  1425. case SEEK_END:
  1426. error = VOP_GETATTR(vp, &vattr, cred, p);
  1427. if (error)
  1428. goto bad;
  1429. newoff = offarg + (off_t)vattr.va_size;
  1430. break;
  1431. case SEEK_SET:
  1432. newoff = offarg;
  1433. break;
  1434. default:
  1435. error = EINVAL;
  1436. goto bad;
  1437. }
  1438. if (!special) {
  1439. if (newoff < 0) {
  1440. error = EINVAL;
  1441. goto bad;
  1442. }
  1443. }
  1444. *(off_t *)retval = fp->f_offset = newoff;
  1445. fp->f_seek++;
  1446. error = 0;
  1447. bad:
  1448. FRELE(fp, p);
  1449. return (error);
  1450. }
  1451. /*
  1452. * Check access permissions.
  1453. */
  1454. int
  1455. sys_access(struct proc *p, void *v, register_t *retval)
  1456. {
  1457. struct sys_access_args /* {
  1458. syscallarg(const char *) path;
  1459. syscallarg(int) amode;
  1460. } */ *uap = v;
  1461. return (dofaccessat(p, AT_FDCWD, SCARG(uap, path),
  1462. SCARG(uap, amode), 0));
  1463. }
  1464. int
  1465. sys_faccessat(struct proc *p, void *v, register_t *retval)
  1466. {
  1467. struct sys_faccessat_args /* {
  1468. syscallarg(int) fd;
  1469. syscallarg(const char *) path;
  1470. syscallarg(int) amode;
  1471. syscallarg(int) flag;
  1472. } */ *uap = v;
  1473. return (dofaccessat(p, SCARG(uap, fd), SCARG(uap, path),
  1474. SCARG(uap, amode), SCARG(uap, flag)));
  1475. }
  1476. int
  1477. dofaccessat(struct proc *p, int fd, const char *path, int amode, int flag)
  1478. {
  1479. struct vnode *vp;
  1480. struct ucred *newcred, *oldcred;
  1481. struct nameidata nd;
  1482. int error;
  1483. if (amode & ~(R_OK | W_OK | X_OK))
  1484. return (EINVAL);
  1485. if (flag & ~AT_EACCESS)
  1486. return (EINVAL);
  1487. newcred = NULL;
  1488. oldcred = p->p_ucred;
  1489. /*
  1490. * If access as real ids was requested and they really differ,
  1491. * give the thread new creds with them reset
  1492. */
  1493. if ((flag & AT_EACCESS) == 0 &&
  1494. (oldcred->cr_uid != oldcred->cr_ruid ||
  1495. (oldcred->cr_gid != oldcred->cr_rgid))) {
  1496. p->p_ucred = newcred = crdup(oldcred);
  1497. newcred->cr_uid = newcred->cr_ruid;
  1498. newcred->cr_gid = newcred->cr_rgid;
  1499. }
  1500. NDINITAT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, fd, path, p);
  1501. if ((error = namei(&nd)) != 0)
  1502. goto out;
  1503. vp = nd.ni_vp;
  1504. /* Flags == 0 means only check for existence. */
  1505. if (amode) {
  1506. int vflags = 0;
  1507. if (amode & R_OK)
  1508. vflags |= VREAD;
  1509. if (amode & W_OK)
  1510. vflags |= VWRITE;
  1511. if (amode & X_OK)
  1512. vflags |= VEXEC;
  1513. error = VOP_ACCESS(vp, vflags, p->p_ucred, p);
  1514. if (!error && (vflags & VWRITE))
  1515. error = vn_writechk(vp);
  1516. }
  1517. vput(vp);
  1518. out:
  1519. if (newcred != NULL) {
  1520. p->p_ucred = oldcred;
  1521. crfree(newcred);
  1522. }
  1523. return (error);
  1524. }
  1525. /*
  1526. * Get file status; this version follows links.
  1527. */
  1528. /* ARGSUSED */
  1529. int
  1530. sys_stat(struct proc *p, void *v, register_t *retval)
  1531. {
  1532. struct sys_stat_args /* {
  1533. syscallarg(const char *) path;
  1534. syscallarg(struct stat *) ub;
  1535. } */ *uap = v;
  1536. return (dofstatat(p, AT_FDCWD, SCARG(uap, path), SCARG(uap, ub), 0));
  1537. }
  1538. int
  1539. sys_fstatat(struct proc *p, void *v, register_t *retval)
  1540. {
  1541. struct sys_fstatat_args /* {
  1542. syscallarg(int) fd;
  1543. syscallarg(const char *) path;
  1544. syscallarg(struct stat *) buf;
  1545. syscallarg(int) flag;
  1546. } */ *uap = v;
  1547. return (dofstatat(p, SCARG(uap, fd), SCARG(uap, path),
  1548. SCARG(uap, buf), SCARG(uap, flag)));
  1549. }
  1550. int
  1551. dofstatat(struct proc *p, int fd, const char *path, struct stat *buf, int flag)
  1552. {
  1553. struct stat sb;
  1554. int error, follow;
  1555. struct nameidata nd;
  1556. if (flag & ~AT_SYMLINK_NOFOLLOW)
  1557. return (EINVAL);
  1558. follow = (flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW;
  1559. NDINITAT(&nd, LOOKUP, follow | LOCKLEAF, UIO_USERSPACE, fd, path, p);
  1560. if ((error = namei(&nd)) != 0)
  1561. return (error);
  1562. error = vn_stat(nd.ni_vp, &sb, p);
  1563. vput(nd.ni_vp);
  1564. if (error)
  1565. return (error);
  1566. /* Don't let non-root see generation numbers (for NFS security) */
  1567. if (suser(p, 0))
  1568. sb.st_gen = 0;
  1569. error = copyout(&sb, buf, sizeof(sb));
  1570. #ifdef KTRACE
  1571. if (error == 0 && KTRPOINT(p, KTR_STRUCT))
  1572. ktrstat(p, &sb);
  1573. #endif
  1574. return (error);
  1575. }
  1576. /*
  1577. * Get file status; this version does not follow links.
  1578. */
  1579. /* ARGSUSED */
  1580. int
  1581. sys_lstat(struct proc *p, void *v, register_t *retval)
  1582. {
  1583. struct sys_lstat_args /* {
  1584. syscallarg(const char *) path;
  1585. syscallarg(struct stat *) ub;
  1586. } */ *uap = v;
  1587. return (dofstatat(p, AT_FDCWD, SCARG(uap, path), SCARG(uap, ub),
  1588. AT_SYMLINK_NOFOLLOW));
  1589. }
  1590. /*
  1591. * Get configurable pathname variables.
  1592. */
  1593. /* ARGSUSED */
  1594. int
  1595. sys_pathconf(struct proc *p, void *v, register_t *retval)
  1596. {
  1597. struct sys_pathconf_args /* {
  1598. syscallarg(const char *) path;
  1599. syscallarg(int) name;
  1600. } */ *uap = v;
  1601. int error;
  1602. struct nameidata nd;
  1603. NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
  1604. SCARG(uap, path), p);
  1605. if ((error = namei(&nd)) != 0)
  1606. return (error);
  1607. error = VOP_PATHCONF(nd.ni_vp, SCARG(uap, name), retval);
  1608. vput(nd.ni_vp);
  1609. return (error);
  1610. }
  1611. /*
  1612. * Return target name of a symbolic link.
  1613. */
  1614. /* ARGSUSED */
  1615. int
  1616. sys_readlink(struct proc *p, void *v, register_t *retval)
  1617. {
  1618. struct sys_readlink_args /* {
  1619. syscallarg(const char *) path;
  1620. syscallarg(char *) buf;
  1621. syscallarg(size_t) count;
  1622. } */ *uap = v;
  1623. return (doreadlinkat(p, AT_FDCWD, SCARG(uap, path), SCARG(uap, buf),
  1624. SCARG(uap, count), retval));
  1625. }
  1626. int
  1627. sys_readlinkat(struct proc *p, void *v, register_t *retval)
  1628. {
  1629. struct sys_readlinkat_args /* {
  1630. syscallarg(int) fd;
  1631. syscallarg(const char *) path;
  1632. syscallarg(char *) buf;
  1633. syscallarg(size_t) count;
  1634. } */ *uap = v;
  1635. return (doreadlinkat(p, SCARG(uap, fd), SCARG(uap, path),
  1636. SCARG(uap, buf), SCARG(uap, count), retval));
  1637. }
  1638. int
  1639. doreadlinkat(struct proc *p, int fd, const char *path, char *buf,
  1640. size_t count, register_t *retval)
  1641. {
  1642. struct vnode *vp;
  1643. struct iovec aiov;
  1644. struct uio auio;
  1645. int error;
  1646. struct nameidata nd;
  1647. NDINITAT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_USERSPACE, fd, path, p);
  1648. if ((error = namei(&nd)) != 0)
  1649. return (error);
  1650. vp = nd.ni_vp;
  1651. if (vp->v_type != VLNK)
  1652. error = EINVAL;
  1653. else {
  1654. aiov.iov_base = buf;
  1655. aiov.iov_len = count;
  1656. auio.uio_iov = &aiov;
  1657. auio.uio_iovcnt = 1;
  1658. auio.uio_offset = 0;
  1659. auio.uio_rw = UIO_READ;
  1660. auio.uio_segflg = UIO_USERSPACE;
  1661. auio.uio_procp = p;
  1662. auio.uio_resid = count;
  1663. error = VOP_READLINK(vp, &auio, p->p_ucred);
  1664. *retval = count - auio.uio_resid;
  1665. }
  1666. vput(vp);
  1667. return (error);
  1668. }
  1669. /*
  1670. * Change flags of a file given a path name.
  1671. */
  1672. int
  1673. sys_chflags(struct proc *p, void *v, register_t *retval)
  1674. {
  1675. struct sys_chflags_args /* {
  1676. syscallarg(const char *) path;
  1677. syscallarg(u_int) flags;
  1678. } */ *uap = v;
  1679. p->p_tamenote |= TMN_IMODIFY;
  1680. return (dochflagsat(p, AT_FDCWD, SCARG(uap, path),
  1681. SCARG(uap, flags), 0));
  1682. }
  1683. int
  1684. sys_chflagsat(struct proc *p, void *v, register_t *retval)
  1685. {
  1686. struct sys_chflagsat_args /* {
  1687. syscallarg(int) fd;
  1688. syscallarg(const char *) path;
  1689. syscallarg(u_int) flags;
  1690. syscallarg(int) atflags;
  1691. } */ *uap = v;
  1692. return (dochflagsat(p, SCARG(uap, fd), SCARG(uap, path),
  1693. SCARG(uap, flags), SCARG(uap, atflags)));
  1694. }
  1695. int
  1696. dochflagsat(struct proc *p, int fd, const char *path, u_int flags, int atflags)
  1697. {
  1698. struct nameidata nd;
  1699. int error, follow;
  1700. if (atflags & ~AT_SYMLINK_NOFOLLOW)
  1701. return (EINVAL);
  1702. follow = (atflags & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW;
  1703. NDINITAT(&nd, LOOKUP, follow, UIO_USERSPACE, fd, path, p);
  1704. if ((error = namei(&nd)) != 0)
  1705. return (error);
  1706. return (dovchflags(p, nd.ni_vp, flags));
  1707. }
  1708. /*
  1709. * Change flags of a file given a file descriptor.
  1710. */
  1711. int
  1712. sys_fchflags(struct proc *p, void *v, register_t *retval)
  1713. {
  1714. struct sys_fchflags_args /* {
  1715. syscallarg(int) fd;
  1716. syscallarg(u_int) flags;
  1717. } */ *uap = v;
  1718. struct file *fp;
  1719. struct vnode *vp;
  1720. int error;
  1721. if ((error = getvnode(p, SCARG(uap, fd), &fp)) != 0)
  1722. return (error);
  1723. vp = fp->f_data;
  1724. vref(vp);
  1725. FRELE(fp, p);
  1726. return (dovchflags(p, vp, SCARG(uap, flags)));
  1727. }
  1728. int
  1729. dovchflags(struct proc *p, struct vnode *vp, u_int flags)
  1730. {
  1731. struct vattr vattr;
  1732. int error;
  1733. vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
  1734. if (vp->v_mount && vp->v_mount->mnt_flag & MNT_RDONLY)
  1735. error = EROFS;
  1736. else if (flags == VNOVAL)
  1737. error = EINVAL;
  1738. else {
  1739. if (suser(p, 0)) {
  1740. if ((error = VOP_GETATTR(vp, &vattr, p->p_ucred, p))
  1741. != 0)
  1742. goto out;
  1743. if (vattr.va_type == VCHR || vattr.va_type == VBLK) {
  1744. error = EINVAL;
  1745. goto out;
  1746. }
  1747. }
  1748. VATTR_NULL(&vattr);
  1749. vattr.va_flags = flags;
  1750. error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
  1751. }
  1752. out:
  1753. vput(vp);
  1754. return (error);
  1755. }
  1756. /*
  1757. * Change mode of a file given path name.
  1758. */
  1759. /* ARGSUSED */
  1760. int
  1761. sys_chmod(struct proc *p, void *v, register_t *retval)
  1762. {
  1763. struct sys_chmod_args /* {
  1764. syscallarg(const char *) path;
  1765. syscallarg(mode_t) mode;
  1766. } */ *uap = v;
  1767. p->p_tamenote |= TMN_IMODIFY;
  1768. return (dofchmodat(p, AT_FDCWD, SCARG(uap, path), SCARG(uap, mode), 0));
  1769. }
  1770. int
  1771. sys_fchmodat(struct proc *p, void *v, register_t *retval)
  1772. {
  1773. struct sys_fchmodat_args /* {
  1774. syscallarg(int) fd;
  1775. syscallarg(const char *) path;
  1776. syscallarg(mode_t) mode;
  1777. syscallarg(int) flag;
  1778. } */ *uap = v;
  1779. return (dofchmodat(p, SCARG(uap, fd), SCARG(uap, path),
  1780. SCARG(uap, mode), SCARG(uap, flag)));
  1781. }
  1782. int
  1783. dofchmodat(struct proc *p, int fd, const char *path, mode_t mode, int flag)
  1784. {
  1785. struct vnode *vp;
  1786. struct vattr vattr;
  1787. int error, follow;
  1788. struct nameidata nd;
  1789. if (mode & ~(S_IFMT | ALLPERMS))
  1790. return (EINVAL);
  1791. if (flag & ~AT_SYMLINK_NOFOLLOW)
  1792. return (EINVAL);
  1793. follow = (flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW;
  1794. NDINITAT(&nd, LOOKUP, follow, UIO_USERSPACE, fd, path, p);
  1795. if ((error = namei(&nd)) != 0)
  1796. return (error);
  1797. vp = nd.ni_vp;
  1798. vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
  1799. if (vp->v_mount->mnt_flag & MNT_RDONLY)
  1800. error = EROFS;
  1801. else {
  1802. VATTR_NULL(&vattr);
  1803. vattr.va_mode = mode & ALLPERMS;
  1804. error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
  1805. }
  1806. vput(vp);
  1807. return (error);
  1808. }
  1809. /*
  1810. * Change mode of a file given a file descriptor.
  1811. */
  1812. /* ARGSUSED */
  1813. int
  1814. sys_fchmod(struct proc *p, void *v, register_t *retval)
  1815. {
  1816. struct sys_fchmod_args /* {
  1817. syscallarg(int) fd;
  1818. syscallarg(mode_t) mode;
  1819. } */ *uap = v;
  1820. struct vattr vattr;
  1821. struct vnode *vp;
  1822. struct file *fp;
  1823. int error;
  1824. if (SCARG(uap, mode) & ~(S_IFMT | ALLPERMS))
  1825. return (EINVAL);
  1826. if ((error = getvnode(p, SCARG(uap, fd), &fp)) != 0)
  1827. return (error);
  1828. vp = (struct vnode *)fp->f_data;
  1829. vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
  1830. if (vp->v_mount && vp->v_mount->mnt_flag & MNT_RDONLY)
  1831. error = EROFS;
  1832. else {
  1833. VATTR_NULL(&vattr);
  1834. vattr.va_mode = SCARG(uap, mode) & ALLPERMS;
  1835. error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
  1836. }
  1837. VOP_UNLOCK(vp, 0, p);
  1838. FRELE(fp, p);
  1839. return (error);
  1840. }
  1841. /*
  1842. * Set ownership given a path name.
  1843. */
  1844. /* ARGSUSED */
  1845. int
  1846. sys_chown(struct proc *p, void *v, register_t *retval)
  1847. {
  1848. struct sys_chown_args /* {
  1849. syscallarg(const char *) path;
  1850. syscallarg(uid_t) uid;
  1851. syscallarg(gid_t) gid;
  1852. } */ *uap = v;
  1853. p->p_tamenote |= TMN_IMODIFY;
  1854. return (dofchownat(p, AT_FDCWD, SCARG(uap, path), SCARG(uap, uid),
  1855. SCARG(uap, gid), 0));
  1856. }
  1857. int
  1858. sys_fchownat(struct proc *p, void *v, register_t *retval)
  1859. {
  1860. struct sys_fchownat_args /* {
  1861. syscallarg(int) fd;
  1862. syscallarg(const char *) path;
  1863. syscallarg(uid_t) uid;
  1864. syscallarg(gid_t) gid;
  1865. syscallarg(int) flag;
  1866. } */ *uap = v;
  1867. return (dofchownat(p, SCARG(uap, fd), SCARG(uap, path),
  1868. SCARG(uap, uid), SCARG(uap, gid), SCARG(uap, flag)));
  1869. }
  1870. int
  1871. dofchownat(struct proc *p, int fd, const char *path, uid_t uid, gid_t gid,
  1872. int flag)
  1873. {
  1874. struct vnode *vp;
  1875. struct vattr vattr;
  1876. int error, follow;
  1877. struct nameidata nd;
  1878. mode_t mode;
  1879. if (flag & ~AT_SYMLINK_NOFOLLOW)
  1880. return (EINVAL);
  1881. follow = (flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW;
  1882. NDINITAT(&nd, LOOKUP, follow, UIO_USERSPACE, fd, path, p);
  1883. if ((error = namei(&nd)) != 0)
  1884. return (error);
  1885. vp = nd.ni_vp;
  1886. vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
  1887. if (vp->v_mount->mnt_flag & MNT_RDONLY)
  1888. error = EROFS;
  1889. else {
  1890. if ((uid != -1 || gid != -1) &&
  1891. (suser(p, 0) || suid_clear)) {
  1892. error = VOP_GETATTR(vp, &vattr, p->p_ucred, p);
  1893. if (error)
  1894. goto out;
  1895. mode = vattr.va_mode & ~(VSUID | VSGID);
  1896. if (mode == vattr.va_mode)
  1897. mode = VNOVAL;
  1898. }
  1899. else
  1900. mode = VNOVAL;
  1901. VATTR_NULL(&vattr);
  1902. vattr.va_uid = uid;
  1903. vattr.va_gid = gid;
  1904. vattr.va_mode = mode;
  1905. error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
  1906. }
  1907. out:
  1908. vput(vp);
  1909. return (error);
  1910. }
  1911. /*
  1912. * Set ownership given a path name, without following links.
  1913. */
  1914. /* ARGSUSED */
  1915. int
  1916. sys_lchown(struct proc *p, void *v, register_t *retval)
  1917. {
  1918. struct sys_lchown_args /* {
  1919. syscallarg(const char *) path;
  1920. syscallarg(uid_t) uid;
  1921. syscallarg(gid_t) gid;
  1922. } */ *uap = v;
  1923. struct vnode *vp;
  1924. struct vattr vattr;
  1925. int error;
  1926. struct nameidata nd;
  1927. mode_t mode;
  1928. uid_t uid = SCARG(uap, uid);
  1929. gid_t gid = SCARG(uap, gid);
  1930. p->p_tamenote |= TMN_IMODIFY;
  1931. NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
  1932. if ((error = namei(&nd)) != 0)
  1933. return (error);
  1934. vp = nd.ni_vp;
  1935. vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
  1936. if (vp->v_mount->mnt_flag & MNT_RDONLY)
  1937. error = EROFS;
  1938. else {
  1939. if ((uid != -1 || gid != -1) &&
  1940. (suser(p, 0) || suid_clear)) {
  1941. error = VOP_GETATTR(vp, &vattr, p->p_ucred, p);
  1942. if (error)
  1943. goto out;
  1944. mode = vattr.va_mode & ~(VSUID | VSGID);
  1945. if (mode == vattr.va_mode)
  1946. mode = VNOVAL;
  1947. }
  1948. else
  1949. mode = VNOVAL;
  1950. VATTR_NULL(&vattr);
  1951. vattr.va_uid = uid;
  1952. vattr.va_gid = gid;
  1953. vattr.va_mode = mode;
  1954. error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
  1955. }
  1956. out:
  1957. vput(vp);
  1958. return (error);
  1959. }
  1960. /*
  1961. * Set ownership given a file descriptor.
  1962. */
  1963. /* ARGSUSED */
  1964. int
  1965. sys_fchown(struct proc *p, void *v, register_t *retval)
  1966. {
  1967. struct sys_fchown_args /* {
  1968. syscallarg(int) fd;
  1969. syscallarg(uid_t) uid;
  1970. syscallarg(gid_t) gid;
  1971. } */ *uap = v;
  1972. struct vnode *vp;
  1973. struct vattr vattr;
  1974. int error;
  1975. struct file *fp;
  1976. mode_t mode;
  1977. uid_t uid = SCARG(uap, uid);
  1978. gid_t gid = SCARG(uap, gid);
  1979. if ((error = getvnode(p, SCARG(uap, fd), &fp)) != 0)
  1980. return (error);
  1981. vp = (struct vnode *)fp->f_data;
  1982. vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
  1983. if (vp->v_mount->mnt_flag & MNT_RDONLY)
  1984. error = EROFS;
  1985. else {
  1986. if ((uid != -1 || gid != -1) &&
  1987. (suser(p, 0) || suid_clear)) {
  1988. error = VOP_GETATTR(vp, &vattr, p->p_ucred, p);
  1989. if (error)
  1990. goto out;
  1991. mode = vattr.va_mode & ~(VSUID | VSGID);
  1992. if (mode == vattr.va_mode)
  1993. mode = VNOVAL;
  1994. } else
  1995. mode = VNOVAL;
  1996. VATTR_NULL(&vattr);
  1997. vattr.va_uid = uid;
  1998. vattr.va_gid = gid;
  1999. vattr.va_mode = mode;
  2000. error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
  2001. }
  2002. out:
  2003. VOP_UNLOCK(vp, 0, p);
  2004. FRELE(fp, p);
  2005. return (error);
  2006. }
  2007. /*
  2008. * Set the access and modification times given a path name.
  2009. */
  2010. /* ARGSUSED */
  2011. int
  2012. sys_utimes(struct proc *p, void *v, register_t *retval)
  2013. {
  2014. struct sys_utimes_args /* {
  2015. syscallarg(const char *) path;
  2016. syscallarg(const struct timeval *) tptr;
  2017. } */ *uap = v;
  2018. struct timespec ts[2];
  2019. struct timeval tv[2];
  2020. const struct timeval *tvp;
  2021. int error;
  2022. p->p_tamenote |= TMN_IMODIFY;
  2023. tvp = SCARG(uap, tptr);
  2024. if (tvp != NULL) {
  2025. error = copyin(tvp, tv, sizeof(tv));
  2026. if (error)
  2027. return (error);
  2028. TIMEVAL_TO_TIMESPEC(&tv[0], &ts[0]);
  2029. TIMEVAL_TO_TIMESPEC(&tv[1], &ts[1]);
  2030. } else
  2031. ts[0].tv_nsec = ts[1].tv_nsec = UTIME_NOW;
  2032. return (doutimensat(p, AT_FDCWD, SCARG(uap, path), ts, 0));
  2033. }
  2034. int
  2035. sys_utimensat(struct proc *p, void *v, register_t *retval)
  2036. {
  2037. struct sys_utimensat_args /* {
  2038. syscallarg(int) fd;
  2039. syscallarg(const char *) path;
  2040. syscallarg(const struct timespec *) times;
  2041. syscallarg(int) flag;
  2042. } */ *uap = v;
  2043. struct timespec ts[2];
  2044. const struct timespec *tsp;
  2045. int error;
  2046. tsp = SCARG(uap, times);
  2047. if (tsp != NULL) {
  2048. error = copyin(tsp, ts, sizeof(ts));
  2049. if (error)
  2050. return (error);
  2051. } else
  2052. ts[0].tv_nsec = ts[1].tv_nsec = UTIME_NOW;
  2053. return (doutimensat(p, SCARG(uap, fd), SCARG(uap, path), ts,
  2054. SCARG(uap, flag)));
  2055. }
  2056. int
  2057. doutimensat(struct proc *p, int fd, const char *path,
  2058. struct timespec ts[2], int flag)
  2059. {
  2060. struct vnode *vp;
  2061. int error, follow;
  2062. struct nameidata nd;
  2063. if (flag & ~AT_SYMLINK_NOFOLLOW)
  2064. return (EINVAL);
  2065. follow = (flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW;
  2066. NDINITAT(&nd, LOOKUP, follow, UIO_USERSPACE, fd, path, p);
  2067. if ((error = namei(&nd)) != 0)
  2068. return (error);
  2069. vp = nd.ni_vp;
  2070. return (dovutimens(p, vp, ts));
  2071. }
  2072. int
  2073. dovutimens(struct proc *p, struct vnode *vp, struct timespec ts[2])
  2074. {
  2075. struct vattr vattr;
  2076. struct timespec now;
  2077. int error;
  2078. #ifdef KTRACE
  2079. /* if they're both UTIME_NOW, then don't report either */
  2080. if ((ts[0].tv_nsec != UTIME_NOW || ts[1].tv_nsec != UTIME_NOW) &&
  2081. KTRPOINT(p, KTR_STRUCT)) {
  2082. ktrabstimespec(p, &ts[0]);
  2083. ktrabstimespec(p, &ts[1]);
  2084. }
  2085. #endif
  2086. VATTR_NULL(&vattr);
  2087. /* make sure ctime is updated even if neither mtime nor atime is */
  2088. vattr.va_vaflags = VA_UTIMES_CHANGE;
  2089. if (ts[0].tv_nsec == UTIME_NOW || ts[1].tv_nsec == UTIME_NOW) {
  2090. if (ts[0].tv_nsec == UTIME_NOW && ts[1].tv_nsec == UTIME_NOW)
  2091. vattr.va_vaflags |= VA_UTIMES_NULL;
  2092. getnanotime(&now);
  2093. if (ts[0].tv_nsec == UTIME_NOW)
  2094. ts[0] = now;
  2095. if (ts[1].tv_nsec == UTIME_NOW)
  2096. ts[1] = now;
  2097. }
  2098. if (ts[0].tv_nsec != UTIME_OMIT) {
  2099. if (ts[0].tv_nsec < 0 || ts[0].tv_nsec >= 1000000000)
  2100. return (EINVAL);
  2101. vattr.va_atime = ts[0];
  2102. }
  2103. if (ts[1].tv_nsec != UTIME_OMIT) {
  2104. if (ts[1].tv_nsec < 0 || ts[1].tv_nsec >= 1000000000)
  2105. return (EINVAL);
  2106. vattr.va_mtime = ts[1];
  2107. }
  2108. vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
  2109. if (vp->v_mount->mnt_flag & MNT_RDONLY)
  2110. error = EROFS;
  2111. else
  2112. error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
  2113. vput(vp);
  2114. return (error);
  2115. }
  2116. /*
  2117. * Set the access and modification times given a file descriptor.
  2118. */
  2119. /* ARGSUSED */
  2120. int
  2121. sys_futimes(struct proc *p, void *v, register_t *retval)
  2122. {
  2123. struct sys_futimes_args /* {
  2124. syscallarg(int) fd;
  2125. syscallarg(const struct timeval *) tptr;
  2126. } */ *uap = v;
  2127. struct timeval tv[2];
  2128. struct timespec ts[2];
  2129. const struct timeval *tvp;
  2130. int error;
  2131. tvp = SCARG(uap, tptr);
  2132. if (tvp != NULL) {
  2133. error = copyin(tvp, tv, sizeof(tv));
  2134. if (error)
  2135. return (error);
  2136. TIMEVAL_TO_TIMESPEC(&tv[0], &ts[0]);
  2137. TIMEVAL_TO_TIMESPEC(&tv[1], &ts[1]);
  2138. } else
  2139. ts[0].tv_nsec = ts[1].tv_nsec = UTIME_NOW;
  2140. return (dofutimens(p, SCARG(uap, fd), ts));
  2141. }
  2142. int
  2143. sys_futimens(struct proc *p, void *v, register_t *retval)
  2144. {
  2145. struct sys_futimens_args /* {
  2146. syscallarg(int) fd;
  2147. syscallarg(const struct timespec *) times;
  2148. } */ *uap = v;
  2149. struct timespec ts[2];
  2150. const struct timespec *tsp;
  2151. int error;
  2152. tsp = SCARG(uap, times);
  2153. if (tsp != NULL) {
  2154. error = copyin(tsp, ts, sizeof(ts));
  2155. if (error)
  2156. return (error);
  2157. } else
  2158. ts[0].tv_nsec = ts[1].tv_nsec = UTIME_NOW;
  2159. return (dofutimens(p, SCARG(uap, fd), ts));
  2160. }
  2161. int
  2162. dofutimens(struct proc *p, int fd, struct timespec ts[2])
  2163. {
  2164. struct file *fp;
  2165. struct vnode *vp;
  2166. int error;
  2167. if ((error = getvnode(p, fd, &fp)) != 0)
  2168. return (error);
  2169. vp = (struct vnode *)fp->f_data;
  2170. vref(vp);
  2171. FRELE(fp, p);
  2172. return (dovutimens(p, vp, ts));
  2173. }
  2174. /*
  2175. * Truncate a file given its path name.
  2176. */
  2177. /* ARGSUSED */
  2178. int
  2179. sys_truncate(struct proc *p, void *v, register_t *retval)
  2180. {
  2181. struct sys_truncate_args /* {
  2182. syscallarg(const char *) path;
  2183. syscallarg(int) pad;
  2184. syscallarg(off_t) length;
  2185. } */ *uap = v;
  2186. struct vnode *vp;
  2187. struct vattr vattr;
  2188. int error;
  2189. struct nameidata nd;
  2190. p->p_tamenote |= TMN_IMODIFY;
  2191. NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
  2192. if ((error = namei(&nd)) != 0)
  2193. return (error);
  2194. vp = nd.ni_vp;
  2195. vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
  2196. if (vp->v_type == VDIR)
  2197. error = EISDIR;
  2198. else if ((error = VOP_ACCESS(vp, VWRITE, p->p_ucred, p)) == 0 &&
  2199. (error = vn_writechk(vp)) == 0) {
  2200. VATTR_NULL(&vattr);
  2201. vattr.va_size = SCARG(uap, length);
  2202. error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
  2203. }
  2204. vput(vp);
  2205. return (error);
  2206. }
  2207. /*
  2208. * Truncate a file given a file descriptor.
  2209. */
  2210. /* ARGSUSED */
  2211. int
  2212. sys_ftruncate(struct proc *p, void *v, register_t *retval)
  2213. {
  2214. struct sys_ftruncate_args /* {
  2215. syscallarg(int) fd;
  2216. syscallarg(int) pad;
  2217. syscallarg(off_t) length;
  2218. } */ *uap = v;
  2219. struct vattr vattr;
  2220. struct vnode *vp;
  2221. struct file *fp;
  2222. off_t len;
  2223. int error;
  2224. if ((error = getvnode(p, SCARG(uap, fd), &fp)) != 0)
  2225. return (error);
  2226. len = SCARG(uap, length);
  2227. if ((fp->f_flag & FWRITE) == 0 || len < 0) {
  2228. error = EINVAL;
  2229. goto bad;
  2230. }
  2231. vp = (struct vnode *)fp->f_data;
  2232. vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
  2233. if (vp->v_type == VDIR)
  2234. error = EISDIR;
  2235. else if ((error = vn_writechk(vp)) == 0) {
  2236. VATTR_NULL(&vattr);
  2237. vattr.va_size = len;
  2238. error = VOP_SETATTR(vp, &vattr, fp->f_cred, p);
  2239. }
  2240. VOP_UNLOCK(vp, 0, p);
  2241. bad:
  2242. FRELE(fp, p);
  2243. return (error);
  2244. }
  2245. /*
  2246. * Sync an open file.
  2247. */
  2248. /* ARGSUSED */
  2249. int
  2250. sys_fsync(struct proc *p, void *v, register_t *retval)
  2251. {
  2252. struct sys_fsync_args /* {
  2253. syscallarg(int) fd;
  2254. } */ *uap = v;
  2255. struct vnode *vp;
  2256. struct file *fp;
  2257. int error;
  2258. if ((error = getvnode(p, SCARG(uap, fd), &fp)) != 0)
  2259. return (error);
  2260. vp = (struct vnode *)fp->f_data;
  2261. vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
  2262. error = VOP_FSYNC(vp, fp->f_cred, MNT_WAIT, p);
  2263. #ifdef FFS_SOFTUPDATES
  2264. if (error == 0 && vp->v_mount && (vp->v_mount->mnt_flag & MNT_SOFTDEP))
  2265. error = softdep_fsync(vp);
  2266. #endif
  2267. VOP_UNLOCK(vp, 0, p);
  2268. FRELE(fp, p);
  2269. return (error);
  2270. }
  2271. /*
  2272. * Rename files. Source and destination must either both be directories,
  2273. * or both not be directories. If target is a directory, it must be empty.
  2274. */
  2275. /* ARGSUSED */
  2276. int
  2277. sys_rename(struct proc *p, void *v, register_t *retval)
  2278. {
  2279. struct sys_rename_args /* {
  2280. syscallarg(const char *) from;
  2281. syscallarg(const char *) to;
  2282. } */ *uap = v;
  2283. p->p_tamenote |= TMN_IMODIFY;
  2284. return (dorenameat(p, AT_FDCWD, SCARG(uap, from), AT_FDCWD,
  2285. SCARG(uap, to)));
  2286. }
  2287. int
  2288. sys_renameat(struct proc *p, void *v, register_t *retval)
  2289. {
  2290. struct sys_renameat_args /* {
  2291. syscallarg(int) fromfd;
  2292. syscallarg(const char *) from;
  2293. syscallarg(int) tofd;
  2294. syscallarg(const char *) to;
  2295. } */ *uap = v;
  2296. return (dorenameat(p, SCARG(uap, fromfd), SCARG(uap, from),
  2297. SCARG(uap, tofd), SCARG(uap, to)));
  2298. }
  2299. int
  2300. dorenameat(struct proc *p, int fromfd, const char *from, int tofd,
  2301. const char *to)
  2302. {
  2303. struct vnode *tvp, *fvp, *tdvp;
  2304. struct nameidata fromnd, tond;
  2305. int error;
  2306. int flags;
  2307. NDINITAT(&fromnd, DELETE, WANTPARENT | SAVESTART, UIO_USERSPACE,
  2308. fromfd, from, p);
  2309. if ((error = namei(&fromnd)) != 0)
  2310. return (error);
  2311. fvp = fromnd.ni_vp;
  2312. flags = LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART;
  2313. /*
  2314. * rename("foo/", "bar/"); is OK
  2315. */
  2316. if (fvp->v_type == VDIR)
  2317. flags |= STRIPSLASHES;
  2318. NDINITAT(&tond, RENAME, flags, UIO_USERSPACE, tofd, to, p);
  2319. if ((error = namei(&tond)) != 0) {
  2320. VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd);
  2321. vrele(fromnd.ni_dvp);
  2322. vrele(fvp);
  2323. goto out1;
  2324. }
  2325. tdvp = tond.ni_dvp;
  2326. tvp = tond.ni_vp;
  2327. if (tvp != NULL) {
  2328. if (fvp->v_type == VDIR && tvp->v_type != VDIR) {
  2329. error = ENOTDIR;
  2330. goto out;
  2331. } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) {
  2332. error = EISDIR;
  2333. goto out;
  2334. }
  2335. }
  2336. if (fvp == tdvp)
  2337. error = EINVAL;
  2338. /*
  2339. * If source is the same as the destination (that is the
  2340. * same inode number)
  2341. */
  2342. if (fvp == tvp)
  2343. error = -1;
  2344. out:
  2345. if (!error) {
  2346. if (tvp) {
  2347. (void)uvm_vnp_uncache(tvp);
  2348. }
  2349. error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd,
  2350. tond.ni_dvp, tond.ni_vp, &tond.ni_cnd);
  2351. } else {
  2352. VOP_ABORTOP(tond.ni_dvp, &tond.ni_cnd);
  2353. if (tdvp == tvp)
  2354. vrele(tdvp);
  2355. else
  2356. vput(tdvp);
  2357. if (tvp)
  2358. vput(tvp);
  2359. VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd);
  2360. vrele(fromnd.ni_dvp);
  2361. vrele(fvp);
  2362. }
  2363. vrele(tond.ni_startdir);
  2364. pool_put(&namei_pool, tond.ni_cnd.cn_pnbuf);
  2365. out1:
  2366. if (fromnd.ni_startdir)
  2367. vrele(fromnd.ni_startdir);
  2368. pool_put(&namei_pool, fromnd.ni_cnd.cn_pnbuf);
  2369. if (error == -1)
  2370. return (0);
  2371. return (error);
  2372. }
  2373. /*
  2374. * Make a directory file.
  2375. */
  2376. /* ARGSUSED */
  2377. int
  2378. sys_mkdir(struct proc *p, void *v, register_t *retval)
  2379. {
  2380. struct sys_mkdir_args /* {
  2381. syscallarg(const char *) path;
  2382. syscallarg(mode_t) mode;
  2383. } */ *uap = v;
  2384. p->p_tamenote |= TMN_CREAT;
  2385. return (domkdirat(p, AT_FDCWD, SCARG(uap, path), SCARG(uap, mode)));
  2386. }
  2387. int
  2388. sys_mkdirat(struct proc *p, void *v, register_t *retval)
  2389. {
  2390. struct sys_mkdirat_args /* {
  2391. syscallarg(int) fd;
  2392. syscallarg(const char *) path;
  2393. syscallarg(mode_t) mode;
  2394. } */ *uap = v;
  2395. return (domkdirat(p, SCARG(uap, fd), SCARG(uap, path),
  2396. SCARG(uap, mode)));
  2397. }
  2398. int
  2399. domkdirat(struct proc *p, int fd, const char *path, mode_t mode)
  2400. {
  2401. struct vnode *vp;
  2402. struct vattr vattr;
  2403. int error;
  2404. struct nameidata nd;
  2405. NDINITAT(&nd, CREATE, LOCKPARENT | STRIPSLASHES, UIO_USERSPACE,
  2406. fd, path, p);
  2407. if ((error = namei(&nd)) != 0)
  2408. return (error);
  2409. vp = nd.ni_vp;
  2410. if (vp != NULL) {
  2411. VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
  2412. if (nd.ni_dvp == vp)
  2413. vrele(nd.ni_dvp);
  2414. else
  2415. vput(nd.ni_dvp);
  2416. vrele(vp);
  2417. return (EEXIST);
  2418. }
  2419. VATTR_NULL(&vattr);
  2420. vattr.va_type = VDIR;
  2421. vattr.va_mode = (mode & ACCESSPERMS) &~ p->p_fd->fd_cmask;
  2422. error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
  2423. if (!error)
  2424. vput(nd.ni_vp);
  2425. return (error);
  2426. }
  2427. /*
  2428. * Remove a directory file.
  2429. */
  2430. /* ARGSUSED */
  2431. int
  2432. sys_rmdir(struct proc *p, void *v, register_t *retval)
  2433. {
  2434. struct sys_rmdir_args /* {
  2435. syscallarg(const char *) path;
  2436. } */ *uap = v;
  2437. p->p_tamenote |= TMN_CREAT;
  2438. return (dounlinkat(p, AT_FDCWD, SCARG(uap, path), AT_REMOVEDIR));
  2439. }
  2440. /*
  2441. * Read a block of directory entries in a file system independent format.
  2442. */
  2443. int
  2444. sys_getdents(struct proc *p, void *v, register_t *retval)
  2445. {
  2446. struct sys_getdents_args /* {
  2447. syscallarg(int) fd;
  2448. syscallarg(void *) buf;
  2449. syscallarg(size_t) buflen;
  2450. } */ *uap = v;
  2451. struct vnode *vp;
  2452. struct file *fp;
  2453. struct uio auio;
  2454. struct iovec aiov;
  2455. size_t buflen;
  2456. int error, eofflag;
  2457. buflen = SCARG(uap, buflen);
  2458. if (buflen > INT_MAX)
  2459. return EINVAL;
  2460. if ((error = getvnode(p, SCARG(uap, fd), &fp)) != 0)
  2461. return (error);
  2462. if ((fp->f_flag & FREAD) == 0) {
  2463. error = EBADF;
  2464. goto bad;
  2465. }
  2466. if (fp->f_offset < 0) {
  2467. error = EINVAL;
  2468. goto bad;
  2469. }
  2470. vp = fp->f_data;
  2471. if (vp->v_type != VDIR) {
  2472. error = EINVAL;
  2473. goto bad;
  2474. }
  2475. aiov.iov_base = SCARG(uap, buf);
  2476. aiov.iov_len = buflen;
  2477. auio.uio_iov = &aiov;
  2478. auio.uio_iovcnt = 1;
  2479. auio.uio_rw = UIO_READ;
  2480. auio.uio_segflg = UIO_USERSPACE;
  2481. auio.uio_procp = p;
  2482. auio.uio_resid = buflen;
  2483. vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
  2484. auio.uio_offset = fp->f_offset;
  2485. error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag);
  2486. fp->f_offset = auio.uio_offset;
  2487. VOP_UNLOCK(vp, 0, p);
  2488. if (error)
  2489. goto bad;
  2490. *retval = buflen - auio.uio_resid;
  2491. bad:
  2492. FRELE(fp, p);
  2493. return (error);
  2494. }
  2495. /*
  2496. * Set the mode mask for creation of filesystem nodes.
  2497. */
  2498. int
  2499. sys_umask(struct proc *p, void *v, register_t *retval)
  2500. {
  2501. struct sys_umask_args /* {
  2502. syscallarg(mode_t) newmask;
  2503. } */ *uap = v;
  2504. struct filedesc *fdp;
  2505. fdp = p->p_fd;
  2506. *retval = fdp->fd_cmask;
  2507. fdp->fd_cmask = SCARG(uap, newmask) & ACCESSPERMS;
  2508. return (0);
  2509. }
  2510. /*
  2511. * Void all references to file by ripping underlying filesystem
  2512. * away from vnode.
  2513. */
  2514. /* ARGSUSED */
  2515. int
  2516. sys_revoke(struct proc *p, void *v, register_t *retval)
  2517. {
  2518. struct sys_revoke_args /* {
  2519. syscallarg(const char *) path;
  2520. } */ *uap = v;
  2521. struct vnode *vp;
  2522. struct vattr vattr;
  2523. int error;
  2524. struct nameidata nd;
  2525. p->p_tamenote |= TMN_CREAT;
  2526. NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
  2527. if ((error = namei(&nd)) != 0)
  2528. return (error);
  2529. vp = nd.ni_vp;
  2530. if ((error = VOP_GETATTR(vp, &vattr, p->p_ucred, p)) != 0)
  2531. goto out;
  2532. if (p->p_ucred->cr_uid != vattr.va_uid &&
  2533. (error = suser(p, 0)))
  2534. goto out;
  2535. if (vp->v_usecount > 1 || (vp->v_flag & (VALIASED)))
  2536. VOP_REVOKE(vp, REVOKEALL);
  2537. out:
  2538. vrele(vp);
  2539. return (error);
  2540. }
  2541. /*
  2542. * Convert a user file descriptor to a kernel file entry.
  2543. *
  2544. * On return *fpp is FREF:ed.
  2545. */
  2546. int
  2547. getvnode(struct proc *p, int fd, struct file **fpp)
  2548. {
  2549. struct file *fp;
  2550. struct vnode *vp;
  2551. if ((fp = fd_getfile(p->p_fd, fd)) == NULL)
  2552. return (EBADF);
  2553. if (fp->f_type != DTYPE_VNODE)
  2554. return (EINVAL);
  2555. vp = (struct vnode *)fp->f_data;
  2556. if (vp->v_type == VBAD)
  2557. return (EBADF);
  2558. FREF(fp);
  2559. *fpp = fp;
  2560. return (0);
  2561. }
  2562. /*
  2563. * Positional read system call.
  2564. */
  2565. int
  2566. sys_pread(struct proc *p, void *v, register_t *retval)
  2567. {
  2568. struct sys_pread_args /* {
  2569. syscallarg(int) fd;
  2570. syscallarg(void *) buf;
  2571. syscallarg(size_t) nbyte;
  2572. syscallarg(int) pad;
  2573. syscallarg(off_t) offset;
  2574. } */ *uap = v;
  2575. struct iovec iov;
  2576. struct filedesc *fdp = p->p_fd;
  2577. struct file *fp;
  2578. struct vnode *vp;
  2579. off_t offset;
  2580. int fd = SCARG(uap, fd);
  2581. if ((fp = fd_getfile_mode(fdp, fd, FREAD)) == NULL)
  2582. return (EBADF);
  2583. vp = (struct vnode *)fp->f_data;
  2584. if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO ||
  2585. (vp->v_flag & VISTTY)) {
  2586. return (ESPIPE);
  2587. }
  2588. iov.iov_base = SCARG(uap, buf);
  2589. iov.iov_len = SCARG(uap, nbyte);
  2590. offset = SCARG(uap, offset);
  2591. if (offset < 0 && vp->v_type != VCHR)
  2592. return (EINVAL);
  2593. FREF(fp);
  2594. /* dofilereadv() will FRELE the descriptor for us */
  2595. return (dofilereadv(p, fd, fp, &iov, 1, 0, &offset, retval));
  2596. }
  2597. /*
  2598. * Positional scatter read system call.
  2599. */
  2600. int
  2601. sys_preadv(struct proc *p, void *v, register_t *retval)
  2602. {
  2603. struct sys_preadv_args /* {
  2604. syscallarg(int) fd;
  2605. syscallarg(const struct iovec *) iovp;
  2606. syscallarg(int) iovcnt;
  2607. syscallarg(int) pad;
  2608. syscallarg(off_t) offset;
  2609. } */ *uap = v;
  2610. struct filedesc *fdp = p->p_fd;
  2611. struct file *fp;
  2612. struct vnode *vp;
  2613. off_t offset;
  2614. int fd = SCARG(uap, fd);
  2615. if ((fp = fd_getfile_mode(fdp, fd, FREAD)) == NULL)
  2616. return (EBADF);
  2617. vp = (struct vnode *)fp->f_data;
  2618. if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO ||
  2619. (vp->v_flag & VISTTY)) {
  2620. return (ESPIPE);
  2621. }
  2622. offset = SCARG(uap, offset);
  2623. if (offset < 0 && vp->v_type != VCHR)
  2624. return (EINVAL);
  2625. FREF(fp);
  2626. /* dofilereadv() will FRELE the descriptor for us */
  2627. return (dofilereadv(p, fd, fp, SCARG(uap, iovp), SCARG(uap, iovcnt), 1,
  2628. &offset, retval));
  2629. }
  2630. /*
  2631. * Positional write system call.
  2632. */
  2633. int
  2634. sys_pwrite(struct proc *p, void *v, register_t *retval)
  2635. {
  2636. struct sys_pwrite_args /* {
  2637. syscallarg(int) fd;
  2638. syscallarg(const void *) buf;
  2639. syscallarg(size_t) nbyte;
  2640. syscallarg(int) pad;
  2641. syscallarg(off_t) offset;
  2642. } */ *uap = v;
  2643. struct iovec iov;
  2644. struct filedesc *fdp = p->p_fd;
  2645. struct file *fp;
  2646. struct vnode *vp;
  2647. off_t offset;
  2648. int fd = SCARG(uap, fd);
  2649. if ((fp = fd_getfile_mode(fdp, fd, FWRITE)) == NULL)
  2650. return (EBADF);
  2651. vp = (struct vnode *)fp->f_data;
  2652. if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO ||
  2653. (vp->v_flag & VISTTY)) {
  2654. return (ESPIPE);
  2655. }
  2656. iov.iov_base = (void *)SCARG(uap, buf);
  2657. iov.iov_len = SCARG(uap, nbyte);
  2658. offset = SCARG(uap, offset);
  2659. if (offset < 0 && vp->v_type != VCHR)
  2660. return (EINVAL);
  2661. FREF(fp);
  2662. /* dofilewritev() will FRELE the descriptor for us */
  2663. return (dofilewritev(p, fd, fp, &iov, 1, 0, &offset, retval));
  2664. }
  2665. /*
  2666. * Positional gather write system call.
  2667. */
  2668. int
  2669. sys_pwritev(struct proc *p, void *v, register_t *retval)
  2670. {
  2671. struct sys_pwritev_args /* {
  2672. syscallarg(int) fd;
  2673. syscallarg(const struct iovec *) iovp;
  2674. syscallarg(int) iovcnt;
  2675. syscallarg(int) pad;
  2676. syscallarg(off_t) offset;
  2677. } */ *uap = v;
  2678. struct filedesc *fdp = p->p_fd;
  2679. struct file *fp;
  2680. struct vnode *vp;
  2681. off_t offset;
  2682. int fd = SCARG(uap, fd);
  2683. if ((fp = fd_getfile_mode(fdp, fd, FWRITE)) == NULL)
  2684. return (EBADF);
  2685. vp = (struct vnode *)fp->f_data;
  2686. if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO ||
  2687. (vp->v_flag & VISTTY)) {
  2688. return (ESPIPE);
  2689. }
  2690. offset = SCARG(uap, offset);
  2691. if (offset < 0 && vp->v_type != VCHR)
  2692. return (EINVAL);
  2693. FREF(fp);
  2694. /* dofilewritev() will FRELE the descriptor for us */
  2695. return (dofilewritev(p, fd, fp, SCARG(uap, iovp), SCARG(uap, iovcnt),
  2696. 1, &offset, retval));
  2697. }