* [RFC][PATCH v5 01/09] fs: common implementation of file type
@ 2019-01-21 0:54 Phillip Potter
2019-01-21 15:43 ` Thiago Jung Bauermann
0 siblings, 1 reply; 4+ messages in thread
From: Phillip Potter @ 2019-01-21 0:54 UTC (permalink / raw)
To: viro; +Cc: jack, amir73il, linux-fsdevel
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 <amir73il@gmail.com>
Signed-off-by: Phillip Potter <phil@philpotter.co.uk>
---
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 <linux/fs.h>
+#include <linux/export.h>
+
+/*
+ * 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 <linux/uuid.h>
#include <linux/errseq.h>
#include <linux/ioprio.h>
+#include <linux/fs_types.h>
#include <asm/byteorder.h>
#include <uapi/linux/fs.h>
@@ -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
--
2.20.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [RFC][PATCH v5 01/09] fs: common implementation of file type
2019-01-21 0:54 [RFC][PATCH v5 01/09] fs: common implementation of file type Phillip Potter
@ 2019-01-21 15:43 ` Thiago Jung Bauermann
2019-01-21 16:49 ` Jan Kara
2019-01-22 10:03 ` Phillip Potter
0 siblings, 2 replies; 4+ messages in thread
From: Thiago Jung Bauermann @ 2019-01-21 15:43 UTC (permalink / raw)
To: Phillip Potter; +Cc: viro, jack, amir73il, linux-fsdevel
Hello Phillip,
Just minor nits.
Phillip Potter <phil@philpotter.co.uk> writes:
> 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 <linux/fs.h>
> +#include <linux/export.h>
> +
> +/*
> + * 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
> +};
This array should be const so that it ends up in .rodata.
> +/*
> + * 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,
> +};
This array should be const so that it ends up in .rodata.
--
Thiago Jung Bauermann
IBM Linux Technology Center
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFC][PATCH v5 01/09] fs: common implementation of file type
2019-01-21 15:43 ` Thiago Jung Bauermann
@ 2019-01-21 16:49 ` Jan Kara
2019-01-22 10:03 ` Phillip Potter
1 sibling, 0 replies; 4+ messages in thread
From: Jan Kara @ 2019-01-21 16:49 UTC (permalink / raw)
To: Thiago Jung Bauermann; +Cc: Phillip Potter, viro, jack, amir73il, linux-fsdevel
On Mon 21-01-19 13:43:57, Thiago Jung Bauermann wrote:
>
> Hello Phillip,
>
> Just minor nits.
>
> Phillip Potter <phil@philpotter.co.uk> writes:
>
> > 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 <linux/fs.h>
> > +#include <linux/export.h>
> > +
> > +/*
> > + * 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
> > +};
>
> This array should be const so that it ends up in .rodata.
>
> > +/*
> > + * 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,
> > +};
>
> This array should be const so that it ends up in .rodata.
Good points! I can update this when pushing the patch to my tree. Thanks
for your review.
Honza
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFC][PATCH v5 01/09] fs: common implementation of file type
2019-01-21 15:43 ` Thiago Jung Bauermann
2019-01-21 16:49 ` Jan Kara
@ 2019-01-22 10:03 ` Phillip Potter
1 sibling, 0 replies; 4+ messages in thread
From: Phillip Potter @ 2019-01-22 10:03 UTC (permalink / raw)
To: Thiago Jung Bauermann; +Cc: viro, jack, amir73il, linux-fsdevel
On Mon, Jan 21, 2019 at 01:43:57PM -0200, Thiago Jung Bauermann wrote:
>
> Hello Phillip,
>
> Just minor nits.
>
> Phillip Potter <phil@philpotter.co.uk> writes:
>
> > 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 <linux/fs.h>
> > +#include <linux/export.h>
> > +
> > +/*
> > + * 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
> > +};
>
> This array should be const so that it ends up in .rodata.
>
> > +/*
> > + * 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,
> > +};
>
> This array should be const so that it ends up in .rodata.
>
> --
> Thiago Jung Bauermann
> IBM Linux Technology Center
>
Dear Thiago,
Thank you for these suggestions. Don't know why I didn't spot
this myself. As Jan has kindly offered to make this change upon
including this in his tree, I will forgo publishing the corrections
on this occasion.
Regards,
Phil
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2019-01-22 10:03 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-21 0:54 [RFC][PATCH v5 01/09] fs: common implementation of file type Phillip Potter
2019-01-21 15:43 ` Thiago Jung Bauermann
2019-01-21 16:49 ` Jan Kara
2019-01-22 10:03 ` Phillip Potter
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).