All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 00/39] Add quota supporting in ubifs
@ 2015-09-15  9:01 ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:01 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

Hi all,
	This is the V3 to add quota in ubifs.

Hi Al,
	There are some patches about vfs, and
some of them are already Reviewed-by Jan, please
take a look at them. Thanx.

Hi Jan,
	There are some new patches for dquot,
please take a look.

Hi Artem and Richard,
	please help to review the ubifs part.

Test:

 # ./check -g quota
FSTYP         -- ubifs
PLATFORM      -- Linux/x86_64 atest-guest 4.2.0-quota_v3+
MKFS_OPTIONS  -- /dev/ubi0_1
MOUNT_OPTIONS -- -o context=system_u:object_r:nfs_t:s0 /dev/ubi0_1 /mnt/scratch

generic/055	 [not run] ubifs does not support shutdown
generic/082 0s ... 1s
generic/219 1s ... [not run] O_DIRECT is not supported
generic/230 13s ... 13s
generic/231 46s ... 47s
generic/232 2s ... 3s
generic/233 4s ... 4s
generic/234 8s ... 8s
generic/235 1s ... 1s
generic/270	 [not run] Filesystem ubifs not supported in _scratch_mkfs_sized
generic/280	 [not run] ubifs does not support freezing
Ran: generic/082 generic/230 generic/231 generic/232 generic/233 generic/234 generic/235
Not run: generic/055 generic/219 generic/270 generic/280
Passed all 7 tests

As usual, you can get the code from:
	https://github.com/yangdongsheng/linux.git   ubifs_quota_v3

Changelog:
	v1->v2:
		- remove the duplication in block_dev and char_dev
		- rename read_block to ubifs_read_block
		- drop patch for ui->budgeted
		- budget in ubifs_dirty_inode() if necessary
	v2->v3:
		- introduce a callback function in quotactl_ops
		  to allow filesystem to do some special work
		  in restoring iflags. This fix the problem
		  in V2 about ubifs_dirty_inode()

Dongsheng Yang (39):
  fs: introduce a ->s_cdev field into struct super_block
  fs: cleanup: remove the blank line before EXPORT_SYMBOL
  fs: super: cleanup: make the comment of each function aligned
  fs: super: consolidate the get_super class functions
  fs: super: introduce a get_super_cdev to get super by a cdev reference
  fs: super: introduce a get_super_cdev_thawed to get sb by cdev
    reference
  fs: char_dev: introduce cd_acquire function to acquire cdev
  fs: introduce a __lookup_dev for internal using
  fs: char_dev: introduce lookup_cdev to get cdev by pathname
  fs: dquot: skip invalidate_bdev if bdev is NULL
  fs: quota: replace opened calling of ->sync_fs with sync_filesystem
  fs: quota: make quota support fs which is running on char dev
  fs: introduce a get_qsize() to inode_operations
  fs: quota: restore i_flags of quota files in dquot_disable
  fs: quota: introduce a callback of restore_iflags to quotactl_ops
  ubi: introduce a interface to get cdev in ubi_volume
  ubifs: extend budget for blocks
  ubifs: fill sb->s_cdev in ubifs_fill_super()
  ubifs: fill ->s_dev in ubifs_fill_super
  ubifs: export read_block() from file.c
  ubifs: introduce i_dquot to ubifs_inode
  ubifs: implement IO functions for quota files
  ubifs: disable quota in ubifs_put_super
  ubifs: write quota back in ubifs_sync
  ubifs: set/clear MS_RDONLY properly in ubifs_remount
  ubifs: suspend & resume quota properly in ubifs_remount
  ubifs: check inode with NULL before using it
  ubifs: record quota information about inode in ubifs_new_inode
  ubifs: free quota inode information in ubifs_evict_inode
  ubifs: alloc quota space in ubifs writing path
  ubifs: free quota space in do_truncation
  ubifs: free quota space when deleting a file
  ubifs: adapt quota space informatin in do_setattr
  ubifs: transfer quota information in changing owner or group
  ubifs: write inode in ubifs_quota_write if we are appending
  ubifs: implement ubifs_get_qsize to get quota size in ubifs
  ubifs: implement ubifs_restore_iflags for quotactl_operations
  ubifs: fill the quota related fields in ubifs_fill_super
  ubifs: introduce quota related mount options

 drivers/mtd/ubi/kapi.c  |   6 +
 fs/Makefile             |   2 +-
 fs/block_dev.c          |  26 +----
 fs/char_dev.c           |  48 ++++++++
 fs/dev.c                |  77 +++++++++++++
 fs/internal.h           |  14 +++
 fs/ioctl.c              |  31 +++--
 fs/quota/dquot.c        |  62 ++++++----
 fs/quota/quota.c        |  30 +++--
 fs/super.c              | 284 ++++++++++++++++++++++++---------------------
 fs/ubifs/budget.c       |   4 +
 fs/ubifs/debug.c        |   2 +
 fs/ubifs/dir.c          |  23 +++-
 fs/ubifs/file.c         |  80 ++++++++++++-
 fs/ubifs/journal.c      |   4 +
 fs/ubifs/super.c        | 297 +++++++++++++++++++++++++++++++++++++++++++++++-
 fs/ubifs/ubifs.h        |  17 +++
 include/linux/fs.h      |   6 +
 include/linux/mtd/ubi.h |   1 +
 include/linux/quota.h   |   5 +
 20 files changed, 819 insertions(+), 200 deletions(-)
 create mode 100644 fs/dev.c

-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 107+ messages in thread

* [PATCH v3 00/39] Add quota supporting in ubifs
@ 2015-09-15  9:01 ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:01 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

Hi all,
	This is the V3 to add quota in ubifs.

Hi Al,
	There are some patches about vfs, and
some of them are already Reviewed-by Jan, please
take a look at them. Thanx.

Hi Jan,
	There are some new patches for dquot,
please take a look.

Hi Artem and Richard,
	please help to review the ubifs part.

Test:

 # ./check -g quota
FSTYP         -- ubifs
PLATFORM      -- Linux/x86_64 atest-guest 4.2.0-quota_v3+
MKFS_OPTIONS  -- /dev/ubi0_1
MOUNT_OPTIONS -- -o context=system_u:object_r:nfs_t:s0 /dev/ubi0_1 /mnt/scratch

generic/055	 [not run] ubifs does not support shutdown
generic/082 0s ... 1s
generic/219 1s ... [not run] O_DIRECT is not supported
generic/230 13s ... 13s
generic/231 46s ... 47s
generic/232 2s ... 3s
generic/233 4s ... 4s
generic/234 8s ... 8s
generic/235 1s ... 1s
generic/270	 [not run] Filesystem ubifs not supported in _scratch_mkfs_sized
generic/280	 [not run] ubifs does not support freezing
Ran: generic/082 generic/230 generic/231 generic/232 generic/233 generic/234 generic/235
Not run: generic/055 generic/219 generic/270 generic/280
Passed all 7 tests

As usual, you can get the code from:
	https://github.com/yangdongsheng/linux.git   ubifs_quota_v3

Changelog:
	v1->v2:
		- remove the duplication in block_dev and char_dev
		- rename read_block to ubifs_read_block
		- drop patch for ui->budgeted
		- budget in ubifs_dirty_inode() if necessary
	v2->v3:
		- introduce a callback function in quotactl_ops
		  to allow filesystem to do some special work
		  in restoring iflags. This fix the problem
		  in V2 about ubifs_dirty_inode()

Dongsheng Yang (39):
  fs: introduce a ->s_cdev field into struct super_block
  fs: cleanup: remove the blank line before EXPORT_SYMBOL
  fs: super: cleanup: make the comment of each function aligned
  fs: super: consolidate the get_super class functions
  fs: super: introduce a get_super_cdev to get super by a cdev reference
  fs: super: introduce a get_super_cdev_thawed to get sb by cdev
    reference
  fs: char_dev: introduce cd_acquire function to acquire cdev
  fs: introduce a __lookup_dev for internal using
  fs: char_dev: introduce lookup_cdev to get cdev by pathname
  fs: dquot: skip invalidate_bdev if bdev is NULL
  fs: quota: replace opened calling of ->sync_fs with sync_filesystem
  fs: quota: make quota support fs which is running on char dev
  fs: introduce a get_qsize() to inode_operations
  fs: quota: restore i_flags of quota files in dquot_disable
  fs: quota: introduce a callback of restore_iflags to quotactl_ops
  ubi: introduce a interface to get cdev in ubi_volume
  ubifs: extend budget for blocks
  ubifs: fill sb->s_cdev in ubifs_fill_super()
  ubifs: fill ->s_dev in ubifs_fill_super
  ubifs: export read_block() from file.c
  ubifs: introduce i_dquot to ubifs_inode
  ubifs: implement IO functions for quota files
  ubifs: disable quota in ubifs_put_super
  ubifs: write quota back in ubifs_sync
  ubifs: set/clear MS_RDONLY properly in ubifs_remount
  ubifs: suspend & resume quota properly in ubifs_remount
  ubifs: check inode with NULL before using it
  ubifs: record quota information about inode in ubifs_new_inode
  ubifs: free quota inode information in ubifs_evict_inode
  ubifs: alloc quota space in ubifs writing path
  ubifs: free quota space in do_truncation
  ubifs: free quota space when deleting a file
  ubifs: adapt quota space informatin in do_setattr
  ubifs: transfer quota information in changing owner or group
  ubifs: write inode in ubifs_quota_write if we are appending
  ubifs: implement ubifs_get_qsize to get quota size in ubifs
  ubifs: implement ubifs_restore_iflags for quotactl_operations
  ubifs: fill the quota related fields in ubifs_fill_super
  ubifs: introduce quota related mount options

 drivers/mtd/ubi/kapi.c  |   6 +
 fs/Makefile             |   2 +-
 fs/block_dev.c          |  26 +----
 fs/char_dev.c           |  48 ++++++++
 fs/dev.c                |  77 +++++++++++++
 fs/internal.h           |  14 +++
 fs/ioctl.c              |  31 +++--
 fs/quota/dquot.c        |  62 ++++++----
 fs/quota/quota.c        |  30 +++--
 fs/super.c              | 284 ++++++++++++++++++++++++---------------------
 fs/ubifs/budget.c       |   4 +
 fs/ubifs/debug.c        |   2 +
 fs/ubifs/dir.c          |  23 +++-
 fs/ubifs/file.c         |  80 ++++++++++++-
 fs/ubifs/journal.c      |   4 +
 fs/ubifs/super.c        | 297 +++++++++++++++++++++++++++++++++++++++++++++++-
 fs/ubifs/ubifs.h        |  17 +++
 include/linux/fs.h      |   6 +
 include/linux/mtd/ubi.h |   1 +
 include/linux/quota.h   |   5 +
 20 files changed, 819 insertions(+), 200 deletions(-)
 create mode 100644 fs/dev.c

-- 
1.8.4.2

^ permalink raw reply	[flat|nested] 107+ messages in thread

* [PATCH v3 01/39] fs: introduce a ->s_cdev field into struct super_block
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:01   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:01 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

There are some filesystems are running on char devs, such
as ubifs. So we need a field in super_block to hold a
reference to the char device.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 include/linux/fs.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/fs.h b/include/linux/fs.h
index 84b783f..9896b62 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1313,6 +1313,7 @@ struct super_block {
 	struct hlist_bl_head	s_anon;		/* anonymous dentries for (nfs) exporting */
 	struct list_head	s_mounts;	/* list of mounts; _not_ for fs use */
 	struct block_device	*s_bdev;
+	struct cdev		*s_cdev;
 	struct backing_dev_info *s_bdi;
 	struct mtd_info		*s_mtd;
 	struct hlist_node	s_instances;
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 01/39] fs: introduce a ->s_cdev field into struct super_block
@ 2015-09-15  9:01   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:01 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

There are some filesystems are running on char devs, such
as ubifs. So we need a field in super_block to hold a
reference to the char device.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 include/linux/fs.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/fs.h b/include/linux/fs.h
index 84b783f..9896b62 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1313,6 +1313,7 @@ struct super_block {
 	struct hlist_bl_head	s_anon;		/* anonymous dentries for (nfs) exporting */
 	struct list_head	s_mounts;	/* list of mounts; _not_ for fs use */
 	struct block_device	*s_bdev;
+	struct cdev		*s_cdev;
 	struct backing_dev_info *s_bdi;
 	struct mtd_info		*s_mtd;
 	struct hlist_node	s_instances;
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 02/39] fs: cleanup: remove the blank line before EXPORT_SYMBOL
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:01   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:01 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/super.c | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/fs/super.c b/fs/super.c
index b613723..72f9e1d 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -299,7 +299,6 @@ void deactivate_locked_super(struct super_block *s)
 		up_write(&s->s_umount);
 	}
 }
-
 EXPORT_SYMBOL(deactivate_locked_super);
 
 /**
@@ -317,7 +316,6 @@ void deactivate_super(struct super_block *s)
 		deactivate_locked_super(s);
 	}
 }
-
 EXPORT_SYMBOL(deactivate_super);
 
 /**
@@ -423,7 +421,6 @@ void generic_shutdown_super(struct super_block *sb)
 	spin_unlock(&sb_lock);
 	up_write(&sb->s_umount);
 }
-
 EXPORT_SYMBOL(generic_shutdown_super);
 
 /**
@@ -484,7 +481,6 @@ retry:
 	register_shrinker(&s->s_shrink);
 	return s;
 }
-
 EXPORT_SYMBOL(sget);
 
 void drop_super(struct super_block *sb)
@@ -492,7 +488,6 @@ void drop_super(struct super_block *sb)
 	up_read(&sb->s_umount);
 	put_super(sb);
 }
-
 EXPORT_SYMBOL(drop_super);
 
 /**
@@ -562,7 +557,6 @@ void iterate_supers_type(struct file_system_type *type,
 		__put_super(p);
 	spin_unlock(&sb_lock);
 }
-
 EXPORT_SYMBOL(iterate_supers_type);
 
 /**
@@ -602,7 +596,6 @@ rescan:
 	spin_unlock(&sb_lock);
 	return NULL;
 }
-
 EXPORT_SYMBOL(get_super);
 
 /**
@@ -870,7 +863,6 @@ int set_anon_super(struct super_block *s, void *data)
 {
 	return get_anon_bdev(&s->s_dev);
 }
-
 EXPORT_SYMBOL(set_anon_super);
 
 void kill_anon_super(struct super_block *sb)
@@ -879,7 +871,6 @@ void kill_anon_super(struct super_block *sb)
 	generic_shutdown_super(sb);
 	free_anon_bdev(dev);
 }
-
 EXPORT_SYMBOL(kill_anon_super);
 
 void kill_litter_super(struct super_block *sb)
@@ -888,7 +879,6 @@ void kill_litter_super(struct super_block *sb)
 		d_genocide(sb->s_root);
 	kill_anon_super(sb);
 }
-
 EXPORT_SYMBOL(kill_litter_super);
 
 static int ns_test_super(struct super_block *sb, void *data)
@@ -924,7 +914,6 @@ struct dentry *mount_ns(struct file_system_type *fs_type, int flags,
 
 	return dget(sb->s_root);
 }
-
 EXPORT_SYMBOL(mount_ns);
 
 #ifdef CONFIG_BLOCK
@@ -1034,7 +1023,6 @@ void kill_block_super(struct super_block *sb)
 	WARN_ON_ONCE(!(mode & FMODE_EXCL));
 	blkdev_put(bdev, mode | FMODE_EXCL);
 }
-
 EXPORT_SYMBOL(kill_block_super);
 #endif
 
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 02/39] fs: cleanup: remove the blank line before EXPORT_SYMBOL
@ 2015-09-15  9:01   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:01 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/super.c | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/fs/super.c b/fs/super.c
index b613723..72f9e1d 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -299,7 +299,6 @@ void deactivate_locked_super(struct super_block *s)
 		up_write(&s->s_umount);
 	}
 }
-
 EXPORT_SYMBOL(deactivate_locked_super);
 
 /**
@@ -317,7 +316,6 @@ void deactivate_super(struct super_block *s)
 		deactivate_locked_super(s);
 	}
 }
-
 EXPORT_SYMBOL(deactivate_super);
 
 /**
@@ -423,7 +421,6 @@ void generic_shutdown_super(struct super_block *sb)
 	spin_unlock(&sb_lock);
 	up_write(&sb->s_umount);
 }
-
 EXPORT_SYMBOL(generic_shutdown_super);
 
 /**
@@ -484,7 +481,6 @@ retry:
 	register_shrinker(&s->s_shrink);
 	return s;
 }
-
 EXPORT_SYMBOL(sget);
 
 void drop_super(struct super_block *sb)
@@ -492,7 +488,6 @@ void drop_super(struct super_block *sb)
 	up_read(&sb->s_umount);
 	put_super(sb);
 }
-
 EXPORT_SYMBOL(drop_super);
 
 /**
@@ -562,7 +557,6 @@ void iterate_supers_type(struct file_system_type *type,
 		__put_super(p);
 	spin_unlock(&sb_lock);
 }
-
 EXPORT_SYMBOL(iterate_supers_type);
 
 /**
@@ -602,7 +596,6 @@ rescan:
 	spin_unlock(&sb_lock);
 	return NULL;
 }
-
 EXPORT_SYMBOL(get_super);
 
 /**
@@ -870,7 +863,6 @@ int set_anon_super(struct super_block *s, void *data)
 {
 	return get_anon_bdev(&s->s_dev);
 }
-
 EXPORT_SYMBOL(set_anon_super);
 
 void kill_anon_super(struct super_block *sb)
@@ -879,7 +871,6 @@ void kill_anon_super(struct super_block *sb)
 	generic_shutdown_super(sb);
 	free_anon_bdev(dev);
 }
-
 EXPORT_SYMBOL(kill_anon_super);
 
 void kill_litter_super(struct super_block *sb)
@@ -888,7 +879,6 @@ void kill_litter_super(struct super_block *sb)
 		d_genocide(sb->s_root);
 	kill_anon_super(sb);
 }
-
 EXPORT_SYMBOL(kill_litter_super);
 
 static int ns_test_super(struct super_block *sb, void *data)
@@ -924,7 +914,6 @@ struct dentry *mount_ns(struct file_system_type *fs_type, int flags,
 
 	return dget(sb->s_root);
 }
-
 EXPORT_SYMBOL(mount_ns);
 
 #ifdef CONFIG_BLOCK
@@ -1034,7 +1023,6 @@ void kill_block_super(struct super_block *sb)
 	WARN_ON_ONCE(!(mode & FMODE_EXCL));
 	blkdev_put(bdev, mode | FMODE_EXCL);
 }
-
 EXPORT_SYMBOL(kill_block_super);
 #endif
 
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 03/39] fs: super: cleanup: make the comment of each function aligned
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:01   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:01 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

Originally, some of the comments start with "*\t" but some of them
start with "* ". This commit make them all start with "* "

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/super.c | 180 ++++++++++++++++++++++++++++++-------------------------------
 1 file changed, 90 insertions(+), 90 deletions(-)

diff --git a/fs/super.c b/fs/super.c
index 72f9e1d..9589fa4 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -136,10 +136,10 @@ static unsigned long super_cache_count(struct shrinker *shrink,
 }
 
 /**
- *	destroy_super	-	frees a superblock
- *	@s: superblock to free
+ * destroy_super	-	frees a superblock
+ * @s: superblock to free
  *
- *	Frees a superblock.
+ * Frees a superblock.
  */
 static void destroy_super(struct super_block *s)
 {
@@ -156,12 +156,12 @@ static void destroy_super(struct super_block *s)
 }
 
 /**
- *	alloc_super	-	create new superblock
- *	@type:	filesystem type superblock should belong to
- *	@flags: the mount flags
+ * alloc_super	-	create new superblock
+ * @type:	filesystem type superblock should belong to
+ * @flags: the mount flags
  *
- *	Allocates and initializes a new &struct super_block.  alloc_super()
- *	returns a pointer new superblock or %NULL if allocation had failed.
+ * Allocates and initializes a new &struct super_block.  alloc_super()
+ * returns a pointer new superblock or %NULL if allocation had failed.
  */
 static struct super_block *alloc_super(struct file_system_type *type, int flags)
 {
@@ -252,11 +252,11 @@ static void __put_super(struct super_block *sb)
 }
 
 /**
- *	put_super	-	drop a temporary reference to superblock
- *	@sb: superblock in question
+ * put_super	-	drop a temporary reference to superblock
+ * @sb: superblock in question
  *
- *	Drops a temporary reference, frees superblock if there's no
- *	references left.
+ * Drops a temporary reference, frees superblock if there's no
+ * references left.
  */
 static void put_super(struct super_block *sb)
 {
@@ -267,15 +267,15 @@ static void put_super(struct super_block *sb)
 
 
 /**
- *	deactivate_locked_super	-	drop an active reference to superblock
- *	@s: superblock to deactivate
+ * deactivate_locked_super	-	drop an active reference to superblock
+ * @s: superblock to deactivate
  *
- *	Drops an active reference to superblock, converting it into a temprory
- *	one if there is no other active references left.  In that case we
- *	tell fs driver to shut it down and drop the temporary reference we
- *	had just acquired.
+ * Drops an active reference to superblock, converting it into a temprory
+ * one if there is no other active references left.  In that case we
+ * tell fs driver to shut it down and drop the temporary reference we
+ * had just acquired.
  *
- *	Caller holds exclusive lock on superblock; that lock is released.
+ * Caller holds exclusive lock on superblock; that lock is released.
  */
 void deactivate_locked_super(struct super_block *s)
 {
@@ -302,12 +302,12 @@ void deactivate_locked_super(struct super_block *s)
 EXPORT_SYMBOL(deactivate_locked_super);
 
 /**
- *	deactivate_super	-	drop an active reference to superblock
- *	@s: superblock to deactivate
+ * deactivate_super	-	drop an active reference to superblock
+ * @s: superblock to deactivate
  *
- *	Variant of deactivate_locked_super(), except that superblock is *not*
- *	locked by caller.  If we are going to drop the final active reference,
- *	lock will be acquired prior to that.
+ * Variant of deactivate_locked_super(), except that superblock is *not*
+ * locked by caller.  If we are going to drop the final active reference,
+ * lock will be acquired prior to that.
  */
 void deactivate_super(struct super_block *s)
 {
@@ -319,17 +319,17 @@ void deactivate_super(struct super_block *s)
 EXPORT_SYMBOL(deactivate_super);
 
 /**
- *	grab_super - acquire an active reference
- *	@s: reference we are trying to make active
+ * grab_super - acquire an active reference
+ * @s: reference we are trying to make active
  *
- *	Tries to acquire an active reference.  grab_super() is used when we
- * 	had just found a superblock in super_blocks or fs_type->fs_supers
- *	and want to turn it into a full-blown active reference.  grab_super()
- *	is called with sb_lock held and drops it.  Returns 1 in case of
- *	success, 0 if we had failed (superblock contents was already dead or
- *	dying when grab_super() had been called).  Note that this is only
- *	called for superblocks not in rundown mode (== ones still on ->fs_supers
- *	of their type), so increment of ->s_count is OK here.
+ * Tries to acquire an active reference.  grab_super() is used when we
+ * had just found a superblock in super_blocks or fs_type->fs_supers
+ * and want to turn it into a full-blown active reference.  grab_super()
+ * is called with sb_lock held and drops it.  Returns 1 in case of
+ * success, 0 if we had failed (superblock contents was already dead or
+ * dying when grab_super() had been called).  Note that this is only
+ * called for superblocks not in rundown mode (== ones still on ->fs_supers
+ * of their type), so increment of ->s_count is OK here.
  */
 static int grab_super(struct super_block *s) __releases(sb_lock)
 {
@@ -346,21 +346,21 @@ static int grab_super(struct super_block *s) __releases(sb_lock)
 }
 
 /*
- *	trylock_super - try to grab ->s_umount shared
- *	@sb: reference we are trying to grab
+ * trylock_super - try to grab ->s_umount shared
+ * @sb: reference we are trying to grab
  *
- *	Try to prevent fs shutdown.  This is used in places where we
- *	cannot take an active reference but we need to ensure that the
- *	filesystem is not shut down while we are working on it. It returns
- *	false if we cannot acquire s_umount or if we lose the race and
- *	filesystem already got into shutdown, and returns true with the s_umount
- *	lock held in read mode in case of success. On successful return,
- *	the caller must drop the s_umount lock when done.
+ * Try to prevent fs shutdown.  This is used in places where we
+ * cannot take an active reference but we need to ensure that the
+ * filesystem is not shut down while we are working on it. It returns
+ * false if we cannot acquire s_umount or if we lose the race and
+ * filesystem already got into shutdown, and returns true with the s_umount
+ * lock held in read mode in case of success. On successful return,
+ * the caller must drop the s_umount lock when done.
  *
- *	Note that unlike get_super() et.al. this one does *not* bump ->s_count.
- *	The reason why it's safe is that we are OK with doing trylock instead
- *	of down_read().  There's a couple of places that are OK with that, but
- *	it's very much not a general-purpose interface.
+ * Note that unlike get_super() et.al. this one does *not* bump ->s_count.
+ * The reason why it's safe is that we are OK with doing trylock instead
+ * of down_read().  There's a couple of places that are OK with that, but
+ * it's very much not a general-purpose interface.
  */
 bool trylock_super(struct super_block *sb)
 {
@@ -375,18 +375,18 @@ bool trylock_super(struct super_block *sb)
 }
 
 /**
- *	generic_shutdown_super	-	common helper for ->kill_sb()
- *	@sb: superblock to kill
+ * generic_shutdown_super	-	common helper for ->kill_sb()
+ * @sb: superblock to kill
  *
- *	generic_shutdown_super() does all fs-independent work on superblock
- *	shutdown.  Typical ->kill_sb() should pick all fs-specific objects
- *	that need destruction out of superblock, call generic_shutdown_super()
- *	and release aforementioned objects.  Note: dentries and inodes _are_
- *	taken care of and do not need specific handling.
+ * generic_shutdown_super() does all fs-independent work on superblock
+ * shutdown.  Typical ->kill_sb() should pick all fs-specific objects
+ * that need destruction out of superblock, call generic_shutdown_super()
+ * and release aforementioned objects.  Note: dentries and inodes _are_
+ * taken care of and do not need specific handling.
  *
- *	Upon calling this function, the filesystem may no longer alter or
- *	rearrange the set of dentries belonging to this super_block, nor may it
- *	change the attachments of dentries to inodes.
+ * Upon calling this function, the filesystem may no longer alter or
+ * rearrange the set of dentries belonging to this super_block, nor may it
+ * change the attachments of dentries to inodes.
  */
 void generic_shutdown_super(struct super_block *sb)
 {
@@ -424,12 +424,12 @@ void generic_shutdown_super(struct super_block *sb)
 EXPORT_SYMBOL(generic_shutdown_super);
 
 /**
- *	sget	-	find or create a superblock
- *	@type:	filesystem type superblock should belong to
- *	@test:	comparison callback
- *	@set:	setup callback
- *	@flags:	mount flags
- *	@data:	argument to each of them
+ * sget	-	find or create a superblock
+ * @type:	filesystem type superblock should belong to
+ * @test:	comparison callback
+ * @set:	setup callback
+ * @flags:	mount flags
+ * @data:	argument to each of them
  */
 struct super_block *sget(struct file_system_type *type,
 			int (*test)(struct super_block *,void *),
@@ -491,12 +491,12 @@ void drop_super(struct super_block *sb)
 EXPORT_SYMBOL(drop_super);
 
 /**
- *	iterate_supers - call function for all active superblocks
- *	@f: function to call
- *	@arg: argument to pass to it
+ * iterate_supers - call function for all active superblocks
+ * @f: function to call
+ * @arg: argument to pass to it
  *
- *	Scans the superblock list and calls given function, passing it
- *	locked superblock and given argument.
+ * Scans the superblock list and calls given function, passing it
+ * locked superblock and given argument.
  */
 void iterate_supers(void (*f)(struct super_block *, void *), void *arg)
 {
@@ -525,13 +525,13 @@ void iterate_supers(void (*f)(struct super_block *, void *), void *arg)
 }
 
 /**
- *	iterate_supers_type - call function for superblocks of given type
- *	@type: fs type
- *	@f: function to call
- *	@arg: argument to pass to it
+ * iterate_supers_type - call function for superblocks of given type
+ * @type: fs type
+ * @f: function to call
+ * @arg: argument to pass to it
  *
- *	Scans the superblock list and calls given function, passing it
- *	locked superblock and given argument.
+ * Scans the superblock list and calls given function, passing it
+ * locked superblock and given argument.
  */
 void iterate_supers_type(struct file_system_type *type,
 	void (*f)(struct super_block *, void *), void *arg)
@@ -560,11 +560,11 @@ void iterate_supers_type(struct file_system_type *type,
 EXPORT_SYMBOL(iterate_supers_type);
 
 /**
- *	get_super - get the superblock of a device
- *	@bdev: device to get the superblock for
- *	
- *	Scans the superblock list and finds the superblock of the file system
- *	mounted on the device given. %NULL is returned if no match is found.
+ * get_super - get the superblock of a device
+ * @bdev: device to get the superblock for
+ * 
+ * Scans the superblock list and finds the superblock of the file system
+ * mounted on the device given. %NULL is returned if no match is found.
  */
 
 struct super_block *get_super(struct block_device *bdev)
@@ -599,13 +599,13 @@ rescan:
 EXPORT_SYMBOL(get_super);
 
 /**
- *	get_super_thawed - get thawed superblock of a device
- *	@bdev: device to get the superblock for
+ * get_super_thawed - get thawed superblock of a device
+ * @bdev: device to get the superblock for
  *
- *	Scans the superblock list and finds the superblock of the file system
- *	mounted on the device. The superblock is returned once it is thawed
- *	(or immediately if it was not frozen). %NULL is returned if no match
- *	is found.
+ * Scans the superblock list and finds the superblock of the file system
+ * mounted on the device. The superblock is returned once it is thawed
+ * (or immediately if it was not frozen). %NULL is returned if no match
+ * is found.
  */
 struct super_block *get_super_thawed(struct block_device *bdev)
 {
@@ -680,13 +680,13 @@ rescan:
 }
 
 /**
- *	do_remount_sb - asks filesystem to change mount options.
- *	@sb:	superblock in question
- *	@flags:	numeric part of options
- *	@data:	the rest of options
+ * do_remount_sb - asks filesystem to change mount options.
+ * @sb:	superblock in question
+ * @flags:	numeric part of options
+ * @data:	the rest of options
  *      @force: whether or not to force the change
  *
- *	Alters the mount options of a mounted file system.
+ * Alters the mount options of a mounted file system.
  */
 int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
 {
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 03/39] fs: super: cleanup: make the comment of each function aligned
@ 2015-09-15  9:01   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:01 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

Originally, some of the comments start with "*\t" but some of them
start with "* ". This commit make them all start with "* "

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/super.c | 180 ++++++++++++++++++++++++++++++-------------------------------
 1 file changed, 90 insertions(+), 90 deletions(-)

diff --git a/fs/super.c b/fs/super.c
index 72f9e1d..9589fa4 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -136,10 +136,10 @@ static unsigned long super_cache_count(struct shrinker *shrink,
 }
 
 /**
- *	destroy_super	-	frees a superblock
- *	@s: superblock to free
+ * destroy_super	-	frees a superblock
+ * @s: superblock to free
  *
- *	Frees a superblock.
+ * Frees a superblock.
  */
 static void destroy_super(struct super_block *s)
 {
@@ -156,12 +156,12 @@ static void destroy_super(struct super_block *s)
 }
 
 /**
- *	alloc_super	-	create new superblock
- *	@type:	filesystem type superblock should belong to
- *	@flags: the mount flags
+ * alloc_super	-	create new superblock
+ * @type:	filesystem type superblock should belong to
+ * @flags: the mount flags
  *
- *	Allocates and initializes a new &struct super_block.  alloc_super()
- *	returns a pointer new superblock or %NULL if allocation had failed.
+ * Allocates and initializes a new &struct super_block.  alloc_super()
+ * returns a pointer new superblock or %NULL if allocation had failed.
  */
 static struct super_block *alloc_super(struct file_system_type *type, int flags)
 {
@@ -252,11 +252,11 @@ static void __put_super(struct super_block *sb)
 }
 
 /**
- *	put_super	-	drop a temporary reference to superblock
- *	@sb: superblock in question
+ * put_super	-	drop a temporary reference to superblock
+ * @sb: superblock in question
  *
- *	Drops a temporary reference, frees superblock if there's no
- *	references left.
+ * Drops a temporary reference, frees superblock if there's no
+ * references left.
  */
 static void put_super(struct super_block *sb)
 {
@@ -267,15 +267,15 @@ static void put_super(struct super_block *sb)
 
 
 /**
- *	deactivate_locked_super	-	drop an active reference to superblock
- *	@s: superblock to deactivate
+ * deactivate_locked_super	-	drop an active reference to superblock
+ * @s: superblock to deactivate
  *
- *	Drops an active reference to superblock, converting it into a temprory
- *	one if there is no other active references left.  In that case we
- *	tell fs driver to shut it down and drop the temporary reference we
- *	had just acquired.
+ * Drops an active reference to superblock, converting it into a temprory
+ * one if there is no other active references left.  In that case we
+ * tell fs driver to shut it down and drop the temporary reference we
+ * had just acquired.
  *
- *	Caller holds exclusive lock on superblock; that lock is released.
+ * Caller holds exclusive lock on superblock; that lock is released.
  */
 void deactivate_locked_super(struct super_block *s)
 {
@@ -302,12 +302,12 @@ void deactivate_locked_super(struct super_block *s)
 EXPORT_SYMBOL(deactivate_locked_super);
 
 /**
- *	deactivate_super	-	drop an active reference to superblock
- *	@s: superblock to deactivate
+ * deactivate_super	-	drop an active reference to superblock
+ * @s: superblock to deactivate
  *
- *	Variant of deactivate_locked_super(), except that superblock is *not*
- *	locked by caller.  If we are going to drop the final active reference,
- *	lock will be acquired prior to that.
+ * Variant of deactivate_locked_super(), except that superblock is *not*
+ * locked by caller.  If we are going to drop the final active reference,
+ * lock will be acquired prior to that.
  */
 void deactivate_super(struct super_block *s)
 {
@@ -319,17 +319,17 @@ void deactivate_super(struct super_block *s)
 EXPORT_SYMBOL(deactivate_super);
 
 /**
- *	grab_super - acquire an active reference
- *	@s: reference we are trying to make active
+ * grab_super - acquire an active reference
+ * @s: reference we are trying to make active
  *
- *	Tries to acquire an active reference.  grab_super() is used when we
- * 	had just found a superblock in super_blocks or fs_type->fs_supers
- *	and want to turn it into a full-blown active reference.  grab_super()
- *	is called with sb_lock held and drops it.  Returns 1 in case of
- *	success, 0 if we had failed (superblock contents was already dead or
- *	dying when grab_super() had been called).  Note that this is only
- *	called for superblocks not in rundown mode (== ones still on ->fs_supers
- *	of their type), so increment of ->s_count is OK here.
+ * Tries to acquire an active reference.  grab_super() is used when we
+ * had just found a superblock in super_blocks or fs_type->fs_supers
+ * and want to turn it into a full-blown active reference.  grab_super()
+ * is called with sb_lock held and drops it.  Returns 1 in case of
+ * success, 0 if we had failed (superblock contents was already dead or
+ * dying when grab_super() had been called).  Note that this is only
+ * called for superblocks not in rundown mode (== ones still on ->fs_supers
+ * of their type), so increment of ->s_count is OK here.
  */
 static int grab_super(struct super_block *s) __releases(sb_lock)
 {
@@ -346,21 +346,21 @@ static int grab_super(struct super_block *s) __releases(sb_lock)
 }
 
 /*
- *	trylock_super - try to grab ->s_umount shared
- *	@sb: reference we are trying to grab
+ * trylock_super - try to grab ->s_umount shared
+ * @sb: reference we are trying to grab
  *
- *	Try to prevent fs shutdown.  This is used in places where we
- *	cannot take an active reference but we need to ensure that the
- *	filesystem is not shut down while we are working on it. It returns
- *	false if we cannot acquire s_umount or if we lose the race and
- *	filesystem already got into shutdown, and returns true with the s_umount
- *	lock held in read mode in case of success. On successful return,
- *	the caller must drop the s_umount lock when done.
+ * Try to prevent fs shutdown.  This is used in places where we
+ * cannot take an active reference but we need to ensure that the
+ * filesystem is not shut down while we are working on it. It returns
+ * false if we cannot acquire s_umount or if we lose the race and
+ * filesystem already got into shutdown, and returns true with the s_umount
+ * lock held in read mode in case of success. On successful return,
+ * the caller must drop the s_umount lock when done.
  *
- *	Note that unlike get_super() et.al. this one does *not* bump ->s_count.
- *	The reason why it's safe is that we are OK with doing trylock instead
- *	of down_read().  There's a couple of places that are OK with that, but
- *	it's very much not a general-purpose interface.
+ * Note that unlike get_super() et.al. this one does *not* bump ->s_count.
+ * The reason why it's safe is that we are OK with doing trylock instead
+ * of down_read().  There's a couple of places that are OK with that, but
+ * it's very much not a general-purpose interface.
  */
 bool trylock_super(struct super_block *sb)
 {
@@ -375,18 +375,18 @@ bool trylock_super(struct super_block *sb)
 }
 
 /**
- *	generic_shutdown_super	-	common helper for ->kill_sb()
- *	@sb: superblock to kill
+ * generic_shutdown_super	-	common helper for ->kill_sb()
+ * @sb: superblock to kill
  *
- *	generic_shutdown_super() does all fs-independent work on superblock
- *	shutdown.  Typical ->kill_sb() should pick all fs-specific objects
- *	that need destruction out of superblock, call generic_shutdown_super()
- *	and release aforementioned objects.  Note: dentries and inodes _are_
- *	taken care of and do not need specific handling.
+ * generic_shutdown_super() does all fs-independent work on superblock
+ * shutdown.  Typical ->kill_sb() should pick all fs-specific objects
+ * that need destruction out of superblock, call generic_shutdown_super()
+ * and release aforementioned objects.  Note: dentries and inodes _are_
+ * taken care of and do not need specific handling.
  *
- *	Upon calling this function, the filesystem may no longer alter or
- *	rearrange the set of dentries belonging to this super_block, nor may it
- *	change the attachments of dentries to inodes.
+ * Upon calling this function, the filesystem may no longer alter or
+ * rearrange the set of dentries belonging to this super_block, nor may it
+ * change the attachments of dentries to inodes.
  */
 void generic_shutdown_super(struct super_block *sb)
 {
@@ -424,12 +424,12 @@ void generic_shutdown_super(struct super_block *sb)
 EXPORT_SYMBOL(generic_shutdown_super);
 
 /**
- *	sget	-	find or create a superblock
- *	@type:	filesystem type superblock should belong to
- *	@test:	comparison callback
- *	@set:	setup callback
- *	@flags:	mount flags
- *	@data:	argument to each of them
+ * sget	-	find or create a superblock
+ * @type:	filesystem type superblock should belong to
+ * @test:	comparison callback
+ * @set:	setup callback
+ * @flags:	mount flags
+ * @data:	argument to each of them
  */
 struct super_block *sget(struct file_system_type *type,
 			int (*test)(struct super_block *,void *),
@@ -491,12 +491,12 @@ void drop_super(struct super_block *sb)
 EXPORT_SYMBOL(drop_super);
 
 /**
- *	iterate_supers - call function for all active superblocks
- *	@f: function to call
- *	@arg: argument to pass to it
+ * iterate_supers - call function for all active superblocks
+ * @f: function to call
+ * @arg: argument to pass to it
  *
- *	Scans the superblock list and calls given function, passing it
- *	locked superblock and given argument.
+ * Scans the superblock list and calls given function, passing it
+ * locked superblock and given argument.
  */
 void iterate_supers(void (*f)(struct super_block *, void *), void *arg)
 {
@@ -525,13 +525,13 @@ void iterate_supers(void (*f)(struct super_block *, void *), void *arg)
 }
 
 /**
- *	iterate_supers_type - call function for superblocks of given type
- *	@type: fs type
- *	@f: function to call
- *	@arg: argument to pass to it
+ * iterate_supers_type - call function for superblocks of given type
+ * @type: fs type
+ * @f: function to call
+ * @arg: argument to pass to it
  *
- *	Scans the superblock list and calls given function, passing it
- *	locked superblock and given argument.
+ * Scans the superblock list and calls given function, passing it
+ * locked superblock and given argument.
  */
 void iterate_supers_type(struct file_system_type *type,
 	void (*f)(struct super_block *, void *), void *arg)
@@ -560,11 +560,11 @@ void iterate_supers_type(struct file_system_type *type,
 EXPORT_SYMBOL(iterate_supers_type);
 
 /**
- *	get_super - get the superblock of a device
- *	@bdev: device to get the superblock for
- *	
- *	Scans the superblock list and finds the superblock of the file system
- *	mounted on the device given. %NULL is returned if no match is found.
+ * get_super - get the superblock of a device
+ * @bdev: device to get the superblock for
+ * 
+ * Scans the superblock list and finds the superblock of the file system
+ * mounted on the device given. %NULL is returned if no match is found.
  */
 
 struct super_block *get_super(struct block_device *bdev)
@@ -599,13 +599,13 @@ rescan:
 EXPORT_SYMBOL(get_super);
 
 /**
- *	get_super_thawed - get thawed superblock of a device
- *	@bdev: device to get the superblock for
+ * get_super_thawed - get thawed superblock of a device
+ * @bdev: device to get the superblock for
  *
- *	Scans the superblock list and finds the superblock of the file system
- *	mounted on the device. The superblock is returned once it is thawed
- *	(or immediately if it was not frozen). %NULL is returned if no match
- *	is found.
+ * Scans the superblock list and finds the superblock of the file system
+ * mounted on the device. The superblock is returned once it is thawed
+ * (or immediately if it was not frozen). %NULL is returned if no match
+ * is found.
  */
 struct super_block *get_super_thawed(struct block_device *bdev)
 {
@@ -680,13 +680,13 @@ rescan:
 }
 
 /**
- *	do_remount_sb - asks filesystem to change mount options.
- *	@sb:	superblock in question
- *	@flags:	numeric part of options
- *	@data:	the rest of options
+ * do_remount_sb - asks filesystem to change mount options.
+ * @sb:	superblock in question
+ * @flags:	numeric part of options
+ * @data:	the rest of options
  *      @force: whether or not to force the change
  *
- *	Alters the mount options of a mounted file system.
+ * Alters the mount options of a mounted file system.
  */
 int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
 {
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 04/39] fs: super: consolidate the get_super class functions
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:01   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:01 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

There is a lot of duplicated code in get_super and user_get_super.
This commit introduc a __get_super as a common function to reduce
the duplication of it.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
Reviewed-by: Jan Kara <jack@suse.com>
---
 fs/super.c | 64 ++++++++++++++++++++++++++++++--------------------------------
 1 file changed, 31 insertions(+), 33 deletions(-)

diff --git a/fs/super.c b/fs/super.c
index 9589fa4..4d667fe 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -559,19 +559,20 @@ void iterate_supers_type(struct file_system_type *type,
 }
 EXPORT_SYMBOL(iterate_supers_type);
 
-/**
- * get_super - get the superblock of a device
- * @bdev: device to get the superblock for
- * 
- * Scans the superblock list and finds the superblock of the file system
- * mounted on the device given. %NULL is returned if no match is found.
+/*
+ * __get_super - helper function for the other functions in get_super class
+ * @compare: function pointer to compare sb in list and key
+ * @key: key of the sb you want
+ *
+ * Scans the superblock list and finds the superblock you want. %NULL is
+ * returned if no match is found.
  */
-
-struct super_block *get_super(struct block_device *bdev)
+static struct super_block *__get_super(
+		int (*compare)(struct super_block *, void *), void *key)
 {
 	struct super_block *sb;
 
-	if (!bdev)
+	if (!key)
 		return NULL;
 
 	spin_lock(&sb_lock);
@@ -579,7 +580,7 @@ rescan:
 	list_for_each_entry(sb, &super_blocks, s_list) {
 		if (hlist_unhashed(&sb->s_instances))
 			continue;
-		if (sb->s_bdev == bdev) {
+		if (compare(sb, key)) {
 			sb->s_count++;
 			spin_unlock(&sb_lock);
 			down_read(&sb->s_umount);
@@ -596,6 +597,20 @@ rescan:
 	spin_unlock(&sb_lock);
 	return NULL;
 }
+
+static int bdev_compare(struct super_block *sb, void *key)
+{
+	return (sb->s_bdev == (struct block_device *)key);
+}
+
+/**
+ * get_super - get the superblock of a device
+ * @bdev: device to get the superblock for
+ */
+struct super_block *get_super(struct block_device *bdev)
+{
+	return __get_super(bdev_compare, bdev);
+}
 EXPORT_SYMBOL(get_super);
 
 /**
@@ -651,32 +666,15 @@ restart:
 	spin_unlock(&sb_lock);
 	return NULL;
 }
+
+static int user_compare(struct super_block *sb, void *key)
+{
+	return (sb->s_dev == *(dev_t *)key);
+}
  
 struct super_block *user_get_super(dev_t dev)
 {
-	struct super_block *sb;
-
-	spin_lock(&sb_lock);
-rescan:
-	list_for_each_entry(sb, &super_blocks, s_list) {
-		if (hlist_unhashed(&sb->s_instances))
-			continue;
-		if (sb->s_dev ==  dev) {
-			sb->s_count++;
-			spin_unlock(&sb_lock);
-			down_read(&sb->s_umount);
-			/* still alive? */
-			if (sb->s_root && (sb->s_flags & MS_BORN))
-				return sb;
-			up_read(&sb->s_umount);
-			/* nope, got unmounted */
-			spin_lock(&sb_lock);
-			__put_super(sb);
-			goto rescan;
-		}
-	}
-	spin_unlock(&sb_lock);
-	return NULL;
+	return __get_super(user_compare, &dev);
 }
 
 /**
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 04/39] fs: super: consolidate the get_super class functions
@ 2015-09-15  9:01   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:01 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

There is a lot of duplicated code in get_super and user_get_super.
This commit introduc a __get_super as a common function to reduce
the duplication of it.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
Reviewed-by: Jan Kara <jack@suse.com>
---
 fs/super.c | 64 ++++++++++++++++++++++++++++++--------------------------------
 1 file changed, 31 insertions(+), 33 deletions(-)

diff --git a/fs/super.c b/fs/super.c
index 9589fa4..4d667fe 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -559,19 +559,20 @@ void iterate_supers_type(struct file_system_type *type,
 }
 EXPORT_SYMBOL(iterate_supers_type);
 
-/**
- * get_super - get the superblock of a device
- * @bdev: device to get the superblock for
- * 
- * Scans the superblock list and finds the superblock of the file system
- * mounted on the device given. %NULL is returned if no match is found.
+/*
+ * __get_super - helper function for the other functions in get_super class
+ * @compare: function pointer to compare sb in list and key
+ * @key: key of the sb you want
+ *
+ * Scans the superblock list and finds the superblock you want. %NULL is
+ * returned if no match is found.
  */
-
-struct super_block *get_super(struct block_device *bdev)
+static struct super_block *__get_super(
+		int (*compare)(struct super_block *, void *), void *key)
 {
 	struct super_block *sb;
 
-	if (!bdev)
+	if (!key)
 		return NULL;
 
 	spin_lock(&sb_lock);
@@ -579,7 +580,7 @@ rescan:
 	list_for_each_entry(sb, &super_blocks, s_list) {
 		if (hlist_unhashed(&sb->s_instances))
 			continue;
-		if (sb->s_bdev == bdev) {
+		if (compare(sb, key)) {
 			sb->s_count++;
 			spin_unlock(&sb_lock);
 			down_read(&sb->s_umount);
@@ -596,6 +597,20 @@ rescan:
 	spin_unlock(&sb_lock);
 	return NULL;
 }
+
+static int bdev_compare(struct super_block *sb, void *key)
+{
+	return (sb->s_bdev == (struct block_device *)key);
+}
+
+/**
+ * get_super - get the superblock of a device
+ * @bdev: device to get the superblock for
+ */
+struct super_block *get_super(struct block_device *bdev)
+{
+	return __get_super(bdev_compare, bdev);
+}
 EXPORT_SYMBOL(get_super);
 
 /**
@@ -651,32 +666,15 @@ restart:
 	spin_unlock(&sb_lock);
 	return NULL;
 }
+
+static int user_compare(struct super_block *sb, void *key)
+{
+	return (sb->s_dev == *(dev_t *)key);
+}
  
 struct super_block *user_get_super(dev_t dev)
 {
-	struct super_block *sb;
-
-	spin_lock(&sb_lock);
-rescan:
-	list_for_each_entry(sb, &super_blocks, s_list) {
-		if (hlist_unhashed(&sb->s_instances))
-			continue;
-		if (sb->s_dev ==  dev) {
-			sb->s_count++;
-			spin_unlock(&sb_lock);
-			down_read(&sb->s_umount);
-			/* still alive? */
-			if (sb->s_root && (sb->s_flags & MS_BORN))
-				return sb;
-			up_read(&sb->s_umount);
-			/* nope, got unmounted */
-			spin_lock(&sb_lock);
-			__put_super(sb);
-			goto rescan;
-		}
-	}
-	spin_unlock(&sb_lock);
-	return NULL;
+	return __get_super(user_compare, &dev);
 }
 
 /**
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 05/39] fs: super: introduce a get_super_cdev to get super by a cdev reference
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:02   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

As we have cdev in superblock now, we can provide get_super_cdev
to get super_block by a cdev reference, similar with get_super
which is working only for block_device.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
Reviewed-by: Jan Kara <jack@suse.com>
---
 fs/super.c         | 15 +++++++++++++++
 include/linux/fs.h |  1 +
 2 files changed, 16 insertions(+)

diff --git a/fs/super.c b/fs/super.c
index 4d667fe..321d16b 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -613,6 +613,21 @@ struct super_block *get_super(struct block_device *bdev)
 }
 EXPORT_SYMBOL(get_super);
 
+static int cdev_compare(struct super_block *sb, void *key)
+{
+	return (sb->s_cdev == (struct cdev *)key);
+}
+
+/**
+ * get_super_cdev - get the superblock of a cdev
+ * @cdev: char device to get the superblock for
+ */
+struct super_block *get_super_cdev(struct cdev *cdev)
+{
+	return __get_super(cdev_compare, cdev);
+}
+EXPORT_SYMBOL(get_super_cdev);
+
 /**
  * get_super_thawed - get thawed superblock of a device
  * @bdev: device to get the superblock for
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 9896b62..df71cbb 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2796,6 +2796,7 @@ extern void get_filesystem(struct file_system_type *fs);
 extern void put_filesystem(struct file_system_type *fs);
 extern struct file_system_type *get_fs_type(const char *name);
 extern struct super_block *get_super(struct block_device *);
+extern struct super_block *get_super_cdev(struct cdev *);
 extern struct super_block *get_super_thawed(struct block_device *);
 extern struct super_block *get_active_super(struct block_device *bdev);
 extern void drop_super(struct super_block *sb);
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 05/39] fs: super: introduce a get_super_cdev to get super by a cdev reference
@ 2015-09-15  9:02   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

As we have cdev in superblock now, we can provide get_super_cdev
to get super_block by a cdev reference, similar with get_super
which is working only for block_device.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
Reviewed-by: Jan Kara <jack@suse.com>
---
 fs/super.c         | 15 +++++++++++++++
 include/linux/fs.h |  1 +
 2 files changed, 16 insertions(+)

diff --git a/fs/super.c b/fs/super.c
index 4d667fe..321d16b 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -613,6 +613,21 @@ struct super_block *get_super(struct block_device *bdev)
 }
 EXPORT_SYMBOL(get_super);
 
+static int cdev_compare(struct super_block *sb, void *key)
+{
+	return (sb->s_cdev == (struct cdev *)key);
+}
+
+/**
+ * get_super_cdev - get the superblock of a cdev
+ * @cdev: char device to get the superblock for
+ */
+struct super_block *get_super_cdev(struct cdev *cdev)
+{
+	return __get_super(cdev_compare, cdev);
+}
+EXPORT_SYMBOL(get_super_cdev);
+
 /**
  * get_super_thawed - get thawed superblock of a device
  * @bdev: device to get the superblock for
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 9896b62..df71cbb 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2796,6 +2796,7 @@ extern void get_filesystem(struct file_system_type *fs);
 extern void put_filesystem(struct file_system_type *fs);
 extern struct file_system_type *get_fs_type(const char *name);
 extern struct super_block *get_super(struct block_device *);
+extern struct super_block *get_super_cdev(struct cdev *);
 extern struct super_block *get_super_thawed(struct block_device *);
 extern struct super_block *get_active_super(struct block_device *bdev);
 extern void drop_super(struct super_block *sb);
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 06/39] fs: super: introduce a get_super_cdev_thawed to get sb by cdev reference
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:02   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

This patch refactors the original get_super_thawed to get a common
helper function of __get_super_thawed. Then take the use of
__get_super_thawed, we can implement get_super_cdev_thawed easily.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/super.c         | 29 +++++++++++++++++++++++++----
 include/linux/fs.h |  1 +
 2 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/fs/super.c b/fs/super.c
index 321d16b..df32393 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -629,18 +629,20 @@ struct super_block *get_super_cdev(struct cdev *cdev)
 EXPORT_SYMBOL(get_super_cdev);
 
 /**
- * get_super_thawed - get thawed superblock of a device
- * @bdev: device to get the superblock for
+ * __get_super_thawed - get thawed superblock
+ * @func: function pointer to get superblock by key
+ * @key: key to find superblock
  *
  * Scans the superblock list and finds the superblock of the file system
  * mounted on the device. The superblock is returned once it is thawed
  * (or immediately if it was not frozen). %NULL is returned if no match
  * is found.
  */
-struct super_block *get_super_thawed(struct block_device *bdev)
+static struct super_block *__get_super_thawed(
+		int (*compare)(struct super_block *, void *), void *key)
 {
 	while (1) {
-		struct super_block *s = get_super(bdev);
+		struct super_block *s = __get_super(compare, key);
 		if (!s || s->s_writers.frozen == SB_UNFROZEN)
 			return s;
 		up_read(&s->s_umount);
@@ -649,9 +651,28 @@ struct super_block *get_super_thawed(struct block_device *bdev)
 		put_super(s);
 	}
 }
+
+/**
+ * get_super_thawed - get thawed superblock of a device
+ * @bdev: device to get the superblock for
+ */
+struct super_block *get_super_thawed(struct block_device *bdev)
+{
+	return __get_super_thawed(bdev_compare, bdev);
+}
 EXPORT_SYMBOL(get_super_thawed);
 
 /**
+ * get_super_cdev_thawed - get thawed superblock of a char device
+ * @cdev: device to get the superblock for
+ */
+struct super_block *get_super_cdev_thawed(struct cdev *cdev)
+{
+	return __get_super_thawed(cdev_compare, cdev);
+}
+EXPORT_SYMBOL(get_super_cdev_thawed);
+
+/**
  * get_active_super - get an active reference to the superblock of a device
  * @bdev: device to get the superblock for
  *
diff --git a/include/linux/fs.h b/include/linux/fs.h
index df71cbb..2c1c122 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2798,6 +2798,7 @@ extern struct file_system_type *get_fs_type(const char *name);
 extern struct super_block *get_super(struct block_device *);
 extern struct super_block *get_super_cdev(struct cdev *);
 extern struct super_block *get_super_thawed(struct block_device *);
+extern struct super_block *get_super_cdev_thawed(struct cdev *);
 extern struct super_block *get_active_super(struct block_device *bdev);
 extern void drop_super(struct super_block *sb);
 extern void iterate_supers(void (*)(struct super_block *, void *), void *);
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 06/39] fs: super: introduce a get_super_cdev_thawed to get sb by cdev reference
@ 2015-09-15  9:02   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

This patch refactors the original get_super_thawed to get a common
helper function of __get_super_thawed. Then take the use of
__get_super_thawed, we can implement get_super_cdev_thawed easily.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/super.c         | 29 +++++++++++++++++++++++++----
 include/linux/fs.h |  1 +
 2 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/fs/super.c b/fs/super.c
index 321d16b..df32393 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -629,18 +629,20 @@ struct super_block *get_super_cdev(struct cdev *cdev)
 EXPORT_SYMBOL(get_super_cdev);
 
 /**
- * get_super_thawed - get thawed superblock of a device
- * @bdev: device to get the superblock for
+ * __get_super_thawed - get thawed superblock
+ * @func: function pointer to get superblock by key
+ * @key: key to find superblock
  *
  * Scans the superblock list and finds the superblock of the file system
  * mounted on the device. The superblock is returned once it is thawed
  * (or immediately if it was not frozen). %NULL is returned if no match
  * is found.
  */
-struct super_block *get_super_thawed(struct block_device *bdev)
+static struct super_block *__get_super_thawed(
+		int (*compare)(struct super_block *, void *), void *key)
 {
 	while (1) {
-		struct super_block *s = get_super(bdev);
+		struct super_block *s = __get_super(compare, key);
 		if (!s || s->s_writers.frozen == SB_UNFROZEN)
 			return s;
 		up_read(&s->s_umount);
@@ -649,9 +651,28 @@ struct super_block *get_super_thawed(struct block_device *bdev)
 		put_super(s);
 	}
 }
+
+/**
+ * get_super_thawed - get thawed superblock of a device
+ * @bdev: device to get the superblock for
+ */
+struct super_block *get_super_thawed(struct block_device *bdev)
+{
+	return __get_super_thawed(bdev_compare, bdev);
+}
 EXPORT_SYMBOL(get_super_thawed);
 
 /**
+ * get_super_cdev_thawed - get thawed superblock of a char device
+ * @cdev: device to get the superblock for
+ */
+struct super_block *get_super_cdev_thawed(struct cdev *cdev)
+{
+	return __get_super_thawed(cdev_compare, cdev);
+}
+EXPORT_SYMBOL(get_super_cdev_thawed);
+
+/**
  * get_active_super - get an active reference to the superblock of a device
  * @bdev: device to get the superblock for
  *
diff --git a/include/linux/fs.h b/include/linux/fs.h
index df71cbb..2c1c122 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2798,6 +2798,7 @@ extern struct file_system_type *get_fs_type(const char *name);
 extern struct super_block *get_super(struct block_device *);
 extern struct super_block *get_super_cdev(struct cdev *);
 extern struct super_block *get_super_thawed(struct block_device *);
+extern struct super_block *get_super_cdev_thawed(struct cdev *);
 extern struct super_block *get_active_super(struct block_device *bdev);
 extern void drop_super(struct super_block *sb);
 extern void iterate_supers(void (*)(struct super_block *, void *), void *);
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 07/39] fs: char_dev: introduce cd_acquire function to acquire cdev
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:02   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

cd_acquire() works like bd_acquire() to get cdev by an inode,
this commit is a preparation for lookup_cdev().

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/char_dev.c | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/fs/char_dev.c b/fs/char_dev.c
index ea06a3d..e818faa 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -439,6 +439,41 @@ static int exact_lock(dev_t dev, void *data)
 	return cdev_get(p) ? 0 : -1;
 }
 
+struct cdev *cd_acquire(struct inode *inode)
+{
+	struct cdev *cdev;
+	struct cdev *new = NULL;
+
+	spin_lock(&cdev_lock);
+	cdev = inode->i_cdev;
+	if (!cdev) {
+		struct kobject *kobj;
+		int idx;
+		spin_unlock(&cdev_lock);
+		kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx);
+		if (!kobj) {
+			cdev = NULL;
+			goto out;
+		}
+		new = container_of(kobj, struct cdev, kobj);
+		spin_lock(&cdev_lock);
+		/* Check i_cdev again in case somebody beat us to it while
+		   we dropped the lock. */
+		cdev = inode->i_cdev;
+		if (!cdev) {
+			inode->i_cdev = cdev = new;
+			list_add(&inode->i_devices, &cdev->list);
+		}
+	}
+
+	if (!cdev_get(cdev))
+		cdev = NULL;
+	spin_unlock(&cdev_lock);
+
+out:
+	return cdev;
+}
+
 /**
  * cdev_add() - add a char device to the system
  * @p: the cdev structure for the device
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 07/39] fs: char_dev: introduce cd_acquire function to acquire cdev
@ 2015-09-15  9:02   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

cd_acquire() works like bd_acquire() to get cdev by an inode,
this commit is a preparation for lookup_cdev().

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/char_dev.c | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/fs/char_dev.c b/fs/char_dev.c
index ea06a3d..e818faa 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -439,6 +439,41 @@ static int exact_lock(dev_t dev, void *data)
 	return cdev_get(p) ? 0 : -1;
 }
 
+struct cdev *cd_acquire(struct inode *inode)
+{
+	struct cdev *cdev;
+	struct cdev *new = NULL;
+
+	spin_lock(&cdev_lock);
+	cdev = inode->i_cdev;
+	if (!cdev) {
+		struct kobject *kobj;
+		int idx;
+		spin_unlock(&cdev_lock);
+		kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx);
+		if (!kobj) {
+			cdev = NULL;
+			goto out;
+		}
+		new = container_of(kobj, struct cdev, kobj);
+		spin_lock(&cdev_lock);
+		/* Check i_cdev again in case somebody beat us to it while
+		   we dropped the lock. */
+		cdev = inode->i_cdev;
+		if (!cdev) {
+			inode->i_cdev = cdev = new;
+			list_add(&inode->i_devices, &cdev->list);
+		}
+	}
+
+	if (!cdev_get(cdev))
+		cdev = NULL;
+	spin_unlock(&cdev_lock);
+
+out:
+	return cdev;
+}
+
 /**
  * cdev_add() - add a char device to the system
  * @p: the cdev structure for the device
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 08/39] fs: introduce a __lookup_dev for internal using
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:02   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

This commit introduce a file of fs/dev.c at first. This is
a internal file shared by block_dev and char_dev. There is
only one function in it __lookup_dev which will be wrapped
to be lookup_bdev and loopup_cdev.

We will put more code in this file which is shared by
block_dev and char_dev.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
Reviewed-by: Jan Kara <jack@suse.com>
---
 fs/Makefile    |  2 +-
 fs/block_dev.c | 26 ++------------------
 fs/dev.c       | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/internal.h  | 14 +++++++++++
 4 files changed, 94 insertions(+), 25 deletions(-)
 create mode 100644 fs/dev.c

diff --git a/fs/Makefile b/fs/Makefile
index cb20e4b..87756f0 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -5,7 +5,7 @@
 # Rewritten to use lists instead of if-statements.
 # 
 
-obj-y :=	open.o read_write.o file_table.o super.o \
+obj-y :=	open.o read_write.o file_table.o super.o dev.o\
 		char_dev.o stat.o exec.o pipe.o namei.o fcntl.o \
 		ioctl.o readdir.o select.o dcache.o inode.o \
 		attr.o bad_inode.o file.o filesystems.o namespace.o \
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 1982437..05cf2ea 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -665,7 +665,7 @@ void bdput(struct block_device *bdev)
 
 EXPORT_SYMBOL(bdput);
  
-static struct block_device *bd_acquire(struct inode *inode)
+struct block_device *bd_acquire(struct inode *inode)
 {
 	struct block_device *bdev;
 
@@ -1713,34 +1713,12 @@ EXPORT_SYMBOL(ioctl_by_bdev);
 struct block_device *lookup_bdev(const char *pathname)
 {
 	struct block_device *bdev;
-	struct inode *inode;
-	struct path path;
 	int error;
 
-	if (!pathname || !*pathname)
-		return ERR_PTR(-EINVAL);
-
-	error = kern_path(pathname, LOOKUP_FOLLOW, &path);
+	error = __lookup_dev(pathname, NULL, &bdev);
 	if (error)
 		return ERR_PTR(error);
-
-	inode = d_backing_inode(path.dentry);
-	error = -ENOTBLK;
-	if (!S_ISBLK(inode->i_mode))
-		goto fail;
-	error = -EACCES;
-	if (path.mnt->mnt_flags & MNT_NODEV)
-		goto fail;
-	error = -ENOMEM;
-	bdev = bd_acquire(inode);
-	if (!bdev)
-		goto fail;
-out:
-	path_put(&path);
 	return bdev;
-fail:
-	bdev = ERR_PTR(error);
-	goto out;
 }
 EXPORT_SYMBOL(lookup_bdev);
 
diff --git a/fs/dev.c b/fs/dev.c
new file mode 100644
index 0000000..5356a47
--- /dev/null
+++ b/fs/dev.c
@@ -0,0 +1,77 @@
+/*
+ * This file contains some functions shared by block_dev and char_dev
+ */
+#include <linux/fs.h>
+#include <linux/namei.h>
+#include <linux/mount.h>
+
+#include "internal.h"
+
+/**
+ * __lookup_dev  - lookup a block_device or cdev by name
+ * @pathname:	special file representing the device
+ * @cdevp:	cdev would be returned by cdevp
+ * @bdevp:	block_device would be returned by bdevp
+ *
+ * Get a reference to the block_deivce or cdev at @pathname in
+ * the current namespace if possible and return it.
+ */
+int __lookup_dev(const char *pathname, struct cdev **cdevp,
+	       struct block_device **bdevp)
+{
+	struct inode *inode;
+	struct path path;
+	int error = 0;
+
+	if (!pathname || !*pathname)
+		return -EINVAL;
+
+	error = kern_path(pathname, LOOKUP_FOLLOW, &path);
+	if (error)
+		return error;
+
+	inode = d_backing_inode(path.dentry);
+
+	/**
+	 * We need at least one of bdevp and cdevp to be NULL,
+	 * but cdevp and bdevp can not be both NULL.
+	 */
+	error = -EINVAL;
+	if (!(cdevp || bdevp) || (cdevp && bdevp))
+		goto out;
+
+	if (cdevp) {
+		if (!S_ISCHR(inode->i_mode)) {
+			error = -EINVAL;
+			goto out;
+		}
+	} else {
+		if (!S_ISBLK(inode->i_mode)) {
+			error = -ENOTBLK;
+			goto out;
+		}
+	}
+	error = -EACCES;
+	if (path.mnt->mnt_flags & MNT_NODEV)
+		goto out;
+	error = -ENXIO;
+	if (S_ISCHR(inode->i_mode)) {
+		struct cdev *cdev;
+
+		cdev = cd_acquire(inode);
+		if (!cdev)
+			goto out;
+		*cdevp = cdev;
+	} else {
+		struct block_device *bdev;
+
+		bdev = bd_acquire(inode);
+		if (!bdev)
+			goto out;
+		*bdevp = bdev;
+	}
+	error = 0;
+out:
+	path_put(&path);
+	return error;
+}
diff --git a/fs/internal.h b/fs/internal.h
index 4d5af58..337b29c 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -17,6 +17,12 @@ struct mount;
 struct shrink_control;
 
 /*
+ * dev.c
+ */
+extern int __lookup_dev(const char *pathname, struct cdev **cdevp,
+			struct block_device **bdevp);
+
+/*
  * block_dev.c
  */
 #ifdef CONFIG_BLOCK
@@ -24,6 +30,8 @@ extern void __init bdev_cache_init(void);
 
 extern int __sync_blockdev(struct block_device *bdev, int wait);
 
+extern struct block_device *bd_acquire(struct inode *inode);
+
 #else
 static inline void bdev_cache_init(void)
 {
@@ -33,6 +41,11 @@ static inline int __sync_blockdev(struct block_device *bdev, int wait)
 {
 	return 0;
 }
+
+static struct block_device *bd_acquire(struct inode *inode)
+{
+	return NULL;
+}
 #endif
 
 /*
@@ -44,6 +57,7 @@ extern void guard_bio_eod(int rw, struct bio *bio);
  * char_dev.c
  */
 extern void __init chrdev_init(void);
+extern struct cdev *cd_acquire(struct inode *inode);
 
 /*
  * namei.c
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 08/39] fs: introduce a __lookup_dev for internal using
@ 2015-09-15  9:02   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

This commit introduce a file of fs/dev.c at first. This is
a internal file shared by block_dev and char_dev. There is
only one function in it __lookup_dev which will be wrapped
to be lookup_bdev and loopup_cdev.

We will put more code in this file which is shared by
block_dev and char_dev.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
Reviewed-by: Jan Kara <jack@suse.com>
---
 fs/Makefile    |  2 +-
 fs/block_dev.c | 26 ++------------------
 fs/dev.c       | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/internal.h  | 14 +++++++++++
 4 files changed, 94 insertions(+), 25 deletions(-)
 create mode 100644 fs/dev.c

diff --git a/fs/Makefile b/fs/Makefile
index cb20e4b..87756f0 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -5,7 +5,7 @@
 # Rewritten to use lists instead of if-statements.
 # 
 
-obj-y :=	open.o read_write.o file_table.o super.o \
+obj-y :=	open.o read_write.o file_table.o super.o dev.o\
 		char_dev.o stat.o exec.o pipe.o namei.o fcntl.o \
 		ioctl.o readdir.o select.o dcache.o inode.o \
 		attr.o bad_inode.o file.o filesystems.o namespace.o \
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 1982437..05cf2ea 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -665,7 +665,7 @@ void bdput(struct block_device *bdev)
 
 EXPORT_SYMBOL(bdput);
  
-static struct block_device *bd_acquire(struct inode *inode)
+struct block_device *bd_acquire(struct inode *inode)
 {
 	struct block_device *bdev;
 
@@ -1713,34 +1713,12 @@ EXPORT_SYMBOL(ioctl_by_bdev);
 struct block_device *lookup_bdev(const char *pathname)
 {
 	struct block_device *bdev;
-	struct inode *inode;
-	struct path path;
 	int error;
 
-	if (!pathname || !*pathname)
-		return ERR_PTR(-EINVAL);
-
-	error = kern_path(pathname, LOOKUP_FOLLOW, &path);
+	error = __lookup_dev(pathname, NULL, &bdev);
 	if (error)
 		return ERR_PTR(error);
-
-	inode = d_backing_inode(path.dentry);
-	error = -ENOTBLK;
-	if (!S_ISBLK(inode->i_mode))
-		goto fail;
-	error = -EACCES;
-	if (path.mnt->mnt_flags & MNT_NODEV)
-		goto fail;
-	error = -ENOMEM;
-	bdev = bd_acquire(inode);
-	if (!bdev)
-		goto fail;
-out:
-	path_put(&path);
 	return bdev;
-fail:
-	bdev = ERR_PTR(error);
-	goto out;
 }
 EXPORT_SYMBOL(lookup_bdev);
 
diff --git a/fs/dev.c b/fs/dev.c
new file mode 100644
index 0000000..5356a47
--- /dev/null
+++ b/fs/dev.c
@@ -0,0 +1,77 @@
+/*
+ * This file contains some functions shared by block_dev and char_dev
+ */
+#include <linux/fs.h>
+#include <linux/namei.h>
+#include <linux/mount.h>
+
+#include "internal.h"
+
+/**
+ * __lookup_dev  - lookup a block_device or cdev by name
+ * @pathname:	special file representing the device
+ * @cdevp:	cdev would be returned by cdevp
+ * @bdevp:	block_device would be returned by bdevp
+ *
+ * Get a reference to the block_deivce or cdev at @pathname in
+ * the current namespace if possible and return it.
+ */
+int __lookup_dev(const char *pathname, struct cdev **cdevp,
+	       struct block_device **bdevp)
+{
+	struct inode *inode;
+	struct path path;
+	int error = 0;
+
+	if (!pathname || !*pathname)
+		return -EINVAL;
+
+	error = kern_path(pathname, LOOKUP_FOLLOW, &path);
+	if (error)
+		return error;
+
+	inode = d_backing_inode(path.dentry);
+
+	/**
+	 * We need at least one of bdevp and cdevp to be NULL,
+	 * but cdevp and bdevp can not be both NULL.
+	 */
+	error = -EINVAL;
+	if (!(cdevp || bdevp) || (cdevp && bdevp))
+		goto out;
+
+	if (cdevp) {
+		if (!S_ISCHR(inode->i_mode)) {
+			error = -EINVAL;
+			goto out;
+		}
+	} else {
+		if (!S_ISBLK(inode->i_mode)) {
+			error = -ENOTBLK;
+			goto out;
+		}
+	}
+	error = -EACCES;
+	if (path.mnt->mnt_flags & MNT_NODEV)
+		goto out;
+	error = -ENXIO;
+	if (S_ISCHR(inode->i_mode)) {
+		struct cdev *cdev;
+
+		cdev = cd_acquire(inode);
+		if (!cdev)
+			goto out;
+		*cdevp = cdev;
+	} else {
+		struct block_device *bdev;
+
+		bdev = bd_acquire(inode);
+		if (!bdev)
+			goto out;
+		*bdevp = bdev;
+	}
+	error = 0;
+out:
+	path_put(&path);
+	return error;
+}
diff --git a/fs/internal.h b/fs/internal.h
index 4d5af58..337b29c 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -17,6 +17,12 @@ struct mount;
 struct shrink_control;
 
 /*
+ * dev.c
+ */
+extern int __lookup_dev(const char *pathname, struct cdev **cdevp,
+			struct block_device **bdevp);
+
+/*
  * block_dev.c
  */
 #ifdef CONFIG_BLOCK
@@ -24,6 +30,8 @@ extern void __init bdev_cache_init(void);
 
 extern int __sync_blockdev(struct block_device *bdev, int wait);
 
+extern struct block_device *bd_acquire(struct inode *inode);
+
 #else
 static inline void bdev_cache_init(void)
 {
@@ -33,6 +41,11 @@ static inline int __sync_blockdev(struct block_device *bdev, int wait)
 {
 	return 0;
 }
+
+static struct block_device *bd_acquire(struct inode *inode)
+{
+	return NULL;
+}
 #endif
 
 /*
@@ -44,6 +57,7 @@ extern void guard_bio_eod(int rw, struct bio *bio);
  * char_dev.c
  */
 extern void __init chrdev_init(void);
+extern struct cdev *cd_acquire(struct inode *inode);
 
 /*
  * namei.c
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 09/39] fs: char_dev: introduce lookup_cdev to get cdev by pathname
  2015-09-15  9:01 ` Dongsheng Yang
                   ` (8 preceding siblings ...)
  (?)
@ 2015-09-15  9:02 ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

Function lookup_cdev works similarly with lookup_bdev, we can get
a cdev instance by lookup_cdev with a parameter of dev name.

This function will be used in quotactl to get a cdev by a dev name.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
Reviewed-by: Jan Kara <jack@suse.com>
---
 fs/char_dev.c      | 13 +++++++++++++
 include/linux/fs.h |  2 ++
 2 files changed, 15 insertions(+)

diff --git a/fs/char_dev.c b/fs/char_dev.c
index e818faa..12c1bd5 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -474,6 +474,18 @@ out:
 	return cdev;
 }
 
+struct cdev *lookup_cdev(const char *pathname)
+{
+	struct cdev *cdev;
+	int error;
+
+	error = __lookup_dev(pathname, &cdev, NULL);
+	if (error)
+		return ERR_PTR(error);
+
+	return cdev;
+}
+
 /**
  * cdev_add() - add a char device to the system
  * @p: the cdev structure for the device
@@ -596,6 +608,7 @@ void __init chrdev_init(void)
 EXPORT_SYMBOL(register_chrdev_region);
 EXPORT_SYMBOL(unregister_chrdev_region);
 EXPORT_SYMBOL(alloc_chrdev_region);
+EXPORT_SYMBOL(lookup_cdev);
 EXPORT_SYMBOL(cdev_init);
 EXPORT_SYMBOL(cdev_alloc);
 EXPORT_SYMBOL(cdev_del);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 2c1c122..6f0c614 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2346,6 +2346,8 @@ extern void __unregister_chrdev(unsigned int major, unsigned int baseminor,
 				unsigned int count, const char *name);
 extern void unregister_chrdev_region(dev_t, unsigned);
 extern void chrdev_show(struct seq_file *,off_t);
+extern struct cdev *lookup_cdev(const char *);
+
 
 static inline int register_chrdev(unsigned int major, const char *name,
 				  const struct file_operations *fops)
-- 
1.8.4.2


^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 10/39] fs: dquot: skip invalidate_bdev if bdev is NULL
  2015-09-15  9:01 ` Dongsheng Yang
                   ` (9 preceding siblings ...)
  (?)
@ 2015-09-15  9:02 ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

There would be a NULL pointer dereference if bdev is NULL

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
Reviewed-by: Jan Kara <jack@suse.com>
---
 fs/quota/dquot.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 20d1f74..140397a 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -2208,7 +2208,8 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
 		 * of the cache could fail because of other unrelated dirty
 		 * data */
 		sync_filesystem(sb);
-		invalidate_bdev(sb->s_bdev);
+		if (sb->s_bdev)
+			invalidate_bdev(sb->s_bdev);
 	}
 	mutex_lock(&dqopt->dqonoff_mutex);
 	if (sb_has_quota_loaded(sb, type)) {
-- 
1.8.4.2


^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 11/39] fs: quota: replace opened calling of ->sync_fs with sync_filesystem
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:02   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

There are only two places in whole kernel to call ->sync_fs directly. It
will sync fs even in read-only mode. It's not a good idea and some filesystem
would warn out if you are syncing in read-only mode. But sync_filesystem()
does filter this case out. Let's call sync_filesystem() here instead.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/quota/dquot.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 140397a..0bda7fa 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -668,8 +668,7 @@ int dquot_quota_sync(struct super_block *sb, int type)
 	/* This is not very clever (and fast) but currently I don't know about
 	 * any other simple way of getting quota data to disk and we must get
 	 * them there for userspace to be visible... */
-	if (sb->s_op->sync_fs)
-		sb->s_op->sync_fs(sb, 1);
+	sync_filesystem(sb);
 	sync_blockdev(sb->s_bdev);
 
 	/*
@@ -2043,7 +2042,7 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
 	/*
 	 * Skip everything if there's nothing to do. We have to do this because
 	 * sometimes we are called when fill_super() failed and calling
-	 * sync_fs() in such cases does no good.
+	 * sync_filesystem() in such cases does no good.
 	 */
 	if (!sb_any_quota_loaded(sb)) {
 		mutex_unlock(&dqopt->dqonoff_mutex);
@@ -2110,8 +2109,7 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
 
 	/* Sync the superblock so that buffers with quota data are written to
 	 * disk (and so userspace sees correct data afterwards). */
-	if (sb->s_op->sync_fs)
-		sb->s_op->sync_fs(sb, 1);
+	sync_filesystem(sb);
 	sync_blockdev(sb->s_bdev);
 	/* Now the quota files are just ordinary files and we can set the
 	 * inode flags back. Moreover we discard the pagecache so that
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 11/39] fs: quota: replace opened calling of ->sync_fs with sync_filesystem
@ 2015-09-15  9:02   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

There are only two places in whole kernel to call ->sync_fs directly. It
will sync fs even in read-only mode. It's not a good idea and some filesystem
would warn out if you are syncing in read-only mode. But sync_filesystem()
does filter this case out. Let's call sync_filesystem() here instead.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/quota/dquot.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 140397a..0bda7fa 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -668,8 +668,7 @@ int dquot_quota_sync(struct super_block *sb, int type)
 	/* This is not very clever (and fast) but currently I don't know about
 	 * any other simple way of getting quota data to disk and we must get
 	 * them there for userspace to be visible... */
-	if (sb->s_op->sync_fs)
-		sb->s_op->sync_fs(sb, 1);
+	sync_filesystem(sb);
 	sync_blockdev(sb->s_bdev);
 
 	/*
@@ -2043,7 +2042,7 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
 	/*
 	 * Skip everything if there's nothing to do. We have to do this because
 	 * sometimes we are called when fill_super() failed and calling
-	 * sync_fs() in such cases does no good.
+	 * sync_filesystem() in such cases does no good.
 	 */
 	if (!sb_any_quota_loaded(sb)) {
 		mutex_unlock(&dqopt->dqonoff_mutex);
@@ -2110,8 +2109,7 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
 
 	/* Sync the superblock so that buffers with quota data are written to
 	 * disk (and so userspace sees correct data afterwards). */
-	if (sb->s_op->sync_fs)
-		sb->s_op->sync_fs(sb, 1);
+	sync_filesystem(sb);
 	sync_blockdev(sb->s_bdev);
 	/* Now the quota files are just ordinary files and we can set the
 	 * inode flags back. Moreover we discard the pagecache so that
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 12/39] fs: quota: make quota support fs which is running on char dev
  2015-09-15  9:01 ` Dongsheng Yang
                   ` (11 preceding siblings ...)
  (?)
@ 2015-09-15  9:02 ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

So far, we have done all preparation. Then let's add some
code to support char dev fs in quotactl.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/quota/quota.c | 30 +++++++++++++++++++++---------
 1 file changed, 21 insertions(+), 9 deletions(-)

diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index 86ded73..3f9acea 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -17,6 +17,7 @@
 #include <linux/quotaops.h>
 #include <linux/types.h>
 #include <linux/writeback.h>
+#include <linux/cdev.h>
 
 static int check_quotactl_permission(struct super_block *sb, int type, int cmd,
 				     qid_t id)
@@ -726,29 +727,40 @@ static int quotactl_cmd_write(int cmd)
  */
 static struct super_block *quotactl_block(const char __user *special, int cmd)
 {
+	struct super_block *sb = NULL;
+	struct filename *tmp = getname(special);
+	struct cdev *cdev = NULL;
+
 #ifdef CONFIG_BLOCK
 	struct block_device *bdev;
-	struct super_block *sb;
-	struct filename *tmp = getname(special);
 
 	if (IS_ERR(tmp))
 		return ERR_CAST(tmp);
 	bdev = lookup_bdev(tmp->name);
-	putname(tmp);
 	if (IS_ERR(bdev))
-		return ERR_CAST(bdev);
+		goto not_block;
 	if (quotactl_cmd_write(cmd))
 		sb = get_super_thawed(bdev);
 	else
 		sb = get_super(bdev);
 	bdput(bdev);
-	if (!sb)
-		return ERR_PTR(-ENODEV);
+	goto out;
 
-	return sb;
-#else
-	return ERR_PTR(-ENODEV);
+not_block:
 #endif
+	cdev = lookup_cdev(tmp->name);
+	if (IS_ERR(cdev))
+		goto out;
+	if (quotactl_cmd_write(cmd))
+		sb = get_super_cdev_thawed(cdev);
+	else
+		sb = get_super_cdev(cdev);
+	cdev_put(cdev);
+out:
+	putname(tmp);
+	if (sb)
+		return sb;
+	return ERR_PTR(-ENODEV);
 }
 
 /*
-- 
1.8.4.2


^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 13/39] fs: introduce a get_qsize() to inode_operations
  2015-09-15  9:01 ` Dongsheng Yang
                   ` (12 preceding siblings ...)
  (?)
@ 2015-09-15  9:02 ` Dongsheng Yang
  2015-10-04  6:33   ` Christoph Hellwig
  -1 siblings, 1 reply; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

get_qsize() is used to allow inode to decide how much of the quota size
in itself. If file system implements the own get_qsize(), ioctl of
FIOQSIZe will call it to get quota size. If not implemented, get the
quota size in a generic way.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ioctl.c         | 31 ++++++++++++++++++++++++-------
 include/linux/fs.h |  1 +
 2 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/fs/ioctl.c b/fs/ioctl.c
index 5d01d26..cc69560 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -545,6 +545,29 @@ static int ioctl_fsthaw(struct file *filp)
 	return thaw_super(sb);
 }
 
+static int ioctl_fioqsize(struct file *filp, int __user *argp)
+{
+	struct inode *inode = file_inode(filp);
+	loff_t res = 0;
+	int error = 0;
+
+	if (inode->i_op->get_qsize) {
+		res = inode->i_op->get_qsize(inode);
+		error = copy_to_user(argp, &res, sizeof(res)) ?
+				-EFAULT : 0;
+	} else {
+                if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode) ||
+                    S_ISLNK(inode->i_mode)) {
+                        res = inode_get_bytes(inode);
+                        error = copy_to_user(argp, &res, sizeof(res)) ?
+                                        -EFAULT : 0;
+                } else {
+                        error = -ENOTTY;
+		}
+	}
+	return error;
+}
+
 /*
  * When you add any new common ioctls to the switches above and below
  * please update compat_sys_ioctl() too.
@@ -577,13 +600,7 @@ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
 		break;
 
 	case FIOQSIZE:
-		if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode) ||
-		    S_ISLNK(inode->i_mode)) {
-			loff_t res = inode_get_bytes(inode);
-			error = copy_to_user(argp, &res, sizeof(res)) ?
-					-EFAULT : 0;
-		} else
-			error = -ENOTTY;
+		error = ioctl_fioqsize(filp, argp);
 		break;
 
 	case FIFREEZE:
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 6f0c614..6d183d5 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1669,6 +1669,7 @@ struct inode_operations {
 			   umode_t create_mode, int *opened);
 	int (*tmpfile) (struct inode *, struct dentry *, umode_t);
 	int (*set_acl)(struct inode *, struct posix_acl *, int);
+	ssize_t (*get_qsize) (struct inode *);
 
 	/* WARNING: probably going away soon, do not use! */
 } ____cacheline_aligned;
-- 
1.8.4.2


^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 14/39] fs: quota: restore i_flags of quota files in dquot_disable
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:02   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

When we load quota files, we set the i_flags of the inodes
to (S_NOQUOTA | S_NOATIME | S_IMMUTABLE). In dquot_disable()
we only clear these flags, But we do not restore the old
flags. That would change the i_flags of quota files if some
of these flags were set before loading quota files.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/quota/dquot.c      | 2 ++
 include/linux/quota.h | 1 +
 2 files changed, 3 insertions(+)

diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 0bda7fa..c73f44d 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -2125,6 +2125,7 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
 				mutex_lock(&toputinode[cnt]->i_mutex);
 				toputinode[cnt]->i_flags &= ~(S_IMMUTABLE |
 				  S_NOATIME | S_NOQUOTA);
+				toputinode[cnt]->i_flags |= dqopt->old_flags[cnt];
 				truncate_inode_pages(&toputinode[cnt]->i_data,
 						     0);
 				mutex_unlock(&toputinode[cnt]->i_mutex);
@@ -2223,6 +2224,7 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
 		oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE |
 					     S_NOQUOTA);
 		inode->i_flags |= S_NOQUOTA | S_NOATIME | S_IMMUTABLE;
+		dqopt->old_flags[type] = oldflags;
 		mutex_unlock(&inode->i_mutex);
 		/*
 		 * When S_NOQUOTA is set, remove dquot references as no more
diff --git a/include/linux/quota.h b/include/linux/quota.h
index b2505ac..fcfee5a 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -507,6 +507,7 @@ struct quota_info {
 	struct mutex dqio_mutex;		/* lock device while I/O in progress */
 	struct mutex dqonoff_mutex;		/* Serialize quotaon & quotaoff */
 	struct inode *files[MAXQUOTAS];		/* inodes of quotafiles */
+	unsigned int old_flags[MAXQUOTAS];	/* i_flags for each quota file */
 	struct mem_dqinfo info[MAXQUOTAS];	/* Information for each quota type */
 	const struct quota_format_ops *ops[MAXQUOTAS];	/* Operations for each type */
 };
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 14/39] fs: quota: restore i_flags of quota files in dquot_disable
@ 2015-09-15  9:02   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

When we load quota files, we set the i_flags of the inodes
to (S_NOQUOTA | S_NOATIME | S_IMMUTABLE). In dquot_disable()
we only clear these flags, But we do not restore the old
flags. That would change the i_flags of quota files if some
of these flags were set before loading quota files.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/quota/dquot.c      | 2 ++
 include/linux/quota.h | 1 +
 2 files changed, 3 insertions(+)

diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 0bda7fa..c73f44d 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -2125,6 +2125,7 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
 				mutex_lock(&toputinode[cnt]->i_mutex);
 				toputinode[cnt]->i_flags &= ~(S_IMMUTABLE |
 				  S_NOATIME | S_NOQUOTA);
+				toputinode[cnt]->i_flags |= dqopt->old_flags[cnt];
 				truncate_inode_pages(&toputinode[cnt]->i_data,
 						     0);
 				mutex_unlock(&toputinode[cnt]->i_mutex);
@@ -2223,6 +2224,7 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
 		oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE |
 					     S_NOQUOTA);
 		inode->i_flags |= S_NOQUOTA | S_NOATIME | S_IMMUTABLE;
+		dqopt->old_flags[type] = oldflags;
 		mutex_unlock(&inode->i_mutex);
 		/*
 		 * When S_NOQUOTA is set, remove dquot references as no more
diff --git a/include/linux/quota.h b/include/linux/quota.h
index b2505ac..fcfee5a 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -507,6 +507,7 @@ struct quota_info {
 	struct mutex dqio_mutex;		/* lock device while I/O in progress */
 	struct mutex dqonoff_mutex;		/* Serialize quotaon & quotaoff */
 	struct inode *files[MAXQUOTAS];		/* inodes of quotafiles */
+	unsigned int old_flags[MAXQUOTAS];	/* i_flags for each quota file */
 	struct mem_dqinfo info[MAXQUOTAS];	/* Information for each quota type */
 	const struct quota_format_ops *ops[MAXQUOTAS];	/* Operations for each type */
 };
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 15/39] fs: quota: introduce a callback of restore_iflags to quotactl_ops
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:02   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

In dquot_disable, we need to restore the iflags of quota files
and mark the inodes to dirty. But that's pain to file-systems
working in out-place-updating way, such as btrfs and ubifs. when
they are going to update inode, they have to reserve space for
this inode.

So we can not mark_inode_dirty() in dquot_disable for them. To solve
this kind of problem, the common solution is introduce a callback
to allow file-systems to do the inode_dirty work by themselves,
the similar way with update_time().

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/quota/dquot.c      | 51 ++++++++++++++++++++++++++++++++++-----------------
 include/linux/quota.h |  4 ++++
 2 files changed, 38 insertions(+), 17 deletions(-)

diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index c73f44d..3f08e69 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -2020,6 +2020,33 @@ int dquot_file_open(struct inode *inode, struct file *file)
 }
 EXPORT_SYMBOL(dquot_file_open);
 
+static int generic_restore_iflags(struct super_block *sb, struct inode **toputinode,
+					unsigned int *old_flags)
+{
+	int cnt = 0;
+	struct quota_info *dqopt = sb_dqopt(sb);
+
+	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
+		if (toputinode[cnt]) {
+			mutex_lock(&dqopt->dqonoff_mutex);
+			/* If quota was reenabled in the meantime, we have
+			 * nothing to do */
+			if (!sb_has_quota_loaded(sb, cnt)) {
+				mutex_lock(&toputinode[cnt]->i_mutex);
+				toputinode[cnt]->i_flags &= ~(S_IMMUTABLE |
+				  S_NOATIME | S_NOQUOTA);
+				toputinode[cnt]->i_flags |= old_flags[cnt];
+				truncate_inode_pages(&toputinode[cnt]->i_data,
+						     0);
+				mutex_unlock(&toputinode[cnt]->i_mutex);
+				mark_inode_dirty_sync(toputinode[cnt]);
+			}
+			mutex_unlock(&dqopt->dqonoff_mutex);
+		}
+
+	return 0;
+}
+
 /*
  * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount)
  */
@@ -2028,6 +2055,7 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
 	int cnt, ret = 0;
 	struct quota_info *dqopt = sb_dqopt(sb);
 	struct inode *toputinode[MAXQUOTAS];
+	unsigned int *old_flags = dqopt->old_flags;
 
 	/* Cannot turn off usage accounting without turning off limits, or
 	 * suspend quotas and simultaneously turn quotas off. */
@@ -2111,28 +2139,17 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
 	 * disk (and so userspace sees correct data afterwards). */
 	sync_filesystem(sb);
 	sync_blockdev(sb->s_bdev);
+
 	/* Now the quota files are just ordinary files and we can set the
 	 * inode flags back. Moreover we discard the pagecache so that
 	 * userspace sees the writes we did bypassing the pagecache. We
 	 * must also discard the blockdev buffers so that we see the
 	 * changes done by userspace on the next quotaon() */
-	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
-		if (toputinode[cnt]) {
-			mutex_lock(&dqopt->dqonoff_mutex);
-			/* If quota was reenabled in the meantime, we have
-			 * nothing to do */
-			if (!sb_has_quota_loaded(sb, cnt)) {
-				mutex_lock(&toputinode[cnt]->i_mutex);
-				toputinode[cnt]->i_flags &= ~(S_IMMUTABLE |
-				  S_NOATIME | S_NOQUOTA);
-				toputinode[cnt]->i_flags |= dqopt->old_flags[cnt];
-				truncate_inode_pages(&toputinode[cnt]->i_data,
-						     0);
-				mutex_unlock(&toputinode[cnt]->i_mutex);
-				mark_inode_dirty_sync(toputinode[cnt]);
-			}
-			mutex_unlock(&dqopt->dqonoff_mutex);
-		}
+	if (sb->s_qcop->restore_iflags)
+		ret = sb->s_qcop->restore_iflags(sb, toputinode, old_flags);
+	else
+		ret = generic_restore_iflags(sb, toputinode, old_flags);
+
 	if (sb->s_bdev)
 		invalidate_bdev(sb->s_bdev);
 put_inodes:
diff --git a/include/linux/quota.h b/include/linux/quota.h
index fcfee5a..64e52e4 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -428,6 +428,10 @@ struct quotactl_ops {
 	int (*set_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *);
 	int (*get_state)(struct super_block *, struct qc_state *);
 	int (*rm_xquota)(struct super_block *, unsigned int);
+	/*
+	 * used in quota_disable to restore the i_flags of quota files.
+	 */
+	int (*restore_iflags)(struct super_block *sb, struct inode **, unsigned int *);
 };
 
 struct quota_format_type {
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 15/39] fs: quota: introduce a callback of restore_iflags to quotactl_ops
@ 2015-09-15  9:02   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

In dquot_disable, we need to restore the iflags of quota files
and mark the inodes to dirty. But that's pain to file-systems
working in out-place-updating way, such as btrfs and ubifs. when
they are going to update inode, they have to reserve space for
this inode.

So we can not mark_inode_dirty() in dquot_disable for them. To solve
this kind of problem, the common solution is introduce a callback
to allow file-systems to do the inode_dirty work by themselves,
the similar way with update_time().

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/quota/dquot.c      | 51 ++++++++++++++++++++++++++++++++++-----------------
 include/linux/quota.h |  4 ++++
 2 files changed, 38 insertions(+), 17 deletions(-)

diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index c73f44d..3f08e69 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -2020,6 +2020,33 @@ int dquot_file_open(struct inode *inode, struct file *file)
 }
 EXPORT_SYMBOL(dquot_file_open);
 
+static int generic_restore_iflags(struct super_block *sb, struct inode **toputinode,
+					unsigned int *old_flags)
+{
+	int cnt = 0;
+	struct quota_info *dqopt = sb_dqopt(sb);
+
+	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
+		if (toputinode[cnt]) {
+			mutex_lock(&dqopt->dqonoff_mutex);
+			/* If quota was reenabled in the meantime, we have
+			 * nothing to do */
+			if (!sb_has_quota_loaded(sb, cnt)) {
+				mutex_lock(&toputinode[cnt]->i_mutex);
+				toputinode[cnt]->i_flags &= ~(S_IMMUTABLE |
+				  S_NOATIME | S_NOQUOTA);
+				toputinode[cnt]->i_flags |= old_flags[cnt];
+				truncate_inode_pages(&toputinode[cnt]->i_data,
+						     0);
+				mutex_unlock(&toputinode[cnt]->i_mutex);
+				mark_inode_dirty_sync(toputinode[cnt]);
+			}
+			mutex_unlock(&dqopt->dqonoff_mutex);
+		}
+
+	return 0;
+}
+
 /*
  * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount)
  */
@@ -2028,6 +2055,7 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
 	int cnt, ret = 0;
 	struct quota_info *dqopt = sb_dqopt(sb);
 	struct inode *toputinode[MAXQUOTAS];
+	unsigned int *old_flags = dqopt->old_flags;
 
 	/* Cannot turn off usage accounting without turning off limits, or
 	 * suspend quotas and simultaneously turn quotas off. */
@@ -2111,28 +2139,17 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
 	 * disk (and so userspace sees correct data afterwards). */
 	sync_filesystem(sb);
 	sync_blockdev(sb->s_bdev);
+
 	/* Now the quota files are just ordinary files and we can set the
 	 * inode flags back. Moreover we discard the pagecache so that
 	 * userspace sees the writes we did bypassing the pagecache. We
 	 * must also discard the blockdev buffers so that we see the
 	 * changes done by userspace on the next quotaon() */
-	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
-		if (toputinode[cnt]) {
-			mutex_lock(&dqopt->dqonoff_mutex);
-			/* If quota was reenabled in the meantime, we have
-			 * nothing to do */
-			if (!sb_has_quota_loaded(sb, cnt)) {
-				mutex_lock(&toputinode[cnt]->i_mutex);
-				toputinode[cnt]->i_flags &= ~(S_IMMUTABLE |
-				  S_NOATIME | S_NOQUOTA);
-				toputinode[cnt]->i_flags |= dqopt->old_flags[cnt];
-				truncate_inode_pages(&toputinode[cnt]->i_data,
-						     0);
-				mutex_unlock(&toputinode[cnt]->i_mutex);
-				mark_inode_dirty_sync(toputinode[cnt]);
-			}
-			mutex_unlock(&dqopt->dqonoff_mutex);
-		}
+	if (sb->s_qcop->restore_iflags)
+		ret = sb->s_qcop->restore_iflags(sb, toputinode, old_flags);
+	else
+		ret = generic_restore_iflags(sb, toputinode, old_flags);
+
 	if (sb->s_bdev)
 		invalidate_bdev(sb->s_bdev);
 put_inodes:
diff --git a/include/linux/quota.h b/include/linux/quota.h
index fcfee5a..64e52e4 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -428,6 +428,10 @@ struct quotactl_ops {
 	int (*set_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *);
 	int (*get_state)(struct super_block *, struct qc_state *);
 	int (*rm_xquota)(struct super_block *, unsigned int);
+	/*
+	 * used in quota_disable to restore the i_flags of quota files.
+	 */
+	int (*restore_iflags)(struct super_block *sb, struct inode **, unsigned int *);
 };
 
 struct quota_format_type {
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 16/39] ubi: introduce a interface to get cdev in ubi_volume
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:02   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

We want to fill the sb->s_cdev in ubifs_fill_super(),
so, we need to add a interface in ubi to get the cdev
of an ubi_volume.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
Acked-by: Richard Weinberger <richard@nod.at>
---
 drivers/mtd/ubi/kapi.c  | 6 ++++++
 include/linux/mtd/ubi.h | 1 +
 2 files changed, 7 insertions(+)

diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c
index e844887..d3d1982 100644
--- a/drivers/mtd/ubi/kapi.c
+++ b/drivers/mtd/ubi/kapi.c
@@ -862,3 +862,9 @@ int ubi_unregister_volume_notifier(struct notifier_block *nb)
 	return blocking_notifier_chain_unregister(&ubi_notifiers, nb);
 }
 EXPORT_SYMBOL_GPL(ubi_unregister_volume_notifier);
+
+inline struct cdev *ubi_get_volume_cdev(struct ubi_volume_desc *desc)
+{
+	return &(desc->vol->cdev);
+}
+EXPORT_SYMBOL_GPL(ubi_get_volume_cdev);
diff --git a/include/linux/mtd/ubi.h b/include/linux/mtd/ubi.h
index 1e271cb..301c6e9 100644
--- a/include/linux/mtd/ubi.h
+++ b/include/linux/mtd/ubi.h
@@ -261,6 +261,7 @@ int ubi_leb_map(struct ubi_volume_desc *desc, int lnum);
 int ubi_is_mapped(struct ubi_volume_desc *desc, int lnum);
 int ubi_sync(int ubi_num);
 int ubi_flush(int ubi_num, int vol_id, int lnum);
+struct cdev *ubi_get_volume_cdev(struct ubi_volume_desc *desc);
 
 /*
  * This function is the same as the 'ubi_leb_read()' function, but it does not
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 16/39] ubi: introduce a interface to get cdev in ubi_volume
@ 2015-09-15  9:02   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

We want to fill the sb->s_cdev in ubifs_fill_super(),
so, we need to add a interface in ubi to get the cdev
of an ubi_volume.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
Acked-by: Richard Weinberger <richard@nod.at>
---
 drivers/mtd/ubi/kapi.c  | 6 ++++++
 include/linux/mtd/ubi.h | 1 +
 2 files changed, 7 insertions(+)

diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c
index e844887..d3d1982 100644
--- a/drivers/mtd/ubi/kapi.c
+++ b/drivers/mtd/ubi/kapi.c
@@ -862,3 +862,9 @@ int ubi_unregister_volume_notifier(struct notifier_block *nb)
 	return blocking_notifier_chain_unregister(&ubi_notifiers, nb);
 }
 EXPORT_SYMBOL_GPL(ubi_unregister_volume_notifier);
+
+inline struct cdev *ubi_get_volume_cdev(struct ubi_volume_desc *desc)
+{
+	return &(desc->vol->cdev);
+}
+EXPORT_SYMBOL_GPL(ubi_get_volume_cdev);
diff --git a/include/linux/mtd/ubi.h b/include/linux/mtd/ubi.h
index 1e271cb..301c6e9 100644
--- a/include/linux/mtd/ubi.h
+++ b/include/linux/mtd/ubi.h
@@ -261,6 +261,7 @@ int ubi_leb_map(struct ubi_volume_desc *desc, int lnum);
 int ubi_is_mapped(struct ubi_volume_desc *desc, int lnum);
 int ubi_sync(int ubi_num);
 int ubi_flush(int ubi_num, int vol_id, int lnum);
+struct cdev *ubi_get_volume_cdev(struct ubi_volume_desc *desc);
 
 /*
  * This function is the same as the 'ubi_leb_read()' function, but it does not
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 17/39] ubifs: extend budget for blocks
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:02   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

Currently, budget subsystem in ubifs are working on budgeting
page-by-page. But sometimes we want to budget a space for one
block, e.g for quota file writing. So this commit extend budget
subsystem to support blocks budgeting and releasing.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/budget.c | 4 ++++
 fs/ubifs/debug.c  | 2 ++
 fs/ubifs/super.c  | 1 +
 fs/ubifs/ubifs.h  | 7 +++++++
 4 files changed, 14 insertions(+)

diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c
index 11a11b3..ec2ac8e 100644
--- a/fs/ubifs/budget.c
+++ b/fs/ubifs/budget.c
@@ -395,6 +395,8 @@ static int calc_data_growth(const struct ubifs_info *c,
 	data_growth = req->new_ino  ? c->bi.inode_budget : 0;
 	if (req->new_page)
 		data_growth += c->bi.page_budget;
+	if (req->new_block)
+		data_growth += c->bi.block_budget;
 	if (req->new_dent)
 		data_growth += c->bi.dent_budget;
 	data_growth += req->new_ino_d;
@@ -414,6 +416,8 @@ static int calc_dd_growth(const struct ubifs_info *c,
 
 	dd_growth = req->dirtied_page ? c->bi.page_budget : 0;
 
+	if (req->dirtied_block)
+		dd_growth += c->bi.block_budget;
 	if (req->dirtied_ino)
 		dd_growth += c->bi.inode_budget << (req->dirtied_ino - 1);
 	if (req->mod_dent)
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 4c46a98..f393df2 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -556,6 +556,8 @@ void ubifs_dump_budget_req(const struct ubifs_budget_req *req)
 	       req->new_page, req->dirtied_page);
 	pr_err("\tnew_dent    %d, mod_dent     %d\n",
 	       req->new_dent, req->mod_dent);
+	pr_err("\tnew_block   %d, dirtied_block %d\n",
+	       req->new_block, req->dirtied_block);
 	pr_err("\tidx_growth  %d\n", req->idx_growth);
 	pr_err("\tdata_growth %d dd_growth     %d\n",
 	       req->data_growth, req->dd_growth);
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 8ee3133..dcffcd6 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -699,6 +699,7 @@ static int init_constants_sb(struct ubifs_info *c)
 	c->bi.page_budget = UBIFS_MAX_DATA_NODE_SZ * UBIFS_BLOCKS_PER_PAGE;
 	c->bi.inode_budget = UBIFS_INO_NODE_SZ;
 	c->bi.dent_budget = UBIFS_MAX_DENT_NODE_SZ;
+	c->bi.block_budget = UBIFS_MAX_DATA_NODE_SZ;
 
 	/*
 	 * When the amount of flash space used by buds becomes
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 3b5e932..5e1a5fe 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -854,6 +854,8 @@ struct ubifs_compressor {
  *               have to be re-calculated
  * @new_page: non-zero if the operation adds a new page
  * @dirtied_page: non-zero if the operation makes a page dirty
+ * @new_block: non-zero if the operation adds a new block
+ * @dirtied_block: non-zero if the operation makes a block dirty
  * @new_dent: non-zero if the operation adds a new directory entry
  * @mod_dent: non-zero if the operation removes or modifies an existing
  *            directory entry
@@ -885,6 +887,8 @@ struct ubifs_budget_req {
 #ifndef UBIFS_DEBUG
 	unsigned int new_page:1;
 	unsigned int dirtied_page:1;
+	unsigned int new_block:1;
+	unsigned int dirtied_block:1;
 	unsigned int new_dent:1;
 	unsigned int mod_dent:1;
 	unsigned int new_ino:1;
@@ -895,6 +899,8 @@ struct ubifs_budget_req {
 	/* Not bit-fields to check for overflows */
 	unsigned int new_page;
 	unsigned int dirtied_page;
+	unsigned int new_block;
+	unsigned int dirtied_block;
 	unsigned int new_dent;
 	unsigned int mod_dent;
 	unsigned int new_ino;
@@ -983,6 +989,7 @@ struct ubifs_budg_info {
 	int page_budget;
 	int inode_budget;
 	int dent_budget;
+	int block_budget;
 };
 
 struct ubifs_debug_info;
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 17/39] ubifs: extend budget for blocks
@ 2015-09-15  9:02   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

Currently, budget subsystem in ubifs are working on budgeting
page-by-page. But sometimes we want to budget a space for one
block, e.g for quota file writing. So this commit extend budget
subsystem to support blocks budgeting and releasing.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/budget.c | 4 ++++
 fs/ubifs/debug.c  | 2 ++
 fs/ubifs/super.c  | 1 +
 fs/ubifs/ubifs.h  | 7 +++++++
 4 files changed, 14 insertions(+)

diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c
index 11a11b3..ec2ac8e 100644
--- a/fs/ubifs/budget.c
+++ b/fs/ubifs/budget.c
@@ -395,6 +395,8 @@ static int calc_data_growth(const struct ubifs_info *c,
 	data_growth = req->new_ino  ? c->bi.inode_budget : 0;
 	if (req->new_page)
 		data_growth += c->bi.page_budget;
+	if (req->new_block)
+		data_growth += c->bi.block_budget;
 	if (req->new_dent)
 		data_growth += c->bi.dent_budget;
 	data_growth += req->new_ino_d;
@@ -414,6 +416,8 @@ static int calc_dd_growth(const struct ubifs_info *c,
 
 	dd_growth = req->dirtied_page ? c->bi.page_budget : 0;
 
+	if (req->dirtied_block)
+		dd_growth += c->bi.block_budget;
 	if (req->dirtied_ino)
 		dd_growth += c->bi.inode_budget << (req->dirtied_ino - 1);
 	if (req->mod_dent)
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 4c46a98..f393df2 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -556,6 +556,8 @@ void ubifs_dump_budget_req(const struct ubifs_budget_req *req)
 	       req->new_page, req->dirtied_page);
 	pr_err("\tnew_dent    %d, mod_dent     %d\n",
 	       req->new_dent, req->mod_dent);
+	pr_err("\tnew_block   %d, dirtied_block %d\n",
+	       req->new_block, req->dirtied_block);
 	pr_err("\tidx_growth  %d\n", req->idx_growth);
 	pr_err("\tdata_growth %d dd_growth     %d\n",
 	       req->data_growth, req->dd_growth);
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 8ee3133..dcffcd6 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -699,6 +699,7 @@ static int init_constants_sb(struct ubifs_info *c)
 	c->bi.page_budget = UBIFS_MAX_DATA_NODE_SZ * UBIFS_BLOCKS_PER_PAGE;
 	c->bi.inode_budget = UBIFS_INO_NODE_SZ;
 	c->bi.dent_budget = UBIFS_MAX_DENT_NODE_SZ;
+	c->bi.block_budget = UBIFS_MAX_DATA_NODE_SZ;
 
 	/*
 	 * When the amount of flash space used by buds becomes
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 3b5e932..5e1a5fe 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -854,6 +854,8 @@ struct ubifs_compressor {
  *               have to be re-calculated
  * @new_page: non-zero if the operation adds a new page
  * @dirtied_page: non-zero if the operation makes a page dirty
+ * @new_block: non-zero if the operation adds a new block
+ * @dirtied_block: non-zero if the operation makes a block dirty
  * @new_dent: non-zero if the operation adds a new directory entry
  * @mod_dent: non-zero if the operation removes or modifies an existing
  *            directory entry
@@ -885,6 +887,8 @@ struct ubifs_budget_req {
 #ifndef UBIFS_DEBUG
 	unsigned int new_page:1;
 	unsigned int dirtied_page:1;
+	unsigned int new_block:1;
+	unsigned int dirtied_block:1;
 	unsigned int new_dent:1;
 	unsigned int mod_dent:1;
 	unsigned int new_ino:1;
@@ -895,6 +899,8 @@ struct ubifs_budget_req {
 	/* Not bit-fields to check for overflows */
 	unsigned int new_page;
 	unsigned int dirtied_page;
+	unsigned int new_block;
+	unsigned int dirtied_block;
 	unsigned int new_dent;
 	unsigned int mod_dent;
 	unsigned int new_ino;
@@ -983,6 +989,7 @@ struct ubifs_budg_info {
 	int page_budget;
 	int inode_budget;
 	int dent_budget;
+	int block_budget;
 };
 
 struct ubifs_debug_info;
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 18/39] ubifs: fill sb->s_cdev in ubifs_fill_super()
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:02   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

We need to fill the sb->s_cdev to tell others, this sb
is for which ubi_volume. quotactl will use this connection
to find the super_block by the device.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
Reviewed-by: Richard Weinberger <richard@nod.at>
---
 fs/ubifs/super.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index dcffcd6..0e0428b 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -2033,6 +2033,7 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
 		goto out_bdi;
 
 	sb->s_bdi = &c->bdi;
+	sb->s_cdev = ubi_get_volume_cdev(c->ubi);
 	sb->s_fs_info = c;
 	sb->s_magic = UBIFS_SUPER_MAGIC;
 	sb->s_blocksize = UBIFS_BLOCK_SIZE;
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 18/39] ubifs: fill sb->s_cdev in ubifs_fill_super()
@ 2015-09-15  9:02   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

We need to fill the sb->s_cdev to tell others, this sb
is for which ubi_volume. quotactl will use this connection
to find the super_block by the device.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
Reviewed-by: Richard Weinberger <richard@nod.at>
---
 fs/ubifs/super.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index dcffcd6..0e0428b 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -2033,6 +2033,7 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
 		goto out_bdi;
 
 	sb->s_bdi = &c->bdi;
+	sb->s_cdev = ubi_get_volume_cdev(c->ubi);
 	sb->s_fs_info = c;
 	sb->s_magic = UBIFS_SUPER_MAGIC;
 	sb->s_blocksize = UBIFS_BLOCK_SIZE;
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 19/39] ubifs: fill ->s_dev in ubifs_fill_super
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:02   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

Some tools in userspace, such as quota-tools, are using
stat() to get the st_dev of a mount point then to find
out the device mounted on this mount point.

So we have to fill ->s_dev here to tell them which device
is mounted on this point.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
Reviewed-by: Richard Weinberger <richard@nod.at>
---
 fs/ubifs/super.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 0e0428b..791bed47 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -36,6 +36,7 @@
 #include <linux/mount.h>
 #include <linux/math64.h>
 #include <linux/writeback.h>
+#include <linux/cdev.h>
 #include "ubifs.h"
 
 /*
@@ -2034,6 +2035,7 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
 
 	sb->s_bdi = &c->bdi;
 	sb->s_cdev = ubi_get_volume_cdev(c->ubi);
+	sb->s_dev = sb->s_cdev->dev;
 	sb->s_fs_info = c;
 	sb->s_magic = UBIFS_SUPER_MAGIC;
 	sb->s_blocksize = UBIFS_BLOCK_SIZE;
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 19/39] ubifs: fill ->s_dev in ubifs_fill_super
@ 2015-09-15  9:02   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

Some tools in userspace, such as quota-tools, are using
stat() to get the st_dev of a mount point then to find
out the device mounted on this mount point.

So we have to fill ->s_dev here to tell them which device
is mounted on this point.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
Reviewed-by: Richard Weinberger <richard@nod.at>
---
 fs/ubifs/super.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 0e0428b..791bed47 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -36,6 +36,7 @@
 #include <linux/mount.h>
 #include <linux/math64.h>
 #include <linux/writeback.h>
+#include <linux/cdev.h>
 #include "ubifs.h"
 
 /*
@@ -2034,6 +2035,7 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
 
 	sb->s_bdi = &c->bdi;
 	sb->s_cdev = ubi_get_volume_cdev(c->ubi);
+	sb->s_dev = sb->s_cdev->dev;
 	sb->s_fs_info = c;
 	sb->s_magic = UBIFS_SUPER_MAGIC;
 	sb->s_blocksize = UBIFS_BLOCK_SIZE;
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 20/39] ubifs: export read_block() from file.c
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:02   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

We want to use read_block to read quota file bypass the page cache.
So export it from file.c, then we can use it in somewhere else.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
Reviewed-by: Richard Weinberger <richard@nod.at>
---
 fs/ubifs/file.c  | 13 +++++++++++--
 fs/ubifs/ubifs.h |  2 ++
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index c85b4fb..4cff712 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -53,7 +53,16 @@
 #include <linux/mount.h>
 #include <linux/slab.h>
 
-static int read_block(struct inode *inode, void *addr, unsigned int block,
+/**
+ * ubifs_read_block - read a block from inode
+ * @inode: inode we want to read
+ * @addr: memory address to put data in
+ * @block:: block number we want to read
+ * @dn: ubifs_data_node to search block
+ *
+ * This function read a specified block from tnc or media to addr.
+ */
+int ubifs_read_block(struct inode *inode, void *addr, unsigned int block,
 		      struct ubifs_data_node *dn)
 {
 	struct ubifs_info *c = inode->i_sb->s_fs_info;
@@ -140,7 +149,7 @@ static int do_readpage(struct page *page)
 			err = -ENOENT;
 			memset(addr, 0, UBIFS_BLOCK_SIZE);
 		} else {
-			ret = read_block(inode, addr, block, dn);
+			ret = ubifs_read_block(inode, addr, block, dn);
 			if (ret) {
 				err = ret;
 				if (err != -ENOENT)
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 5e1a5fe..4215c33 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -1751,6 +1751,8 @@ const struct ubifs_lprops *ubifs_fast_find_frdi_idx(struct ubifs_info *c);
 int ubifs_calc_dark(const struct ubifs_info *c, int spc);
 
 /* file.c */
+int ubifs_read_block(struct inode *inode, void *addr, unsigned int block,
+		      struct ubifs_data_node *dn);
 int ubifs_fsync(struct file *file, loff_t start, loff_t end, int datasync);
 int ubifs_setattr(struct dentry *dentry, struct iattr *attr);
 int ubifs_update_time(struct inode *inode, struct timespec *time, int flags);
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 20/39] ubifs: export read_block() from file.c
@ 2015-09-15  9:02   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

We want to use read_block to read quota file bypass the page cache.
So export it from file.c, then we can use it in somewhere else.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
Reviewed-by: Richard Weinberger <richard@nod.at>
---
 fs/ubifs/file.c  | 13 +++++++++++--
 fs/ubifs/ubifs.h |  2 ++
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index c85b4fb..4cff712 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -53,7 +53,16 @@
 #include <linux/mount.h>
 #include <linux/slab.h>
 
-static int read_block(struct inode *inode, void *addr, unsigned int block,
+/**
+ * ubifs_read_block - read a block from inode
+ * @inode: inode we want to read
+ * @addr: memory address to put data in
+ * @block:: block number we want to read
+ * @dn: ubifs_data_node to search block
+ *
+ * This function read a specified block from tnc or media to addr.
+ */
+int ubifs_read_block(struct inode *inode, void *addr, unsigned int block,
 		      struct ubifs_data_node *dn)
 {
 	struct ubifs_info *c = inode->i_sb->s_fs_info;
@@ -140,7 +149,7 @@ static int do_readpage(struct page *page)
 			err = -ENOENT;
 			memset(addr, 0, UBIFS_BLOCK_SIZE);
 		} else {
-			ret = read_block(inode, addr, block, dn);
+			ret = ubifs_read_block(inode, addr, block, dn);
 			if (ret) {
 				err = ret;
 				if (err != -ENOENT)
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 5e1a5fe..4215c33 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -1751,6 +1751,8 @@ const struct ubifs_lprops *ubifs_fast_find_frdi_idx(struct ubifs_info *c);
 int ubifs_calc_dark(const struct ubifs_info *c, int spc);
 
 /* file.c */
+int ubifs_read_block(struct inode *inode, void *addr, unsigned int block,
+		      struct ubifs_data_node *dn);
 int ubifs_fsync(struct file *file, loff_t start, loff_t end, int datasync);
 int ubifs_setattr(struct dentry *dentry, struct iattr *attr);
 int ubifs_update_time(struct inode *inode, struct timespec *time, int flags);
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 21/39] ubifs: introduce i_dquot to ubifs_inode
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:02   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

This commit introduce i_dquot field to ubifs_inode,
this field will be used later to support quota in ubifs.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/ubifs.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 4215c33..99cf10c 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -418,6 +418,9 @@ struct ubifs_inode {
 	loff_t synced_i_size;
 	loff_t ui_size;
 	int flags;
+#ifdef CONFIG_QUOTA
+	struct dquot *i_dquot[MAXQUOTAS];
+#endif
 	pgoff_t last_page_read;
 	pgoff_t read_in_a_row;
 	int data_len;
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 21/39] ubifs: introduce i_dquot to ubifs_inode
@ 2015-09-15  9:02   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

This commit introduce i_dquot field to ubifs_inode,
this field will be used later to support quota in ubifs.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/ubifs.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 4215c33..99cf10c 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -418,6 +418,9 @@ struct ubifs_inode {
 	loff_t synced_i_size;
 	loff_t ui_size;
 	int flags;
+#ifdef CONFIG_QUOTA
+	struct dquot *i_dquot[MAXQUOTAS];
+#endif
 	pgoff_t last_page_read;
 	pgoff_t read_in_a_row;
 	int data_len;
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 22/39] ubifs: implement IO functions for quota files
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:02   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

We have to implement 3 functions to support quota in ubifs:
ubifs_quota_read(), ubifs_quota_write() and ubifs_get_quotas()

ubifs_quota_read():
	callback to read quota file.
ubifs_quota_write():
	callback to write data to quota file.
ubifs_get_quotas():
	callback to get quota instance for inode.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/super.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 158 insertions(+)

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 791bed47..647677d 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -37,6 +37,7 @@
 #include <linux/math64.h>
 #include <linux/writeback.h>
 #include <linux/cdev.h>
+#include <linux/quotaops.h>
 #include "ubifs.h"
 
 /*
@@ -911,6 +912,158 @@ static int check_volume_empty(struct ubifs_info *c)
 	return 0;
 }
 
+#ifdef CONFIG_QUOTA
+static ssize_t ubifs_quota_read(struct super_block *sb, int type, char *data,
+			       size_t len, loff_t off)
+{
+	struct inode *inode = sb_dqopt(sb)->files[type];
+	unsigned long block = off >> UBIFS_BLOCK_SHIFT;
+	int offset = off & (sb->s_blocksize - 1);
+	int tocopy = 0;
+	size_t toread;
+	char *block_buf;
+	struct ubifs_data_node *dn;
+	int ret, err = 0;
+	loff_t i_size = i_size_read(inode);
+
+	if (off > i_size)
+		return 0;
+	if (off + len > i_size)
+		len = i_size - off;
+	toread = len;
+
+	dn = kmalloc(UBIFS_MAX_DATA_NODE_SZ, GFP_NOFS);
+	if (!dn) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	block_buf = kmalloc(sb->s_blocksize, GFP_NOFS);
+	if (!block_buf) {
+		err = -ENOMEM;
+		goto free_dn;
+	}
+
+	while (toread > 0) {
+		tocopy = sb->s_blocksize - offset < toread ?
+				sb->s_blocksize - offset : toread;
+
+		ret = ubifs_read_block(inode, block_buf, block, dn);
+		if (ret) {
+			if (ret != -ENOENT) {
+				err = ret;
+				goto free_buf;
+			}
+			memset(block_buf, 0, sb->s_blocksize);
+		}
+		memcpy(data, block_buf + offset, tocopy);
+		offset = 0;
+		block++;;
+		toread -= tocopy;
+		data += tocopy;
+	}
+free_buf:
+	kfree(block_buf);
+free_dn:
+	kfree(dn);
+out:
+	if (!err)
+		return len;
+	return err;
+}
+
+static ssize_t ubifs_quota_write(struct super_block *sb, int type,
+				const char *data, size_t len, loff_t off)
+{
+	struct inode *inode = sb_dqopt(sb)->files[type];
+	unsigned long block = off >> UBIFS_BLOCK_SHIFT;
+	struct ubifs_info *c = inode->i_sb->s_fs_info;
+	int offset = off & (sb->s_blocksize - 1);
+	union ubifs_key key;
+	int tocopy = 0;
+	size_t towrite = len;
+	int ret, err = 0;
+	struct ubifs_budget_req req = {};
+	struct ubifs_data_node *dn;
+	char *block_buf;
+
+	/*
+	 * Since we budget at most two blocks (one for dirtied block and
+	 * one for new block) here, then error out if the length out of
+	 * what allowed. NOTE, the writing length from quota should never
+	 * be larger than what we allowed here. Ext3 and Ext4 are also
+	 * limiting more strict for the len to one block size.
+	 */
+	if (sb->s_blocksize + (sb->s_blocksize - offset) < len) {
+		ubifs_err(c, "Quota write (off=%llu, len=%llu)"
+			" cancelled because length is too large",
+			(unsigned long long)off, (unsigned long long)len);
+		return -EIO;
+	}
+
+	if ((offset + len) > sb->s_blocksize)
+		req.new_block = 1;
+	if (offset)
+		req.dirtied_block = 1;
+
+	err = ubifs_budget_space(c, &req);
+	if (err)
+		goto out;
+
+	dn = kmalloc(UBIFS_MAX_DATA_NODE_SZ, GFP_NOFS);
+	if (!dn) {
+		err = -ENOMEM;
+		goto release_budget;
+	}
+
+	block_buf = kmalloc(sb->s_blocksize, GFP_NOFS);
+	if (!block_buf) {
+		err = -ENOMEM;
+		goto free_dn;
+	}
+
+	while (towrite > 0) {
+		tocopy = sb->s_blocksize - offset < towrite ?
+				sb->s_blocksize - offset : towrite;
+
+		if (offset || tocopy != sb->s_blocksize) {
+			ret = ubifs_read_block(inode, block_buf, block, dn);
+			if (ret) {
+				if (ret != -ENOENT) {
+					err = ret;
+					goto free_buf;
+				}
+				memset(block_buf, 0, sb->s_blocksize);
+			}
+		}
+		memcpy(block_buf + offset, data, tocopy);
+		data_key_init(c, &key, inode->i_ino, block);
+		err = ubifs_jnl_write_data(c, inode, &key, block_buf, sb->s_blocksize);
+		if (err)
+			goto free_buf;
+		offset = 0;
+		block++;;
+		towrite -= tocopy;
+		data += tocopy;
+	}
+free_buf:
+	kfree(block_buf);
+free_dn:
+	kfree(dn);
+release_budget:
+	ubifs_release_budget(c, &req);
+out:
+	if (!err)
+		return len;
+	return err;
+}
+
+static struct dquot **ubifs_get_dquots(struct inode *inode)
+{
+	return ubifs_inode(inode)->i_dquot;
+}
+#endif
+
 /*
  * UBIFS mount options.
  *
@@ -1887,6 +2040,11 @@ const struct super_operations ubifs_super_operations = {
 	.remount_fs    = ubifs_remount_fs,
 	.show_options  = ubifs_show_options,
 	.sync_fs       = ubifs_sync_fs,
+#ifdef CONFIG_QUOTA
+	.quota_read    = ubifs_quota_read,
+	.quota_write   = ubifs_quota_write,
+	.get_dquots    = ubifs_get_dquots,
+#endif
 };
 
 /**
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 22/39] ubifs: implement IO functions for quota files
@ 2015-09-15  9:02   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

We have to implement 3 functions to support quota in ubifs:
ubifs_quota_read(), ubifs_quota_write() and ubifs_get_quotas()

ubifs_quota_read():
	callback to read quota file.
ubifs_quota_write():
	callback to write data to quota file.
ubifs_get_quotas():
	callback to get quota instance for inode.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/super.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 158 insertions(+)

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 791bed47..647677d 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -37,6 +37,7 @@
 #include <linux/math64.h>
 #include <linux/writeback.h>
 #include <linux/cdev.h>
+#include <linux/quotaops.h>
 #include "ubifs.h"
 
 /*
@@ -911,6 +912,158 @@ static int check_volume_empty(struct ubifs_info *c)
 	return 0;
 }
 
+#ifdef CONFIG_QUOTA
+static ssize_t ubifs_quota_read(struct super_block *sb, int type, char *data,
+			       size_t len, loff_t off)
+{
+	struct inode *inode = sb_dqopt(sb)->files[type];
+	unsigned long block = off >> UBIFS_BLOCK_SHIFT;
+	int offset = off & (sb->s_blocksize - 1);
+	int tocopy = 0;
+	size_t toread;
+	char *block_buf;
+	struct ubifs_data_node *dn;
+	int ret, err = 0;
+	loff_t i_size = i_size_read(inode);
+
+	if (off > i_size)
+		return 0;
+	if (off + len > i_size)
+		len = i_size - off;
+	toread = len;
+
+	dn = kmalloc(UBIFS_MAX_DATA_NODE_SZ, GFP_NOFS);
+	if (!dn) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	block_buf = kmalloc(sb->s_blocksize, GFP_NOFS);
+	if (!block_buf) {
+		err = -ENOMEM;
+		goto free_dn;
+	}
+
+	while (toread > 0) {
+		tocopy = sb->s_blocksize - offset < toread ?
+				sb->s_blocksize - offset : toread;
+
+		ret = ubifs_read_block(inode, block_buf, block, dn);
+		if (ret) {
+			if (ret != -ENOENT) {
+				err = ret;
+				goto free_buf;
+			}
+			memset(block_buf, 0, sb->s_blocksize);
+		}
+		memcpy(data, block_buf + offset, tocopy);
+		offset = 0;
+		block++;;
+		toread -= tocopy;
+		data += tocopy;
+	}
+free_buf:
+	kfree(block_buf);
+free_dn:
+	kfree(dn);
+out:
+	if (!err)
+		return len;
+	return err;
+}
+
+static ssize_t ubifs_quota_write(struct super_block *sb, int type,
+				const char *data, size_t len, loff_t off)
+{
+	struct inode *inode = sb_dqopt(sb)->files[type];
+	unsigned long block = off >> UBIFS_BLOCK_SHIFT;
+	struct ubifs_info *c = inode->i_sb->s_fs_info;
+	int offset = off & (sb->s_blocksize - 1);
+	union ubifs_key key;
+	int tocopy = 0;
+	size_t towrite = len;
+	int ret, err = 0;
+	struct ubifs_budget_req req = {};
+	struct ubifs_data_node *dn;
+	char *block_buf;
+
+	/*
+	 * Since we budget at most two blocks (one for dirtied block and
+	 * one for new block) here, then error out if the length out of
+	 * what allowed. NOTE, the writing length from quota should never
+	 * be larger than what we allowed here. Ext3 and Ext4 are also
+	 * limiting more strict for the len to one block size.
+	 */
+	if (sb->s_blocksize + (sb->s_blocksize - offset) < len) {
+		ubifs_err(c, "Quota write (off=%llu, len=%llu)"
+			" cancelled because length is too large",
+			(unsigned long long)off, (unsigned long long)len);
+		return -EIO;
+	}
+
+	if ((offset + len) > sb->s_blocksize)
+		req.new_block = 1;
+	if (offset)
+		req.dirtied_block = 1;
+
+	err = ubifs_budget_space(c, &req);
+	if (err)
+		goto out;
+
+	dn = kmalloc(UBIFS_MAX_DATA_NODE_SZ, GFP_NOFS);
+	if (!dn) {
+		err = -ENOMEM;
+		goto release_budget;
+	}
+
+	block_buf = kmalloc(sb->s_blocksize, GFP_NOFS);
+	if (!block_buf) {
+		err = -ENOMEM;
+		goto free_dn;
+	}
+
+	while (towrite > 0) {
+		tocopy = sb->s_blocksize - offset < towrite ?
+				sb->s_blocksize - offset : towrite;
+
+		if (offset || tocopy != sb->s_blocksize) {
+			ret = ubifs_read_block(inode, block_buf, block, dn);
+			if (ret) {
+				if (ret != -ENOENT) {
+					err = ret;
+					goto free_buf;
+				}
+				memset(block_buf, 0, sb->s_blocksize);
+			}
+		}
+		memcpy(block_buf + offset, data, tocopy);
+		data_key_init(c, &key, inode->i_ino, block);
+		err = ubifs_jnl_write_data(c, inode, &key, block_buf, sb->s_blocksize);
+		if (err)
+			goto free_buf;
+		offset = 0;
+		block++;;
+		towrite -= tocopy;
+		data += tocopy;
+	}
+free_buf:
+	kfree(block_buf);
+free_dn:
+	kfree(dn);
+release_budget:
+	ubifs_release_budget(c, &req);
+out:
+	if (!err)
+		return len;
+	return err;
+}
+
+static struct dquot **ubifs_get_dquots(struct inode *inode)
+{
+	return ubifs_inode(inode)->i_dquot;
+}
+#endif
+
 /*
  * UBIFS mount options.
  *
@@ -1887,6 +2040,11 @@ const struct super_operations ubifs_super_operations = {
 	.remount_fs    = ubifs_remount_fs,
 	.show_options  = ubifs_show_options,
 	.sync_fs       = ubifs_sync_fs,
+#ifdef CONFIG_QUOTA
+	.quota_read    = ubifs_quota_read,
+	.quota_write   = ubifs_quota_write,
+	.get_dquots    = ubifs_get_dquots,
+#endif
 };
 
 /**
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 23/39] ubifs: disable quota in ubifs_put_super
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:02   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

We need to disable quota in umounting ubifs. So we have to
disable quota in ubifs_put_super(). But quota disable will
write quota file, and we have to budget for it.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/super.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 647677d..5a22595 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -1914,6 +1914,7 @@ static void ubifs_put_super(struct super_block *sb)
 
 	ubifs_msg(c, "un-mount UBI device %d", c->vi.ubi_num);
 
+	dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
 	/*
 	 * The following asserts are only valid if there has not been a failure
 	 * of the media. For example, there will be dirty inodes if we failed
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 23/39] ubifs: disable quota in ubifs_put_super
@ 2015-09-15  9:02   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

We need to disable quota in umounting ubifs. So we have to
disable quota in ubifs_put_super(). But quota disable will
write quota file, and we have to budget for it.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/super.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 647677d..5a22595 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -1914,6 +1914,7 @@ static void ubifs_put_super(struct super_block *sb)
 
 	ubifs_msg(c, "un-mount UBI device %d", c->vi.ubi_num);
 
+	dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
 	/*
 	 * The following asserts are only valid if there has not been a failure
 	 * of the media. For example, there will be dirty inodes if we failed
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 24/39] ubifs: write quota back in ubifs_sync
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:02   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

Call dquot_writeback_dquots to write quota back in ubifs_sync

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
Reviewed-by: Richard Weinberger <richard@nod.at>
---
 fs/ubifs/super.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 5a22595..2b07709 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -462,6 +462,8 @@ static int ubifs_sync_fs(struct super_block *sb, int wait)
 	if (!wait)
 		return 0;
 
+	dquot_writeback_dquots(sb, -1);
+
 	/*
 	 * Synchronize write buffers, because 'ubifs_run_commit()' does not
 	 * do this if it waits for an already running commit.
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 24/39] ubifs: write quota back in ubifs_sync
@ 2015-09-15  9:02   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

Call dquot_writeback_dquots to write quota back in ubifs_sync

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
Reviewed-by: Richard Weinberger <richard@nod.at>
---
 fs/ubifs/super.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 5a22595..2b07709 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -462,6 +462,8 @@ static int ubifs_sync_fs(struct super_block *sb, int wait)
 	if (!wait)
 		return 0;
 
+	dquot_writeback_dquots(sb, -1);
+
 	/*
 	 * Synchronize write buffers, because 'ubifs_run_commit()' does not
 	 * do this if it waits for an already running commit.
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 25/39] ubifs: set/clear MS_RDONLY properly in ubifs_remount
  2015-09-15  9:01 ` Dongsheng Yang
                   ` (24 preceding siblings ...)
  (?)
@ 2015-09-15  9:02 ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

We need to set or clear MS_RDONLY in remounting.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/super.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 2b07709..59cdfc2 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -1840,6 +1840,7 @@ static int ubifs_remount_rw(struct ubifs_info *c)
 		 */
 		err = dbg_check_space_info(c);
 	}
+	c->vfs_sb->s_flags &= ~MS_RDONLY;
 
 	mutex_unlock(&c->umount_mutex);
 	return err;
@@ -1906,6 +1907,7 @@ static void ubifs_remount_ro(struct ubifs_info *c)
 	err = dbg_check_space_info(c);
 	if (err)
 		ubifs_ro_mode(c, err);
+	c->vfs_sb->s_flags |= MS_RDONLY;
 	mutex_unlock(&c->umount_mutex);
 }
 
-- 
1.8.4.2


^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 26/39] ubifs: suspend & resume quota properly in ubifs_remount
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:02   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
Reviewed-by: Richard Weinberger <richard@nod.at>
---
 fs/ubifs/super.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 59cdfc2..cc2988f 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -2014,11 +2014,17 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
 		err = ubifs_remount_rw(c);
 		if (err)
 			return err;
+		err = dquot_resume(sb, -1);
+		if (err)
+			return err;
 	} else if (!c->ro_mount && (*flags & MS_RDONLY)) {
 		if (c->ro_error) {
 			ubifs_msg(c, "cannot re-mount R/O due to prior errors");
 			return -EROFS;
 		}
+		err = dquot_suspend(sb, -1);
+		if (err)
+			return err;
 		ubifs_remount_ro(c);
 	}
 
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 26/39] ubifs: suspend & resume quota properly in ubifs_remount
@ 2015-09-15  9:02   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
Reviewed-by: Richard Weinberger <richard@nod.at>
---
 fs/ubifs/super.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 59cdfc2..cc2988f 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -2014,11 +2014,17 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
 		err = ubifs_remount_rw(c);
 		if (err)
 			return err;
+		err = dquot_resume(sb, -1);
+		if (err)
+			return err;
 	} else if (!c->ro_mount && (*flags & MS_RDONLY)) {
 		if (c->ro_error) {
 			ubifs_msg(c, "cannot re-mount R/O due to prior errors");
 			return -EROFS;
 		}
+		err = dquot_suspend(sb, -1);
+		if (err)
+			return err;
 		ubifs_remount_ro(c);
 	}
 
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 27/39] ubifs: check inode with NULL before using it
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:02   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

There is a checking of inode with NULL after ubifs_inode(inode),
that's not readable, why we need to check a pointer with NULL
after we having used it?

Although inode=NULL will not hurt ubifs_inode(), checking inode
following new_inode() directly before using it seems more reasonable.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/dir.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index a822148..4db0ceb 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -92,10 +92,10 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
 	struct ubifs_inode *ui;
 
 	inode = new_inode(c->vfs_sb);
-	ui = ubifs_inode(inode);
 	if (!inode)
 		return ERR_PTR(-ENOMEM);
 
+	ui = ubifs_inode(inode);
 	/*
 	 * Set 'S_NOCMTIME' to prevent VFS form updating [mc]time of inodes and
 	 * marking them dirty in file write path (see 'file_update_time()').
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 27/39] ubifs: check inode with NULL before using it
@ 2015-09-15  9:02   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

There is a checking of inode with NULL after ubifs_inode(inode),
that's not readable, why we need to check a pointer with NULL
after we having used it?

Although inode=NULL will not hurt ubifs_inode(), checking inode
following new_inode() directly before using it seems more reasonable.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/dir.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index a822148..4db0ceb 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -92,10 +92,10 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
 	struct ubifs_inode *ui;
 
 	inode = new_inode(c->vfs_sb);
-	ui = ubifs_inode(inode);
 	if (!inode)
 		return ERR_PTR(-ENOMEM);
 
+	ui = ubifs_inode(inode);
 	/*
 	 * Set 'S_NOCMTIME' to prevent VFS form updating [mc]time of inodes and
 	 * marking them dirty in file write path (see 'file_update_time()').
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 28/39] ubifs: record quota information about inode in ubifs_new_inode
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:02   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

Initialize quota and alloc a inode quota information in
ubifs_new_inode(). Then quota would be aware of a new
inode is allocated.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/dir.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 4db0ceb..802c6ad 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -41,6 +41,7 @@
  */
 
 #include "ubifs.h"
+#include <linux/quotaops.h>
 
 /**
  * inherit_flags - inherit flags of the parent inode.
@@ -90,6 +91,7 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
 {
 	struct inode *inode;
 	struct ubifs_inode *ui;
+	int err = 0;
 
 	inode = new_inode(c->vfs_sb);
 	if (!inode)
@@ -109,6 +111,11 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
 			 ubifs_current_time(inode);
 	inode->i_mapping->nrpages = 0;
 
+	dquot_initialize(inode);
+        err = dquot_alloc_inode(inode);
+        if (err)
+                goto fail_drop;
+
 	switch (mode & S_IFMT) {
 	case S_IFREG:
 		inode->i_mapping->a_ops = &ubifs_file_address_operations;
@@ -148,8 +155,8 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
 			spin_unlock(&c->cnt_lock);
 			ubifs_err(c, "out of inode numbers");
 			make_bad_inode(inode);
-			iput(inode);
-			return ERR_PTR(-EINVAL);
+			err = -EINVAL;
+			goto fail_free;
 		}
 		ubifs_warn(c, "running out of inode numbers (current %lu, max %u)",
 			   (unsigned long)c->highest_inum, INUM_WATERMARK);
@@ -166,6 +173,13 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
 	ui->creat_sqnum = ++c->max_sqnum;
 	spin_unlock(&c->cnt_lock);
 	return inode;
+
+fail_free:
+	dquot_free_inode(inode);
+fail_drop:
+	dquot_drop(inode);
+	iput(inode);
+	return ERR_PTR(err);
 }
 
 static int dbg_check_name(const struct ubifs_info *c,
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 28/39] ubifs: record quota information about inode in ubifs_new_inode
@ 2015-09-15  9:02   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

Initialize quota and alloc a inode quota information in
ubifs_new_inode(). Then quota would be aware of a new
inode is allocated.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/dir.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 4db0ceb..802c6ad 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -41,6 +41,7 @@
  */
 
 #include "ubifs.h"
+#include <linux/quotaops.h>
 
 /**
  * inherit_flags - inherit flags of the parent inode.
@@ -90,6 +91,7 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
 {
 	struct inode *inode;
 	struct ubifs_inode *ui;
+	int err = 0;
 
 	inode = new_inode(c->vfs_sb);
 	if (!inode)
@@ -109,6 +111,11 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
 			 ubifs_current_time(inode);
 	inode->i_mapping->nrpages = 0;
 
+	dquot_initialize(inode);
+        err = dquot_alloc_inode(inode);
+        if (err)
+                goto fail_drop;
+
 	switch (mode & S_IFMT) {
 	case S_IFREG:
 		inode->i_mapping->a_ops = &ubifs_file_address_operations;
@@ -148,8 +155,8 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
 			spin_unlock(&c->cnt_lock);
 			ubifs_err(c, "out of inode numbers");
 			make_bad_inode(inode);
-			iput(inode);
-			return ERR_PTR(-EINVAL);
+			err = -EINVAL;
+			goto fail_free;
 		}
 		ubifs_warn(c, "running out of inode numbers (current %lu, max %u)",
 			   (unsigned long)c->highest_inum, INUM_WATERMARK);
@@ -166,6 +173,13 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
 	ui->creat_sqnum = ++c->max_sqnum;
 	spin_unlock(&c->cnt_lock);
 	return inode;
+
+fail_free:
+	dquot_free_inode(inode);
+fail_drop:
+	dquot_drop(inode);
+	iput(inode);
+	return ERR_PTR(err);
 }
 
 static int dbg_check_name(const struct ubifs_info *c,
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 29/39] ubifs: free quota inode information in ubifs_evict_inode
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:02   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

In evict, we have to call dquot_free_inode() to tell quota
subsystem there is one inode to be free. Please update the
quota information.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/super.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index cc2988f..47b1f44 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -362,6 +362,7 @@ static void ubifs_evict_inode(struct inode *inode)
 	if (is_bad_inode(inode))
 		goto out;
 
+	dquot_initialize(inode);
 	ui->ui_size = inode->i_size = 0;
 	err = ubifs_jnl_delete_inode(c, inode);
 	if (err)
@@ -371,7 +372,7 @@ static void ubifs_evict_inode(struct inode *inode)
 		 */
 		ubifs_err(c, "can't delete inode %lu, error %d",
 			  inode->i_ino, err);
-
+	dquot_free_inode(inode);
 out:
 	if (ui->dirty)
 		ubifs_release_dirty_inode_budget(c, ui);
@@ -381,6 +382,7 @@ out:
 		smp_wmb();
 	}
 done:
+	dquot_drop(inode);
 	clear_inode(inode);
 }
 
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 29/39] ubifs: free quota inode information in ubifs_evict_inode
@ 2015-09-15  9:02   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

In evict, we have to call dquot_free_inode() to tell quota
subsystem there is one inode to be free. Please update the
quota information.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/super.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index cc2988f..47b1f44 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -362,6 +362,7 @@ static void ubifs_evict_inode(struct inode *inode)
 	if (is_bad_inode(inode))
 		goto out;
 
+	dquot_initialize(inode);
 	ui->ui_size = inode->i_size = 0;
 	err = ubifs_jnl_delete_inode(c, inode);
 	if (err)
@@ -371,7 +372,7 @@ static void ubifs_evict_inode(struct inode *inode)
 		 */
 		ubifs_err(c, "can't delete inode %lu, error %d",
 			  inode->i_ino, err);
-
+	dquot_free_inode(inode);
 out:
 	if (ui->dirty)
 		ubifs_release_dirty_inode_budget(c, ui);
@@ -381,6 +382,7 @@ out:
 		smp_wmb();
 	}
 done:
+	dquot_drop(inode);
 	clear_inode(inode);
 }
 
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 30/39] ubifs: alloc quota space in ubifs writing path
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:02   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

Besides inode, quota also limit the space. When
user want to write something, we have to tell quota
subsystem there is something is going to be written
into ubifs, please check the quota limit. If it exceed
the limit, return EQUOT. Else, record it and go on.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/file.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 4cff712..64ca91c 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -52,6 +52,7 @@
 #include "ubifs.h"
 #include <linux/mount.h>
 #include <linux/slab.h>
+#include <linux/quotaops.h>
 
 /**
  * ubifs_read_block - read a block from inode
@@ -439,8 +440,10 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
 	struct ubifs_inode *ui = ubifs_inode(inode);
 	pgoff_t index = pos >> PAGE_CACHE_SHIFT;
 	int uninitialized_var(err), appending = !!(pos + len > inode->i_size);
+	int quota_size = 0;
 	int skipped_read = 0;
 	struct page *page;
+	int ret = 0;
 
 	ubifs_assert(ubifs_inode(inode)->ui_size == inode->i_size);
 	ubifs_assert(!c->ro_media && !c->ro_mount);
@@ -448,6 +451,16 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
 	if (unlikely(c->ro_error))
 		return -EROFS;
 
+	quota_size = ((pos + len) - inode->i_size);
+	if (quota_size < 0)
+		quota_size = 0;
+	if (S_ISREG(inode->i_mode)) {
+		dquot_initialize(inode);
+		ret = dquot_alloc_space_nodirty(inode, quota_size);
+		if (unlikely(ret))
+			return ret;
+	}
+
 	/* Try out the fast-path part first */
 	page = grab_cache_page_write_begin(mapping, index, flags);
 	if (unlikely(!page))
@@ -553,6 +566,7 @@ static int ubifs_write_end(struct file *file, struct address_space *mapping,
 	struct ubifs_inode *ui = ubifs_inode(inode);
 	struct ubifs_info *c = inode->i_sb->s_fs_info;
 	loff_t end_pos = pos + len;
+	int quota_size = 0;
 	int appending = !!(end_pos > inode->i_size);
 
 	dbg_gen("ino %lu, pos %llu, pg %lu, len %u, copied %d, i_size %lld",
@@ -571,6 +585,12 @@ static int ubifs_write_end(struct file *file, struct address_space *mapping,
 		dbg_gen("copied %d instead of %d, read page and repeat",
 			copied, len);
 		cancel_budget(c, page, ui, appending);
+		quota_size = ((pos + len) - inode->i_size);
+		if (quota_size < 0)
+			quota_size = 0;
+		if (S_ISREG(inode->i_mode)) {
+			dquot_free_space_nodirty(inode, quota_size);
+		}
 		ClearPageChecked(page);
 
 		/*
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 30/39] ubifs: alloc quota space in ubifs writing path
@ 2015-09-15  9:02   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

Besides inode, quota also limit the space. When
user want to write something, we have to tell quota
subsystem there is something is going to be written
into ubifs, please check the quota limit. If it exceed
the limit, return EQUOT. Else, record it and go on.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/file.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 4cff712..64ca91c 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -52,6 +52,7 @@
 #include "ubifs.h"
 #include <linux/mount.h>
 #include <linux/slab.h>
+#include <linux/quotaops.h>
 
 /**
  * ubifs_read_block - read a block from inode
@@ -439,8 +440,10 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
 	struct ubifs_inode *ui = ubifs_inode(inode);
 	pgoff_t index = pos >> PAGE_CACHE_SHIFT;
 	int uninitialized_var(err), appending = !!(pos + len > inode->i_size);
+	int quota_size = 0;
 	int skipped_read = 0;
 	struct page *page;
+	int ret = 0;
 
 	ubifs_assert(ubifs_inode(inode)->ui_size == inode->i_size);
 	ubifs_assert(!c->ro_media && !c->ro_mount);
@@ -448,6 +451,16 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
 	if (unlikely(c->ro_error))
 		return -EROFS;
 
+	quota_size = ((pos + len) - inode->i_size);
+	if (quota_size < 0)
+		quota_size = 0;
+	if (S_ISREG(inode->i_mode)) {
+		dquot_initialize(inode);
+		ret = dquot_alloc_space_nodirty(inode, quota_size);
+		if (unlikely(ret))
+			return ret;
+	}
+
 	/* Try out the fast-path part first */
 	page = grab_cache_page_write_begin(mapping, index, flags);
 	if (unlikely(!page))
@@ -553,6 +566,7 @@ static int ubifs_write_end(struct file *file, struct address_space *mapping,
 	struct ubifs_inode *ui = ubifs_inode(inode);
 	struct ubifs_info *c = inode->i_sb->s_fs_info;
 	loff_t end_pos = pos + len;
+	int quota_size = 0;
 	int appending = !!(end_pos > inode->i_size);
 
 	dbg_gen("ino %lu, pos %llu, pg %lu, len %u, copied %d, i_size %lld",
@@ -571,6 +585,12 @@ static int ubifs_write_end(struct file *file, struct address_space *mapping,
 		dbg_gen("copied %d instead of %d, read page and repeat",
 			copied, len);
 		cancel_budget(c, page, ui, appending);
+		quota_size = ((pos + len) - inode->i_size);
+		if (quota_size < 0)
+			quota_size = 0;
+		if (S_ISREG(inode->i_mode)) {
+			dquot_free_space_nodirty(inode, quota_size);
+		}
 		ClearPageChecked(page);
 
 		/*
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 31/39] ubifs: free quota space in do_truncation
  2015-09-15  9:01 ` Dongsheng Yang
                   ` (30 preceding siblings ...)
  (?)
@ 2015-09-15  9:02 ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

In truncation, we have to tell quota subsystem
to update the quota information of the space changing.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/file.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 64ca91c..59b2098 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1136,6 +1136,7 @@ static int do_truncation(struct ubifs_info *c, struct inode *inode,
 	int err;
 	struct ubifs_budget_req req;
 	loff_t old_size = inode->i_size, new_size = attr->ia_size;
+	loff_t quota_size = (old_size - new_size);
 	int offset = new_size & (UBIFS_BLOCK_SIZE - 1), budgeted = 1;
 	struct ubifs_inode *ui = ubifs_inode(inode);
 
@@ -1215,6 +1216,10 @@ static int do_truncation(struct ubifs_info *c, struct inode *inode,
 	do_attr_changes(inode, attr);
 	err = ubifs_jnl_truncate(c, inode, old_size, new_size);
 	mutex_unlock(&ui->ui_mutex);
+	if (quota_size < 0)
+		quota_size = 0;
+	if (S_ISREG(inode->i_mode))
+		dquot_free_space_nodirty(inode, quota_size);
 
 out_budg:
 	if (budgeted)
-- 
1.8.4.2


^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 32/39] ubifs: free quota space when deleting a file
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:02   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

When we unlink an inode which has only one last reference,
we are going to free the space in this inode. So free
the quota space at the same time.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/journal.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c
index 0b9da5b..f8a642d 100644
--- a/fs/ubifs/journal.c
+++ b/fs/ubifs/journal.c
@@ -58,6 +58,8 @@
  * all the nodes.
  */
 
+#include <linux/quotaops.h>
+
 #include "ubifs.h"
 
 /**
@@ -614,6 +616,8 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,
 			goto out_finish;
 		}
 		ui->del_cmtno = c->cmt_no;
+		if (S_ISREG(inode->i_mode))
+			dquot_free_space_nodirty((struct inode *)inode, inode->i_size);
 	}
 
 	err = write_head(c, BASEHD, dent, len, &lnum, &dent_offs, sync);
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 32/39] ubifs: free quota space when deleting a file
@ 2015-09-15  9:02   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

When we unlink an inode which has only one last reference,
we are going to free the space in this inode. So free
the quota space at the same time.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/journal.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c
index 0b9da5b..f8a642d 100644
--- a/fs/ubifs/journal.c
+++ b/fs/ubifs/journal.c
@@ -58,6 +58,8 @@
  * all the nodes.
  */
 
+#include <linux/quotaops.h>
+
 #include "ubifs.h"
 
 /**
@@ -614,6 +616,8 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,
 			goto out_finish;
 		}
 		ui->del_cmtno = c->cmt_no;
+		if (S_ISREG(inode->i_mode))
+			dquot_free_space_nodirty((struct inode *)inode, inode->i_size);
 	}
 
 	err = write_head(c, BASEHD, dent, len, &lnum, &dent_offs, sync);
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 33/39] ubifs: adapt quota space informatin in do_setattr
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:02   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

In do_setattr, there is a possibility to change the size of
a file. In this case, we have to notify the changed size to
quota subsystem.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/file.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 59b2098..ec89298 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1256,6 +1256,17 @@ static int do_setattr(struct ubifs_info *c, struct inode *inode,
 
 	if (attr->ia_valid & ATTR_SIZE) {
 		dbg_gen("size %lld -> %lld", inode->i_size, new_size);
+		if (S_ISREG(inode->i_mode)) {
+			if (new_size > inode->i_size) {
+				err = dquot_alloc_space_nodirty(inode, new_size - inode->i_size);
+				if (err) {
+					ubifs_release_budget(c, &req);
+					return err;
+				}
+			} else {
+				dquot_free_space_nodirty(inode, inode->i_size - new_size);
+			}
+		}
 		truncate_setsize(inode, new_size);
 	}
 
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 33/39] ubifs: adapt quota space informatin in do_setattr
@ 2015-09-15  9:02   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

In do_setattr, there is a possibility to change the size of
a file. In this case, we have to notify the changed size to
quota subsystem.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/file.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 59b2098..ec89298 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1256,6 +1256,17 @@ static int do_setattr(struct ubifs_info *c, struct inode *inode,
 
 	if (attr->ia_valid & ATTR_SIZE) {
 		dbg_gen("size %lld -> %lld", inode->i_size, new_size);
+		if (S_ISREG(inode->i_mode)) {
+			if (new_size > inode->i_size) {
+				err = dquot_alloc_space_nodirty(inode, new_size - inode->i_size);
+				if (err) {
+					ubifs_release_budget(c, &req);
+					return err;
+				}
+			} else {
+				dquot_free_space_nodirty(inode, inode->i_size - new_size);
+			}
+		}
 		truncate_setsize(inode, new_size);
 	}
 
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 34/39] ubifs: transfer quota information in changing owner or group
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:02   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

When we change the owner or group of a file, we need to transfer
the quota information at the same time.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/file.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index ec89298..b57ccf3 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1314,6 +1314,15 @@ int ubifs_setattr(struct dentry *dentry, struct iattr *attr)
 	if (err)
 		return err;
 
+	if (is_quota_modification(inode, attr))
+		dquot_initialize(inode);
+	if ((attr->ia_valid & ATTR_UID && !uid_eq(attr->ia_uid, inode->i_uid)) ||
+	    (attr->ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid))) {
+		err = dquot_transfer(inode, attr);
+		if (err)
+			return err;
+	}
+
 	if ((attr->ia_valid & ATTR_SIZE) && attr->ia_size < inode->i_size)
 		/* Truncation to a smaller size */
 		err = do_truncation(c, inode, attr);
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 34/39] ubifs: transfer quota information in changing owner or group
@ 2015-09-15  9:02   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

When we change the owner or group of a file, we need to transfer
the quota information at the same time.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/file.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index ec89298..b57ccf3 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1314,6 +1314,15 @@ int ubifs_setattr(struct dentry *dentry, struct iattr *attr)
 	if (err)
 		return err;
 
+	if (is_quota_modification(inode, attr))
+		dquot_initialize(inode);
+	if ((attr->ia_valid & ATTR_UID && !uid_eq(attr->ia_uid, inode->i_uid)) ||
+	    (attr->ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid))) {
+		err = dquot_transfer(inode, attr);
+		if (err)
+			return err;
+	}
+
 	if ((attr->ia_valid & ATTR_SIZE) && attr->ia_size < inode->i_size)
 		/* Truncation to a smaller size */
 		err = do_truncation(c, inode, attr);
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 35/39] ubifs: write inode in ubifs_quota_write if we are appending
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:02   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

When we are appending writing quota file, we have to do a
budgeting for the inode and write inode in ubifs_quota_write.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/super.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 47b1f44..d3213a2 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -980,6 +980,10 @@ static ssize_t ubifs_quota_write(struct super_block *sb, int type,
 				const char *data, size_t len, loff_t off)
 {
 	struct inode *inode = sb_dqopt(sb)->files[type];
+	struct ubifs_inode *ui = ubifs_inode(inode);
+	loff_t end_pos = off + len;
+	int appending = (end_pos > inode->i_size);
+	int ino_released = 0;
 	unsigned long block = off >> UBIFS_BLOCK_SHIFT;
 	struct ubifs_info *c = inode->i_sb->s_fs_info;
 	int offset = off & (sb->s_blocksize - 1);
@@ -988,6 +992,8 @@ static ssize_t ubifs_quota_write(struct super_block *sb, int type,
 	size_t towrite = len;
 	int ret, err = 0;
 	struct ubifs_budget_req req = {};
+	struct ubifs_budget_req ino_req = { .dirtied_ino = 1,
+				.dirtied_ino_d = ALIGN(ui->data_len, 8) };
 	struct ubifs_data_node *dn;
 	char *block_buf;
 
@@ -1014,6 +1020,12 @@ static ssize_t ubifs_quota_write(struct super_block *sb, int type,
 	if (err)
 		goto out;
 
+	if (appending) {
+		err = ubifs_budget_space(c, &ino_req);
+		if (err)
+			goto release_block;
+	}
+
 	dn = kmalloc(UBIFS_MAX_DATA_NODE_SZ, GFP_NOFS);
 	if (!dn) {
 		err = -ENOMEM;
@@ -1050,11 +1062,23 @@ static ssize_t ubifs_quota_write(struct super_block *sb, int type,
 		towrite -= tocopy;
 		data += tocopy;
 	}
+	if (appending) {
+		mutex_lock(&ui->ui_mutex);
+		i_size_write(inode, end_pos);
+		ui->ui_size = end_pos;
+		__mark_inode_dirty(inode, I_DIRTY_DATASYNC);
+		mutex_unlock(&ui->ui_mutex);
+		err = inode->i_sb->s_op->write_inode(inode, NULL);
+		ino_released = 1;
+	}
 free_buf:
 	kfree(block_buf);
 free_dn:
 	kfree(dn);
 release_budget:
+	if (appending && !ino_released)
+		ubifs_release_budget(c, &ino_req);
+release_block:
 	ubifs_release_budget(c, &req);
 out:
 	if (!err)
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 35/39] ubifs: write inode in ubifs_quota_write if we are appending
@ 2015-09-15  9:02   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

When we are appending writing quota file, we have to do a
budgeting for the inode and write inode in ubifs_quota_write.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/super.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 47b1f44..d3213a2 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -980,6 +980,10 @@ static ssize_t ubifs_quota_write(struct super_block *sb, int type,
 				const char *data, size_t len, loff_t off)
 {
 	struct inode *inode = sb_dqopt(sb)->files[type];
+	struct ubifs_inode *ui = ubifs_inode(inode);
+	loff_t end_pos = off + len;
+	int appending = (end_pos > inode->i_size);
+	int ino_released = 0;
 	unsigned long block = off >> UBIFS_BLOCK_SHIFT;
 	struct ubifs_info *c = inode->i_sb->s_fs_info;
 	int offset = off & (sb->s_blocksize - 1);
@@ -988,6 +992,8 @@ static ssize_t ubifs_quota_write(struct super_block *sb, int type,
 	size_t towrite = len;
 	int ret, err = 0;
 	struct ubifs_budget_req req = {};
+	struct ubifs_budget_req ino_req = { .dirtied_ino = 1,
+				.dirtied_ino_d = ALIGN(ui->data_len, 8) };
 	struct ubifs_data_node *dn;
 	char *block_buf;
 
@@ -1014,6 +1020,12 @@ static ssize_t ubifs_quota_write(struct super_block *sb, int type,
 	if (err)
 		goto out;
 
+	if (appending) {
+		err = ubifs_budget_space(c, &ino_req);
+		if (err)
+			goto release_block;
+	}
+
 	dn = kmalloc(UBIFS_MAX_DATA_NODE_SZ, GFP_NOFS);
 	if (!dn) {
 		err = -ENOMEM;
@@ -1050,11 +1062,23 @@ static ssize_t ubifs_quota_write(struct super_block *sb, int type,
 		towrite -= tocopy;
 		data += tocopy;
 	}
+	if (appending) {
+		mutex_lock(&ui->ui_mutex);
+		i_size_write(inode, end_pos);
+		ui->ui_size = end_pos;
+		__mark_inode_dirty(inode, I_DIRTY_DATASYNC);
+		mutex_unlock(&ui->ui_mutex);
+		err = inode->i_sb->s_op->write_inode(inode, NULL);
+		ino_released = 1;
+	}
 free_buf:
 	kfree(block_buf);
 free_dn:
 	kfree(dn);
 release_budget:
+	if (appending && !ino_released)
+		ubifs_release_budget(c, &ino_req);
+release_block:
 	ubifs_release_budget(c, &req);
 out:
 	if (!err)
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 36/39] ubifs: implement ubifs_get_qsize to get quota size in ubifs
  2015-09-15  9:01 ` Dongsheng Yang
                   ` (35 preceding siblings ...)
  (?)
@ 2015-09-15  9:02 ` Dongsheng Yang
  2015-09-16 10:00   ` Jan Kara
  -1 siblings, 1 reply; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

We only care the size of regular file in ubifs for quota.
The reason is similar with the comment in ubifs_getattr().

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/dir.c   |  3 +++
 fs/ubifs/file.c  | 22 ++++++++++++++++++++++
 fs/ubifs/ubifs.h |  1 +
 3 files changed, 26 insertions(+)

diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 802c6ad..0d3d6d3 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -1205,6 +1205,9 @@ const struct inode_operations ubifs_dir_inode_operations = {
 #ifdef CONFIG_UBIFS_ATIME_SUPPORT
 	.update_time = ubifs_update_time,
 #endif
+#ifdef CONFIG_QUOTA
+	.get_qsize	= ubifs_get_qsize,
+#endif
 };
 
 const struct file_operations ubifs_dir_operations = {
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index b57ccf3..f1d792a 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1636,6 +1636,22 @@ static int ubifs_file_mmap(struct file *file, struct vm_area_struct *vma)
 	return 0;
 }
 
+/*
+ * ubifs_get_qsize: get the quota size of a file
+ * @inode: inode which we are going to get the qsize
+ *
+ * We only care the size of regular file in ubifs
+ * for quota. The reason is similar with the comment
+ * in ubifs_getattr().
+ */
+ssize_t ubifs_get_qsize(struct inode *inode)
+{
+	if (S_ISREG(inode->i_mode))
+		return i_size_read(inode);
+	else
+		return 0;
+}
+
 const struct address_space_operations ubifs_file_address_operations = {
 	.readpage       = ubifs_readpage,
 	.writepage      = ubifs_writepage,
@@ -1656,6 +1672,9 @@ const struct inode_operations ubifs_file_inode_operations = {
 #ifdef CONFIG_UBIFS_ATIME_SUPPORT
 	.update_time = ubifs_update_time,
 #endif
+#ifdef CONFIG_QUOTA
+	.get_qsize	= ubifs_get_qsize,
+#endif
 };
 
 const struct inode_operations ubifs_symlink_inode_operations = {
@@ -1670,6 +1689,9 @@ const struct inode_operations ubifs_symlink_inode_operations = {
 #ifdef CONFIG_UBIFS_ATIME_SUPPORT
 	.update_time = ubifs_update_time,
 #endif
+#ifdef CONFIG_QUOTA
+	.get_qsize	= ubifs_get_qsize,
+#endif
 };
 
 const struct file_operations ubifs_file_operations = {
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 99cf10c..21b5dc0 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -1759,6 +1759,7 @@ int ubifs_read_block(struct inode *inode, void *addr, unsigned int block,
 int ubifs_fsync(struct file *file, loff_t start, loff_t end, int datasync);
 int ubifs_setattr(struct dentry *dentry, struct iattr *attr);
 int ubifs_update_time(struct inode *inode, struct timespec *time, int flags);
+ssize_t ubifs_get_qsize(struct inode *inode);
 
 /* dir.c */
 struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
-- 
1.8.4.2


^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 37/39] ubifs: implement ubifs_restore_iflags for quotactl_operations
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:02   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

We have to implement a ubifs_restore_iflags for quotactl_operations,
because we don't allow dquot mark_inode_dirty() without a budget.
So we need to do it by ourselves in ubifs_restore_iflags.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/super.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index d3213a2..01aaa88 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -2192,6 +2192,67 @@ static struct ubifs_info *alloc_ubifs_info(struct ubi_volume_desc *ubi)
 	return c;
 }
 
+#ifdef CONFIG_QUOTA
+static int ubifs_restore_iflags(struct super_block *sb, struct inode **toputinode,
+					unsigned int *old_flags)
+{
+	int cnt = 0;
+	int err = 0;
+	struct quota_info *dqopt = sb_dqopt(sb);
+	struct ubifs_info *c = sb->s_fs_info;
+
+	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
+		if (toputinode[cnt]) {
+			struct ubifs_inode *ui = ubifs_inode(toputinode[cnt]);
+			struct ubifs_budget_req req = { .dirtied_ino = 1,
+					.dirtied_ino_d = ALIGN(ui->data_len, 8) };
+			int release = 0;
+
+			/* budget for the inode which need to update */
+			err = ubifs_budget_space(c, &req);
+			if (err)
+				return err;
+
+			mutex_lock(&dqopt->dqonoff_mutex);
+			/* If quota was reenabled in the meantime, we have
+			 * nothing to do */
+			if (!sb_has_quota_loaded(sb, cnt)) {
+				mutex_lock(&toputinode[cnt]->i_mutex);
+				toputinode[cnt]->i_flags &= ~(S_IMMUTABLE |
+				  S_NOATIME | S_NOQUOTA);
+				toputinode[cnt]->i_flags |= old_flags[cnt];
+				truncate_inode_pages(&toputinode[cnt]->i_data,
+						     0);
+				mutex_unlock(&toputinode[cnt]->i_mutex);
+
+				mutex_lock(&ui->ui_mutex);
+				release = ui->dirty;
+				mark_inode_dirty_sync(toputinode[cnt]);
+				mutex_unlock(&ui->ui_mutex);
+			} else {
+				release = 1;
+			}
+			mutex_unlock(&dqopt->dqonoff_mutex);
+			/* Release the budget if we don't need to update the inode */
+			if (release)
+				ubifs_release_budget(c, &req);
+		}
+
+	return 0;
+}
+
+static const struct quotactl_ops ubifs_quotactl_ops = {
+	.quota_on	= dquot_quota_on,
+	.quota_off	= dquot_quota_off,
+	.quota_sync	= dquot_quota_sync,
+	.get_state	= dquot_get_state,
+	.set_info	= dquot_set_dqinfo,
+	.get_dqblk	= dquot_get_dqblk,
+	.set_dqblk	= dquot_set_dqblk,
+	.restore_iflags	= ubifs_restore_iflags
+};
+#endif
+
 static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct ubifs_info *c = sb->s_fs_info;
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 37/39] ubifs: implement ubifs_restore_iflags for quotactl_operations
@ 2015-09-15  9:02   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

We have to implement a ubifs_restore_iflags for quotactl_operations,
because we don't allow dquot mark_inode_dirty() without a budget.
So we need to do it by ourselves in ubifs_restore_iflags.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/super.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index d3213a2..01aaa88 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -2192,6 +2192,67 @@ static struct ubifs_info *alloc_ubifs_info(struct ubi_volume_desc *ubi)
 	return c;
 }
 
+#ifdef CONFIG_QUOTA
+static int ubifs_restore_iflags(struct super_block *sb, struct inode **toputinode,
+					unsigned int *old_flags)
+{
+	int cnt = 0;
+	int err = 0;
+	struct quota_info *dqopt = sb_dqopt(sb);
+	struct ubifs_info *c = sb->s_fs_info;
+
+	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
+		if (toputinode[cnt]) {
+			struct ubifs_inode *ui = ubifs_inode(toputinode[cnt]);
+			struct ubifs_budget_req req = { .dirtied_ino = 1,
+					.dirtied_ino_d = ALIGN(ui->data_len, 8) };
+			int release = 0;
+
+			/* budget for the inode which need to update */
+			err = ubifs_budget_space(c, &req);
+			if (err)
+				return err;
+
+			mutex_lock(&dqopt->dqonoff_mutex);
+			/* If quota was reenabled in the meantime, we have
+			 * nothing to do */
+			if (!sb_has_quota_loaded(sb, cnt)) {
+				mutex_lock(&toputinode[cnt]->i_mutex);
+				toputinode[cnt]->i_flags &= ~(S_IMMUTABLE |
+				  S_NOATIME | S_NOQUOTA);
+				toputinode[cnt]->i_flags |= old_flags[cnt];
+				truncate_inode_pages(&toputinode[cnt]->i_data,
+						     0);
+				mutex_unlock(&toputinode[cnt]->i_mutex);
+
+				mutex_lock(&ui->ui_mutex);
+				release = ui->dirty;
+				mark_inode_dirty_sync(toputinode[cnt]);
+				mutex_unlock(&ui->ui_mutex);
+			} else {
+				release = 1;
+			}
+			mutex_unlock(&dqopt->dqonoff_mutex);
+			/* Release the budget if we don't need to update the inode */
+			if (release)
+				ubifs_release_budget(c, &req);
+		}
+
+	return 0;
+}
+
+static const struct quotactl_ops ubifs_quotactl_ops = {
+	.quota_on	= dquot_quota_on,
+	.quota_off	= dquot_quota_off,
+	.quota_sync	= dquot_quota_sync,
+	.get_state	= dquot_get_state,
+	.set_info	= dquot_set_dqinfo,
+	.get_dqblk	= dquot_get_dqblk,
+	.set_dqblk	= dquot_set_dqblk,
+	.restore_iflags	= ubifs_restore_iflags
+};
+#endif
+
 static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct ubifs_info *c = sb->s_fs_info;
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 38/39] ubifs: fill the quota related fields in ubifs_fill_super
  2015-09-15  9:01 ` Dongsheng Yang
                   ` (37 preceding siblings ...)
  (?)
@ 2015-09-15  9:02 ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

We are using dquot_operations for sb->dq_op and
ubifs_quotactl_ops for sb->s_qcop.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/super.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 01aaa88..da16c65 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -2302,6 +2302,11 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
 	sb->s_op = &ubifs_super_operations;
 	sb->s_xattr = ubifs_xattr_handlers;
 
+#ifdef CONFIG_QUOTA
+	sb->dq_op = &dquot_operations;
+	sb->s_qcop = &ubifs_quotactl_ops;
+	sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
+#endif
 	mutex_lock(&c->umount_mutex);
 	err = mount_ubifs(c);
 	if (err) {
-- 
1.8.4.2


^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 39/39] ubifs: introduce quota related mount options
  2015-09-15  9:01 ` Dongsheng Yang
@ 2015-09-15  9:02   ` Dongsheng Yang
  -1 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

This commit introduce mount options of quota, noquota,
usrquota and grpquota. These options are used to make
ubifs support quota.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/super.c | 30 ++++++++++++++++++++++++++++++
 fs/ubifs/ubifs.h |  4 ++++
 2 files changed, 34 insertions(+)

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index da16c65..e7e68ee 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -36,6 +36,7 @@
 #include <linux/mount.h>
 #include <linux/math64.h>
 #include <linux/writeback.h>
+#include <linux/quotaops.h>
 #include <linux/cdev.h>
 #include <linux/quotaops.h>
 #include "ubifs.h"
@@ -443,6 +444,12 @@ static int ubifs_show_options(struct seq_file *s, struct dentry *root)
 	else if (c->mount_opts.chk_data_crc == 1)
 		seq_puts(s, ",no_chk_data_crc");
 
+	if (c->usrquota)
+		seq_puts(s, ",usrquota");
+
+	if (c->grpquota)
+		seq_puts(s, ",grpquota");
+
 	if (c->mount_opts.override_compr) {
 		seq_printf(s, ",compr=%s",
 			   ubifs_compr_name(c->mount_opts.compr_type));
@@ -1112,6 +1119,10 @@ enum {
 	Opt_chk_data_crc,
 	Opt_no_chk_data_crc,
 	Opt_override_compr,
+	Opt_ignore,
+	Opt_quota,
+	Opt_usrquota,
+	Opt_grpquota,
 	Opt_err,
 };
 
@@ -1123,6 +1134,10 @@ static const match_table_t tokens = {
 	{Opt_chk_data_crc, "chk_data_crc"},
 	{Opt_no_chk_data_crc, "no_chk_data_crc"},
 	{Opt_override_compr, "compr=%s"},
+	{Opt_ignore, "noquota"},
+	{Opt_quota, "quota"},
+	{Opt_usrquota, "usrquota"},
+	{Opt_grpquota, "grpquota"},
 	{Opt_err, NULL},
 };
 
@@ -1223,6 +1238,21 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options,
 			c->default_compr = c->mount_opts.compr_type;
 			break;
 		}
+#ifdef CONFIG_QUOTA
+		case Opt_quota:
+		case Opt_usrquota:
+			c->usrquota = 1;
+			break;
+		case Opt_grpquota:
+			c->grpquota = 1;
+			break;
+#else
+		case Opt_quota:
+		case Opt_usrquota:
+		case Opt_grpquota:
+			ubifs_err(c, "quota operations not supported");
+			break;
+#endif
 		default:
 		{
 			unsigned long flag;
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 21b5dc0..ef06af7 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -1044,6 +1044,8 @@ struct ubifs_debug_info;
  * @bulk_read: enable bulk-reads
  * @default_compr: default compression algorithm (%UBIFS_COMPR_LZO, etc)
  * @rw_incompat: the media is not R/W compatible
+ * @usrquota: enable usrquota
+ * @grpquota: enable grpquota
  *
  * @tnc_mutex: protects the Tree Node Cache (TNC), @zroot, @cnext, @enext, and
  *             @calc_idx_sz
@@ -1285,6 +1287,8 @@ struct ubifs_info {
 	unsigned int bulk_read:1;
 	unsigned int default_compr:2;
 	unsigned int rw_incompat:1;
+	unsigned int usrquota:1;
+	unsigned int grpquota:1;
 
 	struct mutex tnc_mutex;
 	struct ubifs_zbranch zroot;
-- 
1.8.4.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* [PATCH v3 39/39] ubifs: introduce quota related mount options
@ 2015-09-15  9:02   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-15  9:02 UTC (permalink / raw)
  To: viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel, Dongsheng Yang

This commit introduce mount options of quota, noquota,
usrquota and grpquota. These options are used to make
ubifs support quota.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/super.c | 30 ++++++++++++++++++++++++++++++
 fs/ubifs/ubifs.h |  4 ++++
 2 files changed, 34 insertions(+)

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index da16c65..e7e68ee 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -36,6 +36,7 @@
 #include <linux/mount.h>
 #include <linux/math64.h>
 #include <linux/writeback.h>
+#include <linux/quotaops.h>
 #include <linux/cdev.h>
 #include <linux/quotaops.h>
 #include "ubifs.h"
@@ -443,6 +444,12 @@ static int ubifs_show_options(struct seq_file *s, struct dentry *root)
 	else if (c->mount_opts.chk_data_crc == 1)
 		seq_puts(s, ",no_chk_data_crc");
 
+	if (c->usrquota)
+		seq_puts(s, ",usrquota");
+
+	if (c->grpquota)
+		seq_puts(s, ",grpquota");
+
 	if (c->mount_opts.override_compr) {
 		seq_printf(s, ",compr=%s",
 			   ubifs_compr_name(c->mount_opts.compr_type));
@@ -1112,6 +1119,10 @@ enum {
 	Opt_chk_data_crc,
 	Opt_no_chk_data_crc,
 	Opt_override_compr,
+	Opt_ignore,
+	Opt_quota,
+	Opt_usrquota,
+	Opt_grpquota,
 	Opt_err,
 };
 
@@ -1123,6 +1134,10 @@ static const match_table_t tokens = {
 	{Opt_chk_data_crc, "chk_data_crc"},
 	{Opt_no_chk_data_crc, "no_chk_data_crc"},
 	{Opt_override_compr, "compr=%s"},
+	{Opt_ignore, "noquota"},
+	{Opt_quota, "quota"},
+	{Opt_usrquota, "usrquota"},
+	{Opt_grpquota, "grpquota"},
 	{Opt_err, NULL},
 };
 
@@ -1223,6 +1238,21 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options,
 			c->default_compr = c->mount_opts.compr_type;
 			break;
 		}
+#ifdef CONFIG_QUOTA
+		case Opt_quota:
+		case Opt_usrquota:
+			c->usrquota = 1;
+			break;
+		case Opt_grpquota:
+			c->grpquota = 1;
+			break;
+#else
+		case Opt_quota:
+		case Opt_usrquota:
+		case Opt_grpquota:
+			ubifs_err(c, "quota operations not supported");
+			break;
+#endif
 		default:
 		{
 			unsigned long flag;
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 21b5dc0..ef06af7 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -1044,6 +1044,8 @@ struct ubifs_debug_info;
  * @bulk_read: enable bulk-reads
  * @default_compr: default compression algorithm (%UBIFS_COMPR_LZO, etc)
  * @rw_incompat: the media is not R/W compatible
+ * @usrquota: enable usrquota
+ * @grpquota: enable grpquota
  *
  * @tnc_mutex: protects the Tree Node Cache (TNC), @zroot, @cnext, @enext, and
  *             @calc_idx_sz
@@ -1285,6 +1287,8 @@ struct ubifs_info {
 	unsigned int bulk_read:1;
 	unsigned int default_compr:2;
 	unsigned int rw_incompat:1;
+	unsigned int usrquota:1;
+	unsigned int grpquota:1;
 
 	struct mutex tnc_mutex;
 	struct ubifs_zbranch zroot;
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 28/39] ubifs: record quota information about inode in ubifs_new_inode
  2015-09-15  9:02   ` Dongsheng Yang
  (?)
@ 2015-09-15  9:35   ` Sheng Yong
  2015-09-16  1:46     ` Dongsheng Yang
  -1 siblings, 1 reply; 107+ messages in thread
From: Sheng Yong @ 2015-09-15  9:35 UTC (permalink / raw)
  To: Dongsheng Yang, viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, linux-mtd



On 9/15/2015 5:02 PM, Dongsheng Yang wrote:
> Initialize quota and alloc a inode quota information in
> ubifs_new_inode(). Then quota would be aware of a new
> inode is allocated.
> 
> Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
> ---
>  fs/ubifs/dir.c | 18 ++++++++++++++++--
>  1 file changed, 16 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
> index 4db0ceb..802c6ad 100644
> --- a/fs/ubifs/dir.c
> +++ b/fs/ubifs/dir.c
> @@ -41,6 +41,7 @@
>   */
>  
>  #include "ubifs.h"
> +#include <linux/quotaops.h>
>  
>  /**
>   * inherit_flags - inherit flags of the parent inode.
> @@ -90,6 +91,7 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
>  {
>  	struct inode *inode;
>  	struct ubifs_inode *ui;
> +	int err = 0;
>  
>  	inode = new_inode(c->vfs_sb);
>  	if (!inode)
> @@ -109,6 +111,11 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
>  			 ubifs_current_time(inode);
>  	inode->i_mapping->nrpages = 0;
>  
> +	dquot_initialize(inode);
> +        err = dquot_alloc_inode(inode);
> +        if (err)
> +                goto fail_drop;
> +
Hi, Dongsheng

I got a question here, it seems the inode used for xattr may not be counted in?

thanks,
Sheng
>  	switch (mode & S_IFMT) {
>  	case S_IFREG:
>  		inode->i_mapping->a_ops = &ubifs_file_address_operations;
> @@ -148,8 +155,8 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
>  			spin_unlock(&c->cnt_lock);
>  			ubifs_err(c, "out of inode numbers");
>  			make_bad_inode(inode);
> -			iput(inode);
> -			return ERR_PTR(-EINVAL);
> +			err = -EINVAL;
> +			goto fail_free;
>  		}
>  		ubifs_warn(c, "running out of inode numbers (current %lu, max %u)",
>  			   (unsigned long)c->highest_inum, INUM_WATERMARK);
> @@ -166,6 +173,13 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
>  	ui->creat_sqnum = ++c->max_sqnum;
>  	spin_unlock(&c->cnt_lock);
>  	return inode;
> +
> +fail_free:
> +	dquot_free_inode(inode);
> +fail_drop:
> +	dquot_drop(inode);
> +	iput(inode);
> +	return ERR_PTR(err);
>  }
>  
>  static int dbg_check_name(const struct ubifs_info *c,
> 


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 39/39] ubifs: introduce quota related mount options
  2015-09-15  9:02   ` Dongsheng Yang
  (?)
@ 2015-09-15  9:36   ` Sheng Yong
  2015-09-16  1:48     ` Dongsheng Yang
  -1 siblings, 1 reply; 107+ messages in thread
From: Sheng Yong @ 2015-09-15  9:36 UTC (permalink / raw)
  To: Dongsheng Yang, viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, linux-mtd



On 9/15/2015 5:02 PM, Dongsheng Yang wrote:
> This commit introduce mount options of quota, noquota,
> usrquota and grpquota. These options are used to make
> ubifs support quota.
> 
> Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
> ---
>  fs/ubifs/super.c | 30 ++++++++++++++++++++++++++++++
>  fs/ubifs/ubifs.h |  4 ++++
>  2 files changed, 34 insertions(+)
> 
> diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
> index da16c65..e7e68ee 100644
> --- a/fs/ubifs/super.c
> +++ b/fs/ubifs/super.c
> @@ -36,6 +36,7 @@
>  #include <linux/mount.h>
>  #include <linux/math64.h>
>  #include <linux/writeback.h>
> +#include <linux/quotaops.h>
>  #include <linux/cdev.h>
>  #include <linux/quotaops.h>
>  #include "ubifs.h"
> @@ -443,6 +444,12 @@ static int ubifs_show_options(struct seq_file *s, struct dentry *root)
>  	else if (c->mount_opts.chk_data_crc == 1)
>  		seq_puts(s, ",no_chk_data_crc");
>  
> +	if (c->usrquota)
> +		seq_puts(s, ",usrquota");
> +
> +	if (c->grpquota)
> +		seq_puts(s, ",grpquota");
> +
>  	if (c->mount_opts.override_compr) {
>  		seq_printf(s, ",compr=%s",
>  			   ubifs_compr_name(c->mount_opts.compr_type));
> @@ -1112,6 +1119,10 @@ enum {
>  	Opt_chk_data_crc,
>  	Opt_no_chk_data_crc,
>  	Opt_override_compr,
> +	Opt_ignore,
> +	Opt_quota,
> +	Opt_usrquota,
> +	Opt_grpquota,
>  	Opt_err,
>  };
>  
> @@ -1123,6 +1134,10 @@ static const match_table_t tokens = {
>  	{Opt_chk_data_crc, "chk_data_crc"},
>  	{Opt_no_chk_data_crc, "no_chk_data_crc"},
>  	{Opt_override_compr, "compr=%s"},
> +	{Opt_ignore, "noquota"},
> +	{Opt_quota, "quota"},
> +	{Opt_usrquota, "usrquota"},
> +	{Opt_grpquota, "grpquota"},
>  	{Opt_err, NULL},
>  };
>  
> @@ -1223,6 +1238,21 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options,
>  			c->default_compr = c->mount_opts.compr_type;
>  			break;
>  		}
> +#ifdef CONFIG_QUOTA
> +		case Opt_quota:
> +		case Opt_usrquota:
> +			c->usrquota = 1;
> +			break;
> +		case Opt_grpquota:
> +			c->grpquota = 1;
> +			break;
> +#else
Hi, Dongsheng,

The elseif here can be covered by default :)

thanks,
Sheng
> +		case Opt_quota:
> +		case Opt_usrquota:
> +		case Opt_grpquota:
> +			ubifs_err(c, "quota operations not supported");
> +			break;
> +#endif
>  		default:
>  		{
>  			unsigned long flag;
> diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
> index 21b5dc0..ef06af7 100644
> --- a/fs/ubifs/ubifs.h
> +++ b/fs/ubifs/ubifs.h
> @@ -1044,6 +1044,8 @@ struct ubifs_debug_info;
>   * @bulk_read: enable bulk-reads
>   * @default_compr: default compression algorithm (%UBIFS_COMPR_LZO, etc)
>   * @rw_incompat: the media is not R/W compatible
> + * @usrquota: enable usrquota
> + * @grpquota: enable grpquota
>   *
>   * @tnc_mutex: protects the Tree Node Cache (TNC), @zroot, @cnext, @enext, and
>   *             @calc_idx_sz
> @@ -1285,6 +1287,8 @@ struct ubifs_info {
>  	unsigned int bulk_read:1;
>  	unsigned int default_compr:2;
>  	unsigned int rw_incompat:1;
> +	unsigned int usrquota:1;
> +	unsigned int grpquota:1;
>  
>  	struct mutex tnc_mutex;
>  	struct ubifs_zbranch zroot;
> 


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 06/39] fs: super: introduce a get_super_cdev_thawed to get sb by cdev reference
  2015-09-15  9:02   ` Dongsheng Yang
  (?)
@ 2015-09-15 21:24   ` Jan Kara
  -1 siblings, 0 replies; 107+ messages in thread
From: Jan Kara @ 2015-09-15 21:24 UTC (permalink / raw)
  To: Dongsheng Yang
  Cc: viro, jack, dedekind1, richard.weinberger, linux-mtd, linux-fsdevel

On Tue 15-09-15 17:02:01, Dongsheng Yang wrote:
> This patch refactors the original get_super_thawed to get a common
> helper function of __get_super_thawed. Then take the use of
> __get_super_thawed, we can implement get_super_cdev_thawed easily.
> 
> Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>

The patch looks good to me. You can add:

Reviewed-by: Jan Kara <jack@suse.com>

								Honza

> ---
>  fs/super.c         | 29 +++++++++++++++++++++++++----
>  include/linux/fs.h |  1 +
>  2 files changed, 26 insertions(+), 4 deletions(-)
> 
> diff --git a/fs/super.c b/fs/super.c
> index 321d16b..df32393 100644
> --- a/fs/super.c
> +++ b/fs/super.c
> @@ -629,18 +629,20 @@ struct super_block *get_super_cdev(struct cdev *cdev)
>  EXPORT_SYMBOL(get_super_cdev);
>  
>  /**
> - * get_super_thawed - get thawed superblock of a device
> - * @bdev: device to get the superblock for
> + * __get_super_thawed - get thawed superblock
> + * @func: function pointer to get superblock by key
> + * @key: key to find superblock
>   *
>   * Scans the superblock list and finds the superblock of the file system
>   * mounted on the device. The superblock is returned once it is thawed
>   * (or immediately if it was not frozen). %NULL is returned if no match
>   * is found.
>   */
> -struct super_block *get_super_thawed(struct block_device *bdev)
> +static struct super_block *__get_super_thawed(
> +		int (*compare)(struct super_block *, void *), void *key)
>  {
>  	while (1) {
> -		struct super_block *s = get_super(bdev);
> +		struct super_block *s = __get_super(compare, key);
>  		if (!s || s->s_writers.frozen == SB_UNFROZEN)
>  			return s;
>  		up_read(&s->s_umount);
> @@ -649,9 +651,28 @@ struct super_block *get_super_thawed(struct block_device *bdev)
>  		put_super(s);
>  	}
>  }
> +
> +/**
> + * get_super_thawed - get thawed superblock of a device
> + * @bdev: device to get the superblock for
> + */
> +struct super_block *get_super_thawed(struct block_device *bdev)
> +{
> +	return __get_super_thawed(bdev_compare, bdev);
> +}
>  EXPORT_SYMBOL(get_super_thawed);
>  
>  /**
> + * get_super_cdev_thawed - get thawed superblock of a char device
> + * @cdev: device to get the superblock for
> + */
> +struct super_block *get_super_cdev_thawed(struct cdev *cdev)
> +{
> +	return __get_super_thawed(cdev_compare, cdev);
> +}
> +EXPORT_SYMBOL(get_super_cdev_thawed);
> +
> +/**
>   * get_active_super - get an active reference to the superblock of a device
>   * @bdev: device to get the superblock for
>   *
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index df71cbb..2c1c122 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -2798,6 +2798,7 @@ extern struct file_system_type *get_fs_type(const char *name);
>  extern struct super_block *get_super(struct block_device *);
>  extern struct super_block *get_super_cdev(struct cdev *);
>  extern struct super_block *get_super_thawed(struct block_device *);
> +extern struct super_block *get_super_cdev_thawed(struct cdev *);
>  extern struct super_block *get_active_super(struct block_device *bdev);
>  extern void drop_super(struct super_block *sb);
>  extern void iterate_supers(void (*)(struct super_block *, void *), void *);
> -- 
> 1.8.4.2
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 28/39] ubifs: record quota information about inode in ubifs_new_inode
  2015-09-15  9:35   ` Sheng Yong
@ 2015-09-16  1:46     ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-16  1:46 UTC (permalink / raw)
  To: Sheng Yong, viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, linux-mtd

On 09/15/2015 05:35 PM, Sheng Yong wrote:
>
>
> On 9/15/2015 5:02 PM, Dongsheng Yang wrote:
>> Initialize quota and alloc a inode quota information in
>> ubifs_new_inode(). Then quota would be aware of a new
>> inode is allocated.
>>
>> Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
>> ---
>>   fs/ubifs/dir.c | 18 ++++++++++++++++--
>>   1 file changed, 16 insertions(+), 2 deletions(-)
>>
>> diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
>> index 4db0ceb..802c6ad 100644
>> --- a/fs/ubifs/dir.c
>> +++ b/fs/ubifs/dir.c
>> @@ -41,6 +41,7 @@
>>    */
>>
>>   #include "ubifs.h"
>> +#include <linux/quotaops.h>
>>
>>   /**
>>    * inherit_flags - inherit flags of the parent inode.
>> @@ -90,6 +91,7 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
>>   {
>>   	struct inode *inode;
>>   	struct ubifs_inode *ui;
>> +	int err = 0;
>>
>>   	inode = new_inode(c->vfs_sb);
>>   	if (!inode)
>> @@ -109,6 +111,11 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
>>   			 ubifs_current_time(inode);
>>   	inode->i_mapping->nrpages = 0;
>>
>> +	dquot_initialize(inode);
>> +        err = dquot_alloc_inode(inode);
>> +        if (err)
>> +                goto fail_drop;
>> +
> Hi, Dongsheng
>
> I got a question here, it seems the inode used for xattr may not be counted in?

Yes, that's intentional. inodes for xattr is not available to user. So I
think we should not count it in quota.

Yang
>
> thanks,
> Sheng
>>   	switch (mode & S_IFMT) {
>>   	case S_IFREG:
>>   		inode->i_mapping->a_ops = &ubifs_file_address_operations;
>> @@ -148,8 +155,8 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
>>   			spin_unlock(&c->cnt_lock);
>>   			ubifs_err(c, "out of inode numbers");
>>   			make_bad_inode(inode);
>> -			iput(inode);
>> -			return ERR_PTR(-EINVAL);
>> +			err = -EINVAL;
>> +			goto fail_free;
>>   		}
>>   		ubifs_warn(c, "running out of inode numbers (current %lu, max %u)",
>>   			   (unsigned long)c->highest_inum, INUM_WATERMARK);
>> @@ -166,6 +173,13 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
>>   	ui->creat_sqnum = ++c->max_sqnum;
>>   	spin_unlock(&c->cnt_lock);
>>   	return inode;
>> +
>> +fail_free:
>> +	dquot_free_inode(inode);
>> +fail_drop:
>> +	dquot_drop(inode);
>> +	iput(inode);
>> +	return ERR_PTR(err);
>>   }
>>
>>   static int dbg_check_name(const struct ubifs_info *c,
>>
>
> .
>


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 39/39] ubifs: introduce quota related mount options
  2015-09-15  9:36   ` Sheng Yong
@ 2015-09-16  1:48     ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-16  1:48 UTC (permalink / raw)
  To: Sheng Yong, viro, jack, dedekind1, richard.weinberger
  Cc: linux-fsdevel, linux-mtd

On 09/15/2015 05:36 PM, Sheng Yong wrote:
>
>
> On 9/15/2015 5:02 PM, Dongsheng Yang wrote:
>> This commit introduce mount options of quota, noquota,
>> usrquota and grpquota. These options are used to make
>> ubifs support quota.
>>
>> Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
>> ---
>>   fs/ubifs/super.c | 30 ++++++++++++++++++++++++++++++
>>   fs/ubifs/ubifs.h |  4 ++++
>>   2 files changed, 34 insertions(+)
>>
>> diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
>> index da16c65..e7e68ee 100644
>> --- a/fs/ubifs/super.c
>> +++ b/fs/ubifs/super.c
>> @@ -36,6 +36,7 @@
>>   #include <linux/mount.h>
>>   #include <linux/math64.h>
>>   #include <linux/writeback.h>
>> +#include <linux/quotaops.h>
>>   #include <linux/cdev.h>
>>   #include <linux/quotaops.h>
>>   #include "ubifs.h"
>> @@ -443,6 +444,12 @@ static int ubifs_show_options(struct seq_file *s, struct dentry *root)
>>   	else if (c->mount_opts.chk_data_crc == 1)
>>   		seq_puts(s, ",no_chk_data_crc");
>>
>> +	if (c->usrquota)
>> +		seq_puts(s, ",usrquota");
>> +
>> +	if (c->grpquota)
>> +		seq_puts(s, ",grpquota");
>> +
>>   	if (c->mount_opts.override_compr) {
>>   		seq_printf(s, ",compr=%s",
>>   			   ubifs_compr_name(c->mount_opts.compr_type));
>> @@ -1112,6 +1119,10 @@ enum {
>>   	Opt_chk_data_crc,
>>   	Opt_no_chk_data_crc,
>>   	Opt_override_compr,
>> +	Opt_ignore,
>> +	Opt_quota,
>> +	Opt_usrquota,
>> +	Opt_grpquota,
>>   	Opt_err,
>>   };
>>
>> @@ -1123,6 +1134,10 @@ static const match_table_t tokens = {
>>   	{Opt_chk_data_crc, "chk_data_crc"},
>>   	{Opt_no_chk_data_crc, "no_chk_data_crc"},
>>   	{Opt_override_compr, "compr=%s"},
>> +	{Opt_ignore, "noquota"},
>> +	{Opt_quota, "quota"},
>> +	{Opt_usrquota, "usrquota"},
>> +	{Opt_grpquota, "grpquota"},
>>   	{Opt_err, NULL},
>>   };
>>
>> @@ -1223,6 +1238,21 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options,
>>   			c->default_compr = c->mount_opts.compr_type;
>>   			break;
>>   		}
>> +#ifdef CONFIG_QUOTA
>> +		case Opt_quota:
>> +		case Opt_usrquota:
>> +			c->usrquota = 1;
>> +			break;
>> +		case Opt_grpquota:
>> +			c->grpquota = 1;
>> +			break;
>> +#else
> Hi, Dongsheng,
>
> The elseif here can be covered by default :)

Yes, default will do that. will update it in next version.

Thanx
Yang
>
> thanks,
> Sheng
>> +		case Opt_quota:
>> +		case Opt_usrquota:
>> +		case Opt_grpquota:
>> +			ubifs_err(c, "quota operations not supported");
>> +			break;
>> +#endif
>>   		default:
>>   		{
>>   			unsigned long flag;
>> diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
>> index 21b5dc0..ef06af7 100644
>> --- a/fs/ubifs/ubifs.h
>> +++ b/fs/ubifs/ubifs.h
>> @@ -1044,6 +1044,8 @@ struct ubifs_debug_info;
>>    * @bulk_read: enable bulk-reads
>>    * @default_compr: default compression algorithm (%UBIFS_COMPR_LZO, etc)
>>    * @rw_incompat: the media is not R/W compatible
>> + * @usrquota: enable usrquota
>> + * @grpquota: enable grpquota
>>    *
>>    * @tnc_mutex: protects the Tree Node Cache (TNC), @zroot, @cnext, @enext, and
>>    *             @calc_idx_sz
>> @@ -1285,6 +1287,8 @@ struct ubifs_info {
>>   	unsigned int bulk_read:1;
>>   	unsigned int default_compr:2;
>>   	unsigned int rw_incompat:1;
>> +	unsigned int usrquota:1;
>> +	unsigned int grpquota:1;
>>
>>   	struct mutex tnc_mutex;
>>   	struct ubifs_zbranch zroot;
>>
>
> .
>


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 07/39] fs: char_dev: introduce cd_acquire function to acquire cdev
  2015-09-15  9:02   ` Dongsheng Yang
  (?)
@ 2015-09-16  8:16   ` Jan Kara
  2015-09-17  3:30     ` Dongsheng Yang
  -1 siblings, 1 reply; 107+ messages in thread
From: Jan Kara @ 2015-09-16  8:16 UTC (permalink / raw)
  To: Dongsheng Yang
  Cc: viro, jack, dedekind1, richard.weinberger, linux-mtd, linux-fsdevel

On Tue 15-09-15 17:02:02, Dongsheng Yang wrote:
> cd_acquire() works like bd_acquire() to get cdev by an inode,
> this commit is a preparation for lookup_cdev().
> 
> Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>

Two comments below.

> ---
>  fs/char_dev.c | 35 +++++++++++++++++++++++++++++++++++
>  1 file changed, 35 insertions(+)
> 
> diff --git a/fs/char_dev.c b/fs/char_dev.c
> index ea06a3d..e818faa 100644
> --- a/fs/char_dev.c
> +++ b/fs/char_dev.c
> @@ -439,6 +439,41 @@ static int exact_lock(dev_t dev, void *data)
>  	return cdev_get(p) ? 0 : -1;
>  }
>  
> +struct cdev *cd_acquire(struct inode *inode)
> +{
> +	struct cdev *cdev;
> +	struct cdev *new = NULL;
> +
> +	spin_lock(&cdev_lock);
> +	cdev = inode->i_cdev;
> +	if (!cdev) {
> +		struct kobject *kobj;
> +		int idx;

Empty line here please to separate variable declarations from the code.

> +		spin_unlock(&cdev_lock);
> +		kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx);
> +		if (!kobj) {
> +			cdev = NULL;
> +			goto out;
> +		}
> +		new = container_of(kobj, struct cdev, kobj);
> +		spin_lock(&cdev_lock);
> +		/* Check i_cdev again in case somebody beat us to it while
> +		   we dropped the lock. */
> +		cdev = inode->i_cdev;
> +		if (!cdev) {
> +			inode->i_cdev = cdev = new;
> +			list_add(&inode->i_devices, &cdev->list);
> +		}

I think you need to put 'new' in case you didn't use it, don't you?

> +	}
> +
> +	if (!cdev_get(cdev))
> +		cdev = NULL;
> +	spin_unlock(&cdev_lock);
> +
> +out:
> +	return cdev;
> +}
> +
>  /**
>   * cdev_add() - add a char device to the system
>   * @p: the cdev structure for the device

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 15/39] fs: quota: introduce a callback of restore_iflags to quotactl_ops
  2015-09-15  9:02   ` Dongsheng Yang
  (?)
@ 2015-09-16  9:47   ` Jan Kara
  -1 siblings, 0 replies; 107+ messages in thread
From: Jan Kara @ 2015-09-16  9:47 UTC (permalink / raw)
  To: Dongsheng Yang
  Cc: viro, jack, dedekind1, richard.weinberger, linux-mtd, linux-fsdevel

On Tue 15-09-15 17:02:10, Dongsheng Yang wrote:
> In dquot_disable, we need to restore the iflags of quota files
> and mark the inodes to dirty. But that's pain to file-systems
> working in out-place-updating way, such as btrfs and ubifs. when
> they are going to update inode, they have to reserve space for
> this inode.
> 
> So we can not mark_inode_dirty() in dquot_disable for them. To solve
> this kind of problem, the common solution is introduce a callback
> to allow file-systems to do the inode_dirty work by themselves,
> the similar way with update_time().
> 
> Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>

So do you have a good reason to have quota files accessible from userspace?
Because the experience with ext2/3/4 which did this originally taught me it
is a pain in the ass. It is easier to have quota data stored in dedicated
system inodes which are invisible from userspace (ext4 can do it this way,
xfs, ocfs2, gfs2 as well). Then you don't have to bother with flushing
quota files, switching inode bits etc. when enabling / disabling quotas.
Also it makes more sense logically since quota information is really a part
of filesystem metadata.

The only larger disadvantage is that you have to have support for handling
quota files in mkfs and fsck. But in the long run the additional work is
worth it.

								Honza
> ---
>  fs/quota/dquot.c      | 51 ++++++++++++++++++++++++++++++++++-----------------
>  include/linux/quota.h |  4 ++++
>  2 files changed, 38 insertions(+), 17 deletions(-)
> 
> diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
> index c73f44d..3f08e69 100644
> --- a/fs/quota/dquot.c
> +++ b/fs/quota/dquot.c
> @@ -2020,6 +2020,33 @@ int dquot_file_open(struct inode *inode, struct file *file)
>  }
>  EXPORT_SYMBOL(dquot_file_open);
>  
> +static int generic_restore_iflags(struct super_block *sb, struct inode **toputinode,
> +					unsigned int *old_flags)
> +{
> +	int cnt = 0;
> +	struct quota_info *dqopt = sb_dqopt(sb);
> +
> +	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
> +		if (toputinode[cnt]) {
> +			mutex_lock(&dqopt->dqonoff_mutex);
> +			/* If quota was reenabled in the meantime, we have
> +			 * nothing to do */
> +			if (!sb_has_quota_loaded(sb, cnt)) {
> +				mutex_lock(&toputinode[cnt]->i_mutex);
> +				toputinode[cnt]->i_flags &= ~(S_IMMUTABLE |
> +				  S_NOATIME | S_NOQUOTA);
> +				toputinode[cnt]->i_flags |= old_flags[cnt];
> +				truncate_inode_pages(&toputinode[cnt]->i_data,
> +						     0);
> +				mutex_unlock(&toputinode[cnt]->i_mutex);
> +				mark_inode_dirty_sync(toputinode[cnt]);
> +			}
> +			mutex_unlock(&dqopt->dqonoff_mutex);
> +		}
> +
> +	return 0;
> +}
> +
>  /*
>   * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount)
>   */
> @@ -2028,6 +2055,7 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
>  	int cnt, ret = 0;
>  	struct quota_info *dqopt = sb_dqopt(sb);
>  	struct inode *toputinode[MAXQUOTAS];
> +	unsigned int *old_flags = dqopt->old_flags;
>  
>  	/* Cannot turn off usage accounting without turning off limits, or
>  	 * suspend quotas and simultaneously turn quotas off. */
> @@ -2111,28 +2139,17 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
>  	 * disk (and so userspace sees correct data afterwards). */
>  	sync_filesystem(sb);
>  	sync_blockdev(sb->s_bdev);
> +
>  	/* Now the quota files are just ordinary files and we can set the
>  	 * inode flags back. Moreover we discard the pagecache so that
>  	 * userspace sees the writes we did bypassing the pagecache. We
>  	 * must also discard the blockdev buffers so that we see the
>  	 * changes done by userspace on the next quotaon() */
> -	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
> -		if (toputinode[cnt]) {
> -			mutex_lock(&dqopt->dqonoff_mutex);
> -			/* If quota was reenabled in the meantime, we have
> -			 * nothing to do */
> -			if (!sb_has_quota_loaded(sb, cnt)) {
> -				mutex_lock(&toputinode[cnt]->i_mutex);
> -				toputinode[cnt]->i_flags &= ~(S_IMMUTABLE |
> -				  S_NOATIME | S_NOQUOTA);
> -				toputinode[cnt]->i_flags |= dqopt->old_flags[cnt];
> -				truncate_inode_pages(&toputinode[cnt]->i_data,
> -						     0);
> -				mutex_unlock(&toputinode[cnt]->i_mutex);
> -				mark_inode_dirty_sync(toputinode[cnt]);
> -			}
> -			mutex_unlock(&dqopt->dqonoff_mutex);
> -		}
> +	if (sb->s_qcop->restore_iflags)
> +		ret = sb->s_qcop->restore_iflags(sb, toputinode, old_flags);
> +	else
> +		ret = generic_restore_iflags(sb, toputinode, old_flags);
> +
>  	if (sb->s_bdev)
>  		invalidate_bdev(sb->s_bdev);
>  put_inodes:
> diff --git a/include/linux/quota.h b/include/linux/quota.h
> index fcfee5a..64e52e4 100644
> --- a/include/linux/quota.h
> +++ b/include/linux/quota.h
> @@ -428,6 +428,10 @@ struct quotactl_ops {
>  	int (*set_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *);
>  	int (*get_state)(struct super_block *, struct qc_state *);
>  	int (*rm_xquota)(struct super_block *, unsigned int);
> +	/*
> +	 * used in quota_disable to restore the i_flags of quota files.
> +	 */
> +	int (*restore_iflags)(struct super_block *sb, struct inode **, unsigned int *);
>  };
>  
>  struct quota_format_type {
> -- 
> 1.8.4.2
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 36/39] ubifs: implement ubifs_get_qsize to get quota size in ubifs
  2015-09-15  9:02 ` [PATCH v3 36/39] ubifs: implement ubifs_get_qsize to get quota size in ubifs Dongsheng Yang
@ 2015-09-16 10:00   ` Jan Kara
  2015-09-17  7:23       ` Dongsheng Yang
  0 siblings, 1 reply; 107+ messages in thread
From: Jan Kara @ 2015-09-16 10:00 UTC (permalink / raw)
  To: Dongsheng Yang
  Cc: viro, jack, dedekind1, richard.weinberger, linux-mtd, linux-fsdevel

On Tue 15-09-15 17:02:31, Dongsheng Yang wrote:
> We only care the size of regular file in ubifs for quota.
> The reason is similar with the comment in ubifs_getattr().
> 
> Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
> ---
>  fs/ubifs/dir.c   |  3 +++
>  fs/ubifs/file.c  | 22 ++++++++++++++++++++++
>  fs/ubifs/ubifs.h |  1 +
>  3 files changed, 26 insertions(+)
> 
> diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
> index 802c6ad..0d3d6d3 100644
> --- a/fs/ubifs/dir.c
> +++ b/fs/ubifs/dir.c
> @@ -1205,6 +1205,9 @@ const struct inode_operations ubifs_dir_inode_operations = {
>  #ifdef CONFIG_UBIFS_ATIME_SUPPORT
>  	.update_time = ubifs_update_time,
>  #endif
> +#ifdef CONFIG_QUOTA
> +	.get_qsize	= ubifs_get_qsize,
> +#endif
>  };
>  
>  const struct file_operations ubifs_dir_operations = {
> diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
> index b57ccf3..f1d792a 100644
> --- a/fs/ubifs/file.c
> +++ b/fs/ubifs/file.c
> @@ -1636,6 +1636,22 @@ static int ubifs_file_mmap(struct file *file, struct vm_area_struct *vma)
>  	return 0;
>  }
>  
> +/*
> + * ubifs_get_qsize: get the quota size of a file
> + * @inode: inode which we are going to get the qsize
> + *
> + * We only care the size of regular file in ubifs
> + * for quota. The reason is similar with the comment
> + * in ubifs_getattr().
> + */
> +ssize_t ubifs_get_qsize(struct inode *inode)
> +{
> +	if (S_ISREG(inode->i_mode))
> +		return i_size_read(inode);
> +	else
> +		return 0;
> +}
> +

The quota space is accounted in bytes. So why don't you store appropriate
number of bytes the file consumes in i_blocks / i_bytes? Reiserfs can also
have files occupying only say 100 bytes and everything works properly
there so I don't see why ubifs needs to differ.

								Honza

>  const struct address_space_operations ubifs_file_address_operations = {
>  	.readpage       = ubifs_readpage,
>  	.writepage      = ubifs_writepage,
> @@ -1656,6 +1672,9 @@ const struct inode_operations ubifs_file_inode_operations = {
>  #ifdef CONFIG_UBIFS_ATIME_SUPPORT
>  	.update_time = ubifs_update_time,
>  #endif
> +#ifdef CONFIG_QUOTA
> +	.get_qsize	= ubifs_get_qsize,
> +#endif
>  };
>  
>  const struct inode_operations ubifs_symlink_inode_operations = {
> @@ -1670,6 +1689,9 @@ const struct inode_operations ubifs_symlink_inode_operations = {
>  #ifdef CONFIG_UBIFS_ATIME_SUPPORT
>  	.update_time = ubifs_update_time,
>  #endif
> +#ifdef CONFIG_QUOTA
> +	.get_qsize	= ubifs_get_qsize,
> +#endif
>  };
>  
>  const struct file_operations ubifs_file_operations = {
> diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
> index 99cf10c..21b5dc0 100644
> --- a/fs/ubifs/ubifs.h
> +++ b/fs/ubifs/ubifs.h
> @@ -1759,6 +1759,7 @@ int ubifs_read_block(struct inode *inode, void *addr, unsigned int block,
>  int ubifs_fsync(struct file *file, loff_t start, loff_t end, int datasync);
>  int ubifs_setattr(struct dentry *dentry, struct iattr *attr);
>  int ubifs_update_time(struct inode *inode, struct timespec *time, int flags);
> +ssize_t ubifs_get_qsize(struct inode *inode);
>  
>  /* dir.c */
>  struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
> -- 
> 1.8.4.2
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 11/39] fs: quota: replace opened calling of ->sync_fs with sync_filesystem
  2015-09-15  9:02   ` Dongsheng Yang
  (?)
@ 2015-09-16 10:14   ` Jan Kara
  2015-09-17  6:28       ` Dongsheng Yang
  -1 siblings, 1 reply; 107+ messages in thread
From: Jan Kara @ 2015-09-16 10:14 UTC (permalink / raw)
  To: Dongsheng Yang
  Cc: viro, jack, dedekind1, richard.weinberger, linux-mtd, linux-fsdevel

On Tue 15-09-15 17:02:06, Dongsheng Yang wrote:
> There are only two places in whole kernel to call ->sync_fs directly. It
> will sync fs even in read-only mode. It's not a good idea and some filesystem
> would warn out if you are syncing in read-only mode. But sync_filesystem()
> does filter this case out. Let's call sync_filesystem() here instead.
> 
> Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>

So I'd prefer ubifs used hidden system inodes for quota files, set
DQUOT_QUOTA_SYS_FILE flag and so this code calling sync_fs() could be
completely avoided.

I don't like calling sync_filesystem() from quota code. Mainly, it does
much more work than ->sync_fs() for most filesystems (it flushes all files
to disk). Just adding a check for read-only filesystem would look better to
me.

									Honza
> ---
>  fs/quota/dquot.c | 8 +++-----
>  1 file changed, 3 insertions(+), 5 deletions(-)
> 
> diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
> index 140397a..0bda7fa 100644
> --- a/fs/quota/dquot.c
> +++ b/fs/quota/dquot.c
> @@ -668,8 +668,7 @@ int dquot_quota_sync(struct super_block *sb, int type)
>  	/* This is not very clever (and fast) but currently I don't know about
>  	 * any other simple way of getting quota data to disk and we must get
>  	 * them there for userspace to be visible... */
> -	if (sb->s_op->sync_fs)
> -		sb->s_op->sync_fs(sb, 1);
> +	sync_filesystem(sb);
>  	sync_blockdev(sb->s_bdev);
>  
>  	/*
> @@ -2043,7 +2042,7 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
>  	/*
>  	 * Skip everything if there's nothing to do. We have to do this because
>  	 * sometimes we are called when fill_super() failed and calling
> -	 * sync_fs() in such cases does no good.
> +	 * sync_filesystem() in such cases does no good.
>  	 */
>  	if (!sb_any_quota_loaded(sb)) {
>  		mutex_unlock(&dqopt->dqonoff_mutex);
> @@ -2110,8 +2109,7 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
>  
>  	/* Sync the superblock so that buffers with quota data are written to
>  	 * disk (and so userspace sees correct data afterwards). */
> -	if (sb->s_op->sync_fs)
> -		sb->s_op->sync_fs(sb, 1);
> +	sync_filesystem(sb);
>  	sync_blockdev(sb->s_bdev);
>  	/* Now the quota files are just ordinary files and we can set the
>  	 * inode flags back. Moreover we discard the pagecache so that
> -- 
> 1.8.4.2
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 07/39] fs: char_dev: introduce cd_acquire function to acquire cdev
  2015-09-16  8:16   ` Jan Kara
@ 2015-09-17  3:30     ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-17  3:30 UTC (permalink / raw)
  To: Jan Kara; +Cc: viro, dedekind1, richard.weinberger, linux-mtd, linux-fsdevel

On 09/16/2015 04:16 PM, Jan Kara wrote:
> On Tue 15-09-15 17:02:02, Dongsheng Yang wrote:
>> cd_acquire() works like bd_acquire() to get cdev by an inode,
>> this commit is a preparation for lookup_cdev().
>>
>> Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
>
> Two comments below.
>
>> ---
>>   fs/char_dev.c | 35 +++++++++++++++++++++++++++++++++++
>>   1 file changed, 35 insertions(+)
>>
>> diff --git a/fs/char_dev.c b/fs/char_dev.c
>> index ea06a3d..e818faa 100644
>> --- a/fs/char_dev.c
>> +++ b/fs/char_dev.c
>> @@ -439,6 +439,41 @@ static int exact_lock(dev_t dev, void *data)
>>   	return cdev_get(p) ? 0 : -1;
>>   }
>>
>> +struct cdev *cd_acquire(struct inode *inode)
>> +{
>> +	struct cdev *cdev;
>> +	struct cdev *new = NULL;
>> +
>> +	spin_lock(&cdev_lock);
>> +	cdev = inode->i_cdev;
>> +	if (!cdev) {
>> +		struct kobject *kobj;
>> +		int idx;
>
> Empty line here please to separate variable declarations from the code.

Yes,
>
>> +		spin_unlock(&cdev_lock);
>> +		kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx);
>> +		if (!kobj) {
>> +			cdev = NULL;
>> +			goto out;
>> +		}
>> +		new = container_of(kobj, struct cdev, kobj);
>> +		spin_lock(&cdev_lock);
>> +		/* Check i_cdev again in case somebody beat us to it while
>> +		   we dropped the lock. */
>> +		cdev = inode->i_cdev;
>> +		if (!cdev) {
>> +			inode->i_cdev = cdev = new;
>> +			list_add(&inode->i_devices, &cdev->list);
>> +		}
>
> I think you need to put 'new' in case you didn't use it, don't you?

Oh, yes, I forgot it. will update it.

Thanx
Yang
>
>> +	}
>> +
>> +	if (!cdev_get(cdev))
>> +		cdev = NULL;
>> +	spin_unlock(&cdev_lock);
>> +
>> +out:
>> +	return cdev;
>> +}
>> +
>>   /**
>>    * cdev_add() - add a char device to the system
>>    * @p: the cdev structure for the device
>
> 								Honza
>


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 11/39] fs: quota: replace opened calling of ->sync_fs with sync_filesystem
  2015-09-16 10:14   ` Jan Kara
@ 2015-09-17  6:28       ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-17  6:28 UTC (permalink / raw)
  To: Jan Kara; +Cc: richard.weinberger, linux-fsdevel, linux-mtd, viro, dedekind1

On 09/16/2015 06:14 PM, Jan Kara wrote:
> On Tue 15-09-15 17:02:06, Dongsheng Yang wrote:
>> There are only two places in whole kernel to call ->sync_fs directly. It
>> will sync fs even in read-only mode. It's not a good idea and some filesystem
>> would warn out if you are syncing in read-only mode. But sync_filesystem()
>> does filter this case out. Let's call sync_filesystem() here instead.
>>
>> Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
>
> So I'd prefer ubifs used hidden system inodes for quota files, set
> DQUOT_QUOTA_SYS_FILE flag and so this code calling sync_fs() could be
> completely avoided.

Hmmm, I think it's a good idea to make quota files SYS_FILEs. But how
about quota-tools? E.g, if quotacheck do some modification
on quota files, we would not read them without a sync_fs().

Could you help explain how quota works in this case?
>
> I don't like calling sync_filesystem() from quota code. Mainly, it does
> much more work than ->sync_fs() for most filesystems (it flushes all files
> to disk). Just adding a check for read-only filesystem would look better to
> me.

Okey, I will add a read-only check here.

Thanx
Yang
>
> 									Honza
>> ---
>>   fs/quota/dquot.c | 8 +++-----
>>   1 file changed, 3 insertions(+), 5 deletions(-)
>>
>> diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
>> index 140397a..0bda7fa 100644
>> --- a/fs/quota/dquot.c
>> +++ b/fs/quota/dquot.c
>> @@ -668,8 +668,7 @@ int dquot_quota_sync(struct super_block *sb, int type)
>>   	/* This is not very clever (and fast) but currently I don't know about
>>   	 * any other simple way of getting quota data to disk and we must get
>>   	 * them there for userspace to be visible... */
>> -	if (sb->s_op->sync_fs)
>> -		sb->s_op->sync_fs(sb, 1);
>> +	sync_filesystem(sb);
>>   	sync_blockdev(sb->s_bdev);
>>
>>   	/*
>> @@ -2043,7 +2042,7 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
>>   	/*
>>   	 * Skip everything if there's nothing to do. We have to do this because
>>   	 * sometimes we are called when fill_super() failed and calling
>> -	 * sync_fs() in such cases does no good.
>> +	 * sync_filesystem() in such cases does no good.
>>   	 */
>>   	if (!sb_any_quota_loaded(sb)) {
>>   		mutex_unlock(&dqopt->dqonoff_mutex);
>> @@ -2110,8 +2109,7 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
>>
>>   	/* Sync the superblock so that buffers with quota data are written to
>>   	 * disk (and so userspace sees correct data afterwards). */
>> -	if (sb->s_op->sync_fs)
>> -		sb->s_op->sync_fs(sb, 1);
>> +	sync_filesystem(sb);
>>   	sync_blockdev(sb->s_bdev);
>>   	/* Now the quota files are just ordinary files and we can set the
>>   	 * inode flags back. Moreover we discard the pagecache so that
>> --
>> 1.8.4.2
>>


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 11/39] fs: quota: replace opened calling of ->sync_fs with sync_filesystem
@ 2015-09-17  6:28       ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-17  6:28 UTC (permalink / raw)
  To: Jan Kara; +Cc: viro, dedekind1, richard.weinberger, linux-mtd, linux-fsdevel

On 09/16/2015 06:14 PM, Jan Kara wrote:
> On Tue 15-09-15 17:02:06, Dongsheng Yang wrote:
>> There are only two places in whole kernel to call ->sync_fs directly. It
>> will sync fs even in read-only mode. It's not a good idea and some filesystem
>> would warn out if you are syncing in read-only mode. But sync_filesystem()
>> does filter this case out. Let's call sync_filesystem() here instead.
>>
>> Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
>
> So I'd prefer ubifs used hidden system inodes for quota files, set
> DQUOT_QUOTA_SYS_FILE flag and so this code calling sync_fs() could be
> completely avoided.

Hmmm, I think it's a good idea to make quota files SYS_FILEs. But how
about quota-tools? E.g, if quotacheck do some modification
on quota files, we would not read them without a sync_fs().

Could you help explain how quota works in this case?
>
> I don't like calling sync_filesystem() from quota code. Mainly, it does
> much more work than ->sync_fs() for most filesystems (it flushes all files
> to disk). Just adding a check for read-only filesystem would look better to
> me.

Okey, I will add a read-only check here.

Thanx
Yang
>
> 									Honza
>> ---
>>   fs/quota/dquot.c | 8 +++-----
>>   1 file changed, 3 insertions(+), 5 deletions(-)
>>
>> diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
>> index 140397a..0bda7fa 100644
>> --- a/fs/quota/dquot.c
>> +++ b/fs/quota/dquot.c
>> @@ -668,8 +668,7 @@ int dquot_quota_sync(struct super_block *sb, int type)
>>   	/* This is not very clever (and fast) but currently I don't know about
>>   	 * any other simple way of getting quota data to disk and we must get
>>   	 * them there for userspace to be visible... */
>> -	if (sb->s_op->sync_fs)
>> -		sb->s_op->sync_fs(sb, 1);
>> +	sync_filesystem(sb);
>>   	sync_blockdev(sb->s_bdev);
>>
>>   	/*
>> @@ -2043,7 +2042,7 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
>>   	/*
>>   	 * Skip everything if there's nothing to do. We have to do this because
>>   	 * sometimes we are called when fill_super() failed and calling
>> -	 * sync_fs() in such cases does no good.
>> +	 * sync_filesystem() in such cases does no good.
>>   	 */
>>   	if (!sb_any_quota_loaded(sb)) {
>>   		mutex_unlock(&dqopt->dqonoff_mutex);
>> @@ -2110,8 +2109,7 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
>>
>>   	/* Sync the superblock so that buffers with quota data are written to
>>   	 * disk (and so userspace sees correct data afterwards). */
>> -	if (sb->s_op->sync_fs)
>> -		sb->s_op->sync_fs(sb, 1);
>> +	sync_filesystem(sb);
>>   	sync_blockdev(sb->s_bdev);
>>   	/* Now the quota files are just ordinary files and we can set the
>>   	 * inode flags back. Moreover we discard the pagecache so that
>> --
>> 1.8.4.2
>>

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 36/39] ubifs: implement ubifs_get_qsize to get quota size in ubifs
  2015-09-16 10:00   ` Jan Kara
@ 2015-09-17  7:23       ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-17  7:23 UTC (permalink / raw)
  To: Jan Kara; +Cc: richard.weinberger, linux-fsdevel, linux-mtd, viro, dedekind1

On 09/16/2015 06:00 PM, Jan Kara wrote:
> On Tue 15-09-15 17:02:31, Dongsheng Yang wrote:
>> We only care the size of regular file in ubifs for quota.
>> The reason is similar with the comment in ubifs_getattr().
>>
>> Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
>> ---
>>   fs/ubifs/dir.c   |  3 +++
>>   fs/ubifs/file.c  | 22 ++++++++++++++++++++++
>>   fs/ubifs/ubifs.h |  1 +
>>   3 files changed, 26 insertions(+)
>>
>> diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
>> index 802c6ad..0d3d6d3 100644
>> --- a/fs/ubifs/dir.c
>> +++ b/fs/ubifs/dir.c
>> @@ -1205,6 +1205,9 @@ const struct inode_operations ubifs_dir_inode_operations = {
>>   #ifdef CONFIG_UBIFS_ATIME_SUPPORT
>>   	.update_time = ubifs_update_time,
>>   #endif
>> +#ifdef CONFIG_QUOTA
>> +	.get_qsize	= ubifs_get_qsize,
>> +#endif
>>   };
>>
>>   const struct file_operations ubifs_dir_operations = {
>> diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
>> index b57ccf3..f1d792a 100644
>> --- a/fs/ubifs/file.c
>> +++ b/fs/ubifs/file.c
>> @@ -1636,6 +1636,22 @@ static int ubifs_file_mmap(struct file *file, struct vm_area_struct *vma)
>>   	return 0;
>>   }
>>
>> +/*
>> + * ubifs_get_qsize: get the quota size of a file
>> + * @inode: inode which we are going to get the qsize
>> + *
>> + * We only care the size of regular file in ubifs
>> + * for quota. The reason is similar with the comment
>> + * in ubifs_getattr().
>> + */
>> +ssize_t ubifs_get_qsize(struct inode *inode)
>> +{
>> +	if (S_ISREG(inode->i_mode))
>> +		return i_size_read(inode);
>> +	else
>> +		return 0;
>> +}
>> +
>
> The quota space is accounted in bytes. So why don't you store appropriate
> number of bytes the file consumes in i_blocks / i_bytes? Reiserfs can also
> have files occupying only say 100 bytes and everything works properly
> there so I don't see why ubifs needs to differ.

Ha, yes, we did not keep i_blocks in ubifs currently. Because we have
no blocks in ubifs. Although we can simulate a i_block for quota, I
did not do it. Let me try to show what I am thinking here.

(1).Block file system are counting space with blocks. Then the quota
could works in (dquot_alloc_block & i_blocks) way. I mean, account
spaces by dquot_alloc_block() and FIOQSIZE can get the qsize from
i_blocks.

(2). But ubifs has no blocks, then I choose another way to do it,
(quot_alloc_space & i_size). That means, we account quota spaces
in ubifs by dquot_alloc_space() and want FIOSIZE to get i_size
of inodes. Then there is no notion of *block* but only space.

So, I want to make FIOSIZE more flexible here to introduce a get_qsize()
into inode_operations.

Yang
>
> 								Honza
>
>>   const struct address_space_operations ubifs_file_address_operations = {
>>   	.readpage       = ubifs_readpage,
>>   	.writepage      = ubifs_writepage,
>> @@ -1656,6 +1672,9 @@ const struct inode_operations ubifs_file_inode_operations = {
>>   #ifdef CONFIG_UBIFS_ATIME_SUPPORT
>>   	.update_time = ubifs_update_time,
>>   #endif
>> +#ifdef CONFIG_QUOTA
>> +	.get_qsize	= ubifs_get_qsize,
>> +#endif
>>   };
>>
>>   const struct inode_operations ubifs_symlink_inode_operations = {
>> @@ -1670,6 +1689,9 @@ const struct inode_operations ubifs_symlink_inode_operations = {
>>   #ifdef CONFIG_UBIFS_ATIME_SUPPORT
>>   	.update_time = ubifs_update_time,
>>   #endif
>> +#ifdef CONFIG_QUOTA
>> +	.get_qsize	= ubifs_get_qsize,
>> +#endif
>>   };
>>
>>   const struct file_operations ubifs_file_operations = {
>> diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
>> index 99cf10c..21b5dc0 100644
>> --- a/fs/ubifs/ubifs.h
>> +++ b/fs/ubifs/ubifs.h
>> @@ -1759,6 +1759,7 @@ int ubifs_read_block(struct inode *inode, void *addr, unsigned int block,
>>   int ubifs_fsync(struct file *file, loff_t start, loff_t end, int datasync);
>>   int ubifs_setattr(struct dentry *dentry, struct iattr *attr);
>>   int ubifs_update_time(struct inode *inode, struct timespec *time, int flags);
>> +ssize_t ubifs_get_qsize(struct inode *inode);
>>
>>   /* dir.c */
>>   struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
>> --
>> 1.8.4.2
>>


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 36/39] ubifs: implement ubifs_get_qsize to get quota size in ubifs
@ 2015-09-17  7:23       ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-17  7:23 UTC (permalink / raw)
  To: Jan Kara; +Cc: viro, dedekind1, richard.weinberger, linux-mtd, linux-fsdevel

On 09/16/2015 06:00 PM, Jan Kara wrote:
> On Tue 15-09-15 17:02:31, Dongsheng Yang wrote:
>> We only care the size of regular file in ubifs for quota.
>> The reason is similar with the comment in ubifs_getattr().
>>
>> Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
>> ---
>>   fs/ubifs/dir.c   |  3 +++
>>   fs/ubifs/file.c  | 22 ++++++++++++++++++++++
>>   fs/ubifs/ubifs.h |  1 +
>>   3 files changed, 26 insertions(+)
>>
>> diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
>> index 802c6ad..0d3d6d3 100644
>> --- a/fs/ubifs/dir.c
>> +++ b/fs/ubifs/dir.c
>> @@ -1205,6 +1205,9 @@ const struct inode_operations ubifs_dir_inode_operations = {
>>   #ifdef CONFIG_UBIFS_ATIME_SUPPORT
>>   	.update_time = ubifs_update_time,
>>   #endif
>> +#ifdef CONFIG_QUOTA
>> +	.get_qsize	= ubifs_get_qsize,
>> +#endif
>>   };
>>
>>   const struct file_operations ubifs_dir_operations = {
>> diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
>> index b57ccf3..f1d792a 100644
>> --- a/fs/ubifs/file.c
>> +++ b/fs/ubifs/file.c
>> @@ -1636,6 +1636,22 @@ static int ubifs_file_mmap(struct file *file, struct vm_area_struct *vma)
>>   	return 0;
>>   }
>>
>> +/*
>> + * ubifs_get_qsize: get the quota size of a file
>> + * @inode: inode which we are going to get the qsize
>> + *
>> + * We only care the size of regular file in ubifs
>> + * for quota. The reason is similar with the comment
>> + * in ubifs_getattr().
>> + */
>> +ssize_t ubifs_get_qsize(struct inode *inode)
>> +{
>> +	if (S_ISREG(inode->i_mode))
>> +		return i_size_read(inode);
>> +	else
>> +		return 0;
>> +}
>> +
>
> The quota space is accounted in bytes. So why don't you store appropriate
> number of bytes the file consumes in i_blocks / i_bytes? Reiserfs can also
> have files occupying only say 100 bytes and everything works properly
> there so I don't see why ubifs needs to differ.

Ha, yes, we did not keep i_blocks in ubifs currently. Because we have
no blocks in ubifs. Although we can simulate a i_block for quota, I
did not do it. Let me try to show what I am thinking here.

(1).Block file system are counting space with blocks. Then the quota
could works in (dquot_alloc_block & i_blocks) way. I mean, account
spaces by dquot_alloc_block() and FIOQSIZE can get the qsize from
i_blocks.

(2). But ubifs has no blocks, then I choose another way to do it,
(quot_alloc_space & i_size). That means, we account quota spaces
in ubifs by dquot_alloc_space() and want FIOSIZE to get i_size
of inodes. Then there is no notion of *block* but only space.

So, I want to make FIOSIZE more flexible here to introduce a get_qsize()
into inode_operations.

Yang
>
> 								Honza
>
>>   const struct address_space_operations ubifs_file_address_operations = {
>>   	.readpage       = ubifs_readpage,
>>   	.writepage      = ubifs_writepage,
>> @@ -1656,6 +1672,9 @@ const struct inode_operations ubifs_file_inode_operations = {
>>   #ifdef CONFIG_UBIFS_ATIME_SUPPORT
>>   	.update_time = ubifs_update_time,
>>   #endif
>> +#ifdef CONFIG_QUOTA
>> +	.get_qsize	= ubifs_get_qsize,
>> +#endif
>>   };
>>
>>   const struct inode_operations ubifs_symlink_inode_operations = {
>> @@ -1670,6 +1689,9 @@ const struct inode_operations ubifs_symlink_inode_operations = {
>>   #ifdef CONFIG_UBIFS_ATIME_SUPPORT
>>   	.update_time = ubifs_update_time,
>>   #endif
>> +#ifdef CONFIG_QUOTA
>> +	.get_qsize	= ubifs_get_qsize,
>> +#endif
>>   };
>>
>>   const struct file_operations ubifs_file_operations = {
>> diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
>> index 99cf10c..21b5dc0 100644
>> --- a/fs/ubifs/ubifs.h
>> +++ b/fs/ubifs/ubifs.h
>> @@ -1759,6 +1759,7 @@ int ubifs_read_block(struct inode *inode, void *addr, unsigned int block,
>>   int ubifs_fsync(struct file *file, loff_t start, loff_t end, int datasync);
>>   int ubifs_setattr(struct dentry *dentry, struct iattr *attr);
>>   int ubifs_update_time(struct inode *inode, struct timespec *time, int flags);
>> +ssize_t ubifs_get_qsize(struct inode *inode);
>>
>>   /* dir.c */
>>   struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
>> --
>> 1.8.4.2
>>

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 11/39] fs: quota: replace opened calling of ->sync_fs with sync_filesystem
  2015-09-17  6:28       ` Dongsheng Yang
  (?)
@ 2015-09-17 11:05       ` Jan Kara
  2015-09-18  5:49         ` Dongsheng Yang
  -1 siblings, 1 reply; 107+ messages in thread
From: Jan Kara @ 2015-09-17 11:05 UTC (permalink / raw)
  To: Dongsheng Yang
  Cc: Jan Kara, viro, dedekind1, richard.weinberger, linux-mtd, linux-fsdevel

On Thu 17-09-15 14:28:26, Dongsheng Yang wrote:
> On 09/16/2015 06:14 PM, Jan Kara wrote:
> >On Tue 15-09-15 17:02:06, Dongsheng Yang wrote:
> >>There are only two places in whole kernel to call ->sync_fs directly. It
> >>will sync fs even in read-only mode. It's not a good idea and some filesystem
> >>would warn out if you are syncing in read-only mode. But sync_filesystem()
> >>does filter this case out. Let's call sync_filesystem() here instead.
> >>
> >>Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
> >
> >So I'd prefer ubifs used hidden system inodes for quota files, set
> >DQUOT_QUOTA_SYS_FILE flag and so this code calling sync_fs() could be
> >completely avoided.
> 
> Hmmm, I think it's a good idea to make quota files SYS_FILEs. But how
> about quota-tools? E.g, if quotacheck do some modification
> on quota files, we would not read them without a sync_fs().
> 
> Could you help explain how quota works in this case?

So tools like quota(1) or setquota(1) work using quotactl so they don't
need access to quota files. When quota files are system files, quotacheck
functionality belongs into the fsck - so fsck.ubifs is responsible for
checking consistency of quota files. How e.g. e2fsck does it is that when
scanning inodes, it computes usage for each user / group, loads limits
information from old quota files and then just creates new quota files with
updated information if there's any difference to the old quota files.

Another advantage of the checking functionality being in fsck is that
fs-specific fsck can gather usage information much more efficiently (and
fsck has to do full fs scan anyway) and there's no need to propagate quota
usage information to userspace using FIQSIZE ioctl() and similar stuff...

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 36/39] ubifs: implement ubifs_get_qsize to get quota size in ubifs
  2015-09-17  7:23       ` Dongsheng Yang
  (?)
@ 2015-09-17 12:00       ` Jan Kara
  2015-09-18  6:14         ` Dongsheng Yang
  -1 siblings, 1 reply; 107+ messages in thread
From: Jan Kara @ 2015-09-17 12:00 UTC (permalink / raw)
  To: Dongsheng Yang
  Cc: Jan Kara, viro, dedekind1, richard.weinberger, linux-mtd, linux-fsdevel

On Thu 17-09-15 15:23:11, Dongsheng Yang wrote:
> On 09/16/2015 06:00 PM, Jan Kara wrote:
> >On Tue 15-09-15 17:02:31, Dongsheng Yang wrote:
> >>We only care the size of regular file in ubifs for quota.
> >>The reason is similar with the comment in ubifs_getattr().
> >>
> >>Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
> >>---
> >>  fs/ubifs/dir.c   |  3 +++
> >>  fs/ubifs/file.c  | 22 ++++++++++++++++++++++
> >>  fs/ubifs/ubifs.h |  1 +
> >>  3 files changed, 26 insertions(+)
> >>
> >>diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
> >>index 802c6ad..0d3d6d3 100644
> >>--- a/fs/ubifs/dir.c
> >>+++ b/fs/ubifs/dir.c
> >>@@ -1205,6 +1205,9 @@ const struct inode_operations ubifs_dir_inode_operations = {
> >>  #ifdef CONFIG_UBIFS_ATIME_SUPPORT
> >>  	.update_time = ubifs_update_time,
> >>  #endif
> >>+#ifdef CONFIG_QUOTA
> >>+	.get_qsize	= ubifs_get_qsize,
> >>+#endif
> >>  };
> >>
> >>  const struct file_operations ubifs_dir_operations = {
> >>diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
> >>index b57ccf3..f1d792a 100644
> >>--- a/fs/ubifs/file.c
> >>+++ b/fs/ubifs/file.c
> >>@@ -1636,6 +1636,22 @@ static int ubifs_file_mmap(struct file *file, struct vm_area_struct *vma)
> >>  	return 0;
> >>  }
> >>
> >>+/*
> >>+ * ubifs_get_qsize: get the quota size of a file
> >>+ * @inode: inode which we are going to get the qsize
> >>+ *
> >>+ * We only care the size of regular file in ubifs
> >>+ * for quota. The reason is similar with the comment
> >>+ * in ubifs_getattr().
> >>+ */
> >>+ssize_t ubifs_get_qsize(struct inode *inode)
> >>+{
> >>+	if (S_ISREG(inode->i_mode))
> >>+		return i_size_read(inode);
> >>+	else
> >>+		return 0;
> >>+}
> >>+
> >
> >The quota space is accounted in bytes. So why don't you store appropriate
> >number of bytes the file consumes in i_blocks / i_bytes? Reiserfs can also
> >have files occupying only say 100 bytes and everything works properly
> >there so I don't see why ubifs needs to differ.
> 
> Ha, yes, we did not keep i_blocks in ubifs currently. Because we have
> no blocks in ubifs. Although we can simulate a i_block for quota, I
> did not do it. Let me try to show what I am thinking here.
> 
> (1).Block file system are counting space with blocks. Then the quota
> could works in (dquot_alloc_block & i_blocks) way. I mean, account
> spaces by dquot_alloc_block() and FIOQSIZE can get the qsize from
> i_blocks.
> 
> (2). But ubifs has no blocks, then I choose another way to do it,
> (quot_alloc_space & i_size). That means, we account quota spaces
> in ubifs by dquot_alloc_space() and want FIOSIZE to get i_size
> of inodes. Then there is no notion of *block* but only space.
> 
> So, I want to make FIOSIZE more flexible here to introduce a get_qsize()
> into inode_operations.

But when you use dquot_alloc_space(), then i_blocks / i_bytes will be
updated accordingly by quota code (after all, those values are used when
inode gets transferred between users on chown to update quota information
accordingly). So I don't see a reason why you should need to use i_size in
FIOSIZE.

As a side note, I think that using inode size as the amount of space used
is wrong. I believe even ubifs has a notion of how many bytes of storage
the file occupies and *this* information should be fed into quota subsystem
and updated via dquot_alloc_space(). That way it will be more or less
consistent with how quota for other filesystems works as well. However this
is more or less filesystem internal decision so I can live with ubifs doing
it either way...

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 11/39] fs: quota: replace opened calling of ->sync_fs with sync_filesystem
  2015-09-17 11:05       ` Jan Kara
@ 2015-09-18  5:49         ` Dongsheng Yang
  2015-09-18  9:00           ` Jan Kara
  0 siblings, 1 reply; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-18  5:49 UTC (permalink / raw)
  To: Jan Kara; +Cc: viro, dedekind1, richard.weinberger, linux-mtd, linux-fsdevel

[-- Attachment #1: Type: text/plain, Size: 3163 bytes --]

On 09/17/2015 07:05 PM, Jan Kara wrote:
> On Thu 17-09-15 14:28:26, Dongsheng Yang wrote:
>> On 09/16/2015 06:14 PM, Jan Kara wrote:
>>> On Tue 15-09-15 17:02:06, Dongsheng Yang wrote:
>>>> There are only two places in whole kernel to call ->sync_fs directly. It
>>>> will sync fs even in read-only mode. It's not a good idea and some filesystem
>>>> would warn out if you are syncing in read-only mode. But sync_filesystem()
>>>> does filter this case out. Let's call sync_filesystem() here instead.
>>>>
>>>> Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
>>>
>>> So I'd prefer ubifs used hidden system inodes for quota files, set
>>> DQUOT_QUOTA_SYS_FILE flag and so this code calling sync_fs() could be
>>> completely avoided.
>>
>> Hmmm, I think it's a good idea to make quota files SYS_FILEs. But how
>> about quota-tools? E.g, if quotacheck do some modification
>> on quota files, we would not read them without a sync_fs().
>>
>> Could you help explain how quota works in this case?
>
> So tools like quota(1) or setquota(1) work using quotactl so they don't
> need access to quota files. When quota files are system files, quotacheck
> functionality belongs into the fsck - so fsck.ubifs is responsible for
> checking consistency of quota files. How e.g. e2fsck does it is that when
> scanning inodes, it computes usage for each user / group, loads limits
> information from old quota files and then just creates new quota files with
> updated information if there's any difference to the old quota files.

About quotacheck, I think just call fsync() in it sounds good to me.
Maybe something like the attachment.

OKEY, but I found repquota is still using read() to access quota files.
Please consider that case: 1.we read quota file and there is a pagecache
for it. 2. Then kernel did some modification on quota files. But
if the files is SYS_FILES marked, dquot_quota_sync() would not drop
the pagecache, then 3. repquota would get an outdated data from pagecache.

I am not sure why ext4 works well in this case. There must be something
I am missing.

Maybe we can introduce a Q_GETBLK for quotactl() to make all
quota tools getting informations from ioctl.
>
> Another advantage of the checking functionality being in fsck is that
> fs-specific fsck can gather usage information much more efficiently (and
> fsck has to do full fs scan anyway) and there's no need to propagate quota
> usage information to userspace using FIQSIZE ioctl() and similar stuff...

So, let me try to summary the my opinions about it.
Pros:
	(1). Security. quota files shouldn't be accessible to usespace.
	(2). Efficiency. No need for quotacheck, just do it in fsck.
	(3). No need FIOQSIZE any more.
Cons:
	(1). Incompatibility:
		If I set DQUOT_QUOTA_SYS_FILE currently, there are at
least two commands would not work: quotacheck and repquota. Actually
that means the whole quota is not usable to user.

So, I think the compatibility is important to me. Then what about
setting quota files as regular files at first. After all tools (quota
tools, quotacheck, repquota, fsck) prepared, setting the
DQUOT_QUOTA_SYS_FILE seems better.

Yang
>
> 								Honza
>


[-- Attachment #2: 0001-quotacheck-sync-files-in-quotacheck.patch --]
[-- Type: text/x-patch, Size: 1100 bytes --]

>From 1cf9d072cdd4d17c620834864f79ec5a0765d2bf Mon Sep 17 00:00:00 2001
From: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
Date: Fri, 18 Sep 2015 08:40:49 -0400
Subject: [PATCH] quotacheck: sync files in quotacheck.

After a quotacheck, we need to make kernel to see the modification.
Compared with syncing quota files in kernel, we would rather sync
it in quotacheck command.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 quotacheck.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/quotacheck.c b/quotacheck.c
index 6f34cff..e4b184d 100644
--- a/quotacheck.c
+++ b/quotacheck.c
@@ -768,6 +768,20 @@ rename_new:
 		close(fd);
 	}
 #endif
+
+	/* Do a syncing for the quota file */
+	if ((fd = open(filename, O_RDWR)) < 0) {
+		errstr(_("Cannot open new quota file %s: %s\n"), filename, strerror(errno));
+		free(filename);
+		return -1;
+	}
+        if (fsync(fd)) {
+		errstr(_("Cannot sync quota file %s: %s\n"), filename, strerror(errno));
+		free(filename);
+                return -1;
+        }
+	close(fd);
+
 	free(filename);
 	return 0;
 }
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 36/39] ubifs: implement ubifs_get_qsize to get quota size in ubifs
  2015-09-17 12:00       ` Jan Kara
@ 2015-09-18  6:14         ` Dongsheng Yang
  2015-09-18 11:20           ` Jan Kara
  0 siblings, 1 reply; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-18  6:14 UTC (permalink / raw)
  To: Jan Kara; +Cc: viro, dedekind1, richard.weinberger, linux-mtd, linux-fsdevel

On 09/17/2015 08:00 PM, Jan Kara wrote:
> On Thu 17-09-15 15:23:11, Dongsheng Yang wrote:
>> On 09/16/2015 06:00 PM, Jan Kara wrote:
>>> On Tue 15-09-15 17:02:31, Dongsheng Yang wrote:
>>>> We only care the size of regular file in ubifs for quota.
>>>> The reason is similar with the comment in ubifs_getattr().
>>>>
>>>> Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
>>>> ---
>>>>   fs/ubifs/dir.c   |  3 +++
>>>>   fs/ubifs/file.c  | 22 ++++++++++++++++++++++
>>>>   fs/ubifs/ubifs.h |  1 +
>>>>   3 files changed, 26 insertions(+)
>>>>
>>>> diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
>>>> index 802c6ad..0d3d6d3 100644
>>>> --- a/fs/ubifs/dir.c
>>>> +++ b/fs/ubifs/dir.c
>>>> @@ -1205,6 +1205,9 @@ const struct inode_operations ubifs_dir_inode_operations = {
>>>>   #ifdef CONFIG_UBIFS_ATIME_SUPPORT
>>>>   	.update_time = ubifs_update_time,
>>>>   #endif
>>>> +#ifdef CONFIG_QUOTA
>>>> +	.get_qsize	= ubifs_get_qsize,
>>>> +#endif
>>>>   };
>>>>
>>>>   const struct file_operations ubifs_dir_operations = {
>>>> diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
>>>> index b57ccf3..f1d792a 100644
>>>> --- a/fs/ubifs/file.c
>>>> +++ b/fs/ubifs/file.c
>>>> @@ -1636,6 +1636,22 @@ static int ubifs_file_mmap(struct file *file, struct vm_area_struct *vma)
>>>>   	return 0;
>>>>   }
>>>>
>>>> +/*
>>>> + * ubifs_get_qsize: get the quota size of a file
>>>> + * @inode: inode which we are going to get the qsize
>>>> + *
>>>> + * We only care the size of regular file in ubifs
>>>> + * for quota. The reason is similar with the comment
>>>> + * in ubifs_getattr().
>>>> + */
>>>> +ssize_t ubifs_get_qsize(struct inode *inode)
>>>> +{
>>>> +	if (S_ISREG(inode->i_mode))
>>>> +		return i_size_read(inode);
>>>> +	else
>>>> +		return 0;
>>>> +}
>>>> +
>>>
>>> The quota space is accounted in bytes. So why don't you store appropriate
>>> number of bytes the file consumes in i_blocks / i_bytes? Reiserfs can also
>>> have files occupying only say 100 bytes and everything works properly
>>> there so I don't see why ubifs needs to differ.
>>
>> Ha, yes, we did not keep i_blocks in ubifs currently. Because we have
>> no blocks in ubifs. Although we can simulate a i_block for quota, I
>> did not do it. Let me try to show what I am thinking here.
>>
>> (1).Block file system are counting space with blocks. Then the quota
>> could works in (dquot_alloc_block & i_blocks) way. I mean, account
>> spaces by dquot_alloc_block() and FIOQSIZE can get the qsize from
>> i_blocks.
>>
>> (2). But ubifs has no blocks, then I choose another way to do it,
>> (quot_alloc_space & i_size). That means, we account quota spaces
>> in ubifs by dquot_alloc_space() and want FIOSIZE to get i_size
>> of inodes. Then there is no notion of *block* but only space.
>>
>> So, I want to make FIOSIZE more flexible here to introduce a get_qsize()
>> into inode_operations.
>
> But when you use dquot_alloc_space(), then i_blocks / i_bytes will be
> updated accordingly by quota code (after all, those values are used when
> inode gets transferred between users on chown to update quota information
> accordingly). So I don't see a reason why you should need to use i_size in
> FIOSIZE.

Yes, dquot_alloc_space() would update i_blocks. But ubifs_iget() would
never set i_blocks. So i_blocks would be 0 if you get inode from flash
again. Yes, I can make ubifs to maintain a i_blocks. But.....
>
> As a side note, I think that using inode size as the amount of space used
> is wrong. I believe even ubifs has a notion of how many bytes of storage
> the file occupies and *this* information should be fed into quota subsystem
> and updated via dquot_alloc_space(). That way it will be more or less
> consistent with how quota for other filesystems works as well.

.... TBH, there is a little different with other filesystems. I did not
use the "disk" space, but the file space in ubifs quota, although dquot
means disk quota. Same with btrfs quota. If we use disk space for quota,
the most common problem from user is that: why I did not reach the limit
but I can not write any byte. COW in btrfs or out-place-updating in
ubifs makes this problem much worse.

So I choose file space here for ubifs.

Yang
> However this is more or less filesystem internal decision so I can live with ubifs doing
> it either way...
>
> 								Honza
>


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 11/39] fs: quota: replace opened calling of ->sync_fs with sync_filesystem
  2015-09-18  5:49         ` Dongsheng Yang
@ 2015-09-18  9:00           ` Jan Kara
  2015-09-21  4:31             ` Dongsheng Yang
  0 siblings, 1 reply; 107+ messages in thread
From: Jan Kara @ 2015-09-18  9:00 UTC (permalink / raw)
  To: Dongsheng Yang
  Cc: Jan Kara, viro, dedekind1, richard.weinberger, linux-mtd, linux-fsdevel

On Fri 18-09-15 13:49:25, Dongsheng Yang wrote:
> On 09/17/2015 07:05 PM, Jan Kara wrote:
> >On Thu 17-09-15 14:28:26, Dongsheng Yang wrote:
> >>On 09/16/2015 06:14 PM, Jan Kara wrote:
> >>>On Tue 15-09-15 17:02:06, Dongsheng Yang wrote:
> >>>>There are only two places in whole kernel to call ->sync_fs directly. It
> >>>>will sync fs even in read-only mode. It's not a good idea and some filesystem
> >>>>would warn out if you are syncing in read-only mode. But sync_filesystem()
> >>>>does filter this case out. Let's call sync_filesystem() here instead.
> >>>>
> >>>>Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
> >>>
> >>>So I'd prefer ubifs used hidden system inodes for quota files, set
> >>>DQUOT_QUOTA_SYS_FILE flag and so this code calling sync_fs() could be
> >>>completely avoided.
> >>
> >>Hmmm, I think it's a good idea to make quota files SYS_FILEs. But how
> >>about quota-tools? E.g, if quotacheck do some modification
> >>on quota files, we would not read them without a sync_fs().
> >>
> >>Could you help explain how quota works in this case?
> >
> >So tools like quota(1) or setquota(1) work using quotactl so they don't
> >need access to quota files. When quota files are system files, quotacheck
> >functionality belongs into the fsck - so fsck.ubifs is responsible for
> >checking consistency of quota files. How e.g. e2fsck does it is that when
> >scanning inodes, it computes usage for each user / group, loads limits
> >information from old quota files and then just creates new quota files with
> >updated information if there's any difference to the old quota files.
> 
> About quotacheck, I think just call fsync() in it sounds good to me.
> Maybe something like the attachment.
> 
> OKEY, but I found repquota is still using read() to access quota files.

repquota(8) uses read on quota files only if quota files are visible to
userspace. If quota files are invisible (they are system files),
repquota(8) uses Q_GETQUOTA quotactl to report quotas. So this is not an
issue.

> Please consider that case: 1.we read quota file and there is a pagecache
> for it. 2. Then kernel did some modification on quota files. But
> if the files is SYS_FILES marked, dquot_quota_sync() would not drop
> the pagecache, then 3. repquota would get an outdated data from pagecache.

You can mark quota files as SYS_FILES only if they are invisible to
userspace - usually they are stored in inodes not attached to any directory
(their inode numbers are stored in superblock or similarly so that fs can
find them when it is mounted).
 
> I am not sure why ext4 works well in this case. There must be something
> I am missing.

Ext4 marks quota files as SYS_FILES only if it is configured to have quota
files in hidden system inodes. So everything works fine.
 
> Maybe we can introduce a Q_GETBLK for quotactl() to make all
> quota tools getting informations from ioctl.

The idea is we don't want to expose raw quota blocks to quota tools
anymore and there's no real need to. The only suboptimal thing is
repquota(8) which would benefit from a way to iterate over all quota
entries of a particular quota type to make it more efficient if it doesn't
have access to quota file. For that we could create a new quotactl
but it was never pressing enough so that it would get implemented.

> >Another advantage of the checking functionality being in fsck is that
> >fs-specific fsck can gather usage information much more efficiently (and
> >fsck has to do full fs scan anyway) and there's no need to propagate quota
> >usage information to userspace using FIQSIZE ioctl() and similar stuff...
> 
> So, let me try to summary the my opinions about it.
> Pros:
> 	(1). Security. quota files shouldn't be accessible to usespace.
> 	(2). Efficiency. No need for quotacheck, just do it in fsck.
> 	(3). No need FIOQSIZE any more.
> Cons:
> 	(1). Incompatibility:
> 		If I set DQUOT_QUOTA_SYS_FILE currently, there are at
> least two commands would not work: quotacheck and repquota. Actually
> that means the whole quota is not usable to user.

When quota file is a system file, quotacheck(8) is not needed - fsck does
all the work. So that isn't an issue. Repquota(8) knows how to deal with a
situation when quota file is not visible (when it is a system file), so
that works as well.  Believe me, both ext4 and ocfs2 use this mechanism and
it works fine. XFS and GFS2 use the same principles but the don't fully use
the quota framework (only quotactl interface) so that's a bit different
case.
 
> So, I think the compatibility is important to me. Then what about
> setting quota files as regular files at first. After all tools (quota
> tools, quotacheck, repquota, fsck) prepared, setting the
> DQUOT_QUOTA_SYS_FILE seems better.

Quota tools are prepared for this. And ext4 originally used quota files as
regular files and later transitioned to store quota in system files and the
transition isn't a trivial process so it's better to avoid it.

Furthermore I'm not inclined to accept changes to generic quota
infrastructure just to accommodate ubifs to store quotas in regular files
when storing them in system files will solve these problems without changes
to the generic infrastructure.

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 36/39] ubifs: implement ubifs_get_qsize to get quota size in ubifs
  2015-09-18  6:14         ` Dongsheng Yang
@ 2015-09-18 11:20           ` Jan Kara
  2015-09-21  4:35             ` Dongsheng Yang
  0 siblings, 1 reply; 107+ messages in thread
From: Jan Kara @ 2015-09-18 11:20 UTC (permalink / raw)
  To: Dongsheng Yang
  Cc: Jan Kara, viro, dedekind1, richard.weinberger, linux-mtd, linux-fsdevel

On Fri 18-09-15 14:14:48, Dongsheng Yang wrote:
> On 09/17/2015 08:00 PM, Jan Kara wrote:
> >On Thu 17-09-15 15:23:11, Dongsheng Yang wrote:
> >>On 09/16/2015 06:00 PM, Jan Kara wrote:
> >>>On Tue 15-09-15 17:02:31, Dongsheng Yang wrote:
> >>>>We only care the size of regular file in ubifs for quota.
> >>>>The reason is similar with the comment in ubifs_getattr().
> >>>>
> >>>>Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
> >>>>---
> >>>>  fs/ubifs/dir.c   |  3 +++
> >>>>  fs/ubifs/file.c  | 22 ++++++++++++++++++++++
> >>>>  fs/ubifs/ubifs.h |  1 +
> >>>>  3 files changed, 26 insertions(+)
> >>>>
> >>>>diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
> >>>>index 802c6ad..0d3d6d3 100644
> >>>>--- a/fs/ubifs/dir.c
> >>>>+++ b/fs/ubifs/dir.c
> >>>>@@ -1205,6 +1205,9 @@ const struct inode_operations ubifs_dir_inode_operations = {
> >>>>  #ifdef CONFIG_UBIFS_ATIME_SUPPORT
> >>>>  	.update_time = ubifs_update_time,
> >>>>  #endif
> >>>>+#ifdef CONFIG_QUOTA
> >>>>+	.get_qsize	= ubifs_get_qsize,
> >>>>+#endif
> >>>>  };
> >>>>
> >>>>  const struct file_operations ubifs_dir_operations = {
> >>>>diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
> >>>>index b57ccf3..f1d792a 100644
> >>>>--- a/fs/ubifs/file.c
> >>>>+++ b/fs/ubifs/file.c
> >>>>@@ -1636,6 +1636,22 @@ static int ubifs_file_mmap(struct file *file, struct vm_area_struct *vma)
> >>>>  	return 0;
> >>>>  }
> >>>>
> >>>>+/*
> >>>>+ * ubifs_get_qsize: get the quota size of a file
> >>>>+ * @inode: inode which we are going to get the qsize
> >>>>+ *
> >>>>+ * We only care the size of regular file in ubifs
> >>>>+ * for quota. The reason is similar with the comment
> >>>>+ * in ubifs_getattr().
> >>>>+ */
> >>>>+ssize_t ubifs_get_qsize(struct inode *inode)
> >>>>+{
> >>>>+	if (S_ISREG(inode->i_mode))
> >>>>+		return i_size_read(inode);
> >>>>+	else
> >>>>+		return 0;
> >>>>+}
> >>>>+
> >>>
> >>>The quota space is accounted in bytes. So why don't you store appropriate
> >>>number of bytes the file consumes in i_blocks / i_bytes? Reiserfs can also
> >>>have files occupying only say 100 bytes and everything works properly
> >>>there so I don't see why ubifs needs to differ.
> >>
> >>Ha, yes, we did not keep i_blocks in ubifs currently. Because we have
> >>no blocks in ubifs. Although we can simulate a i_block for quota, I
> >>did not do it. Let me try to show what I am thinking here.
> >>
> >>(1).Block file system are counting space with blocks. Then the quota
> >>could works in (dquot_alloc_block & i_blocks) way. I mean, account
> >>spaces by dquot_alloc_block() and FIOQSIZE can get the qsize from
> >>i_blocks.
> >>
> >>(2). But ubifs has no blocks, then I choose another way to do it,
> >>(quot_alloc_space & i_size). That means, we account quota spaces
> >>in ubifs by dquot_alloc_space() and want FIOSIZE to get i_size
> >>of inodes. Then there is no notion of *block* but only space.
> >>
> >>So, I want to make FIOSIZE more flexible here to introduce a get_qsize()
> >>into inode_operations.
> >
> >But when you use dquot_alloc_space(), then i_blocks / i_bytes will be
> >updated accordingly by quota code (after all, those values are used when
> >inode gets transferred between users on chown to update quota information
> >accordingly). So I don't see a reason why you should need to use i_size in
> >FIOSIZE.
> 
> Yes, dquot_alloc_space() would update i_blocks. But ubifs_iget() would
> never set i_blocks. So i_blocks would be 0 if you get inode from flash
> again. Yes, I can make ubifs to maintain a i_blocks. But.....
> >
> >As a side note, I think that using inode size as the amount of space used
> >is wrong. I believe even ubifs has a notion of how many bytes of storage
> >the file occupies and *this* information should be fed into quota subsystem
> >and updated via dquot_alloc_space(). That way it will be more or less
> >consistent with how quota for other filesystems works as well.
> 
> .... TBH, there is a little different with other filesystems. I did not
> use the "disk" space, but the file space in ubifs quota, although dquot
> means disk quota. Same with btrfs quota. If we use disk space for quota,
> the most common problem from user is that: why I did not reach the limit
> but I can not write any byte. COW in btrfs or out-place-updating in
> ubifs makes this problem much worse.
> 
> So I choose file space here for ubifs.

OK, so these are really two separate questions. I understand your choice of
using file space as the amount of space to account for quota purposes and
I'm fine with that choice. Another thing is that regardless of how you
decide to do quota accounting, you must maintain i_blocks / i_bytes to
contain proper value because dquot_transfer() uses that information to update
quota usage when inode owner is changed.

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 11/39] fs: quota: replace opened calling of ->sync_fs with sync_filesystem
  2015-09-18  9:00           ` Jan Kara
@ 2015-09-21  4:31             ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-21  4:31 UTC (permalink / raw)
  To: Jan Kara; +Cc: viro, dedekind1, richard.weinberger, linux-mtd, linux-fsdevel

On 09/18/2015 05:00 PM, Jan Kara wrote:
> On Fri 18-09-15 13:49:25, Dongsheng Yang wrote:
>> On 09/17/2015 07:05 PM, Jan Kara wrote:
>>> On Thu 17-09-15 14:28:26, Dongsheng Yang wrote:
>>>> On 09/16/2015 06:14 PM, Jan Kara wrote:
>>>>> On Tue 15-09-15 17:02:06, Dongsheng Yang wrote:
>>>>>> There are only two places in whole kernel to call ->sync_fs directly. It
>>>>>> will sync fs even in read-only mode. It's not a good idea and some filesystem
>>>>>> would warn out if you are syncing in read-only mode. But sync_filesystem()
>>>>>> does filter this case out. Let's call sync_filesystem() here instead.
>>>>>>
>>>>>> Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
>>>>>
>>>>> So I'd prefer ubifs used hidden system inodes for quota files, set
>>>>> DQUOT_QUOTA_SYS_FILE flag and so this code calling sync_fs() could be
>>>>> completely avoided.
>>>>
>>>> Hmmm, I think it's a good idea to make quota files SYS_FILEs. But how
>>>> about quota-tools? E.g, if quotacheck do some modification
>>>> on quota files, we would not read them without a sync_fs().
>>>>
>>>> Could you help explain how quota works in this case?
>>>
>>> So tools like quota(1) or setquota(1) work using quotactl so they don't
>>> need access to quota files. When quota files are system files, quotacheck
>>> functionality belongs into the fsck - so fsck.ubifs is responsible for
>>> checking consistency of quota files. How e.g. e2fsck does it is that when
>>> scanning inodes, it computes usage for each user / group, loads limits
>>> information from old quota files and then just creates new quota files with
>>> updated information if there's any difference to the old quota files.
>>
>> About quotacheck, I think just call fsync() in it sounds good to me.
>> Maybe something like the attachment.
>>
>> OKEY, but I found repquota is still using read() to access quota files.
>
> repquota(8) uses read on quota files only if quota files are visible to
> userspace. If quota files are invisible (they are system files),
> repquota(8) uses Q_GETQUOTA quotactl to report quotas. So this is not an
> issue.
>
>> Please consider that case: 1.we read quota file and there is a pagecache
>> for it. 2. Then kernel did some modification on quota files. But
>> if the files is SYS_FILES marked, dquot_quota_sync() would not drop
>> the pagecache, then 3. repquota would get an outdated data from pagecache.
>
> You can mark quota files as SYS_FILES only if they are invisible to
> userspace - usually they are stored in inodes not attached to any directory
> (their inode numbers are stored in superblock or similarly so that fs can
> find them when it is mounted).
>
>> I am not sure why ext4 works well in this case. There must be something
>> I am missing.
>
> Ext4 marks quota files as SYS_FILES only if it is configured to have quota
> files in hidden system inodes. So everything works fine.
>
>> Maybe we can introduce a Q_GETBLK for quotactl() to make all
>> quota tools getting informations from ioctl.
>
> The idea is we don't want to expose raw quota blocks to quota tools
> anymore and there's no real need to. The only suboptimal thing is
> repquota(8) which would benefit from a way to iterate over all quota
> entries of a particular quota type to make it more efficient if it doesn't
> have access to quota file. For that we could create a new quotactl
> but it was never pressing enough so that it would get implemented.
>
>>> Another advantage of the checking functionality being in fsck is that
>>> fs-specific fsck can gather usage information much more efficiently (and
>>> fsck has to do full fs scan anyway) and there's no need to propagate quota
>>> usage information to userspace using FIQSIZE ioctl() and similar stuff...
>>
>> So, let me try to summary the my opinions about it.
>> Pros:
>> 	(1). Security. quota files shouldn't be accessible to usespace.
>> 	(2). Efficiency. No need for quotacheck, just do it in fsck.
>> 	(3). No need FIOQSIZE any more.
>> Cons:
>> 	(1). Incompatibility:
>> 		If I set DQUOT_QUOTA_SYS_FILE currently, there are at
>> least two commands would not work: quotacheck and repquota. Actually
>> that means the whole quota is not usable to user.
>
> When quota file is a system file, quotacheck(8) is not needed - fsck does
> all the work. So that isn't an issue. Repquota(8) knows how to deal with a
> situation when quota file is not visible (when it is a system file), so
> that works as well.  Believe me, both ext4 and ocfs2 use this mechanism and
> it works fine. XFS and GFS2 use the same principles but the don't fully use
> the quota framework (only quotactl interface) so that's a bit different
> case.
>
>> So, I think the compatibility is important to me. Then what about
>> setting quota files as regular files at first. After all tools (quota
>> tools, quotacheck, repquota, fsck) prepared, setting the
>> DQUOT_QUOTA_SYS_FILE seems better.
>
> Quota tools are prepared for this. And ext4 originally used quota files as
> regular files and later transitioned to store quota in system files and the
> transition isn't a trivial process so it's better to avoid it.

Okey, so I need to do my work similar with what ext4 is doing. I will read
more about it in ext4 and quota-tools to see how to implement it in
ubifs.
>
> Furthermore I'm not inclined to accept changes to generic quota
> infrastructure just to accommodate ubifs to store quotas in regular files
> when storing them in system files will solve these problems without changes
> to the generic infrastructure.

Yes, I agree with that. We should keep the generic
infrastructure until we have to change it. :)

Yang
>
> 								Honza
>


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 36/39] ubifs: implement ubifs_get_qsize to get quota size in ubifs
  2015-09-18 11:20           ` Jan Kara
@ 2015-09-21  4:35             ` Dongsheng Yang
  2015-09-21  9:13               ` Jan Kara
  0 siblings, 1 reply; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-21  4:35 UTC (permalink / raw)
  To: Jan Kara; +Cc: viro, dedekind1, richard.weinberger, linux-mtd, linux-fsdevel

On 09/18/2015 07:20 PM, Jan Kara wrote:
> On Fri 18-09-15 14:14:48, Dongsheng Yang wrote:
>> On 09/17/2015 08:00 PM, Jan Kara wrote:
>>> On Thu 17-09-15 15:23:11, Dongsheng Yang wrote:
>>>> On 09/16/2015 06:00 PM, Jan Kara wrote:
>>>>> On Tue 15-09-15 17:02:31, Dongsheng Yang wrote:
>>>>>> We only care the size of regular file in ubifs for quota.
>>>>>> The reason is similar with the comment in ubifs_getattr().
>>>>>>
>>>>>> Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
>>>>>> ---
>>>>>>   fs/ubifs/dir.c   |  3 +++
>>>>>>   fs/ubifs/file.c  | 22 ++++++++++++++++++++++
>>>>>>   fs/ubifs/ubifs.h |  1 +
>>>>>>   3 files changed, 26 insertions(+)
>>>>>>
>>>>>> diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
>>>>>> index 802c6ad..0d3d6d3 100644
>>>>>> --- a/fs/ubifs/dir.c
>>>>>> +++ b/fs/ubifs/dir.c
>>>>>> @@ -1205,6 +1205,9 @@ const struct inode_operations ubifs_dir_inode_operations = {
>>>>>>   #ifdef CONFIG_UBIFS_ATIME_SUPPORT
>>>>>>   	.update_time = ubifs_update_time,
>>>>>>   #endif
>>>>>> +#ifdef CONFIG_QUOTA
>>>>>> +	.get_qsize	= ubifs_get_qsize,
>>>>>> +#endif
>>>>>>   };
>>>>>>
>>>>>>   const struct file_operations ubifs_dir_operations = {
>>>>>> diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
>>>>>> index b57ccf3..f1d792a 100644
>>>>>> --- a/fs/ubifs/file.c
>>>>>> +++ b/fs/ubifs/file.c
>>>>>> @@ -1636,6 +1636,22 @@ static int ubifs_file_mmap(struct file *file, struct vm_area_struct *vma)
>>>>>>   	return 0;
>>>>>>   }
>>>>>>
>>>>>> +/*
>>>>>> + * ubifs_get_qsize: get the quota size of a file
>>>>>> + * @inode: inode which we are going to get the qsize
>>>>>> + *
>>>>>> + * We only care the size of regular file in ubifs
>>>>>> + * for quota. The reason is similar with the comment
>>>>>> + * in ubifs_getattr().
>>>>>> + */
>>>>>> +ssize_t ubifs_get_qsize(struct inode *inode)
>>>>>> +{
>>>>>> +	if (S_ISREG(inode->i_mode))
>>>>>> +		return i_size_read(inode);
>>>>>> +	else
>>>>>> +		return 0;
>>>>>> +}
>>>>>> +
>>>>>
>>>>> The quota space is accounted in bytes. So why don't you store appropriate
>>>>> number of bytes the file consumes in i_blocks / i_bytes? Reiserfs can also
>>>>> have files occupying only say 100 bytes and everything works properly
>>>>> there so I don't see why ubifs needs to differ.
>>>>
>>>> Ha, yes, we did not keep i_blocks in ubifs currently. Because we have
>>>> no blocks in ubifs. Although we can simulate a i_block for quota, I
>>>> did not do it. Let me try to show what I am thinking here.
>>>>
>>>> (1).Block file system are counting space with blocks. Then the quota
>>>> could works in (dquot_alloc_block & i_blocks) way. I mean, account
>>>> spaces by dquot_alloc_block() and FIOQSIZE can get the qsize from
>>>> i_blocks.
>>>>
>>>> (2). But ubifs has no blocks, then I choose another way to do it,
>>>> (quot_alloc_space & i_size). That means, we account quota spaces
>>>> in ubifs by dquot_alloc_space() and want FIOSIZE to get i_size
>>>> of inodes. Then there is no notion of *block* but only space.
>>>>
>>>> So, I want to make FIOSIZE more flexible here to introduce a get_qsize()
>>>> into inode_operations.
>>>
>>> But when you use dquot_alloc_space(), then i_blocks / i_bytes will be
>>> updated accordingly by quota code (after all, those values are used when
>>> inode gets transferred between users on chown to update quota information
>>> accordingly). So I don't see a reason why you should need to use i_size in
>>> FIOSIZE.
>>
>> Yes, dquot_alloc_space() would update i_blocks. But ubifs_iget() would
>> never set i_blocks. So i_blocks would be 0 if you get inode from flash
>> again. Yes, I can make ubifs to maintain a i_blocks. But.....
>>>
>>> As a side note, I think that using inode size as the amount of space used
>>> is wrong. I believe even ubifs has a notion of how many bytes of storage
>>> the file occupies and *this* information should be fed into quota subsystem
>>> and updated via dquot_alloc_space(). That way it will be more or less
>>> consistent with how quota for other filesystems works as well.
>>
>> .... TBH, there is a little different with other filesystems. I did not
>> use the "disk" space, but the file space in ubifs quota, although dquot
>> means disk quota. Same with btrfs quota. If we use disk space for quota,
>> the most common problem from user is that: why I did not reach the limit
>> but I can not write any byte. COW in btrfs or out-place-updating in
>> ubifs makes this problem much worse.
>>
>> So I choose file space here for ubifs.
>
> OK, so these are really two separate questions. I understand your choice of
> using file space as the amount of space to account for quota purposes and
> I'm fine with that choice. Another thing is that regardless of how you
> decide to do quota accounting, you must maintain i_blocks / i_bytes to
> contain proper value because dquot_transfer() uses that information to update
> quota usage when inode owner is changed.

But if we don't use i_blocks to get qsize, what we care only in 
dquot_transter() is dquot->dq_dqb. That means, even if the i_blocks
is not correct in dquot_transfer() in ubifs, that's okey, because we
will never use this value, right?

Yang
>
> 								Honza
>


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 36/39] ubifs: implement ubifs_get_qsize to get quota size in ubifs
  2015-09-21  4:35             ` Dongsheng Yang
@ 2015-09-21  9:13               ` Jan Kara
  2015-09-21  9:16                 ` Dongsheng Yang
  0 siblings, 1 reply; 107+ messages in thread
From: Jan Kara @ 2015-09-21  9:13 UTC (permalink / raw)
  To: Dongsheng Yang
  Cc: Jan Kara, viro, dedekind1, richard.weinberger, linux-mtd, linux-fsdevel

On Mon 21-09-15 12:35:01, Dongsheng Yang wrote:
> On 09/18/2015 07:20 PM, Jan Kara wrote:
> >>.... TBH, there is a little different with other filesystems. I did not
> >>use the "disk" space, but the file space in ubifs quota, although dquot
> >>means disk quota. Same with btrfs quota. If we use disk space for quota,
> >>the most common problem from user is that: why I did not reach the limit
> >>but I can not write any byte. COW in btrfs or out-place-updating in
> >>ubifs makes this problem much worse.
> >>
> >>So I choose file space here for ubifs.
> >
> >OK, so these are really two separate questions. I understand your choice of
> >using file space as the amount of space to account for quota purposes and
> >I'm fine with that choice. Another thing is that regardless of how you
> >decide to do quota accounting, you must maintain i_blocks / i_bytes to
> >contain proper value because dquot_transfer() uses that information to update
> >quota usage when inode owner is changed.
> 
> But if we don't use i_blocks to get qsize, what we care only in
> dquot_transter() is dquot->dq_dqb. That means, even if the i_blocks
> is not correct in dquot_transfer() in ubifs, that's okey, because we
> will never use this value, right?

dquot_transfer() will use the value - when file F changes owner from user A
to user B, then you need to decrement amount of space used by F from A's
quota usage and add that amount to B's quota usage. And the amount of space
is obtained via inode_get_bytes() which uses i_blocks and i_bytes. See
__dquot_transfer() in fs/quota/dquot.c for details.

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 36/39] ubifs: implement ubifs_get_qsize to get quota size in ubifs
  2015-09-21  9:13               ` Jan Kara
@ 2015-09-21  9:16                 ` Dongsheng Yang
  2015-09-21  9:44                   ` Jan Kara
  0 siblings, 1 reply; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-21  9:16 UTC (permalink / raw)
  To: Jan Kara; +Cc: viro, dedekind1, richard.weinberger, linux-mtd, linux-fsdevel

On 09/21/2015 05:13 PM, Jan Kara wrote:
> On Mon 21-09-15 12:35:01, Dongsheng Yang wrote:
>> On 09/18/2015 07:20 PM, Jan Kara wrote:
>>>> .... TBH, there is a little different with other filesystems. I did not
>>>> use the "disk" space, but the file space in ubifs quota, although dquot
>>>> means disk quota. Same with btrfs quota. If we use disk space for quota,
>>>> the most common problem from user is that: why I did not reach the limit
>>>> but I can not write any byte. COW in btrfs or out-place-updating in
>>>> ubifs makes this problem much worse.
>>>>
>>>> So I choose file space here for ubifs.
>>>
>>> OK, so these are really two separate questions. I understand your choice of
>>> using file space as the amount of space to account for quota purposes and
>>> I'm fine with that choice. Another thing is that regardless of how you
>>> decide to do quota accounting, you must maintain i_blocks / i_bytes to
>>> contain proper value because dquot_transfer() uses that information to update
>>> quota usage when inode owner is changed.
>>
>> But if we don't use i_blocks to get qsize, what we care only in
>> dquot_transter() is dquot->dq_dqb. That means, even if the i_blocks
>> is not correct in dquot_transfer() in ubifs, that's okey, because we
>> will never use this value, right?
>
> dquot_transfer() will use the value - when file F changes owner from user A
> to user B, then you need to decrement amount of space used by F from A's
> quota usage and add that amount to B's quota usage. And the amount of space
> is obtained via inode_get_bytes() which uses i_blocks and i_bytes. See
> __dquot_transfer() in fs/quota/dquot.c for details.

Yes, I see it. But if ubifs doesn't use i_blocks and i_bytes to stand
for quota size, as I mentioned I want to use i_size. Then we will never
use i_blocks. So we only need a to transfer dquot->dq_dqb values. That
means, even the i_blocks in dquot_transfer() is not correct, we don't
care it. we only need to make sure values in dquot_dq_dqb are 
transfered, such as dquot->dq_dqb->curspace for user B is equal with
i_size.

Yang


>
> 								Honza
>


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 36/39] ubifs: implement ubifs_get_qsize to get quota size in ubifs
  2015-09-21  9:16                 ` Dongsheng Yang
@ 2015-09-21  9:44                   ` Jan Kara
  2015-09-21 11:02                     ` Dongsheng Yang
  0 siblings, 1 reply; 107+ messages in thread
From: Jan Kara @ 2015-09-21  9:44 UTC (permalink / raw)
  To: Dongsheng Yang
  Cc: Jan Kara, viro, dedekind1, richard.weinberger, linux-mtd, linux-fsdevel

On Mon 21-09-15 17:16:49, Dongsheng Yang wrote:
> On 09/21/2015 05:13 PM, Jan Kara wrote:
> >On Mon 21-09-15 12:35:01, Dongsheng Yang wrote:
> >>On 09/18/2015 07:20 PM, Jan Kara wrote:
> >>>>.... TBH, there is a little different with other filesystems. I did not
> >>>>use the "disk" space, but the file space in ubifs quota, although dquot
> >>>>means disk quota. Same with btrfs quota. If we use disk space for quota,
> >>>>the most common problem from user is that: why I did not reach the limit
> >>>>but I can not write any byte. COW in btrfs or out-place-updating in
> >>>>ubifs makes this problem much worse.
> >>>>
> >>>>So I choose file space here for ubifs.
> >>>
> >>>OK, so these are really two separate questions. I understand your choice of
> >>>using file space as the amount of space to account for quota purposes and
> >>>I'm fine with that choice. Another thing is that regardless of how you
> >>>decide to do quota accounting, you must maintain i_blocks / i_bytes to
> >>>contain proper value because dquot_transfer() uses that information to update
> >>>quota usage when inode owner is changed.
> >>
> >>But if we don't use i_blocks to get qsize, what we care only in
> >>dquot_transter() is dquot->dq_dqb. That means, even if the i_blocks
> >>is not correct in dquot_transfer() in ubifs, that's okey, because we
> >>will never use this value, right?
> >
> >dquot_transfer() will use the value - when file F changes owner from user A
> >to user B, then you need to decrement amount of space used by F from A's
> >quota usage and add that amount to B's quota usage. And the amount of space
> >is obtained via inode_get_bytes() which uses i_blocks and i_bytes. See
> >__dquot_transfer() in fs/quota/dquot.c for details.
> 
> Yes, I see it. But if ubifs doesn't use i_blocks and i_bytes to stand
> for quota size, as I mentioned I want to use i_size. Then we will never
> use i_blocks. So we only need a to transfer dquot->dq_dqb values. That
> means, even the i_blocks in dquot_transfer() is not correct, we don't
> care it. we only need to make sure values in dquot_dq_dqb are
> transfered, such as dquot->dq_dqb->curspace for user B is equal with
> i_size.

I think you are missing one thing:

Assume user A has files F1 (1MB) F2 (2MB) F3 (3MB).
User B has one file G1 (4MB).

So user A uses 6 MB in total (stored in dquot for user A in dqb_curspace
field). User B uses 4MB.

Now you do "chown B F1"

You need to change dq_dqb of F1 to point to user B quota structure as you
explain, that is correct. However you also need to subtract 1MB from user
A's total usage (which is stored in struct dquot for user A) since file F1
no longer belongs to him. And you need to add 1 MB to user B's total usage.

After this user A will have total usage of 5 MB and user B has usage of 5
MB as well. You need to properly update the total usage of each user so
that you can check the usage against quota limits.

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 36/39] ubifs: implement ubifs_get_qsize to get quota size in ubifs
  2015-09-21  9:44                   ` Jan Kara
@ 2015-09-21 11:02                     ` Dongsheng Yang
  2015-09-23  7:42                       ` Jan Kara
  0 siblings, 1 reply; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-21 11:02 UTC (permalink / raw)
  To: Jan Kara; +Cc: viro, dedekind1, richard.weinberger, linux-mtd, linux-fsdevel

On 09/21/2015 05:44 PM, Jan Kara wrote:
> On Mon 21-09-15 17:16:49, Dongsheng Yang wrote:
>> On 09/21/2015 05:13 PM, Jan Kara wrote:
>>> On Mon 21-09-15 12:35:01, Dongsheng Yang wrote:
>>>> On 09/18/2015 07:20 PM, Jan Kara wrote:
>>>>>> .... TBH, there is a little different with other filesystems. I did not
>>>>>> use the "disk" space, but the file space in ubifs quota, although dquot
>>>>>> means disk quota. Same with btrfs quota. If we use disk space for quota,
>>>>>> the most common problem from user is that: why I did not reach the limit
>>>>>> but I can not write any byte. COW in btrfs or out-place-updating in
>>>>>> ubifs makes this problem much worse.
>>>>>>
>>>>>> So I choose file space here for ubifs.
>>>>>
>>>>> OK, so these are really two separate questions. I understand your choice of
>>>>> using file space as the amount of space to account for quota purposes and
>>>>> I'm fine with that choice. Another thing is that regardless of how you
>>>>> decide to do quota accounting, you must maintain i_blocks / i_bytes to
>>>>> contain proper value because dquot_transfer() uses that information to update
>>>>> quota usage when inode owner is changed.
>>>>
>>>> But if we don't use i_blocks to get qsize, what we care only in
>>>> dquot_transter() is dquot->dq_dqb. That means, even if the i_blocks
>>>> is not correct in dquot_transfer() in ubifs, that's okey, because we
>>>> will never use this value, right?
>>>
>>> dquot_transfer() will use the value - when file F changes owner from user A
>>> to user B, then you need to decrement amount of space used by F from A's
>>> quota usage and add that amount to B's quota usage. And the amount of space
>>> is obtained via inode_get_bytes() which uses i_blocks and i_bytes. See
>>> __dquot_transfer() in fs/quota/dquot.c for details.
>>
>> Yes, I see it. But if ubifs doesn't use i_blocks and i_bytes to stand
>> for quota size, as I mentioned I want to use i_size. Then we will never
>> use i_blocks. So we only need a to transfer dquot->dq_dqb values. That
>> means, even the i_blocks in dquot_transfer() is not correct, we don't
>> care it. we only need to make sure values in dquot_dq_dqb are
>> transfered, such as dquot->dq_dqb->curspace for user B is equal with
>> i_size.
>
> I think you are missing one thing:
>
> Assume user A has files F1 (1MB) F2 (2MB) F3 (3MB).
> User B has one file G1 (4MB).
>
> So user A uses 6 MB in total (stored in dquot for user A in dqb_curspace
> field). User B uses 4MB.
>
> Now you do "chown B F1"
>
> You need to change dq_dqb of F1 to point to user B quota structure as you
> explain, that is correct. However you also need to subtract 1MB from user
> A's total usage (which is stored in struct dquot for user A) since file F1
> no longer belongs to him. And you need to add 1 MB to user B's total usage.
>
> After this user A will have total usage of 5 MB and user B has usage of 5
> MB as well. You need to properly update the total usage of each user so
> that you can check the usage against quota limits.

But that's all done in dquot_transfer(). It dquot_decr_space(from) and
dquot_incr_space(to). Let me show the test result in my implementation.

(1). root -> 1M/2M/3M     yds ->4M

[root@atest-guest linux_compile]# ll -h /mnt/ubifs/
total 11M
-rw-r--r--. 1 root root 1.0M Sep 21 15:54 1M
-rw-r--r--. 1 root root 2.0M Sep 21 15:54 2M
-rw-r--r--. 1 root root 3.0M Sep 21 15:54 3M
-rw-r--r--. 1 yds  root 4.0M Sep 21 15:55 4M
-rw-------. 1 root root 6.0K Sep 21 15:53 aquota.group
-rw-------. 1 root root 7.0K Sep 21 15:53 aquota.user
[root@atest-guest linux_compile]# repquota -u /mnt/ubifs/
*** Report for user quotas on device /dev/ubi0_0
Block grace time: 7days; Inode grace time: 7days
                         Block limits                File limits
User            used    soft    hard  grace    used  soft  hard  grace
----------------------------------------------------------------------
root      --    6144       0       0              4     0     0
yds       --    4096       0       0              1     0     0


(2). chown yds /mnt/ubifs/1M
[root@atest-guest linux_compile]# chown yds /mnt/ubifs/1M
[root@atest-guest linux_compile]# ll -h /mnt/ubifs/
total 11M
-rw-r--r--. 1 yds  root 1.0M Sep 21 15:54 1M
-rw-r--r--. 1 root root 2.0M Sep 21 15:54 2M
-rw-r--r--. 1 root root 3.0M Sep 21 15:54 3M
-rw-r--r--. 1 yds  root 4.0M Sep 21 15:55 4M
-rw-------. 1 root root 6.0K Sep 21 15:53 aquota.group
-rw-------. 1 root root 7.0K Sep 21 15:53 aquota.user
[root@atest-guest linux_compile]# repquota -u /mnt/ubifs/
*** Report for user quotas on device /dev/ubi0_0
Block grace time: 7days; Inode grace time: 7days
                         Block limits                File limits
User            used    soft    hard  grace    used  soft  hard  grace
----------------------------------------------------------------------
root      --    5120       0       0              3     0     0
yds       --    5120       0       0              2     0     0


(3). quotacheck and check again.
[root@atest-guest linux_compile]# quotaoff /mnt/ubifs && quotacheck -u 
/mnt/ubifs/
[root@atest-guest linux_compile]# ll -h /mnt/ubifs
total 11M
-rw-r--r--. 1 yds  root 1.0M Sep 21 15:54 1M
-rw-r--r--. 1 root root 2.0M Sep 21 15:54 2M
-rw-r--r--. 1 root root 3.0M Sep 21 15:54 3M
-rw-r--r--. 1 yds  root 4.0M Sep 21 15:55 4M
-rw-------. 1 root root 6.0K Sep 21 15:53 aquota.group
-rw-------. 1 root root 7.0K Sep 21 16:00 aquota.user
[root@atest-guest linux_compile]# repquota -u /mnt/ubifs/
*** Report for user quotas on device /dev/ubi0_0
Block grace time: 7days; Inode grace time: 7days
                         Block limits                File limits
User            used    soft    hard  grace    used  soft  hard  grace
----------------------------------------------------------------------
root      --    5120       0       0              3     0     0
yds       --    5120       0       0              2     0     0

Yang
>
> 								Honza
>


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 36/39] ubifs: implement ubifs_get_qsize to get quota size in ubifs
  2015-09-21 11:02                     ` Dongsheng Yang
@ 2015-09-23  7:42                       ` Jan Kara
  2015-09-24  0:50                         ` Dongsheng Yang
  0 siblings, 1 reply; 107+ messages in thread
From: Jan Kara @ 2015-09-23  7:42 UTC (permalink / raw)
  To: Dongsheng Yang
  Cc: Jan Kara, viro, dedekind1, richard.weinberger, linux-mtd, linux-fsdevel

On Mon 21-09-15 19:02:30, Dongsheng Yang wrote:
> On 09/21/2015 05:44 PM, Jan Kara wrote:
> >On Mon 21-09-15 17:16:49, Dongsheng Yang wrote:
> >>On 09/21/2015 05:13 PM, Jan Kara wrote:
> >>>On Mon 21-09-15 12:35:01, Dongsheng Yang wrote:
> >>>>On 09/18/2015 07:20 PM, Jan Kara wrote:
> >>>>>>.... TBH, there is a little different with other filesystems. I did not
> >>>>>>use the "disk" space, but the file space in ubifs quota, although dquot
> >>>>>>means disk quota. Same with btrfs quota. If we use disk space for quota,
> >>>>>>the most common problem from user is that: why I did not reach the limit
> >>>>>>but I can not write any byte. COW in btrfs or out-place-updating in
> >>>>>>ubifs makes this problem much worse.
> >>>>>>
> >>>>>>So I choose file space here for ubifs.
> >>>>>
> >>>>>OK, so these are really two separate questions. I understand your choice of
> >>>>>using file space as the amount of space to account for quota purposes and
> >>>>>I'm fine with that choice. Another thing is that regardless of how you
> >>>>>decide to do quota accounting, you must maintain i_blocks / i_bytes to
> >>>>>contain proper value because dquot_transfer() uses that information to update
> >>>>>quota usage when inode owner is changed.
> >>>>
> >>>>But if we don't use i_blocks to get qsize, what we care only in
> >>>>dquot_transter() is dquot->dq_dqb. That means, even if the i_blocks
> >>>>is not correct in dquot_transfer() in ubifs, that's okey, because we
> >>>>will never use this value, right?
> >>>
> >>>dquot_transfer() will use the value - when file F changes owner from user A
> >>>to user B, then you need to decrement amount of space used by F from A's
> >>>quota usage and add that amount to B's quota usage. And the amount of space
> >>>is obtained via inode_get_bytes() which uses i_blocks and i_bytes. See
> >>>__dquot_transfer() in fs/quota/dquot.c for details.
> >>
> >>Yes, I see it. But if ubifs doesn't use i_blocks and i_bytes to stand
> >>for quota size, as I mentioned I want to use i_size. Then we will never
> >>use i_blocks. So we only need a to transfer dquot->dq_dqb values. That
> >>means, even the i_blocks in dquot_transfer() is not correct, we don't
> >>care it. we only need to make sure values in dquot_dq_dqb are
> >>transfered, such as dquot->dq_dqb->curspace for user B is equal with
> >>i_size.
> >
> >I think you are missing one thing:
> >
> >Assume user A has files F1 (1MB) F2 (2MB) F3 (3MB).
> >User B has one file G1 (4MB).
> >
> >So user A uses 6 MB in total (stored in dquot for user A in dqb_curspace
> >field). User B uses 4MB.
> >
> >Now you do "chown B F1"
> >
> >You need to change dq_dqb of F1 to point to user B quota structure as you
> >explain, that is correct. However you also need to subtract 1MB from user
> >A's total usage (which is stored in struct dquot for user A) since file F1
> >no longer belongs to him. And you need to add 1 MB to user B's total usage.
> >
> >After this user A will have total usage of 5 MB and user B has usage of 5
> >MB as well. You need to properly update the total usage of each user so
> >that you can check the usage against quota limits.
> 
> But that's all done in dquot_transfer(). It dquot_decr_space(from) and
> dquot_incr_space(to). Let me show the test result in my implementation.

Yes, dquot_decr_space(transfer_from[cnt], cur_space) and
dquot_incr_space(transfer_to[cnt], cur_space) are the functions changing
usage. However have a look at what cur_space is. It is set as:

cur_space = inode_get_bytes(inode);

and inode_get_bytes() is:

ret = (((loff_t)inode->i_blocks) << 9) + inode->i_bytes;

So for dquot_transfer() to work correctly, filesystem has to properly
maintain i_blocks and i_bytes.

> (1). root -> 1M/2M/3M     yds ->4M
> 
> [root@atest-guest linux_compile]# ll -h /mnt/ubifs/
> total 11M
> -rw-r--r--. 1 root root 1.0M Sep 21 15:54 1M
> -rw-r--r--. 1 root root 2.0M Sep 21 15:54 2M
> -rw-r--r--. 1 root root 3.0M Sep 21 15:54 3M
> -rw-r--r--. 1 yds  root 4.0M Sep 21 15:55 4M
> -rw-------. 1 root root 6.0K Sep 21 15:53 aquota.group
> -rw-------. 1 root root 7.0K Sep 21 15:53 aquota.user
> [root@atest-guest linux_compile]# repquota -u /mnt/ubifs/
> *** Report for user quotas on device /dev/ubi0_0
> Block grace time: 7days; Inode grace time: 7days
>                         Block limits                File limits
> User            used    soft    hard  grace    used  soft  hard  grace
> ----------------------------------------------------------------------
> root      --    6144       0       0              4     0     0
> yds       --    4096       0       0              1     0     0
> 
> 
> (2). chown yds /mnt/ubifs/1M
> [root@atest-guest linux_compile]# chown yds /mnt/ubifs/1M
> [root@atest-guest linux_compile]# ll -h /mnt/ubifs/
> total 11M
> -rw-r--r--. 1 yds  root 1.0M Sep 21 15:54 1M
> -rw-r--r--. 1 root root 2.0M Sep 21 15:54 2M
> -rw-r--r--. 1 root root 3.0M Sep 21 15:54 3M
> -rw-r--r--. 1 yds  root 4.0M Sep 21 15:55 4M
> -rw-------. 1 root root 6.0K Sep 21 15:53 aquota.group
> -rw-------. 1 root root 7.0K Sep 21 15:53 aquota.user
> [root@atest-guest linux_compile]# repquota -u /mnt/ubifs/
> *** Report for user quotas on device /dev/ubi0_0
> Block grace time: 7days; Inode grace time: 7days
>                         Block limits                File limits
> User            used    soft    hard  grace    used  soft  hard  grace
> ----------------------------------------------------------------------
> root      --    5120       0       0              3     0     0
> yds       --    5120       0       0              2     0     0
> 
> 
> (3). quotacheck and check again.
> [root@atest-guest linux_compile]# quotaoff /mnt/ubifs && quotacheck
> -u /mnt/ubifs/
> [root@atest-guest linux_compile]# ll -h /mnt/ubifs
> total 11M
> -rw-r--r--. 1 yds  root 1.0M Sep 21 15:54 1M
> -rw-r--r--. 1 root root 2.0M Sep 21 15:54 2M
> -rw-r--r--. 1 root root 3.0M Sep 21 15:54 3M
> -rw-r--r--. 1 yds  root 4.0M Sep 21 15:55 4M
> -rw-------. 1 root root 6.0K Sep 21 15:53 aquota.group
> -rw-------. 1 root root 7.0K Sep 21 16:00 aquota.user
> [root@atest-guest linux_compile]# repquota -u /mnt/ubifs/
> *** Report for user quotas on device /dev/ubi0_0
> Block grace time: 7days; Inode grace time: 7days
>                         Block limits                File limits
> User            used    soft    hard  grace    used  soft  hard  grace
> ----------------------------------------------------------------------
> root      --    5120       0       0              3     0     0
> yds       --    5120       0       0              2     0     0

Yes, this case is working because quota code updated i_blocks properly when
creating files. But if you do not set i_blocks when reading inodes
(which seems to be the case) I expect the following would not work:

mount -t ubifs -o usrjquota=aquota.user,jqfmt=vfsv0 <dev> /mnt
quotacheck -vu /mnt
quotaon -vu /mnt
dd if=/dev/zero of=file1 bs=1M count=1
# Umount fs to prune cached information
umount /mnt
mount -t ubifs -o usrjquota=aquota.user,jqfmt=vfsv0 <dev> /mnt
quotaon -vu /mnt
chown yds /mnt/file1
repquota -u /mnt/

Now unless you set i_blocks when reading inode, yds would not be accounted
for 1 MB /mnt/file1 is using...

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 36/39] ubifs: implement ubifs_get_qsize to get quota size in ubifs
  2015-09-23  7:42                       ` Jan Kara
@ 2015-09-24  0:50                         ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-09-24  0:50 UTC (permalink / raw)
  To: Jan Kara; +Cc: viro, dedekind1, richard.weinberger, linux-mtd, linux-fsdevel

On 09/23/2015 03:42 PM, Jan Kara wrote:
> On Mon 21-09-15 19:02:30, Dongsheng Yang wrote:
>> On 09/21/2015 05:44 PM, Jan Kara wrote:
>>> On Mon 21-09-15 17:16:49, Dongsheng Yang wrote:
>>>> On 09/21/2015 05:13 PM, Jan Kara wrote:
>>>>> On Mon 21-09-15 12:35:01, Dongsheng Yang wrote:
>>>>>> On 09/18/2015 07:20 PM, Jan Kara wrote:
>>>>>>>> .... TBH, there is a little different with other filesystems. I did not
>>>>>>>> use the "disk" space, but the file space in ubifs quota, although dquot
>>>>>>>> means disk quota. Same with btrfs quota. If we use disk space for quota,
>>>>>>>> the most common problem from user is that: why I did not reach the limit
>>>>>>>> but I can not write any byte. COW in btrfs or out-place-updating in
>>>>>>>> ubifs makes this problem much worse.
>>>>>>>>
>>>>>>>> So I choose file space here for ubifs.
>>>>>>>
>>>>>>> OK, so these are really two separate questions. I understand your choice of
>>>>>>> using file space as the amount of space to account for quota purposes and
>>>>>>> I'm fine with that choice. Another thing is that regardless of how you
>>>>>>> decide to do quota accounting, you must maintain i_blocks / i_bytes to
>>>>>>> contain proper value because dquot_transfer() uses that information to update
>>>>>>> quota usage when inode owner is changed.
>>>>>>
>>>>>> But if we don't use i_blocks to get qsize, what we care only in
>>>>>> dquot_transter() is dquot->dq_dqb. That means, even if the i_blocks
>>>>>> is not correct in dquot_transfer() in ubifs, that's okey, because we
>>>>>> will never use this value, right?
>>>>>
>>>>> dquot_transfer() will use the value - when file F changes owner from user A
>>>>> to user B, then you need to decrement amount of space used by F from A's
>>>>> quota usage and add that amount to B's quota usage. And the amount of space
>>>>> is obtained via inode_get_bytes() which uses i_blocks and i_bytes. See
>>>>> __dquot_transfer() in fs/quota/dquot.c for details.
>>>>
>>>> Yes, I see it. But if ubifs doesn't use i_blocks and i_bytes to stand
>>>> for quota size, as I mentioned I want to use i_size. Then we will never
>>>> use i_blocks. So we only need a to transfer dquot->dq_dqb values. That
>>>> means, even the i_blocks in dquot_transfer() is not correct, we don't
>>>> care it. we only need to make sure values in dquot_dq_dqb are
>>>> transfered, such as dquot->dq_dqb->curspace for user B is equal with
>>>> i_size.
>>>
>>> I think you are missing one thing:
>>>
>>> Assume user A has files F1 (1MB) F2 (2MB) F3 (3MB).
>>> User B has one file G1 (4MB).
>>>
>>> So user A uses 6 MB in total (stored in dquot for user A in dqb_curspace
>>> field). User B uses 4MB.
>>>
>>> Now you do "chown B F1"
>>>
>>> You need to change dq_dqb of F1 to point to user B quota structure as you
>>> explain, that is correct. However you also need to subtract 1MB from user
>>> A's total usage (which is stored in struct dquot for user A) since file F1
>>> no longer belongs to him. And you need to add 1 MB to user B's total usage.
>>>
>>> After this user A will have total usage of 5 MB and user B has usage of 5
>>> MB as well. You need to properly update the total usage of each user so
>>> that you can check the usage against quota limits.
>>
>> But that's all done in dquot_transfer(). It dquot_decr_space(from) and
>> dquot_incr_space(to). Let me show the test result in my implementation.
>
> Yes, dquot_decr_space(transfer_from[cnt], cur_space) and
> dquot_incr_space(transfer_to[cnt], cur_space) are the functions changing
> usage. However have a look at what cur_space is. It is set as:
>
> cur_space = inode_get_bytes(inode);
>
> and inode_get_bytes() is:
>
> ret = (((loff_t)inode->i_blocks) << 9) + inode->i_bytes;
>
> So for dquot_transfer() to work correctly, filesystem has to properly
> maintain i_blocks and i_bytes.

Oh, my mistake. you are right. We have to maintain i_blocks for quota
then. will update it.

Yang
>
>> (1). root -> 1M/2M/3M     yds ->4M
>>
>> [root@atest-guest linux_compile]# ll -h /mnt/ubifs/
>> total 11M
>> -rw-r--r--. 1 root root 1.0M Sep 21 15:54 1M
>> -rw-r--r--. 1 root root 2.0M Sep 21 15:54 2M
>> -rw-r--r--. 1 root root 3.0M Sep 21 15:54 3M
>> -rw-r--r--. 1 yds  root 4.0M Sep 21 15:55 4M
>> -rw-------. 1 root root 6.0K Sep 21 15:53 aquota.group
>> -rw-------. 1 root root 7.0K Sep 21 15:53 aquota.user
>> [root@atest-guest linux_compile]# repquota -u /mnt/ubifs/
>> *** Report for user quotas on device /dev/ubi0_0
>> Block grace time: 7days; Inode grace time: 7days
>>                          Block limits                File limits
>> User            used    soft    hard  grace    used  soft  hard  grace
>> ----------------------------------------------------------------------
>> root      --    6144       0       0              4     0     0
>> yds       --    4096       0       0              1     0     0
>>
>>
>> (2). chown yds /mnt/ubifs/1M
>> [root@atest-guest linux_compile]# chown yds /mnt/ubifs/1M
>> [root@atest-guest linux_compile]# ll -h /mnt/ubifs/
>> total 11M
>> -rw-r--r--. 1 yds  root 1.0M Sep 21 15:54 1M
>> -rw-r--r--. 1 root root 2.0M Sep 21 15:54 2M
>> -rw-r--r--. 1 root root 3.0M Sep 21 15:54 3M
>> -rw-r--r--. 1 yds  root 4.0M Sep 21 15:55 4M
>> -rw-------. 1 root root 6.0K Sep 21 15:53 aquota.group
>> -rw-------. 1 root root 7.0K Sep 21 15:53 aquota.user
>> [root@atest-guest linux_compile]# repquota -u /mnt/ubifs/
>> *** Report for user quotas on device /dev/ubi0_0
>> Block grace time: 7days; Inode grace time: 7days
>>                          Block limits                File limits
>> User            used    soft    hard  grace    used  soft  hard  grace
>> ----------------------------------------------------------------------
>> root      --    5120       0       0              3     0     0
>> yds       --    5120       0       0              2     0     0
>>
>>
>> (3). quotacheck and check again.
>> [root@atest-guest linux_compile]# quotaoff /mnt/ubifs && quotacheck
>> -u /mnt/ubifs/
>> [root@atest-guest linux_compile]# ll -h /mnt/ubifs
>> total 11M
>> -rw-r--r--. 1 yds  root 1.0M Sep 21 15:54 1M
>> -rw-r--r--. 1 root root 2.0M Sep 21 15:54 2M
>> -rw-r--r--. 1 root root 3.0M Sep 21 15:54 3M
>> -rw-r--r--. 1 yds  root 4.0M Sep 21 15:55 4M
>> -rw-------. 1 root root 6.0K Sep 21 15:53 aquota.group
>> -rw-------. 1 root root 7.0K Sep 21 16:00 aquota.user
>> [root@atest-guest linux_compile]# repquota -u /mnt/ubifs/
>> *** Report for user quotas on device /dev/ubi0_0
>> Block grace time: 7days; Inode grace time: 7days
>>                          Block limits                File limits
>> User            used    soft    hard  grace    used  soft  hard  grace
>> ----------------------------------------------------------------------
>> root      --    5120       0       0              3     0     0
>> yds       --    5120       0       0              2     0     0
>
> Yes, this case is working because quota code updated i_blocks properly when
> creating files. But if you do not set i_blocks when reading inodes
> (which seems to be the case) I expect the following would not work:
>
> mount -t ubifs -o usrjquota=aquota.user,jqfmt=vfsv0 <dev> /mnt
> quotacheck -vu /mnt
> quotaon -vu /mnt
> dd if=/dev/zero of=file1 bs=1M count=1
> # Umount fs to prune cached information
> umount /mnt
> mount -t ubifs -o usrjquota=aquota.user,jqfmt=vfsv0 <dev> /mnt
> quotaon -vu /mnt
> chown yds /mnt/file1
> repquota -u /mnt/
>
> Now unless you set i_blocks when reading inode, yds would not be accounted
> for 1 MB /mnt/file1 is using...
>
> 								Honza
>


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 00/39] Add quota supporting in ubifs
  2015-09-15  9:01 ` Dongsheng Yang
                   ` (39 preceding siblings ...)
  (?)
@ 2015-10-03 18:57 ` Richard Weinberger
  2015-10-04  2:32   ` Dongsheng Yang
  -1 siblings, 1 reply; 107+ messages in thread
From: Richard Weinberger @ 2015-10-03 18:57 UTC (permalink / raw)
  To: Dongsheng Yang, viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel

Hi!

Am 15.09.2015 um 11:01 schrieb Dongsheng Yang:
> Hi all,
> 	This is the V3 to add quota in ubifs.
> 
> Hi Al,
> 	There are some patches about vfs, and
> some of them are already Reviewed-by Jan, please
> take a look at them. Thanx.
> 
> Hi Jan,
> 	There are some new patches for dquot,
> please take a look.
> 
> Hi Artem and Richard,
> 	please help to review the ubifs part.

Yang, from the discussion with Jan it seems as you'll send an v4 of your
patches.
Shall I wait with reviewing UBIFS specific parts or won't they change in v4?

> Dongsheng Yang (39):
>   fs: introduce a ->s_cdev field into struct super_block
>   fs: cleanup: remove the blank line before EXPORT_SYMBOL

This patch is unrelated to this series. Not sure if it makes sense to
carry it here.

>   fs: super: cleanup: make the comment of each function aligned
>   fs: super: consolidate the get_super class functions
>   fs: super: introduce a get_super_cdev to get super by a cdev reference
>   fs: super: introduce a get_super_cdev_thawed to get sb by cdev
>     reference
>   fs: char_dev: introduce cd_acquire function to acquire cdev
>   fs: introduce a __lookup_dev for internal using
>   fs: char_dev: introduce lookup_cdev to get cdev by pathname
>   fs: dquot: skip invalidate_bdev if bdev is NULL
>   fs: quota: replace opened calling of ->sync_fs with sync_filesystem
>   fs: quota: make quota support fs which is running on char dev
>   fs: introduce a get_qsize() to inode_operations
>   fs: quota: restore i_flags of quota files in dquot_disable
>   fs: quota: introduce a callback of restore_iflags to quotactl_ops

Jan, Al, will you take the VFS/quota specific changes or shall I
take them? Of course iff you ACK them.

Thanks,
//richard

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 00/39] Add quota supporting in ubifs
  2015-10-03 18:57 ` [PATCH v3 00/39] Add quota supporting in ubifs Richard Weinberger
@ 2015-10-04  2:32   ` Dongsheng Yang
  0 siblings, 0 replies; 107+ messages in thread
From: Dongsheng Yang @ 2015-10-04  2:32 UTC (permalink / raw)
  To: Richard Weinberger, viro, jack, dedekind1, richard.weinberger
  Cc: linux-mtd, linux-fsdevel

On 10/04/2015 02:57 AM, Richard Weinberger wrote:
> Hi!
>
> Am 15.09.2015 um 11:01 schrieb Dongsheng Yang:
>> Hi all,
>> 	This is the V3 to add quota in ubifs.
>>
>> Hi Al,
>> 	There are some patches about vfs, and
>> some of them are already Reviewed-by Jan, please
>> take a look at them. Thanx.
>>
>> Hi Jan,
>> 	There are some new patches for dquot,
>> please take a look.
>>
>> Hi Artem and Richard,
>> 	please help to review the ubifs part.
>
> Yang, from the discussion with Jan it seems as you'll send an v4 of your
> patches.
> Shall I wait with reviewing UBIFS specific parts or won't they change in v4?

Please wait for V4, there would be something different. :)
>
>> Dongsheng Yang (39):
>>    fs: introduce a ->s_cdev field into struct super_block
>>    fs: cleanup: remove the blank line before EXPORT_SYMBOL
>
> This patch is unrelated to this series. Not sure if it makes sense to
> carry it here.
>
>>    fs: super: cleanup: make the comment of each function aligned

The two commits is about cleanup, but there would be a conflict with
other commits in this thread. So I put them here.
>>    fs: super: consolidate the get_super class functions
>>    fs: super: introduce a get_super_cdev to get super by a cdev reference
>>    fs: super: introduce a get_super_cdev_thawed to get sb by cdev
>>      reference
>>    fs: char_dev: introduce cd_acquire function to acquire cdev
>>    fs: introduce a __lookup_dev for internal using
>>    fs: char_dev: introduce lookup_cdev to get cdev by pathname
>>    fs: dquot: skip invalidate_bdev if bdev is NULL
>>    fs: quota: replace opened calling of ->sync_fs with sync_filesystem
>>    fs: quota: make quota support fs which is running on char dev
>>    fs: introduce a get_qsize() to inode_operations
>>    fs: quota: restore i_flags of quota files in dquot_disable
>>    fs: quota: introduce a callback of restore_iflags to quotactl_ops
>
> Jan, Al, will you take the VFS/quota specific changes or shall I
> take them? Of course iff you ACK them.

I think it's better to go through ubifs tree with other commits, but
yes, we need ACKs at first.

Thanx
Yang
>
> Thanks,
> //richard
> .
>


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 01/39] fs: introduce a ->s_cdev field into struct super_block
  2015-09-15  9:01   ` Dongsheng Yang
  (?)
@ 2015-10-04  6:31   ` Christoph Hellwig
  2015-10-05  8:36     ` Jan Kara
  -1 siblings, 1 reply; 107+ messages in thread
From: Christoph Hellwig @ 2015-10-04  6:31 UTC (permalink / raw)
  To: Dongsheng Yang
  Cc: viro, jack, dedekind1, richard.weinberger, linux-mtd, linux-fsdevel

On Tue, Sep 15, 2015 at 05:01:56PM +0800, Dongsheng Yang wrote:
> There are some filesystems are running on char devs, such
> as ubifs. So we need a field in super_block to hold a
> reference to the char device.

We only care about the block device to get a device number to return
in st.st_dev.  And while filesystem literally run on top of a block
device that is not the case of a character device - you might use a
chardev to identify a device to mount but it'll never use the actual
char device.

So please don't bloat the superblock with this.

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 05/39] fs: super: introduce a get_super_cdev to get super by a cdev reference
  2015-09-15  9:02   ` Dongsheng Yang
  (?)
@ 2015-10-04  6:32   ` Christoph Hellwig
  -1 siblings, 0 replies; 107+ messages in thread
From: Christoph Hellwig @ 2015-10-04  6:32 UTC (permalink / raw)
  To: Dongsheng Yang
  Cc: viro, jack, dedekind1, richard.weinberger, linux-mtd, linux-fsdevel

As mentioned before I don't think the cdev has any business in core VFS
code.  You must alredy have an anonymous block device for the st_dev
value, please use that.


^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 13/39] fs: introduce a get_qsize() to inode_operations
  2015-09-15  9:02 ` [PATCH v3 13/39] fs: introduce a get_qsize() to inode_operations Dongsheng Yang
@ 2015-10-04  6:33   ` Christoph Hellwig
  2015-10-05  8:01     ` Jan Kara
  0 siblings, 1 reply; 107+ messages in thread
From: Christoph Hellwig @ 2015-10-04  6:33 UTC (permalink / raw)
  To: Dongsheng Yang
  Cc: viro, jack, dedekind1, richard.weinberger, linux-mtd, linux-fsdevel

On Tue, Sep 15, 2015 at 05:02:08PM +0800, Dongsheng Yang wrote:
> get_qsize() is used to allow inode to decide how much of the quota size
> in itself. If file system implements the own get_qsize(), ioctl of
> FIOQSIZe will call it to get quota size. If not implemented, get the
> quota size in a generic way.

This should be in struct dquot_operations.

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 13/39] fs: introduce a get_qsize() to inode_operations
  2015-10-04  6:33   ` Christoph Hellwig
@ 2015-10-05  8:01     ` Jan Kara
  0 siblings, 0 replies; 107+ messages in thread
From: Jan Kara @ 2015-10-05  8:01 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Dongsheng Yang, viro, jack, dedekind1, richard.weinberger,
	linux-mtd, linux-fsdevel

On Sat 03-10-15 23:33:57, Christoph Hellwig wrote:
> On Tue, Sep 15, 2015 at 05:02:08PM +0800, Dongsheng Yang wrote:
> > get_qsize() is used to allow inode to decide how much of the quota size
> > in itself. If file system implements the own get_qsize(), ioctl of
> > FIOQSIZe will call it to get quota size. If not implemented, get the
> > quota size in a generic way.
> 
> This should be in struct dquot_operations.

This function won't be needed at all in the end as we talked with Yang...

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 107+ messages in thread

* Re: [PATCH v3 01/39] fs: introduce a ->s_cdev field into struct super_block
  2015-10-04  6:31   ` Christoph Hellwig
@ 2015-10-05  8:36     ` Jan Kara
  0 siblings, 0 replies; 107+ messages in thread
From: Jan Kara @ 2015-10-05  8:36 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Dongsheng Yang, viro, jack, dedekind1, richard.weinberger,
	linux-mtd, linux-fsdevel

On Sat 03-10-15 23:31:19, Christoph Hellwig wrote:
> On Tue, Sep 15, 2015 at 05:01:56PM +0800, Dongsheng Yang wrote:
> > There are some filesystems are running on char devs, such
> > as ubifs. So we need a field in super_block to hold a
> > reference to the char device.
> 
> We only care about the block device to get a device number to return
> in st.st_dev.  And while filesystem literally run on top of a block
> device that is not the case of a character device - you might use a
> chardev to identify a device to mount but it'll never use the actual
> char device.
> 
> So please don't bloat the superblock with this.

Hum, interesting idea. You're right that using anon bdev ubifs got assigned
in set_anon_super() would work as well. It may be slightly confusing for
quota-tools usage where specifying char device on command line would not
work (specifying block device to identify filesystem works there). But
using mount point would work fine so the situation would be the same as
with network filesystems.

We could even add a translation in quota-tools to convert char device to
corresponding anon block device if there's a reasonably simple way to do
that in userspace or we could translate in quotactl code in kernel if
that's any easier. But currently I don't see a way how we could easily do
either of those.

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 107+ messages in thread

end of thread, other threads:[~2015-10-05  8:36 UTC | newest]

Thread overview: 107+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-15  9:01 [PATCH v3 00/39] Add quota supporting in ubifs Dongsheng Yang
2015-09-15  9:01 ` Dongsheng Yang
2015-09-15  9:01 ` [PATCH v3 01/39] fs: introduce a ->s_cdev field into struct super_block Dongsheng Yang
2015-09-15  9:01   ` Dongsheng Yang
2015-10-04  6:31   ` Christoph Hellwig
2015-10-05  8:36     ` Jan Kara
2015-09-15  9:01 ` [PATCH v3 02/39] fs: cleanup: remove the blank line before EXPORT_SYMBOL Dongsheng Yang
2015-09-15  9:01   ` Dongsheng Yang
2015-09-15  9:01 ` [PATCH v3 03/39] fs: super: cleanup: make the comment of each function aligned Dongsheng Yang
2015-09-15  9:01   ` Dongsheng Yang
2015-09-15  9:01 ` [PATCH v3 04/39] fs: super: consolidate the get_super class functions Dongsheng Yang
2015-09-15  9:01   ` Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 05/39] fs: super: introduce a get_super_cdev to get super by a cdev reference Dongsheng Yang
2015-09-15  9:02   ` Dongsheng Yang
2015-10-04  6:32   ` Christoph Hellwig
2015-09-15  9:02 ` [PATCH v3 06/39] fs: super: introduce a get_super_cdev_thawed to get sb by " Dongsheng Yang
2015-09-15  9:02   ` Dongsheng Yang
2015-09-15 21:24   ` Jan Kara
2015-09-15  9:02 ` [PATCH v3 07/39] fs: char_dev: introduce cd_acquire function to acquire cdev Dongsheng Yang
2015-09-15  9:02   ` Dongsheng Yang
2015-09-16  8:16   ` Jan Kara
2015-09-17  3:30     ` Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 08/39] fs: introduce a __lookup_dev for internal using Dongsheng Yang
2015-09-15  9:02   ` Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 09/39] fs: char_dev: introduce lookup_cdev to get cdev by pathname Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 10/39] fs: dquot: skip invalidate_bdev if bdev is NULL Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 11/39] fs: quota: replace opened calling of ->sync_fs with sync_filesystem Dongsheng Yang
2015-09-15  9:02   ` Dongsheng Yang
2015-09-16 10:14   ` Jan Kara
2015-09-17  6:28     ` Dongsheng Yang
2015-09-17  6:28       ` Dongsheng Yang
2015-09-17 11:05       ` Jan Kara
2015-09-18  5:49         ` Dongsheng Yang
2015-09-18  9:00           ` Jan Kara
2015-09-21  4:31             ` Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 12/39] fs: quota: make quota support fs which is running on char dev Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 13/39] fs: introduce a get_qsize() to inode_operations Dongsheng Yang
2015-10-04  6:33   ` Christoph Hellwig
2015-10-05  8:01     ` Jan Kara
2015-09-15  9:02 ` [PATCH v3 14/39] fs: quota: restore i_flags of quota files in dquot_disable Dongsheng Yang
2015-09-15  9:02   ` Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 15/39] fs: quota: introduce a callback of restore_iflags to quotactl_ops Dongsheng Yang
2015-09-15  9:02   ` Dongsheng Yang
2015-09-16  9:47   ` Jan Kara
2015-09-15  9:02 ` [PATCH v3 16/39] ubi: introduce a interface to get cdev in ubi_volume Dongsheng Yang
2015-09-15  9:02   ` Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 17/39] ubifs: extend budget for blocks Dongsheng Yang
2015-09-15  9:02   ` Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 18/39] ubifs: fill sb->s_cdev in ubifs_fill_super() Dongsheng Yang
2015-09-15  9:02   ` Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 19/39] ubifs: fill ->s_dev in ubifs_fill_super Dongsheng Yang
2015-09-15  9:02   ` Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 20/39] ubifs: export read_block() from file.c Dongsheng Yang
2015-09-15  9:02   ` Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 21/39] ubifs: introduce i_dquot to ubifs_inode Dongsheng Yang
2015-09-15  9:02   ` Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 22/39] ubifs: implement IO functions for quota files Dongsheng Yang
2015-09-15  9:02   ` Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 23/39] ubifs: disable quota in ubifs_put_super Dongsheng Yang
2015-09-15  9:02   ` Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 24/39] ubifs: write quota back in ubifs_sync Dongsheng Yang
2015-09-15  9:02   ` Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 25/39] ubifs: set/clear MS_RDONLY properly in ubifs_remount Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 26/39] ubifs: suspend & resume quota " Dongsheng Yang
2015-09-15  9:02   ` Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 27/39] ubifs: check inode with NULL before using it Dongsheng Yang
2015-09-15  9:02   ` Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 28/39] ubifs: record quota information about inode in ubifs_new_inode Dongsheng Yang
2015-09-15  9:02   ` Dongsheng Yang
2015-09-15  9:35   ` Sheng Yong
2015-09-16  1:46     ` Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 29/39] ubifs: free quota inode information in ubifs_evict_inode Dongsheng Yang
2015-09-15  9:02   ` Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 30/39] ubifs: alloc quota space in ubifs writing path Dongsheng Yang
2015-09-15  9:02   ` Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 31/39] ubifs: free quota space in do_truncation Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 32/39] ubifs: free quota space when deleting a file Dongsheng Yang
2015-09-15  9:02   ` Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 33/39] ubifs: adapt quota space informatin in do_setattr Dongsheng Yang
2015-09-15  9:02   ` Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 34/39] ubifs: transfer quota information in changing owner or group Dongsheng Yang
2015-09-15  9:02   ` Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 35/39] ubifs: write inode in ubifs_quota_write if we are appending Dongsheng Yang
2015-09-15  9:02   ` Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 36/39] ubifs: implement ubifs_get_qsize to get quota size in ubifs Dongsheng Yang
2015-09-16 10:00   ` Jan Kara
2015-09-17  7:23     ` Dongsheng Yang
2015-09-17  7:23       ` Dongsheng Yang
2015-09-17 12:00       ` Jan Kara
2015-09-18  6:14         ` Dongsheng Yang
2015-09-18 11:20           ` Jan Kara
2015-09-21  4:35             ` Dongsheng Yang
2015-09-21  9:13               ` Jan Kara
2015-09-21  9:16                 ` Dongsheng Yang
2015-09-21  9:44                   ` Jan Kara
2015-09-21 11:02                     ` Dongsheng Yang
2015-09-23  7:42                       ` Jan Kara
2015-09-24  0:50                         ` Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 37/39] ubifs: implement ubifs_restore_iflags for quotactl_operations Dongsheng Yang
2015-09-15  9:02   ` Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 38/39] ubifs: fill the quota related fields in ubifs_fill_super Dongsheng Yang
2015-09-15  9:02 ` [PATCH v3 39/39] ubifs: introduce quota related mount options Dongsheng Yang
2015-09-15  9:02   ` Dongsheng Yang
2015-09-15  9:36   ` Sheng Yong
2015-09-16  1:48     ` Dongsheng Yang
2015-10-03 18:57 ` [PATCH v3 00/39] Add quota supporting in ubifs Richard Weinberger
2015-10-04  2:32   ` Dongsheng Yang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.