4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.gnu.org/licenses/gpl-2.0.html
23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Use is subject to license terms.
26 * Copyright (c) 2011, 2012, Intel Corporation.
29 * This file is part of Lustre, http://www.lustre.org/
30 * Lustre is a trademark of Sun Microsystems, Inc.
32 * lustre/lustre/llite/llite_nfs.c
34 * NFS export of Lustre Light File System
36 * Author: Yury Umanets <umka@clusterfs.com>
37 * Author: Huang Hua <huanghua@clusterfs.com>
40 #define DEBUG_SUBSYSTEM S_LLITE
41 #include "../include/lustre_lite.h"
42 #include "llite_internal.h"
43 #include <linux/exportfs.h>
45 __u32
get_uuid2int(const char *name
, int len
)
47 __u32 key0
= 0x12a3fe2d, key1
= 0x37abe8f9;
50 __u32 key
= key1
+ (key0
^ (*name
++ * 7152373));
60 void get_uuid2fsid(const char *name
, int len
, __kernel_fsid_t
*fsid
)
62 __u64 key
= 0, key0
= 0x12a3fe2d, key1
= 0x37abe8f9;
65 key
= key1
+ (key0
^ (*name
++ * 7152373));
66 if (key
& 0x8000000000000000ULL
)
67 key
-= 0x7fffffffffffffffULL
;
73 fsid
->val
[1] = key
>> 32;
76 static int ll_nfs_test_inode(struct inode
*inode
, void *opaque
)
78 return lu_fid_eq(&ll_i2info(inode
)->lli_fid
, opaque
);
81 struct inode
*search_inode_for_lustre(struct super_block
*sb
,
82 const struct lu_fid
*fid
)
84 struct ll_sb_info
*sbi
= ll_s2sbi(sb
);
85 struct ptlrpc_request
*req
= NULL
;
86 struct inode
*inode
= NULL
;
88 unsigned long hash
= cl_fid_build_ino(fid
,
89 ll_need_32bit_api(sbi
));
90 struct md_op_data
*op_data
;
93 CDEBUG(D_INFO
, "searching inode for:(%lu,"DFID
")\n", hash
, PFID(fid
));
95 inode
= ilookup5(sb
, hash
, ll_nfs_test_inode
, (void *)fid
);
99 rc
= ll_get_default_mdsize(sbi
, &eadatalen
);
103 /* Because inode is NULL, ll_prep_md_op_data can not
104 * be used here. So we allocate op_data ourselves
106 op_data
= kzalloc(sizeof(*op_data
), GFP_NOFS
);
108 return ERR_PTR(-ENOMEM
);
110 op_data
->op_fid1
= *fid
;
111 op_data
->op_mode
= eadatalen
;
112 op_data
->op_valid
= OBD_MD_FLEASIZE
;
114 /* mds_fid2dentry ignores f_type */
115 rc
= md_getattr(sbi
->ll_md_exp
, op_data
, &req
);
118 CDEBUG(D_INFO
, "can't get object attrs, fid "DFID
", rc %d\n",
122 rc
= ll_prep_inode(&inode
, req
, sb
, NULL
);
123 ptlrpc_req_finished(req
);
130 struct lustre_nfs_fid
{
131 struct lu_fid lnf_child
;
132 struct lu_fid lnf_parent
;
135 static struct dentry
*
136 ll_iget_for_nfs(struct super_block
*sb
, struct lu_fid
*fid
, struct lu_fid
*parent
)
139 struct dentry
*result
;
141 if (!fid_is_sane(fid
))
142 return ERR_PTR(-ESTALE
);
144 CDEBUG(D_INFO
, "Get dentry for fid: " DFID
"\n", PFID(fid
));
146 inode
= search_inode_for_lustre(sb
, fid
);
148 return ERR_CAST(inode
);
150 if (is_bad_inode(inode
)) {
151 /* we didn't find the right inode.. */
153 return ERR_PTR(-ESTALE
);
157 * It is an anonymous dentry without OST objects created yet.
158 * We have to find the parent to tell MDS how to init lov objects.
160 if (S_ISREG(inode
->i_mode
) && !ll_i2info(inode
)->lli_has_smd
&&
161 parent
&& !fid_is_zero(parent
)) {
162 struct ll_inode_info
*lli
= ll_i2info(inode
);
164 spin_lock(&lli
->lli_lock
);
165 lli
->lli_pfid
= *parent
;
166 spin_unlock(&lli
->lli_lock
);
169 /* N.B. d_obtain_alias() drops inode ref on error */
170 result
= d_obtain_alias(inode
);
176 * \a connectable - is nfsd will connect himself or this should be done
179 * The return value is file handle type:
180 * 1 -- contains child file handle;
181 * 2 -- contains child file handle and parent file handle;
184 static int ll_encode_fh(struct inode
*inode
, __u32
*fh
, int *plen
,
185 struct inode
*parent
)
187 int fileid_len
= sizeof(struct lustre_nfs_fid
) / 4;
188 struct lustre_nfs_fid
*nfs_fid
= (void *)fh
;
190 CDEBUG(D_INFO
, "%s: encoding for ("DFID
") maxlen=%d minlen=%d\n",
191 ll_get_fsname(inode
->i_sb
, NULL
, 0),
192 PFID(ll_inode2fid(inode
)), *plen
, fileid_len
);
194 if (*plen
< fileid_len
) {
196 return FILEID_INVALID
;
199 nfs_fid
->lnf_child
= *ll_inode2fid(inode
);
201 nfs_fid
->lnf_parent
= *ll_inode2fid(parent
);
203 fid_zero(&nfs_fid
->lnf_parent
);
206 return FILEID_LUSTRE
;
209 static int ll_nfs_get_name_filldir(struct dir_context
*ctx
, const char *name
,
210 int namelen
, loff_t hash
, u64 ino
,
213 /* It is hack to access lde_fid for comparison with lgd_fid.
214 * So the input 'name' must be part of the 'lu_dirent'.
216 struct lu_dirent
*lde
= container_of0(name
, struct lu_dirent
, lde_name
);
217 struct ll_getname_data
*lgd
=
218 container_of(ctx
, struct ll_getname_data
, ctx
);
221 fid_le_to_cpu(&fid
, &lde
->lde_fid
);
222 if (lu_fid_eq(&fid
, &lgd
->lgd_fid
)) {
223 memcpy(lgd
->lgd_name
, name
, namelen
);
224 lgd
->lgd_name
[namelen
] = 0;
227 return lgd
->lgd_found
;
230 static int ll_get_name(struct dentry
*dentry
, char *name
,
231 struct dentry
*child
)
233 struct inode
*dir
= d_inode(dentry
);
235 struct ll_getname_data lgd
= {
237 .lgd_fid
= ll_i2info(d_inode(child
))->lli_fid
,
238 .ctx
.actor
= ll_nfs_get_name_filldir
,
241 if (!dir
|| !S_ISDIR(dir
->i_mode
)) {
252 rc
= ll_dir_read(dir
, &lgd
.ctx
);
254 if (!rc
&& !lgd
.lgd_found
)
260 static struct dentry
*ll_fh_to_dentry(struct super_block
*sb
, struct fid
*fid
,
261 int fh_len
, int fh_type
)
263 struct lustre_nfs_fid
*nfs_fid
= (struct lustre_nfs_fid
*)fid
;
265 if (fh_type
!= FILEID_LUSTRE
)
266 return ERR_PTR(-EPROTO
);
268 return ll_iget_for_nfs(sb
, &nfs_fid
->lnf_child
, &nfs_fid
->lnf_parent
);
271 static struct dentry
*ll_fh_to_parent(struct super_block
*sb
, struct fid
*fid
,
272 int fh_len
, int fh_type
)
274 struct lustre_nfs_fid
*nfs_fid
= (struct lustre_nfs_fid
*)fid
;
276 if (fh_type
!= FILEID_LUSTRE
)
277 return ERR_PTR(-EPROTO
);
279 return ll_iget_for_nfs(sb
, &nfs_fid
->lnf_parent
, NULL
);
282 static struct dentry
*ll_get_parent(struct dentry
*dchild
)
284 struct ptlrpc_request
*req
= NULL
;
285 struct inode
*dir
= d_inode(dchild
);
286 struct ll_sb_info
*sbi
;
287 struct dentry
*result
= NULL
;
288 struct mdt_body
*body
;
289 static char dotdot
[] = "..";
290 struct md_op_data
*op_data
;
294 LASSERT(dir
&& S_ISDIR(dir
->i_mode
));
296 sbi
= ll_s2sbi(dir
->i_sb
);
298 CDEBUG(D_INFO
, "%s: getting parent for ("DFID
")\n",
299 ll_get_fsname(dir
->i_sb
, NULL
, 0),
300 PFID(ll_inode2fid(dir
)));
302 rc
= ll_get_default_mdsize(sbi
, &lmmsize
);
306 op_data
= ll_prep_md_op_data(NULL
, dir
, NULL
, dotdot
,
307 strlen(dotdot
), lmmsize
,
308 LUSTRE_OPC_ANY
, NULL
);
310 return (void *)op_data
;
312 rc
= md_getattr_name(sbi
->ll_md_exp
, op_data
, &req
);
313 ll_finish_md_op_data(op_data
);
315 CERROR("%s: failure inode "DFID
" get parent: rc = %d\n",
316 ll_get_fsname(dir
->i_sb
, NULL
, 0),
317 PFID(ll_inode2fid(dir
)), rc
);
320 body
= req_capsule_server_get(&req
->rq_pill
, &RMF_MDT_BODY
);
322 * LU-3952: MDT may lost the FID of its parent, we should not crash
323 * the NFS server, ll_iget_for_nfs() will handle the error.
325 if (body
->valid
& OBD_MD_FLID
) {
326 CDEBUG(D_INFO
, "parent for " DFID
" is " DFID
"\n",
327 PFID(ll_inode2fid(dir
)), PFID(&body
->fid1
));
329 result
= ll_iget_for_nfs(dir
->i_sb
, &body
->fid1
, NULL
);
331 ptlrpc_req_finished(req
);
335 const struct export_operations lustre_export_operations
= {
336 .get_parent
= ll_get_parent
,
337 .encode_fh
= ll_encode_fh
,
338 .get_name
= ll_get_name
,
339 .fh_to_dentry
= ll_fh_to_dentry
,
340 .fh_to_parent
= ll_fh_to_parent
,