Subject: Collected Debian patches for OpenAFS
Author: Russ Allbery <rra@debian.org>

The packaging for OpenAFS is maintained in Git with no Debian-specific
patches, just cherry-picks from upstream (possibly from upstream Gerrit).
This makes it complex to separate the changes into individual patches.
They are therefore all included in a single Debian patch.

For full commit history and separated commits, see the packaging Git
repository.
--- openafs-1.6.0.orig/acinclude.m4
+++ openafs-1.6.0/acinclude.m4
@@ -916,9 +916,11 @@ case $AFS_SYSNAME in *_linux* | *_umlinu
 		 LINUX_IOP_I_PERMISSION_TAKES_FLAGS
 	  	 LINUX_IOP_I_PERMISSION_TAKES_NAMEIDATA
 	  	 LINUX_IOP_I_PUT_LINK_TAKES_COOKIE
+		 LINUX_DOP_D_DELETE_TAKES_CONST
 	  	 LINUX_DOP_D_REVALIDATE_TAKES_NAMEIDATA
 	  	 LINUX_FOP_F_FLUSH_TAKES_FL_OWNER_T
 	  	 LINUX_FOP_F_FSYNC_TAKES_DENTRY
+		 LINUX_FOP_F_FSYNC_TAKES_RANGE
 	  	 LINUX_AOP_WRITEBACK_CONTROL
 		 LINUX_FS_STRUCT_FOP_HAS_SPLICE
 		 LINUX_KERNEL_POSIX_LOCK_FILE_WAIT_ARG
@@ -941,6 +943,7 @@ case $AFS_SYSNAME in *_linux* | *_umlinu
 		 LINUX_REGISTER_SYSCTL_TABLE_NOFLAG
 		 LINUX_HAVE_DCACHE_LOCK
 		 LINUX_D_COUNT_IS_INT
+		 LINUX_HAVE_SET_NLINK
 
 		 dnl If we are guaranteed that keyrings will work - that is
 		 dnl  a) The kernel has keyrings enabled
--- /dev/null
+++ openafs-1.6.0/src/libuafs/make_h_tree.pl
@@ -0,0 +1,45 @@
+#!/usr/bin/perl
+# make_h_tree.pl
+# Generate an h tree that includes the appropriate sys headers
+#
+# Usage: make_h_tree.pl ${SRC} ...
+#
+# The specified makefiles will be scanned for variable values.  The h
+# directory will be created under the current directory and populated with
+# stubs that include the actual header file for every header included by any
+# source file in the ${SRC} directories.  This is an ugly hack to work around
+# the naming of header files using h instead of their proper names elsewhere
+# in the code.
+
+use IO::File;
+
+if (@ARGV < 1) {
+  die "Usage: $0 SRC ...\n";
+}
+
+%remap = ('h' => 'sys');
+foreach $src (keys %remap) {
+    mkdir($src, 0777) or die "$src: $!\n";
+%seen = ();
+@q = map { glob ("$_/*.[Sc]") } @ARGV;
+  while (@q) {
+    $src = shift @q;
+    $content = new IO::File($src, O_RDONLY) or die "$src: $!\n";
+  LINE:
+    while (<$content>) {
+      chomp;
+      if (/^\s*\#\s*include\s*[<\"](?:\.\.\/)?([^\/>\"]*)(.*?)[>\"]/) {
+	$inc = "$1$2";
+	if (exists $seen{$inc}) {
+	  next;
+	} elsif (exists $remap{$1}  &&  $2 !~ /.\//) {
+	  $H = new IO::File("$inc", O_WRONLY|O_CREAT|O_TRUNC, 0666)
+	    or die "$inc: $!\n";
+	  print $H "#include <sys$2>\n";
+	  $H->close() or die "$inc: $!\n";
+          $seen{$inc} = 1;
+	}
+      }
+    }
+  }
+}
--- openafs-1.6.0.orig/src/libuafs/Makefile.common.in
+++ openafs-1.6.0/src/libuafs/Makefile.common.in
@@ -1484,9 +1484,9 @@ $(JUAFS)/xdr_len.o: $(TOP_SRC_RX)/xdr_le
 	$(CRULE1)
 
 clean:
