Linux 3.6 compat, iops->lookup()
[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/zfs_znode.h>
29 #include <sys/vfs.h>
30 #include <sys/zpl.h>
31
32
33 static struct dentry *
34 #ifdef HAVE_LOOKUP_NAMEIDATA
35 zpl_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
36 #else
37 zpl_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
38 #endif
39 {
40         cred_t *cr = CRED();
41         struct inode *ip;
42         int error;
43
44         crhold(cr);
45         error = -zfs_lookup(dir, dname(dentry), &ip, 0, cr, NULL, NULL);
46         ASSERT3S(error, <=, 0);
47         crfree(cr);
48
49         if (error) {
50                 if (error == -ENOENT)
51                         return d_splice_alias(NULL, dentry);
52                 else
53                         return ERR_PTR(error);
54         }
55
56         return d_splice_alias(ip, dentry);
57 }
58
59 void
60 zpl_vap_init(vattr_t *vap, struct inode *dir, struct dentry *dentry,
61     zpl_umode_t mode, cred_t *cr)
62 {
63         vap->va_mask = ATTR_MODE;
64         vap->va_mode = mode;
65         vap->va_dentry = dentry;
66         vap->va_uid = crgetfsuid(cr);
67
68         if (dir && dir->i_mode & S_ISGID) {
69                 vap->va_gid = dir->i_gid;
70                 if (S_ISDIR(mode))
71                         vap->va_mode |= S_ISGID;
72         } else {
73                 vap->va_gid = crgetfsgid(cr);
74         }
75 }
76
77 static int
78 zpl_create(struct inode *dir, struct dentry *dentry, zpl_umode_t mode,
79     struct nameidata *nd)
80 {
81         cred_t *cr = CRED();
82         struct inode *ip;
83         vattr_t *vap;
84         int error;
85
86         crhold(cr);
87         vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
88         zpl_vap_init(vap, dir, dentry, mode, cr);
89
90         error = -zfs_create(dir, (char *)dentry->d_name.name,
91             vap, 0, mode, &ip, cr, 0, NULL);
92         kmem_free(vap, sizeof(vattr_t));
93         crfree(cr);
94         ASSERT3S(error, <=, 0);
95
96         return (error);
97 }
98
99 static int
100 zpl_mknod(struct inode *dir, struct dentry *dentry, zpl_umode_t mode,
101     dev_t rdev)
102 {
103         cred_t *cr = CRED();
104         struct inode *ip;
105         vattr_t *vap;
106         int error;
107
108         /*
109          * We currently expect Linux to supply rdev=0 for all sockets
110          * and fifos, but we want to know if this behavior ever changes.
111          */
112         if (S_ISSOCK(mode) || S_ISFIFO(mode))
113                 ASSERT(rdev == 0);
114
115         crhold(cr);
116         vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
117         zpl_vap_init(vap, dir, dentry, mode, cr);
118         vap->va_rdev = rdev;
119
120         error = -zfs_create(dir, (char *)dentry->d_name.name,
121             vap, 0, mode, &ip, cr, 0, NULL);
122         kmem_free(vap, sizeof(vattr_t));
123         crfree(cr);
124         ASSERT3S(error, <=, 0);
125
126         return (-error);
127 }
128
129 static int
130 zpl_unlink(struct inode *dir, struct dentry *dentry)
131 {
132         cred_t *cr = CRED();
133         int error;
134
135         crhold(cr);
136         error = -zfs_remove(dir, dname(dentry), cr);
137         crfree(cr);
138         ASSERT3S(error, <=, 0);
139
140         return (error);
141 }
142
143 static int
144 zpl_mkdir(struct inode *dir, struct dentry *dentry, zpl_umode_t mode)
145 {
146         cred_t *cr = CRED();
147         vattr_t *vap;
148         struct inode *ip;
149         int error;
150
151         crhold(cr);
152         vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
153         zpl_vap_init(vap, dir, dentry, mode | S_IFDIR, cr);
154
155         error = -zfs_mkdir(dir, dname(dentry), vap, &ip, cr, 0, NULL);
156         kmem_free(vap, sizeof(vattr_t));
157         crfree(cr);
158         ASSERT3S(error, <=, 0);
159
160         return (error);
161 }
162
163 static int
164 zpl_rmdir(struct inode * dir, struct dentry *dentry)
165 {
166         cred_t *cr = CRED();
167         int error;
168
169         crhold(cr);
170         error = -zfs_rmdir(dir, dname(dentry), NULL, cr, 0);
171         crfree(cr);
172         ASSERT3S(error, <=, 0);
173
174         return (error);
175 }
176
177 static int
178 zpl_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
179 {
180         boolean_t issnap = ITOZSB(dentry->d_inode)->z_issnap;
181         int error;
182
183         /*
184          * Ensure MNT_SHRINKABLE is set on snapshots to ensure they are
185          * unmounted automatically with the parent file system.  This
186          * is done on the first getattr because it's not easy to get the
187          * vfsmount structure at mount time.  This call path is explicitly
188          * marked unlikely to avoid any performance impact.  FWIW, ext4
189          * resorts to a similar trick for sysadmin convenience.
190          */
191         if (unlikely(issnap && !(mnt->mnt_flags & MNT_SHRINKABLE)))
192                 mnt->mnt_flags |= MNT_SHRINKABLE;
193
194         error = -zfs_getattr_fast(dentry->d_inode, stat);
195         ASSERT3S(error, <=, 0);
196
197         return (error);
198 }
199
200 static int
201 zpl_setattr(struct dentry *dentry, struct iattr *ia)
202 {
203         cred_t *cr = CRED();
204         vattr_t *vap;
205         int error;
206
207         error = inode_change_ok(dentry->d_inode, ia);
208         if (error)
209                 return (error);
210
211         crhold(cr);
212         vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
213         vap->va_mask = ia->ia_valid & ATTR_IATTR_MASK;
214         vap->va_mode = ia->ia_mode;
215         vap->va_uid = ia->ia_uid;
216         vap->va_gid = ia->ia_gid;
217         vap->va_size = ia->ia_size;
218         vap->va_atime = ia->ia_atime;
219         vap->va_mtime = ia->ia_mtime;
220         vap->va_ctime = ia->ia_ctime;
221
222         error = -zfs_setattr(dentry->d_inode, vap, 0, cr);
223
224         kmem_free(vap, sizeof(vattr_t));
225         crfree(cr);
226         ASSERT3S(error, <=, 0);
227
228         return (error);
229 }
230
231 static int
232 zpl_rename(struct inode *sdip, struct dentry *sdentry,
233     struct inode *tdip, struct dentry *tdentry)
234 {
235         cred_t *cr = CRED();
236         int error;
237
238         crhold(cr);
239         error = -zfs_rename(sdip, dname(sdentry), tdip, dname(tdentry), cr, 0);
240         crfree(cr);
241         ASSERT3S(error, <=, 0);
242
243         return (error);
244 }
245
246 static int
247 zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name)
248 {
249         cred_t *cr = CRED();
250         vattr_t *vap;
251         struct inode *ip;
252         int error;
253
254         crhold(cr);
255         vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
256         zpl_vap_init(vap, dir, dentry, S_IFLNK | S_IRWXUGO, cr);
257
258         error = -zfs_symlink(dir, dname(dentry), vap, (char *)name, &ip, cr, 0);
259         kmem_free(vap, sizeof(vattr_t));
260         crfree(cr);
261         ASSERT3S(error, <=, 0);
262
263         return (error);
264 }
265
266 static void *
267 zpl_follow_link(struct dentry *dentry, struct nameidata *nd)
268 {
269         cred_t *cr = CRED();
270         struct inode *ip = dentry->d_inode;
271         struct iovec iov;
272         uio_t uio;
273         char *link;
274         int error;
275
276         crhold(cr);
277
278         iov.iov_len = MAXPATHLEN;
279         iov.iov_base = link = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
280
281         uio.uio_iov = &iov;
282         uio.uio_iovcnt = 1;
283         uio.uio_resid = (MAXPATHLEN - 1);
284         uio.uio_segflg = UIO_SYSSPACE;
285
286         error = -zfs_readlink(ip, &uio, cr);
287         if (error) {
288                 kmem_free(link, MAXPATHLEN);
289                 nd_set_link(nd, ERR_PTR(error));
290         } else {
291                 nd_set_link(nd, link);
292         }
293
294         crfree(cr);
295         return (NULL);
296 }
297
298 static void
299 zpl_put_link(struct dentry *dentry, struct nameidata *nd, void *ptr)
300 {
301         const char *link = nd_get_link(nd);
302
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 #ifdef HAVE_INODE_TRUNCATE_RANGE
336 static void
337 zpl_truncate_range(struct inode* ip, loff_t start, loff_t end)
338 {
339         cred_t *cr = CRED();
340         flock64_t bf;
341
342         ASSERT3S(start, <=, end);
343
344         /*
345          * zfs_freesp() will interpret (len == 0) as meaning "truncate until
346          * the end of the file". We don't want that.
347          */
348         if (start == end)
349                 return;
350
351         crhold(cr);
352
353         bf.l_type = F_WRLCK;
354         bf.l_whence = 0;
355         bf.l_start = start;
356         bf.l_len = end - start;
357         bf.l_pid = 0;
358         zfs_space(ip, F_FREESP, &bf, FWRITE, start, cr);
359
360         crfree(cr);
361 }
362 #endif /* HAVE_INODE_TRUNCATE_RANGE */
363
364 #ifdef HAVE_INODE_FALLOCATE
365 static long
366 zpl_fallocate(struct inode *ip, int mode, loff_t offset, loff_t len)
367 {
368         return zpl_fallocate_common(ip, mode, offset, len);
369 }
370 #endif /* HAVE_INODE_FALLOCATE */
371
372
373 const struct inode_operations zpl_inode_operations = {
374         .create         = zpl_create,
375         .link           = zpl_link,
376         .unlink         = zpl_unlink,
377         .symlink        = zpl_symlink,
378         .mkdir          = zpl_mkdir,
379         .rmdir          = zpl_rmdir,
380         .mknod          = zpl_mknod,
381         .rename         = zpl_rename,
382         .setattr        = zpl_setattr,
383         .getattr        = zpl_getattr,
384         .setxattr       = generic_setxattr,
385         .getxattr       = generic_getxattr,
386         .removexattr    = generic_removexattr,
387         .listxattr      = zpl_xattr_list,
388 #ifdef HAVE_INODE_TRUNCATE_RANGE
389         .truncate_range = zpl_truncate_range,
390 #endif /* HAVE_INODE_TRUNCATE_RANGE */
391 #ifdef HAVE_INODE_FALLOCATE
392         .fallocate      = zpl_fallocate,
393 #endif /* HAVE_INODE_FALLOCATE */
394 };
395
396 const struct inode_operations zpl_dir_inode_operations = {
397         .create         = zpl_create,
398         .lookup         = zpl_lookup,
399         .link           = zpl_link,
400         .unlink         = zpl_unlink,
401         .symlink        = zpl_symlink,
402         .mkdir          = zpl_mkdir,
403         .rmdir          = zpl_rmdir,
404         .mknod          = zpl_mknod,
405         .rename         = zpl_rename,
406         .setattr        = zpl_setattr,
407         .getattr        = zpl_getattr,
408         .setxattr       = generic_setxattr,
409         .getxattr       = generic_getxattr,
410         .removexattr    = generic_removexattr,
411         .listxattr      = zpl_xattr_list,
412 };
413
414 const struct inode_operations zpl_symlink_inode_operations = {
415         .readlink       = generic_readlink,
416         .follow_link    = zpl_follow_link,
417         .put_link       = zpl_put_link,
418         .setattr        = zpl_setattr,
419         .getattr        = zpl_getattr,
420         .setxattr       = generic_setxattr,
421         .getxattr       = generic_getxattr,
422         .removexattr    = generic_removexattr,
423         .listxattr      = zpl_xattr_list,
424 };
425
426 const struct inode_operations zpl_special_inode_operations = {
427         .setattr        = zpl_setattr,
428         .getattr        = zpl_getattr,
429         .setxattr       = generic_setxattr,
430         .getxattr       = generic_getxattr,
431         .removexattr    = generic_removexattr,
432         .listxattr      = zpl_xattr_list,
433 };