aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/getroot.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/getroot.c')
-rw-r--r--fs/nfs/getroot.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c
index 4d6e5a317e6d..1084792bc0fe 100644
--- a/fs/nfs/getroot.c
+++ b/fs/nfs/getroot.c
@@ -82,12 +82,18 @@ struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh,
82 struct nfs_fsinfo fsinfo; 82 struct nfs_fsinfo fsinfo;
83 struct dentry *ret; 83 struct dentry *ret;
84 struct inode *inode; 84 struct inode *inode;
85 void *name = kstrdup(devname, GFP_KERNEL);
85 int error; 86 int error;
86 87
88 if (!name)
89 return ERR_PTR(-ENOMEM);
90
87 /* get the actual root for this mount */ 91 /* get the actual root for this mount */
88 fsinfo.fattr = nfs_alloc_fattr(); 92 fsinfo.fattr = nfs_alloc_fattr();
89 if (fsinfo.fattr == NULL) 93 if (fsinfo.fattr == NULL) {
94 kfree(name);
90 return ERR_PTR(-ENOMEM); 95 return ERR_PTR(-ENOMEM);
96 }
91 97
92 error = server->nfs_client->rpc_ops->getroot(server, mntfh, &fsinfo); 98 error = server->nfs_client->rpc_ops->getroot(server, mntfh, &fsinfo);
93 if (error < 0) { 99 if (error < 0) {
@@ -120,7 +126,15 @@ struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh,
120 } 126 }
121 127
122 security_d_instantiate(ret, inode); 128 security_d_instantiate(ret, inode);
129 spin_lock(&ret->d_lock);
130 if (IS_ROOT(ret) && !(ret->d_flags & DCACHE_NFSFS_RENAMED)) {
131 ret->d_fsdata = name;
132 name = NULL;
133 }
134 spin_unlock(&ret->d_lock);
123out: 135out:
136 if (name)
137 kfree(name);
124 nfs_free_fattr(fsinfo.fattr); 138 nfs_free_fattr(fsinfo.fattr);
125 return ret; 139 return ret;
126} 140}
@@ -177,21 +191,28 @@ struct dentry *nfs4_get_root(struct super_block *sb, struct nfs_fh *mntfh,
177 struct nfs_fattr *fattr = NULL; 191 struct nfs_fattr *fattr = NULL;
178 struct dentry *ret; 192 struct dentry *ret;
179 struct inode *inode; 193 struct inode *inode;
194 void *name = kstrdup(devname, GFP_KERNEL);
180 int error; 195 int error;
181 196
182 dprintk("--> nfs4_get_root()\n"); 197 dprintk("--> nfs4_get_root()\n");
183 198
199 if (!name)
200 return ERR_PTR(-ENOMEM);
201
184 /* get the info about the server and filesystem */ 202 /* get the info about the server and filesystem */
185 error = nfs4_server_capabilities(server, mntfh); 203 error = nfs4_server_capabilities(server, mntfh);
186 if (error < 0) { 204 if (error < 0) {
187 dprintk("nfs_get_root: getcaps error = %d\n", 205 dprintk("nfs_get_root: getcaps error = %d\n",
188 -error); 206 -error);
207 kfree(name);
189 return ERR_PTR(error); 208 return ERR_PTR(error);
190 } 209 }
191 210
192 fattr = nfs_alloc_fattr(); 211 fattr = nfs_alloc_fattr();
193 if (fattr == NULL) 212 if (fattr == NULL) {
194 return ERR_PTR(-ENOMEM);; 213 kfree(name);
214 return ERR_PTR(-ENOMEM);
215 }
195 216
196 /* get the actual root for this mount */ 217 /* get the actual root for this mount */
197 error = server->nfs_client->rpc_ops->getattr(server, mntfh, fattr); 218 error = server->nfs_client->rpc_ops->getattr(server, mntfh, fattr);
@@ -225,8 +246,15 @@ struct dentry *nfs4_get_root(struct super_block *sb, struct nfs_fh *mntfh,
225 } 246 }
226 247
227 security_d_instantiate(ret, inode); 248 security_d_instantiate(ret, inode);
228 249 spin_lock(&ret->d_lock);
250 if (IS_ROOT(ret) && !(ret->d_flags & DCACHE_NFSFS_RENAMED)) {
251 ret->d_fsdata = name;
252 name = NULL;
253 }
254 spin_unlock(&ret->d_lock);
229out: 255out:
256 if (name)
257 kfree(name);
230 nfs_free_fattr(fattr); 258 nfs_free_fattr(fattr);
231 dprintk("<-- nfs4_get_root()\n"); 259 dprintk("<-- nfs4_get_root()\n");
232 return ret; 260 return ret;