diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2011-03-16 05:44:14 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2011-03-16 16:44:24 -0400 |
commit | b1942c5f8cf3bea3a3c88a7498ae4c4361f31afe (patch) | |
tree | 0ff98cbdf75b23104df97344dcd6a35a86bbe9ec /fs/nfs/dir.c | |
parent | 0d5839ad05acd0fe2a84a39f33ac5efdf634a5a5 (diff) |
nfs: store devname at disconnected NFS roots
part 2: make sure that disconnected roots have corresponding mnt_devname
values stashed into them.
Have nfs*_get_root() stuff a copy of devname into ->d_fsdata of the
found root, provided that it is disconnected.
Have ->d_release() free it when dentry goes away.
Have the places where NFS uses ->d_fsdata for sillyrename (and that
can *never* happen to a disconnected root - dentry will be attached
to its parent) free old devname copies if they find those.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r-- | fs/nfs/dir.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 2c3eb33b904d..abdf38d5971d 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -1169,11 +1169,23 @@ static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode) | |||
1169 | iput(inode); | 1169 | iput(inode); |
1170 | } | 1170 | } |
1171 | 1171 | ||
1172 | static void nfs_d_release(struct dentry *dentry) | ||
1173 | { | ||
1174 | /* free cached devname value, if it survived that far */ | ||
1175 | if (unlikely(dentry->d_fsdata)) { | ||
1176 | if (dentry->d_flags & DCACHE_NFSFS_RENAMED) | ||
1177 | WARN_ON(1); | ||
1178 | else | ||
1179 | kfree(dentry->d_fsdata); | ||
1180 | } | ||
1181 | } | ||
1182 | |||
1172 | const struct dentry_operations nfs_dentry_operations = { | 1183 | const struct dentry_operations nfs_dentry_operations = { |
1173 | .d_revalidate = nfs_lookup_revalidate, | 1184 | .d_revalidate = nfs_lookup_revalidate, |
1174 | .d_delete = nfs_dentry_delete, | 1185 | .d_delete = nfs_dentry_delete, |
1175 | .d_iput = nfs_dentry_iput, | 1186 | .d_iput = nfs_dentry_iput, |
1176 | .d_automount = nfs_d_automount, | 1187 | .d_automount = nfs_d_automount, |
1188 | .d_release = nfs_d_release, | ||
1177 | }; | 1189 | }; |
1178 | 1190 | ||
1179 | static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) | 1191 | static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) |
@@ -1248,6 +1260,7 @@ const struct dentry_operations nfs4_dentry_operations = { | |||
1248 | .d_delete = nfs_dentry_delete, | 1260 | .d_delete = nfs_dentry_delete, |
1249 | .d_iput = nfs_dentry_iput, | 1261 | .d_iput = nfs_dentry_iput, |
1250 | .d_automount = nfs_d_automount, | 1262 | .d_automount = nfs_d_automount, |
1263 | .d_release = nfs_d_release, | ||
1251 | }; | 1264 | }; |
1252 | 1265 | ||
1253 | /* | 1266 | /* |