From 902b8809f03533ffa7731919930bb5178f77df6c Mon Sep 17 00:00:00 2001 From: Marc Dionne Date: Mon, 8 Jul 2013 10:53:00 -0400 Subject: [PATCH] Linux 3.11: Convert from readdir to iterate file operation Convert the readdir function so that it can be used as the new "iterate" file operation. This new operation is passed a context that contains a pointer to the filldir function and the offset. The context is passed into the new dir_emit function that will call the function specified by the context. The new dir_emit function returns true on success, so we must be careful about how we check for failure since this is different behaviour from what filldir currently does. Change-Id: I6b01b4c78a501bdf4f8d583b0d3b94d677c5d541 Reviewed-on: http://gerrit.openafs.org/10051 Tested-by: BuildBot Reviewed-by: Derrick Brashear --- acinclude.m4 | 1 + src/afs/LINUX/osi_vnodeops.c | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/acinclude.m4 b/acinclude.m4 index 6ffb686..15b5ad8 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -842,6 +842,7 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) AC_CHECK_LINUX_STRUCT([inode], [i_mutex], [fs.h]) AC_CHECK_LINUX_STRUCT([inode], [i_security], [fs.h]) AC_CHECK_LINUX_STRUCT([file_operations], [flock], [fs.h]) + AC_CHECK_LINUX_STRUCT([file_operations], [iterate], [fs.h]) AC_CHECK_LINUX_STRUCT([file_operations], [sendfile], [fs.h]) AC_CHECK_LINUX_STRUCT([file_system_type], [mount], [fs.h]) AC_CHECK_LINUX_STRUCT([filename], [name], [fs.h]) diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index 46fbb88..25cbac2 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -271,7 +271,11 @@ extern int BlobScan(struct dcache * afile, afs_int32 ablob); * handling and use of bulkstats will need to be reflected here as well. */ static int +#if defined(STRUCT_FILE_OPERATIONS_HAS_ITERATE) +afs_linux_readdir(struct file *fp, struct dir_context *ctx) +#else afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir) +#endif { struct vcache *avc = VTOAFS(FILE_INODE(fp)); struct vrequest treq; @@ -350,7 +354,11 @@ afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir) * takes an offset in units of blobs, rather than bytes. */ code = 0; +#if defined(STRUCT_FILE_OPERATIONS_HAS_ITERATE) + offset = ctx->pos; +#else offset = (int) fp->f_pos; +#endif while (1) { dirpos = BlobScan(tdc, offset); if (!dirpos) @@ -408,7 +416,13 @@ afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir) * holding the GLOCK. */ AFS_GUNLOCK(); +#if defined(STRUCT_FILE_OPERATIONS_HAS_ITERATE) + /* dir_emit returns a bool - true when it succeeds. + * Inverse the result to fit with how we check "code" */ + code = !dir_emit(ctx, de->name, len, ino, type); +#else code = (*filldir) (dirbuf, de->name, len, offset, ino, type); +#endif AFS_GLOCK(); } DRelease(&entry, 0); @@ -419,7 +433,11 @@ afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir) /* If filldir didn't fill in the last one this is still pointing to that * last attempt. */ +#if defined(STRUCT_FILE_OPERATIONS_HAS_ITERATE) + ctx->pos = (loff_t) offset; +#else fp->f_pos = (loff_t) offset; +#endif ReleaseReadLock(&tdc->lock); afs_PutDCache(tdc); @@ -748,7 +766,11 @@ out: struct file_operations afs_dir_fops = { .read = generic_read_dir, +#if defined(STRUCT_FILE_OPERATIONS_HAS_ITERATE) + .iterate = afs_linux_readdir, +#else .readdir = afs_linux_readdir, +#endif #ifdef HAVE_UNLOCKED_IOCTL .unlocked_ioctl = afs_unlocked_xioctl, #else -- 1.9.4