@@ -144,7 +144,7 @@ struct mqueue_inode_info {
144144 struct pid * notify_owner ;
145145 u32 notify_self_exec_id ;
146146 struct user_namespace * notify_user_ns ;
147- struct user_struct * user ; /* user who created, for accounting */
147+ struct ucounts * ucounts ; /* user who created, for accounting */
148148 struct sock * notify_sock ;
149149 struct sk_buff * notify_cookie ;
150150
@@ -292,7 +292,6 @@ static struct inode *mqueue_get_inode(struct super_block *sb,
292292 struct ipc_namespace * ipc_ns , umode_t mode ,
293293 struct mq_attr * attr )
294294{
295- struct user_struct * u = current_user ();
296295 struct inode * inode ;
297296 int ret = - ENOMEM ;
298297
@@ -321,7 +320,7 @@ static struct inode *mqueue_get_inode(struct super_block *sb,
321320 info -> notify_owner = NULL ;
322321 info -> notify_user_ns = NULL ;
323322 info -> qsize = 0 ;
324- info -> user = NULL ; /* set when all is ok */
323+ info -> ucounts = NULL ; /* set when all is ok */
325324 info -> msg_tree = RB_ROOT ;
326325 info -> msg_tree_rightmost = NULL ;
327326 info -> node_cache = NULL ;
@@ -371,19 +370,23 @@ static struct inode *mqueue_get_inode(struct super_block *sb,
371370 if (mq_bytes + mq_treesize < mq_bytes )
372371 goto out_inode ;
373372 mq_bytes += mq_treesize ;
374- spin_lock (& mq_lock );
375- if (u -> mq_bytes + mq_bytes < u -> mq_bytes ||
376- u -> mq_bytes + mq_bytes > rlimit (RLIMIT_MSGQUEUE )) {
373+ info -> ucounts = get_ucounts (current_ucounts ());
374+ if (info -> ucounts ) {
375+ long msgqueue ;
376+
377+ spin_lock (& mq_lock );
378+ msgqueue = inc_rlimit_ucounts (info -> ucounts , UCOUNT_RLIMIT_MSGQUEUE , mq_bytes );
379+ if (msgqueue == LONG_MAX || msgqueue > rlimit (RLIMIT_MSGQUEUE )) {
380+ dec_rlimit_ucounts (info -> ucounts , UCOUNT_RLIMIT_MSGQUEUE , mq_bytes );
381+ spin_unlock (& mq_lock );
382+ put_ucounts (info -> ucounts );
383+ info -> ucounts = NULL ;
384+ /* mqueue_evict_inode() releases info->messages */
385+ ret = - EMFILE ;
386+ goto out_inode ;
387+ }
377388 spin_unlock (& mq_lock );
378- /* mqueue_evict_inode() releases info->messages */
379- ret = - EMFILE ;
380- goto out_inode ;
381389 }
382- u -> mq_bytes += mq_bytes ;
383- spin_unlock (& mq_lock );
384-
385- /* all is ok */
386- info -> user = get_uid (u );
387390 } else if (S_ISDIR (mode )) {
388391 inc_nlink (inode );
389392 /* Some things misbehave if size == 0 on a directory */
@@ -497,7 +500,6 @@ static void mqueue_free_inode(struct inode *inode)
497500static void mqueue_evict_inode (struct inode * inode )
498501{
499502 struct mqueue_inode_info * info ;
500- struct user_struct * user ;
501503 struct ipc_namespace * ipc_ns ;
502504 struct msg_msg * msg , * nmsg ;
503505 LIST_HEAD (tmp_msg );
@@ -520,8 +522,7 @@ static void mqueue_evict_inode(struct inode *inode)
520522 free_msg (msg );
521523 }
522524
523- user = info -> user ;
524- if (user ) {
525+ if (info -> ucounts ) {
525526 unsigned long mq_bytes , mq_treesize ;
526527
527528 /* Total amount of bytes accounted for the mqueue */
@@ -533,7 +534,7 @@ static void mqueue_evict_inode(struct inode *inode)
533534 info -> attr .mq_msgsize );
534535
535536 spin_lock (& mq_lock );
536- user -> mq_bytes -= mq_bytes ;
537+ dec_rlimit_ucounts ( info -> ucounts , UCOUNT_RLIMIT_MSGQUEUE , mq_bytes ) ;
537538 /*
538539 * get_ns_from_inode() ensures that the
539540 * (ipc_ns = sb->s_fs_info) is either a valid ipc_ns
@@ -543,7 +544,8 @@ static void mqueue_evict_inode(struct inode *inode)
543544 if (ipc_ns )
544545 ipc_ns -> mq_queues_count -- ;
545546 spin_unlock (& mq_lock );
546- free_uid (user );
547+ put_ucounts (info -> ucounts );
548+ info -> ucounts = NULL ;
547549 }
548550 if (ipc_ns )
549551 put_ipc_ns (ipc_ns );
0 commit comments