aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/getroot.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2010-04-16 16:22:48 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2010-05-14 15:09:23 -0400
commit8bac9db9cf85f2518cb523bb1d69c481975c1f9a (patch)
tree30c3d3cd02d34386e28f07b0fb3d172e1088cc47 /fs/nfs/getroot.c
parent04ffdbe2e69beb0f1745f921871fbe0f97dc4697 (diff)
NFSv4: Reduce stack footprint of nfs4_get_root()
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/getroot.c')
-rw-r--r--fs/nfs/getroot.c76
1 files changed, 46 insertions, 30 deletions
diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c
index ada369a5647b..7428f7d6273b 100644
--- a/fs/nfs/getroot.c
+++ b/fs/nfs/getroot.c
@@ -78,46 +78,52 @@ struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh)
78{ 78{
79 struct nfs_server *server = NFS_SB(sb); 79 struct nfs_server *server = NFS_SB(sb);
80 struct nfs_fsinfo fsinfo; 80 struct nfs_fsinfo fsinfo;
81 struct nfs_fattr fattr; 81 struct dentry *ret;
82 struct dentry *mntroot;
83 struct inode *inode; 82 struct inode *inode;
84 int error; 83 int error;
85 84
86 /* get the actual root for this mount */ 85 /* get the actual root for this mount */
87 fsinfo.fattr = &fattr; 86 fsinfo.fattr = nfs_alloc_fattr();
87 if (fsinfo.fattr == NULL)
88 return ERR_PTR(-ENOMEM);
88 89
89 error = server->nfs_client->rpc_ops->getroot(server, mntfh, &fsinfo); 90 error = server->nfs_client->rpc_ops->getroot(server, mntfh, &fsinfo);
90 if (error < 0) { 91 if (error < 0) {
91 dprintk("nfs_get_root: getattr error = %d\n", -error); 92 dprintk("nfs_get_root: getattr error = %d\n", -error);
92 return ERR_PTR(error); 93 ret = ERR_PTR(error);
94 goto out;
93 } 95 }
94 96
95 inode = nfs_fhget(sb, mntfh, fsinfo.fattr); 97 inode = nfs_fhget(sb, mntfh, fsinfo.fattr);
96 if (IS_ERR(inode)) { 98 if (IS_ERR(inode)) {
97 dprintk("nfs_get_root: get root inode failed\n"); 99 dprintk("nfs_get_root: get root inode failed\n");
98 return ERR_CAST(inode); 100 ret = ERR_CAST(inode);
101 goto out;
99 } 102 }
100 103
101 error = nfs_superblock_set_dummy_root(sb, inode); 104 error = nfs_superblock_set_dummy_root(sb, inode);
102 if (error != 0) 105 if (error != 0) {
103 return ERR_PTR(error); 106 ret = ERR_PTR(error);
107 goto out;
108 }
104 109
105 /* root dentries normally start off anonymous and get spliced in later 110 /* root dentries normally start off anonymous and get spliced in later
106 * if the dentry tree reaches them; however if the dentry already 111 * if the dentry tree reaches them; however if the dentry already
107 * exists, we'll pick it up at this point and use it as the root 112 * exists, we'll pick it up at this point and use it as the root
108 */ 113 */
109 mntroot = d_obtain_alias(inode); 114 ret = d_obtain_alias(inode);
110 if (IS_ERR(mntroot)) { 115 if (IS_ERR(ret)) {
111 dprintk("nfs_get_root: get root dentry failed\n"); 116 dprintk("nfs_get_root: get root dentry failed\n");
112 return mntroot; 117 goto out;
113 } 118 }
114 119
115 security_d_instantiate(mntroot, inode); 120 security_d_instantiate(ret, inode);
116 121
117 if (!mntroot->d_op) 122 if (ret->d_op == NULL)
118 mntroot->d_op = server->nfs_client->rpc_ops->dentry_ops; 123 ret->d_op = server->nfs_client->rpc_ops->dentry_ops;
119 124out:
120 return mntroot; 125 nfs_free_fattr(fsinfo.fattr);
126 return ret;
121} 127}
122 128
123#ifdef CONFIG_NFS_V4 129#ifdef CONFIG_NFS_V4
@@ -168,8 +174,8 @@ out:
168struct dentry *nfs4_get_root(struct super_block *sb, struct nfs_fh *mntfh) 174struct dentry *nfs4_get_root(struct super_block *sb, struct nfs_fh *mntfh)
169{ 175{
170 struct nfs_server *server = NFS_SB(sb); 176 struct nfs_server *server = NFS_SB(sb);
171 struct nfs_fattr fattr; 177 struct nfs_fattr *fattr = NULL;
172 struct dentry *mntroot; 178 struct dentry *ret;
173 struct inode *inode; 179 struct inode *inode;
174 int error; 180 int error;
175 181
@@ -183,40 +189,50 @@ struct dentry *nfs4_get_root(struct super_block *sb, struct nfs_fh *mntfh)
183 return ERR_PTR(error); 189 return ERR_PTR(error);
184 } 190 }
185 191
192 fattr = nfs_alloc_fattr();
193 if (fattr == NULL)
194 return ERR_PTR(-ENOMEM);;
195
186 /* get the actual root for this mount */ 196 /* get the actual root for this mount */
187 error = server->nfs_client->rpc_ops->getattr(server, mntfh, &fattr); 197 error = server->nfs_client->rpc_ops->getattr(server, mntfh, fattr);
188 if (error < 0) { 198 if (error < 0) {
189 dprintk("nfs_get_root: getattr error = %d\n", -error); 199 dprintk("nfs_get_root: getattr error = %d\n", -error);
190 return ERR_PTR(error); 200 ret = ERR_PTR(error);
201 goto out;
191 } 202 }
192 203
193 inode = nfs_fhget(sb, mntfh, &fattr); 204 inode = nfs_fhget(sb, mntfh, fattr);
194 if (IS_ERR(inode)) { 205 if (IS_ERR(inode)) {
195 dprintk("nfs_get_root: get root inode failed\n"); 206 dprintk("nfs_get_root: get root inode failed\n");
196 return ERR_CAST(inode); 207 ret = ERR_CAST(inode);
208 goto out;
197 } 209 }
198 210
199 error = nfs_superblock_set_dummy_root(sb, inode); 211 error = nfs_superblock_set_dummy_root(sb, inode);
200 if (error != 0) 212 if (error != 0) {
201 return ERR_PTR(error); 213 ret = ERR_PTR(error);
214 goto out;
215 }
202 216
203 /* root dentries normally start off anonymous and get spliced in later 217 /* root dentries normally start off anonymous and get spliced in later
204 * if the dentry tree reaches them; however if the dentry already 218 * if the dentry tree reaches them; however if the dentry already
205 * exists, we'll pick it up at this point and use it as the root 219 * exists, we'll pick it up at this point and use it as the root
206 */ 220 */
207 mntroot = d_obtain_alias(inode); 221 ret = d_obtain_alias(inode);
208 if (IS_ERR(mntroot)) { 222 if (IS_ERR(ret)) {
209 dprintk("nfs_get_root: get root dentry failed\n"); 223 dprintk("nfs_get_root: get root dentry failed\n");
210 return mntroot; 224 goto out;
211 } 225 }
212 226
213 security_d_instantiate(mntroot, inode); 227 security_d_instantiate(ret, inode);
214 228
215 if (!mntroot->d_op) 229 if (ret->d_op == NULL)
216 mntroot->d_op = server->nfs_client->rpc_ops->dentry_ops; 230 ret->d_op = server->nfs_client->rpc_ops->dentry_ops;
217 231
232out:
233 nfs_free_fattr(fattr);
218 dprintk("<-- nfs4_get_root()\n"); 234 dprintk("<-- nfs4_get_root()\n");
219 return mntroot; 235 return ret;
220} 236}
221 237
222#endif /* CONFIG_NFS_V4 */ 238#endif /* CONFIG_NFS_V4 */