Skip to contentSkip to conversation

exofs

PATCH In review Boaz Harrosh 6 participants 32 messages Feb 9, 2009 – Mar 15, 2009

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

cover exofs

exofs is a file system that uses an OSD device as it's back store.

OSD is a new T10 command set that views storage devices not as a large/flat array of sectors but as a container of objects, each having a length, quota, time attributes and more. Each object is addressed by a 64bit ID, and is contained in a 64bit ID partition. Each object has associated attributes attached to it, which are integral part of the object and provide metadata about the object. The standard defines some common obligatory attributes, but user attributes can be added as needed.

What's new since last iteration:
Lots and lots of changes the actual diff is big.

- mkexofs is removed from Kernel code
Open-osd has a user-mode library now. It is the exact same API (and source) as the Kernel library. Commands are issued through (patched) bsg.ko. If anyone is interested see URLs below, patches will be sent to the open-osd-mailing-list. Horay.

- Incorporate changes made to ext2 since exofs was first derived. Thanks to Andrew Morton, I've referred to the git-log of fs/ext2 and have incorporated all relevant changes into exofs. Lots of bug fixes and short comings where fixed this way.

- Made everything LE safe.
All on disk types are now using proper Endian types, and properly converted back and forth. exofs is an LE filesystem just as ext2.

- Completely got rid of IBM API
Previous version was using IBM API for osd commands and those API where implemented over open-osd in osd.c. open-osd API is now used directly and osd.c is reduced to a few exofs internal helpers.

- A sleep forever Bug fix, related to async object creation.

- Cleaned up some usage of types, naming conventions, code organization. Lots of cleanups, and reorganization.

And the regular information for first comers

