]> git.proxmox.com Git - mirror_zfs-debian.git/blame - module/zfs/zpl_inode.c
Fix FIFO and socket handling
[mirror_zfs-debian.git] / module / zfs / zpl_inode.c
CommitLineData
ee154f01
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/vfs.h>
29#include <sys/zpl.h>
30
31
32static struct dentry *
33zpl_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
34{
35 struct inode *ip;
36 cred_t *cr;
37 int error;
38
39 cr = (cred_t *)get_current_cred();
40 error = -zfs_lookup(dir, dname(dentry), &ip, 0, cr, NULL, NULL);
41 ASSERT3S(error, <=, 0);
42 put_cred(cr);
43
44 if (error) {
45 if (error == -ENOENT)
46 return d_splice_alias(NULL, dentry);
47 else
48 return ERR_PTR(error);
49 }
50
51 return d_splice_alias(ip, dentry);
52}
53
54static int
55zpl_create(struct inode *dir, struct dentry *dentry, int mode,
56 struct nameidata *nd)
57{
58 const struct cred *cred;
59 struct inode *ip;
60 vattr_t *vap;
61 int error;
62
63 cred = get_current_cred();
64 vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
65 vap->va_mode = mode;
66 vap->va_mask = ATTR_MODE;
67 vap->va_uid = current_fsuid();
68 vap->va_gid = current_fsgid();
69
70 error = -zfs_create(dir, (char *)dentry->d_name.name,
71 vap, 0, mode, &ip, (struct cred *)cred, 0, NULL);
72 if (error)
73 goto out;
74
75 d_instantiate(dentry, ip);
76out:
77 kmem_free(vap, sizeof(vattr_t));
78 put_cred(cred);
79 ASSERT3S(error, <=, 0);
80
81 return (error);
82}
83
84static int
85zpl_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
86{
87 const struct cred *cred;
88 struct inode *ip;
89 vattr_t *vap;
90 int error;
91
92 cred = get_current_cred();
93 vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
94 vap->va_mode = mode;
95 vap->va_mask = ATTR_MODE;
96 vap->va_rdev = rdev;
97 vap->va_uid = current_fsuid();
98 vap->va_gid = current_fsgid();
99
100 error = -zfs_create(dir, (char *)dentry->d_name.name,
101 vap, 0, mode, &ip, (struct cred *)cred, 0, NULL);
102 if (error)
103 goto out;
104
105 d_instantiate(dentry, ip);
106out:
107 kmem_free(vap, sizeof(vattr_t));
108 put_cred(cred);
109 ASSERT3S(error, <=, 0);
110
111 return (-error);
112}
113
114static int
115zpl_unlink(struct inode *dir, struct dentry *dentry)
116{
117 cred_t *cr;
118 int error;
119
120 cr = (cred_t *)get_current_cred();
121 error = -zfs_remove(dir, dname(dentry), cr);
122 put_cred(cr);
123 ASSERT3S(error, <=, 0);
124
125 return (error);
126}
127
128static int
129zpl_mkdir(struct inode *dir, struct dentry *dentry, int mode)
130{
131 cred_t *cr;
132 vattr_t *vap;
133 struct inode *ip;
134 int error;
135
136 cr = (cred_t *)get_current_cred();
137 vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
138 vap->va_mode = S_IFDIR | mode;
139 vap->va_mask = ATTR_MODE;
140 vap->va_uid = current_fsuid();
141 vap->va_gid = current_fsgid();
142
143 error = -zfs_mkdir(dir, dname(dentry), vap, &ip, cr, 0, NULL);
144 if (error)
145 goto out;
146
147 d_instantiate(dentry, ip);
148out:
149 kmem_free(vap, sizeof(vattr_t));
150 put_cred(cr);
151 ASSERT3S(error, <=, 0);
152
153 return (error);
154}
155
156static int
157zpl_rmdir(struct inode * dir, struct dentry *dentry)
158{
159 cred_t *cr;
160 int error;
161
162 cr = (cred_t *)get_current_cred();
163 error = -zfs_rmdir(dir, dname(dentry), NULL, cr, 0);
164 put_cred(cr);
165 ASSERT3S(error, <=, 0);
166
167 return (error);
168}
169
170static int
171zpl_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
172{
173 cred_t *cr;
174 int error;
175
176 cr = (cred_t *)get_current_cred();
177 error = -zfs_getattr(dentry->d_inode, stat, 0, cr);
178 put_cred(cr);
179 ASSERT3S(error, <=, 0);
180
181 return (error);
182}
183
184static int
185zpl_setattr(struct dentry *dentry, struct iattr *attr)
186{
187 cred_t *cr;
188 int error;
189
190 error = inode_change_ok(dentry->d_inode, attr);
191 if (error)
192 return (error);
193
194 cr = (cred_t *)get_current_cred();
195 error = -zfs_setattr(dentry->d_inode, attr, 0, cr);
196 put_cred(cr);
197 ASSERT3S(error, <=, 0);
198
199 return (-error);
200}
201
202static int
203zpl_rename(struct inode *sdip, struct dentry *sdentry,
204 struct inode *tdip, struct dentry *tdentry)
205{
206 cred_t *cr;
207 int error;
208
209 cr = (cred_t *)get_current_cred();
210 error = -zfs_rename(sdip, dname(sdentry), tdip, dname(tdentry), cr, 0);
211 put_cred(cr);
212 ASSERT3S(error, <=, 0);
213
214 return (error);
215}
216
217static int
218zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name)
219{
220 cred_t *cr;
221 vattr_t *vap;
222 struct inode *ip;
223 int error;
224
225 cr = (cred_t *)get_current_cred();
226 vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
227 vap->va_mode = S_IFLNK | S_IRWXUGO;
228 vap->va_mask = ATTR_MODE;
229 vap->va_uid = current_fsuid();
230 vap->va_gid = current_fsgid();
231
232 error = -zfs_symlink(dir, dname(dentry), vap, (char *)name, &ip, cr, 0);
233 if (error)
234 goto out;
235
236 d_instantiate(dentry, ip);
237out:
238 kmem_free(vap, sizeof(vattr_t));
239 put_cred(cr);
240 ASSERT3S(error, <=, 0);
241
242 return (error);
243}
244
245static void *
246zpl_follow_link(struct dentry *dentry, struct nameidata *nd)
247{
248 (void) zfs_follow_link(dentry, nd);
249 return NULL;
250}
251
252static void
253zpl_put_link(struct dentry *dentry, struct nameidata *nd, void *ptr)
254{
255 char *link;
256
257 link = nd_get_link(nd);
258 if (!IS_ERR(link))
259 kmem_free(link, MAXPATHLEN + 1);
260}
261
262static int
263zpl_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
264{
265 struct inode *ip = old_dentry->d_inode;
266 cred_t *cr;
267 int error;
268
269 if (ip->i_nlink >= ZFS_LINK_MAX)
270 return -EMLINK;
271
272 cr = (cred_t *)get_current_cred();
273 ip->i_ctime = CURRENT_TIME_SEC;
274 igrab(ip); /* Use ihold() if available */
275
276 error = -zfs_link(dir, ip, dname(dentry), cr);
277 if (error) {
278 iput(ip);
279 goto out;
280 }
281
282 d_instantiate(dentry, ip);
283out:
284 put_cred(cr);
285 ASSERT3S(error, <=, 0);
286
287 return (error);
288}
289
290const struct inode_operations zpl_inode_operations = {
291 .check_acl = NULL,
292 .create = zpl_create,
293 .link = zpl_link,
294 .unlink = zpl_unlink,
295 .symlink = zpl_symlink,
296 .mkdir = zpl_mkdir,
297 .rmdir = zpl_rmdir,
298 .mknod = zpl_mknod,
299 .rename = zpl_rename,
300 .setattr = zpl_setattr,
301 .getattr = zpl_getattr,
302 .setxattr = generic_setxattr,
303 .getxattr = generic_getxattr,
304 .removexattr = generic_removexattr,
305 .listxattr = zpl_xattr_list,
306};
307
308const struct inode_operations zpl_dir_inode_operations = {
309 .check_acl = NULL,
310 .create = zpl_create,
311 .lookup = zpl_lookup,
312 .link = zpl_link,
313 .unlink = zpl_unlink,
314 .symlink = zpl_symlink,
315 .mkdir = zpl_mkdir,
316 .rmdir = zpl_rmdir,
317 .mknod = zpl_mknod,
318 .rename = zpl_rename,
319 .setattr = zpl_setattr,
320};
321
322const struct inode_operations zpl_symlink_inode_operations = {
323 .check_acl = NULL,
324 .readlink = generic_readlink,
325 .follow_link = zpl_follow_link,
326 .put_link = zpl_put_link,
327};
328
329const struct inode_operations zpl_special_inode_operations = {
330 .check_acl = NULL,
331};