1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2002 Cluster File Systems, Inc.
5 * Author: Phil Schwan <phil@clusterfs.com>
7 * This file is part of Lustre, http://www.lustre.org.
9 * Lustre is free software; you can redistribute it and/or
10 * modify it under the terms of version 2 of the GNU General Public
11 * License as published by the Free Software Foundation.
13 * Lustre is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with Lustre; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 * Darwin porting library
23 * Make things easy to port
25 #include <mach/mach_types.h>
28 #include <sys/malloc.h>
30 #include <sys/vnode.h>
31 #include <sys/mount.h>
33 #include <sys/filedesc.h>
34 #include <sys/namei.h>
36 #define DEBUG_SUBSYSTEM S_PORTALS
38 #include <libcfs/libcfs.h>
39 #include <libcfs/kp30.h>
42 * Kernel APIs for file system in xnu
47 filp_node_size(struct file *fp, off_t *size)
49 struct vnode *vp = (struct vnode *)fp->f_data;
53 rc = vn_stat(vp, &sb, current_proc());
63 filp_open(const char * filename, int flags, int mode, int *err)
66 register cfs_file_t *fp;
67 register struct vnode *vp;
70 extern struct fileops vnops;
76 MALLOC_ZONE(nfp, cfs_file_t *, sizeof(cfs_file_t), M_FILE, M_WAITOK|M_ZERO);
77 bzero(nfp, sizeof(cfs_file_t));
80 NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, (char *)filename, current_proc());
81 if ((rc = vn_open(&nd, flags, mode)) != 0){
82 printf("filp_open failed at (%d)\n", rc);
90 fp->f_flag = flags & FMASK;
91 fp->f_type = DTYPE_VNODE;
93 fp->f_data = (caddr_t)vp;
94 fp->f_cred = current_proc()->p_ucred;
96 * Hold cred to increase reference
100 * vnode is locked inside vn_open for lookup,
101 * we should release the lock before return
103 VOP_UNLOCK(vp, 0, current_proc());
110 frele_internal(cfs_file_t *fp)
112 if (fp->f_count == (short)0xffff)
113 panic("frele of lustre: stale");
114 if (--fp->f_count < 0)
115 panic("frele of lustre: count < 0");
116 return ((int)fp->f_count);
120 filp_close (cfs_file_t *fp)
129 if (frele_internal(fp) > 0)
131 vp = (struct vnode *)fp->f_data;
132 (void )vn_close(vp, fp->f_flag, fp->f_cred, current_proc());
135 * Dont use ffree to release fp!!!!
136 * ffree will call LIST_REMOVE(fp),
137 * but fp is not in any list, this will
142 if (cred != NOCRED) {
148 memset(fp, 0xff, sizeof *fp);
149 fp->f_count = (short)0xffff;
150 FREE_ZONE(fp, sizeof *fp, M_FILE);
156 extern void bwillwrite(void);
159 * Write buffer to filp inside kernel
162 filp_write (cfs_file_t *fp, void *buf, size_t nbyte, off_t *pos)
166 struct proc *p = current_proc();
170 aiov.iov_base = (void *)(uintptr_t)buf;
171 aiov.iov_len = nbyte;
172 auio.uio_iov = &aiov;
175 auio.uio_offset = *pos;
177 auio.uio_offset = (off_t)-1;
180 auio.uio_resid = nbyte;
181 auio.uio_rw = UIO_WRITE;
182 auio.uio_segflg = UIO_SYSSPACE;
187 if (fp->f_type == DTYPE_VNODE)
188 bwillwrite(); /* empty stuff now */
189 if ((error = fo_write(fp, &auio, fp->f_cred, 0, p))) {
190 if (auio.uio_resid != cnt && (error == ERESTART ||\
191 error == EINTR || error == EWOULDBLOCK))
193 /* The socket layer handles SIGPIPE */
194 if (error == EPIPE && fp->f_type != DTYPE_SOCKET)
201 cnt -= auio.uio_resid;
203 *pos = auio.uio_offset;
208 * Read from filp inside kernel
211 filp_read (cfs_file_t *fp, void *buf, size_t nbyte, off_t *pos)
215 struct proc *p = current_proc();
219 aiov.iov_base = (caddr_t)buf;
220 aiov.iov_len = nbyte;
221 auio.uio_iov = &aiov;
224 auio.uio_offset = *pos;
226 auio.uio_offset = (off_t)-1;
229 auio.uio_resid = nbyte;
230 auio.uio_rw = UIO_READ;
231 auio.uio_segflg = UIO_SYSSPACE;
236 if ((error = fo_read(fp, &auio, fp->f_cred, 0, p)) != 0) {
237 if (auio.uio_resid != cnt && (error == ERESTART ||
238 error == EINTR || error == EWOULDBLOCK))
245 cnt -= auio.uio_resid;
247 *pos = auio.uio_offset;
253 filp_fsync (cfs_file_t *fp)
255 struct vnode *vp = (struct vnode *)fp->f_data;
256 struct proc *p = current_proc();
261 if (fref(fp) == -1) {
265 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
266 error = VOP_FSYNC(vp, fp->f_cred, MNT_WAIT, p);
267 VOP_UNLOCK(vp, 0, p);
275 ref_file(cfs_file_t *fp)
286 rele_file(cfs_file_t *fp)
299 void vrele_safe(struct vnode *nd)
309 path_lookup(const char *path, unsigned int flags, struct nameidata *nd)
315 NDINIT(nd, LOOKUP, FOLLOW, UIO_SYSSPACE, (char *)path, current_proc());
316 if ((ret = namei(nd)) != 0){
317 CERROR("path_lookup fail!\n");
325 file_count(struct file *fp)