Our intention with exofs is to make it exportable by Linux pNFS server, as reference implementation for pNFS-object-layout server. A pNFS-objects client implementation is also in the works (See all about pNFS in Linux at:
http://wiki.linux-nfs.org/wiki/index.php/PNFS_prototype_design)

exofs was originally developed by Avishay Traeger <[email protected]> from IBM. A very old version of it is hosted on sourceforge as the osdfs project. The Original code was based on ext2 of the 2.6.10 Kernel and ran over the old IBM's osd-initiator Linux driver.
Since then it was picked by us, open-osd, and was both forward ported to current Kernel, as well as converted to run over open-osd Kernel Library.

I have mechanically divided the code in parts, each introducing a group of vfs function vectors, all tied at the end into a full filesystem. Each patch can be compiled but it will only run at the very end. This was done for the hope of easier reviewing.

Here is the list of patches
[PATCH 1/8] exofs: Kbuild, Headers and osd utils
[PATCH 2/8] exofs: file and file_inode operations [PATCH 3/8] exofs: symlink_inode and fast_symlink_inode operations [PATCH 4/8] exofs: address_space_operations
[PATCH 5/8] exofs: dir_inode and directory operations [PATCH 6/8] exofs: super_operations and file_system_type [PATCH 7/8] exofs: Documentation
[PATCH 8/8] fs: Add exofs to Kernel build

This patchset is also available on:
git-clone git://git.open-osd.org/linux-open-osd.git linux-next
or on the web at:
http://git.open-osd.org/gitweb.cgi?p=linux-open-osd.git;a=shortlog;h=refs/heads/linux-next

(Above tree is based on Linus 2.6.29-rc4)

If anyone wants to actually run this code and test it then please start reading at:

    http://open-osd.org

You will need to checkout the out-of-tree git (below) for the user-mode utilities. Also the exofs.txt file in patch 7/8 should help

If you want to review the user-mode library and supporting plumbings, patches will be sent to this mailing-list:
http://www.open-osd.org/bin/view/Main/MailingList

And code is on this git-tree:
git-clone git://git.open-osd.org/open-osd.git
or on the web at:
http://git.open-osd.org/gitweb.cgi?p=open-osd.git;a=summary

Thank you all for the very useful comments, suggestions, and banging me on the head about the user-mode API.

Boaz

#1 lore raw

PATCH 1/8 exofs: Kbuild, Headers and osd utils

This patch includes osd infrastructure that will be used later by the file system.

Also the declarations of constants, on disk structures, and prototypes.

And the Kbuild+Kconfig files needed to build the exofs module.

---
 fs/exofs/Kbuild   |   30 +++++++
 fs/exofs/Kconfig  |   13 +++
 fs/exofs/common.h |  181 +++++++++++++++++++++++++++++++++++++++++
 fs/exofs/exofs.h  |  139 ++++++++++++++++++++++++++++++++
 fs/exofs/osd.c    |  230 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 593 insertions(+), 0 deletions(-)
 create mode 100644 fs/exofs/Kbuild
 create mode 100644 fs/exofs/Kconfig
 create mode 100644 fs/exofs/common.h
 create mode 100644 fs/exofs/exofs.h
 create mode 100644 fs/exofs/osd.c
fs/exofs/Kbuild new file +30 -0
new file mode 100644
index 0000000..c806738
@@ -0,0 +1,30 @@
+#
+# Kbuild for the EXOFS module
+#
+# Copyright (C) 2008 Panasas Inc.  All rights reserved.
+#
+# Authors:
+#   Boaz Harrosh <[email protected]>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2
+#
+# Kbuild - Gets included from the Kernels Makefile and build system
+#
+
+ifneq ($(OSD_INC),)
+# we are built out-of-tree Kconfigure everything as on
+
+CONFIG_EXOFS_FS=m
+ccflags-y += -DCONFIG_EXOFS_FS -DCONFIG_EXOFS_FS_MODULE
+# ccflags-y += -DCONFIG_EXOFS_DEBUG
+
+# if we are built out-of-tree and the hosting kernel has OSD headers
+# then "ccflags-y +=" will not pick the out-off-tree headers. Only by doing
+# this it will work. This might break in future kernels
+KBUILD_CPPFLAGS := -I$(OSD_INC) $(KBUILD_CPPFLAGS)
+
+endif
+
+exofs-objs := osd.o
+obj-$(CONFIG_EXOFS_FS) += exofs.o
fs/exofs/Kconfig new file +13 -0
new file mode 100644
index 0000000..86194b2
@@ -0,0 +1,13 @@
+config EXOFS_FS
+	tristate "exofs: OSD based file system support"
+	depends on SCSI_OSD_ULD
+	help
+	  EXOFS is a file system that uses an OSD storage device,
+	  as its backing storage.
+
+# Debugging-related stuff
+config EXOFS_DEBUG
+	bool "Enable debugging"
+	depends on EXOFS_FS
+	help
+	  This option enables EXOFS debug prints.
fs/exofs/common.h new file +181 -0

181 lines not on this page · raw message

fs/exofs/exofs.h new file +139 -0

139 lines not on this page · raw message

fs/exofs/osd.c new file +230 -0

230 lines not on this page · raw message

Signature · 1 line
1.6.0.1
#19 lore raw

PATCH 2/8 exofs: file and file_inode operations

In reply to Boaz Harrosh

implementation of the file_operations and inode_operations for regular data files.

Most file_operations are generic vfs implementations except:
- exofs_truncate will truncate the OSD object as well
- Generic file_fsync is not good for none_bd devices so open code it
- The default for .flush in Linux is todo nothing so call exofs_fsync on the file.

---
 fs/exofs/Kbuild  |    2 +-
 fs/exofs/exofs.h |   11 ++++
 fs/exofs/file.c  |   82 ++++++++++++++++++++++++++++++
 fs/exofs/inode.c |  148 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 242 insertions(+), 1 deletions(-)
 create mode 100644 fs/exofs/file.c
 create mode 100644 fs/exofs/inode.c
fs/exofs/Kbuild +1 -1
index c806738..d8bd4d5 100644
@@ -26,5 +26,5 @@ KBUILD_CPPFLAGS := -I$(OSD_INC) $(KBUILD_CPPFLAGS)
 
 endif
 
-exofs-objs := osd.o
+exofs-objs := osd.o inode.o file.o
 obj-$(CONFIG_EXOFS_FS) += exofs.o
fs/exofs/exofs.h +11 -0
index 0637237..b6d9089 100644
@@ -136,4 +136,15 @@ int osd_req_write_pages(struct osd_request *or,
 	const struct osd_obj_id *, u64 offset, u64 length,
 	struct page **pages, int page_count);
 
+/* inode.c               */
+void exofs_truncate(struct inode *inode);
+int exofs_setattr(struct dentry *, struct iattr *);
+
+/*********************
+ * operation vectors *
+ *********************/
+/* file.c            */
+extern const struct inode_operations exofs_file_inode_operations;
+extern const struct file_operations exofs_file_operations;
+
 #endif
fs/exofs/file.c new file +82 -0

82 lines not on this page · raw message

fs/exofs/inode.c new file +148 -0

148 lines not on this page · raw message

Signature · 1 line
1.6.0.1
#20 lore raw

PATCH 3/8 exofs: symlink_inode and fast_symlink_inode operations

In reply to Boaz Harrosh

Generic implementation of symlink ops.

---
 fs/exofs/Kbuild    |    2 +-
 fs/exofs/exofs.h   |    4 +++
 fs/exofs/symlink.c |   57 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 62 insertions(+), 1 deletions(-)
 create mode 100644 fs/exofs/symlink.c
fs/exofs/Kbuild +1 -1
index d8bd4d5..18c6158 100644
@@ -26,5 +26,5 @@ KBUILD_CPPFLAGS := -I$(OSD_INC) $(KBUILD_CPPFLAGS)
 
 endif
 
-exofs-objs := osd.o inode.o file.o
+exofs-objs := osd.o inode.o file.o symlink.o
 obj-$(CONFIG_EXOFS_FS) += exofs.o
fs/exofs/exofs.h +4 -0
index b6d9089..9470be3 100644
@@ -147,4 +147,8 @@ int exofs_setattr(struct dentry *, struct iattr *);
 extern const struct inode_operations exofs_file_inode_operations;
 extern const struct file_operations exofs_file_operations;
 
+/* symlink.c         */
+extern const struct inode_operations exofs_symlink_inode_operations;
+extern const struct inode_operations exofs_fast_symlink_inode_operations;
+
 #endif
fs/exofs/symlink.c new file +57 -0

57 lines not on this page · raw message

Signature · 1 line
1.6.0.1
#21 lore raw

PATCH 4/8 exofs: address_space_operations

In reply to Boaz Harrosh

OK Now we start to read and write from osd-objects, page-by-page. The page index is the object's offset.

---
 fs/exofs/exofs.h |    6 +
 fs/exofs/inode.c |  322 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 328 insertions(+), 0 deletions(-)
fs/exofs/exofs.h +6 -0
index 9470be3..59163eb 100644
@@ -139,6 +139,9 @@ int osd_req_write_pages(struct osd_request *or,
 /* inode.c               */
 void exofs_truncate(struct inode *inode);
 int exofs_setattr(struct dentry *, struct iattr *);
+int exofs_write_begin(struct file *file, struct address_space *mapping,
+		loff_t pos, unsigned len, unsigned flags,
+		struct page **pagep, void **fsdata);
 
 /*********************
  * operation vectors *
@@ -147,6 +150,9 @@ int exofs_setattr(struct dentry *, struct iattr *);
 extern const struct inode_operations exofs_file_inode_operations;
 extern const struct file_operations exofs_file_operations;
 
+/* inode.c           */
+extern const struct address_space_operations exofs_aops;
+
 /* symlink.c         */
 extern const struct inode_operations exofs_symlink_inode_operations;
 extern const struct inode_operations exofs_fast_symlink_inode_operations;
fs/exofs/inode.c +322 -0

328 lines not on this page · raw message

Signature · 1 line
1.6.0.1
#22 lore raw

PATCH 5/8 exofs: dir_inode and directory operations

In reply to Boaz Harrosh

implementation of directory and inode operations.

* A directory is treated as a file, and essentially contains a list of <file name, inode #> pairs for files that are found in that directory. The object IDs correspond to the files' inode numbers and are allocated using a 64bit incrementing global counter.
* Each file's control block (AKA on-disk inode) is stored in its object's attributes. This applies to both regular files and other types (directories, device files, symlinks, etc.).

---
 fs/exofs/Kbuild  |    2 +-
 fs/exofs/dir.c   |  643 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/exofs/exofs.h |   26 +++
 fs/exofs/inode.c |  272 +++++++++++++++++++++++
 fs/exofs/namei.c |  338 ++++++++++++++++++++++++++++
 5 files changed, 1280 insertions(+), 1 deletions(-)
 create mode 100644 fs/exofs/dir.c
 create mode 100644 fs/exofs/namei.c
fs/exofs/Kbuild +1 -1
index 18c6158..61162c6 100644
@@ -26,5 +26,5 @@ KBUILD_CPPFLAGS := -I$(OSD_INC) $(KBUILD_CPPFLAGS)
 
 endif
 
-exofs-objs := osd.o inode.o file.o symlink.o
+exofs-objs := osd.o inode.o file.o symlink.o namei.o dir.o
 obj-$(CONFIG_EXOFS_FS) += exofs.o
fs/exofs/dir.c new file +643 -0

643 lines not on this page · raw message

fs/exofs/exofs.h +26 -0
index 59163eb..4c859bd 100644
@@ -124,6 +124,11 @@ static inline struct exofs_i_info *exofs_i(struct inode *inode)
 	return container_of(inode, struct exofs_i_info, vfs_inode);
 }
 
+/*
+ * Maximum count of links to a file
+ */
+#define EXOFS_LINK_MAX           32000
+
 /*************************
  * function declarations *
  *************************/
@@ -142,10 +147,27 @@ int exofs_setattr(struct dentry *, struct iattr *);
 int exofs_write_begin(struct file *file, struct address_space *mapping,
 		loff_t pos, unsigned len, unsigned flags,
 		struct page **pagep, void **fsdata);
+extern struct inode *exofs_iget(struct super_block *, unsigned long);
+struct inode *exofs_new_inode(struct inode *, int);
+
+/* dir.c:                */
+int exofs_add_link(struct dentry *, struct inode *);
+ino_t exofs_inode_by_name(struct inode *, struct dentry *);
+int exofs_delete_entry(struct exofs_dir_entry *, struct page *);
+int exofs_make_empty(struct inode *, struct inode *);
+struct exofs_dir_entry *exofs_find_entry(struct inode *, struct dentry *,
+					 struct page **);
+int exofs_empty_dir(struct inode *);
+struct exofs_dir_entry *exofs_dotdot(struct inode *, struct page **);
+void exofs_set_link(struct inode *, struct exofs_dir_entry *, struct page *,
+		    struct inode *);
 
 /*********************
  * operation vectors *
  *********************/
+/* dir.c:            */
+extern const struct file_operations exofs_dir_operations;
+
 /* file.c            */
 extern const struct inode_operations exofs_file_inode_operations;
 extern const struct file_operations exofs_file_operations;
@@ -153,6 +175,10 @@ extern const struct file_operations exofs_file_operations;
 /* inode.c           */
 extern const struct address_space_operations exofs_aops;
 
+/* namei.c           */
+extern const struct inode_operations exofs_dir_inode_operations;
+extern const struct inode_operations exofs_special_inode_operations;
+
 /* symlink.c         */
 extern const struct inode_operations exofs_symlink_inode_operations;
 extern const struct inode_operations exofs_fast_symlink_inode_operations;
fs/exofs/inode.c +272 -0

275 lines not on this page · raw message

fs/exofs/namei.c new file +338 -0

338 lines not on this page · raw message

Signature · 1 line
1.6.0.1
#27 lore raw

PATCH 6/8 exofs: super_operations and file_system_type

In reply to Boaz Harrosh

This patch ties all operation vectors into a file system superblock and registers the exofs file_system_type at module's load time.

* The file system control block (AKA on-disk superblock) resides in an object with a special ID (defined in common.h). Information included in the file system control block is used to fill the in-memory superblock structure at mount time. This object is created before the file system is used by mkexofs.c It contains information such as:
- The file system's magic number
- The next inode number to be allocated

---
 fs/exofs/Kbuild  |    2 +-
 fs/exofs/exofs.h |   22 +++
 fs/exofs/inode.c |  189 ++++++++++++++++++++
 fs/exofs/super.c |  520 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 732 insertions(+), 1 deletions(-)
 create mode 100644 fs/exofs/super.c
fs/exofs/Kbuild +1 -1
index 61162c6..2268502 100644
@@ -26,5 +26,5 @@ KBUILD_CPPFLAGS := -I$(OSD_INC) $(KBUILD_CPPFLAGS)
 
 endif
 
-exofs-objs := osd.o inode.o file.o symlink.o namei.o dir.o
+exofs-objs := osd.o inode.o file.o symlink.o namei.o dir.o super.o
 obj-$(CONFIG_EXOFS_FS) += exofs.o
fs/exofs/exofs.h +22 -0
index 4c859bd..38a82a6 100644
@@ -54,6 +54,15 @@
 #define _LLU(x) (unsigned long long)(x)
 
 /*
+ * struct to hold what we get from mount options
+ */
+struct exofs_mountopt {
+	const char *dev_name;
+	uint64_t pid;
+	int timeout;
+};
+
+/*
  * our extension to the in-memory superblock
  */
 struct exofs_sb_info {
@@ -125,6 +134,14 @@ static inline struct exofs_i_info *exofs_i(struct inode *inode)
 }
 
 /*
+ * ugly struct so that we can pass two arguments to update_inode's callback
+ */
+struct updatei_args {
+	struct exofs_sb_info	*sbi;
+	struct exofs_fcb	fcb;
+};
+
+/*
  * Maximum count of links to a file
  */
 #define EXOFS_LINK_MAX           32000
@@ -149,6 +166,8 @@ int exofs_write_begin(struct file *file, struct address_space *mapping,
 		struct page **pagep, void **fsdata);
 extern struct inode *exofs_iget(struct super_block *, unsigned long);
 struct inode *exofs_new_inode(struct inode *, int);
+extern int exofs_write_inode(struct inode *, int);
+extern void exofs_delete_inode(struct inode *);
 
 /* dir.c:                */
 int exofs_add_link(struct dentry *, struct inode *);
@@ -179,6 +198,9 @@ extern const struct address_space_operations exofs_aops;
 extern const struct inode_operations exofs_dir_inode_operations;
 extern const struct inode_operations exofs_special_inode_operations;
 
+/* super.c           */
+extern const struct super_operations exofs_sops;
+
 /* symlink.c         */
 extern const struct inode_operations exofs_symlink_inode_operations;
 extern const struct inode_operations exofs_fast_symlink_inode_operations;
fs/exofs/inode.c +189 -0

192 lines not on this page · raw message

fs/exofs/super.c new file +520 -0

520 lines not on this page · raw message

Signature · 1 line
1.6.0.1
#30 lore raw

PATCH 7/8 exofs: Documentation

In reply to Boaz Harrosh

Added some documentation in exofs.txt, as well as a BUGS file.

For further reading, operation instructions, example scripts and up to date infomation and code please see:
http://open-osd.org

---
 Documentation/filesystems/exofs.txt |  176 +++++++++++++++++++++++++++++++++++
 fs/exofs/BUGS                       |    3 +
 2 files changed, 179 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/filesystems/exofs.txt
 create mode 100644 fs/exofs/BUGS
Documentation/filesystems/exofs.txt new file +176 -0
new file mode 100644
index 0000000..0ced74c
@@ -0,0 +1,176 @@
+===============================================================================
+WHAT IS EXOFS?
+===============================================================================
+
+exofs is a file system that uses an OSD and exports the API of a normal Linux
+file system. Users access exofs like any other local file system, and exofs
+will in turn issue commands to the local OSD initiator.
+
+OSD is a new T10 command set that views storage devices not as a large/flat
+array of sectors but as a container of objects, each having a length, quota,
+time attributes and more. Each object is addressed by a 64bit ID, and is
+contained in a 64bit ID partition. Each object has associated attributes
+attached to it, which are integral part of the object and provide metadata about
+the object. The standard defines some common obligatory attributes, but user
+attributes can be added as needed.
+
+===============================================================================
+ENVIRONMENT
+===============================================================================
+
+To use this file system, you need to have an object store to run it on.  You
+may download a target from:
+http://open-osd.org
+
+See Documentation/scsi/osd.txt for how to setup a working osd environment.
+
+===============================================================================
+USAGE
+===============================================================================
+
+1. Download and compile exofs and open-osd initiator:
+  You need an external Kernel source tree or kernel headers from your
+  distribution. (anything based on 2.6.26 or later).
+
+  a. download open-osd including exofs source using:
+     [parent-directory]$ git clone git://git.open-osd.org/open-osd.git
+
+  b. Build the library module like this:
+     [parent-directory]$ make -C KSRC=$(KER_DIR) open-osd
+
+     This will build both the open-osd initiator as well as the exofs kernel
+     module. Use whatever parameters you compiled your Kernel with and
+     $(KER_DIR) above pointing to the Kernel you compile against. See the file
+     open-osd/top-level-Makefile for an example.
+
+2. Get the OSD initiator and target set up properly, and login to the target.
+  See Documentation/scsi/osd.txt for farther instructions. Also see ./do-osd
+  for example script that does all these steps.
+
+3. Insmod the exofs.ko module:
+   [exofs]$ insmod exofs.ko
+
+4. Make sure the directory where you want to mount exists. If not, create it.
+   (For example, mkdir /mnt/exofs)
+
+5. At first run you will need to invoke the mkfs.exofs application
+
+   As an example, this will create the file system on:
+   /dev/osd0 partition ID 65536
+
+   mkfs.exofs --pid=65536 --format /dev/osd0
+
+   The --format is optional if not specified no OSD_FORMAT will be
+   preformed and a clean file system will be created in the specified pid,
+   in the available space of the target. (Use --format=size_in_meg to limit
+   the total LUN space available)
+
+   If pid already exist it will be deleted and a new one will be created in it's
+   place. Be careful.
+
+   An exofs lives inside a single OSD partition. You can create multiple exofs
+   filesystems on the same device using multiple pids.
+
+   (run mkfs.exofs without any parameters for usage help message)
+
+6. Mount the file system.
+
+   For example, to mount /dev/osd0, partition ID 0x10000 on /mnt/exofs:
+
+	mount -t exofs -o pid=65536 /dev/osd0 /mnt/exofs/
+
+7. For reference (See do-exofs example script):
+	do-exofs start - an example of how to perform the above steps.
+	do-exofs stop -  an example of how to unmount the file system.
+	do-exofs format - an example of how to format and mkfs a new exofs.
+
+8. Extra compilation flags (uncomment in fs/exofs/Kbuild):
+	CONFIG_EXOFS_DEBUG - for debug messages and extra checks.
+
+===============================================================================
+exofs mount options
+===============================================================================
+Similar to any mount command:
+	mount -t exofs -o exofs_options /dev/osdX mount_exofs_directory
+
+Where:
+    -t exofs: specifies the exofs file system
+
+    /dev/osdX: X is a decimal number. /dev/osdX was created after a successful
+               login into an OSD target.
+
+    mount_exofs_directory: The directory to mount the file system on
+
+    exofs specific options: Options are separated by commas (,)
+		pid=<integer> - The partition number to mount/create as
+                                container of the filesystem.
+                                This option is mandatory
+                to=<integer>  - Timeout in ticks for a single command
+                                default is (60 * HZ) [for debugging only]
+
+===============================================================================
+DESIGN
+===============================================================================
+
+* The file system control block (AKA on-disk superblock) resides in an object
+  with a special ID (defined in common.h).
+  Information included in the file system control block is used to fill the
+  in-memory superblock structure at mount time. This object is created before
+  the file system is used by mkexofs.c It contains information such as:
+	- The file system's magic number
+	- The next inode number to be allocated
+
+* Each file resides in its own object and contains the data (and it will be
+  possible to extend the file over multiple objects, though this has not been
+  implemented yet).
+
+* A directory is treated as a file, and essentially contains a list of <file
+  name, inode #> pairs for files that are found in that directory. The object
+  IDs correspond to the files' inode numbers and will be allocated according to
+  a bitmap (stored in a separate object). Now they are allocated using a
+  counter.
+
+* Each file's control block (AKA on-disk inode) is stored in its object's
+  attributes. This applies to both regular files and other types (directories,
+  device files, symlinks, etc.).
+
+* Credentials are generated per object (inode and superblock) when they is
+  created in memory (read off disk or created). The credential works for all
+  operations and is used as long as the object remains in memory.
+
+* Async OSD operations are used whenever possible, but the target may execute
+  them out of order. The operations that concern us are create, delete,
+  readpage, writepage, update_inode, and truncate. The following pairs of
+  operations should execute in the order written, and we need to prevent them
+  from executing in reverse order:
+	- The following are handled with the OBJ_CREATED and OBJ_2BCREATED
+	  flags. OBJ_CREATED is set when we know the object exists on the OSD -
+	  in create's callback function, and when we successfully do a read_inode.
+	  OBJ_2BCREATED is set in the beginning of the create function, so we
+	  know that we should wait.
+		- create/delete: delete should wait until the object is created
+		  on the OSD.
+		- create/readpage: readpage should be able to return a page
+		  full of zeroes in this case. If there was a write already
+		  en-route (i.e. create, writepage, readpage) then the page
+		  would be locked, and so it would really be the same as
+		  create/writepage.
+		- create/writepage: if writepage is called for a sync write, it
+		  should wait until the object is created on the OSD.
+		  Otherwise, it should just return.
+		- create/truncate: truncate should wait until the object is
+		  created on the OSD.
+		- create/update_inode: update_inode should wait until the
+		  object is created on the OSD.
+	- Handled by VFS locks:
+		- readpage/delete: shouldn't happen because of page lock.
+		- writepage/delete: shouldn't happen because of page lock.
+		- readpage/writepage: shouldn't happen because of page lock.
+
+===============================================================================
+LICENSE/COPYRIGHT
+===============================================================================
+The exofs file system is based on ext2 v0.5b (distributed with the Linux kernel
+version 2.6.10).  All files include the original copyrights, and the license
+is GPL version 2 (only version 2, as is true for the Linux kernel).  The
+Linux kernel can be downloaded from www.kernel.org.
fs/exofs/BUGS new file +3 -0
new file mode 100644
index 0000000..1b2d4c6
@@ -0,0 +1,3 @@
+- Out-of-space may cause a severe problem if the object (and directory entry)
+  were written, but the inode attributes failed. Then if the filesystem was
+  unmounted and mounted the kernel can get into an endless loop doing a readdir.
Signature · 1 line
1.6.0.1
#31 lore raw

PATCH 8/8 fs: Add exofs to Kernel build

In reply to Boaz Harrosh

- Add exofs to fs/Kconfig under "menu 'Miscellaneous filesystems'"
- Add exofs to fs/Makefile

---
 fs/Kconfig  |    2 ++
 fs/Makefile |    1 +
 2 files changed, 3 insertions(+), 0 deletions(-)
fs/Kconfig +2 -0
index 93945dd..d0c544c 100644
@@ -223,6 +223,8 @@ source "fs/romfs/Kconfig"
 source "fs/sysv/Kconfig"
 source "fs/ufs/Kconfig"
 
+source "fs/exofs/Kconfig"
+
 endif # MISC_FILESYSTEMS
 
 menuconfig NETWORK_FILESYSTEMS
fs/Makefile +1 -0
index 38bc735..c907161 100644
@@ -122,3 +122,4 @@ obj-$(CONFIG_DEBUG_FS)		+= debugfs/
 obj-$(CONFIG_OCFS2_FS)		+= ocfs2/
 obj-$(CONFIG_BTRFS_FS)		+= btrfs/
 obj-$(CONFIG_GFS2_FS)           += gfs2/
+obj-$(CONFIG_EXOFS_FS)          += exofs/
Signature · 1 line
1.6.0.1
#23 lore raw

Re: [PATCH 5/8] exofs: dir_inode and directory operations

In reply to Boaz Harrosh

Hi.

fs/exofs/dir.c line 408

Quoted 12 lines · Boaz Harrosh
fs/exofs/dir.c new file +12 -0
+void exofs_set_link(struct inode *dir, struct exofs_dir_entry *de,
+			struct page *page, struct inode *inode)
+{
+	loff_t pos = page_offset(page) +
+			(char *) de - (char *) page_address(page);
+	unsigned len = le16_to_cpu(de->rec_len);
+	int err;
+
+	lock_page(page);
+	err = exofs_write_begin(NULL, page->mapping, pos, len,
+				AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
+	BUG_ON(err);

How unfriendly :)
simple_write_begin() may fail if there is no memory or appropriate cgroup does not allow to charge more memory.

Quoted 58 lines
fs/exofs/dir.c new file +58 -0
+	de->inode_no = cpu_to_le64(inode->i_ino);
+	exofs_set_de_type(de, inode);
+	err = exofs_commit_chunk(page, pos, len);
+	exofs_put_page(page);
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	mark_inode_dirty(dir);
+}
+
+int exofs_add_link(struct dentry *dentry, struct inode *inode)
+{
+	struct inode *dir = dentry->d_parent->d_inode;
+	const unsigned char *name = dentry->d_name.name;
+	int namelen = dentry->d_name.len;
+	unsigned chunk_size = exofs_chunk_size(dir);
+	unsigned reclen = EXOFS_DIR_REC_LEN(namelen);
+	unsigned short rec_len, name_len;
+	struct page *page = NULL;
+	struct exofs_sb_info *sbi = inode->i_sb->s_fs_info;
+	struct exofs_dir_entry *de;
+	unsigned long npages = dir_pages(dir);
+	unsigned long n;
+	char *kaddr;
+	loff_t pos;
+	int err;
+
+	for (n = 0; n <= npages; n++) {
+		char *dir_end;
+
+		page = exofs_get_page(dir, n);
+		err = PTR_ERR(page);
+		if (IS_ERR(page))
+			goto out;
+		lock_page(page);
+		kaddr = page_address(page);
+		dir_end = kaddr + exofs_last_byte(dir, n);
+		de = (struct exofs_dir_entry *)kaddr;
+		kaddr += PAGE_CACHE_SIZE - reclen;
+		while ((char *)de <= kaddr) {
+			if ((char *)de == dir_end) {
+				name_len = 0;
+				rec_len = chunk_size;
+				de->rec_len = cpu_to_le16(chunk_size);
+				de->inode_no = 0;
+				goto got_it;
+			}
+			if (de->rec_len == 0) {
+				EXOFS_ERR("ERROR: exofs_add_link: "
+					"zero-length directory entry");
+				err = -EIO;
+				goto out_unlock;
+			}
+			err = -EEXIST;
+			if (exofs_match(namelen, name, de))
+				goto out_unlock;
+			name_len = EXOFS_DIR_REC_LEN(de->name_len);
+			rec_len = le16_to_cpu(de->rec_len);
+			if (!de->inode_no && rec_len >= reclen)
+				goto got_it;

fs/exofs/dir.c line 476

Quoted 10 lines
fs/exofs/dir.c new file +10 -0
+			if (rec_len >= name_len + reclen)
+				goto got_it;
+			de = (struct exofs_dir_entry *) ((char *) de + rec_len);
+		}
+		unlock_page(page);
+		exofs_put_page(page);
+	}
+	BUG();
+	return -EINVAL;
+

So it will crash the system if directory entry does not contain any data? What was wrong with -EINVAL?

Also, dir_pages(), readpage_done() and similar functions scream for less generic names, and at least dir_pages() is already implemented in another 5 filesystems.

Quoted 4 lines
fs/exofs/dir.c new file +4 -0
+int exofs_delete_entry(struct exofs_dir_entry *dir, struct page *page)
+{
+	struct address_space *mapping = page->mapping;
+	struct inode *inode = mapping->host;

fs/exofs/dir.c line 522

Quoted 10 lines
fs/exofs/dir.c new file +10 -0
+	struct exofs_sb_info *sbi = inode->i_sb->s_fs_info;
+	char *kaddr = page_address(page);
+	unsigned from = ((char *)dir - kaddr) & ~(exofs_chunk_size(inode)-1);
+	unsigned to = ((char *)dir - kaddr) + le16_to_cpu(dir->rec_len);
+	loff_t pos;
+	struct exofs_dir_entry *pde = NULL;
+	struct exofs_dir_entry *de = (struct exofs_dir_entry *) (kaddr + from);
+	int err;
+
+	while ((char *)de < (char *)dir) {

They have the same type, why is it needed to cast them to char pointer?

Quoted 6 lines
fs/exofs/dir.c new file +6 -0
+		if (de->rec_len == 0) {
+			EXOFS_ERR("ERROR: exofs_delete_entry:"
+				"zero-length directory entry");
+			err = -EIO;
+			goto out;
+		}

fs/exofs/dir.c line 538

Quoted 10 lines
fs/exofs/dir.c new file +10 -0
+		pde = de;
+		de = exofs_next_entry(de);
+	}
+	if (pde)
+		from = (char *)pde - (char *)page_address(page);
+	pos = page_offset(page) + from;
+	lock_page(page);
+	err = exofs_write_begin(NULL, page->mapping, pos, to - from, 0,
+							&page, NULL);
+	BUG_ON(err);

Ugh, in the exofs_make_empty() it is handled without so visible pain.

Quoted 26 lines
fs/exofs/dir.c new file +26 -0
+	if (pde)
+		pde->rec_len = cpu_to_le16(to - from);
+	dir->inode_no = 0;
+	err = exofs_commit_chunk(page, pos, to - from);
+	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+	mark_inode_dirty(inode);
+	sbi->s_numfiles--;
+out:
+	exofs_put_page(page);
+	return err;
+}
+
+int exofs_make_empty(struct inode *inode, struct inode *parent)
+{
+	struct address_space *mapping = inode->i_mapping;
+	struct page *page = grab_cache_page(mapping, 0);
+	unsigned chunk_size = exofs_chunk_size(inode);
+	struct exofs_dir_entry *de;
+	int err;
+	void *kaddr;
+
+	if (!page)
+		return -ENOMEM;
+
+	err = exofs_write_begin(NULL, page->mapping, 0, chunk_size, 0,
+							&page, NULL);

fs/exofs/dir.c line 574

Quoted 10 lines
fs/exofs/dir.c new file +10 -0
+	if (err) {
+		unlock_page(page);
+		goto fail;
+	}
+
+	kaddr = kmap_atomic(page, KM_USER0);
+	de = (struct exofs_dir_entry *)kaddr;
+	de->name_len = 1;
+	de->rec_len = cpu_to_le16(EXOFS_DIR_REC_LEN(1));
+	memcpy(de->name, ".\0\0", 4);

Plus one byte from the stack?

fs/exofs/dir.c line 582

Quoted 8 lines
fs/exofs/dir.c new file +8 -0
+	de->inode_no = cpu_to_le64(inode->i_ino);
+	exofs_set_de_type(de, inode);
+
+	de = (struct exofs_dir_entry *)(kaddr + EXOFS_DIR_REC_LEN(1));
+	de->name_len = 2;
+	de->rec_len = cpu_to_le16(chunk_size - EXOFS_DIR_REC_LEN(1));
+	de->inode_no = cpu_to_le64(parent->i_ino);
+	memcpy(de->name, "..\0", 4);

And another one.

Quoted 63 lines
fs/exofs/inode.c +62 -0
+	exofs_set_de_type(de, inode);
+	kunmap_atomic(page, KM_USER0);
+	err = exofs_commit_chunk(page, 0, chunk_size);
+fail:
+	page_cache_release(page);
+	return err;
+}
+
 
+struct inode *exofs_new_inode(struct inode *dir, int mode)
+{
+	struct super_block *sb;
+	struct inode *inode;
+	struct exofs_i_info *oi;
+	struct exofs_sb_info *sbi;
+	struct osd_request *or;
+	struct osd_obj_id obj;
+	int ret;
+
+	sb = dir->i_sb;
+	inode = new_inode(sb);
+	if (!inode)
+		return ERR_PTR(-ENOMEM);
+
+	oi = exofs_i(inode);
+
+	init_waitqueue_head(&oi->i_wq);
+	set_obj_2bcreated(oi);
+
+	sbi = sb->s_fs_info;
+
+	sb->s_dirt = 1;
+	inode->i_uid = current->cred->fsuid;
+	if (dir->i_mode & S_ISGID) {
+		inode->i_gid = dir->i_gid;
+		if (S_ISDIR(mode))
+			mode |= S_ISGID;
+	} else {
+		inode->i_gid = current->cred->fsgid;
+	}
+	inode->i_mode = mode;
+
+	inode->i_ino = sbi->s_nextid++;
+	inode->i_blkbits = EXOFS_BLKSHIFT;
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	oi->i_commit_size = inode->i_size = 0;
+	spin_lock(&sbi->s_next_gen_lock);
+	inode->i_generation = sbi->s_next_generation++;
+	spin_unlock(&sbi->s_next_gen_lock);
+	insert_inode_hash(inode);
+
+	mark_inode_dirty(inode);
+
+	obj.partition = sbi->s_pid;
+	obj.id = inode->i_ino + EXOFS_OBJ_OFF;
+	exofs_make_credential(oi->i_cred, &obj);
+
+	or = osd_start_request(sbi->s_dev, GFP_KERNEL);
+	if (unlikely(!or)) {
+		EXOFS_ERR("exofs_new_inode: osd_start_request failed\n");
+		return ERR_PTR(-ENOMEM);
+	}
+

fs/exofs/inode.c int exofs_setattr(struct dentry *dentry, struct iattr *iattr) · line 735

Quoted 10 lines
fs/exofs/inode.c +10 -0
+	osd_req_create_object(or, &obj);
+
+	/* increment the refcount so that the inode will still be around when we
+	 * reach the callback
+	 */
+	atomic_inc(&inode->i_count);
+
+	ret = exofs_async_op(or, create_done, inode, oi->i_cred);
+	if (ret) {
+		atomic_dec(&inode->i_count);

igrab()/iput()?

Quoted 34 lines
fs/exofs/namei.c new file +33 -0
+		osd_end_request(or);
+		return ERR_PTR(-EIO);
+	}
+	atomic_inc(&sbi->s_curr_pending);
+
+	return inode;
+}
 
+static int exofs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+	struct inode *inode;
+	int err = -EMLINK;
+
+	if (dir->i_nlink >= EXOFS_LINK_MAX)
+		goto out;
+
+	inode_inc_link_count(dir);
+
+	inode = exofs_new_inode(dir, S_IFDIR | mode);
+	err = PTR_ERR(inode);
+	if (IS_ERR(inode))
+		goto out_dir;
+
+	inode->i_op = &exofs_dir_inode_operations;
+	inode->i_fop = &exofs_dir_operations;
+	inode->i_mapping->a_ops = &exofs_aops;
+
+	inode_inc_link_count(inode);
+
+	err = exofs_make_empty(inode, dir);
+	if (err)
+		goto out_fail;
+
+	err = exofs_add_link(dentry, inode);

fs/exofs/namei.c line 198

Quoted 10 lines
fs/exofs/namei.c new file +10 -0
+	if (err)
+		goto out_fail;
+
+	d_instantiate(dentry, inode);
+out:
+	return err;
+
+out_fail:
+	inode_dec_link_count(inode);
+	inode_dec_link_count(inode);

Why two decrements, will it be ok after exofs_make_empty() fail when it was incremented only once?

Quoted 5 lines
fs/exofs/namei.c new file +5 -0
+	iput(inode);
+out_dir:
+	inode_dec_link_count(dir);
+	goto out;
+}
Signature · 1 line
	Evgeniy Polyakov
#28 lore raw

Re: [PATCH 6/8] exofs: super_operations and file_system_type

In reply to Boaz Harrosh

Hi.

Quoted 30 lines · Boaz Harrosh
fs/exofs/super.c new file +30 -0
+static int parse_options(char *options, struct exofs_mountopt *opts)
+{
+	char *p;
+	substring_t args[MAX_OPT_ARGS];
+	int option;
+	bool s_pid = false;
+
+	EXOFS_DBGMSG("parse_options %s\n", options);
+	/* defaults */
+	memset(opts, 0, sizeof(*opts));
+	opts->timeout = BLK_DEFAULT_SG_TIMEOUT;
+
+	while ((p = strsep(&options, ",")) != NULL) {
+		int token;
+		char str[32];
+
+		if (!*p)
+			continue;
+
+		token = match_token(p, tokens, args);
+		switch (token) {
+		case Opt_pid:
+			if (0 == match_strlcpy(str, &args[0], sizeof(str)))
+				return -EINVAL;
+			opts->pid = simple_strtoull(str, NULL, 0);
+			if (opts->pid < EXOFS_MIN_PID) {
+				EXOFS_ERR("Partition ID must be >= %u",
+					  EXOFS_MIN_PID);
+				return -EINVAL;
+			}

fs/exofs/super.c line 106

Quoted 10 lines
fs/exofs/super.c new file +10 -0
+			s_pid = 1;
+			break;
+		case Opt_to:
+			if (match_int(&args[0], &option))
+				return -EINVAL;
+			if (option <= 0) {
+				EXOFS_ERR("Timout must be > 0");
+				return -EINVAL;
+			}
+			opts->timeout = option * HZ;

Is it intentional to be a different timeouton systems with different HX but the same mount option?

fs/exofs/super.c line 136

Quoted 5 lines
fs/exofs/super.c new file +5 -0
+static struct inode *exofs_alloc_inode(struct super_block *sb)
+{
+	struct exofs_i_info *oi;
+
+	oi = kmem_cache_alloc(exofs_inode_cachep, GFP_KERNEL);

I'm curious if this should be GFP_NOFS or not?

Quoted 5 lines
fs/exofs/super.c new file +5 -0
+	if (!oi)
+		return NULL;
+
+	oi->vfs_inode.i_version = 1;
+	return &oi->vfs_inode;

fs/exofs/super.c

Quoted 10 lines
fs/exofs/super.c new file +9 -0
+}
 
+static void exofs_put_super(struct super_block *sb)
+{
+	int num_pend;
+	struct exofs_sb_info *sbi = sb->s_fs_info;
+
+	/* make sure there are no pending commands */
+	for (num_pend = atomic_read(&sbi->s_curr_pending); num_pend > 0;
+	     num_pend = atomic_read(&sbi->s_curr_pending)) {

This rises a question. Let's check exofs_new_inode() for example (it is a bad example, since inode can not be created when we already in the put_super() callback, but still there are others), it increments s_curr_pending way after inode was created, so is it possible that some in-flight callback is about to be executed and its subsequent s_curr_pending manipulation will not be detected by this loop?

Should s_curr_pending increment be audited all over the code to be increased before the potential postponing command starts (which is not the case in exofs_new_inode() above)?

Quoted 11 lines
fs/exofs/super.c new file +11 -0
+		wait_queue_head_t wq;
+		init_waitqueue_head(&wq);
+		wait_event_timeout(wq,
+				  (atomic_read(&sbi->s_curr_pending) == 0),
+				  msecs_to_jiffies(100));
+	}
+
+	osduld_put_device(sbi->s_dev);
+	kfree(sb->s_fs_info);
+	sb->s_fs_info = NULL;
+}
Signature · 1 line
	Evgeniy Polyakov
#2 lore raw

Re: [PATCH 1/8] exofs: Kbuild, Headers and osd utils

In reply to Boaz Harrosh
Quoted 22 lines · On Mon, 9 Feb 2009 15:12:09 +0200 Boaz Harrosh <[email protected]> wrote:

This patch includes osd infrastructure that will be used later by the file system.

Also the declarations of constants, on disk structures, and prototypes.

And the Kbuild+Kconfig files needed to build the exofs module.

---
 fs/exofs/Kbuild   |   30 +++++++
 fs/exofs/Kconfig  |   13 +++
 fs/exofs/common.h |  181 +++++++++++++++++++++++++++++++++++++++++
 fs/exofs/exofs.h  |  139 ++++++++++++++++++++++++++++++++
 fs/exofs/osd.c    |  230 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 593 insertions(+), 0 deletions(-)
 create mode 100644 fs/exofs/Kbuild
 create mode 100644 fs/exofs/Kconfig
 create mode 100644 fs/exofs/common.h
 create mode 100644 fs/exofs/exofs.h
 create mode 100644 fs/exofs/osd.c

fs/exofs/osd.c line 131

Quoted 10 lines
fs/exofs/osd.c new file +10 -0
+static void _osd_read(struct osd_request *or,
+	const struct osd_obj_id *obj, uint64_t offset, struct bio *bio)
+{
+	osd_req_read(or, obj, bio, offset);
+	EXOFS_DBGMSG("osd_req_read(p=%llX, ob=%llX, l=%llu, of=%llu)\n",
+		_LLU(obj->partition), _LLU(obj->id), _LLU(bio->bi_size),
+		_LLU(offset));
+}
+
+#ifdef __KERNEL__

Hmm?

Quoted 21 lines
fs/exofs/osd.c new file +21 -0
+static struct bio *_bio_map_pages(struct request_queue *req_q,
+				  struct page **pages, unsigned page_count,
+				  size_t length, gfp_t gfp_mask)
+{
+	struct bio *bio;
+	int i;
+
+	bio = bio_alloc(gfp_mask, page_count);
+	if (!bio) {
+		EXOFS_DBGMSG("Failed to bio_alloc page_count=%d\n", page_count);
+		return NULL;
+	}
+
+	for (i = 0; i < page_count && length; i++) {
+		size_t use_len = min(length, PAGE_SIZE);
+
+		if (use_len !=
+		    bio_add_pc_page(req_q, bio, pages[i], use_len, 0)) {
+			EXOFS_ERR("Failed bio_add_pc_page req_q=%p pages[i]=%p "
+				  "use_len=%Zd page_count=%d length=%Zd\n",
+				  req_q, pages[i], use_len, page_count, length);

fs/exofs/osd.c line 162

Quoted 10 lines
fs/exofs/osd.c new file +10 -0
+			bio_put(bio);
+			return NULL;
+		}
+
+		length -= use_len;
+	}
+
+	WARN_ON(length);
+	return bio;
+}

1) exofs builds bios by hand.
2) exofs passes bio to OSD SCSI ULD.

As a result, exofs and OSD SCSI ULD need to know the internal of bio, that is, you reinvent the bio handling infrastructure, as pointed out in another thread in scsi-ml.

_bio_map_pages is called where the VFS passes an array of a pointer to a page frame.

Why can't you simply pass the array to OSD SCSI ULD? Then OSD SCSI ULD can use the block layer helper functions to build a request out of pages without knowing the internal of bio.

Quoted 75 lines
fs/exofs/osd.c new file +67 -0
+int osd_req_read_pages(struct osd_request *or,
+	const struct osd_obj_id *obj, u64 offset, u64 length,
+	struct page **pages, int page_count)
+{
+	struct request_queue *req_q = or->osd_dev->scsi_device->request_queue;
+	struct bio *bio = _bio_map_pages(req_q, pages, page_count, length,
+					 GFP_KERNEL);
+
+	if (!bio)
+		return -ENOMEM;
+
+	_osd_read(or, obj, offset, bio);
+	return 0;
+}
+#endif /* def __KERNEL__ */
+
+int osd_req_read_kern(struct osd_request *or,
+	const struct osd_obj_id *obj, u64 offset, void* buff, u64 len)
+{
+	struct request_queue *req_q = or->osd_dev->scsi_device->request_queue;
+	struct bio *bio = bio_map_kern(req_q, buff, len, GFP_KERNEL);
+
+	if (!bio)
+		return -ENOMEM;
+
+	_osd_read(or, obj, offset, bio);
+	return 0;
+}
+
+static void _osd_write(struct osd_request *or,
+	const struct osd_obj_id *obj, uint64_t offset, struct bio *bio)
+{
+	osd_req_write(or, obj, bio, offset);
+	EXOFS_DBGMSG("osd_req_write(p=%llX, ob=%llX, l=%llu, of=%llu)\n",
+		_LLU(obj->partition), _LLU(obj->id), _LLU(bio->bi_size),
+		_LLU(offset));
+}
+
+#ifdef __KERNEL__
+int osd_req_write_pages(struct osd_request *or,
+	const struct osd_obj_id *obj, u64 offset, u64 length,
+	struct page **pages, int page_count)
+{
+	struct request_queue *req_q = or->osd_dev->scsi_device->request_queue;
+	struct bio *bio = _bio_map_pages(req_q, pages, page_count, length,
+					 GFP_KERNEL);
+
+	if (!bio)
+		return -ENOMEM;
+
+	_osd_write(or, obj, offset, bio);
+	return 0;
+}
+#endif /* def __KERNEL__ */
+
+int osd_req_write_kern(struct osd_request *or,
+	const struct osd_obj_id *obj, u64 offset, void* buff, u64 len)
+{
+	struct request_queue *req_q = or->osd_dev->scsi_device->request_queue;
+	struct bio *bio = bio_map_kern(req_q, buff, len, GFP_KERNEL);
+
+	if (!bio)
+		return -ENOMEM;
+
+	_osd_write(or, obj, offset, bio);
+	return 0;
+}
Signature · 7 lines
1.6.0.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
#3 lore raw

Re: [PATCH 1/8] exofs: Kbuild, Headers and osd utils

Quoted 25 lines · FUJITA Tomonori
Quoted 21 lines · On Mon, 9 Feb 2009 15:12:09 +0200 Boaz Harrosh <[email protected]> wrote:

This patch includes osd infrastructure that will be used later by the file system.

Also the declarations of constants, on disk structures, and prototypes.

And the Kbuild+Kconfig files needed to build the exofs module.

---
 fs/exofs/Kbuild   |   30 +++++++
 fs/exofs/Kconfig  |   13 +++
 fs/exofs/common.h |  181 +++++++++++++++++++++++++++++++++++++++++
 fs/exofs/exofs.h  |  139 ++++++++++++++++++++++++++++++++
 fs/exofs/osd.c    |  230 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 593 insertions(+), 0 deletions(-)
 create mode 100644 fs/exofs/Kbuild
 create mode 100644 fs/exofs/Kconfig
 create mode 100644 fs/exofs/common.h
 create mode 100644 fs/exofs/exofs.h
 create mode 100644 fs/exofs/osd.c
Quoted 13 lines

fs/exofs/osd.c line 131

Quoted 10 lines
fs/exofs/osd.c new file +10 -0
+static void _osd_read(struct osd_request *or,
+	const struct osd_obj_id *obj, uint64_t offset, struct bio *bio)
+{
+	osd_req_read(or, obj, bio, offset);
+	EXOFS_DBGMSG("osd_req_read(p=%llX, ob=%llX, l=%llu, of=%llu)\n",
+		_LLU(obj->partition), _LLU(obj->id), _LLU(bio->bi_size),
+		_LLU(offset));
+}
+
+#ifdef __KERNEL__

Hmm?

Yep, this file also complies in user mode.

Quoted 39 lines
Quoted 21 lines
fs/exofs/osd.c new file +21 -0
+static struct bio *_bio_map_pages(struct request_queue *req_q,
+				  struct page **pages, unsigned page_count,
+				  size_t length, gfp_t gfp_mask)
+{
+	struct bio *bio;
+	int i;
+
+	bio = bio_alloc(gfp_mask, page_count);
+	if (!bio) {
+		EXOFS_DBGMSG("Failed to bio_alloc page_count=%d\n", page_count);
+		return NULL;
+	}
+
+	for (i = 0; i < page_count && length; i++) {
+		size_t use_len = min(length, PAGE_SIZE);
+
+		if (use_len !=
+		    bio_add_pc_page(req_q, bio, pages[i], use_len, 0)) {
+			EXOFS_ERR("Failed bio_add_pc_page req_q=%p pages[i]=%p "
+				  "use_len=%Zd page_count=%d length=%Zd\n",
+				  req_q, pages[i], use_len, page_count, length);

fs/exofs/osd.c line 162

Quoted 10 lines
fs/exofs/osd.c new file +10 -0
+			bio_put(bio);
+			return NULL;
+		}
+
+		length -= use_len;
+	}
+
+	WARN_ON(length);
+	return bio;
+}

1) exofs builds bios by hand.
2) exofs passes bio to OSD SCSI ULD.

