]>
Commit | Line | Data |
---|---|---|
1efb473f BB |
1 | /* |
2 | * CDDL HEADER START | |
3 | * | |
4 | * The contents of this file are subject to the terms of the | |
5 | * Common Development and Distribution License (the "License"). | |
6 | * You may not use this file except in compliance with the License. | |
7 | * | |
8 | * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | |
9 | * or http://www.opensolaris.org/os/licensing. | |
10 | * See the License for the specific language governing permissions | |
11 | * and limitations under the License. | |
12 | * | |
13 | * When distributing Covered Code, include this CDDL HEADER in each | |
14 | * file and include the License file at usr/src/OPENSOLARIS.LICENSE. | |
15 | * If applicable, add the following below this CDDL HEADER, with the | |
16 | * fields enclosed by brackets "[]" replaced with your own identifying | |
17 | * information: Portions Copyright [yyyy] [name of copyright owner] | |
18 | * | |
19 | * CDDL HEADER END | |
20 | */ | |
21 | /* | |
22 | * Copyright (c) 2011, Lawrence Livermore National Security, LLC. | |
23 | */ | |
24 | ||
25 | ||
26 | #include <sys/zfs_vfsops.h> | |
27 | #include <sys/zfs_vnops.h> | |
28 | #include <sys/zfs_znode.h> | |
29 | #include <sys/zpl.h> | |
30 | ||
31 | ||
32 | static int | |
33 | zpl_readdir(struct file *filp, void *dirent, filldir_t filldir) | |
34 | { | |
35 | struct dentry *dentry = filp->f_path.dentry; | |
36 | cred_t *cr; | |
37 | int error; | |
38 | ||
39 | cr = (cred_t *)get_current_cred(); | |
40 | error = -zfs_readdir(dentry->d_inode, dirent, filldir, | |
41 | &filp->f_pos, cr); | |
42 | put_cred(cr); | |
43 | ASSERT3S(error, <=, 0); | |
44 | ||
45 | return (error); | |
46 | } | |
47 | ||
48 | static int | |
49 | zpl_fsync(struct file *filp, struct dentry *dentry, int datasync) | |
50 | { | |
51 | cred_t *cr; | |
52 | int error; | |
53 | ||
54 | cr = (cred_t *)get_current_cred(); | |
55 | error = -zfs_fsync(filp->f_path.dentry->d_inode, datasync, cr); | |
56 | put_cred(cr); | |
57 | ASSERT3S(error, <=, 0); | |
58 | ||
59 | return (error); | |
60 | } | |
61 | ||
62 | ssize_t | |
63 | zpl_read_common(struct inode *ip, const char *buf, size_t len, loff_t pos, | |
64 | uio_seg_t segment, int flags, cred_t *cr) | |
65 | { | |
66 | int error; | |
67 | struct iovec iov; | |
68 | uio_t uio; | |
69 | ||
70 | iov.iov_base = (void *)buf; | |
71 | iov.iov_len = len; | |
72 | ||
73 | uio.uio_iov = &iov; | |
74 | uio.uio_resid = len; | |
75 | uio.uio_iovcnt = 1; | |
76 | uio.uio_loffset = pos; | |
77 | uio.uio_limit = MAXOFFSET_T; | |
78 | uio.uio_segflg = segment; | |
79 | ||
80 | error = -zfs_read(ip, &uio, flags, cr); | |
81 | if (error < 0) | |
82 | return (error); | |
83 | ||
84 | return (len - uio.uio_resid); | |
85 | } | |
86 | ||
87 | static ssize_t | |
88 | zpl_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos) | |
89 | { | |
90 | cred_t *cr; | |
91 | ssize_t read; | |
92 | ||
93 | cr = (cred_t *)get_current_cred(); | |
94 | read = zpl_read_common(filp->f_mapping->host, buf, len, *ppos, | |
95 | UIO_USERSPACE, filp->f_flags, cr); | |
96 | put_cred(cr); | |
97 | ||
98 | if (read < 0) | |
99 | return (read); | |
100 | ||
101 | *ppos += read; | |
102 | return (read); | |
103 | } | |
104 | ||
105 | ssize_t | |
106 | zpl_write_common(struct inode *ip, const char *buf, size_t len, loff_t pos, | |
107 | uio_seg_t segment, int flags, cred_t *cr) | |
108 | { | |
109 | int error; | |
110 | struct iovec iov; | |
111 | uio_t uio; | |
112 | ||
113 | iov.iov_base = (void *)buf; | |
114 | iov.iov_len = len; | |
115 | ||
116 | uio.uio_iov = &iov; | |
117 | uio.uio_resid = len, | |
118 | uio.uio_iovcnt = 1; | |
119 | uio.uio_loffset = pos; | |
120 | uio.uio_limit = MAXOFFSET_T; | |
121 | uio.uio_segflg = segment; | |
122 | ||
123 | error = -zfs_write(ip, &uio, flags, cr); | |
124 | if (error < 0) | |
125 | return (error); | |
126 | ||
127 | return (len - uio.uio_resid); | |
128 | } | |
129 | ||
130 | static ssize_t | |
131 | zpl_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) | |
132 | { | |
133 | cred_t *cr; | |
134 | ssize_t wrote; | |
135 | ||
136 | cr = (cred_t *)get_current_cred(); | |
137 | wrote = zpl_write_common(filp->f_mapping->host, buf, len, *ppos, | |
138 | UIO_USERSPACE, filp->f_flags, cr); | |
139 | put_cred(cr); | |
140 | ||
141 | if (wrote < 0) | |
142 | return (wrote); | |
143 | ||
144 | *ppos += wrote; | |
145 | return (wrote); | |
146 | } | |
147 | ||
148 | const struct address_space_operations zpl_address_space_operations = { | |
149 | #if 0 | |
150 | .readpage = zpl_readpage, | |
151 | .writepage = zpl_writepage, | |
152 | .direct_IO = zpl_direct_IO, | |
153 | #endif | |
154 | }; | |
155 | ||
156 | const struct file_operations zpl_file_operations = { | |
157 | .open = generic_file_open, | |
158 | .llseek = generic_file_llseek, | |
159 | .read = zpl_read, /* do_sync_read */ | |
160 | .write = zpl_write, /* do_sync_write */ | |
161 | .readdir = zpl_readdir, | |
162 | .mmap = generic_file_mmap, | |
163 | .fsync = zpl_fsync, | |
164 | .aio_read = NULL, /* generic_file_aio_read */ | |
165 | .aio_write = NULL, /* generic_file_aio_write */ | |
166 | }; | |
167 | ||
168 | const struct file_operations zpl_dir_file_operations = { | |
169 | .llseek = generic_file_llseek, | |
170 | .read = generic_read_dir, | |
171 | .readdir = zpl_readdir, | |
172 | .fsync = zpl_fsync, | |
173 | }; |