Received: by 10.223.185.111 with SMTP id b44csp1643867wrg; Sat, 10 Mar 2018 10:27:05 -0800 (PST) X-Google-Smtp-Source: AG47ELu//85os3k1aZHL/YxLd2qGov0BgtK5qp+I3DHfrULZGUkVSqum2mA1RdNWAJgQHrxIoY4I X-Received: by 2002:a17:902:aa89:: with SMTP id d9-v6mr2748677plr.337.1520706424965; Sat, 10 Mar 2018 10:27:04 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520706424; cv=none; d=google.com; s=arc-20160816; b=aM2WB5TNRMCSazWPUOZRjcqi/Jbw53aqd70GJtq1bXkEQqNEzuG5qGyGxuzMMsIRoj lU2i7VdNQb+No7P8Hdz6IHnM12M6mRJ4yNCFORL05A7398EIqk1JFMj1BoAGSWaxKLCP 4nUV1fvR38bXvR88m+ftHIW0dQdeC++njUlBDJJonAVuGjrLEiXONO4/ANCEb2TFhjtB c6iS3Jvl8FYVTARPrSjF5ddIedxDXA5pCswke6kxtK+ru0kY8SgO+qEoqGIBivuUXwO7 Mqln5hQt7mZa/6a6XU7TeR/OGIIUxBNOABQiLvEPq1m4VZDGiaRTeNRWkc6unnxGLv6Q C8Uw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=yd+84+j3iEoEam5TkIADwdGgMrtQ2QxxG+sExNSVx/Q=; b=pw/XUXE2LhjpLYmyqS45N3j2Xzxia8MHZv2rd2s+zqEflioeCEQJk6vi7EUR37GPxm OFHDE/OdP8cOtkyH74Jx/xIECupnw+rBVltdWaCiPplBbH9T6PIK6K7JsFkioROEOx+w 4TCH2hBgwpyulyvy5JwHno4KEE/b6ZHPHgjCx2d63JUgv05e5JibYCJ0KmOcJFitGtau JSidlC0j8BDbpWnQ9f23fdaJD9Z5KXjeJIyTlhvlChOW2K5a//mSXb+o9rAgiUx/+Gjm 7baERsoSwEBlHl7qN55mPrgoehnIdSQckVfUjKWHyIOr5aAKbe75n83UZOs2zlXX0n06 t3kg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@eng.ucsd.edu header.s=google header.b=a1TjKQ2s; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j12si2577064pgn.115.2018.03.10.10.26.50; Sat, 10 Mar 2018 10:27:04 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@eng.ucsd.edu header.s=google header.b=a1TjKQ2s; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933070AbeCJSYP (ORCPT + 99 others); Sat, 10 Mar 2018 13:24:15 -0500 Received: from mail-pf0-f196.google.com ([209.85.192.196]:34961 "EHLO mail-pf0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932925AbeCJSVs (ORCPT ); Sat, 10 Mar 2018 13:21:48 -0500 Received: by mail-pf0-f196.google.com with SMTP id y186so2627314pfb.2 for ; Sat, 10 Mar 2018 10:21:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=eng.ucsd.edu; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=yd+84+j3iEoEam5TkIADwdGgMrtQ2QxxG+sExNSVx/Q=; b=a1TjKQ2shuxsnPCghv98paTB2VAEIxwojPuG7DBipFT7uOVOcAu94nQ1ejBHSYV8Sv O6sGatmWwxxLsSyTEYpButVWnM0m+6qEKZ/57Z19u8S2Rt/fFI2lQmcZaC2ogMZ+vZ55 zPeySfs/eNwP+l8XLZl9NpXbK3z7LKZ/RVKIY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=yd+84+j3iEoEam5TkIADwdGgMrtQ2QxxG+sExNSVx/Q=; b=aBZC3Y5XNs7A8RtuJcuObV+bLeu07g0jSsxWcvt5am0eaj487f8ESsP3r362VQnuHZ ih0/X8Vxpyfs8ZBKYjqA1jSrg2pLSrC0GmGvZitUs+y78jykmTW89caCNzxwFYQyTlxr kz+CAwqd1BL/y96BhabkVc8Um98I5jMNyQKmmNj0B9ma9qhnBcpfB3RUuuLm8U3o+Jdr s7ucdCRSn7o6STrI3Ix2+dK0LroxaLL6vCq54VHX8Ia2ooJ1MyRMeyYhCSSiywyvmV0W ksqQv+cS1ynOaqyt5TWlCp5h9SvwZGDFu/YIPcv2VN06QXHWSFc+Ew2YkSOtZZTSYKvz mBIA== X-Gm-Message-State: AElRT7EyQh1DrRSr6MNDKS92jRf1UEa903mYyyQVzgc1wT5BdjAoqZMi ++OHTIpSWWwZkPXZ5qwFyV35qA== X-Received: by 10.98.147.156 with SMTP id r28mr2691177pfk.204.1520706108217; Sat, 10 Mar 2018 10:21:48 -0800 (PST) Received: from brienza-desktop.8.8.4.4 (andxu.ucsd.edu. [132.239.17.134]) by smtp.gmail.com with ESMTPSA id h80sm9210167pfj.181.2018.03.10.10.21.47 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 10 Mar 2018 10:21:47 -0800 (PST) From: Andiry Xu To: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nvdimm@lists.01.org Cc: dan.j.williams@intel.com, andy.rudoff@intel.com, coughlan@redhat.com, swanson@cs.ucsd.edu, david@fromorbit.com, jack@suse.com, swhiteho@redhat.com, miklos@szeredi.hu, andiry.xu@gmail.com, Andiry Xu Subject: [RFC v2 76/83] Ioctl support. Date: Sat, 10 Mar 2018 10:18:57 -0800 Message-Id: <1520705944-6723-77-git-send-email-jix024@eng.ucsd.edu> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1520705944-6723-1-git-send-email-jix024@eng.ucsd.edu> References: <1520705944-6723-1-git-send-email-jix024@eng.ucsd.edu> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Andiry Xu NOVA appends link change entry to the inode log to implement SETFLAGS and SETVERSION. Signed-off-by: Andiry Xu --- fs/nova/Makefile | 4 +- fs/nova/dir.c | 4 ++ fs/nova/file.c | 4 ++ fs/nova/inode.h | 2 + fs/nova/ioctl.c | 184 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/nova/nova.h | 7 +++ 6 files changed, 203 insertions(+), 2 deletions(-) create mode 100644 fs/nova/ioctl.c diff --git a/fs/nova/Makefile b/fs/nova/Makefile index 7bf6403..87e56c6 100644 --- a/fs/nova/Makefile +++ b/fs/nova/Makefile @@ -4,5 +4,5 @@ obj-$(CONFIG_NOVA_FS) += nova.o -nova-y := balloc.o bbuild.o dax.o dir.o file.o inode.o journal.o log.o namei.o\ - rebuild.o stats.o super.o symlink.o +nova-y := balloc.o bbuild.o dax.o dir.o file.o inode.o ioctl.o journal.o\ + log.o namei.o rebuild.o stats.o super.o symlink.o diff --git a/fs/nova/dir.c b/fs/nova/dir.c index 47ee9ad..3694d9d 100644 --- a/fs/nova/dir.c +++ b/fs/nova/dir.c @@ -513,4 +513,8 @@ const struct file_operations nova_dir_operations = { .read = generic_read_dir, .iterate = nova_readdir, .fsync = noop_fsync, + .unlocked_ioctl = nova_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = nova_compat_ioctl, +#endif }; diff --git a/fs/nova/file.c b/fs/nova/file.c index 7e90415..2b70b9d 100644 --- a/fs/nova/file.c +++ b/fs/nova/file.c @@ -714,7 +714,11 @@ const struct file_operations nova_dax_file_operations = { .open = nova_open, .fsync = nova_fsync, .flush = nova_flush, + .unlocked_ioctl = nova_ioctl, .fallocate = nova_fallocate, +#ifdef CONFIG_COMPAT + .compat_ioctl = nova_compat_ioctl, +#endif }; const struct inode_operations nova_file_inode_operations = { diff --git a/fs/nova/inode.h b/fs/nova/inode.h index 693aa90..086a7cb 100644 --- a/fs/nova/inode.h +++ b/fs/nova/inode.h @@ -264,6 +264,8 @@ int nova_delete_file_tree(struct super_block *sb, struct nova_inode_info_header *sih, unsigned long start_blocknr, unsigned long last_blocknr, bool delete_nvmm, bool delete_dead, u64 epoch_id); +extern void nova_set_inode_flags(struct inode *inode, struct nova_inode *pi, + unsigned int flags); unsigned long nova_find_region(struct inode *inode, loff_t *offset, int hole); extern void nova_evict_inode(struct inode *inode); extern int nova_write_inode(struct inode *inode, struct writeback_control *wbc); diff --git a/fs/nova/ioctl.c b/fs/nova/ioctl.c new file mode 100644 index 0000000..2509371 --- /dev/null +++ b/fs/nova/ioctl.c @@ -0,0 +1,184 @@ +/* + * BRIEF DESCRIPTION + * + * Ioctl operations. + * + * Copyright 2015-2016 Regents of the University of California, + * UCSD Non-Volatile Systems Lab, Andiry Xu + * Copyright 2012-2013 Intel Corporation + * Copyright 2010-2011 Marco Stornelli + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include "nova.h" +#include "inode.h" + +long nova_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + struct address_space *mapping = filp->f_mapping; + struct inode *inode = mapping->host; + struct nova_inode_info *si = NOVA_I(inode); + struct nova_inode_info_header *sih = &si->header; + struct nova_inode *pi; + struct super_block *sb = inode->i_sb; + struct nova_inode_update update; + unsigned int flags; + int ret; + + pi = nova_get_inode(sb, inode); + if (!pi) + return -EACCES; + + switch (cmd) { + case FS_IOC_GETFLAGS: + flags = (sih->i_flags) & NOVA_FL_USER_VISIBLE; + return put_user(flags, (int __user *)arg); + case FS_IOC_SETFLAGS: { + unsigned int oldflags; + u64 old_linkc = 0; + u64 epoch_id; + + ret = mnt_want_write_file(filp); + if (ret) + return ret; + + if (!inode_owner_or_capable(inode)) { + ret = -EPERM; + goto flags_out; + } + + if (get_user(flags, (int __user *)arg)) { + ret = -EFAULT; + goto flags_out; + } + + inode_lock(inode); + sih_lock(sih); + oldflags = le32_to_cpu(pi->i_flags); + + if ((flags ^ oldflags) & + (FS_APPEND_FL | FS_IMMUTABLE_FL)) { + if (!capable(CAP_LINUX_IMMUTABLE)) { + inode_unlock(inode); + ret = -EPERM; + goto flags_out_unlock; + } + } + + if (!S_ISDIR(inode->i_mode)) + flags &= ~FS_DIRSYNC_FL; + + epoch_id = nova_get_epoch_id(sb); + flags = flags & FS_FL_USER_MODIFIABLE; + flags |= oldflags & ~FS_FL_USER_MODIFIABLE; + inode->i_ctime = current_time(inode); + nova_set_inode_flags(inode, pi, flags); + sih->i_flags = flags; + + update.tail = 0; + ret = nova_append_link_change_entry(sb, pi, inode, + &update, &old_linkc, epoch_id); + if (!ret) { + nova_update_inode(sb, inode, pi, &update); + nova_invalidate_link_change_entry(sb, old_linkc); + } + sih->trans_id++; +flags_out_unlock: + sih_unlock(sih); + inode_unlock(inode); +flags_out: + mnt_drop_write_file(filp); + return ret; + } + case FS_IOC_GETVERSION: + return put_user(inode->i_generation, (int __user *)arg); + case FS_IOC_SETVERSION: { + u64 old_linkc = 0; + u64 epoch_id; + __u32 generation; + + if (!inode_owner_or_capable(inode)) + return -EPERM; + ret = mnt_want_write_file(filp); + if (ret) + return ret; + if (get_user(generation, (int __user *)arg)) { + ret = -EFAULT; + goto setversion_out; + } + + epoch_id = nova_get_epoch_id(sb); + inode_lock(inode); + sih_lock(sih); + inode->i_ctime = current_time(inode); + inode->i_generation = generation; + + update.tail = 0; + ret = nova_append_link_change_entry(sb, pi, inode, + &update, &old_linkc, epoch_id); + if (!ret) { + nova_update_inode(sb, inode, pi, &update); + nova_invalidate_link_change_entry(sb, old_linkc); + } + sih->trans_id++; + sih_unlock(sih); + inode_unlock(inode); +setversion_out: + mnt_drop_write_file(filp); + return ret; + } + case NOVA_PRINT_TIMING: { + nova_print_timing_stats(sb); + return 0; + } + case NOVA_CLEAR_STATS: { + nova_clear_stats(sb); + return 0; + } + case NOVA_PRINT_LOG: { + nova_print_inode_log(sb, inode); + return 0; + } + case NOVA_PRINT_LOG_PAGES: { + nova_print_inode_log_pages(sb, inode); + return 0; + } + case NOVA_PRINT_FREE_LISTS: { + nova_print_free_lists(sb); + return 0; + } + default: + return -ENOTTY; + } +} + +#ifdef CONFIG_COMPAT +long nova_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + switch (cmd) { + case FS_IOC32_GETFLAGS: + cmd = FS_IOC_GETFLAGS; + break; + case FS_IOC32_SETFLAGS: + cmd = FS_IOC_SETFLAGS; + break; + case FS_IOC32_GETVERSION: + cmd = FS_IOC_GETVERSION; + break; + case FS_IOC32_SETVERSION: + cmd = FS_IOC_SETVERSION; + break; + default: + return -ENOIOCTLCMD; + } + return nova_ioctl(file, cmd, (unsigned long)compat_ptr(arg)); +} +#endif diff --git a/fs/nova/nova.h b/fs/nova/nova.h index d209cfc..ab9153e 100644 --- a/fs/nova/nova.h +++ b/fs/nova/nova.h @@ -515,6 +515,13 @@ int nova_remove_dentry(struct dentry *dentry, int dec_link, extern const struct file_operations nova_dax_file_operations; extern const struct inode_operations nova_file_inode_operations; +/* ioctl.c */ +extern long nova_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); +#ifdef CONFIG_COMPAT +extern long nova_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg); +#endif + /* namei.c */ extern const struct inode_operations nova_dir_inode_operations; extern const struct inode_operations nova_special_inode_operations; -- 2.7.4