As a result, exofs and OSD SCSI ULD need to know the internal of bio, that is, you reinvent the bio handling infrastructure, as pointed out in another thread in scsi-ml.

Quoted 8 lines

_bio_map_pages is called where the VFS passes an array of a pointer to a page frame.

Why can't you simply pass the array to OSD SCSI ULD? Then OSD SCSI ULD can use the block layer helper functions to build a request out of pages without knowing the internal of bio.

Because actually this code is wrong and temporary and will change soon. At vfs write_pages I do not get a linear array of page pointers but a link-list of pages. This will not fit any current model. Also looking ahead I will have RAID 0, 1, 5, and 6 on objects of different devices. bio is the perfect collector for memory information in this situation.

exofs is not the first and only file system who is using bios. Proof of the matter is that block exports a bio submit routine.

As I said on the other thread, I could live without it for now, for a short while, but I will regret it badly and it will hurt performance in the long run.

<snip>

Boaz

#4 lore raw

Re: [PATCH 1/8] exofs: Kbuild, Headers and osd utils

Quoted 40 lines · On Mon, 16 Feb 2009 10:49:39 +0200 Boaz Harrosh <[email protected]> wrote:
Quoted 25 lines · FUJITA Tomonori
Quoted 21 lines · On Mon, 9 Feb 2009 15:12:09 +0200 Boaz Harrosh <[email protected]> wrote:

