diff options
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r-- | fs/nfs/dir.c | 56 |
1 files changed, 5 insertions, 51 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 0989a2099688..f430057ff3b3 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -1354,10 +1354,10 @@ out: | |||
1354 | } | 1354 | } |
1355 | 1355 | ||
1356 | #ifdef CONFIG_NFS_V4 | 1356 | #ifdef CONFIG_NFS_V4 |
1357 | static int nfs_open_revalidate(struct dentry *, struct nameidata *); | 1357 | static int nfs4_lookup_revalidate(struct dentry *, struct nameidata *); |
1358 | 1358 | ||
1359 | const struct dentry_operations nfs4_dentry_operations = { | 1359 | const struct dentry_operations nfs4_dentry_operations = { |
1360 | .d_revalidate = nfs_open_revalidate, | 1360 | .d_revalidate = nfs4_lookup_revalidate, |
1361 | .d_delete = nfs_dentry_delete, | 1361 | .d_delete = nfs_dentry_delete, |
1362 | .d_iput = nfs_dentry_iput, | 1362 | .d_iput = nfs_dentry_iput, |
1363 | .d_automount = nfs_d_automount, | 1363 | .d_automount = nfs_d_automount, |
@@ -1519,13 +1519,11 @@ no_open: | |||
1519 | return nfs_lookup(dir, dentry, nd); | 1519 | return nfs_lookup(dir, dentry, nd); |
1520 | } | 1520 | } |
1521 | 1521 | ||
1522 | static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd) | 1522 | static int nfs4_lookup_revalidate(struct dentry *dentry, struct nameidata *nd) |
1523 | { | 1523 | { |
1524 | struct dentry *parent = NULL; | 1524 | struct dentry *parent = NULL; |
1525 | struct inode *inode; | 1525 | struct inode *inode; |
1526 | struct inode *dir; | 1526 | struct inode *dir; |
1527 | struct nfs_open_context *ctx; | ||
1528 | struct iattr attr; | ||
1529 | int openflags, ret = 0; | 1527 | int openflags, ret = 0; |
1530 | 1528 | ||
1531 | if (nd->flags & LOOKUP_RCU) | 1529 | if (nd->flags & LOOKUP_RCU) |
@@ -1554,57 +1552,13 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
1554 | /* We cannot do exclusive creation on a positive dentry */ | 1552 | /* We cannot do exclusive creation on a positive dentry */ |
1555 | if ((openflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL)) | 1553 | if ((openflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL)) |
1556 | goto no_open_dput; | 1554 | goto no_open_dput; |
1557 | /* We can't create new files here */ | ||
1558 | openflags &= ~(O_CREAT|O_EXCL); | ||
1559 | |||
1560 | ctx = create_nfs_open_context(dentry, openflags); | ||
1561 | ret = PTR_ERR(ctx); | ||
1562 | if (IS_ERR(ctx)) | ||
1563 | goto out; | ||
1564 | 1555 | ||
1565 | attr.ia_valid = ATTR_OPEN; | 1556 | /* Let f_op->open() actually open (and revalidate) the file */ |
1566 | if (openflags & O_TRUNC) { | 1557 | ret = 1; |
1567 | attr.ia_valid |= ATTR_SIZE; | ||
1568 | attr.ia_size = 0; | ||
1569 | nfs_wb_all(inode); | ||
1570 | } | ||
1571 | |||
1572 | /* | ||
1573 | * Note: we're not holding inode->i_mutex and so may be racing with | ||
1574 | * operations that change the directory. We therefore save the | ||
1575 | * change attribute *before* we do the RPC call. | ||
1576 | */ | ||
1577 | inode = NFS_PROTO(dir)->open_context(dir, ctx, openflags, &attr); | ||
1578 | if (IS_ERR(inode)) { | ||
1579 | ret = PTR_ERR(inode); | ||
1580 | switch (ret) { | ||
1581 | case -EPERM: | ||
1582 | case -EACCES: | ||
1583 | case -EDQUOT: | ||
1584 | case -ENOSPC: | ||
1585 | case -EROFS: | ||
1586 | goto out_put_ctx; | ||
1587 | default: | ||
1588 | goto out_drop; | ||
1589 | } | ||
1590 | } | ||
1591 | iput(inode); | ||
1592 | if (inode != dentry->d_inode) | ||
1593 | goto out_drop; | ||
1594 | 1558 | ||
1595 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); | ||
1596 | ret = nfs_intent_set_file(nd, ctx); | ||
1597 | if (ret >= 0) | ||
1598 | ret = 1; | ||
1599 | out: | 1559 | out: |
1600 | dput(parent); | 1560 | dput(parent); |
1601 | return ret; | 1561 | return ret; |
1602 | out_drop: | ||
1603 | d_drop(dentry); | ||
1604 | ret = 0; | ||
1605 | out_put_ctx: | ||
1606 | put_nfs_open_context(ctx); | ||
1607 | goto out; | ||
1608 | 1562 | ||
1609 | no_open_dput: | 1563 | no_open_dput: |
1610 | dput(parent); | 1564 | dput(parent); |