aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r--fs/nfs/dir.c81
1 files changed, 61 insertions, 20 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 7468735d299e..e79bc6ce828e 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -43,6 +43,8 @@
43#include "internal.h" 43#include "internal.h"
44#include "fscache.h" 44#include "fscache.h"
45 45
46#include "nfstrace.h"
47
46/* #define NFS_DEBUG_VERBOSE 1 */ 48/* #define NFS_DEBUG_VERBOSE 1 */
47 49
48static int nfs_opendir(struct inode *, struct file *); 50static int nfs_opendir(struct inode *, struct file *);
@@ -1100,7 +1102,9 @@ static int nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
1100 if (IS_ERR(label)) 1102 if (IS_ERR(label))
1101 goto out_error; 1103 goto out_error;
1102 1104
1105 trace_nfs_lookup_revalidate_enter(dir, dentry, flags);
1103 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, label); 1106 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, label);
1107 trace_nfs_lookup_revalidate_exit(dir, dentry, flags, error);
1104 if (error) 1108 if (error)
1105 goto out_bad; 1109 goto out_bad;
1106 if (nfs_compare_fh(NFS_FH(inode), fhandle)) 1110 if (nfs_compare_fh(NFS_FH(inode), fhandle))
@@ -1312,6 +1316,7 @@ struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, unsigned in
1312 1316
1313 parent = dentry->d_parent; 1317 parent = dentry->d_parent;
1314 /* Protect against concurrent sillydeletes */ 1318 /* Protect against concurrent sillydeletes */
1319 trace_nfs_lookup_enter(dir, dentry, flags);
1315 nfs_block_sillyrename(parent); 1320 nfs_block_sillyrename(parent);
1316 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, label); 1321 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, label);
1317 if (error == -ENOENT) 1322 if (error == -ENOENT)
@@ -1338,6 +1343,7 @@ no_entry:
1338 nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 1343 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
1339out_unblock_sillyrename: 1344out_unblock_sillyrename:
1340 nfs_unblock_sillyrename(parent); 1345 nfs_unblock_sillyrename(parent);
1346 trace_nfs_lookup_exit(dir, dentry, flags, error);
1341 nfs4_label_free(label); 1347 nfs4_label_free(label);
1342out: 1348out:
1343 nfs_free_fattr(fattr); 1349 nfs_free_fattr(fattr);
@@ -1392,7 +1398,6 @@ static int nfs_finish_open(struct nfs_open_context *ctx,
1392 nfs_file_set_open_context(file, ctx); 1398 nfs_file_set_open_context(file, ctx);
1393 1399
1394out: 1400out:
1395 put_nfs_open_context(ctx);
1396 return err; 1401 return err;
1397} 1402}
1398 1403
@@ -1404,6 +1409,7 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
1404 struct dentry *res; 1409 struct dentry *res;
1405 struct iattr attr = { .ia_valid = ATTR_OPEN }; 1410 struct iattr attr = { .ia_valid = ATTR_OPEN };
1406 struct inode *inode; 1411 struct inode *inode;
1412 unsigned int lookup_flags = 0;
1407 int err; 1413 int err;
1408 1414
1409 /* Expect a negative dentry */ 1415 /* Expect a negative dentry */
@@ -1412,6 +1418,10 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
1412 dfprintk(VFS, "NFS: atomic_open(%s/%ld), %s\n", 1418 dfprintk(VFS, "NFS: atomic_open(%s/%ld), %s\n",
1413 dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); 1419 dir->i_sb->s_id, dir->i_ino, dentry->d_name.name);
1414 1420
1421 err = nfs_check_flags(open_flags);
1422 if (err)
1423 return err;
1424
1415 /* NFS only supports OPEN on regular files */ 1425 /* NFS only supports OPEN on regular files */
1416 if ((open_flags & O_DIRECTORY)) { 1426 if ((open_flags & O_DIRECTORY)) {
1417 if (!d_unhashed(dentry)) { 1427 if (!d_unhashed(dentry)) {
@@ -1422,6 +1432,7 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
1422 */ 1432 */
1423 return -ENOENT; 1433 return -ENOENT;
1424 } 1434 }
1435 lookup_flags = LOOKUP_OPEN|LOOKUP_DIRECTORY;
1425 goto no_open; 1436 goto no_open;
1426 } 1437 }
1427 1438
@@ -1442,12 +1453,14 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
1442 if (IS_ERR(ctx)) 1453 if (IS_ERR(ctx))
1443 goto out; 1454 goto out;
1444 1455
1456 trace_nfs_atomic_open_enter(dir, ctx, open_flags);
1445 nfs_block_sillyrename(dentry->d_parent); 1457 nfs_block_sillyrename(dentry->d_parent);
1446 inode = NFS_PROTO(dir)->open_context(dir, ctx, open_flags, &attr); 1458 inode = NFS_PROTO(dir)->open_context(dir, ctx, open_flags, &attr);
1447 nfs_unblock_sillyrename(dentry->d_parent); 1459 nfs_unblock_sillyrename(dentry->d_parent);
1448 if (IS_ERR(inode)) { 1460 if (IS_ERR(inode)) {
1449 put_nfs_open_context(ctx);
1450 err = PTR_ERR(inode); 1461 err = PTR_ERR(inode);
1462 trace_nfs_atomic_open_exit(dir, ctx, open_flags, err);
1463 put_nfs_open_context(ctx);
1451 switch (err) { 1464 switch (err) {
1452 case -ENOENT: 1465 case -ENOENT:
1453 d_drop(dentry); 1466 d_drop(dentry);
@@ -1468,11 +1481,13 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
1468 } 1481 }
1469 1482
1470 err = nfs_finish_open(ctx, ctx->dentry, file, open_flags, opened); 1483 err = nfs_finish_open(ctx, ctx->dentry, file, open_flags, opened);
1484 trace_nfs_atomic_open_exit(dir, ctx, open_flags, err);
1485 put_nfs_open_context(ctx);
1471out: 1486out:
1472 return err; 1487 return err;
1473 1488
1474no_open: 1489no_open:
1475 res = nfs_lookup(dir, dentry, 0); 1490 res = nfs_lookup(dir, dentry, lookup_flags);
1476 err = PTR_ERR(res); 1491 err = PTR_ERR(res);
1477 if (IS_ERR(res)) 1492 if (IS_ERR(res))
1478 goto out; 1493 goto out;
@@ -1596,7 +1611,9 @@ int nfs_create(struct inode *dir, struct dentry *dentry,
1596 attr.ia_mode = mode; 1611 attr.ia_mode = mode;
1597 attr.ia_valid = ATTR_MODE; 1612 attr.ia_valid = ATTR_MODE;
1598 1613
1614 trace_nfs_create_enter(dir, dentry, open_flags);
1599 error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags); 1615 error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags);
1616 trace_nfs_create_exit(dir, dentry, open_flags, error);
1600 if (error != 0) 1617 if (error != 0)
1601 goto out_err; 1618 goto out_err;
1602 return 0; 1619 return 0;
@@ -1624,7 +1641,9 @@ nfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev)
1624 attr.ia_mode = mode; 1641 attr.ia_mode = mode;
1625 attr.ia_valid = ATTR_MODE; 1642 attr.ia_valid = ATTR_MODE;
1626 1643
1644 trace_nfs_mknod_enter(dir, dentry);
1627 status = NFS_PROTO(dir)->mknod(dir, dentry, &attr, rdev); 1645 status = NFS_PROTO(dir)->mknod(dir, dentry, &attr, rdev);
1646 trace_nfs_mknod_exit(dir, dentry, status);
1628 if (status != 0) 1647 if (status != 0)
1629 goto out_err; 1648 goto out_err;
1630 return 0; 1649 return 0;
@@ -1648,7 +1667,9 @@ int nfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
1648 attr.ia_valid = ATTR_MODE; 1667 attr.ia_valid = ATTR_MODE;
1649 attr.ia_mode = mode | S_IFDIR; 1668 attr.ia_mode = mode | S_IFDIR;
1650 1669
1670 trace_nfs_mkdir_enter(dir, dentry);
1651 error = NFS_PROTO(dir)->mkdir(dir, dentry, &attr); 1671 error = NFS_PROTO(dir)->mkdir(dir, dentry, &attr);
1672 trace_nfs_mkdir_exit(dir, dentry, error);
1652 if (error != 0) 1673 if (error != 0)
1653 goto out_err; 1674 goto out_err;
1654 return 0; 1675 return 0;
@@ -1671,12 +1692,21 @@ int nfs_rmdir(struct inode *dir, struct dentry *dentry)
1671 dfprintk(VFS, "NFS: rmdir(%s/%ld), %s\n", 1692 dfprintk(VFS, "NFS: rmdir(%s/%ld), %s\n",
1672 dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); 1693 dir->i_sb->s_id, dir->i_ino, dentry->d_name.name);
1673 1694
1674 error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name); 1695 trace_nfs_rmdir_enter(dir, dentry);
1675 /* Ensure the VFS deletes this inode */ 1696 if (dentry->d_inode) {
1676 if (error == 0 && dentry->d_inode != NULL) 1697 nfs_wait_on_sillyrename(dentry);
1677 clear_nlink(dentry->d_inode); 1698 error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name);
1678 else if (error == -ENOENT) 1699 /* Ensure the VFS deletes this inode */
1679 nfs_dentry_handle_enoent(dentry); 1700 switch (error) {
1701 case 0:
1702 clear_nlink(dentry->d_inode);
1703 break;
1704 case -ENOENT:
1705 nfs_dentry_handle_enoent(dentry);
1706 }
1707 } else
1708 error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name);
1709 trace_nfs_rmdir_exit(dir, dentry, error);
1680 1710
1681 return error; 1711 return error;
1682} 1712}
@@ -1704,6 +1734,7 @@ static int nfs_safe_remove(struct dentry *dentry)
1704 goto out; 1734 goto out;
1705 } 1735 }
1706 1736
1737 trace_nfs_remove_enter(dir, dentry);
1707 if (inode != NULL) { 1738 if (inode != NULL) {
1708 NFS_PROTO(inode)->return_delegation(inode); 1739 NFS_PROTO(inode)->return_delegation(inode);
1709 error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); 1740 error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
@@ -1713,6 +1744,7 @@ static int nfs_safe_remove(struct dentry *dentry)
1713 error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); 1744 error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
1714 if (error == -ENOENT) 1745 if (error == -ENOENT)
1715 nfs_dentry_handle_enoent(dentry); 1746 nfs_dentry_handle_enoent(dentry);
1747 trace_nfs_remove_exit(dir, dentry, error);
1716out: 1748out:
1717 return error; 1749 return error;
1718} 1750}
@@ -1730,13 +1762,14 @@ int nfs_unlink(struct inode *dir, struct dentry *dentry)
1730 dfprintk(VFS, "NFS: unlink(%s/%ld, %s)\n", dir->i_sb->s_id, 1762 dfprintk(VFS, "NFS: unlink(%s/%ld, %s)\n", dir->i_sb->s_id,
1731 dir->i_ino, dentry->d_name.name); 1763 dir->i_ino, dentry->d_name.name);
1732 1764
1765 trace_nfs_unlink_enter(dir, dentry);
1733 spin_lock(&dentry->d_lock); 1766 spin_lock(&dentry->d_lock);
1734 if (d_count(dentry) > 1) { 1767 if (d_count(dentry) > 1) {
1735 spin_unlock(&dentry->d_lock); 1768 spin_unlock(&dentry->d_lock);
1736 /* Start asynchronous writeout of the inode */ 1769 /* Start asynchronous writeout of the inode */
1737 write_inode_now(dentry->d_inode, 0); 1770 write_inode_now(dentry->d_inode, 0);
1738 error = nfs_sillyrename(dir, dentry); 1771 error = nfs_sillyrename(dir, dentry);
1739 return error; 1772 goto out;
1740 } 1773 }
1741 if (!d_unhashed(dentry)) { 1774 if (!d_unhashed(dentry)) {
1742 __d_drop(dentry); 1775 __d_drop(dentry);
@@ -1748,6 +1781,8 @@ int nfs_unlink(struct inode *dir, struct dentry *dentry)
1748 nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 1781 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
1749 } else if (need_rehash) 1782 } else if (need_rehash)
1750 d_rehash(dentry); 1783 d_rehash(dentry);
1784out:
1785 trace_nfs_unlink_exit(dir, dentry, error);
1751 return error; 1786 return error;
1752} 1787}
1753EXPORT_SYMBOL_GPL(nfs_unlink); 1788EXPORT_SYMBOL_GPL(nfs_unlink);
@@ -1794,7 +1829,9 @@ int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
1794 memset(kaddr + pathlen, 0, PAGE_SIZE - pathlen); 1829 memset(kaddr + pathlen, 0, PAGE_SIZE - pathlen);
1795 kunmap_atomic(kaddr); 1830 kunmap_atomic(kaddr);
1796 1831
1832 trace_nfs_symlink_enter(dir, dentry);
1797 error = NFS_PROTO(dir)->symlink(dir, dentry, page, pathlen, &attr); 1833 error = NFS_PROTO(dir)->symlink(dir, dentry, page, pathlen, &attr);
1834 trace_nfs_symlink_exit(dir, dentry, error);
1798 if (error != 0) { 1835 if (error != 0) {
1799 dfprintk(VFS, "NFS: symlink(%s/%ld, %s, %s) error %d\n", 1836 dfprintk(VFS, "NFS: symlink(%s/%ld, %s, %s) error %d\n",
1800 dir->i_sb->s_id, dir->i_ino, 1837 dir->i_sb->s_id, dir->i_ino,
@@ -1829,6 +1866,7 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
1829 old_dentry->d_parent->d_name.name, old_dentry->d_name.name, 1866 old_dentry->d_parent->d_name.name, old_dentry->d_name.name,
1830 dentry->d_parent->d_name.name, dentry->d_name.name); 1867 dentry->d_parent->d_name.name, dentry->d_name.name);
1831 1868
1869 trace_nfs_link_enter(inode, dir, dentry);
1832 NFS_PROTO(inode)->return_delegation(inode); 1870 NFS_PROTO(inode)->return_delegation(inode);
1833 1871
1834 d_drop(dentry); 1872 d_drop(dentry);
@@ -1837,6 +1875,7 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
1837 ihold(inode); 1875 ihold(inode);
1838 d_add(dentry, inode); 1876 d_add(dentry, inode);
1839 } 1877 }
1878 trace_nfs_link_exit(inode, dir, dentry, error);
1840 return error; 1879 return error;
1841} 1880}
1842EXPORT_SYMBOL_GPL(nfs_link); 1881EXPORT_SYMBOL_GPL(nfs_link);
@@ -1878,6 +1917,7 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1878 new_dentry->d_parent->d_name.name, new_dentry->d_name.name, 1917 new_dentry->d_parent->d_name.name, new_dentry->d_name.name,
1879 d_count(new_dentry)); 1918 d_count(new_dentry));
1880 1919
1920 trace_nfs_rename_enter(old_dir, old_dentry, new_dir, new_dentry);
1881 /* 1921 /*
1882 * For non-directories, check whether the target is busy and if so, 1922 * For non-directories, check whether the target is busy and if so,
1883 * make a copy of the dentry and then do a silly-rename. If the 1923 * make a copy of the dentry and then do a silly-rename. If the
@@ -1924,6 +1964,8 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1924out: 1964out:
1925 if (rehash) 1965 if (rehash)
1926 d_rehash(rehash); 1966 d_rehash(rehash);
1967 trace_nfs_rename_exit(old_dir, old_dentry,
1968 new_dir, new_dentry, error);
1927 if (!error) { 1969 if (!error) {
1928 if (new_inode != NULL) 1970 if (new_inode != NULL)
1929 nfs_drop_nlink(new_inode); 1971 nfs_drop_nlink(new_inode);
@@ -2173,9 +2215,11 @@ static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask)
2173 struct nfs_access_entry cache; 2215 struct nfs_access_entry cache;
2174 int status; 2216 int status;
2175 2217
2218 trace_nfs_access_enter(inode);
2219
2176 status = nfs_access_get_cached(inode, cred, &cache); 2220 status = nfs_access_get_cached(inode, cred, &cache);
2177 if (status == 0) 2221 if (status == 0)
2178 goto out; 2222 goto out_cached;
2179 2223
2180 /* Be clever: ask server to check for all possible rights */ 2224 /* Be clever: ask server to check for all possible rights */
2181 cache.mask = MAY_EXEC | MAY_WRITE | MAY_READ; 2225 cache.mask = MAY_EXEC | MAY_WRITE | MAY_READ;
@@ -2188,13 +2232,15 @@ static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask)
2188 if (!S_ISDIR(inode->i_mode)) 2232 if (!S_ISDIR(inode->i_mode))
2189 set_bit(NFS_INO_STALE, &NFS_I(inode)->flags); 2233 set_bit(NFS_INO_STALE, &NFS_I(inode)->flags);
2190 } 2234 }
2191 return status; 2235 goto out;
2192 } 2236 }
2193 nfs_access_add_cache(inode, &cache); 2237 nfs_access_add_cache(inode, &cache);
2238out_cached:
2239 if ((mask & ~cache.mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) != 0)
2240 status = -EACCES;
2194out: 2241out:
2195 if ((mask & ~cache.mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0) 2242 trace_nfs_access_exit(inode, status);
2196 return 0; 2243 return status;
2197 return -EACCES;
2198} 2244}
2199 2245
2200static int nfs_open_permission_mask(int openflags) 2246static int nfs_open_permission_mask(int openflags)
@@ -2240,11 +2286,6 @@ int nfs_permission(struct inode *inode, int mask)
2240 case S_IFLNK: 2286 case S_IFLNK:
2241 goto out; 2287 goto out;
2242 case S_IFREG: 2288 case S_IFREG:
2243 /* NFSv4 has atomic_open... */
2244 if (nfs_server_capable(inode, NFS_CAP_ATOMIC_OPEN)
2245 && (mask & MAY_OPEN)
2246 && !(mask & MAY_EXEC))
2247 goto out;
2248 break; 2289 break;
2249 case S_IFDIR: 2290 case S_IFDIR:
2250 /* 2291 /*