This patch includes osd infrastructure that will be used later by the file system.

Also the declarations of constants, on disk structures, and prototypes.

And the Kbuild+Kconfig files needed to build the exofs module.

---
 fs/exofs/Kbuild   |   30 +++++++
 fs/exofs/Kconfig  |   13 +++
 fs/exofs/common.h |  181 +++++++++++++++++++++++++++++++++++++++++
 fs/exofs/exofs.h  |  139 ++++++++++++++++++++++++++++++++
 fs/exofs/osd.c    |  230 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 593 insertions(+), 0 deletions(-)
 create mode 100644 fs/exofs/Kbuild
 create mode 100644 fs/exofs/Kconfig
 create mode 100644 fs/exofs/common.h
 create mode 100644 fs/exofs/exofs.h
 create mode 100644 fs/exofs/osd.c
Quoted 13 lines

fs/exofs/osd.c line 131

Quoted 10 lines
fs/exofs/osd.c new file +10 -0
+static void _osd_read(struct osd_request *or,
+	const struct osd_obj_id *obj, uint64_t offset, struct bio *bio)
+{
+	osd_req_read(or, obj, bio, offset);
+	EXOFS_DBGMSG("osd_req_read(p=%llX, ob=%llX, l=%llu, of=%llu)\n",
+		_LLU(obj->partition), _LLU(obj->id), _LLU(bio->bi_size),
+		_LLU(offset));
+}
+
+#ifdef __KERNEL__

