diff options
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r-- | fs/nfs/dir.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 95b081bc9e25..2c3eb33b904d 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -970,7 +970,7 @@ int nfs_lookup_verify_inode(struct inode *inode, struct nameidata *nd) | |||
970 | { | 970 | { |
971 | struct nfs_server *server = NFS_SERVER(inode); | 971 | struct nfs_server *server = NFS_SERVER(inode); |
972 | 972 | ||
973 | if (test_bit(NFS_INO_MOUNTPOINT, &NFS_I(inode)->flags)) | 973 | if (IS_AUTOMOUNT(inode)) |
974 | return 0; | 974 | return 0; |
975 | if (nd != NULL) { | 975 | if (nd != NULL) { |
976 | /* VFS wants an on-the-wire revalidation */ | 976 | /* VFS wants an on-the-wire revalidation */ |
@@ -1173,6 +1173,7 @@ const struct dentry_operations nfs_dentry_operations = { | |||
1173 | .d_revalidate = nfs_lookup_revalidate, | 1173 | .d_revalidate = nfs_lookup_revalidate, |
1174 | .d_delete = nfs_dentry_delete, | 1174 | .d_delete = nfs_dentry_delete, |
1175 | .d_iput = nfs_dentry_iput, | 1175 | .d_iput = nfs_dentry_iput, |
1176 | .d_automount = nfs_d_automount, | ||
1176 | }; | 1177 | }; |
1177 | 1178 | ||
1178 | static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) | 1179 | static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) |
@@ -1246,6 +1247,7 @@ const struct dentry_operations nfs4_dentry_operations = { | |||
1246 | .d_revalidate = nfs_open_revalidate, | 1247 | .d_revalidate = nfs_open_revalidate, |
1247 | .d_delete = nfs_dentry_delete, | 1248 | .d_delete = nfs_dentry_delete, |
1248 | .d_iput = nfs_dentry_iput, | 1249 | .d_iput = nfs_dentry_iput, |
1250 | .d_automount = nfs_d_automount, | ||
1249 | }; | 1251 | }; |
1250 | 1252 | ||
1251 | /* | 1253 | /* |
@@ -1406,11 +1408,15 @@ no_open: | |||
1406 | static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd) | 1408 | static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd) |
1407 | { | 1409 | { |
1408 | struct dentry *parent = NULL; | 1410 | struct dentry *parent = NULL; |
1409 | struct inode *inode = dentry->d_inode; | 1411 | struct inode *inode; |
1410 | struct inode *dir; | 1412 | struct inode *dir; |
1411 | struct nfs_open_context *ctx; | 1413 | struct nfs_open_context *ctx; |
1412 | int openflags, ret = 0; | 1414 | int openflags, ret = 0; |
1413 | 1415 | ||
1416 | if (nd->flags & LOOKUP_RCU) | ||
1417 | return -ECHILD; | ||
1418 | |||
1419 | inode = dentry->d_inode; | ||
1414 | if (!is_atomic_open(nd) || d_mountpoint(dentry)) | 1420 | if (!is_atomic_open(nd) || d_mountpoint(dentry)) |
1415 | goto no_open; | 1421 | goto no_open; |
1416 | 1422 | ||
@@ -1579,6 +1585,7 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
1579 | { | 1585 | { |
1580 | struct iattr attr; | 1586 | struct iattr attr; |
1581 | int error; | 1587 | int error; |
1588 | int open_flags = 0; | ||
1582 | 1589 | ||
1583 | dfprintk(VFS, "NFS: create(%s/%ld), %s\n", | 1590 | dfprintk(VFS, "NFS: create(%s/%ld), %s\n", |
1584 | dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); | 1591 | dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); |
@@ -1586,7 +1593,10 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
1586 | attr.ia_mode = mode; | 1593 | attr.ia_mode = mode; |
1587 | attr.ia_valid = ATTR_MODE; | 1594 | attr.ia_valid = ATTR_MODE; |
1588 | 1595 | ||
1589 | error = NFS_PROTO(dir)->create(dir, dentry, &attr, 0, NULL); | 1596 | if ((nd->flags & LOOKUP_CREATE) != 0) |
1597 | open_flags = nd->intent.open.flags; | ||
1598 | |||
1599 | error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags, NULL); | ||
1590 | if (error != 0) | 1600 | if (error != 0) |
1591 | goto out_err; | 1601 | goto out_err; |
1592 | return 0; | 1602 | return 0; |