aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/dir.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2013-07-12 06:34:42 -0400
committerThomas Gleixner <tglx@linutronix.de>2013-07-12 06:34:42 -0400
commitf2006e27396f55276f24434f56e208d86e7f9908 (patch)
tree71896db916d33888b4286f80117d3cac0da40e6d /fs/nfs/dir.c
parente399eb56a6110e13f97e644658648602e2b08de7 (diff)
parent9903883f1dd6e86f286b7bfa6e4b423f98c1cd9e (diff)
Merge branch 'linus' into timers/urgent
Get upstream changes so we can apply fixes against them Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r--fs/nfs/dir.c94
1 files changed, 51 insertions, 43 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 5d051419527b..e474ca2b2bfe 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -33,6 +33,7 @@
33#include <linux/pagevec.h> 33#include <linux/pagevec.h>
34#include <linux/namei.h> 34#include <linux/namei.h>
35#include <linux/mount.h> 35#include <linux/mount.h>
36#include <linux/swap.h>
36#include <linux/sched.h> 37#include <linux/sched.h>
37#include <linux/kmemleak.h> 38#include <linux/kmemleak.h>
38#include <linux/xattr.h> 39#include <linux/xattr.h>
@@ -436,6 +437,7 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry)
436 struct dentry *alias; 437 struct dentry *alias;
437 struct inode *dir = parent->d_inode; 438 struct inode *dir = parent->d_inode;
438 struct inode *inode; 439 struct inode *inode;
440 int status;
439 441
440 if (filename.name[0] == '.') { 442 if (filename.name[0] == '.') {
441 if (filename.len == 1) 443 if (filename.len == 1)
@@ -448,7 +450,10 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry)
448 dentry = d_lookup(parent, &filename); 450 dentry = d_lookup(parent, &filename);
449 if (dentry != NULL) { 451 if (dentry != NULL) {
450 if (nfs_same_file(dentry, entry)) { 452 if (nfs_same_file(dentry, entry)) {
451 nfs_refresh_inode(dentry->d_inode, entry->fattr); 453 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
454 status = nfs_refresh_inode(dentry->d_inode, entry->fattr);
455 if (!status)
456 nfs_setsecurity(dentry->d_inode, entry->fattr, entry->label);
452 goto out; 457 goto out;
453 } else { 458 } else {
454 if (d_invalidate(dentry) != 0) 459 if (d_invalidate(dentry) != 0)
@@ -461,7 +466,7 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry)
461 if (dentry == NULL) 466 if (dentry == NULL)
462 return; 467 return;
463 468
464 inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr); 469 inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr, entry->label);
465 if (IS_ERR(inode)) 470 if (IS_ERR(inode))
466 goto out; 471 goto out;
467 472
@@ -586,10 +591,16 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,
586 if (entry.fh == NULL || entry.fattr == NULL) 591 if (entry.fh == NULL || entry.fattr == NULL)
587 goto out; 592 goto out;
588 593
594 entry.label = nfs4_label_alloc(NFS_SERVER(inode), GFP_NOWAIT);
595 if (IS_ERR(entry.label)) {
596 status = PTR_ERR(entry.label);
597 goto out;
598 }
599
589 array = nfs_readdir_get_array(page); 600 array = nfs_readdir_get_array(page);
590 if (IS_ERR(array)) { 601 if (IS_ERR(array)) {
591 status = PTR_ERR(array); 602 status = PTR_ERR(array);
592 goto out; 603 goto out_label_free;
593 } 604 }
594 memset(array, 0, sizeof(struct nfs_cache_array)); 605 memset(array, 0, sizeof(struct nfs_cache_array));
595 array->eof_index = -1; 606 array->eof_index = -1;
@@ -615,6 +626,8 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,
615 nfs_readdir_free_large_page(pages_ptr, pages, array_size); 626 nfs_readdir_free_large_page(pages_ptr, pages, array_size);
616out_release_array: 627out_release_array:
617 nfs_readdir_release_array(page); 628 nfs_readdir_release_array(page);
629out_label_free:
630 nfs4_label_free(entry.label);
618out: 631out:
619 nfs_free_fattr(entry.fattr); 632 nfs_free_fattr(entry.fattr);
620 nfs_free_fhandle(entry.fh); 633 nfs_free_fhandle(entry.fh);
@@ -805,7 +818,7 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
805 nfs_readdir_descriptor_t my_desc, 818 nfs_readdir_descriptor_t my_desc,
806 *desc = &my_desc; 819 *desc = &my_desc;
807 struct nfs_open_dir_context *dir_ctx = file->private_data; 820 struct nfs_open_dir_context *dir_ctx = file->private_data;
808 int res; 821 int res = 0;
809 822
810 dfprintk(FILE, "NFS: readdir(%s/%s) starting at cookie %llu\n", 823 dfprintk(FILE, "NFS: readdir(%s/%s) starting at cookie %llu\n",
811 dentry->d_parent->d_name.name, dentry->d_name.name, 824 dentry->d_parent->d_name.name, dentry->d_name.name,
@@ -827,7 +840,8 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
827 desc->plus = nfs_use_readdirplus(inode, ctx) ? 1 : 0; 840 desc->plus = nfs_use_readdirplus(inode, ctx) ? 1 : 0;
828 841
829 nfs_block_sillyrename(dentry); 842 nfs_block_sillyrename(dentry);
830 res = nfs_revalidate_mapping(inode, file->f_mapping); 843 if (ctx->pos == 0 || nfs_attribute_cache_expired(inode))
844 res = nfs_revalidate_mapping(inode, file->f_mapping);
831 if (res < 0) 845 if (res < 0)
832 goto out; 846 goto out;
833 847
@@ -1039,6 +1053,7 @@ static int nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
1039 struct dentry *parent; 1053 struct dentry *parent;
1040 struct nfs_fh *fhandle = NULL; 1054 struct nfs_fh *fhandle = NULL;
1041 struct nfs_fattr *fattr = NULL; 1055 struct nfs_fattr *fattr = NULL;
1056 struct nfs4_label *label = NULL;
1042 int error; 1057 int error;
1043 1058
1044 if (flags & LOOKUP_RCU) 1059 if (flags & LOOKUP_RCU)
@@ -1081,7 +1096,11 @@ static int nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
1081 if (fhandle == NULL || fattr == NULL) 1096 if (fhandle == NULL || fattr == NULL)
1082 goto out_error; 1097 goto out_error;
1083 1098
1084 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr); 1099 label = nfs4_label_alloc(NFS_SERVER(inode), GFP_NOWAIT);
1100 if (IS_ERR(label))
1101 goto out_error;
1102
1103 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, label);
1085 if (error) 1104 if (error)
1086 goto out_bad; 1105 goto out_bad;
1087 if (nfs_compare_fh(NFS_FH(inode), fhandle)) 1106 if (nfs_compare_fh(NFS_FH(inode), fhandle))
@@ -1089,8 +1108,12 @@ static int nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
1089 if ((error = nfs_refresh_inode(inode, fattr)) != 0) 1108 if ((error = nfs_refresh_inode(inode, fattr)) != 0)
1090 goto out_bad; 1109 goto out_bad;
1091 1110
1111 nfs_setsecurity(inode, fattr, label);
1112
1092 nfs_free_fattr(fattr); 1113 nfs_free_fattr(fattr);
1093 nfs_free_fhandle(fhandle); 1114 nfs_free_fhandle(fhandle);
1115 nfs4_label_free(label);
1116
1094out_set_verifier: 1117out_set_verifier:
1095 nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 1118 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
1096 out_valid: 1119 out_valid:
@@ -1107,6 +1130,7 @@ out_zap_parent:
1107 out_bad: 1130 out_bad:
1108 nfs_free_fattr(fattr); 1131 nfs_free_fattr(fattr);
1109 nfs_free_fhandle(fhandle); 1132 nfs_free_fhandle(fhandle);
1133 nfs4_label_free(label);
1110 nfs_mark_for_revalidate(dir); 1134 nfs_mark_for_revalidate(dir);
1111 if (inode && S_ISDIR(inode->i_mode)) { 1135 if (inode && S_ISDIR(inode->i_mode)) {
1112 /* Purge readdir caches. */ 1136 /* Purge readdir caches. */
@@ -1127,6 +1151,7 @@ out_zap_parent:
1127out_error: 1151out_error:
1128 nfs_free_fattr(fattr); 1152 nfs_free_fattr(fattr);
1129 nfs_free_fhandle(fhandle); 1153 nfs_free_fhandle(fhandle);
1154 nfs4_label_free(label);
1130 dput(parent); 1155 dput(parent);
1131 dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) lookup returned error %d\n", 1156 dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) lookup returned error %d\n",
1132 __func__, dentry->d_parent->d_name.name, 1157 __func__, dentry->d_parent->d_name.name,
@@ -1255,6 +1280,7 @@ struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, unsigned in
1255 struct inode *inode = NULL; 1280 struct inode *inode = NULL;
1256 struct nfs_fh *fhandle = NULL; 1281 struct nfs_fh *fhandle = NULL;
1257 struct nfs_fattr *fattr = NULL; 1282 struct nfs_fattr *fattr = NULL;
1283 struct nfs4_label *label = NULL;
1258 int error; 1284 int error;
1259 1285
1260 dfprintk(VFS, "NFS: lookup(%s/%s)\n", 1286 dfprintk(VFS, "NFS: lookup(%s/%s)\n",
@@ -1281,17 +1307,21 @@ struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, unsigned in
1281 if (fhandle == NULL || fattr == NULL) 1307 if (fhandle == NULL || fattr == NULL)
1282 goto out; 1308 goto out;
1283 1309
1310 label = nfs4_label_alloc(NFS_SERVER(dir), GFP_NOWAIT);
1311 if (IS_ERR(label))
1312 goto out;
1313
1284 parent = dentry->d_parent; 1314 parent = dentry->d_parent;
1285 /* Protect against concurrent sillydeletes */ 1315 /* Protect against concurrent sillydeletes */
1286 nfs_block_sillyrename(parent); 1316 nfs_block_sillyrename(parent);
1287 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr); 1317 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, label);
1288 if (error == -ENOENT) 1318 if (error == -ENOENT)
1289 goto no_entry; 1319 goto no_entry;
1290 if (error < 0) { 1320 if (error < 0) {
1291 res = ERR_PTR(error); 1321 res = ERR_PTR(error);
1292 goto out_unblock_sillyrename; 1322 goto out_unblock_sillyrename;
1293 } 1323 }
1294 inode = nfs_fhget(dentry->d_sb, fhandle, fattr); 1324 inode = nfs_fhget(dentry->d_sb, fhandle, fattr, label);
1295 res = ERR_CAST(inode); 1325 res = ERR_CAST(inode);
1296 if (IS_ERR(res)) 1326 if (IS_ERR(res))
1297 goto out_unblock_sillyrename; 1327 goto out_unblock_sillyrename;
@@ -1309,6 +1339,7 @@ no_entry:
1309 nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 1339 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
1310out_unblock_sillyrename: 1340out_unblock_sillyrename:
1311 nfs_unblock_sillyrename(parent); 1341 nfs_unblock_sillyrename(parent);
1342 nfs4_label_free(label);
1312out: 1343out:
1313 nfs_free_fattr(fattr); 1344 nfs_free_fattr(fattr);
1314 nfs_free_fhandle(fhandle); 1345 nfs_free_fhandle(fhandle);
@@ -1356,18 +1387,6 @@ static int nfs_finish_open(struct nfs_open_context *ctx,
1356{ 1387{
1357 int err; 1388 int err;
1358 1389
1359 if (ctx->dentry != dentry) {
1360 dput(ctx->dentry);
1361 ctx->dentry = dget(dentry);
1362 }
1363
1364 /* If the open_intent is for execute, we have an extra check to make */
1365 if (ctx->mode & FMODE_EXEC) {
1366 err = nfs_may_open(dentry->d_inode, ctx->cred, open_flags);
1367 if (err < 0)
1368 goto out;
1369 }
1370
1371 err = finish_open(file, dentry, do_open, opened); 1390 err = finish_open(file, dentry, do_open, opened);
1372 if (err) 1391 if (err)
1373 goto out; 1392 goto out;
@@ -1426,13 +1445,13 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
1426 1445
1427 nfs_block_sillyrename(dentry->d_parent); 1446 nfs_block_sillyrename(dentry->d_parent);
1428 inode = NFS_PROTO(dir)->open_context(dir, ctx, open_flags, &attr); 1447 inode = NFS_PROTO(dir)->open_context(dir, ctx, open_flags, &attr);
1429 d_drop(dentry); 1448 nfs_unblock_sillyrename(dentry->d_parent);
1430 if (IS_ERR(inode)) { 1449 if (IS_ERR(inode)) {
1431 nfs_unblock_sillyrename(dentry->d_parent);
1432 put_nfs_open_context(ctx); 1450 put_nfs_open_context(ctx);
1433 err = PTR_ERR(inode); 1451 err = PTR_ERR(inode);
1434 switch (err) { 1452 switch (err) {
1435 case -ENOENT: 1453 case -ENOENT:
1454 d_drop(dentry);
1436 d_add(dentry, NULL); 1455 d_add(dentry, NULL);
1437 break; 1456 break;
1438 case -EISDIR: 1457 case -EISDIR:
@@ -1448,16 +1467,8 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
1448 } 1467 }
1449 goto out; 1468 goto out;
1450 } 1469 }
1451 res = d_add_unique(dentry, inode);
1452 if (res != NULL)
1453 dentry = res;
1454
1455 nfs_unblock_sillyrename(dentry->d_parent);
1456 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
1457
1458 err = nfs_finish_open(ctx, dentry, file, open_flags, opened);
1459 1470
1460 dput(res); 1471 err = nfs_finish_open(ctx, ctx->dentry, file, open_flags, opened);
1461out: 1472out:
1462 return err; 1473 return err;
1463 1474
@@ -1527,7 +1538,8 @@ no_open:
1527 * Code common to create, mkdir, and mknod. 1538 * Code common to create, mkdir, and mknod.
1528 */ 1539 */
1529int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle, 1540int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
1530 struct nfs_fattr *fattr) 1541 struct nfs_fattr *fattr,
1542 struct nfs4_label *label)
1531{ 1543{
1532 struct dentry *parent = dget_parent(dentry); 1544 struct dentry *parent = dget_parent(dentry);
1533 struct inode *dir = parent->d_inode; 1545 struct inode *dir = parent->d_inode;
@@ -1540,18 +1552,18 @@ int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
1540 if (dentry->d_inode) 1552 if (dentry->d_inode)
1541 goto out; 1553 goto out;
1542 if (fhandle->size == 0) { 1554 if (fhandle->size == 0) {
1543 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr); 1555 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, NULL);
1544 if (error) 1556 if (error)
1545 goto out_error; 1557 goto out_error;
1546 } 1558 }
1547 nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 1559 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
1548 if (!(fattr->valid & NFS_ATTR_FATTR)) { 1560 if (!(fattr->valid & NFS_ATTR_FATTR)) {
1549 struct nfs_server *server = NFS_SB(dentry->d_sb); 1561 struct nfs_server *server = NFS_SB(dentry->d_sb);
1550 error = server->nfs_client->rpc_ops->getattr(server, fhandle, fattr); 1562 error = server->nfs_client->rpc_ops->getattr(server, fhandle, fattr, NULL);
1551 if (error < 0) 1563 if (error < 0)
1552 goto out_error; 1564 goto out_error;
1553 } 1565 }
1554 inode = nfs_fhget(dentry->d_sb, fhandle, fattr); 1566 inode = nfs_fhget(dentry->d_sb, fhandle, fattr, label);
1555 error = PTR_ERR(inode); 1567 error = PTR_ERR(inode);
1556 if (IS_ERR(inode)) 1568 if (IS_ERR(inode))
1557 goto out_error; 1569 goto out_error;
@@ -1720,7 +1732,7 @@ int nfs_unlink(struct inode *dir, struct dentry *dentry)
1720 dir->i_ino, dentry->d_name.name); 1732 dir->i_ino, dentry->d_name.name);
1721 1733
1722 spin_lock(&dentry->d_lock); 1734 spin_lock(&dentry->d_lock);
1723 if (dentry->d_count > 1) { 1735 if (d_count(dentry) > 1) {
1724 spin_unlock(&dentry->d_lock); 1736 spin_unlock(&dentry->d_lock);
1725 /* Start asynchronous writeout of the inode */ 1737 /* Start asynchronous writeout of the inode */
1726 write_inode_now(dentry->d_inode, 0); 1738 write_inode_now(dentry->d_inode, 0);
@@ -1758,7 +1770,6 @@ EXPORT_SYMBOL_GPL(nfs_unlink);
1758 */ 1770 */
1759int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) 1771int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
1760{ 1772{
1761 struct pagevec lru_pvec;
1762 struct page *page; 1773 struct page *page;
1763 char *kaddr; 1774 char *kaddr;
1764 struct iattr attr; 1775 struct iattr attr;
@@ -1798,11 +1809,8 @@ int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
1798 * No big deal if we can't add this page to the page cache here. 1809 * No big deal if we can't add this page to the page cache here.
1799 * READLINK will get the missing page from the server if needed. 1810 * READLINK will get the missing page from the server if needed.
1800 */ 1811 */
1801 pagevec_init(&lru_pvec, 0); 1812 if (!add_to_page_cache_lru(page, dentry->d_inode->i_mapping, 0,
1802 if (!add_to_page_cache(page, dentry->d_inode->i_mapping, 0,
1803 GFP_KERNEL)) { 1813 GFP_KERNEL)) {
1804 pagevec_add(&lru_pvec, page);
1805 pagevec_lru_add_file(&lru_pvec);
1806 SetPageUptodate(page); 1814 SetPageUptodate(page);
1807 unlock_page(page); 1815 unlock_page(page);
1808 } else 1816 } else
@@ -1869,7 +1877,7 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1869 dfprintk(VFS, "NFS: rename(%s/%s -> %s/%s, ct=%d)\n", 1877 dfprintk(VFS, "NFS: rename(%s/%s -> %s/%s, ct=%d)\n",
1870 old_dentry->d_parent->d_name.name, old_dentry->d_name.name, 1878 old_dentry->d_parent->d_name.name, old_dentry->d_name.name,
1871 new_dentry->d_parent->d_name.name, new_dentry->d_name.name, 1879 new_dentry->d_parent->d_name.name, new_dentry->d_name.name,
1872 new_dentry->d_count); 1880 d_count(new_dentry));
1873 1881
1874 /* 1882 /*
1875 * For non-directories, check whether the target is busy and if so, 1883 * For non-directories, check whether the target is busy and if so,
@@ -1887,7 +1895,7 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1887 rehash = new_dentry; 1895 rehash = new_dentry;
1888 } 1896 }
1889 1897
1890 if (new_dentry->d_count > 2) { 1898 if (d_count(new_dentry) > 2) {
1891 int err; 1899 int err;
1892 1900
1893 /* copy the target dentry's name */ 1901 /* copy the target dentry's name */