From eeaabffccffca0bf4c622819da62c6eaa51888bb Mon Sep 17 00:00:00 2001 From: Marc Dionne Date: Wed, 9 Jan 2013 19:26:54 -0500 Subject: [PATCH] Linux 3.8: session_keyring changes The session_keyring is now attached directly to the cred structure and the thread_group_cred structure (cred->tgcred) no longer exists. Adapt code that makes use of tgcred, and use the standard rcu based mechanism to update session_keyring. Reviewed-on: http://gerrit.openafs.org/8905 Reviewed-by: Andrew Deason Tested-by: BuildBot Reviewed-by: Derrick Brashear (cherry picked from commit c6d27e322a8d3b352554650473a048235a9c763a) Change-Id: I048ed7b52062a5d666c78dba2599d5fb81c676c1 --- acinclude.m4 | 1 + src/afs/LINUX/osi_compat.h | 34 ++++++++++++++++++++++++++++++++-- src/afs/LINUX/osi_groups.c | 9 ++------- src/afs/LINUX/osi_machdep.h | 9 +++++++-- 4 files changed, 42 insertions(+), 11 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 8c57779..0a05caa 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -812,6 +812,7 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) [write_begin], [fs.h]) AC_CHECK_LINUX_STRUCT([backing_dev_info], [name], [backing-dev.h]) + AC_CHECK_LINUX_STRUCT([cred], [session_keyring], [cred.h]) AC_CHECK_LINUX_STRUCT([ctl_table], [ctl_name], [sysctl.h]) AC_CHECK_LINUX_STRUCT([dentry_operations], [d_automount], [dcache.h]) AC_CHECK_LINUX_STRUCT([inode], [i_alloc_sem], [fs.h]) diff --git a/src/afs/LINUX/osi_compat.h b/src/afs/LINUX/osi_compat.h index 2dda136..a777542 100644 --- a/src/afs/LINUX/osi_compat.h +++ b/src/afs/LINUX/osi_compat.h @@ -186,14 +186,24 @@ afs_linux_key_alloc(struct key_type *type, const char *desc, uid_t uid, } # if defined(STRUCT_TASK_STRUCT_HAS_CRED) +static inline struct key * +afs_session_keyring(afs_ucred_t *cred) +{ +# if defined(STRUCT_CRED_HAS_SESSION_KEYRING) + return cred->session_keyring; +# else + return cred->tgcred->session_keyring; +# endif +} + static inline struct key* afs_linux_search_keyring(afs_ucred_t *cred, struct key_type *type) { key_ref_t key_ref; - if (cred->tgcred->session_keyring) { + if (afs_session_keyring(cred)) { key_ref = keyring_search( - make_key_ref(cred->tgcred->session_keyring, 1), + make_key_ref(afs_session_keyring(cred), 1), type, "_pag"); if (IS_ERR(key_ref)) return ERR_CAST(key_ref); @@ -507,4 +517,24 @@ afs_set_name(afs_name_t aname, char *string) { } #endif +static_inline struct key * +afs_set_session_keyring(struct key *keyring) +{ + struct key *old; +#if defined(STRUCT_CRED_HAS_SESSION_KEYRING) + struct cred *new_creds; + old = current_session_keyring(); + new_creds = prepare_creds(); + rcu_assign_pointer(new_creds->session_keyring, keyring); + commit_creds(new_creds); +#else + spin_lock_irq(¤t->sighand->siglock); + old = task_session_keyring(current); + smp_wmb(); + task_session_keyring(current) = keyring; + spin_unlock_irq(¤t->sighand->siglock); +#endif + return old; +} + #endif /* AFS_LINUX_OSI_COMPAT_H */ diff --git a/src/afs/LINUX/osi_groups.c b/src/afs/LINUX/osi_groups.c index c2a0308..e351344 100644 --- a/src/afs/LINUX/osi_groups.c +++ b/src/afs/LINUX/osi_groups.c @@ -214,14 +214,9 @@ install_session_keyring(struct key *keyring) } /* install the keyring */ - spin_lock_irq(¤t->sighand->siglock); - old = task_session_keyring(current); - smp_wmb(); - task_session_keyring(current) = keyring; - spin_unlock_irq(¤t->sighand->siglock); - + old = afs_set_session_keyring(keyring); if (old) - key_put(old); + key_put(old); out: return code; diff --git a/src/afs/LINUX/osi_machdep.h b/src/afs/LINUX/osi_machdep.h index 9260733..0202d0d 100644 --- a/src/afs/LINUX/osi_machdep.h +++ b/src/afs/LINUX/osi_machdep.h @@ -179,8 +179,13 @@ afs_set_cr_group_info(cred_t *cred, struct group_info *group_info) { # define current_group_info() (current->cred->group_info) # define task_gid(task) (task->cred->gid) # define task_user(task) (task->cred->user) -# define task_session_keyring(task) (task->cred->tgcred->session_keyring) -# define current_session_keyring() (current->cred->tgcred->session_keyring) +# if defined(STRUCT_CRED_HAS_SESSION_KEYRING) +# define task_session_keyring(task) (task->cred->session_keyring) +# define current_session_keyring() (current->cred->session_keyring) +# else +# define task_session_keyring(task) (task->cred->tgcred->session_keyring) +# define current_session_keyring() (current->cred->tgcred->session_keyring) +# endif #else -- 1.7.2.5