• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
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.
9  *
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).
15  *
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.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  *
30  * Copyright (c) 2011, 2012, Intel Corporation.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  */
36 
37 #include <linux/fs.h>
38 #include <linux/mm.h>
39 #include <linux/stat.h>
40 #define DEBUG_SUBSYSTEM S_LLITE
41 
42 #include "../include/lustre_lite.h"
43 #include "llite_internal.h"
44 
ll_readlink_internal(struct inode * inode,struct ptlrpc_request ** request,char ** symname)45 static int ll_readlink_internal(struct inode *inode,
46 				struct ptlrpc_request **request, char **symname)
47 {
48 	struct ll_inode_info *lli = ll_i2info(inode);
49 	struct ll_sb_info *sbi = ll_i2sbi(inode);
50 	int rc, symlen = i_size_read(inode) + 1;
51 	struct mdt_body *body;
52 	struct md_op_data *op_data;
53 
54 	*request = NULL;
55 
56 	if (lli->lli_symlink_name) {
57 		int print_limit = min_t(int, PAGE_SIZE - 128, symlen);
58 
59 		*symname = lli->lli_symlink_name;
60 		/* If the total CDEBUG() size is larger than a page, it
61 		 * will print a warning to the console, avoid this by
62 		 * printing just the last part of the symlink. */
63 		CDEBUG(D_INODE, "using cached symlink %s%.*s, len = %d\n",
64 		       print_limit < symlen ? "..." : "", print_limit,
65 		       (*symname) + symlen - print_limit, symlen);
66 		return 0;
67 	}
68 
69 	op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, symlen,
70 				     LUSTRE_OPC_ANY, NULL);
71 	if (IS_ERR(op_data))
72 		return PTR_ERR(op_data);
73 
74 	op_data->op_valid = OBD_MD_LINKNAME;
75 	rc = md_getattr(sbi->ll_md_exp, op_data, request);
76 	ll_finish_md_op_data(op_data);
77 	if (rc) {
78 		if (rc != -ENOENT)
79 			CERROR("inode %lu: rc = %d\n", inode->i_ino, rc);
80 		goto failed;
81 	}
82 
83 	body = req_capsule_server_get(&(*request)->rq_pill, &RMF_MDT_BODY);
84 	LASSERT(body != NULL);
85 	if ((body->valid & OBD_MD_LINKNAME) == 0) {
86 		CERROR("OBD_MD_LINKNAME not set on reply\n");
87 		rc = -EPROTO;
88 		goto failed;
89 	}
90 
91 	LASSERT(symlen != 0);
92 	if (body->eadatasize != symlen) {
93 		CERROR("inode %lu: symlink length %d not expected %d\n",
94 			inode->i_ino, body->eadatasize - 1, symlen - 1);
95 		rc = -EPROTO;
96 		goto failed;
97 	}
98 
99 	*symname = req_capsule_server_get(&(*request)->rq_pill, &RMF_MDT_MD);
100 	if (*symname == NULL ||
101 	    strnlen(*symname, symlen) != symlen - 1) {
102 		/* not full/NULL terminated */
103 		CERROR("inode %lu: symlink not NULL terminated string of length %d\n",
104 		       inode->i_ino, symlen - 1);
105 		rc = -EPROTO;
106 		goto failed;
107 	}
108 
109 	lli->lli_symlink_name = kzalloc(symlen, GFP_NOFS);
110 	/* do not return an error if we cannot cache the symlink locally */
111 	if (lli->lli_symlink_name) {
112 		memcpy(lli->lli_symlink_name, *symname, symlen);
113 		*symname = lli->lli_symlink_name;
114 	}
115 	return 0;
116 
117 failed:
118 	return rc;
119 }
120 
ll_follow_link(struct dentry * dentry,void ** cookie)121 static const char *ll_follow_link(struct dentry *dentry, void **cookie)
122 {
123 	struct inode *inode = d_inode(dentry);
124 	struct ptlrpc_request *request = NULL;
125 	int rc;
126 	char *symname = NULL;
127 
128 	CDEBUG(D_VFSTRACE, "VFS Op\n");
129 	ll_inode_size_lock(inode);
130 	rc = ll_readlink_internal(inode, &request, &symname);
131 	ll_inode_size_unlock(inode);
132 	if (rc) {
133 		ptlrpc_req_finished(request);
134 		return ERR_PTR(rc);
135 	}
136 
137 	/* symname may contain a pointer to the request message buffer,
138 	 * we delay request releasing until ll_put_link then.
139 	 */
140 	*cookie = request;
141 	return symname;
142 }
143 
ll_put_link(struct inode * unused,void * cookie)144 static void ll_put_link(struct inode *unused, void *cookie)
145 {
146 	ptlrpc_req_finished(cookie);
147 }
148 
149 struct inode_operations ll_fast_symlink_inode_operations = {
150 	.readlink	= generic_readlink,
151 	.setattr	= ll_setattr,
152 	.follow_link	= ll_follow_link,
153 	.put_link	= ll_put_link,
154 	.getattr	= ll_getattr,
155 	.permission	= ll_inode_permission,
156 	.setxattr	= ll_setxattr,
157 	.getxattr	= ll_getxattr,
158 	.listxattr	= ll_listxattr,
159 	.removexattr	= ll_removexattr,
160 };
161