From patchwork Mon Jan 21 00:54:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phillip Potter X-Patchwork-Id: 10773201 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 10BA014E5 for ; Mon, 21 Jan 2019 08:20:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F32C129B02 for ; Mon, 21 Jan 2019 08:20:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E74EA29EEA; Mon, 21 Jan 2019 08:20:47 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2DAA229B02 for ; Mon, 21 Jan 2019 08:20:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729526AbfAUIUi (ORCPT ); Mon, 21 Jan 2019 03:20:38 -0500 Received: from mail-wr1-f65.google.com ([209.85.221.65]:42828 "EHLO mail-wr1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727993AbfAUIUh (ORCPT ); Mon, 21 Jan 2019 03:20:37 -0500 Received: by mail-wr1-f65.google.com with SMTP id q18so22128903wrx.9 for ; Mon, 21 Jan 2019 00:20:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=philpotter-co-uk.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:mime-version:content-disposition :user-agent; bh=rhUlWcoSXvKZI4bRokQXi9wFoSLeSonaISFpUPyRSBc=; b=YlD7QknWvUB0aZjejMmOhhhXxRJNd71lBdasWdprXZBjf5Ai2UlbdUypv08fa5sdW4 LdHKyzAWaLiWfbwNjxqvQ+xVkTiZmiKcWAcVgohyBlFmyBGcGOlieNa49YJJ7HyS7aW5 2TatnDrY5zpfX4nITyfnUcdLyxyHBnQX58CcE+upQhV1mcaTg2hLXQ9PgGbAGFUsjNSd RizI6YmHPg1iZ27ouIVRu3Hktdn7Zn9t2+SDijqYteh79OKjfIBGLYDRdpsto1Lb63ew Qjvp4jyDwuXOglFU5/1Jch5Rj3qSaDt5/XE96DECKvyZmesvv7kW2lm1KZWBJsdn/LlF LDBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:mime-version :content-disposition:user-agent; bh=rhUlWcoSXvKZI4bRokQXi9wFoSLeSonaISFpUPyRSBc=; b=ibo1NY0vGMgMZNRgszpFoxdqEDpw7CsI/x0yLms403IWeBgksPCQWinUZrBr+Ccy2Q aUq8xHVhX30g3KYOcDHXyHdvpvT47W8yhcIz3kE1jplg6iDtKPvJQByLvLpXO/R+9D4u Bg/iF5+aUc3/cHftW2UVYc2QWw1RSp6kNHDDvSgClsUXm9pZAgDQ7LvPhVnrXiG764wW 5Seelqf5vsHsfxc2wzOve9xY0SjyF8J0Ma2K6z9rsmNGhaFKP8/caIkyNZWSrdiwcr3V EsvFP1iTeqtbM9ownkUHJQYUOEvaN62capYezGd5FJkPBYrwPRxqzGOMPp1iiBxcbi6P KKGw== X-Gm-Message-State: AJcUuke/mIUCcp/p3vahQpwwLzgBxKv8HliQXjNCQqCvqN50xWhAuKtn OiMM47mf4xFwSCa0KPws3E1H1Fj2bfjFgw== X-Google-Smtp-Source: ALg8bN7kOZAD0No0shqatMVRnUDbOk8VUi0LgymMIgfcewIMM85WS+7HkwHgilQhsioC+NE3TZvt5w== X-Received: by 2002:adf:fe8f:: with SMTP id l15mr10434801wrr.313.1548032068986; Sun, 20 Jan 2019 16:54:28 -0800 (PST) Received: from pathfinder ([90.222.17.17]) by smtp.gmail.com with ESMTPSA id x12sm70519613wrt.20.2019.01.20.16.54.28 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Sun, 20 Jan 2019 16:54:28 -0800 (PST) Date: Mon, 21 Jan 2019 00:54:27 +0000 From: Phillip Potter To: viro@zeniv.linux.org.uk Cc: jack@suse.cz, amir73il@gmail.com, linux-fsdevel@vger.kernel.org Subject: [RFC][PATCH v5 01/09] fs: common implementation of file type Message-ID: <20190121005427.GA32322@pathfinder> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Many file systems use a copy&paste implementation of dirent to on-disk file type conversions. Create a common implementation to be used by file systems with some useful conversion helpers to reduce open coded file type conversions in file system code. Signed-off-by: Amir Goldstein Signed-off-by: Phillip Potter --- MAINTAINERS | 1 + fs/Makefile | 3 +- fs/fs_types.c | 105 +++++++++++++++++++++++++++++++++++++++ include/linux/fs.h | 17 +------ include/linux/fs_types.h | 75 ++++++++++++++++++++++++++++ 5 files changed, 184 insertions(+), 17 deletions(-) create mode 100644 fs/fs_types.c create mode 100644 include/linux/fs_types.h diff --git a/MAINTAINERS b/MAINTAINERS index 4d04cebb4a71..f0f7d7750a38 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5882,6 +5882,7 @@ L: linux-fsdevel@vger.kernel.org S: Maintained F: fs/* F: include/linux/fs.h +F: include/linux/fs_types.h F: include/uapi/linux/fs.h FINTEK F75375S HARDWARE MONITOR AND FAN CONTROLLER DRIVER diff --git a/fs/Makefile b/fs/Makefile index 293733f61594..23fcd8c164a3 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -12,7 +12,8 @@ obj-y := open.o read_write.o file_table.o super.o \ attr.o bad_inode.o file.o filesystems.o namespace.o \ seq_file.o xattr.o libfs.o fs-writeback.o \ pnode.o splice.o sync.o utimes.o d_path.o \ - stack.o fs_struct.o statfs.o fs_pin.o nsfs.o + stack.o fs_struct.o statfs.o fs_pin.o nsfs.o \ + fs_types.o ifeq ($(CONFIG_BLOCK),y) obj-y += buffer.o block_dev.o direct-io.o mpage.o diff --git a/fs/fs_types.c b/fs/fs_types.c new file mode 100644 index 000000000000..6fc57f4b1dcb --- /dev/null +++ b/fs/fs_types.c @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include + +/* + * fs on-disk file type to dirent file type conversion + */ +static unsigned char fs_dtype_by_ftype[FT_MAX] = { + [FT_UNKNOWN] = DT_UNKNOWN, + [FT_REG_FILE] = DT_REG, + [FT_DIR] = DT_DIR, + [FT_CHRDEV] = DT_CHR, + [FT_BLKDEV] = DT_BLK, + [FT_FIFO] = DT_FIFO, + [FT_SOCK] = DT_SOCK, + [FT_SYMLINK] = DT_LNK +}; + +/** + * fs_ftype_to_dtype() - fs on-disk file type to dirent type. + * @filetype: The on-disk file type to convert. + * + * This function converts the on-disk file type value (FT_*) to the directory + * entry type (DT_*). + * + * Context: Any context. + * Return: + * * DT_UNKNOWN - Unknown type + * * DT_FIFO - FIFO + * * DT_CHR - Character device + * * DT_DIR - Directory + * * DT_BLK - Block device + * * DT_REG - Regular file + * * DT_LNK - Symbolic link + * * DT_SOCK - Local-domain socket + */ +unsigned char fs_ftype_to_dtype(unsigned int filetype) +{ + if (filetype >= FT_MAX) + return DT_UNKNOWN; + + return fs_dtype_by_ftype[filetype]; +} +EXPORT_SYMBOL_GPL(fs_ftype_to_dtype); + +/* + * dirent file type to fs on-disk file type conversion + * Values not initialized explicitly are FT_UNKNOWN (0). + */ +static unsigned char fs_ftype_by_dtype[DT_MAX] = { + [DT_REG] = FT_REG_FILE, + [DT_DIR] = FT_DIR, + [DT_LNK] = FT_SYMLINK, + [DT_CHR] = FT_CHRDEV, + [DT_BLK] = FT_BLKDEV, + [DT_FIFO] = FT_FIFO, + [DT_SOCK] = FT_SOCK, +}; + +/** + * fs_umode_to_ftype() - file mode to on-disk file type. + * @mode: The file mode to convert. + * + * This function converts the file mode value to the on-disk file type (FT_*). + * + * Context: Any context. + * Return: + * * FT_UNKNOWN - Unknown type + * * FT_REG_FILE - Regular file + * * FT_DIR - Directory + * * FT_CHRDEV - Character device + * * FT_BLKDEV - Block device + * * FT_FIFO - FIFO + * * FT_SOCK - Local-domain socket + * * FT_SYMLINK - Symbolic link + */ +unsigned char fs_umode_to_ftype(umode_t mode) +{ + return fs_ftype_by_dtype[S_DT(mode)]; +} +EXPORT_SYMBOL_GPL(fs_umode_to_ftype); + +/** + * fs_umode_to_dtype() - file mode to dirent file type. + * @mode: The file mode to convert. + * + * This function converts the file mode value to the directory + * entry type (DT_*). + * + * Context: Any context. + * Return: + * * DT_UNKNOWN - Unknown type + * * DT_FIFO - FIFO + * * DT_CHR - Character device + * * DT_DIR - Directory + * * DT_BLK - Block device + * * DT_REG - Regular file + * * DT_LNK - Symbolic link + * * DT_SOCK - Local-domain socket + */ +unsigned char fs_umode_to_dtype(umode_t mode) +{ + return fs_ftype_to_dtype(fs_umode_to_ftype(mode)); +} +EXPORT_SYMBOL_GPL(fs_umode_to_dtype); diff --git a/include/linux/fs.h b/include/linux/fs.h index 811c77743dad..92966678539d 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -1699,22 +1700,6 @@ int fiemap_fill_next_extent(struct fiemap_extent_info *info, u64 logical, u64 phys, u64 len, u32 flags); int fiemap_check_flags(struct fiemap_extent_info *fieinfo, u32 fs_flags); -/* - * File types - * - * NOTE! These match bits 12..15 of stat.st_mode - * (ie "(i_mode >> 12) & 15"). - */ -#define DT_UNKNOWN 0 -#define DT_FIFO 1 -#define DT_CHR 2 -#define DT_DIR 4 -#define DT_BLK 6 -#define DT_REG 8 -#define DT_LNK 10 -#define DT_SOCK 12 -#define DT_WHT 14 - /* * This is the "filldir" function type, used by readdir() to let * the kernel specify what kind of dirent layout it wants to have. diff --git a/include/linux/fs_types.h b/include/linux/fs_types.h new file mode 100644 index 000000000000..54816791196f --- /dev/null +++ b/include/linux/fs_types.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_FS_TYPES_H +#define _LINUX_FS_TYPES_H + +/* + * This is a header for the common implementation of dirent + * to fs on-disk file type conversion. Although the fs on-disk + * bits are specific to every file system, in practice, many + * file systems use the exact same on-disk format to describe + * the lower 3 file type bits that represent the 7 POSIX file + * types. + * + * It is important to note that the definitions in this + * header MUST NOT change. This would break both the + * userspace ABI and the on-disk format of filesystems + * using this code. + * + * All those file systems can use this generic code for the + * conversions. + */ + +/* + * struct dirent file types + * exposed to user via getdents(2), readdir(3) + * + * These match bits 12..15 of stat.st_mode + * (ie "(i_mode >> 12) & 15"). + */ +#define S_DT_SHIFT 12 +#define S_DT(mode) (((mode) & S_IFMT) >> S_DT_SHIFT) +#define S_DT_MASK (S_IFMT >> S_DT_SHIFT) + +/* these are defined by POSIX and also present in glibc's dirent.h */ +#define DT_UNKNOWN 0 +#define DT_FIFO 1 +#define DT_CHR 2 +#define DT_DIR 4 +#define DT_BLK 6 +#define DT_REG 8 +#define DT_LNK 10 +#define DT_SOCK 12 +#define DT_WHT 14 + +#define DT_MAX (S_DT_MASK + 1) /* 16 */ + +/* + * fs on-disk file types. + * Only the low 3 bits are used for the POSIX file types. + * Other bits are reserved for fs private use. + * These definitions are shared and used by multiple filesystems, + * and MUST NOT change under any circumstances. + * + * Note that no fs currently stores the whiteout type on-disk, + * so whiteout dirents are exposed to user as DT_CHR. + */ +#define FT_UNKNOWN 0 +#define FT_REG_FILE 1 +#define FT_DIR 2 +#define FT_CHRDEV 3 +#define FT_BLKDEV 4 +#define FT_FIFO 5 +#define FT_SOCK 6 +#define FT_SYMLINK 7 + +#define FT_MAX 8 + +/* + * declarations for helper functions, accompanying implementation + * is in fs/fs_types.c + */ +extern unsigned char fs_ftype_to_dtype(unsigned int filetype); +extern unsigned char fs_umode_to_ftype(umode_t mode); +extern unsigned char fs_umode_to_dtype(umode_t mode); + +#endif