diff options
author | M. Mohan Kumar <mohan@in.ibm.com> | 2013-02-05 14:25:05 +0530 |
---|---|---|
committer | Eric Van Hensbergen <ericvh@gmail.com> | 2013-02-10 16:29:59 -0600 |
commit | b6f4bee02f682d1c86ece297871b78ae01afaaf4 (patch) | |
tree | cebad2fa8b3fbc43a54f115b1f69491d5f8d67a5 /fs/9p | |
parent | 03f0e022736d123bc42907a958535f4f10d0c4c3 (diff) | |
download | linux-3.10-b6f4bee02f682d1c86ece297871b78ae01afaaf4.tar.gz linux-3.10-b6f4bee02f682d1c86ece297871b78ae01afaaf4.tar.bz2 linux-3.10-b6f4bee02f682d1c86ece297871b78ae01afaaf4.zip |
fs/9p: Fix atomic_open
Return EEXISTS if requested file already exists, without this patch open
call will always succeed even if the file exists and user specified
O_CREAT|O_EXCL.
Following test code can be used to verify this patch. Without this patch
executing following test code on 9p mount will result in printing 'test case
failed' always.
main()
{
int fd;
/* first create the file */
fd = open("./file", O_CREAT|O_WRONLY);
if (fd < 0) {
perror("open");
return -1;
}
close(fd);
/* Now opening same file with O_CREAT|O_EXCL should fail */
fd = open("./file", O_CREAT|O_EXCL);
if (fd < 0 && errno == EEXIST)
printf("test case pass\n");
else
printf("test case failed\n");
close(fd);
return 0;
}
Signed-off-by: M. Mohan Kumar <mohan@in.ibm.com>
Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
Diffstat (limited to 'fs/9p')
-rw-r--r-- | fs/9p/vfs_inode_dotl.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index edd41d918e6..8d24ad66dfb 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c @@ -267,8 +267,14 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, } /* Only creates */ - if (!(flags & O_CREAT) || dentry->d_inode) - return finish_no_open(file, res); + if (!(flags & O_CREAT)) + return finish_no_open(file, res); + else if (dentry->d_inode) { + if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) + return -EEXIST; + else + return finish_no_open(file, res); + } v9ses = v9fs_inode2v9ses(dir); |