diff options
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r-- | fs/nfs/inode.c | 100 |
1 files changed, 86 insertions, 14 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index bd7938eda6a8..060022b4651c 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include "iostat.h" | 46 | #include "iostat.h" |
47 | #include "internal.h" | 47 | #include "internal.h" |
48 | #include "fscache.h" | 48 | #include "fscache.h" |
49 | #include "dns_resolve.h" | ||
49 | 50 | ||
50 | #define NFSDBG_FACILITY NFSDBG_VFS | 51 | #define NFSDBG_FACILITY NFSDBG_VFS |
51 | 52 | ||
@@ -286,6 +287,11 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) | |||
286 | /* We can't support update_atime(), since the server will reset it */ | 287 | /* We can't support update_atime(), since the server will reset it */ |
287 | inode->i_flags |= S_NOATIME|S_NOCMTIME; | 288 | inode->i_flags |= S_NOATIME|S_NOCMTIME; |
288 | inode->i_mode = fattr->mode; | 289 | inode->i_mode = fattr->mode; |
290 | if ((fattr->valid & NFS_ATTR_FATTR_MODE) == 0 | ||
291 | && nfs_server_capable(inode, NFS_CAP_MODE)) | ||
292 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR | ||
293 | | NFS_INO_INVALID_ACCESS | ||
294 | | NFS_INO_INVALID_ACL; | ||
289 | /* Why so? Because we want revalidate for devices/FIFOs, and | 295 | /* Why so? Because we want revalidate for devices/FIFOs, and |
290 | * that's precisely what we have in nfs_file_inode_operations. | 296 | * that's precisely what we have in nfs_file_inode_operations. |
291 | */ | 297 | */ |
@@ -330,20 +336,46 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) | |||
330 | nfsi->attr_gencount = fattr->gencount; | 336 | nfsi->attr_gencount = fattr->gencount; |
331 | if (fattr->valid & NFS_ATTR_FATTR_ATIME) | 337 | if (fattr->valid & NFS_ATTR_FATTR_ATIME) |
332 | inode->i_atime = fattr->atime; | 338 | inode->i_atime = fattr->atime; |
339 | else if (nfs_server_capable(inode, NFS_CAP_ATIME)) | ||
340 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | ||
333 | if (fattr->valid & NFS_ATTR_FATTR_MTIME) | 341 | if (fattr->valid & NFS_ATTR_FATTR_MTIME) |
334 | inode->i_mtime = fattr->mtime; | 342 | inode->i_mtime = fattr->mtime; |
343 | else if (nfs_server_capable(inode, NFS_CAP_MTIME)) | ||
344 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR | ||
345 | | NFS_INO_INVALID_DATA; | ||
335 | if (fattr->valid & NFS_ATTR_FATTR_CTIME) | 346 | if (fattr->valid & NFS_ATTR_FATTR_CTIME) |
336 | inode->i_ctime = fattr->ctime; | 347 | inode->i_ctime = fattr->ctime; |
348 | else if (nfs_server_capable(inode, NFS_CAP_CTIME)) | ||
349 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR | ||
350 | | NFS_INO_INVALID_ACCESS | ||
351 | | NFS_INO_INVALID_ACL; | ||
337 | if (fattr->valid & NFS_ATTR_FATTR_CHANGE) | 352 | if (fattr->valid & NFS_ATTR_FATTR_CHANGE) |
338 | nfsi->change_attr = fattr->change_attr; | 353 | nfsi->change_attr = fattr->change_attr; |
354 | else if (nfs_server_capable(inode, NFS_CAP_CHANGE_ATTR)) | ||
355 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR | ||
356 | | NFS_INO_INVALID_DATA; | ||
339 | if (fattr->valid & NFS_ATTR_FATTR_SIZE) | 357 | if (fattr->valid & NFS_ATTR_FATTR_SIZE) |
340 | inode->i_size = nfs_size_to_loff_t(fattr->size); | 358 | inode->i_size = nfs_size_to_loff_t(fattr->size); |
359 | else | ||
360 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR | ||
361 | | NFS_INO_INVALID_DATA | ||
362 | | NFS_INO_REVAL_PAGECACHE; | ||
341 | if (fattr->valid & NFS_ATTR_FATTR_NLINK) | 363 | if (fattr->valid & NFS_ATTR_FATTR_NLINK) |
342 | inode->i_nlink = fattr->nlink; | 364 | inode->i_nlink = fattr->nlink; |
365 | else if (nfs_server_capable(inode, NFS_CAP_NLINK)) | ||
366 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | ||
343 | if (fattr->valid & NFS_ATTR_FATTR_OWNER) | 367 | if (fattr->valid & NFS_ATTR_FATTR_OWNER) |
344 | inode->i_uid = fattr->uid; | 368 | inode->i_uid = fattr->uid; |
369 | else if (nfs_server_capable(inode, NFS_CAP_OWNER)) | ||
370 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR | ||
371 | | NFS_INO_INVALID_ACCESS | ||
372 | | NFS_INO_INVALID_ACL; | ||
345 | if (fattr->valid & NFS_ATTR_FATTR_GROUP) | 373 | if (fattr->valid & NFS_ATTR_FATTR_GROUP) |
346 | inode->i_gid = fattr->gid; | 374 | inode->i_gid = fattr->gid; |
375 | else if (nfs_server_capable(inode, NFS_CAP_OWNER_GROUP)) | ||
376 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR | ||
377 | | NFS_INO_INVALID_ACCESS | ||
378 | | NFS_INO_INVALID_ACL; | ||
347 | if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED) | 379 | if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED) |
348 | inode->i_blocks = fattr->du.nfs2.blocks; | 380 | inode->i_blocks = fattr->du.nfs2.blocks; |
349 | if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) { | 381 | if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) { |
@@ -1145,6 +1177,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1145 | loff_t cur_isize, new_isize; | 1177 | loff_t cur_isize, new_isize; |
1146 | unsigned long invalid = 0; | 1178 | unsigned long invalid = 0; |
1147 | unsigned long now = jiffies; | 1179 | unsigned long now = jiffies; |
1180 | unsigned long save_cache_validity; | ||
1148 | 1181 | ||
1149 | dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n", | 1182 | dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n", |
1150 | __func__, inode->i_sb->s_id, inode->i_ino, | 1183 | __func__, inode->i_sb->s_id, inode->i_ino, |
@@ -1171,10 +1204,11 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1171 | */ | 1204 | */ |
1172 | nfsi->read_cache_jiffies = fattr->time_start; | 1205 | nfsi->read_cache_jiffies = fattr->time_start; |
1173 | 1206 | ||
1174 | if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) || (fattr->valid & (NFS_ATTR_FATTR_MTIME|NFS_ATTR_FATTR_CTIME))) | 1207 | save_cache_validity = nfsi->cache_validity; |
1175 | nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR | 1208 | nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR |
1176 | | NFS_INO_INVALID_ATIME | 1209 | | NFS_INO_INVALID_ATIME |
1177 | | NFS_INO_REVAL_PAGECACHE); | 1210 | | NFS_INO_REVAL_FORCED |
1211 | | NFS_INO_REVAL_PAGECACHE); | ||
1178 | 1212 | ||
1179 | /* Do atomic weak cache consistency updates */ | 1213 | /* Do atomic weak cache consistency updates */ |
1180 | nfs_wcc_update_inode(inode, fattr); | 1214 | nfs_wcc_update_inode(inode, fattr); |
@@ -1189,7 +1223,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1189 | nfs_force_lookup_revalidate(inode); | 1223 | nfs_force_lookup_revalidate(inode); |
1190 | nfsi->change_attr = fattr->change_attr; | 1224 | nfsi->change_attr = fattr->change_attr; |
1191 | } | 1225 | } |
1192 | } | 1226 | } else if (server->caps & NFS_CAP_CHANGE_ATTR) |
1227 | invalid |= save_cache_validity; | ||
1193 | 1228 | ||
1194 | if (fattr->valid & NFS_ATTR_FATTR_MTIME) { | 1229 | if (fattr->valid & NFS_ATTR_FATTR_MTIME) { |
1195 | /* NFSv2/v3: Check if the mtime agrees */ | 1230 | /* NFSv2/v3: Check if the mtime agrees */ |
@@ -1201,7 +1236,12 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1201 | nfs_force_lookup_revalidate(inode); | 1236 | nfs_force_lookup_revalidate(inode); |
1202 | memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); | 1237 | memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); |
1203 | } | 1238 | } |
1204 | } | 1239 | } else if (server->caps & NFS_CAP_MTIME) |
1240 | invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR | ||
1241 | | NFS_INO_INVALID_DATA | ||
1242 | | NFS_INO_REVAL_PAGECACHE | ||
1243 | | NFS_INO_REVAL_FORCED); | ||
1244 | |||
1205 | if (fattr->valid & NFS_ATTR_FATTR_CTIME) { | 1245 | if (fattr->valid & NFS_ATTR_FATTR_CTIME) { |
1206 | /* If ctime has changed we should definitely clear access+acl caches */ | 1246 | /* If ctime has changed we should definitely clear access+acl caches */ |
1207 | if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) { | 1247 | if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) { |
@@ -1215,7 +1255,11 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1215 | } | 1255 | } |
1216 | memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); | 1256 | memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); |
1217 | } | 1257 | } |
1218 | } | 1258 | } else if (server->caps & NFS_CAP_CTIME) |
1259 | invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR | ||
1260 | | NFS_INO_INVALID_ACCESS | ||
1261 | | NFS_INO_INVALID_ACL | ||
1262 | | NFS_INO_REVAL_FORCED); | ||
1219 | 1263 | ||
1220 | /* Check if our cached file size is stale */ | 1264 | /* Check if our cached file size is stale */ |
1221 | if (fattr->valid & NFS_ATTR_FATTR_SIZE) { | 1265 | if (fattr->valid & NFS_ATTR_FATTR_SIZE) { |
@@ -1231,30 +1275,50 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1231 | dprintk("NFS: isize change on server for file %s/%ld\n", | 1275 | dprintk("NFS: isize change on server for file %s/%ld\n", |
1232 | inode->i_sb->s_id, inode->i_ino); | 1276 | inode->i_sb->s_id, inode->i_ino); |
1233 | } | 1277 | } |
1234 | } | 1278 | } else |
1279 | invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR | ||
1280 | | NFS_INO_REVAL_PAGECACHE | ||
1281 | | NFS_INO_REVAL_FORCED); | ||
1235 | 1282 | ||
1236 | 1283 | ||
1237 | if (fattr->valid & NFS_ATTR_FATTR_ATIME) | 1284 | if (fattr->valid & NFS_ATTR_FATTR_ATIME) |
1238 | memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime)); | 1285 | memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime)); |
1286 | else if (server->caps & NFS_CAP_ATIME) | ||
1287 | invalid |= save_cache_validity & (NFS_INO_INVALID_ATIME | ||
1288 | | NFS_INO_REVAL_FORCED); | ||
1239 | 1289 | ||
1240 | if (fattr->valid & NFS_ATTR_FATTR_MODE) { | 1290 | if (fattr->valid & NFS_ATTR_FATTR_MODE) { |
1241 | if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)) { | 1291 | if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)) { |
1242 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; | 1292 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; |
1243 | inode->i_mode = fattr->mode; | 1293 | inode->i_mode = fattr->mode; |
1244 | } | 1294 | } |
1245 | } | 1295 | } else if (server->caps & NFS_CAP_MODE) |
1296 | invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR | ||
1297 | | NFS_INO_INVALID_ACCESS | ||
1298 | | NFS_INO_INVALID_ACL | ||
1299 | | NFS_INO_REVAL_FORCED); | ||
1300 | |||
1246 | if (fattr->valid & NFS_ATTR_FATTR_OWNER) { | 1301 | if (fattr->valid & NFS_ATTR_FATTR_OWNER) { |
1247 | if (inode->i_uid != fattr->uid) { | 1302 | if (inode->i_uid != fattr->uid) { |
1248 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; | 1303 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; |
1249 | inode->i_uid = fattr->uid; | 1304 | inode->i_uid = fattr->uid; |
1250 | } | 1305 | } |
1251 | } | 1306 | } else if (server->caps & NFS_CAP_OWNER) |
1307 | invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR | ||
1308 | | NFS_INO_INVALID_ACCESS | ||
1309 | | NFS_INO_INVALID_ACL | ||
1310 | | NFS_INO_REVAL_FORCED); | ||
1311 | |||
1252 | if (fattr->valid & NFS_ATTR_FATTR_GROUP) { | 1312 | if (fattr->valid & NFS_ATTR_FATTR_GROUP) { |
1253 | if (inode->i_gid != fattr->gid) { | 1313 | if (inode->i_gid != fattr->gid) { |
1254 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; | 1314 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; |
1255 | inode->i_gid = fattr->gid; | 1315 | inode->i_gid = fattr->gid; |
1256 | } | 1316 | } |
1257 | } | 1317 | } else if (server->caps & NFS_CAP_OWNER_GROUP) |
1318 | invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR | ||
1319 | | NFS_INO_INVALID_ACCESS | ||
1320 | | NFS_INO_INVALID_ACL | ||
1321 | | NFS_INO_REVAL_FORCED); | ||
1258 | 1322 | ||
1259 | if (fattr->valid & NFS_ATTR_FATTR_NLINK) { | 1323 | if (fattr->valid & NFS_ATTR_FATTR_NLINK) { |
1260 | if (inode->i_nlink != fattr->nlink) { | 1324 | if (inode->i_nlink != fattr->nlink) { |
@@ -1263,7 +1327,9 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1263 | invalid |= NFS_INO_INVALID_DATA; | 1327 | invalid |= NFS_INO_INVALID_DATA; |
1264 | inode->i_nlink = fattr->nlink; | 1328 | inode->i_nlink = fattr->nlink; |
1265 | } | 1329 | } |
1266 | } | 1330 | } else if (server->caps & NFS_CAP_NLINK) |
1331 | invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR | ||
1332 | | NFS_INO_REVAL_FORCED); | ||
1267 | 1333 | ||
1268 | if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) { | 1334 | if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) { |
1269 | /* | 1335 | /* |
@@ -1293,9 +1359,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1293 | || S_ISLNK(inode->i_mode))) | 1359 | || S_ISLNK(inode->i_mode))) |
1294 | invalid &= ~NFS_INO_INVALID_DATA; | 1360 | invalid &= ~NFS_INO_INVALID_DATA; |
1295 | if (!nfs_have_delegation(inode, FMODE_READ) || | 1361 | if (!nfs_have_delegation(inode, FMODE_READ) || |
1296 | (nfsi->cache_validity & NFS_INO_REVAL_FORCED)) | 1362 | (save_cache_validity & NFS_INO_REVAL_FORCED)) |
1297 | nfsi->cache_validity |= invalid; | 1363 | nfsi->cache_validity |= invalid; |
1298 | nfsi->cache_validity &= ~NFS_INO_REVAL_FORCED; | ||
1299 | 1364 | ||
1300 | return 0; | 1365 | return 0; |
1301 | out_changed: | 1366 | out_changed: |
@@ -1442,6 +1507,10 @@ static int __init init_nfs_fs(void) | |||
1442 | { | 1507 | { |
1443 | int err; | 1508 | int err; |
1444 | 1509 | ||
1510 | err = nfs_dns_resolver_init(); | ||
1511 | if (err < 0) | ||
1512 | goto out8; | ||
1513 | |||
1445 | err = nfs_fscache_register(); | 1514 | err = nfs_fscache_register(); |
1446 | if (err < 0) | 1515 | if (err < 0) |
1447 | goto out7; | 1516 | goto out7; |
@@ -1500,6 +1569,8 @@ out5: | |||
1500 | out6: | 1569 | out6: |
1501 | nfs_fscache_unregister(); | 1570 | nfs_fscache_unregister(); |
1502 | out7: | 1571 | out7: |
1572 | nfs_dns_resolver_destroy(); | ||
1573 | out8: | ||
1503 | return err; | 1574 | return err; |
1504 | } | 1575 | } |
1505 | 1576 | ||
@@ -1511,6 +1582,7 @@ static void __exit exit_nfs_fs(void) | |||
1511 | nfs_destroy_inodecache(); | 1582 | nfs_destroy_inodecache(); |
1512 | nfs_destroy_nfspagecache(); | 1583 | nfs_destroy_nfspagecache(); |
1513 | nfs_fscache_unregister(); | 1584 | nfs_fscache_unregister(); |
1585 | nfs_dns_resolver_destroy(); | ||
1514 | #ifdef CONFIG_PROC_FS | 1586 | #ifdef CONFIG_PROC_FS |
1515 | rpc_proc_unregister("nfs"); | 1587 | rpc_proc_unregister("nfs"); |
1516 | #endif | 1588 | #endif |