Hmm?

Quoted 1 line

Yep, this file also complies in user mode.

Even if you do, it's a good thing to add __KERNEL__ to fs/*.c?

Quoted 48 lines
Quoted 39 lines
Quoted 21 lines
fs/exofs/osd.c new file +21 -0
+static struct bio *_bio_map_pages(struct request_queue *req_q,
+				  struct page **pages, unsigned page_count,
+				  size_t length, gfp_t gfp_mask)
+{
+	struct bio *bio;
+	int i;
+
+	bio = bio_alloc(gfp_mask, page_count);
+	if (!bio) {
+		EXOFS_DBGMSG("Failed to bio_alloc page_count=%d\n", page_count);
+		return NULL;
+	}
+
+	for (i = 0; i < page_count && length; i++) {
+		size_t use_len = min(length, PAGE_SIZE);
+
+		if (use_len !=
+		    bio_add_pc_page(req_q, bio, pages[i], use_len, 0)) {
+			EXOFS_ERR("Failed bio_add_pc_page req_q=%p pages[i]=%p "
+				  "use_len=%Zd page_count=%d length=%Zd\n",
+				  req_q, pages[i], use_len, page_count, length);

fs/exofs/osd.c line 162

Quoted 10 lines
fs/exofs/osd.c new file +10 -0
+			bio_put(bio);
+			return NULL;
+		}
+
+		length -= use_len;
+	}
+
+	WARN_ON(length);
+	return bio;
+}

1) exofs builds bios by hand.
2) exofs passes bio to OSD SCSI ULD.

As a result, exofs and OSD SCSI ULD need to know the internal of bio, that is, you reinvent the bio handling infrastructure, as pointed out in another thread in scsi-ml.

Quoted 8 lines

_bio_map_pages is called where the VFS passes an array of a pointer to a page frame.

Why can't you simply pass the array to OSD SCSI ULD? Then OSD SCSI ULD can use the block layer helper functions to build a request out of pages without knowing the internal of bio.

Quoted 3 lines

Because actually this code is wrong and temporary and will change soon. At vfs write_pages I do not get a linear array of page pointers but a link-list of pages. This will not fit any current model.

Then, why can't you pass a link-list of pages?

Quoted 3 lines

Also looking
ahead I will have RAID 0, 1, 5, and 6 on objects of different devices. bio is the perfect collector for memory information in this situation.

You will add such features to exofs, handling multiple devices internally?

Quoted 2 lines

exofs is not the first and only file system who is using bios. Proof of the matter is that block exports a bio submit routine.

Seems that exofs just passes pages and the ULD sends a SCSI command including these pages. I don't see how exofs needs to handle bio directly.

Quoted 10 lines

As I said on the other thread, I could live without it for now, for a short while, but I will regret it badly and it will hurt performance in the long run.

<snip>

Boaz
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#5 lore raw

Re: [PATCH 1/8] exofs: Kbuild, Headers and osd utils

Quoted 91 lines · FUJITA Tomonori
Quoted 37 lines · On Mon, 16 Feb 2009 10:49:39 +0200 Boaz Harrosh <[email protected]> wrote:
Quoted 27 lines · FUJITA Tomonori
Quoted 24 lines · On Mon, 9 Feb 2009 15:12:09 +0200 Boaz Harrosh <[email protected]> wrote:

This patch includes osd infrastructure that will be used later by the file system.

Also the declarations of constants, on disk structures, and prototypes.

And the Kbuild+Kconfig files needed to build the exofs module.

---
 fs/exofs/Kbuild   |   30 +++++++
 fs/exofs/Kconfig  |   13 +++
 fs/exofs/common.h |  181 +++++++++++++++++++++++++++++++++++++++++
 fs/exofs/exofs.h  |  139 ++++++++++++++++++++++++++++++++
 fs/exofs/osd.c    |  230 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 593 insertions(+), 0 deletions(-)
 create mode 100644 fs/exofs/Kbuild
 create mode 100644 fs/exofs/Kconfig
 create mode 100644 fs/exofs/common.h
 create mode 100644 fs/exofs/exofs.h
 create mode 100644 fs/exofs/osd.c
fs/exofs/osd.c new file +3 -0
+static void _osd_read(struct osd_request *or,
+	const struct osd_obj_id *obj, uint64_t offset, struct bio *bio)
+{
Quoted 9 lines

fs/exofs/osd.c line 131

Quoted 7 lines
fs/exofs/osd.c new file +7 -0
+	osd_req_read(or, obj, bio, offset);
+	EXOFS_DBGMSG("osd_req_read(p=%llX, ob=%llX, l=%llu, of=%llu)\n",
+		_LLU(obj->partition), _LLU(obj->id), _LLU(bio->bi_size),
+		_LLU(offset));
+}
+
+#ifdef __KERNEL__

Hmm?

Quoted 1 line

Yep, this file also complies in user mode.

Even if you do, it's a good thing to add __KERNEL__ to fs/*.c?

Quoted 46 lines
Quoted 46 lines
Quoted 21 lines
fs/exofs/osd.c new file +21 -0
+static struct bio *_bio_map_pages(struct request_queue *req_q,
+				  struct page **pages, unsigned page_count,
+				  size_t length, gfp_t gfp_mask)
+{
+	struct bio *bio;
+	int i;
+
+	bio = bio_alloc(gfp_mask, page_count);
+	if (!bio) {
+		EXOFS_DBGMSG("Failed to bio_alloc page_count=%d\n", page_count);
+		return NULL;
+	}
+
+	for (i = 0; i < page_count && length; i++) {
+		size_t use_len = min(length, PAGE_SIZE);
+
+		if (use_len !=
+		    bio_add_pc_page(req_q, bio, pages[i], use_len, 0)) {
+			EXOFS_ERR("Failed bio_add_pc_page req_q=%p pages[i]=%p "
+				  "use_len=%Zd page_count=%d length=%Zd\n",
+				  req_q, pages[i], use_len, page_count, length);

fs/exofs/osd.c line 162

Quoted 10 lines
fs/exofs/osd.c new file +10 -0
+			bio_put(bio);
+			return NULL;
+		}
+
+		length -= use_len;
+	}
+
+	WARN_ON(length);
+	return bio;
+}

1) exofs builds bios by hand.
2) exofs passes bio to OSD SCSI ULD.

As a result, exofs and OSD SCSI ULD need to know the internal of bio, that is, you reinvent the bio handling infrastructure, as pointed out in another thread in scsi-ml.

_bio_map_pages is called where the VFS passes an array of a pointer to a page frame.

Why can't you simply pass the array to OSD SCSI ULD? Then OSD SCSI ULD can use the block layer helper functions to build a request out of pages without knowing the internal of bio.

Quoted 6 lines
Quoted 3 lines

Because actually this code is wrong and temporary and will change soon. At vfs write_pages I do not get a linear array of page pointers but a link-list of pages. This will not fit any current model.

Then, why can't you pass a link-list of pages?

What? How to do that? I mean how to move from link-list of pages to request?

Quoted 8 lines
Quoted 4 lines

Also looking
ahead I will have RAID 0, 1, 5, and 6 on objects of different devices. bio is the perfect collector for memory information in this situation.

You will add such features to exofs, handling multiple devices internally?

Multiple objects on Multiple devices, Yes.

Quoted 8 lines
Quoted 3 lines

exofs is not the first and only file system who is using bios. Proof of the matter is that block exports a bio submit routine.

Seems that exofs just passes pages and the ULD sends a SCSI command including these pages. I don't see how exofs needs to handle bio directly.

How do you propose to collect these pages? and keep them without allocating an extra list? without pre-allocating a struct request? and without re-inventing the bio structure?

Quoted 7 lines
Quoted 7 lines

As I said on the other thread, I could live without it for now, for a short while, but I will regret it badly and it will hurt performance in the long run.

<snip>

Boaz

#6 lore raw

Re: [PATCH 1/8] exofs: Kbuild, Headers and osd utils

Quoted 10 lines · Boaz Harrosh
Quoted 7 lines · FUJITA Tomonori
Quoted 3 lines · Boaz Harrosh

Also looking
ahead I will have RAID 0, 1, 5, and 6 on objects of different devices. bio is the perfect collector for memory information in this situation.

You will add such features to exofs, handling multiple devices internally?

Multiple objects on Multiple devices, Yes.

That sort of feature does not belong in exofs, but somewhat separate. Ideally we should be able to share "MD for OSD" with other OSD filesystems, and the "osdblk" device that I will produce once libosd hits upstream.

Jeff

#24 lore raw

Re: [PATCH 5/8] exofs: dir_inode and directory operations

In reply to Evgeniy Polyakov
Quoted 4 lines · Evgeniy Polyakov

Hi.

On Mon, Feb 09, 2009 at 03:24:13PM +0200, Boaz Harrosh ([email protected]) wrote:

Quoted 17 lines

fs/exofs/dir.c line 408

Quoted 12 lines
fs/exofs/dir.c new file +12 -0
+void exofs_set_link(struct inode *dir, struct exofs_dir_entry *de,
+			struct page *page, struct inode *inode)
+{
+	loff_t pos = page_offset(page) +
+			(char *) de - (char *) page_address(page);
+	unsigned len = le16_to_cpu(de->rec_len);
+	int err;
+
+	lock_page(page);
+	err = exofs_write_begin(NULL, page->mapping, pos, len,
+				AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
+	BUG_ON(err);

How unfriendly :)
simple_write_begin() may fail if there is no memory or appropriate cgroup does not allow to charge more memory.

You are right on the money. I'll go and revisit all the BUGs and BUG_ONs Thanks good catch.

Quoted 10 lines

fs/exofs/dir.c line 476

Quoted 6 lines
fs/exofs/dir.c new file +6 -0
+		unlock_page(page);
+		exofs_put_page(page);
+	}
+	BUG();
+	return -EINVAL;
+

So it will crash the system if directory entry does not contain any data? What was wrong with -EINVAL?

Yes, thanks, will fix

Quoted 4 lines

Also, dir_pages(), readpage_done() and similar functions scream for less generic names, and at least dir_pages() is already implemented in another 5 filesystems.

I will fix that too. I thought I changed all these, I must have missed a few.

We are so used to filesystems been loadable modules we never try to compile a few in-kernel.