-	-$(RM) -rf UAFS* JUAFS* AFSWEB* nsapi des afs afsint config rx
-	-$(RM) -f  h net netinet rpc ufs machine inet nfs sys des linktest $(AFS_OS_CLEAN)
-
+	-$(RM) -rf UAFS* JUAFS* AFSWEB* nsapi afsd afs afsint config rx
+	-$(RM) -rf h
+	-$(RM) linktest $(AFS_OS_CLEAN)
 
 install: UAFS/$(LIBUAFS) JUAFS/$(LIBJUAFS)
 	${INSTALL} -d ${DESTDIR}${libdir}
@@ -1531,15 +1531,10 @@ AFSWEB:
 	mkdir -p $@
 
 setup_common:
-	-$(RM) -f h net netinet rpc ufs nfs machine sys inet nsapi afsd
-	-ln -s ${ISYSROOT}/usr/include/sys h
-	-ln -s ${ISYSROOT}/usr/include/net net
-	-ln -s ${ISYSROOT}/usr/include/netinet netinet
-	-ln -s ${ISYSROOT}/usr/include/rpc rpc
-	-ln -s ${ISYSROOT}/usr/include/sys sys
-	-ln -s ${ISYSROOT}/usr/include/nfs nfs
-	-ln -s ${ISYSROOT}/usr/include/inet inet
-	-ln -s ${ISYSROOT}/usr/include/ufs ufs
+	-$(RM) -f nsapi afsd
+	-$(RM) -rf h
+	@TOP_SRCDIR@/libuafs/make_h_tree.pl $(TOP_SRC_AFS) $(TOP_SRC_VNOPS) \
+		$(TOP_SRC_RX)
 	-ln -s $(TOP_SRCDIR)/afsd afsd
 	-ln -s $(NS_INCL) nsapi
 
