LINUX: Drop dentry if lookup returns new file
[openafs.git] / src / afs / LINUX / osi_vnodeops.c
index 30e6f30..0c907d8 100644 (file)
@@ -101,8 +101,11 @@ afs_linux_VerifyVCache(struct vcache *avc, cred_t **retcred) {
     return afs_convert_code(code);
 }
 
-#ifdef HAVE_LINUX_GENERIC_FILE_AIO_READ
-# ifdef LINUX_HAS_NONVECTOR_AIO
+#if defined(STRUCT_FILE_OPERATIONS_HAS_READ_ITER) || defined(HAVE_LINUX_GENERIC_FILE_AIO_READ)
+# if defined(STRUCT_FILE_OPERATIONS_HAS_READ_ITER)
+static ssize_t
+afs_linux_read_iter(struct kiocb *iocb, struct iov_iter *iter)
+# elif defined(LINUX_HAS_NONVECTOR_AIO)
 static ssize_t
 afs_linux_aio_read(struct kiocb *iocb, char __user *buf, size_t bufsize,
                    loff_t pos)
@@ -115,6 +118,11 @@ afs_linux_aio_read(struct kiocb *iocb, const struct iovec *buf,
     struct file *fp = iocb->ki_filp;
     ssize_t code = 0;
     struct vcache *vcp = VTOAFS(fp->f_dentry->d_inode);
+# if defined(STRUCT_FILE_OPERATIONS_HAS_READ_ITER)
+    loff_t pos = iocb->ki_pos;
+    unsigned long bufsize = iter->nr_segs;
+# endif
+
 
     AFS_GLOCK();
     afs_Trace4(afs_iclSetp, CM_TRACE_AIOREADOP, ICL_TYPE_POINTER, vcp,
@@ -127,7 +135,11 @@ afs_linux_aio_read(struct kiocb *iocb, const struct iovec *buf,
         * so we optimise by not using it */
        osi_FlushPages(vcp, NULL);      /* ensure stale pages are gone */
        AFS_GUNLOCK();
+# if defined(STRUCT_FILE_OPERATIONS_HAS_READ_ITER)
+       code = generic_file_read_iter(iocb, iter);
+# else
        code = generic_file_aio_read(iocb, buf, bufsize, pos);
+# endif
        AFS_GLOCK();
     }
 
@@ -172,8 +184,11 @@ afs_linux_read(struct file *fp, char *buf, size_t count, loff_t * offp)
  * also take care of re-positioning the pointer if file is open in append
  * mode. Call fake open/close to ensure we do writes of core dumps.
  */
-#ifdef HAVE_LINUX_GENERIC_FILE_AIO_READ
-# ifdef LINUX_HAS_NONVECTOR_AIO
+#if defined(STRUCT_FILE_OPERATIONS_HAS_READ_ITER) || defined(HAVE_LINUX_GENERIC_FILE_AIO_READ)
+# if defined(STRUCT_FILE_OPERATIONS_HAS_READ_ITER)
+static ssize_t
+afs_linux_write_iter(struct kiocb *iocb, struct iov_iter *iter)
+# elif defined(LINUX_HAS_NONVECTOR_AIO)
 static ssize_t
 afs_linux_aio_write(struct kiocb *iocb, const char __user *buf, size_t bufsize,
                     loff_t pos)
@@ -186,6 +201,10 @@ afs_linux_aio_write(struct kiocb *iocb, const struct iovec *buf,
     ssize_t code = 0;
     struct vcache *vcp = VTOAFS(iocb->ki_filp->f_dentry->d_inode);
     cred_t *credp;
+# if defined(STRUCT_FILE_OPERATIONS_HAS_READ_ITER)
+    loff_t pos = iocb->ki_pos;
+    unsigned long bufsize = iter->nr_segs;
+# endif
 
     AFS_GLOCK();
 
@@ -201,7 +220,11 @@ afs_linux_aio_write(struct kiocb *iocb, const struct iovec *buf,
     ReleaseWriteLock(&vcp->lock);
     if (code == 0) {
            AFS_GUNLOCK();
+# if defined(STRUCT_FILE_OPERATIONS_HAS_READ_ITER)
+           code = generic_file_write_iter(iocb, iter);
+# else
            code = generic_file_aio_write(iocb, buf, bufsize, pos);
+# endif
            AFS_GLOCK();
     }
 
@@ -803,7 +826,12 @@ struct file_operations afs_dir_fops = {
 };
 
 struct file_operations afs_file_fops = {
-#ifdef HAVE_LINUX_GENERIC_FILE_AIO_READ
+#ifdef STRUCT_FILE_OPERATIONS_HAS_READ_ITER
+  .read_iter = afs_linux_read_iter,
+  .write_iter =        afs_linux_write_iter,
+  .read =      new_sync_read,
+  .write =     new_sync_write,
+#elif defined(HAVE_LINUX_GENERIC_FILE_AIO_READ)
   .aio_read =  afs_linux_aio_read,
   .aio_write = afs_linux_aio_write,
   .read =      do_sync_read,
@@ -827,7 +855,11 @@ struct file_operations afs_file_fops = {
   .sendfile =   generic_file_sendfile,
 #endif
 #if defined(STRUCT_FILE_OPERATIONS_HAS_SPLICE)
+# if defined(HAVE_LINUX_ITER_FILE_SPLICE_WRITE)
+  .splice_write = iter_file_splice_write,
+# else
   .splice_write = generic_file_splice_write,
+# endif
   .splice_read = generic_file_splice_read,
 #endif
   .release =   afs_linux_release,
@@ -1272,9 +1304,14 @@ afs_linux_dentry_revalidate(struct dentry *dp, int flags)
            code = afs_lookup(pvcp, (char *)dp->d_name.name, &tvc, credp);
            if (!tvc || tvc != vcp) {
                dput(parent);
-               /* Force unhash if name is known not to exist. */
-               if (code == ENOENT)
-                   force_drop = 1;
+               /* Force unhash; the name doesn't point to this file
+                * anymore. */
+               force_drop = 1;
+               if (code && code != ENOENT) {
+                   /* ...except if we couldn't perform the actual lookup,
+                    * we don't know if the name points to this file or not. */
+                   force_drop = 0;
+               }
                goto bad_dentry;
            }
 
@@ -2665,11 +2702,6 @@ afs_linux_writepage(struct page *pp)
     int code = 0;
     int code1 = 0;
 
-    if (PageReclaim(pp)) {
-       return AOP_WRITEPAGE_ACTIVATE;
-       /* XXX - Do we need to redirty the page here? */
-    }
-
     page_cache_get(pp);
 
     inode = mapping->host;