From: Mark Vitale Date: Fri, 2 Mar 2018 04:16:56 +0000 (-0500) Subject: LINUX: fix RedHat 7.5 ENOTDIR issues X-Git-Tag: openafs-devel-1_9_0~608 X-Git-Url: http://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=c818f86b79a636532d396887d4f22cc196c86288 LINUX: fix RedHat 7.5 ENOTDIR issues Red Hat Linux 7.5 beta introduces a new file->f_mode flag FMODE_KABI_ITERATE as a means for certain in-tree filesystems to indicate that they have implemented file operation iterate() instead of readdir(). The kernel routine iterate_dir() tests this flag to decide whether to invoke the file operation iterate() or readdir(). The OpenAFS configure script detects that the file operation iterate() is available under RH7.5 and so implements iterate() as afs_linux_readdir(). However, since OpenAFS does not set FMODE_KABI_ITERATE on any of its files, the kernel's iterate_dir() will not invoke iterate() for any OpenAFS files. OpenAFS has also not implemented readdir(), so iterate_dir() must return -ENOTDIR. Instead, modify OpenAFS to fall back to readdir() in this case. Change-Id: I242276150ab2a506e1e9c5c752e3f17d36c98935 Reviewed-on: https://gerrit.openafs.org/12935 Tested-by: BuildBot Reviewed-by: Benjamin Kaduk --- diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index c1acca9..969a27b 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -53,6 +53,16 @@ # define D_SPLICE_ALIAS_RACE #endif +/* Workaround for RH 7.5 which introduced file operation iterate() but requires + * each file->f_mode to be marked with FMODE_KABI_ITERATE. Instead OpenAFS will + * continue to use file opearation readdir() in this case. + */ +#if defined(STRUCT_FILE_OPERATIONS_HAS_ITERATE) && !defined(FMODE_KABI_ITERATE) +#define USE_FOP_ITERATE 1 +#else +#undef USE_FOP_ITERATE +#endif + int cachefs_noreadpage = 0; extern struct backing_dev_info *afs_backing_dev_info; @@ -302,7 +312,7 @@ extern int BlobScan(struct dcache * afile, afs_int32 ablob, afs_int32 *ablobOut) * handling and use of bulkstats will need to be reflected here as well. */ static int -#if defined(STRUCT_FILE_OPERATIONS_HAS_ITERATE) +#if defined(USE_FOP_ITERATE) afs_linux_readdir(struct file *fp, struct dir_context *ctx) #else afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir) @@ -385,7 +395,7 @@ 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) +#if defined(USE_FOP_ITERATE) offset = ctx->pos; #else offset = (int) fp->f_pos; @@ -455,7 +465,7 @@ afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir) * holding the GLOCK. */ AFS_GUNLOCK(); -#if defined(STRUCT_FILE_OPERATIONS_HAS_ITERATE) +#if defined(USE_FOP_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); @@ -475,7 +485,7 @@ afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir) code = 0; unlock_out: -#if defined(STRUCT_FILE_OPERATIONS_HAS_ITERATE) +#if defined(USE_FOP_ITERATE) ctx->pos = (loff_t) offset; #else fp->f_pos = (loff_t) offset; @@ -798,7 +808,7 @@ out: struct file_operations afs_dir_fops = { .read = generic_read_dir, -#if defined(STRUCT_FILE_OPERATIONS_HAS_ITERATE) +#if defined(USE_FOP_ITERATE) .iterate = afs_linux_readdir, #else .readdir = afs_linux_readdir,