Set stat->st_dev and statfs->f_fsid
[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         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
54 static int
55 zpl_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);
76 out:
77         kmem_free(vap, sizeof(vattr_t));
78         put_cred(cred);
79         ASSERT3S(error, <=, 0);
80
81         return (error);
82 }
83
84 static int
85 zpl_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);
106 out:
107         kmem_free(vap, sizeof(vattr_t));
108         put_cred(cred);
109         ASSERT3S(error, <=, 0);
110
111         return (-error);
112 }
113
114 static int
115 zpl_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
128 static int
129 zpl_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);
148 out:
149         kmem_free(vap, sizeof(vattr_t));
150         put_cred(cr);
151         ASSERT3S(error, <=, 0);
152
153         return (error);
154 }
155
156 static int
157 zpl_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
170 static int
171 zpl_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
172 {
173         cred_t *cr;
174         vattr_t *vap;
175         struct inode *ip;
176         int error;
177
178         ip = dentry->d_inode;
179         cr = (cred_t *)get_current_cred();
180         vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
181
182         error = -zfs_getattr(ip, vap, 0, cr);
183         if (error)
184                 goto out;
185
186         stat->ino = ip->i_ino;
187         stat->dev = ip->i_sb->s_dev;
188         stat->mode = vap->va_mode;
189         stat->nlink = vap->va_nlink;
190         stat->uid = vap->va_uid;
191         stat->gid = vap->va_gid;
192         stat->rdev = vap->va_rdev;
193         stat->size = vap->va_size;
194         stat->atime = vap->va_atime;
195         stat->mtime = vap->va_mtime;
196         stat->ctime = vap->va_ctime;
197         stat->blksize = vap->va_blksize;
198         stat->blocks = vap->va_nblocks;
199 out:
200         kmem_free(vap, sizeof(vattr_t));
201         put_cred(cr);
202         ASSERT3S(error, <=, 0);
203
204         return (error);
205 }
206
207 static int
208 zpl_setattr(struct dentry *dentry, struct iattr *ia)
209 {
210         cred_t *cr;
211         vattr_t *vap;
212         int error;
213
214         error = inode_change_ok(dentry->d_inode, ia);
215         if (error)
216                 return (error);
217
218         cr = (cred_t *)get_current_cred();
219         vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
220         vap->va_mask = ia->ia_valid & ATTR_IATTR_MASK;
221         vap->va_mode = ia->ia_mode;
222         vap->va_uid = ia->ia_uid;
223         vap->va_gid = ia->ia_gid;
224         vap->va_size = ia->ia_size;
225         vap->va_atime = ia->ia_atime;
226         vap->va_mtime = ia->ia_mtime;
227         vap->va_ctime = ia->ia_ctime;
228
229         error = -zfs_setattr(dentry->d_inode, vap, 0, cr);
230
231         kmem_free(vap, sizeof(vattr_t));
232         put_cred(cr);
233         ASSERT3S(error, <=, 0);
234
235         return (error);
236 }
237
238 static int
239 zpl_rename(struct inode *sdip, struct dentry *sdentry,
240     struct inode *tdip, struct dentry *tdentry)
241 {
242         cred_t *cr;
243         int error;
244
245         cr = (cred_t *)get_current_cred();
246         error = -zfs_rename(sdip, dname(sdentry), tdip, dname(tdentry), cr, 0);
247         put_cred(cr);
248         ASSERT3S(error, <=, 0);
249
250         return (error);
251 }
252
253 static int
254 zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name)
255 {
256         cred_t *cr;
257         vattr_t *vap;
258         struct inode *ip;
259         int error;
260
261         cr = (cred_t *)get_current_cred();
262         vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
263         vap->va_mode = S_IFLNK | S_IRWXUGO;
264         vap->va_mask = ATTR_MODE;
265         vap->va_uid = current_fsuid();
266         vap->va_gid = current_fsgid();
267
268         error = -zfs_symlink(dir, dname(dentry), vap, (char *)name, &ip, cr, 0);
269         if (error)
270                 goto out;
271
272         d_instantiate(dentry, ip);
273 out:
274         kmem_free(vap, sizeof(vattr_t));
275         put_cred(cr);
276         ASSERT3S(error, <=, 0);
277
278         return (error);
279 }
280
281 static void *
282 zpl_follow_link(struct dentry *dentry, struct nameidata *nd)
283 {
284         struct inode *ip = dentry->d_inode;
285         struct iovec iov;
286         uio_t uio;
287         char *link;
288         cred_t *cr;
289         int error;
290
291         cr = (cred_t *)get_current_cred();
292
293         iov.iov_len = MAXPATHLEN;
294         iov.iov_base = link = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
295
296         uio.uio_iov = &iov;
297         uio.uio_iovcnt = 1;
298         uio.uio_resid = (MAXPATHLEN - 1);
299         uio.uio_segflg = UIO_SYSSPACE;
300
301         error = -zfs_readlink(ip, &uio, cr);
302         if (error) {
303                 kmem_free(link, MAXPATHLEN);
304                 nd_set_link(nd, ERR_PTR(error));
305         } else {
306                 nd_set_link(nd, link);
307         }
308
309         put_cred(cr);
310         return (NULL);
311 }
312
313 static void
314 zpl_put_link(struct dentry *dentry, struct nameidata *nd, void *ptr)
315 {
316         char *link;
317
318         link = nd_get_link(nd);
319         if (!IS_ERR(link))
320                 kmem_free(link, MAXPATHLEN);
321 }
322
323 static int
324 zpl_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
325 {
326         struct inode *ip = old_dentry->d_inode;
327         cred_t *cr;
328         int error;
329
330         if (ip->i_nlink >= ZFS_LINK_MAX)
331                 return -EMLINK;
332
333         cr = (cred_t *)get_current_cred();
334         ip->i_ctime = CURRENT_TIME_SEC;
335         igrab(ip); /* Use ihold() if available */
336
337         error = -zfs_link(dir, ip, dname(dentry), cr);
338         if (error) {
339                 iput(ip);
340                 goto out;
341         }
342
343         d_instantiate(dentry, ip);
344 out:
345         put_cred(cr);
346         ASSERT3S(error, <=, 0);
347
348         return (error);
349 }
350
351 const struct inode_operations zpl_inode_operations = {
352         .create         = zpl_create,
353         .link           = zpl_link,
354         .unlink         = zpl_unlink,
355         .symlink        = zpl_symlink,
356         .mkdir          = zpl_mkdir,
357         .rmdir          = zpl_rmdir,
358         .mknod          = zpl_mknod,
359         .rename         = zpl_rename,
360         .setattr        = zpl_setattr,
361         .getattr        = zpl_getattr,
362         .setxattr       = generic_setxattr,
363         .getxattr       = generic_getxattr,
364         .removexattr    = generic_removexattr,
365         .listxattr      = zpl_xattr_list,
366 };
367
368 const struct inode_operations zpl_dir_inode_operations = {
369         .create         = zpl_create,
370         .lookup         = zpl_lookup,
371         .link           = zpl_link,
372         .unlink         = zpl_unlink,
373         .symlink        = zpl_symlink,
374         .mkdir          = zpl_mkdir,
375         .rmdir          = zpl_rmdir,
376         .mknod          = zpl_mknod,
377         .rename         = zpl_rename,
378         .setattr        = zpl_setattr,
379         .getattr        = zpl_getattr,
380         .setxattr       = generic_setxattr,
381         .getxattr       = generic_getxattr,
382         .removexattr    = generic_removexattr,
383         .listxattr      = zpl_xattr_list,
384 };
385
386 const struct inode_operations zpl_symlink_inode_operations = {
387         .readlink       = generic_readlink,
388         .follow_link    = zpl_follow_link,
389         .put_link       = zpl_put_link,
390 };
391
392 const struct inode_operations zpl_special_inode_operations = {
393         .setattr        = zpl_setattr,
394         .getattr        = zpl_getattr,
395         .setxattr       = generic_setxattr,
396         .getxattr       = generic_getxattr,
397         .removexattr    = generic_removexattr,
398         .listxattr      = zpl_xattr_list,
399 };