029a4038b10b411611cc1827e409f19b081de15a
[zfs.git] / module / zfs / zpl_inode.c
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
32 static struct dentry *
33 zpl_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
34 {
35         cred_t *cr = CRED();
36         struct inode *ip;
37         int error;
38
39         crhold(cr);
40         error = -zfs_lookup(dir, dname(dentry), &ip, 0, cr, NULL, NULL);
41         ASSERT3S(error, <=, 0);
42         crfree(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
54 static int
55 zpl_create(struct inode *dir, struct dentry *dentry, int mode,
56     struct nameidata *nd)
57 {
58         cred_t *cr = CRED();
59         struct inode *ip;
60         vattr_t *vap;
61         int error;
62
63         crhold(cr);
64         vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
65         vap->va_mode = mode;
66         vap->va_mask = ATTR_MODE;
67         vap->va_uid = crgetfsuid(cr);
68         vap->va_gid = crgetfsgid(cr);
69         vap->va_dentry = dentry;
70
71         error = -zfs_create(dir, (char *)dentry->d_name.name,
72             vap, 0, mode, &ip, cr, 0, NULL);
73         kmem_free(vap, sizeof(vattr_t));
74         crfree(cr);
75         ASSERT3S(error, <=, 0);
76
77         return (error);
78 }
79
80 static int
81 zpl_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
82 {
83         cred_t *cr = CRED();
84         struct inode *ip;
85         vattr_t *vap;
86         int error;
87
88         crhold(cr);
89         vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
90         vap->va_mode = mode;
91         vap->va_mask = ATTR_MODE;
92         vap->va_rdev = rdev;
93         vap->va_uid = crgetfsuid(cr);
94         vap->va_gid = crgetfsgid(cr);
95         vap->va_dentry = dentry;
96
97         error = -zfs_create(dir, (char *)dentry->d_name.name,
98             vap, 0, mode, &ip, cr, 0, NULL);
99         kmem_free(vap, sizeof(vattr_t));
100         crfree(cr);
101         ASSERT3S(error, <=, 0);
102
103         return (-error);
104 }
105
106 static int
107 zpl_unlink(struct inode *dir, struct dentry *dentry)
108 {
109         cred_t *cr = CRED();
110         int error;
111
112         crhold(cr);
113         error = -zfs_remove(dir, dname(dentry), cr);
114         crfree(cr);
115         ASSERT3S(error, <=, 0);
116
117         return (error);
118 }
119
120 static int
121 zpl_mkdir(struct inode *dir, struct dentry *dentry, int mode)
122 {
123         cred_t *cr = CRED();
124         vattr_t *vap;
125         struct inode *ip;
126         int error;
127
128         crhold(cr);
129         vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
130         vap->va_mode = S_IFDIR | mode;
131         vap->va_mask = ATTR_MODE;
132         vap->va_uid = crgetfsuid(cr);
133         vap->va_gid = crgetfsgid(cr);
134         vap->va_dentry = dentry;
135
136         error = -zfs_mkdir(dir, dname(dentry), vap, &ip, cr, 0, NULL);
137         kmem_free(vap, sizeof(vattr_t));
138         crfree(cr);
139         ASSERT3S(error, <=, 0);
140
141         return (error);
142 }
143
144 static int
145 zpl_rmdir(struct inode * dir, struct dentry *dentry)
146 {
147         cred_t *cr = CRED();
148         int error;
149
150         crhold(cr);
151         error = -zfs_rmdir(dir, dname(dentry), NULL, cr, 0);
152         crfree(cr);
153         ASSERT3S(error, <=, 0);
154
155         return (error);
156 }
157
158 static int
159 zpl_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
160 {
161         cred_t *cr = CRED();
162         vattr_t *vap;
163         struct inode *ip;
164         int error;
165
166         ip = dentry->d_inode;
167         crhold(cr);
168         vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
169
170         error = -zfs_getattr(ip, vap, 0, cr);
171         if (error)
172                 goto out;
173
174         stat->ino = ip->i_ino;
175         stat->dev = ip->i_sb->s_dev;
176         stat->mode = vap->va_mode;
177         stat->nlink = vap->va_nlink;
178         stat->uid = vap->va_uid;
179         stat->gid = vap->va_gid;
180         stat->rdev = vap->va_rdev;
181         stat->size = vap->va_size;
182         stat->atime = vap->va_atime;
183         stat->mtime = vap->va_mtime;
184         stat->ctime = vap->va_ctime;
185         stat->blksize = vap->va_blksize;
186         stat->blocks = vap->va_nblocks;
187 out:
188         kmem_free(vap, sizeof(vattr_t));
189         crfree(cr);
190         ASSERT3S(error, <=, 0);
191
192         return (error);
193 }
194
195 static int
196 zpl_setattr(struct dentry *dentry, struct iattr *ia)
197 {
198         cred_t *cr = CRED();
199         vattr_t *vap;
200         int error;
201
202         error = inode_change_ok(dentry->d_inode, ia);
203         if (error)
204                 return (error);
205
206         crhold(cr);
207         vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
208         vap->va_mask = ia->ia_valid & ATTR_IATTR_MASK;
209         vap->va_mode = ia->ia_mode;
210         vap->va_uid = ia->ia_uid;
211         vap->va_gid = ia->ia_gid;
212         vap->va_size = ia->ia_size;
213         vap->va_atime = ia->ia_atime;
214         vap->va_mtime = ia->ia_mtime;
215         vap->va_ctime = ia->ia_ctime;
216
217         error = -zfs_setattr(dentry->d_inode, vap, 0, cr);
218
219         kmem_free(vap, sizeof(vattr_t));
220         crfree(cr);
221         ASSERT3S(error, <=, 0);
222
223         return (error);
224 }
225
226 static int
227 zpl_rename(struct inode *sdip, struct dentry *sdentry,
228     struct inode *tdip, struct dentry *tdentry)
229 {
230         cred_t *cr = CRED();
231         int error;
232
233         crhold(cr);
234         error = -zfs_rename(sdip, dname(sdentry), tdip, dname(tdentry), cr, 0);
235         crfree(cr);
236         ASSERT3S(error, <=, 0);
237
238         return (error);
239 }
240
241 static int
242 zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name)
243 {
244         cred_t *cr = CRED();
245         vattr_t *vap;
246         struct inode *ip;
247         int error;
248
249         crhold(cr);
250         vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
251         vap->va_mode = S_IFLNK | S_IRWXUGO;
252         vap->va_mask = ATTR_MODE;
253         vap->va_uid = crgetfsuid(cr);
254         vap->va_gid = crgetfsgid(cr);
255         vap->va_dentry = dentry;
256
257         error = -zfs_symlink(dir, dname(dentry), vap, (char *)name, &ip, cr, 0);
258         kmem_free(vap, sizeof(vattr_t));
259         crfree(cr);
260         ASSERT3S(error, <=, 0);
261
262         return (error);
263 }
264
265 static void *
266 zpl_follow_link(struct dentry *dentry, struct nameidata *nd)
267 {
268         cred_t *cr = CRED();
269         struct inode *ip = dentry->d_inode;
270         struct iovec iov;
271         uio_t uio;
272         char *link;
273         int error;
274
275         crhold(cr);
276
277         iov.iov_len = MAXPATHLEN;
278         iov.iov_base = link = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
279
280         uio.uio_iov = &iov;
281         uio.uio_iovcnt = 1;
282         uio.uio_resid = (MAXPATHLEN - 1);
283         uio.uio_segflg = UIO_SYSSPACE;
284
285         error = -zfs_readlink(ip, &uio, cr);
286         if (error) {
287                 kmem_free(link, MAXPATHLEN);
288                 nd_set_link(nd, ERR_PTR(error));
289         } else {
290                 nd_set_link(nd, link);
291         }
292
293         crfree(cr);
294         return (NULL);
295 }
296
297 static void
298 zpl_put_link(struct dentry *dentry, struct nameidata *nd, void *ptr)
299 {
300         char *link;
301
302         link = nd_get_link(nd);
303         if (!IS_ERR(link))
304                 kmem_free(link, MAXPATHLEN);
305 }
306
307 static int
308 zpl_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
309 {
310         cred_t *cr = CRED();
311         struct inode *ip = old_dentry->d_inode;
312         int error;
313
314         if (ip->i_nlink >= ZFS_LINK_MAX)
315                 return -EMLINK;
316
317         crhold(cr);
318         ip->i_ctime = CURRENT_TIME_SEC;
319         igrab(ip); /* Use ihold() if available */
320
321         error = -zfs_link(dir, ip, dname(dentry), cr);
322         if (error) {
323                 iput(ip);
324                 goto out;
325         }
326
327         d_instantiate(dentry, ip);
328 out:
329         crfree(cr);
330         ASSERT3S(error, <=, 0);
331
332         return (error);
333 }
334
335 const struct inode_operations zpl_inode_operations = {
336         .create         = zpl_create,
337         .link           = zpl_link,
338         .unlink         = zpl_unlink,
339         .symlink        = zpl_symlink,
340         .mkdir          = zpl_mkdir,
341         .rmdir          = zpl_rmdir,
342         .mknod          = zpl_mknod,
343         .rename         = zpl_rename,
344         .setattr        = zpl_setattr,
345         .getattr        = zpl_getattr,
346         .setxattr       = generic_setxattr,
347         .getxattr       = generic_getxattr,
348         .removexattr    = generic_removexattr,
349         .listxattr      = zpl_xattr_list,
350 };
351
352 const struct inode_operations zpl_dir_inode_operations = {
353         .create         = zpl_create,
354         .lookup         = zpl_lookup,
355         .link           = zpl_link,
356         .unlink         = zpl_unlink,
357         .symlink        = zpl_symlink,
358         .mkdir          = zpl_mkdir,
359         .rmdir          = zpl_rmdir,
360         .mknod          = zpl_mknod,
361         .rename         = zpl_rename,
362         .setattr        = zpl_setattr,
363         .getattr        = zpl_getattr,
364         .setxattr       = generic_setxattr,
365         .getxattr       = generic_getxattr,
366         .removexattr    = generic_removexattr,
367         .listxattr      = zpl_xattr_list,
368 };
369
370 const struct inode_operations zpl_symlink_inode_operations = {
371         .readlink       = generic_readlink,
372         .follow_link    = zpl_follow_link,
373         .put_link       = zpl_put_link,
374 };
375
376 const struct inode_operations zpl_special_inode_operations = {
377         .setattr        = zpl_setattr,
378         .getattr        = zpl_getattr,
379         .setxattr       = generic_setxattr,
380         .getxattr       = generic_getxattr,
381         .removexattr    = generic_removexattr,
382         .listxattr      = zpl_xattr_list,
383 };