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 struct inode
*search_inode_for_lustre(struct super_block
*sb
,
77 const struct lu_fid
*fid
)
79 struct ll_sb_info
*sbi
= ll_s2sbi(sb
);
80 struct ptlrpc_request
*req
= NULL
;
81 struct inode
*inode
= NULL
;
83 unsigned long hash
= cl_fid_build_ino(fid
,
84 ll_need_32bit_api(sbi
));
85 struct md_op_data
*op_data
;
88 CDEBUG(D_INFO
, "searching inode for:(%lu,"DFID
")\n", hash
, PFID(fid
));
90 inode
= ilookup5(sb
, hash
, ll_test_inode_by_fid
, (void *)fid
);
94 rc
= ll_get_default_mdsize(sbi
, &eadatalen
);
98 /* Because inode is NULL, ll_prep_md_op_data can not
99 * be used here. So we allocate op_data ourselves
101 op_data
= kzalloc(sizeof(*op_data
), GFP_NOFS
);
103 return ERR_PTR(-ENOMEM
);
105 op_data
->op_fid1
= *fid
;
106 op_data
->op_mode
= eadatalen
;
107 op_data
->op_valid
= OBD_MD_FLEASIZE
;
109 /* mds_fid2dentry ignores f_type */
110 rc
= md_getattr(sbi
->ll_md_exp
, op_data
, &req
);
113 CDEBUG(D_INFO
, "can't get object attrs, fid "DFID
", rc %d\n",
117 rc
= ll_prep_inode(&inode
, req
, sb
, NULL
);
118 ptlrpc_req_finished(req
);
125 struct lustre_nfs_fid
{
126 struct lu_fid lnf_child
;
127 struct lu_fid lnf_parent
;
130 static struct dentry
*
131 ll_iget_for_nfs(struct super_block
*sb
, struct lu_fid
*fid
, struct lu_fid
*parent
)
134 struct dentry
*result
;
136 if (!fid_is_sane(fid
))
137 return ERR_PTR(-ESTALE
);
139 CDEBUG(D_INFO
, "Get dentry for fid: " DFID
"\n", PFID(fid
));
141 inode
= search_inode_for_lustre(sb
, fid
);
143 return ERR_CAST(inode
);
145 if (is_bad_inode(inode
)) {
146 /* we didn't find the right inode.. */
148 return ERR_PTR(-ESTALE
);
151 result
= d_obtain_alias(inode
);
152 if (IS_ERR(result
)) {
158 * In case d_obtain_alias() found a disconnected dentry, always update
159 * lli_pfid to allow later operation (normally open) have parent fid,
160 * which may be used by MDS to create data.
163 struct ll_inode_info
*lli
= ll_i2info(inode
);
165 spin_lock(&lli
->lli_lock
);
166 lli
->lli_pfid
= *parent
;
167 spin_unlock(&lli
->lli_lock
);
170 /* N.B. d_obtain_alias() drops inode ref on error */
171 result
= d_obtain_alias(inode
);
172 if (!IS_ERR(result
)) {
175 rc
= ll_d_init(result
);
178 result
= ERR_PTR(rc
);
180 struct ll_dentry_data
*ldd
= ll_d2d(result
);
183 * Need to signal to the ll_intent_file_open that
184 * we came from NFS and so opencache needs to be
185 * enabled for this one
187 ldd
->lld_nfs_dentry
= 1;
195 * \a connectable - is nfsd will connect himself or this should be done
198 * The return value is file handle type:
199 * 1 -- contains child file handle;
200 * 2 -- contains child file handle and parent file handle;
203 static int ll_encode_fh(struct inode
*inode
, __u32
*fh
, int *plen
,
204 struct inode
*parent
)
206 int fileid_len
= sizeof(struct lustre_nfs_fid
) / 4;
207 struct lustre_nfs_fid
*nfs_fid
= (void *)fh
;
209 CDEBUG(D_INFO
, "%s: encoding for ("DFID
") maxlen=%d minlen=%d\n",
210 ll_get_fsname(inode
->i_sb
, NULL
, 0),
211 PFID(ll_inode2fid(inode
)), *plen
, fileid_len
);
213 if (*plen
< fileid_len
) {
215 return FILEID_INVALID
;
218 nfs_fid
->lnf_child
= *ll_inode2fid(inode
);
220 nfs_fid
->lnf_parent
= *ll_inode2fid(parent
);
222 fid_zero(&nfs_fid
->lnf_parent
);
225 return FILEID_LUSTRE
;
228 static int ll_nfs_get_name_filldir(struct dir_context
*ctx
, const char *name
,
229 int namelen
, loff_t hash
, u64 ino
,
232 /* It is hack to access lde_fid for comparison with lgd_fid.
233 * So the input 'name' must be part of the 'lu_dirent'.
235 struct lu_dirent
*lde
= container_of0(name
, struct lu_dirent
, lde_name
);
236 struct ll_getname_data
*lgd
=
237 container_of(ctx
, struct ll_getname_data
, ctx
);
240 fid_le_to_cpu(&fid
, &lde
->lde_fid
);
241 if (lu_fid_eq(&fid
, &lgd
->lgd_fid
)) {
242 memcpy(lgd
->lgd_name
, name
, namelen
);
243 lgd
->lgd_name
[namelen
] = 0;
246 return lgd
->lgd_found
;
249 static int ll_get_name(struct dentry
*dentry
, char *name
,
250 struct dentry
*child
)
252 struct inode
*dir
= d_inode(dentry
);
254 struct ll_getname_data lgd
= {
256 .lgd_fid
= ll_i2info(d_inode(child
))->lli_fid
,
257 .ctx
.actor
= ll_nfs_get_name_filldir
,
259 struct md_op_data
*op_data
;
262 if (!dir
|| !S_ISDIR(dir
->i_mode
)) {
272 op_data
= ll_prep_md_op_data(NULL
, dir
, dir
, NULL
, 0, 0,
273 LUSTRE_OPC_ANY
, dir
);
274 if (IS_ERR(op_data
)) {
275 rc
= PTR_ERR(op_data
);
279 op_data
->op_max_pages
= ll_i2sbi(dir
)->ll_md_brw_pages
;
281 rc
= ll_dir_read(dir
, &pos
, op_data
, &lgd
.ctx
);
283 ll_finish_md_op_data(op_data
);
284 if (!rc
&& !lgd
.lgd_found
)
290 static struct dentry
*ll_fh_to_dentry(struct super_block
*sb
, struct fid
*fid
,
291 int fh_len
, int fh_type
)
293 struct lustre_nfs_fid
*nfs_fid
= (struct lustre_nfs_fid
*)fid
;
295 if (fh_type
!= FILEID_LUSTRE
)
296 return ERR_PTR(-EPROTO
);
298 return ll_iget_for_nfs(sb
, &nfs_fid
->lnf_child
, &nfs_fid
->lnf_parent
);
301 static struct dentry
*ll_fh_to_parent(struct super_block
*sb
, struct fid
*fid
,
302 int fh_len
, int fh_type
)
304 struct lustre_nfs_fid
*nfs_fid
= (struct lustre_nfs_fid
*)fid
;
306 if (fh_type
!= FILEID_LUSTRE
)
307 return ERR_PTR(-EPROTO
);
309 return ll_iget_for_nfs(sb
, &nfs_fid
->lnf_parent
, NULL
);
312 int ll_dir_get_parent_fid(struct inode
*dir
, struct lu_fid
*parent_fid
)
314 struct ptlrpc_request
*req
= NULL
;
315 struct ll_sb_info
*sbi
;
316 struct mdt_body
*body
;
317 static const char dotdot
[] = "..";
318 struct md_op_data
*op_data
;
322 LASSERT(dir
&& S_ISDIR(dir
->i_mode
));
324 sbi
= ll_s2sbi(dir
->i_sb
);
326 CDEBUG(D_INFO
, "%s: getting parent for ("DFID
")\n",
327 ll_get_fsname(dir
->i_sb
, NULL
, 0),
328 PFID(ll_inode2fid(dir
)));
330 rc
= ll_get_default_mdsize(sbi
, &lmmsize
);
334 op_data
= ll_prep_md_op_data(NULL
, dir
, NULL
, dotdot
,
335 strlen(dotdot
), lmmsize
,
336 LUSTRE_OPC_ANY
, NULL
);
338 return PTR_ERR(op_data
);
340 rc
= md_getattr_name(sbi
->ll_md_exp
, op_data
, &req
);
341 ll_finish_md_op_data(op_data
);
343 CERROR("%s: failure inode "DFID
" get parent: rc = %d\n",
344 ll_get_fsname(dir
->i_sb
, NULL
, 0),
345 PFID(ll_inode2fid(dir
)), rc
);
348 body
= req_capsule_server_get(&req
->rq_pill
, &RMF_MDT_BODY
);
350 * LU-3952: MDT may lost the FID of its parent, we should not crash
351 * the NFS server, ll_iget_for_nfs() will handle the error.
353 if (body
->mbo_valid
& OBD_MD_FLID
) {
354 CDEBUG(D_INFO
, "parent for " DFID
" is " DFID
"\n",
355 PFID(ll_inode2fid(dir
)), PFID(&body
->mbo_fid1
));
356 *parent_fid
= body
->mbo_fid1
;
359 ptlrpc_req_finished(req
);
363 static struct dentry
*ll_get_parent(struct dentry
*dchild
)
365 struct lu_fid parent_fid
= { 0 };
366 struct dentry
*dentry
;
369 rc
= ll_dir_get_parent_fid(dchild
->d_inode
, &parent_fid
);
373 dentry
= ll_iget_for_nfs(dchild
->d_inode
->i_sb
, &parent_fid
, NULL
);
378 const struct export_operations lustre_export_operations
= {
379 .get_parent
= ll_get_parent
,
380 .encode_fh
= ll_encode_fh
,
381 .get_name
= ll_get_name
,
382 .fh_to_dentry
= ll_fh_to_dentry
,
383 .fh_to_parent
= ll_fh_to_parent
,