@@ -218,6 +218,20 @@ static inline bool cap_ambient_invariant_ok(const struct cred *cred)
218218 cred -> cap_inheritable ));
219219}
220220
221+ /**
222+ * get_new_cred_many - Get references on a new set of credentials
223+ * @cred: The new credentials to reference
224+ * @nr: Number of references to acquire
225+ *
226+ * Get references on the specified set of new credentials. The caller must
227+ * release all acquired references.
228+ */
229+ static inline struct cred * get_new_cred_many (struct cred * cred , int nr )
230+ {
231+ atomic_add (nr , & cred -> usage );
232+ return cred ;
233+ }
234+
221235/**
222236 * get_new_cred - Get a reference on a new set of credentials
223237 * @cred: The new credentials to reference
@@ -227,31 +241,45 @@ static inline bool cap_ambient_invariant_ok(const struct cred *cred)
227241 */
228242static inline struct cred * get_new_cred (struct cred * cred )
229243{
230- atomic_inc (& cred -> usage );
231- return cred ;
244+ return get_new_cred_many (cred , 1 );
232245}
233246
234247/**
235- * get_cred - Get a reference on a set of credentials
248+ * get_cred_many - Get references on a set of credentials
236249 * @cred: The credentials to reference
250+ * @nr: Number of references to acquire
237251 *
238- * Get a reference on the specified set of credentials. The caller must
239- * release the reference. If %NULL is passed, it is returned with no action.
252+ * Get references on the specified set of credentials. The caller must release
253+ * all acquired reference. If %NULL is passed, it is returned with no action.
240254 *
241255 * This is used to deal with a committed set of credentials. Although the
242256 * pointer is const, this will temporarily discard the const and increment the
243257 * usage count. The purpose of this is to attempt to catch at compile time the
244258 * accidental alteration of a set of credentials that should be considered
245259 * immutable.
246260 */
247- static inline const struct cred * get_cred (const struct cred * cred )
261+ static inline const struct cred * get_cred_many (const struct cred * cred , int nr )
248262{
249263 struct cred * nonconst_cred = (struct cred * ) cred ;
250264 if (!cred )
251265 return cred ;
252266 validate_creds (cred );
253267 nonconst_cred -> non_rcu = 0 ;
254- return get_new_cred (nonconst_cred );
268+ return get_new_cred_many (nonconst_cred , nr );
269+ }
270+
271+ /*
272+ * get_cred - Get a reference on a set of credentials
273+ * @cred: The credentials to reference
274+ *
275+ * Get a reference on the specified set of credentials. The caller must
276+ * release the reference. If %NULL is passed, it is returned with no action.
277+ *
278+ * This is used to deal with a committed set of credentials.
279+ */
280+ static inline const struct cred * get_cred (const struct cred * cred )
281+ {
282+ return get_cred_many (cred , 1 );
255283}
256284
257285static inline const struct cred * get_cred_rcu (const struct cred * cred )
@@ -269,6 +297,7 @@ static inline const struct cred *get_cred_rcu(const struct cred *cred)
269297/**
270298 * put_cred - Release a reference to a set of credentials
271299 * @cred: The credentials to release
300+ * @nr: Number of references to release
272301 *
273302 * Release a reference to a set of credentials, deleting them when the last ref
274303 * is released. If %NULL is passed, nothing is done.
@@ -277,17 +306,29 @@ static inline const struct cred *get_cred_rcu(const struct cred *cred)
277306 * on task_struct are attached by const pointers to prevent accidental
278307 * alteration of otherwise immutable credential sets.
279308 */
280- static inline void put_cred (const struct cred * _cred )
309+ static inline void put_cred_many (const struct cred * _cred , int nr )
281310{
282311 struct cred * cred = (struct cred * ) _cred ;
283312
284313 if (cred ) {
285314 validate_creds (cred );
286- if (atomic_dec_and_test ( & ( cred ) -> usage ))
315+ if (atomic_sub_and_test ( nr , & cred -> usage ))
287316 __put_cred (cred );
288317 }
289318}
290319
320+ /*
321+ * put_cred - Release a reference to a set of credentials
322+ * @cred: The credentials to release
323+ *
324+ * Release a reference to a set of credentials, deleting them when the last ref
325+ * is released. If %NULL is passed, nothing is done.
326+ */
327+ static inline void put_cred (const struct cred * cred )
328+ {
329+ put_cred_many (cred , 1 );
330+ }
331+
291332/**
292333 * current_cred - Access the current task's subjective credentials
293334 *
0 commit comments