From patchwork Wed Jun 1 07:52:58 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolay Borisov X-Patchwork-Id: 628511 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3rKN151qN3z9t7r for ; Wed, 1 Jun 2016 17:54:33 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757417AbcFAHyY (ORCPT ); Wed, 1 Jun 2016 03:54:24 -0400 Received: from mail-wm0-f49.google.com ([74.125.82.49]:38641 "EHLO mail-wm0-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757528AbcFAHxR (ORCPT ); Wed, 1 Jun 2016 03:53:17 -0400 Received: by mail-wm0-f49.google.com with SMTP id a20so15045302wma.1 for ; Wed, 01 Jun 2016 00:53:15 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=p2wpojd7eVtzYVexrdjAC0TSxcioc9Q+6uo6gHX3kYQ=; b=GemL8x9irHjzh795daPXRdEag8+2WNAsFpHS4pN56bupmDLsvB4SfbxfRrUoglaDS+ BF7Rlzm80Vyun8wqDL8KSllxaK6AH8/cTQr5GzM3eq2gbgxrYogDhu/2NGViHcNpv3Un +lb+PS4pGCV92BLtBplCy1pW62Sp9tRgLp2atVAuGkJNW+J3b0n2DnwH/qyzhKwO01VB 6zbxqv6mjT0J3FUEePEc2eRD9qwmH9gGUP9lgkmc0cGFOPhRQLxVE/9zV0mPz0jE9Cgf Moef1voWN+w/unHCBZqsBzcGKak8uGev7kzfBtdSJZpQ9THF73U2AHUMHL38J9nudnK2 vmRw== X-Gm-Message-State: ALyK8tLAjDegJTKvAoNCqrt+uR/iVJbcrljJd30OmVFcdd9bfQl64rAlz7EqsiYjcxrIgl/w X-Received: by 10.28.182.8 with SMTP id g8mr2244581wmf.56.1464767594178; Wed, 01 Jun 2016 00:53:14 -0700 (PDT) Received: from localhost.localdomain (admins.1h.com. [82.118.240.130]) by smtp.gmail.com with ESMTPSA id b189sm33419395wmh.5.2016.06.01.00.53.12 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 01 Jun 2016 00:53:13 -0700 (PDT) From: Nikolay Borisov To: john@johnmccutchan.com, eparis@redhat.com, ebiederm@xmission.com Cc: jack@suse.cz, linux-kernel@vger.kernel.org, gorcunov@openvz.org, avagin@openvz.org, netdev@vger.kernel.org, operations@siteground.com, Nikolay Borisov Subject: [PATCH 2/4] inotify: Convert inotify limits to be accounted per-realuser/per-namespace Date: Wed, 1 Jun 2016 10:52:58 +0300 Message-Id: <1464767580-22732-3-git-send-email-kernel@kyup.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1464767580-22732-1-git-send-email-kernel@kyup.com> References: <1464767580-22732-1-git-send-email-kernel@kyup.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Signed-off-by: Nikolay Borisov --- fs/notify/inotify/inotify_fsnotify.c | 14 +++++++++++++- fs/notify/inotify/inotify_user.c | 23 +++++++++++++++-------- include/linux/sched.h | 2 -- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c index 2cd900c2c737..efaeec3f2e26 100644 --- a/fs/notify/inotify/inotify_fsnotify.c +++ b/fs/notify/inotify/inotify_fsnotify.c @@ -166,7 +166,19 @@ static void inotify_free_group_priv(struct fsnotify_group *group) idr_for_each(&group->inotify_data.idr, idr_callback, group); idr_destroy(&group->inotify_data.idr); if (group->inotify_data.user) { - atomic_dec(&group->inotify_data.user->inotify_devs); + struct user_struct *user = group->inotify_data.user; + void *key = group->inotify_data.userns_ptr; + struct inotify_state *state; + + spin_lock(&user->inotify_lock); + state = __find_inotify_state(user, key); + if (--state->inotify_devs == 0) + hash_del(&state->node); + spin_unlock(&user->inotify_lock); + + if (state->inotify_devs == 0) + kfree(state); + free_uid(group->inotify_data.user); } } diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index ae7ec2414252..e7cc4eaa838f 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c @@ -94,7 +94,7 @@ static int inotify_init_state(struct user_struct *user, int ret = 0; spin_lock(&user->inotify_lock); - state = __find_inotify_count(user, key); + state = __find_inotify_state(user, key); if (!state) { spin_unlock(&user->inotify_lock); @@ -536,7 +536,8 @@ void inotify_ignored_and_remove_idr(struct fsnotify_mark *fsn_mark, /* remove this mark from the idr */ inotify_remove_from_idr(group, i_mark); - atomic_dec(&group->inotify_data.user->inotify_watches); + inotify_dec_watches(group->inotify_data.user, + group->inotify_data.userns_ptr); } /* ding dong the mark is dead */ @@ -609,6 +610,8 @@ static int inotify_new_watch(struct fsnotify_group *group, int ret; struct idr *idr = &group->inotify_data.idr; spinlock_t *idr_lock = &group->inotify_data.idr_lock; + struct user_struct *user = group->inotify_data.user; + void *key = group->inotify_data.userns_ptr; mask = inotify_arg_to_mask(arg); @@ -621,7 +624,7 @@ static int inotify_new_watch(struct fsnotify_group *group, tmp_i_mark->wd = -1; ret = -ENOSPC; - if (atomic_read(&group->inotify_data.user->inotify_watches) >= inotify_max_user_watches) + if (inotify_read_watches(user, key) >= inotify_max_user_watches) goto out_err; ret = inotify_add_to_idr(idr, idr_lock, tmp_i_mark); @@ -638,7 +641,7 @@ static int inotify_new_watch(struct fsnotify_group *group, } /* increment the number of watches the user has */ - atomic_inc(&group->inotify_data.user->inotify_watches); + inotify_inc_watches(user, key); /* return the watch descriptor for this new mark */ ret = tmp_i_mark->wd; @@ -669,6 +672,9 @@ static struct fsnotify_group *inotify_new_group(unsigned int max_events) { struct fsnotify_group *group; struct inotify_event_info *oevent; + struct user_struct *user = get_current_user(); + void *key = current_user_ns(); + int ret; group = fsnotify_alloc_group(&inotify_fsnotify_ops); if (IS_ERR(group)) @@ -689,12 +695,13 @@ static struct fsnotify_group *inotify_new_group(unsigned int max_events) spin_lock_init(&group->inotify_data.idr_lock); idr_init(&group->inotify_data.idr); - group->inotify_data.user = get_current_user(); + group->inotify_data.user = user; + group->inotify_data.userns_ptr = key; - if (atomic_inc_return(&group->inotify_data.user->inotify_devs) > - inotify_max_user_instances) { + ret = inotify_init_state(user, key); + if (ret < 0) { fsnotify_destroy_group(group); - return ERR_PTR(-EMFILE); + return ERR_PTR(ret); } return group; diff --git a/include/linux/sched.h b/include/linux/sched.h index 0c55d951d0bb..8f589b32ed15 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -842,8 +842,6 @@ struct user_struct { #ifdef CONFIG_INOTIFY_USER spinlock_t inotify_lock; DECLARE_HASHTABLE(inotify_tbl, 6); - atomic_t inotify_watches; /* How many inotify watches does this user have? */ - atomic_t inotify_devs; /* How many inotify devs does this user have opened? */ #endif #ifdef CONFIG_FANOTIFY atomic_t fanotify_listeners;