2 * Copyright (c) 1995-2002, 2004-2007 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 #include <nnpfs/nnpfs_locl.h>
39 * NNPFS vfs operations.
42 #include <nnpfs/nnpfs_common.h>
43 #include <nnpfs/nnpfs_message.h>
44 #include <nnpfs/nnpfs_fs.h>
45 #include <nnpfs/nnpfs_dev.h>
46 #include <nnpfs/nnpfs_deb.h>
47 #include <nnpfs/nnpfs_vfsops.h>
48 #include <nnpfs/nnpfs_vfsops-bsd.h>
49 #include <nnpfs/nnpfs_vnodeops.h>
53 nnpfs_mount_caddr(struct mount
*mp
,
54 const char *user_path
,
56 struct nameidata
*ndp
,
59 return nnpfs_mount_common(mp
, user_path
, user_data
, ndp
, p
);
63 nnpfs_start(struct mount
* mp
, int flags
, d_thread_t
* p
)
65 NNPFSDEB(XDEBVFOPS
, ("nnpfs_start mp = %lx, flags = %d, proc = %lx\n",
66 (unsigned long)mp
, flags
, (unsigned long)p
));
71 nnpfs_unmount(struct mount
* mp
, int mntflags
, d_thread_t
*p
)
73 NNPFSDEB(XDEBVFOPS
, ("nnpfs_umount: mp = %lx, mntflags = %d, proc = %lx\n",
74 (unsigned long)mp
, mntflags
, (unsigned long)p
));
75 return nnpfs_unmount_common(mp
, mntflags
);
79 nnpfs_root(struct mount
*mp
, struct vnode
**vpp
)
81 NNPFSDEB(XDEBVFOPS
, ("nnpfs_root mp = %lx\n", (unsigned long)mp
));
83 return nnpfs_root_common(mp
, vpp
, nnpfs_curproc());
87 nnpfs_quotactl(struct mount
*mp
, int cmd
, uid_t uid
, caddr_t arg
, d_thread_t
*p
)
89 NNPFSDEB(XDEBVFOPS
, ("nnpfs_quotactl: mp = %lx, cmd = %d, uid = %u, "
90 "arg = %lx, proc = %lx\n",
91 (unsigned long)mp
, cmd
, uid
,
92 (unsigned long)arg
, (unsigned long)p
));
97 nnpfs_statfs(struct mount
*mp
, nnpfs_statvfs
*sbp
, d_thread_t
*p
)
99 NNPFSDEB(XDEBVFOPS
, ("nnpfs_statfs: mp = %lx, sbp = %lx, proc = %lx\n",
103 bcopy(&mp
->mnt_stat
, sbp
, sizeof(*sbp
));
107 #if defined(__DragonFly__) || (defined(__FreeBSD_version) && __FreeBSD_version > 600006)
109 nnpfs_sync(struct mount
*mp
, int waitfor
, d_thread_t
*p
)
111 NNPFSDEB(XDEBVFOPS
, ("nnpfs_sync: mp = %lx, waitfor = %d, "
120 nnpfs_sync(struct mount
*mp
, int waitfor
, nnpfs_kernel_cred cred
, d_thread_t
*p
)
122 NNPFSDEB(XDEBVFOPS
, ("nnpfs_sync: mp = %lx, waitfor = %d, "
123 "cred = %lx, proc = %lx\n",
133 nnpfs_snapshot(struct mount
*mp
, struct vnode
*vp
, struct timespec
*ts
)
135 NNPFSDEB(XDEBVFOPS
, ("nnpfs_snapshot: mp = %lx\n",
141 nnpfs_vget(struct mount
* mp
, ino_t ino
, struct vnode
** vpp
)
143 NNPFSDEB(XDEBVFOPS
, ("nnpfs_vget\n"));
148 common_fhtovp(struct mount
* mp
,
155 /* new style fhtovp */
157 #ifdef HAVE_STRUCT_VFSOPS_VFS_CHECKEXP
159 nnpfs_fhtovp(struct mount
* mp
,
163 return common_fhtovp (mp
, fhp
, vpp
);
166 #else /* !HAVE_STRUCT_VFSOPS_VFS_CHECKEXP */
168 /* old style fhtovp */
171 nnpfs_fhtovp(struct mount
* mp
,
176 struct ucred
** credanonp
)
178 static struct ucred fhtovpcred
;
181 /* XXX: Should see if we is exported to this client */
183 np
= vfs_export_lookup(mp
, &ump
->um_export
, nam
);
187 error
= common_fhtovp(mp
, fhp
, vpp
);
189 fhtovpcred
.cr_uid
= 0;
190 fhtovpcred
.cr_gid
= 0;
191 fhtovpcred
.cr_ngroups
= 0;
194 *exflagsp
= MNT_EXPUBLIC
;
198 *credanonp
= &fhtovpcred
;
202 #endif /* !HAVE_STRUCT_VFSOPS_VFS_CHECKEXP */
205 nnpfs_checkexp (struct mount
*mp
,
206 #if defined(__FreeBSD__) || defined(__DragonFly__)
207 struct sockaddr
*nam
,
212 struct ucred
**credanonp
)
218 NNPFSDEB(XDEBVFOPS
, ("nnpfs_checkexp\n"));
221 np
= vfs_export_lookup(mp
, &ump
->um_export
, nam
);
229 nnpfs_vptofh(struct vnode
* vp
,
231 #if defined(__NetBSD__) && __NetBSD_Version__ >= 399002200 /* 3.99.22 */
236 NNPFSDEB(XDEBVFOPS
, ("nnpfs_vptofh\n"));
240 #endif /* !__APPLE__ */
243 * nnpfs complete dead vnodes implementation.
245 * this is because the dead_vnodeops_p is _not_ filesystem, but rather
246 * a part of the vfs-layer.
251 nnpfs_dead_lookup(struct vnop_lookup_args
* ap
)
254 nnpfs_dead_lookup(struct vop_lookup_args
* ap
)
255 /* struct vop_lookup_args {
256 struct vnodeop_desc *a_desc;
258 struct vnode **a_vpp;
259 struct componentname *a_cnp;
271 #ifdef HAVE_VOP_PUTPAGES
273 nnpfs_dead_putpages (struct vop_putpages_args
*ap
)
275 struct vnode
*vp
= ap
->a_vp
;
277 NNPFSDEB(XDEBVNOPS
, ("nnpfs_dead_putpages %s\n", ap
->a_gen
.a_desc
->vdesc_name
));
279 NNPFSDEB(XDEBVNOPS
, ("nnpfs_dead_putpages %s\n", ap
->a_desc
->vdesc_name
));
281 #ifndef __DragonFly__
282 nnpfs_interlock_unlock(&vp
->v_interlock
)
289 * Given `fsid', `fileid', and `gen', return in `vpp' a locked and
290 * ref'ed vnode from that file system with that id and generation.
291 * All is done in the context of `proc'. Returns 0 if succesful, and
298 nnpfs_fhlookup (d_thread_t
*proc
,
299 struct nnpfs_fhandle_t
*fhp
,
302 /* XXX write code here */
310 nnpfs_fhlookup (d_thread_t
*proc
,
311 struct nnpfs_fhandle_t
*fhp
,
316 #if !(defined(HAVE_GETFH) && defined(HAVE_FHOPEN))
317 struct ucred
*cred
= proc
->p_ucred
;
320 struct nnpfs_fh_args
*fh_args
= (struct nnpfs_fh_args
*)fhp
->fhdata
;
322 NNPFSDEB(XDEBVFOPS
, ("nnpfs_fhlookup (nnpfs)\n"));
324 error
= nnpfs_suser (proc
);
328 if (fhp
->len
< sizeof(struct nnpfs_fh_args
))
331 fsid
= SCARG(fh_args
, fsid
);
333 mp
= nnpfs_vfs_getvfs (&fsid
);
339 uint32_t ino
= SCARG(fh_args
, fileid
);
340 error
= VFS_VGET(mp
, &ino
, vpp
);
343 error
= VFS_VGET(mp
, SCARG(fh_args
, fileid
), vpp
);
352 error
= VOP_GETATTR(*vpp
, &vattr
, cred
, proc
);
358 if (vattr
.va_gen
!= SCARG(fh_args
, gen
)) {
362 #else /* HAVE_GETFH && HAVE_FHOPEN */
364 fhandle_t
*fh
= (fhandle_t
*) fhp
;
366 NNPFSDEB(XDEBVFOPS
, ("nnpfs_fhlookup (native)\n"));
368 mp
= nnpfs_vfs_getvfs (&fh
->fh_fsid
);
372 #ifdef __APPLE__ /* XXX write code here */
376 if ((error
= VFS_FHTOVP(mp
, &fh
->fh_fid
, vpp
)) != 0) {
382 #endif /* HAVE_GETFH && HAVE_FHOPEN */
385 if ((*vpp
)->v_type
== VREG
&& (!UBCINFOEXISTS(*vpp
)))
398 * Perform an open operation on the vnode identified by a `nnpfs_fhandle_t'
399 * (see nnpfs_fhlookup) with flags `user_flags'. Returns 0 or
400 * error. If successful, the file descriptor is returned in `retval'.
404 /* sometimes declared in <sys/file.h> */
405 extern KERNEL_VAR_VNOPS_CONST
struct fileops vnops
;
409 nnpfs_fhopen (d_thread_t
*proc
,
410 struct nnpfs_fhandle_t
*fhp
,
416 nnpfs_kernel_cred cred
= nnpfs_proc_to_cred(proc
);
417 int flags
= FFLAGS(user_flags
);
421 struct nnpfs_fhandle_t fh
;
423 NNPFSDEB(XDEBVFOPS
, ("nnpfs_fhopen: flags = %d\n", user_flags
));
425 error
= copyin (fhp
, &fh
, sizeof(fh
));
429 error
= nnpfs_fhlookup (proc
, &fh
, &vp
);
430 NNPFSDEB(XDEBVFOPS
, ("nnpfs_fhlookup returned %d\n", error
));
438 switch (vp
->v_type
) {
451 if (flags
& FWRITE
) {
452 switch (vp
->v_type
) {
463 error
= vn_writechk (vp
);
473 error
= VOP_ACCESS(vp
, mode
, cred
, proc
);
478 #if defined(__DragonFly__)
479 error
= falloc(proc
->td_proc
, &fp
, &index
);
481 error
= falloc(proc
, &fp
, &index
);
486 #if defined(__FreeBSD__) && __FreeBSD_version >= 502000
487 error
= VOP_OPEN(vp
, flags
, cred
, proc
, index
);
489 error
= VOP_OPEN(vp
, flags
, cred
, proc
);
497 fp
->f_flag
= flags
& FMASK
;
498 fp
->f_type
= DTYPE_VNODE
;
500 fp
->f_data
= (caddr_t
)vp
;
501 nnpfs_vfs_unlock(vp
, proc
);
503 #ifdef FILE_SET_MATURE
507 FILE_UNUSE(fp
, proc
);
510 *fdflags(proc
, index
) &= ~UF_RESERVED
;
513 fdpunlock(proc
->p_fd
);
518 FILE_UNUSE(fp
, proc
);
520 #if defined(__FreeBSD__)
522 #elif defined(OpenBSD)
523 fdremove(proc
->p_fd
, index
);
532 fdpunlock(proc
->p_fd
);
535 NNPFSDEB(XDEBVFOPS
, ("nnpfs_fhopen: error = %d\n", error
));