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.
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.
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]
22 * Copyright (c) 2011 Gunnar Beutner
26 #include <sys/zfs_vnops.h>
27 #include <sys/zfs_znode.h>
28 #include <sys/zfs_ctldir.h>
33 #ifdef HAVE_ENCODE_FH_WITH_INODE
34 zpl_encode_fh(struct inode
*ip
, __u32
*fh
, int *max_len
, struct inode
*parent
)
37 zpl_encode_fh(struct dentry
*dentry
, __u32
*fh
, int *max_len
, int connectable
)
39 struct inode
*ip
= dentry
->d_inode
;
40 #endif /* HAVE_ENCODE_FH_WITH_INODE */
41 fid_t
*fid
= (fid_t
*)fh
;
44 len_bytes
= *max_len
* sizeof (__u32
);
46 if (len_bytes
< offsetof(fid_t
, fid_data
))
49 fid
->fid_len
= len_bytes
- offsetof(fid_t
, fid_data
);
51 if (zfsctl_is_node(ip
))
52 rc
= zfsctl_fid(ip
, fid
);
54 rc
= zfs_fid(ip
, fid
);
56 len_bytes
= offsetof(fid_t
, fid_data
) + fid
->fid_len
;
57 *max_len
= roundup(len_bytes
, sizeof (__u32
)) / sizeof (__u32
);
59 return (rc
== 0 ? FILEID_INO32_GEN
: 255);
62 static struct dentry
*
63 zpl_dentry_obtain_alias(struct inode
*ip
)
65 struct dentry
*result
;
67 #ifdef HAVE_D_OBTAIN_ALIAS
68 result
= d_obtain_alias(ip
);
70 result
= d_alloc_anon(ip
);
74 result
= ERR_PTR(-ENOMEM
);
76 #endif /* HAVE_D_OBTAIN_ALIAS */
81 static struct dentry
*
82 zpl_fh_to_dentry(struct super_block
*sb
, struct fid
*fh
,
83 int fh_len
, int fh_type
)
85 fid_t
*fid
= (fid_t
*)fh
;
89 len_bytes
= fh_len
* sizeof (__u32
);
91 if (fh_type
!= FILEID_INO32_GEN
||
92 len_bytes
< offsetof(fid_t
, fid_data
) ||
93 len_bytes
< offsetof(fid_t
, fid_data
) + fid
->fid_len
)
94 return ERR_PTR(-EINVAL
);
96 rc
= zfs_vget(sb
, &ip
, fid
);
101 ASSERT((ip
!= NULL
) && !IS_ERR(ip
));
103 return zpl_dentry_obtain_alias(ip
);
106 static struct dentry
*
107 zpl_get_parent(struct dentry
*child
)
114 error
= -zfs_lookup(child
->d_inode
, "..", &ip
, 0, cr
, NULL
, NULL
);
116 ASSERT3S(error
, <=, 0);
119 return ERR_PTR(error
);
121 return zpl_dentry_obtain_alias(ip
);
124 const struct export_operations zpl_export_operations
= {
125 .encode_fh
= zpl_encode_fh
,
126 .fh_to_dentry
= zpl_fh_to_dentry
,
127 .get_parent
= zpl_get_parent