linux-dont-flush-writes-on-exec-20080326
[openafs.git] / src / afs / LINUX / osi_vnodeops.c
index e115ae4..ded2fa7 100644 (file)
@@ -491,11 +491,11 @@ afs_linux_lock(struct file *fp, int cmd, struct file_lock *flp)
 #ifdef AFS_LINUX24_ENV
     if ((code == 0 || flp->fl_type == F_UNLCK) && 
         (cmd == F_SETLK || cmd == F_SETLKW)) {
-#ifdef AFS_LINUX26_ENV
+#ifdef POSIX_LOCK_FILE_WAIT_ARG
+       code = posix_lock_file(fp, flp, 0);
+#else
        flp->fl_flags &=~ FL_SLEEP;
        code = posix_lock_file(fp, flp);
-#else
-       code = posix_lock_file(fp, flp, 0);
 #endif 
        if (code && flp->fl_type != F_UNLCK) {
            struct AFS_FLOCK flock2;
@@ -575,21 +575,31 @@ afs_linux_flock(struct file *fp, int cmd, struct file_lock *flp) {
  * afs_StoreAllSegments() with AFS_LASTSTORE
  */
 static int
+#if defined(FOP_FLUSH_TAKES_FL_OWNER_T)
+afs_linux_flush(struct file *fp, fl_owner_t id)
+#else
 afs_linux_flush(struct file *fp)
+#endif
 {
     struct vrequest treq;
-    struct vcache *vcp = VTOAFS(FILE_INODE(fp));
-    cred_t *credp = crref();
+    struct vcache *vcp;
+    cred_t *credp;
     int code;
 
     AFS_GLOCK();
 
+    if (fp->f_flags | O_RDONLY)     /* readers dont flush */
+       return 0;
+
+    credp = crref();
+    vcp = VTOAFS(FILE_INODE(fp));
+
     code = afs_InitReq(&treq, credp);
     if (code)
        goto out;
 
     ObtainSharedLock(&vcp->lock, 535);
-    if (vcp->execsOrWriters > 0) {
+    if ((vcp->execsOrWriters > 0) && (file_count(fp) == 1)) {
        UpgradeSToWLock(&vcp->lock, 536);
        code = afs_StoreAllSegments(vcp, &treq, AFS_SYNC | AFS_LASTSTORE);
        ConvertWToSLock(&vcp->lock);
@@ -654,9 +664,13 @@ struct file_operations afs_file_fops = {
   .mmap =      afs_linux_mmap,
   .open =      afs_linux_open,
   .flush =     afs_linux_flush,
-#ifdef AFS_LINUX26_ENV
+#if defined(AFS_LINUX26_ENV) && defined(STRUCT_FILE_OPERATIONS_HAS_SENDFILE)
   .sendfile =   generic_file_sendfile,
 #endif
+#if defined(AFS_LINUX26_ENV) && defined(STRUCT_FILE_OPERATIONS_HAS_SPLICE)
+  .splice_write = generic_file_splice_write,
+  .splice_read = generic_file_splice_read,
+#endif
   .release =   afs_linux_release,
   .fsync =     afs_linux_fsync,
   .lock =      afs_linux_lock,
@@ -892,6 +906,15 @@ afs_dentry_iput(struct dentry *dp, struct inode *ip)
     AFS_GLOCK();
     (void) afs_InactiveVCache(vcp, NULL);
     AFS_GUNLOCK();
+#ifdef DCACHE_NFSFS_RENAMED
+#ifdef AFS_LINUX26_ENV
+    spin_lock(&dp->d_lock);
+#endif
+    dp->d_flags &= ~DCACHE_NFSFS_RENAMED;   
+#ifdef AFS_LINUX26_ENV
+    spin_unlock(&dp->d_lock);
+#endif
+#endif
 
     iput(ip);
 }
@@ -953,6 +976,7 @@ afs_linux_create(struct inode *dip, struct dentry *dp, int mode)
 
        afs_getattr(vcp, &vattr, credp);
        afs_fill_inode(ip, &vattr);
+       insert_inode_hash(ip);
        dp->d_op = &afs_dentry_operations;
        dp->d_time = hgetlo(VTOAFS(dip)->m.DataVersion);
        d_instantiate(dp, ip);
@@ -1001,6 +1025,8 @@ afs_linux_lookup(struct inode *dip, struct dentry *dp)
        ip = AFSTOV(vcp);
        afs_getattr(vcp, &vattr, credp);
        afs_fill_inode(ip, &vattr);
+       if (hlist_unhashed(&ip->i_hash))
+           insert_inode_hash(ip);
     }
     dp->d_op = &afs_dentry_operations;
     dp->d_time = hgetlo(VTOAFS(dip)->m.DataVersion);
@@ -1127,6 +1153,15 @@ afs_linux_unlink(struct inode *dip, struct dentry *dp)
             }
             tvc->uncred = credp;
            tvc->states |= CUnlinked;
+#ifdef DCACHE_NFSFS_RENAMED
+#ifdef AFS_LINUX26_ENV
+           spin_lock(&dp->d_lock);
+#endif
+           dp->d_flags |= DCACHE_NFSFS_RENAMED;   
+#ifdef AFS_LINUX26_ENV
+           spin_unlock(&dp->d_lock);
+#endif
+#endif
        } else {
            osi_FreeSmallSpace(__name); 
        }
@@ -1854,5 +1889,4 @@ afs_fill_inode(struct inode *ip, struct vattr *vattr)
 #endif
     }
 
-    /* insert_inode_hash(ip);  -- this would make iget() work (if we used it) */
 }