Quoted 8 lines
Quoted 8 lines
fs/exofs/dir.c new file +8 -0
+int exofs_delete_entry(struct exofs_dir_entry *dir, struct page *page)
+{
+	struct address_space *mapping = page->mapping;
+	struct inode *inode = mapping->host;
+	struct exofs_sb_info *sbi = inode->i_sb->s_fs_info;
+	char *kaddr = page_address(page);
+	unsigned from = ((char *)dir - kaddr) & ~(exofs_chunk_size(inode)-1);
+	unsigned to = ((char *)dir - kaddr) + le16_to_cpu(dir->rec_len);
Quoted 9 lines

fs/exofs/dir.c line 522

Quoted 6 lines
fs/exofs/dir.c new file +6 -0
+	loff_t pos;
+	struct exofs_dir_entry *pde = NULL;
+	struct exofs_dir_entry *de = (struct exofs_dir_entry *) (kaddr + from);
+	int err;
+
+	while ((char *)de < (char *)dir) {

They have the same type, why is it needed to cast them to char pointer?

Will fix, thanks

Quoted 11 lines
Quoted 11 lines
fs/exofs/dir.c new file +11 -0
+		if (de->rec_len == 0) {
+			EXOFS_ERR("ERROR: exofs_delete_entry:"
+				"zero-length directory entry");
+			err = -EIO;
+			goto out;
+		}
+		pde = de;
+		de = exofs_next_entry(de);
+	}
+	if (pde)
+		from = (char *)pde - (char *)page_address(page);
Quoted 9 lines

fs/exofs/dir.c line 538

Quoted 5 lines
fs/exofs/dir.c new file +5 -0
+	pos = page_offset(page) + from;
+	lock_page(page);
+	err = exofs_write_begin(NULL, page->mapping, pos, to - from, 0,
+							&page, NULL);
+	BUG_ON(err);

Ugh, in the exofs_make_empty() it is handled without so visible pain.

Yep, will fix

Quoted 11 lines
Quoted 11 lines
fs/exofs/dir.c new file +11 -0
+	if (pde)
+		pde->rec_len = cpu_to_le16(to - from);
+	dir->inode_no = 0;
+	err = exofs_commit_chunk(page, pos, to - from);
+	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+	mark_inode_dirty(inode);
+	sbi->s_numfiles--;
+out:
+	exofs_put_page(page);
+	return err;
+}

<snip>

Quoted 9 lines

fs/exofs/inode.c int exofs_setattr(struct dentry *dentry, struct iattr *iattr) · line 735

Quoted 6 lines
fs/exofs/inode.c +6 -0
+
+	atomic_inc(&inode->i_count);
+
+	ret = exofs_async_op(or, create_done, inode, oi->i_cred);
+	if (ret) {
+		atomic_dec(&inode->i_count);

igrab()/iput()?

Thanks, makes much more sense. Sorry leftovers from 2.6.10

Quoted 39 lines
Quoted 39 lines
fs/exofs/namei.c new file +38 -0
+		osd_end_request(or);
+		return ERR_PTR(-EIO);
+	}
+	atomic_inc(&sbi->s_curr_pending);
+
+	return inode;
+}
 
+static int exofs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+	struct inode *inode;
+	int err = -EMLINK;
+
+	if (dir->i_nlink >= EXOFS_LINK_MAX)
+		goto out;
+
+	inode_inc_link_count(dir);
+
+	inode = exofs_new_inode(dir, S_IFDIR | mode);
+	err = PTR_ERR(inode);
+	if (IS_ERR(inode))
+		goto out_dir;
+
+	inode->i_op = &exofs_dir_inode_operations;
+	inode->i_fop = &exofs_dir_operations;
+	inode->i_mapping->a_ops = &exofs_aops;
+
+	inode_inc_link_count(inode);
+
+	err = exofs_make_empty(inode, dir);
+	if (err)
+		goto out_fail;
+
+	err = exofs_add_link(dentry, inode);
+	if (err)
+		goto out_fail;
+
+	d_instantiate(dentry, inode);
+out:
Quoted 9 lines

fs/exofs/namei.c line 197

Quoted 5 lines
fs/exofs/namei.c new file +5 -0
+	return err;
+
+out_fail:
+	inode_dec_link_count(inode);
+	inode_dec_link_count(inode);

Why two decrements, will it be ok after exofs_make_empty() fail when it was incremented only once?

That's hard to say, I'll investigate it some more. Thanks

Quoted 6 lines

fs/exofs/namei.c line 203

Quoted 5 lines
fs/exofs/namei.c new file +5 -0
+	iput(inode);
+out_dir:
+	inode_dec_link_count(dir);
+	goto out;
+}

Most valuable input, thank you for taking the time to review.

Boaz

#13 lore raw

Re: [PATCH 1/8] exofs: Kbuild, Headers and osd utils

In reply to Boaz Harrosh
Quoted 9 lines · On Mon, 16 Feb 2009 11:19:21 +0200 Boaz Harrosh <[email protected]> wrote:
Quoted 7 lines
Quoted 3 lines

Also looking
ahead I will have RAID 0, 1, 5, and 6 on objects of different devices. bio is the perfect collector for memory information in this situation.

You will add such features to exofs, handling multiple devices internally?

Multiple objects on Multiple devices, Yes.

I thought that exofs is kinda example (reference) file system.

Nobody has seen your code. Let's discuss when we have the code. Over-designing for what we've not seen is not a good idea.

Quoted 11 lines
Quoted 7 lines
Quoted 2 lines

exofs is not the first and only file system who is using bios. Proof of the matter is that block exports a bio submit routine.

Seems that exofs just passes pages and the ULD sends a SCSI command including these pages. I don't see how exofs needs to handle bio directly.

How do you propose to collect these pages? and keep them without allocating an extra list? without pre-allocating a struct request? and without re-inventing the bio structure?

I don't think that allocating an extra list (or something) to keep them hurts performance. We can talk about it when you have the real performance results.

#29 lore raw

Re: [PATCH 6/8] exofs: super_operations and file_system_type

In reply to Evgeniy Polyakov
Quoted 2 lines · Evgeniy Polyakov

Hi.

Hi

Quoted 13 lines · Boaz Harrosh

fs/exofs/super.c line 106

Quoted 8 lines
fs/exofs/super.c new file +8 -0
+		case Opt_to:
+			if (match_int(&args[0], &option))
+				return -EINVAL;
+			if (option <= 0) {
+				EXOFS_ERR("Timout must be > 0");
+				return -EINVAL;
+			}
+			opts->timeout = option * HZ;

Is it intentional to be a different timeouton systems with different HX but the same mount option?

Does not "option * HZ" means that "option" is in seconds?
Any way I would not bother, it is an undocumented option for debugging only.

Quoted 8 lines

fs/exofs/super.c line 136

Quoted 5 lines
fs/exofs/super.c new file +5 -0
+static struct inode *exofs_alloc_inode(struct super_block *sb)
+{
+	struct exofs_i_info *oi;
+
+	oi = kmem_cache_alloc(exofs_inode_cachep, GFP_KERNEL);

I'm curious if this should be GFP_NOFS or not?

Currently none of the OSD transports, (Shhhh ... including osd initiator library), are not SWAP safe.

I will revisit all that, far in the future, when I will need SWAPyness?

Quoted 23 lines
Quoted 5 lines
fs/exofs/super.c new file +5 -0
+	if (!oi)
+		return NULL;
+
+	oi->vfs_inode.i_version = 1;
+	return &oi->vfs_inode;

fs/exofs/super.c

Quoted 10 lines
fs/exofs/super.c new file +9 -0
+}
 
+static void exofs_put_super(struct super_block *sb)
+{
+	int num_pend;
+	struct exofs_sb_info *sbi = sb->s_fs_info;
+
+	/* make sure there are no pending commands */
+	for (num_pend = atomic_read(&sbi->s_curr_pending); num_pend > 0;
+	     num_pend = atomic_read(&sbi->s_curr_pending)) {

This rises a question. Let's check exofs_new_inode() for example (it is a bad example, since inode can not be created when we already in the put_super() callback, but still there are others), it increments s_curr_pending way after inode was created, so is it possible that some in-flight callback is about to be executed and its subsequent s_curr_pending manipulation will not be detected by this loop?

Quoted 4 lines

Should s_curr_pending increment be audited all over the code to be increased before the potential postponing command starts (which is not the case in exofs_new_inode() above)?

I have experimented with this a bit in the passed. And did not find any problems. To the best of my understanding, I'm somehow protected by the VFS. If the FS is busy ie. file handles open. It will refuse an unmount. Once all handles are closed, it will remove visibility from the FS and only then unmount. So the loop above will only wait for old commands. Actually I put prints in there and I never ever got a count of pending commands.

It is hard to test because it is hard to find the time slot after all file handles are close, but with heavy pending IO, and before the umount kicks in.

Also note that I've decided to fsync on file close so I think most/all IO should be finished by the time a file is closed.

Quoted 12 lines

fs/exofs/super.c line 262

Quoted 11 lines
fs/exofs/super.c new file +11 -0
+		wait_queue_head_t wq;
+		init_waitqueue_head(&wq);
+		wait_event_timeout(wq,
+				  (atomic_read(&sbi->s_curr_pending) == 0),
+				  msecs_to_jiffies(100));
+	}
+
+	osduld_put_device(sbi->s_dev);
+	kfree(sb->s_fs_info);
+	sb->s_fs_info = NULL;
+}

Thanks, I appreciate your comments, they make me think

Boaz

#7 lore raw

Re: [PATCH 1/8] exofs: Kbuild, Headers and osd utils

In reply to Jeff Garzik
Quoted 10 lines · Jeff Garzik
Quoted 8 lines · Boaz Harrosh
Quoted 7 lines · FUJITA Tomonori
Quoted 3 lines · Boaz Harrosh

Also looking
ahead I will have RAID 0, 1, 5, and 6 on objects of different devices. bio is the perfect collector for memory information in this situation.

You will add such features to exofs, handling multiple devices internally?

Quoted 7 lines
Quoted 1 line

Multiple objects on Multiple devices, Yes.

That sort of feature does not belong in exofs, but somewhat separate. Ideally we should be able to share "MD for OSD" with other OSD filesystems, and the "osdblk" device that I will produce once libosd hits upstream.

No can do. exofs is meant to be a reference implementation of a pNFS-objects file serving system. Have you read the spec of pNFS-objects layout? they define RAID 0, 1, 5, and 6. In pNFS the MDS is suppose to be able to write the data for its clients as NFS, so it needs to have all the infra structure and knowledge of an Client pNFS-object layout drive.

But don't worry, the plans are that layout-drive and exofs will reuse all the same library code that does all that. There will not be a single line of duplicate code.

In fact one of the things I wanted to talk about in LSF is a generic, BIO based (or some thing else), RAID engine, That could be used by all RAIDers in Kernel, DM, MD, btrfs, exofs pNFS-objects, TUX3, ZFS and so on. And I don't mean just the low level memory-pointers XOR functions, but the more higher level of memory splitters/collectors, abstract-device lists, and RAID description structures. (Because RAIDs can be stacked like 10, 50, and all kind of crazy things)

Quoted 5 lines

Jeff

Boaz

#14 lore raw

Re: [PATCH 1/8] exofs: Kbuild, Headers and osd utils

In reply to FUJITA Tomonori
Quoted 9 lines · FUJITA Tomonori
Quoted 6 lines · On Mon, 16 Feb 2009 11:19:21 +0200 Boaz Harrosh <[email protected]> wrote:
Quoted 6 lines
Quoted 3 lines

Also looking
ahead I will have RAID 0, 1, 5, and 6 on objects of different devices. bio is the perfect collector for memory information in this situation.

You will add such features to exofs, handling multiple devices internally?

Quoted 7 lines
Quoted 1 line

Multiple objects on Multiple devices, Yes.

I thought that exofs is kinda example (reference) file system.

Nobody has seen your code. Let's discuss when we have the code. Over-designing for what we've not seen is not a good idea.

Thanks for the insults, and high credit ;)

Yes it's "kinda example (reference) file system" of a pNFS-objects file system. What can I do life is tough.

Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 3 lines

exofs is not the first and only file system who is using bios. Proof of the matter is that block exports a bio submit routine.

Seems that exofs just passes pages and the ULD sends a SCSI command including these pages. I don't see how exofs needs to handle bio directly.

Quoted 7 lines
Quoted 3 lines

How do you propose to collect these pages? and keep them without allocating an extra list? without pre-allocating a struct request? and without re-inventing the bio structure?

I don't think that allocating an extra list (or something) to keep them hurts performance. We can talk about it when you have the real performance results.

So you are the one that starts to invent the wheel here. I thought I was the one that does that, only you only called me by names, because you never showed me where.

But please only answer one question for me: Please don't write back if you do not answer this question:

Why do other filesystems allow to use bios? are they going to stop? Who is going to remove that?

And as I said, I am going to remove it for now, please be patient. You have never herd from me that I refuse to do it, did you?

Boaz

#8 lore raw

pNFS rant (was Re: [PATCH 1/8] exofs: Kbuild, Headers and osd utils)

In reply to Boaz Harrosh
Quoted 5 lines · Boaz Harrosh

No can do. exofs is meant to be a reference implementation of a pNFS-objects file serving system. Have you read the spec of pNFS-objects layout? they define RAID 0, 1, 5, and 6. In pNFS the MDS is suppose to be able to write the data for its clients as NFS, so it needs to have all the infra structure and knowledge of an Client pNFS-object layout drive.

Yes, I have studied pNFS! I plan to add v4.1 and pNFS support to my NFS server, once v4.0 support is working well.

