diff options
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r-- | fs/nfs/inode.c | 154 |
1 files changed, 99 insertions, 55 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index bd7938eda6a8..faa091865ad0 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) { |
@@ -426,49 +458,21 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
426 | */ | 458 | */ |
427 | static int nfs_vmtruncate(struct inode * inode, loff_t offset) | 459 | static int nfs_vmtruncate(struct inode * inode, loff_t offset) |
428 | { | 460 | { |
429 | if (i_size_read(inode) < offset) { | 461 | loff_t oldsize; |
430 | unsigned long limit; | 462 | int err; |
431 | |||
432 | limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; | ||
433 | if (limit != RLIM_INFINITY && offset > limit) | ||
434 | goto out_sig; | ||
435 | if (offset > inode->i_sb->s_maxbytes) | ||
436 | goto out_big; | ||
437 | spin_lock(&inode->i_lock); | ||
438 | i_size_write(inode, offset); | ||
439 | spin_unlock(&inode->i_lock); | ||
440 | } else { | ||
441 | struct address_space *mapping = inode->i_mapping; | ||
442 | 463 | ||
443 | /* | 464 | err = inode_newsize_ok(inode, offset); |
444 | * truncation of in-use swapfiles is disallowed - it would | 465 | if (err) |
445 | * cause subsequent swapout to scribble on the now-freed | 466 | goto out; |
446 | * blocks. | ||
447 | */ | ||
448 | if (IS_SWAPFILE(inode)) | ||
449 | return -ETXTBSY; | ||
450 | spin_lock(&inode->i_lock); | ||
451 | i_size_write(inode, offset); | ||
452 | spin_unlock(&inode->i_lock); | ||
453 | 467 | ||
454 | /* | 468 | spin_lock(&inode->i_lock); |
455 | * unmap_mapping_range is called twice, first simply for | 469 | oldsize = inode->i_size; |
456 | * efficiency so that truncate_inode_pages does fewer | 470 | i_size_write(inode, offset); |
457 | * single-page unmaps. However after this first call, and | 471 | spin_unlock(&inode->i_lock); |
458 | * before truncate_inode_pages finishes, it is possible for | 472 | |
459 | * private pages to be COWed, which remain after | 473 | truncate_pagecache(inode, oldsize, offset); |
460 | * truncate_inode_pages finishes, hence the second | 474 | out: |
461 | * unmap_mapping_range call must be made for correctness. | 475 | return err; |
462 | */ | ||
463 | unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); | ||
464 | truncate_inode_pages(mapping, offset); | ||
465 | unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); | ||
466 | } | ||
467 | return 0; | ||
468 | out_sig: | ||
469 | send_sig(SIGXFSZ, current, 0); | ||
470 | out_big: | ||
471 | return -EFBIG; | ||
472 | } | 476 | } |
473 | 477 | ||
474 | /** | 478 | /** |
@@ -1145,6 +1149,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1145 | loff_t cur_isize, new_isize; | 1149 | loff_t cur_isize, new_isize; |
1146 | unsigned long invalid = 0; | 1150 | unsigned long invalid = 0; |
1147 | unsigned long now = jiffies; | 1151 | unsigned long now = jiffies; |
1152 | unsigned long save_cache_validity; | ||
1148 | 1153 | ||
1149 | dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n", | 1154 | dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n", |
1150 | __func__, inode->i_sb->s_id, inode->i_ino, | 1155 | __func__, inode->i_sb->s_id, inode->i_ino, |
@@ -1171,10 +1176,11 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1171 | */ | 1176 | */ |
1172 | nfsi->read_cache_jiffies = fattr->time_start; | 1177 | nfsi->read_cache_jiffies = fattr->time_start; |
1173 | 1178 | ||
1174 | if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) || (fattr->valid & (NFS_ATTR_FATTR_MTIME|NFS_ATTR_FATTR_CTIME))) | 1179 | save_cache_validity = nfsi->cache_validity; |
1175 | nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR | 1180 | nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR |
1176 | | NFS_INO_INVALID_ATIME | 1181 | | NFS_INO_INVALID_ATIME |
1177 | | NFS_INO_REVAL_PAGECACHE); | 1182 | | NFS_INO_REVAL_FORCED |
1183 | | NFS_INO_REVAL_PAGECACHE); | ||
1178 | 1184 | ||
1179 | /* Do atomic weak cache consistency updates */ | 1185 | /* Do atomic weak cache consistency updates */ |
1180 | nfs_wcc_update_inode(inode, fattr); | 1186 | nfs_wcc_update_inode(inode, fattr); |
@@ -1189,7 +1195,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1189 | nfs_force_lookup_revalidate(inode); | 1195 | nfs_force_lookup_revalidate(inode); |
1190 | nfsi->change_attr = fattr->change_attr; | 1196 | nfsi->change_attr = fattr->change_attr; |
1191 | } | 1197 | } |
1192 | } | 1198 | } else if (server->caps & NFS_CAP_CHANGE_ATTR) |
1199 | invalid |= save_cache_validity; | ||
1193 | 1200 | ||
1194 | if (fattr->valid & NFS_ATTR_FATTR_MTIME) { | 1201 | if (fattr->valid & NFS_ATTR_FATTR_MTIME) { |
1195 | /* NFSv2/v3: Check if the mtime agrees */ | 1202 | /* NFSv2/v3: Check if the mtime agrees */ |
@@ -1201,7 +1208,12 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1201 | nfs_force_lookup_revalidate(inode); | 1208 | nfs_force_lookup_revalidate(inode); |
1202 | memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); | 1209 | memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); |
1203 | } | 1210 | } |
1204 | } | 1211 | } else if (server->caps & NFS_CAP_MTIME) |
1212 | invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR | ||
1213 | | NFS_INO_INVALID_DATA | ||
1214 | | NFS_INO_REVAL_PAGECACHE | ||
1215 | | NFS_INO_REVAL_FORCED); | ||
1216 | |||
1205 | if (fattr->valid & NFS_ATTR_FATTR_CTIME) { | 1217 | if (fattr->valid & NFS_ATTR_FATTR_CTIME) { |
1206 | /* If ctime has changed we should definitely clear access+acl caches */ | 1218 | /* If ctime has changed we should definitely clear access+acl caches */ |
1207 | if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) { | 1219 | if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) { |
@@ -1215,7 +1227,11 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1215 | } | 1227 | } |
1216 | memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); | 1228 | memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); |
1217 | } | 1229 | } |
1218 | } | 1230 | } else if (server->caps & NFS_CAP_CTIME) |
1231 | invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR | ||
1232 | | NFS_INO_INVALID_ACCESS | ||
1233 | | NFS_INO_INVALID_ACL | ||
1234 | | NFS_INO_REVAL_FORCED); | ||
1219 | 1235 | ||
1220 | /* Check if our cached file size is stale */ | 1236 | /* Check if our cached file size is stale */ |
1221 | if (fattr->valid & NFS_ATTR_FATTR_SIZE) { | 1237 | if (fattr->valid & NFS_ATTR_FATTR_SIZE) { |
@@ -1231,30 +1247,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", | 1247 | dprintk("NFS: isize change on server for file %s/%ld\n", |
1232 | inode->i_sb->s_id, inode->i_ino); | 1248 | inode->i_sb->s_id, inode->i_ino); |
1233 | } | 1249 | } |
1234 | } | 1250 | } else |
1251 | invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR | ||
1252 | | NFS_INO_REVAL_PAGECACHE | ||
1253 | | NFS_INO_REVAL_FORCED); | ||
1235 | 1254 | ||
1236 | 1255 | ||
1237 | if (fattr->valid & NFS_ATTR_FATTR_ATIME) | 1256 | if (fattr->valid & NFS_ATTR_FATTR_ATIME) |
1238 | memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime)); | 1257 | memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime)); |
1258 | else if (server->caps & NFS_CAP_ATIME) | ||
1259 | invalid |= save_cache_validity & (NFS_INO_INVALID_ATIME | ||
1260 | | NFS_INO_REVAL_FORCED); | ||
1239 | 1261 | ||
1240 | if (fattr->valid & NFS_ATTR_FATTR_MODE) { | 1262 | if (fattr->valid & NFS_ATTR_FATTR_MODE) { |
1241 | if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)) { | 1263 | if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)) { |
1242 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; | 1264 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; |
1243 | inode->i_mode = fattr->mode; | 1265 | inode->i_mode = fattr->mode; |
1244 | } | 1266 | } |
1245 | } | 1267 | } else if (server->caps & NFS_CAP_MODE) |
1268 | invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR | ||
1269 | | NFS_INO_INVALID_ACCESS | ||
1270 | | NFS_INO_INVALID_ACL | ||
1271 | | NFS_INO_REVAL_FORCED); | ||
1272 | |||
1246 | if (fattr->valid & NFS_ATTR_FATTR_OWNER) { | 1273 | if (fattr->valid & NFS_ATTR_FATTR_OWNER) { |
1247 | if (inode->i_uid != fattr->uid) { | 1274 | if (inode->i_uid != fattr->uid) { |
1248 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; | 1275 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; |
1249 | inode->i_uid = fattr->uid; | 1276 | inode->i_uid = fattr->uid; |
1250 | } | 1277 | } |
1251 | } | 1278 | } else if (server->caps & NFS_CAP_OWNER) |
1279 | invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR | ||
1280 | | NFS_INO_INVALID_ACCESS | ||
1281 | | NFS_INO_INVALID_ACL | ||
1282 | | NFS_INO_REVAL_FORCED); | ||
1283 | |||
1252 | if (fattr->valid & NFS_ATTR_FATTR_GROUP) { | 1284 | if (fattr->valid & NFS_ATTR_FATTR_GROUP) { |
1253 | if (inode->i_gid != fattr->gid) { | 1285 | if (inode->i_gid != fattr->gid) { |
1254 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; | 1286 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; |
1255 | inode->i_gid = fattr->gid; | 1287 | inode->i_gid = fattr->gid; |
1256 | } | 1288 | } |
1257 | } | 1289 | } else if (server->caps & NFS_CAP_OWNER_GROUP) |
1290 | invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR | ||
1291 | | NFS_INO_INVALID_ACCESS | ||
1292 | | NFS_INO_INVALID_ACL | ||
1293 | | NFS_INO_REVAL_FORCED); | ||
1258 | 1294 | ||
1259 | if (fattr->valid & NFS_ATTR_FATTR_NLINK) { | 1295 | if (fattr->valid & NFS_ATTR_FATTR_NLINK) { |
1260 | if (inode->i_nlink != fattr->nlink) { | 1296 | if (inode->i_nlink != fattr->nlink) { |
@@ -1263,7 +1299,9 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1263 | invalid |= NFS_INO_INVALID_DATA; | 1299 | invalid |= NFS_INO_INVALID_DATA; |
1264 | inode->i_nlink = fattr->nlink; | 1300 | inode->i_nlink = fattr->nlink; |
1265 | } | 1301 | } |
1266 | } | 1302 | } else if (server->caps & NFS_CAP_NLINK) |
1303 | invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR | ||
1304 | | NFS_INO_REVAL_FORCED); | ||
1267 | 1305 | ||
1268 | if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) { | 1306 | if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) { |
1269 | /* | 1307 | /* |
@@ -1293,9 +1331,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1293 | || S_ISLNK(inode->i_mode))) | 1331 | || S_ISLNK(inode->i_mode))) |
1294 | invalid &= ~NFS_INO_INVALID_DATA; | 1332 | invalid &= ~NFS_INO_INVALID_DATA; |
1295 | if (!nfs_have_delegation(inode, FMODE_READ) || | 1333 | if (!nfs_have_delegation(inode, FMODE_READ) || |
1296 | (nfsi->cache_validity & NFS_INO_REVAL_FORCED)) | 1334 | (save_cache_validity & NFS_INO_REVAL_FORCED)) |
1297 | nfsi->cache_validity |= invalid; | 1335 | nfsi->cache_validity |= invalid; |
1298 | nfsi->cache_validity &= ~NFS_INO_REVAL_FORCED; | ||
1299 | 1336 | ||
1300 | return 0; | 1337 | return 0; |
1301 | out_changed: | 1338 | out_changed: |
@@ -1442,6 +1479,10 @@ static int __init init_nfs_fs(void) | |||
1442 | { | 1479 | { |
1443 | int err; | 1480 | int err; |
1444 | 1481 | ||
1482 | err = nfs_dns_resolver_init(); | ||
1483 | if (err < 0) | ||
1484 | goto out8; | ||
1485 | |||
1445 | err = nfs_fscache_register(); | 1486 | err = nfs_fscache_register(); |
1446 | if (err < 0) | 1487 | if (err < 0) |
1447 | goto out7; | 1488 | goto out7; |
@@ -1500,6 +1541,8 @@ out5: | |||
1500 | out6: | 1541 | out6: |
1501 | nfs_fscache_unregister(); | 1542 | nfs_fscache_unregister(); |
1502 | out7: | 1543 | out7: |
1544 | nfs_dns_resolver_destroy(); | ||
1545 | out8: | ||
1503 | return err; | 1546 | return err; |
1504 | } | 1547 | } |
1505 | 1548 | ||
@@ -1511,6 +1554,7 @@ static void __exit exit_nfs_fs(void) | |||
1511 | nfs_destroy_inodecache(); | 1554 | nfs_destroy_inodecache(); |
1512 | nfs_destroy_nfspagecache(); | 1555 | nfs_destroy_nfspagecache(); |
1513 | nfs_fscache_unregister(); | 1556 | nfs_fscache_unregister(); |
1557 | nfs_dns_resolver_destroy(); | ||
1514 | #ifdef CONFIG_PROC_FS | 1558 | #ifdef CONFIG_PROC_FS |
1515 | rpc_proc_unregister("nfs"); | 1559 | rpc_proc_unregister("nfs"); |
1516 | #endif | 1560 | #endif |