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.c56
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
1357static int nfs_open_revalidate(struct dentry *, struct nameidata *); 1357static int nfs4_lookup_revalidate(struct dentry *, struct nameidata *);
1358 1358
1359const struct dentry_operations nfs4_dentry_operations = { 1359const 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
1522static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd) 1522static 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;
1599out: 1559out:
1600 dput(parent); 1560 dput(parent);
1601 return ret; 1561 return ret;
1602out_drop:
1603 d_drop(dentry);
1604 ret = 0;
1605out_put_ctx:
1606 put_nfs_open_context(ctx);
1607 goto out;
1608 1562
1609no_open_dput: 1563no_open_dput:
1610 dput(parent); 1564 dput(parent);