--- openafs-1.6.0.orig/src/afs/LINUX/osi_vfsops.c
+++ openafs-1.6.0/src/afs/LINUX/osi_vfsops.c
@@ -114,6 +114,7 @@ afs_fill_super(struct super_block *sb, v
 
     /* used for inodes backing_dev_info field, also */
     afs_backing_dev_info = osi_Alloc(sizeof(struct backing_dev_info));
+    memset(afs_backing_dev_info, 0, sizeof(struct backing_dev_info));
 #if defined(HAVE_LINUX_BDI_INIT)
     bdi_init(afs_backing_dev_info);
 #endif
@@ -439,7 +440,11 @@ void
 vattr2inode(struct inode *ip, struct vattr *vp)
 {
     ip->i_ino = vp->va_nodeid;
+#ifdef HAVE_SET_NLINK
+    set_nlink(ip, vp->va_nlink);
+#else
     ip->i_nlink = vp->va_nlink;
+#endif
     ip->i_blocks = vp->va_blocks;
 #ifdef STRUCT_INODE_HAS_I_BLKBITS
     ip->i_blkbits = AFS_BLKBITS;
--- openafs-1.6.0.orig/src/afs/LINUX/osi_vnodeops.c
+++ openafs-1.6.0/src/afs/LINUX/osi_vnodeops.c
@@ -425,6 +425,8 @@ afs_linux_release(struct inode *ip, stru
 static int
 #if defined(FOP_FSYNC_TAKES_DENTRY)
 afs_linux_fsync(struct file *fp, struct dentry *dp, int datasync)
+#elif defined(FOP_FSYNC_TAKES_RANGE)
+afs_linux_fsync(struct file *fp, loff_t start, loff_t end, int datasync)
 #else
 afs_linux_fsync(struct file *fp, int datasync)
 #endif
@@ -433,9 +435,15 @@ afs_linux_fsync(struct file *fp, int dat
     struct inode *ip = FILE_INODE(fp);
     cred_t *credp = crref();
 
+#if defined(FOP_FSYNC_TAKES_RANGE)
+    mutex_lock(&ip->i_mutex);
+#endif
     AFS_GLOCK();
     code = afs_fsync(VTOAFS(ip), credp);
     AFS_GUNLOCK();
+#if defined(FOP_FSYNC_TAKES_RANGE)
+    mutex_unlock(&ip->i_mutex);
+#endif
     crfree(credp);
     return afs_convert_code(code);
 
@@ -961,7 +969,11 @@ afs_dentry_iput(struct dentry *dp, struc
 }
 
 static int
+#if defined(DOP_D_DELETE_TAKES_CONST)
+afs_dentry_delete(const struct dentry *dp)
+#else
 afs_dentry_delete(struct dentry *dp)
+#endif
 {
     if (dp->d_inode && (VTOAFS(dp->d_inode)->f.states & CUnlinked))
 	return 1;		/* bad inode? */
@@ -2245,10 +2257,13 @@ afs_linux_permission(struct inode *ip, i
     cred_t *credp;
     int tmp = 0;
 
+    /* Check for RCU path walking */
 #if defined(IOP_PERMISSION_TAKES_FLAGS)
-    /* We don't support RCU path walking */
     if (flags & IPERM_FLAG_RCU)
        return -ECHILD;
+#elif defined(MAY_NOT_BLOCK)
+    if (mode & MAY_NOT_BLOCK)
+       return -ECHILD;
 #endif
 
     credp = crref();
--- openafs-1.6.0.orig/src/viced/afsfileprocs.c
+++ openafs-1.6.0/src/viced/afsfileprocs.c
@@ -1265,48 +1265,6 @@ CopyOnWrite(Vnode * targetptr, Volume *
     return 0;			/* success */
 }				/*CopyOnWrite */
 
-static int
-CopyOnWrite2(FdHandle_t *targFdP, FdHandle_t *newFdP, afs_foff_t off,
-             afs_sfsize_t size)
-{
-    char *buff = malloc(COPYBUFFSIZE);
-    size_t length;
-    ssize_t rdlen;
-    ssize_t wrlen;
-    int rc = 0;
-    afs_foff_t done = off;
-
-    if (size > FDH_SIZE(targFdP) - off)
-	size = FDH_SIZE(targFdP) - off;
-
-    while (size > 0) {
-	if (size > COPYBUFFSIZE) {	/* more than a buffer */
-	    length = COPYBUFFSIZE;
-	    size -= COPYBUFFSIZE;
-	} else {
-	    length = size;
-	    size = 0;
-	}
-	rdlen = FDH_PREAD(targFdP, buff, length, done);
-	if (rdlen == length) {
-	    wrlen = FDH_PWRITE(newFdP, buff, length, done);
-	    done += rdlen;
-	}
-	else
-	    wrlen = 0;
-
-	if ((rdlen != length) || (wrlen != length)) {
-	    /* no error recovery, at the worst we'll have a "hole"
-	     * in the file */
-	    rc = 1;
-	    break;
-	}
-    }
-    free(buff);
-    return rc;
-}
-
-
 /*
  * Common code to handle with removing the Name (file when it's called from
  * SAFS_RemoveFile() or an empty dir when called from SAFS_rmdir()) from a
@@ -7264,9 +7222,8 @@ StoreData_RXStyle(Volume * volptr, Vnode
     afs_fsize_t NewLength;	/* size after this store completes */
     afs_sfsize_t adjustSize;	/* bytes to call VAdjust... with */
     int linkCount = 0;		/* link count on inode */
-    afs_fsize_t CoW_off, CoW_len;
     ssize_t nBytes;
-    FdHandle_t *fdP, *origfdP = NULL;
+    FdHandle_t *fdP;
     struct in_addr logHostAddr;	/* host ip holder for inet_ntoa */
     afs_ino_str_t stmp;
 
@@ -7326,32 +7283,20 @@ StoreData_RXStyle(Volume * volptr, Vnode
 	     * mechanisms (i.e. copy on write overhead.) Also the right size
 	     * of the disk will be recorded...
 	     */
-	    origfdP = fdP;
+	    FDH_CLOSE(fdP);
 	    VN_GET_LEN(size, targetptr);
 	    volptr->partition->flags &= ~PART_DONTUPDATE;
 	    VSetPartitionDiskUsage(volptr->partition);
 	    volptr->partition->flags |= PART_DONTUPDATE;
 	    if ((errorCode = VDiskUsage(volptr, nBlocks(size)))) {
 		volptr->partition->flags &= ~PART_DONTUPDATE;
-		FDH_CLOSE(origfdP);
 		return (errorCode);
 	    }
 
-	    CoW_len = (FileLength >= (Length + Pos)) ? FileLength - Length : Pos;
-	    CopyOnWrite_calls++;
-	    if (CoW_len == 0) CopyOnWrite_size0++;
-	    if (Pos == 0) CopyOnWrite_off0++;
-	    if (CoW_len > CopyOnWrite_maxsize) CopyOnWrite_maxsize = CoW_len;
-
-	    ViceLog(1, ("StoreData : calling CopyOnWrite on vnode %u.%u (%s) "
-			"off 0x0 size 0x%llx\n",
-			afs_printable_VolumeId_u(V_id(volptr)),
-			afs_printable_VnodeId_u(targetptr->vnodeNumber),
-			V_name(volptr), Pos));
-	    if ((errorCode = CopyOnWrite(targetptr, volptr, 0, Pos))) {
+	    ViceLog(25, ("StoreData : calling CopyOnWrite on  target dir\n"));
+	    if ((errorCode = CopyOnWrite(targetptr, volptr, 0, MAXFSIZE))) {
 		ViceLog(25, ("StoreData : CopyOnWrite failed\n"));
 		volptr->partition->flags &= ~PART_DONTUPDATE;
-		FDH_CLOSE(origfdP);
 		return (errorCode);
 	    }
 	    volptr->partition->flags &= ~PART_DONTUPDATE;
@@ -7360,7 +7305,6 @@ StoreData_RXStyle(Volume * volptr, Vnode
 	    if (fdP == NULL) {
 		ViceLog(25,
 			("StoreData : Reopen after CopyOnWrite failed\n"));
-		FDH_REALLYCLOSE(origfdP);
 		return ENOENT;
 	    }
 	}
@@ -7392,7 +7336,6 @@ StoreData_RXStyle(Volume * volptr, Vnode
 	 AdjustDiskUsage(volptr, adjustSize,
 			 adjustSize - SpareComp(volptr)))) {
 	FDH_CLOSE(fdP);
-	if (origfdP) FDH_REALLYCLOSE(origfdP);
 	return (errorCode);
     }
 
@@ -7490,9 +7433,6 @@ StoreData_RXStyle(Volume * volptr, Vnode
 	 * need to update the target vnode.
 	 */
 	targetptr->changed_newTime = 1;
-	if (origfdP && (bytesTransfered < Length))	/* Need to "finish" CopyOnWrite still */
-	    CopyOnWrite2(origfdP, fdP, Pos + bytesTransfered, NewLength - Pos - bytesTransfered);
-	if (origfdP) FDH_REALLYCLOSE(origfdP);
 	FDH_CLOSE(fdP);
 	/* set disk usage to be correct */
 	VAdjustDiskUsage(&errorCode, volptr,
@@ -7500,17 +7440,6 @@ StoreData_RXStyle(Volume * volptr, Vnode
 					 nBlocks(NewLength)), 0);
 	return errorCode;
     }
-    if (origfdP) {					/* finish CopyOnWrite */
-	if ( (CoW_off = Pos + Length) < NewLength) {
-	    errorCode = CopyOnWrite2(origfdP, fdP, CoW_off, CoW_len = NewLength - CoW_off);
-	    ViceLog(1, ("StoreData : CopyOnWrite2 on vnode %u.%u (%s) "
-			"off 0x%llx size 0x%llx returns %d\n",
-                        afs_printable_VolumeId_u(V_id(volptr)),
-			afs_printable_VnodeId_u(targetptr->vnodeNumber),
-			V_name(volptr), CoW_off, CoW_len, errorCode));
-	}
-	FDH_REALLYCLOSE(origfdP);
-    }
     FDH_CLOSE(fdP);
 
     FT_GetTimeOfDay(&StopTime, 0);
--- openafs-1.6.0.orig/src/cf/linux-test4.m4
+++ openafs-1.6.0/src/cf/linux-test4.m4
@@ -414,6 +414,22 @@ struct dentry _d;
 ])
 
 
+int (*fsync) (struct file *, loff_t start, loff_t end, int datasync);
+
+AC_DEFUN([LINUX_FOP_F_FSYNC_TAKES_RANGE], [
+  AC_CHECK_LINUX_BUILD([whether file_operations.fsync takes a range],
+		       [ac_cv_linux_func_f_fsync_takes_range],
+		       [#include <linux/fs.h>],
+[struct inode _inode;
+struct file _file;
+loff_t start, end;
+(void)_inode.i_fop->fsync(&_file, start, end, 0);],
+		       [FOP_FSYNC_TAKES_RANGE],
+		       [define if your fops.fsync takes range arguments],
+		       [])
+])
+
+
 AC_DEFUN([LINUX_HAVE_KMEM_CACHE_T], [
   AC_CHECK_LINUX_BUILD([whether kmem_cache_t exists],
 		       [ac_cv_linux_have_kmem_cache_t],
@@ -604,3 +620,29 @@ AC_DEFUN([LINUX_D_COUNT_IS_INT], [
 			[define if dentry->d_count is an int],
 			[-Werror])
 ])
+
+
+AC_DEFUN([LINUX_DOP_D_DELETE_TAKES_CONST], [
+  AC_CHECK_LINUX_BUILD([whether dentry.d_op->d_delete takes a const argument],
+			[ac_cv_linux_dop_d_delete_takes_const],
+			[#include <linux/fs.h>
+			#include <linux/dcache.h>],
+			[struct dentry_operations _d_ops;
+			int _d_del(const struct dentry *de) {return 0;};
+			_d_ops.d_delete = _d_del;],
+			[DOP_D_DELETE_TAKES_CONST],
+			[define if dentry.d_op->d_delete takes a const argument],
+			[-Werror])
+])
+
+
+AC_DEFUN([LINUX_HAVE_SET_NLINK], [
+  AC_CHECK_LINUX_BUILD([for set_nlink],
+			[ac_cv_linux_have_set_nlink],
+			[#include <linux/fs.h>],
+			[struct inode _inode;
+			set_nlink(&_inode, 1);],
+			[HAVE_SET_NLINK],
+			[define if set_nlink exists],
+			[-Werror])
+])
--- openafs-1.6.0.orig/src/packaging/Debian/sysname
+++ openafs-1.6.0/src/packaging/Debian/sysname
@@ -9,7 +9,7 @@ case `dpkg --print-architecture` in
 alpha)
     echo alpha_linux_26
     ;;
-arm|armel|armv5tel)
+arm|armel|armhf|armv5tel)
     echo arm_linux26
     ;;
 amd64)
--- openafs-1.6.0.orig/src/packaging/Debian/module/sysname
+++ openafs-1.6.0/src/packaging/Debian/module/sysname
@@ -21,7 +21,7 @@ alpha)
         ;;
     esac
     ;;
-arm|armel|armv5tel)
+arm|armel|armhf|armv5tel)
     case $KVERS in
     2.4*)
         echo arm_linux24