pNFS The Theory: is wise and necessary: permit clients to directly connect to data storage, rather than copying through the metadata server(s). This is what every distributed filesystem is doing these days -- direct to data server for bulk data read/write.

pNFS The Specification: is an utter piece of shit. I can only presume some shady backroom deal in a smoke-filled room was the reason this saw the light of day.

In a sane world, NFS clients would speak... NFS.

In the crazy world of pNFS, NFS clients are now forced to speak NFS, SCSI, RAID, and any number of proprietary layout types. When will HTTP be added to the list? :)

But anything beyond the NFS protocol for talking client <-> data servers is code bloat complexity madness for an NFS client that wishes to be compatible with "most of the NFS 4.1 world".

An ideal NFS client for pNFS should be asked to do these two things, and nothing more:

1) send metadata transactions to one or more metadata servers, using well-known NFS protocol

2) send data to one or more data servers, using well-known NFS protocol subset designed for storage (v4.1, section 13.6)

But no.

pNFS has forced a huge complexity on the NFS client, by permitting an unbounded number of network protocols. A "layout plugin" layer is required. SCSI and OSD support are REQUIRED for any reasonably compatible setup going forward.

But even more than the technical complexity, this is the first time in NFS history that NFS has required a protocol besides... NFS.

pNFS means that a useful. compatible NFS client must know all these storage protocols, in addition to NFS.

Furthermore, enabling proprietary layout types means that it is easy for a "compatible" v4.1 client to be denied parallel access to data available to other "compatible" v4.1 clients:

Client A: Linux, fully open source

Client B: Linux, with closed source module for
layout type SuperWhizBang storage

Both Client A and Client B can claim to be NFS v4.1 and pNFS compatible,
yet Client A must read data through the metadata server because it lacks the SuperWhizBang storage plugin.

pNFS means a never-ending arms race for the best storage layout, where NFS clients are inevitably compatibly with a __random subset__ of total available layout types. pNFS will be a continuing train wreck of fly-by-night storage companies, and their pet layout types & storage protocols.

It is a support nightmare, an admin nightmare, a firewall nightmare, a client implementor's nightmare, but a storage vendor's wet dream.

NFS was never beautiful, but at least until v4.0 it was well known and widely cross-compatible. And only required one network protocol: NFS.

Jeff

#9 lore raw

Re: pNFS rant (was Re: [PATCH 1/8] exofs: Kbuild, Headers and osd utils)

Quoted 73 lines · Jeff Garzik
Quoted 5 lines · Boaz Harrosh

No can do. exofs is meant to be a reference implementation of a pNFS-objects file serving system. Have you read the spec of pNFS-objects layout? they define RAID 0, 1, 5, and 6. In pNFS the MDS is suppose to be able to write the data for its clients as NFS, so it needs to have all the infra structure and knowledge of an Client pNFS-object layout drive.

Yes, I have studied pNFS! I plan to add v4.1 and pNFS support to my NFS server, once v4.0 support is working well.

pNFS The Theory: is wise and necessary: permit clients to directly
connect to data storage, rather than copying through the metadata server(s). This is what every distributed filesystem is doing these days -- direct to data server for bulk data read/write.

pNFS The Specification: is an utter piece of shit. I can only presume
some shady backroom deal in a smoke-filled room was the reason this saw the light of day.

In a sane world, NFS clients would speak... NFS.

In the crazy world of pNFS, NFS clients are now forced to speak NFS, SCSI, RAID, and any number of proprietary layout types. When will HTTP be added to the list? :)

But anything beyond the NFS protocol for talking client <-> data servers is code bloat complexity madness for an NFS client that wishes to be compatible with "most of the NFS 4.1 world".

An ideal NFS client for pNFS should be asked to do these two things, and nothing more:

1) send metadata transactions to one or more metadata servers, using well-known NFS protocol

2) send data to one or more data servers, using well-known NFS protocol subset designed for storage (v4.1, section 13.6)

But no.

pNFS has forced a huge complexity on the NFS client, by permitting an unbounded number of network protocols. A "layout plugin" layer is required. SCSI and OSD support are REQUIRED for any reasonably compatible setup going forward.

But even more than the technical complexity, this is the first time in NFS history that NFS has required a protocol besides... NFS.

pNFS means that a useful. compatible NFS client must know all these storage protocols, in addition to NFS.

Furthermore, enabling proprietary layout types means that it is easy for a "compatible" v4.1 client to be denied parallel access to data available to other "compatible" v4.1 clients:

Client A: Linux, fully open source

Client B: Linux, with closed source module for
layout type SuperWhizBang storage

Both Client A and Client B can claim to be NFS v4.1 and pNFS compatible,
yet Client A must read data through the metadata server because it lacks the SuperWhizBang storage plugin.

pNFS means a never-ending arms race for the best storage layout, where NFS clients are inevitably compatibly with a __random subset__ of total available layout types. pNFS will be a continuing train wreck of fly-by-night storage companies, and their pet layout types & storage protocols.

Quoted 8 lines

It is a support nightmare, an admin nightmare, a firewall nightmare, a client implementor's nightmare, but a storage vendor's wet dream.

NFS was never beautiful, but at least until v4.0 it was well known and widely cross-compatible. And only required one network protocol: NFS.

Jeff

I hear you. I'm paying close attention and noting down all of above hazardous signals. However, please allow me my own on-look on the matter. Perhaps one day soon, (Probably not in LSF, no travel budget approval yet), we will meet and we can talk about it more closely, and maybe I could convince you of other aspects as well.

But pragmatically speaking. All the above has nothing that I can do about it. My job is to show an OO reference implementation of pNFS-objects, a public and signed protocol. I admit that pNFS-objects is a Panasas's pet, which is my boss and the inventor of pNFS. I hope to remove it from your above SuperWhizBang category, please. Actually my job is so it will not be. I want an open standard implementation from day one, so there will be no questions. I understand that you argue about the do or die of the OSD protocol under pNFS. For me it is just that much more challenge of swimming up stream, as a Salmon. Everyone is doing "Files" I get to do "Objects". I hope when finally the code will arrive, soon, and it gets to be used, it's merits, performance, security, and ease-of-use will win users over, big time.
(Lets compare notes, what is the minimal NFS DS implementation you can imagine?
What would you say an OSD's target is? not counting all the extras an OSD gives you, like no proprietary back-channel protocol between MDS-to-DS inside the cluster.)

But I do hear you, really, you have very valid points that must be taken into consideration.

Thanks
Boaz

maintainer
#10 lore raw

Re: pNFS rant (was Re: [PATCH 1/8] exofs: Kbuild, Headers and osd utils)

In reply to Jeff Garzik
Quoted 21 lines · Jeff Garzik
Quoted 5 lines · Boaz Harrosh

No can do. exofs is meant to be a reference implementation of a pNFS-objects file serving system. Have you read the spec of pNFS-objects layout? they define RAID 0, 1, 5, and 6. In pNFS the MDS is suppose to be able to write the data for its clients as NFS, so it needs to have all the infra structure and knowledge of an Client pNFS-object layout drive.

Yes, I have studied pNFS! I plan to add v4.1 and pNFS support to my NFS server, once v4.0 support is working well.

pNFS The Theory: is wise and necessary: permit clients to directly
connect to data storage, rather than copying through the metadata server(s). This is what every distributed filesystem is doing these days -- direct to data server for bulk data read/write.

pNFS The Specification: is an utter piece of shit. I can only presume
some shady backroom deal in a smoke-filled room was the reason this saw the light of day.

Quoted 5 lines

In a sane world, NFS clients would speak... NFS.

In the crazy world of pNFS, NFS clients are now forced to speak NFS, SCSI, RAID, and any number of proprietary layout types. When will HTTP be added to the list? :)

Heh, it's one of the endearing faults of the storage industry that we never learn from our mistakes ... particularly in storage protocols.

Actually, perhaps that's a mischaracterised: we never actually learn from our successes. For example, most popular storage protocols solve about 80% of the problem (NFSv2) get something bolted on to take that to 95% (locking) and rule for decades. We end up obsessing about the 5% and produce something that's like 10x the overhead to solve it. Customers, for some unfathomable reason, hate complexity (I suspect principally because it in some measure equals expense) so the 100% solution (which actually turns out to be a 95% one because the over engineered complexity adds another 5% of different problems that take years to find) tends to work its way into a niche and stay there ... eventually fading.

If you're really lucky, the niche evolves into something sustainable. For example iSCSI: blew its early promise, pulled a bunch of unnecessary networking into the protocol and ended up too big to fit in disk firmware (thus destroying the ability to have a simple network tap to replace storage fabric). It's been slowly fading until Virtualisation came along. Now all the other solutions to getting storage into virtual machines are so horrible and arcane that iSCSI looks like a winner (if the alternative is Frankenstein's monster, Grendel's mother suddenly looks more attractive as a partner).

So, trust the customer ... if it's so horrible it shouldn't have seen the light of day, the chances are that no-one will buy it anyway.

James

#12 lore raw

Re: pNFS rant (was Re: [PATCH 1/8] exofs: Kbuild, Headers and osd utils)

In reply to Jeff Garzik
Quoted 59 lines · Jeff Garzik
Quoted 5 lines · Boaz Harrosh

No can do. exofs is meant to be a reference implementation of a pNFS-objects file serving system. Have you read the spec of pNFS-objects layout? they define RAID 0, 1, 5, and 6. In pNFS the MDS is suppose to be able to write the data for its clients as NFS, so it needs to have all the infra structure and knowledge of an Client pNFS-object layout drive.

Yes, I have studied pNFS! I plan to add v4.1 and pNFS support to my NFS server, once v4.0 support is working well.

pNFS The Theory: is wise and necessary: permit clients to directly
connect to data storage, rather than copying through the metadata server(s). This is what every distributed filesystem is doing these days -- direct to data server for bulk data read/write.

pNFS The Specification: is an utter piece of shit. I can only presume
some shady backroom deal in a smoke-filled room was the reason this saw the light of day.

In a sane world, NFS clients would speak... NFS.

In the crazy world of pNFS, NFS clients are now forced to speak NFS, SCSI, RAID, and any number of proprietary layout types. When will HTTP be added to the list? :)

But anything beyond the NFS protocol for talking client <-> data servers is code bloat complexity madness for an NFS client that wishes to be compatible with "most of the NFS 4.1 world".

An ideal NFS client for pNFS should be asked to do these two things, and nothing more:

1) send metadata transactions to one or more metadata servers, using well-known NFS protocol

2) send data to one or more data servers, using well-known NFS protocol subset designed for storage (v4.1, section 13.6)

But no.

pNFS has forced a huge complexity on the NFS client, by permitting an unbounded number of network protocols. A "layout plugin" layer is required. SCSI and OSD support are REQUIRED for any reasonably compatible setup going forward.

But even more than the technical complexity, this is the first time in NFS history that NFS has required a protocol besides... NFS.

pNFS means that a useful. compatible NFS client must know all these storage protocols, in addition to NFS.

Furthermore, enabling proprietary layout types means that it is easy for a "compatible" v4.1 client to be denied parallel access to data available to other "compatible" v4.1 clients:

Client A: Linux, fully open source

Quoted 7 lines

Client B: Linux, with closed source module for
layout type SuperWhizBang storage

Both Client A and Client B can claim to be NFS v4.1 and pNFS compatible,
yet Client A must read data through the metadata server because it lacks the SuperWhizBang storage plugin.

At least, for SuperWhizBang to comply with NFSv4.1 requirements it needs to follow the IETF process as an open protocol and address important semantic details (as listed by nfsv4.1) on-top of the wire data structures like security considerations and client fencing.

Being open source or not is somewhat orthogonal to that since from the protocol specification one should be able to implement a fully comply client and/or server.

Quoted 9 lines

pNFS means a never-ending arms race for the best storage layout, where NFS clients are inevitably compatibly with a __random subset__ of total available layout types. pNFS will be a continuing train wreck of fly-by-night storage companies, and their pet layout types & storage protocols.

It is a support nightmare, an admin nightmare, a firewall nightmare, a client implementor's nightmare, but a storage vendor's wet dream.

What you're basically saying is similar to rejecting the filesystem export kABI since this will cause a never-ending arms race for the best file system. (a.k.a. "640KB of RAM and FAT file system is likely anything that a sane user will ever need"... ;-)

I believe that competition is good. Good for customers, for which the pNFS protocol was designed for, and good for vendors as well. The extra complexity is there since one-size does not fit all. Different storage technologies fit certain applications better than others and exposing storage for direct client access can convey these strengths all the way up to the host running the application.

Besides, the pNFS specification was also driven by customers that use proprietary clustered filesystems today, that use block or object-based storage. These customers want pNFS to be a standard to steam up competition for several reasons, like:
- encourage open source implementations
- second source availability
- building best-of-breed systems by integrating
parts from different vendors
- reuse of existing storage and networking infrastructure

Benny

Quoted 12 lines

NFS was never beautiful, but at least until v4.0 it was well known and widely cross-compatible. And only required one network protocol: NFS.

Jeff

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#11 lore raw

Re: pNFS rant (was Re: [PATCH 1/8] exofs: Kbuild, Headers and osd utils)

In reply to James Bottomley
Quoted 52 lines · James Bottomley
Quoted 20 lines · Jeff Garzik
Quoted 5 lines · Boaz Harrosh

