diff options
Diffstat (limited to 'fs/nfsd/vfs.c')
-rw-r--r-- | fs/nfsd/vfs.c | 54 |
1 files changed, 27 insertions, 27 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index bd584bcf1d9f..99f835753596 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -101,36 +101,35 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp, | |||
101 | { | 101 | { |
102 | struct svc_export *exp = *expp, *exp2 = NULL; | 102 | struct svc_export *exp = *expp, *exp2 = NULL; |
103 | struct dentry *dentry = *dpp; | 103 | struct dentry *dentry = *dpp; |
104 | struct vfsmount *mnt = mntget(exp->ex_path.mnt); | 104 | struct path path = {.mnt = mntget(exp->ex_path.mnt), |
105 | struct dentry *mounts = dget(dentry); | 105 | .dentry = dget(dentry)}; |
106 | int err = 0; | 106 | int err = 0; |
107 | 107 | ||
108 | while (follow_down(&mnt,&mounts)&&d_mountpoint(mounts)); | 108 | while (d_mountpoint(path.dentry) && follow_down(&path)) |
109 | ; | ||
109 | 110 | ||
110 | exp2 = rqst_exp_get_by_name(rqstp, mnt, mounts); | 111 | exp2 = rqst_exp_get_by_name(rqstp, &path); |
111 | if (IS_ERR(exp2)) { | 112 | if (IS_ERR(exp2)) { |
112 | if (PTR_ERR(exp2) != -ENOENT) | 113 | if (PTR_ERR(exp2) != -ENOENT) |
113 | err = PTR_ERR(exp2); | 114 | err = PTR_ERR(exp2); |
114 | dput(mounts); | 115 | path_put(&path); |
115 | mntput(mnt); | ||
116 | goto out; | 116 | goto out; |
117 | } | 117 | } |
118 | if ((exp->ex_flags & NFSEXP_CROSSMOUNT) || EX_NOHIDE(exp2)) { | 118 | if ((exp->ex_flags & NFSEXP_CROSSMOUNT) || EX_NOHIDE(exp2)) { |
119 | /* successfully crossed mount point */ | 119 | /* successfully crossed mount point */ |
120 | /* | 120 | /* |
121 | * This is subtle: dentry is *not* under mnt at this point. | 121 | * This is subtle: path.dentry is *not* on path.mnt |
122 | * The only reason we are safe is that original mnt is pinned | 122 | * at this point. The only reason we are safe is that |
123 | * down by exp, so we should dput before putting exp. | 123 | * original mnt is pinned down by exp, so we should |
124 | * put path *before* putting exp | ||
124 | */ | 125 | */ |
125 | dput(dentry); | 126 | *dpp = path.dentry; |
126 | *dpp = mounts; | 127 | path.dentry = dentry; |
127 | exp_put(exp); | ||
128 | *expp = exp2; | 128 | *expp = exp2; |
129 | } else { | 129 | exp2 = exp; |
130 | exp_put(exp2); | ||
131 | dput(mounts); | ||
132 | } | 130 | } |
133 | mntput(mnt); | 131 | path_put(&path); |
132 | exp_put(exp2); | ||
134 | out: | 133 | out: |
135 | return err; | 134 | return err; |
136 | } | 135 | } |
@@ -169,28 +168,29 @@ nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
169 | /* checking mountpoint crossing is very different when stepping up */ | 168 | /* checking mountpoint crossing is very different when stepping up */ |
170 | struct svc_export *exp2 = NULL; | 169 | struct svc_export *exp2 = NULL; |
171 | struct dentry *dp; | 170 | struct dentry *dp; |
172 | struct vfsmount *mnt = mntget(exp->ex_path.mnt); | 171 | struct path path = {.mnt = mntget(exp->ex_path.mnt), |
173 | dentry = dget(dparent); | 172 | .dentry = dget(dparent)}; |
174 | while(dentry == mnt->mnt_root && follow_up(&mnt, &dentry)) | 173 | |
174 | while (path.dentry == path.mnt->mnt_root && | ||
175 | follow_up(&path)) | ||
175 | ; | 176 | ; |
176 | dp = dget_parent(dentry); | 177 | dp = dget_parent(path.dentry); |
177 | dput(dentry); | 178 | dput(path.dentry); |
178 | dentry = dp; | 179 | path.dentry = dp; |
179 | 180 | ||
180 | exp2 = rqst_exp_parent(rqstp, mnt, dentry); | 181 | exp2 = rqst_exp_parent(rqstp, &path); |
181 | if (PTR_ERR(exp2) == -ENOENT) { | 182 | if (PTR_ERR(exp2) == -ENOENT) { |
182 | dput(dentry); | ||
183 | dentry = dget(dparent); | 183 | dentry = dget(dparent); |
184 | } else if (IS_ERR(exp2)) { | 184 | } else if (IS_ERR(exp2)) { |
185 | host_err = PTR_ERR(exp2); | 185 | host_err = PTR_ERR(exp2); |
186 | dput(dentry); | 186 | path_put(&path); |
187 | mntput(mnt); | ||
188 | goto out_nfserr; | 187 | goto out_nfserr; |
189 | } else { | 188 | } else { |
189 | dentry = dget(path.dentry); | ||
190 | exp_put(exp); | 190 | exp_put(exp); |
191 | exp = exp2; | 191 | exp = exp2; |
192 | } | 192 | } |
193 | mntput(mnt); | 193 | path_put(&path); |
194 | } | 194 | } |
195 | } else { | 195 | } else { |
196 | fh_lock(fhp); | 196 | fh_lock(fhp); |