diff -u openafs-1.4.14+dfsg/debian/changelog openafs-1.4.14+dfsg/debian/changelog --- openafs-1.4.14+dfsg/debian/changelog +++ openafs-1.4.14+dfsg/debian/changelog @@ -1,3 +1,24 @@ +openafs (1.4.14+dfsg-1+ubuntu1) natty; urgency=low + + * Apply upstream deltas for kernel 2.6.38 support (LP: #675768): + - [02f2c7cb] Linux: Add autoconf macro for structure checks + - [a89d6b02] Linux: Add general autoconf macro for Linux kernel + - [08bb83d9] linux: 2.6.38: New d_op handling + - [52556d50] linux: 2.6.38: Make d_revalidate RCU-walk aware + - [ca38c954] Linux: allow compile flags to be passed to AC_CHECK_LINUX_BUILD + - [5bcc0ea7] Linux: 2.6.38: Adjust for permission inode operation changes + - [2eca7aef] Linux: 2.6.38: deal with dcache_lock removal + - [281f5bf5] Linux: 2.6.38: dentry->d_count is not an atomic + * Apply upstream deltas: + - [c4537f04] Don't count root session keyrings against quota (LP: #723481) + - [dfcd3fca] Linux: Reduce key_alloc flags confusion + (from http://gerrit.openafs.org/4033) + - [01c6e6bb] Linux: install_session_keyring: key_alloc flags are + unsigned long + (from http://gerrit.openafs.org/4034) + + -- Anders Kaseorg Tue, 22 Feb 2011 20:17:04 -0500 + openafs (1.4.14+dfsg-1) unstable; urgency=low * New upstream release. diff -u openafs-1.4.14+dfsg/debian/control openafs-1.4.14+dfsg/debian/control --- openafs-1.4.14+dfsg/debian/control +++ openafs-1.4.14+dfsg/debian/control @@ -1,7 +1,8 @@ Source: openafs Section: net Priority: optional -Maintainer: Russ Allbery +Maintainer: Ubuntu Developers +XSBC-Original-Maintainer: Russ Allbery Uploaders: Sam Hartman Build-Depends: debhelper (>= 7), autoconf, automake, bison, comerr-dev, cpio, dblatex, dkms (>= 2.1.1.1), docbook-xsl, doxygen, flex, diff -u openafs-1.4.14+dfsg/src/afs/LINUX/osi_compat.h openafs-1.4.14+dfsg/src/afs/LINUX/osi_compat.h --- openafs-1.4.14+dfsg/src/afs/LINUX/osi_compat.h +++ openafs-1.4.14+dfsg/src/afs/LINUX/osi_compat.h @@ -135,15 +135,6 @@ #else #define KALLOC_TYPE GFP_KERNEL #endif - -#ifdef LINUX_KEYRING_SUPPORT -# ifndef KEY_ALLOC_NOT_IN_QUOTA -# define KEY_ALLOC_NOT_IN_QUOTA 1 -# endif -# ifndef KEY_ALLOC_IN_QUOTA -# define KEY_ALLOC_IN_QUOTA 0 -# endif -#endif #endif static inline int diff -u openafs-1.4.14+dfsg/src/afs/LINUX/osi_groups.c openafs-1.4.14+dfsg/src/afs/LINUX/osi_groups.c --- openafs-1.4.14+dfsg/src/afs/LINUX/osi_groups.c +++ openafs-1.4.14+dfsg/src/afs/LINUX/osi_groups.c @@ -230,7 +230,7 @@ { struct key *old; char desc[20]; - unsigned long not_in_quota; + unsigned long flags; int code = -EINVAL; if (!__key_type_keyring) @@ -239,24 +239,31 @@ if (!keyring) { /* create an empty session keyring */ - not_in_quota = KEY_ALLOC_IN_QUOTA; sprintf(desc, "_ses.%u", current->tgid); + /* if we're root, don't count the keyring against our quota. This + * avoids starvation issues when dealing with PAM modules that always + * setpag() as root */ + if (current_uid() == 0) + flags = KEY_ALLOC_NOT_IN_QUOTA; + else + flags = KEY_ALLOC_IN_QUOTA; + #if defined(KEY_ALLOC_NEEDS_STRUCT_TASK) keyring = key_alloc(__key_type_keyring, desc, current_uid(), current_gid(), current, (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL, - not_in_quota); + flags); #elif defined(KEY_ALLOC_NEEDS_CRED) keyring = key_alloc(__key_type_keyring, desc, current_uid(), current_gid(), current_cred(), (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL, - not_in_quota); + flags); #else keyring = key_alloc(__key_type_keyring, desc, current_uid(), current_gid(), (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL, - not_in_quota); + flags); #endif if (IS_ERR(keyring)) { code = PTR_ERR(keyring); only in patch2: unchanged: --- openafs-1.4.14+dfsg.orig/acinclude.m4 +++ openafs-1.4.14+dfsg/acinclude.m4 @@ -749,6 +749,7 @@ LINUX_FS_STRUCT_SUPER_HAS_ALLOC_INODE LINUX_FS_STRUCT_SUPER_HAS_EVICT_INODE LINUX_FS_STRUCT_SUPER_BLOCK_HAS_S_BDI + AC_CHECK_LINUX_STRUCT([super_block], [s_d_op], [fs.h]) LINUX_STRUCT_BDI_HAS_NAME LINUX_FS_STRUCT_ADDRESS_SPACE_HAS_PAGE_LOCK LINUX_FS_STRUCT_ADDRESS_SPACE_HAS_GFP_MASK @@ -768,6 +769,7 @@ LINUX_WRITE_INODE_RETURN_TYPE LINUX_IOP_I_CREATE_TAKES_NAMEIDATA LINUX_IOP_I_LOOKUP_TAKES_NAMEIDATA + LINUX_IOP_I_PERMISSION_TAKES_FLAGS LINUX_IOP_I_PERMISSION_TAKES_NAMEIDATA LINUX_IOP_I_PUT_LINK_TAKES_COOKIE LINUX_DOP_D_REVALIDATE_TAKES_NAMEIDATA @@ -815,6 +817,8 @@ LINUX_GENERIC_FILE_AIO_READ LINUX_INIT_WORK_HAS_DATA LINUX_REGISTER_SYSCTL_TABLE_NOFLAG + LINUX_HAVE_DCACHE_LOCK + LINUX_D_COUNT_IS_INT LINUX_SYSCTL_TABLE_CHECKING LINUX_STRUCT_CTL_TABLE_HAS_CTL_NAME LINUX_HAVE_IGET only in patch2: unchanged: --- openafs-1.4.14+dfsg.orig/src/cf/linux-test1.m4 +++ openafs-1.4.14+dfsg/src/cf/linux-test1.m4 @@ -84,3 +84,28 @@ ac_linux_kbuild_requires_extra_cflags=yes) CPPFLAGS="$save_CPPFLAGS" AC_MSG_RESULT($ac_linux_kbuild_requires_extra_cflags)]) + +dnl AC_CHECK_LINUX_BUILD([msg], [var], [includes], [code], [define], [CFLAGS]) +AC_DEFUN([AC_CHECK_LINUX_BUILD], + [AS_VAR_PUSHDEF([ac_linux_build], [$2])dnl + AC_CACHE_CHECK([$1], [ac_linux_build], + [save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $7" + AC_TRY_KBUILD([$3], [$4], + AS_VAR_SET([ac_linux_build], [yes]), + AS_VAR_SET([ac_linux_build], [no])) + CPPFLAGS="$save_CPPFLAGS" + ]) + AS_IF([test AS_VAR_GET([ac_linux_build]) = yes], + [AC_DEFINE([$5],1,[$6])]) + ]) + +dnl AC_CHECK_LINUX_STRUCT([structure], [element], [includes]) +AC_DEFUN([AC_CHECK_LINUX_STRUCT], + [AC_CHECK_LINUX_BUILD([for $2 in struct $1], + [ac_cv_linux_struct_$1_has_$2], + [#include ], + [struct $1 _test; printk("%x\n", &_test.$2); ], + AS_TR_CPP(STRUCT_$1_HAS_$2), + [Define if kernel struct $1 has the $2 element]) + ]) only in patch2: unchanged: --- openafs-1.4.14+dfsg.orig/src/cf/linux-test4.m4 +++ openafs-1.4.14+dfsg/src/cf/linux-test4.m4 @@ -675,18 +675,30 @@ AC_DEFUN([LINUX_IOP_I_PERMISSION_TAKES_NAMEIDATA], [ - AC_MSG_CHECKING([whether inode_operations.permission takes a nameidata]) - AC_CACHE_VAL([ac_cv_linux_func_i_permission_takes_nameidata], [ - AC_TRY_KBUILD( + AC_CHECK_LINUX_BUILD([whether inode_operations.permission takes a nameidata], + [ac_cv_linux_func_i_permission_takes_nameidata], [#include #include ], [struct inode _inode; -struct dentry _dentry; struct nameidata _nameidata; (void)_inode.i_op->permission(&_inode, 0, &_nameidata);], - ac_cv_linux_func_i_permission_takes_nameidata=yes, - ac_cv_linux_func_i_permission_takes_nameidata=no)]) - AC_MSG_RESULT($ac_cv_linux_func_i_permission_takes_nameidata)]) + [IOP_PERMISSION_TAKES_NAMEIDATA], + [define if your iops.permission takes a nameidata argument], + [-Werror]) +]) + + +AC_DEFUN([LINUX_IOP_I_PERMISSION_TAKES_FLAGS], [ + AC_CHECK_LINUX_BUILD([whether inode_operations.permission takes flags], + [ac_cv_linux_func_i_permission_takes_flags], + [#include ], + [struct inode _inode; + unsigned int flags = 0; + (void)_inode.i_op->permission(&_inode, 0, flags);], + [IOP_PERMISSION_TAKES_FLAGS], + [define if your iops.permission takes a flags argument], + [-Werror]) +]) AC_DEFUN([LINUX_IOP_I_PUT_LINK_TAKES_COOKIE], [ @@ -1304,3 +1316,26 @@ if test "x$ac_cv_linux_inode_setattr" = "xyes"; then AC_DEFINE([HAVE_LINUX_INODE_SETATTR], 1, [define if your kernel has inode_setattr()]) fi]) + +AC_DEFUN([LINUX_HAVE_DCACHE_LOCK], [ + AC_CHECK_LINUX_BUILD([for dcache_lock], + [ac_cv_linux_have_dcache_lock], + [#include ], + [printk("%p", &dcache_lock);], + [HAVE_DCACHE_LOCK], + [define if dcache_lock exists], + []) +]) + + +AC_DEFUN([LINUX_D_COUNT_IS_INT], [ + AC_CHECK_LINUX_BUILD([if dentry->d_count is an int], + [ac_cv_linux_d_count_int], + [#include ], + [struct dentry _d; + dget(&_d); + _d.d_count = 1;], + [D_COUNT_INT], + [define if dentry->d_count is an int], + [-Werror]) +]) only in patch2: unchanged: --- openafs-1.4.14+dfsg.orig/src/afs/afs_daemons.c +++ openafs-1.4.14+dfsg/src/afs/afs_daemons.c @@ -376,7 +376,11 @@ dp = d_find_alias(AFSTOV(afs_globalVp)); #if defined(AFS_LINUX24_ENV) +#if defined(HAVE_DCACHE_LOCK) spin_lock(&dcache_lock); +#else + spin_lock(&AFSTOV(vcp)->i_lock); +#endif #if defined(AFS_LINUX26_ENV) spin_lock(&dp->d_lock); #endif @@ -388,7 +392,11 @@ #if defined(AFS_LINUX26_ENV) spin_unlock(&dp->d_lock); #endif +#if defined(HAVE_DCACHE_LOCK) spin_unlock(&dcache_lock); +#else + spin_unlock(&AFSTOV(vcp)->i_lock); +#endif #endif dput(dp); only in patch2: unchanged: --- openafs-1.4.14+dfsg.orig/src/afs/afs_vcache.c +++ openafs-1.4.14+dfsg/src/afs/afs_vcache.c @@ -673,12 +673,15 @@ #if defined(AFS_LINUX22_ENV) if (tvc != afs_globalVp && VREFCOUNT(tvc) > 1 && tvc->opens == 0) { struct dentry *dentry; + struct inode *inode = AFSTOV(tvc); struct list_head *cur, *head; AFS_GUNLOCK(); + +#if defined(HAVE_DCACHE_LOCK) #if defined(AFS_LINUX24_ENV) spin_lock(&dcache_lock); #endif - head = &(AFSTOV(tvc))->i_dentry; + head = &inode->i_dentry; restart: cur = head; @@ -687,7 +690,6 @@ if (d_unhashed(dentry)) continue; - dget_locked(dentry); #if defined(AFS_LINUX24_ENV) @@ -707,6 +709,35 @@ #if defined(AFS_LINUX24_ENV) spin_unlock(&dcache_lock); #endif +#else /* HAVE_DCACHE_LOCK */ + spin_lock(&inode->i_lock); + head = &inode->i_dentry; + +restart: + cur = head; + while ((cur = cur->next) != head) { + dentry = list_entry(cur, struct dentry, d_alias); + + spin_lock(&dentry->d_lock); + if (d_unhashed(dentry)) { + spin_unlock(&dentry->d_lock); + continue; + } + spin_unlock(&dentry->d_lock); + dget(dentry); + + spin_unlock(&inode->i_lock); + if (d_invalidate(dentry) == -EBUSY) { + dput(dentry); + /* perhaps lock and try to continue? (use cur as head?) */ + goto inuse; + } + dput(dentry); + spin_lock(&inode->i_lock); + goto restart; + } + spin_unlock(&inode->i_lock); +#endif /* HAVE_DCACHE_LOCK */ inuse: AFS_GLOCK(); } only in patch2: unchanged: --- openafs-1.4.14+dfsg.orig/src/afs/sysincludes.h +++ openafs-1.4.14+dfsg/src/afs/sysincludes.h @@ -79,7 +79,10 @@ #include #endif #ifndef KEY_ALLOC_IN_QUOTA -#define KEY_ALLOC_IN_QUOTA 1 +/* Before these flags were added in Linux commit v2.6.18-rc1~816, + * key_alloc just took a boolean not_in_quota */ +#define KEY_ALLOC_IN_QUOTA 0 +#define KEY_ALLOC_NOT_IN_QUOTA 1 #endif #endif #endif only in patch2: unchanged: --- openafs-1.4.14+dfsg.orig/src/afs/LINUX/osi_vfsops.c +++ openafs-1.4.14+dfsg/src/afs/LINUX/osi_vfsops.c @@ -140,6 +140,11 @@ sb->s_blocksize_bits = 10; sb->s_magic = AFS_VFSMAGIC; sb->s_op = &afs_sops; /* Super block (vfs) ops */ + +#if defined(STRUCT_SUPER_BLOCK_HAS_S_D_OP) + sb->s_d_op = &afs_dentry_operations; +#endif + /* used for inodes backing_dev_info field, also */ afs_backing_dev_info = osi_Alloc(sizeof(struct backing_dev_info)); #if defined(HAVE_BDI_INIT) @@ -227,7 +232,9 @@ #else afsp->s_root = d_alloc_root(ip, NULL); #endif +#if !defined(STRUCT_SUPER_BLOCK_HAS_S_D_OP) afsp->s_root->d_op = &afs_dentry_operations; +#endif } else code = ENOENT; } only in patch2: unchanged: --- openafs-1.4.14+dfsg.orig/src/afs/LINUX/osi_vnodeops.c +++ openafs-1.4.14+dfsg/src/afs/LINUX/osi_vnodeops.c @@ -865,10 +865,16 @@ int valid; struct afs_fakestat_state fakestate; +#ifdef LOOKUP_RCU + /* We don't support RCU path walking */ + if (nd->flags & LOOKUP_RCU) + return -ECHILD; +#endif #ifdef AFS_LINUX24_ENV lock_kernel(); #endif AFS_GLOCK(); + afs_InitFakeStat(&fakestate); if (dp->d_inode) { @@ -1067,7 +1073,9 @@ afs_getattr(vcp, &vattr, credp); afs_fill_inode(ip, &vattr); insert_inode_hash(ip); +#if !defined(STRUCT_SUPER_BLOCK_HAS_S_D_OP) dp->d_op = &afs_dentry_operations; +#endif dp->d_time = hgetlo(VTOAFS(dip)->m.DataVersion); d_instantiate(dp, ip); } @@ -1123,7 +1131,9 @@ ) insert_inode_hash(ip); } +#if !defined(STRUCT_SUPER_BLOCK_HAS_S_D_OP) dp->d_op = &afs_dentry_operations; +#endif dp->d_time = hgetlo(VTOAFS(dip)->m.DataVersion); AFS_GUNLOCK(); @@ -1315,7 +1325,9 @@ afs_getattr(tvcp, &vattr, credp); afs_fill_inode(ip, &vattr); +#if !defined(STRUCT_SUPER_BLOCK_HAS_S_D_OP) dp->d_op = &afs_dentry_operations; +#endif dp->d_time = hgetlo(VTOAFS(dip)->m.DataVersion); d_instantiate(dp, ip); } @@ -1384,9 +1396,18 @@ #endif #if defined(AFS_LINUX24_ENV) +#if defined(D_COUNT_INT) + spin_lock(&olddp->d_lock); + if (olddp->d_count > 1) { + spin_unlock(&olddp->d_lock); + shrink_dcache_parent(olddp); + } else + spin_unlock(&olddp->d_lock); +#else if (atomic_read(&olddp->d_count) > 1) shrink_dcache_parent(olddp); #endif +#endif AFS_GLOCK(); code = afs_rename(VTOAFS(oldip), oldname, VTOAFS(newip), newname, credp); @@ -1786,16 +1807,25 @@ * Check access rights - returns error if can't check or permission denied. */ static int -#ifdef IOP_PERMISSION_TAKES_NAMEIDATA +#if defined(IOP_PERMISSION_TAKES_FLAGS) +afs_linux_permission(struct inode *ip, int mode, unsigned int flags) +#elif defined(IOP_PERMISSION_TAKES_NAMEIDATA) afs_linux_permission(struct inode *ip, int mode, struct nameidata *nd) #else afs_linux_permission(struct inode *ip, int mode) #endif { int code; - cred_t *credp = crref(); + cred_t *credp; int tmp = 0; +#if defined(IOP_PERMISSION_TAKES_FLAGS) + /* We don't support RCU path walking */ + if (flags & IPERM_FLAG_RCU) + return -ECHILD; +#endif + + credp = crref(); AFS_GLOCK(); if (mode & MAY_EXEC) tmp |= VEXEC;