aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/nfs4namespace.c84
1 files changed, 46 insertions, 38 deletions
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
index b112857301f7..956cbbc2ae9f 100644
--- a/fs/nfs/nfs4namespace.c
+++ b/fs/nfs/nfs4namespace.c
@@ -110,6 +110,48 @@ static inline int valid_ipaddr4(const char *buf)
110 return 0; 110 return 0;
111} 111}
112 112
113static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,
114 char *page, char *page2,
115 const struct nfs4_fs_location *location)
116{
117 struct vfsmount *mnt = ERR_PTR(-ENOENT);
118 char *mnt_path;
119 unsigned int s = 0;
120
121 mnt_path = nfs4_pathname_string(&location->rootpath, page2, PAGE_SIZE);
122 if (IS_ERR(mnt_path))
123 return mnt;
124 mountdata->mnt_path = mnt_path;
125
126 while (s < location->nservers) {
127 struct sockaddr_in addr = {
128 .sin_family = AF_INET,
129 .sin_port = htons(NFS_PORT),
130 };
131
132 if (location->servers[s].len <= 0 ||
133 valid_ipaddr4(location->servers[s].data) < 0) {
134 s++;
135 continue;
136 }
137
138 mountdata->hostname = location->servers[s].data;
139 addr.sin_addr.s_addr = in_aton(mountdata->hostname),
140 mountdata->addr = (struct sockaddr *)&addr;
141 mountdata->addrlen = sizeof(addr);
142
143 snprintf(page, PAGE_SIZE, "%s:%s",
144 mountdata->hostname,
145 mountdata->mnt_path);
146
147 mnt = vfs_kern_mount(&nfs4_referral_fs_type, 0, page, mountdata);
148 if (!IS_ERR(mnt))
149 break;
150 s++;
151 }
152 return mnt;
153}
154
113/** 155/**
114 * nfs_follow_referral - set up mountpoint when hitting a referral on moved error 156 * nfs_follow_referral - set up mountpoint when hitting a referral on moved error
115 * @mnt_parent - mountpoint of parent directory 157 * @mnt_parent - mountpoint of parent directory
@@ -128,7 +170,6 @@ static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent,
128 .authflavor = NFS_SB(mnt_parent->mnt_sb)->client->cl_auth->au_flavor, 170 .authflavor = NFS_SB(mnt_parent->mnt_sb)->client->cl_auth->au_flavor,
129 }; 171 };
130 char *page = NULL, *page2 = NULL; 172 char *page = NULL, *page2 = NULL;
131 unsigned int s;
132 int loc, error; 173 int loc, error;
133 174
134 if (locations == NULL || locations->nlocations <= 0) 175 if (locations == NULL || locations->nlocations <= 0)
@@ -153,9 +194,8 @@ static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent,
153 } 194 }
154 195
155 loc = 0; 196 loc = 0;
156 while (loc < locations->nlocations && IS_ERR(mnt)) { 197 while (loc < locations->nlocations) {
157 const struct nfs4_fs_location *location = &locations->locations[loc]; 198 const struct nfs4_fs_location *location = &locations->locations[loc];
158 char *mnt_path;
159 199
160 if (location == NULL || location->nservers <= 0 || 200 if (location == NULL || location->nservers <= 0 ||
161 location->rootpath.ncomponents == 0) { 201 location->rootpath.ncomponents == 0) {
@@ -163,41 +203,9 @@ static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent,
163 continue; 203 continue;
164 } 204 }
165 205
166 mnt_path = nfs4_pathname_string(&location->rootpath, page2, PAGE_SIZE); 206 mnt = try_location(&mountdata, page, page2, location);
167 if (IS_ERR(mnt_path)) { 207 if (!IS_ERR(mnt))
168 loc++; 208 break;
169 continue;
170 }
171 mountdata.mnt_path = mnt_path;
172
173 s = 0;
174 while (s < location->nservers) {
175 struct sockaddr_in addr = {
176 .sin_family = AF_INET,
177 .sin_port = htons(NFS_PORT),
178 };
179
180 if (location->servers[s].len <= 0 ||
181 valid_ipaddr4(location->servers[s].data) < 0) {
182 s++;
183 continue;
184 }
185
186 mountdata.hostname = location->servers[s].data;
187 addr.sin_addr.s_addr = in_aton(mountdata.hostname),
188 mountdata.addr = (struct sockaddr *)&addr;
189 mountdata.addrlen = sizeof(addr);
190
191 snprintf(page, PAGE_SIZE, "%s:%s",
192 mountdata.hostname,
193 mountdata.mnt_path);
194
195 mnt = vfs_kern_mount(&nfs4_referral_fs_type, 0, page, &mountdata);
196 if (!IS_ERR(mnt)) {
197 break;
198 }
199 s++;
200 }
201 loc++; 209 loc++;
202 } 210 }
203 211