summaryrefslogtreecommitdiffstats
path: root/fs/coda
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2016-04-21 05:08:32 +0200
committerAl Viro <viro@zeniv.linux.org.uk>2016-05-03 01:49:29 +0200
commit6192269444ebfbfb42e23c7a6a93c76ffe4b5e51 (patch)
treeec40fbbad46725d88f2c16b11ff5976d87f497bb /fs/coda
parentgive readdir(2)/getdents(2)/etc. uniform exclusion with lseek() (diff)
downloadlinux-6192269444ebfbfb42e23c7a6a93c76ffe4b5e51.tar.xz
linux-6192269444ebfbfb42e23c7a6a93c76ffe4b5e51.zip
introduce a parallel variant of ->iterate()
New method: ->iterate_shared(). Same arguments as in ->iterate(), called with the directory locked only shared. Once all filesystems switch, the old one will be gone. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/coda')
-rw-r--r--fs/coda/dir.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/fs/coda/dir.c b/fs/coda/dir.c
index 42e731b8c80a..6fb8672c0892 100644
--- a/fs/coda/dir.c
+++ b/fs/coda/dir.c
@@ -424,16 +424,22 @@ static int coda_readdir(struct file *coda_file, struct dir_context *ctx)
BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
host_file = cfi->cfi_container;
- if (host_file->f_op->iterate) {
+ if (host_file->f_op->iterate || host_file->f_op->iterate_shared) {
struct inode *host_inode = file_inode(host_file);
-
- inode_lock(host_inode);
ret = -ENOENT;
if (!IS_DEADDIR(host_inode)) {
- ret = host_file->f_op->iterate(host_file, ctx);
- file_accessed(host_file);
+ if (host_file->f_op->iterate_shared) {
+ inode_lock_shared(host_inode);
+ ret = host_file->f_op->iterate_shared(host_file, ctx);
+ file_accessed(host_file);
+ inode_unlock_shared(host_inode);
+ } else {
+ inode_lock(host_inode);
+ ret = host_file->f_op->iterate(host_file, ctx);
+ file_accessed(host_file);
+ inode_unlock(host_inode);
+ }
}
- inode_unlock(host_inode);
return ret;
}
/* Venus: we must read Venus dirents from a file */