No can do. exofs is meant to be a reference implementation of a pNFS-objects file serving system. Have you read the spec of pNFS-objects layout? they define RAID 0, 1, 5, and 6. In pNFS the MDS is suppose to be able to write the data for its clients as NFS, so it needs to have all the infra structure and knowledge of an Client pNFS-object layout drive.

Yes, I have studied pNFS! I plan to add v4.1 and pNFS support to my NFS server, once v4.0 support is working well.

pNFS The Theory: is wise and necessary: permit clients to directly
connect to data storage, rather than copying through the metadata server(s). This is what every distributed filesystem is doing these days -- direct to data server for bulk data read/write.

pNFS The Specification: is an utter piece of shit. I can only presume
some shady backroom deal in a smoke-filled room was the reason this saw the light of day.

Quoted 5 lines

In a sane world, NFS clients would speak... NFS.

In the crazy world of pNFS, NFS clients are now forced to speak NFS, SCSI, RAID, and any number of proprietary layout types. When will HTTP be added to the list? :)

Heh, it's one of the endearing faults of the storage industry that we never learn from our mistakes ... particularly in storage protocols.

Actually, perhaps that's a mischaracterised: we never actually learn from our successes. For example, most popular storage protocols solve about 80% of the problem (NFSv2) get something bolted on to take that to 95% (locking) and rule for decades. We end up obsessing about the 5% and produce something that's like 10x the overhead to solve it. Customers, for some unfathomable reason, hate complexity (I suspect principally because it in some measure equals expense) so the 100% solution (which actually turns out to be a 95% one because the over engineered complexity adds another 5% of different problems that take years to find) tends to work its way into a niche and stay there ... eventually fading.

If you're really lucky, the niche evolves into something sustainable. For example iSCSI: blew its early promise, pulled a bunch of unnecessary networking into the protocol and ended up too big to fit in disk firmware (thus destroying the ability to have a simple network tap to replace storage fabric). It's been slowly fading until Virtualisation came along. Now all the other solutions to getting storage into virtual machines are so horrible and arcane that iSCSI looks like a winner (if the alternative is Frankenstein's monster, Grendel's mother suddenly looks more attractive as a partner).

Quoted 2 lines

So, trust the customer ... if it's so horrible it shouldn't have seen the light of day, the chances are that no-one will buy it anyway.

I completely agree with this sentence.
And no customer, whatsoever, that I've talked to about pNFS had any reservations about supporting multiple layout types. On the contrary...

Benny

Quoted 8 lines

James

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#15 lore raw

Re: [PATCH 1/8] exofs: Kbuild, Headers and osd utils

In reply to Boaz Harrosh
Quoted 18 lines · On Mon, 16 Feb 2009 12:29:06 +0200 Boaz Harrosh <[email protected]> wrote:
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 2 lines

exofs is not the first and only file system who is using bios. Proof of the matter is that block exports a bio submit routine.

Seems that exofs just passes pages and the ULD sends a SCSI command including these pages. I don't see how exofs needs to handle bio directly.

Quoted 7 lines
Quoted 3 lines

How do you propose to collect these pages? and keep them without allocating an extra list? without pre-allocating a struct request? and without re-inventing the bio structure?

I don't think that allocating an extra list (or something) to keep them hurts performance. We can talk about it when you have the real performance results.

So you are the one that starts to invent the wheel here. I thought I was the one that does that, only you only called me by names, because you never showed me where.

Quoted 5 lines

But please only answer one question for me: Please don't write back if you do not answer this question:

Why do other filesystems allow to use bios? are they going to stop? Who is going to remove that?

Can you stop the argument, "exofs is similar to the existing traditional file systems hence it should be treated equally". It's simply untrue. Does anyone except for panasas people insist the same argument?

We are talking about the design of exofs, which also affects the design of OSD ULD (including the library) living in SCSI mid-layer. It's something completely different from existing traditional file systems that work nicely on the top of the block layer.

As discussed in another thread, now OSD ULD reinvents the bio handling infrastructure because of the design of exofs. But OSD ULD can use the block layer helper functions to avoid the re-invention if we change the exofs design to take pages instead of bios. For now, it works perfectly for exofs. In the future, we might change it but we don't know until you submit patches (or the performance results) that show taking pages doesn't work for exofs nicely.

I guess that we need to evolve the block layer to support OSD stuff cleanly than we've discussed recently. But again we can do when we definitely need to do.

#16 lore raw

Re: [osd-dev] [PATCH 1/8] exofs: Kbuild, Headers and osd utils

Quoted 6 lines · FUJITA Tomonori

Can you stop the argument, "exofs is similar to the existing traditional file systems hence it should be treated equally". It's simply untrue. Does anyone except for panasas people insist the same argument?

No I will not, it is true. exofs is just a regular old filesystem nothing different.

Quoted 3 lines

We are talking about the design of exofs, which also affects the design of OSD ULD (including the library) living in SCSI mid-layer.

The ULD belongs to scsi but the library could sit else where, how is that an argument?

Quoted 4 lines

It's something completely different from existing traditional file systems that work nicely on the top of the block layer.

Nicely is a matter of opinion. I think that building a bio in stages in the background, then at the point of execution build a request-from-bio and execute is a nice design that makes sure nothing is duplicated, copied, and wheels are not re-invented. Current Kernel design is nice, why change it?

Quoted 2 lines

As discussed in another thread, now OSD ULD reinvents the bio handling infrastructure because of the design of exofs.

Not true, show me where? You keep saying that. Where in the code is it reinvented?

Quoted 3 lines

But OSD ULD can use the
block layer helper functions to avoid the re-invention if we change the exofs design to take pages instead of bios.

That, above is exactly a re-invention of block layer. What was all that scatterlist pointers and scsi_execute_async() cleanup that you worked so hard to get rid off. It was a list of pages+offsets+lengths, that's what it was. Now you ask me to do the same, keep an external structure of pages+offsets+lengths. pass them three layers down and at some point in time force new block_layer interfaces, which do not fully exist today, to prepare a request for submission.

No! the decision was, keep preparation of request local and submit it in place, without intermediate structures. From-memory-to-request in one stage.

That's what I want. The bio lets me do that yesterday, lots of file systems do that yesterday.

All I'm asking for is one small blk_make_request() that is a parallel of generic_make_request() of the BLOCK_FS, for the BLOCK_PC requests

If someone wanted a filesystem over tape drives, over st.c or osst.c. He would design it similar. collect bios in background, point and shoot. The blk_map_xxx functions where made to satisfy user-mode interfaces, for filesystems it was bio for ages.

Quoted 6 lines

For now, it works

perfectly for exofs. In the future, we might change it but we don't know until you submit patches (or the performance results) that show taking pages doesn't work for exofs nicely.

I don't know about you, but me, I don't have to do some work to know it's bad. I can imagine before hand that it is bad. I usually run hundreds of simulations in my head, discarding any bad options until I find the one way I like. Usually the short easiest way is also the best. (Since I'm very lazy)
Like with bidi for example, Why not just take two requests instead of one? But I was sent to do all that gigantic work so everyone will see that.

Quoted 3 lines

I guess that we need to evolve the block layer to support OSD stuff cleanly than we've discussed recently. But again we can do when we definitely need to do.

It's not that big and long evolution. It is a simple:

struct request *blk_make_request(struct bio*, gfp_t gfp);

And we are done. more simple then that? I don't know

Boaz

#17 lore raw

Re: [osd-dev] [PATCH 1/8] exofs: Kbuild, Headers and osd utils

Quoted 10 lines · On Tue, 17 Feb 2009 10:10:15 +0200 Boaz Harrosh <[email protected]> wrote:
Quoted 6 lines · FUJITA Tomonori

Can you stop the argument, "exofs is similar to the existing traditional file systems hence it should be treated equally". It's simply untrue. Does anyone except for panasas people insist the same argument?

No I will not, it is true. exofs is just a regular old filesystem nothing different.

After reading this, I gave up discussing this issue with you but I still wait for your fixes that you promised:

http://marc.info/?l=linux-scsi&m=123445759718253&w=2

Thanks,

#18 lore raw

Re: [osd-dev] [PATCH 1/8] exofs: Kbuild, Headers and osd utils

Quoted 12 lines · FUJITA Tomonori
Quoted 8 lines · On Tue, 17 Feb 2009 10:10:15 +0200 Boaz Harrosh <[email protected]> wrote:
Quoted 5 lines · FUJITA Tomonori

Can you stop the argument, "exofs is similar to the existing traditional file systems hence it should be treated equally". It's simply untrue. Does anyone except for panasas people insist the same argument?

No I will not, it is true. exofs is just a regular old filesystem nothing different.

Quoted 8 lines

After reading this, I gave up discussing this issue with you but I still wait for your fixes that you promised:

http://marc.info/?l=linux-scsi&m=123445759718253&w=2

Thanks,
--

They are on the way, I have not forgotten

Boaz

#25 lore raw

Re: [PATCH 5/8] exofs: dir_inode and directory operations

In reply to Boaz Harrosh
Quoted 5 lines · Boaz Harrosh
Quoted 4 lines · Evgeniy Polyakov

Hi.

On Mon, Feb 09, 2009 at 03:24:13PM +0200, Boaz Harrosh ([email protected]) wrote:

<snip>

Quoted 10 lines

<snip>

Quoted 8 lines

fs/exofs/inode.c int exofs_setattr(struct dentry *dentry, struct iattr *iattr) · line 735

Quoted 6 lines
fs/exofs/inode.c +6 -0
+
+	atomic_inc(&inode->i_count);
+
+	ret = exofs_async_op(or, create_done, inode, oi->i_cred);
+	if (ret) {
+		atomic_dec(&inode->i_count);

igrab()/iput()?

Quoted 2 lines

Thanks, makes much more sense. Sorry leftovers from 2.6.10

It's the same at ext2. I looked at the igrab()/iput() code it does some extra locks which I'm afraid of at this stage. I'll postpone this to the next (next) merge window, after I ran with it for a while.

Quoted 47 lines
Quoted 37 lines
Quoted 37 lines
fs/exofs/namei.c new file +37 -0
+		osd_end_request(or);
+		return ERR_PTR(-EIO);
+	}
+	atomic_inc(&sbi->s_curr_pending);
+
+	return inode;
+}
+static int exofs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+	struct inode *inode;
+	int err = -EMLINK;
+
+	if (dir->i_nlink >= EXOFS_LINK_MAX)
+		goto out;
+
+	inode_inc_link_count(dir);
+
+	inode = exofs_new_inode(dir, S_IFDIR | mode);
+	err = PTR_ERR(inode);
+	if (IS_ERR(inode))
+		goto out_dir;
+
+	inode->i_op = &exofs_dir_inode_operations;
+	inode->i_fop = &exofs_dir_operations;
+	inode->i_mapping->a_ops = &exofs_aops;
+
+	inode_inc_link_count(inode);
+
+	err = exofs_make_empty(inode, dir);
+	if (err)
+		goto out_fail;
+
+	err = exofs_add_link(dentry, inode);
+	if (err)
+		goto out_fail;
+
+	d_instantiate(dentry, inode);
Quoted 9 lines

fs/exofs/namei.c line 197

Quoted 6 lines
fs/exofs/namei.c new file +6 -0
+out:
+	return err;
+
+out_fail:
+	inode_dec_link_count(inode);
+	inode_dec_link_count(inode);

Why two decrements, will it be ok after exofs_make_empty() fail when it was incremented only once?

Quoted 3 lines

That's hard to say, I'll investigate it some more. Thanks

I've put some prints and current code is correct. inode->i_nlink (the target of inode_dec_link_count()) is 1 after exofs_new_inode() and 2 after inode_inc_link_count() (Just before exofs_make_empty()). Very confusing, but exofs_add_link() does not touch inode->i_nlink.

I will be posting a new set tomorrow

Thanks
Boaz

#26 lore raw

Re: [PATCH 5/8] exofs: dir_inode and directory operations

Quoted 8 lines · Boaz Harrosh
Quoted 8 lines
Quoted 7 lines

fs/exofs/inode.c int exofs_setattr(struct dentry *dentry, struct iattr *iattr) · line 735

Quoted 5 lines
fs/exofs/inode.c +5 -0
+	atomic_inc(&inode->i_count);
+
+	ret = exofs_async_op(or, create_done, inode, oi->i_cred);
+	if (ret) {
+		atomic_dec(&inode->i_count);

igrab()/iput()?

Quoted 6 lines
Quoted 2 lines

Thanks, makes much more sense. Sorry leftovers from 2.6.10

It's the same at ext2. I looked at the igrab()/iput() code it does some extra locks which I'm afraid of at this stage. I'll postpone this to the next (next) merge window, after I ran with it for a while.

It does not allow to work with to be freed inode, getting that it is fresh inode, things should be ok just to increase the reference counter, but iput() may highlight problems if inode's reference counter can be decreased, and apparently it can not since otherwise increment would not be added around exofs_async_op().

What if exofs_async_op() drops a reference and returns error? inode will not be freed and will not be placed into to be freed list, which in turn will break accounting and potentially prevent superblock freeing.

Signature · 1 line
	Evgeniy Polyakov