All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 00/25] Add quota supporting in ubifs
@ 2015-07-21  8:37 Dongsheng Yang
  2015-07-21  8:37 ` [PATCH 01/25] fs: introduce a ->s_cdev field into struct super_block Dongsheng Yang
                   ` (29 more replies)
  0 siblings, 30 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, linux-mtd, Dongsheng Yang

Hi Atem, Richard and others,
	This is a patchset to add quota supporting in ubifs.
[1/25] - [7/25] are working to make quotactl to support filesystems
which are running on char device.

Others are about making ubifs to support quota
Please help to review or test it. Any comment is welcome :).

Hi Jan Kara,
	I am not sure I am using the quota APIs correctly, please
help to correct me if I am wrong.

Also you can get the code from:
https://github.com/yangdongsheng/linux.git  ubifs_quota_v1

	My simple testing is shown as below:
[root@atest-guest linux_compile]# mount -t ubifs -o usrquota,grpquota /dev/ubi0_0 /mnt/ubifs/
[root@atest-guest linux_compile]# quotacheck -ug /mnt/ubifs
[root@atest-guest linux_compile]# quotaon /mnt/ubifs
[root@atest-guest linux_compile]# repquota /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      --       0       0       0              1     0     0 
[root@atest-guest linux_compile]# setquota root 10 10 3 3 /mnt/ubifs
[root@atest-guest linux_compile]# repquota /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      --       0      10      10              1     3     3 
[root@atest-guest linux_compile]# touch /mnt/ubifs/{1,11,111}
ubifs: warning, user file quota exceeded.
[root@atest-guest linux_compile]# repquota /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      -+       0      10      10              4     3     3  7days
[root@atest-guest linux_compile]# rm -rf /mnt/ubifs/1*
[root@atest-guest linux_compile]# repquota /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      --       0      10      10              1     3     3    
[root@atest-guest linux_compile]# dd if=/dev/urandom of=/mnt/ubifs/data bs=1K count=11
ubifs: warning, user block quota exceeded.
11+0 records in
11+0 records out
11264 bytes (11 kB) copied, 0.216498 s, 52.0 kB/s
[root@atest-guest linux_compile]# repquota /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      +-      11      10      10  7days       2     3     3   
[root@atest-guest linux_compile]# rm -rf /mnt/ubifs/data 
[root@atest-guest linux_compile]# repquota /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      --       0      10      10              1     3     3     


Dongsheng Yang (25):
  fs: introduce a ->s_cdev field into struct super_block
  ubi: introduce a interface to get cdev in ubi_volume
  ubifs: fill sb->s_cdev in ubifs_fill_super()
  fs: super: introduce the functions to get super by cdev reference
  fs: char_dev: introduce lookup_cdev function to find cdev by name
  fs: dquot: skip invalidate_bdev if bdev is NULL
  fs: quota: make quota support fs which is running on char dev
  ubifs: fix a typo in comment of ubifs_budget_req
  ubifs: extend budget for blocks
  ubifs: fill ->s_dev in ubifs_fill_super
  ubifs: export read_block() from file.c
  ubifs: introduce quota related mount options
  ubifs: introduce a field named as budgeted 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: suspend & resume quota properly in ubifs_remount
  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_write_begin
  ubifs: free quota space in do_truncation and unlink
  ubifs: adapt quota space informatin in do_setattr
  ubifs: transfer quota information in changing owner or group
  ubifs: implement ubifs_qctl_operations for quotactl
  ubifs: make ubifs to support quota

 drivers/mtd/ubi/kapi.c  |   6 +
 fs/char_dev.c           |  72 ++++++++++
 fs/quota/dquot.c        |   3 +-
 fs/quota/quota.c        |  30 +++--
 fs/super.c              |  45 +++++++
 fs/ubifs/budget.c       |   4 +
 fs/ubifs/debug.c        |   2 +
 fs/ubifs/dir.c          |  24 +++-
 fs/ubifs/file.c         |  56 +++++++-
 fs/ubifs/ioctl.c        |   1 +
 fs/ubifs/super.c        | 352 +++++++++++++++++++++++++++++++++++++++++++++++-
 fs/ubifs/ubifs.h        |  19 ++-
 include/linux/fs.h      |   5 +
 include/linux/mtd/ubi.h |   1 +
 14 files changed, 597 insertions(+), 23 deletions(-)

-- 
1.8.4.2


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

* [PATCH 01/25] fs: introduce a ->s_cdev field into struct super_block
  2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
@ 2015-07-21  8:37 ` Dongsheng Yang
  2015-07-21  8:37 ` [PATCH 02/25] ubi: introduce a interface to get cdev in ubi_volume Dongsheng Yang
                   ` (28 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, linux-mtd, 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 35ec87e..2f1d9499 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1284,6 +1284,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] 52+ messages in thread

* [PATCH 02/25] ubi: introduce a interface to get cdev in ubi_volume
  2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
  2015-07-21  8:37 ` [PATCH 01/25] fs: introduce a ->s_cdev field into struct super_block Dongsheng Yang
@ 2015-07-21  8:37 ` Dongsheng Yang
  2015-07-21  8:37 ` [PATCH 03/25] ubifs: fill sb->s_cdev in ubifs_fill_super() Dongsheng Yang
                   ` (27 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, linux-mtd, 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>
---
 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] 52+ messages in thread

* [PATCH 03/25] ubifs: fill sb->s_cdev in ubifs_fill_super()
  2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
  2015-07-21  8:37 ` [PATCH 01/25] fs: introduce a ->s_cdev field into struct super_block Dongsheng Yang
  2015-07-21  8:37 ` [PATCH 02/25] ubi: introduce a interface to get cdev in ubi_volume Dongsheng Yang
@ 2015-07-21  8:37 ` Dongsheng Yang
  2015-07-21  8:37 ` [PATCH 04/25] fs: super: introduce the functions to get super by cdev reference Dongsheng Yang
                   ` (26 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, linux-mtd, 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>
---
 fs/ubifs/super.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index c643261..3e4a01b 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -2031,6 +2031,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] 52+ messages in thread

* [PATCH 04/25] fs: super: introduce the functions to get super by cdev reference
  2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
                   ` (2 preceding siblings ...)
  2015-07-21  8:37 ` [PATCH 03/25] ubifs: fill sb->s_cdev in ubifs_fill_super() Dongsheng Yang
@ 2015-07-21  8:37 ` Dongsheng Yang
  2015-07-21  9:04   ` Jan Kara
  2015-07-21  8:37 ` [PATCH 05/25] fs: char_dev: introduce lookup_cdev function to find cdev by name Dongsheng Yang
                   ` (25 subsequent siblings)
  29 siblings, 1 reply; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, linux-mtd, Dongsheng Yang

As we have cdev in super block 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>
---
 fs/super.c         | 45 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/fs.h |  2 ++
 2 files changed, 47 insertions(+)

diff --git a/fs/super.c b/fs/super.c
index 928c20f..4a9031a 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -605,6 +605,37 @@ rescan:
 
 EXPORT_SYMBOL(get_super);
 
+struct super_block *get_super_cdev(struct cdev *cdev)
+{
+	struct super_block *sb;
+
+	if (!cdev)
+		return NULL;
+
+	spin_lock(&sb_lock);
+rescan:
+	list_for_each_entry(sb, &super_blocks, s_list) {
+		if (hlist_unhashed(&sb->s_instances))
+			continue;
+		if (sb->s_cdev == cdev) {
+			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;
+}
+EXPORT_SYMBOL(get_super_cdev);
+
 /**
  *	get_super_thawed - get thawed superblock of a device
  *	@bdev: device to get the superblock for
@@ -628,6 +659,20 @@ struct super_block *get_super_thawed(struct block_device *bdev)
 }
 EXPORT_SYMBOL(get_super_thawed);
 
+struct super_block *get_super_cdev_thawed(struct cdev *cdev)
+{
+	while (1) {
+		struct super_block *s = get_super_cdev(cdev);
+		if (!s || s->s_writers.frozen == SB_UNFROZEN)
+			return s;
+		up_read(&s->s_umount);
+		wait_event(s->s_writers.wait_unfrozen,
+			   s->s_writers.frozen == SB_UNFROZEN);
+		put_super(s);
+	}
+}
+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 2f1d9499..5c7d789 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2744,7 +2744,9 @@ 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_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] 52+ messages in thread

* [PATCH 05/25] fs: char_dev: introduce lookup_cdev function to find cdev by name
  2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
                   ` (3 preceding siblings ...)
  2015-07-21  8:37 ` [PATCH 04/25] fs: super: introduce the functions to get super by cdev reference Dongsheng Yang
@ 2015-07-21  8:37 ` Dongsheng Yang
  2015-07-21  9:20   ` Jan Kara
  2015-07-21  8:37 ` [PATCH 06/25] fs: dquot: skip invalidate_bdev if bdev is NULL Dongsheng Yang
                   ` (24 subsequent siblings)
  29 siblings, 1 reply; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, linux-mtd, Dongsheng Yang

Function lookup_cdev works similar 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>
---
 fs/char_dev.c      | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/fs.h |  2 ++
 2 files changed, 74 insertions(+)

diff --git a/fs/char_dev.c b/fs/char_dev.c
index ea06a3d..899f08b 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -22,6 +22,9 @@
 #include <linux/backing-dev.h>
 #include <linux/tty.h>
 
+#include <linux/namei.h>
+#include <linux/mount.h>
+
 #include "internal.h"
 
 static struct kobj_map *cdev_map;
@@ -439,6 +442,74 @@ static int exact_lock(dev_t dev, void *data)
 	return cdev_get(p) ? 0 : -1;
 }
 
+static 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;
+}
+
+struct cdev *lookup_cdev(const char *pathname)
+{
+	struct cdev *cdev;
+	struct inode *inode;
+	struct path path;
+	int error;
+
+	if (!pathname || !*pathname)
+		return ERR_PTR(-EINVAL);
+
+	error = kern_path(pathname, LOOKUP_FOLLOW, &path);
+	if (error)
+		return ERR_PTR(error);
+
+	inode = d_backing_inode(path.dentry);
+	error = -ENODEV;
+	if (!S_ISCHR(inode->i_mode))
+		goto fail;
+	error = -EACCES;
+	if (path.mnt->mnt_flags & MNT_NODEV)
+		goto fail;
+	error = -ENXIO;
+	cdev = cd_acquire(inode);
+	if (!cdev)
+		goto fail;
+out:
+	path_put(&path);
+	return cdev;
+fail:
+	cdev = ERR_PTR(error);
+	goto out;
+}
+
 /**
  * cdev_add() - add a char device to the system
  * @p: the cdev structure for the device
@@ -561,6 +632,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 5c7d789..860b235 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2308,6 +2308,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] 52+ messages in thread

* [PATCH 06/25] fs: dquot: skip invalidate_bdev if bdev is NULL
  2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
                   ` (4 preceding siblings ...)
  2015-07-21  8:37 ` [PATCH 05/25] fs: char_dev: introduce lookup_cdev function to find cdev by name Dongsheng Yang
@ 2015-07-21  8:37 ` Dongsheng Yang
  2015-07-21  8:37   ` Dongsheng Yang
                   ` (23 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, linux-mtd, Dongsheng Yang

There would be a NULL pointer dereference if bdev is NULL

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.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] 52+ messages in thread

* [PATCH 07/25] fs: quota: make quota support fs which is running on char dev
  2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
@ 2015-07-21  8:37   ` Dongsheng Yang
  2015-07-21  8:37 ` [PATCH 02/25] ubi: introduce a interface to get cdev in ubi_volume Dongsheng Yang
                     ` (28 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

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


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

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

* [PATCH 07/25] fs: quota: make quota support fs which is running on char dev
@ 2015-07-21  8:37   ` Dongsheng Yang
  0 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, linux-mtd, 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] 52+ messages in thread

* [PATCH 08/25] ubifs: fix a typo in comment of ubifs_budget_req
  2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
@ 2015-07-21  8:37   ` Dongsheng Yang
  2015-07-21  8:37 ` [PATCH 02/25] ubi: introduce a interface to get cdev in ubi_volume Dongsheng Yang
                     ` (28 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

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

diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index de75902..6ef2415 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -858,9 +858,9 @@ struct ubifs_compressor {
  * @mod_dent: non-zero if the operation removes or modifies an existing
  *            directory entry
  * @new_ino: non-zero if the operation adds a new inode
- * @new_ino_d: now much data newly created inode contains
+ * @new_ino_d: how much data newly created inode contains
  * @dirtied_ino: how many inodes the operation makes dirty
- * @dirtied_ino_d: now much data dirtied inode contains
+ * @dirtied_ino_d: how much data dirtied inode contains
  * @idx_growth: how much the index will supposedly grow
  * @data_growth: how much new data the operation will supposedly add
  * @dd_growth: how much data that makes other data dirty the operation will
-- 
1.8.4.2


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

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

* [PATCH 08/25] ubifs: fix a typo in comment of ubifs_budget_req
@ 2015-07-21  8:37   ` Dongsheng Yang
  0 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, linux-mtd, Dongsheng Yang

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

diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index de75902..6ef2415 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -858,9 +858,9 @@ struct ubifs_compressor {
  * @mod_dent: non-zero if the operation removes or modifies an existing
  *            directory entry
  * @new_ino: non-zero if the operation adds a new inode
- * @new_ino_d: now much data newly created inode contains
+ * @new_ino_d: how much data newly created inode contains
  * @dirtied_ino: how many inodes the operation makes dirty
- * @dirtied_ino_d: now much data dirtied inode contains
+ * @dirtied_ino_d: how much data dirtied inode contains
  * @idx_growth: how much the index will supposedly grow
  * @data_growth: how much new data the operation will supposedly add
  * @dd_growth: how much data that makes other data dirty the operation will
-- 
1.8.4.2

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

* [PATCH 09/25] ubifs: extend budget for blocks
  2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
@ 2015-07-21  8:37   ` Dongsheng Yang
  2015-07-21  8:37 ` [PATCH 02/25] ubi: introduce a interface to get cdev in ubi_volume Dongsheng Yang
                     ` (28 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  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  | 5 +++++
 4 files changed, 12 insertions(+)

diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c
index 11a11b3..ba4e530 100644
--- a/fs/ubifs/budget.c
+++ b/fs/ubifs/budget.c
@@ -397,6 +397,8 @@ static int calc_data_growth(const struct ubifs_info *c,
 		data_growth += c->bi.page_budget;
 	if (req->new_dent)
 		data_growth += c->bi.dent_budget;
+	if (req->new_block_num)
+		data_growth += c->bi.block_budget * req->new_block_num;
 	data_growth += req->new_ino_d;
 	return data_growth;
 }
@@ -418,6 +420,8 @@ static int calc_dd_growth(const struct ubifs_info *c,
 		dd_growth += c->bi.inode_budget << (req->dirtied_ino - 1);
 	if (req->mod_dent)
 		dd_growth += c->bi.dent_budget;
+	if (req->dirtied_block_num)
+		dd_growth += c->bi.block_budget * req->dirtied_block_num;
 	dd_growth += req->dirtied_ino_d;
 	return dd_growth;
 }
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 4c46a98..cafd592 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_num, req->dirtied_block_num);
 	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 3e4a01b..27e1739 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -698,6 +698,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 6ef2415..ae6723e 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -861,6 +861,8 @@ struct ubifs_compressor {
  * @new_ino_d: how much data newly created inode contains
  * @dirtied_ino: how many inodes the operation makes dirty
  * @dirtied_ino_d: how much data dirtied inode contains
+ * @new_block_num: how many new blocks
+ * @dirtied_block_num: how many dirtied blocks
  * @idx_growth: how much the index will supposedly grow
  * @data_growth: how much new data the operation will supposedly add
  * @dd_growth: how much data that makes other data dirty the operation will
@@ -902,6 +904,8 @@ struct ubifs_budget_req {
 	unsigned int dirtied_ino;
 	unsigned int dirtied_ino_d;
 #endif
+	unsigned int new_block_num;
+	unsigned int dirtied_block_num;
 	int idx_growth;
 	int data_growth;
 	int dd_growth;
@@ -983,6 +987,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] 52+ messages in thread

* [PATCH 09/25] ubifs: extend budget for blocks
@ 2015-07-21  8:37   ` Dongsheng Yang
  0 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, linux-mtd, 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  | 5 +++++
 4 files changed, 12 insertions(+)

diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c
index 11a11b3..ba4e530 100644
--- a/fs/ubifs/budget.c
+++ b/fs/ubifs/budget.c
@@ -397,6 +397,8 @@ static int calc_data_growth(const struct ubifs_info *c,
 		data_growth += c->bi.page_budget;
 	if (req->new_dent)
 		data_growth += c->bi.dent_budget;
+	if (req->new_block_num)
+		data_growth += c->bi.block_budget * req->new_block_num;
 	data_growth += req->new_ino_d;
 	return data_growth;
 }
@@ -418,6 +420,8 @@ static int calc_dd_growth(const struct ubifs_info *c,
 		dd_growth += c->bi.inode_budget << (req->dirtied_ino - 1);
 	if (req->mod_dent)
 		dd_growth += c->bi.dent_budget;
+	if (req->dirtied_block_num)
+		dd_growth += c->bi.block_budget * req->dirtied_block_num;
 	dd_growth += req->dirtied_ino_d;
 	return dd_growth;
 }
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 4c46a98..cafd592 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_num, req->dirtied_block_num);
 	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 3e4a01b..27e1739 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -698,6 +698,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 6ef2415..ae6723e 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -861,6 +861,8 @@ struct ubifs_compressor {
  * @new_ino_d: how much data newly created inode contains
  * @dirtied_ino: how many inodes the operation makes dirty
  * @dirtied_ino_d: how much data dirtied inode contains
+ * @new_block_num: how many new blocks
+ * @dirtied_block_num: how many dirtied blocks
  * @idx_growth: how much the index will supposedly grow
  * @data_growth: how much new data the operation will supposedly add
  * @dd_growth: how much data that makes other data dirty the operation will
@@ -902,6 +904,8 @@ struct ubifs_budget_req {
 	unsigned int dirtied_ino;
 	unsigned int dirtied_ino_d;
 #endif
+	unsigned int new_block_num;
+	unsigned int dirtied_block_num;
 	int idx_growth;
 	int data_growth;
 	int dd_growth;
@@ -983,6 +987,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] 52+ messages in thread

* [PATCH 10/25] ubifs: fill ->s_dev in ubifs_fill_super
  2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
                   ` (8 preceding siblings ...)
  2015-07-21  8:37   ` Dongsheng Yang
@ 2015-07-21  8:37 ` Dongsheng Yang
  2015-07-21  8:37 ` [PATCH 11/25] ubifs: export read_block() from file.c Dongsheng Yang
                   ` (19 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, linux-mtd, 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>
---
 fs/ubifs/super.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 27e1739..161b1a6 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"
 
 /*
@@ -2033,6 +2034,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] 52+ messages in thread

* [PATCH 11/25] ubifs: export read_block() from file.c
  2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
                   ` (9 preceding siblings ...)
  2015-07-21  8:37 ` [PATCH 10/25] ubifs: fill ->s_dev in ubifs_fill_super Dongsheng Yang
@ 2015-07-21  8:37 ` Dongsheng Yang
  2015-07-21 20:36   ` Richard Weinberger
  2015-07-21  8:37 ` [PATCH 12/25] ubifs: introduce quota related mount options Dongsheng Yang
                   ` (18 subsequent siblings)
  29 siblings, 1 reply; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, linux-mtd, 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>
---
 fs/ubifs/file.c  | 2 +-
 fs/ubifs/ubifs.h | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 27de484..dc8bf0b 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -54,7 +54,7 @@
 #include <linux/namei.h>
 #include <linux/slab.h>
 
-static int read_block(struct inode *inode, void *addr, unsigned int block,
+int 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;
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index ae6723e..a6ad955 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -1749,6 +1749,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 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);
 
-- 
1.8.4.2


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

* [PATCH 12/25] ubifs: introduce quota related mount options
  2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
                   ` (10 preceding siblings ...)
  2015-07-21  8:37 ` [PATCH 11/25] ubifs: export read_block() from file.c Dongsheng Yang
@ 2015-07-21  8:37 ` Dongsheng Yang
  2015-07-21 20:39   ` Richard Weinberger
  2015-07-21  8:37   ` Dongsheng Yang
                   ` (17 subsequent siblings)
  29 siblings, 1 reply; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, linux-mtd, Dongsheng Yang

This commit introduce mount options of quota, noquota,
usrquota and grpquota. These options are used to make
ubifs support quota. But with this commit, quota will
not working on ubifs actually. We just introduce options
here and will make ubifs support quota later.

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

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 161b1a6..2491fff 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 "ubifs.h"
 
@@ -439,6 +440,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));
@@ -930,6 +937,10 @@ enum {
 	Opt_chk_data_crc,
 	Opt_no_chk_data_crc,
 	Opt_override_compr,
+	Opt_ignore,
+	Opt_quota,
+	Opt_usrquota,
+	Opt_grpquota,
 	Opt_err,
 };
 
@@ -941,6 +952,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},
 };
 
@@ -1041,6 +1056,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 a6ad955..9754bb6 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;
@@ -1039,6 +1042,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
@@ -1280,6 +1285,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] 52+ messages in thread

* [PATCH 13/25] ubifs: introduce a field named as budgeted to ubifs_inode
  2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
@ 2015-07-21  8:37   ` Dongsheng Yang
  2015-07-21  8:37 ` [PATCH 02/25] ubi: introduce a interface to get cdev in ubi_volume Dongsheng Yang
                     ` (28 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

There is a long-term pain in ubifs, we have to introduce a
ui_mutex in ubifs_inode to solve two problems below:

1: make some process atomic, such as ubifs_rename.
2: make sure we budget space for inode before dirting it.

About 1, it's true and we have to do it.

About 2, we can do it better.
	There is a ubifs_assert(mutex_is_locked(&ui->mutex)) in
ubifs_dirty_inode(). But there is probably some processes
are very long, and we can not make all of it into a pair of
lock/unlock ui->mutex.

E.g: dquot_disable().
	It would mark the quota files as dirty and write the
inode back. We can do a budget before this function, but we
can not make the whole dquot_disable() into mutex_lock/mutex_unlock.
Because we need to lock the ui_mutex in dquot_disable().

So, this commit introduce a ui->budgeted to allow us to make
budgeting and dirting in two different lock windows.

Result:
	ubifs_budget_space()
	mutex_lock();
	ui->budgeted = 1;
	mutex_unlock();
	...
	dquot_disable();

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

diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index dc8bf0b..113c3a6 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -307,6 +307,7 @@ static int write_begin_slow(struct address_space *mapping,
 			 * budget we allocated.
 			 */
 			ubifs_release_dirty_inode_budget(c, ui);
+		ui->budgeted = 1;
 	}
 
 	*pagep = page;
@@ -357,6 +358,7 @@ static int allocate_budget(struct ubifs_info *c, struct page *page,
 		 * we need to budget the inode change.
 		 */
 		req.dirtied_ino = 1;
+		ui->budgeted = 1;
 	} else {
 		if (PageChecked(page))
 			/*
@@ -384,6 +386,7 @@ static int allocate_budget(struct ubifs_info *c, struct page *page,
 				 * needs a budget.
 				 */
 				req.dirtied_ino = 1;
+			ui->budgeted = 1;
 		}
 	}
 
@@ -1237,6 +1240,7 @@ static int do_setattr(struct ubifs_info *c, struct inode *inode,
 	do_attr_changes(inode, attr);
 
 	release = ui->dirty;
+	ui->budgeted = 1;
 	if (attr->ia_valid & ATTR_SIZE)
 		/*
 		 * Inode length changed, so we have to make sure
@@ -1397,6 +1401,7 @@ static int ubifs_update_time(struct inode *inode, struct timespec *time,
 		iflags |= I_DIRTY_SYNC;
 
 	release = ui->dirty;
+	ui->budgeted = 1;
 	__mark_inode_dirty(inode, iflags);
 	mutex_unlock(&ui->ui_mutex);
 	if (release)
@@ -1430,6 +1435,7 @@ static int update_mctime(struct inode *inode)
 		mutex_lock(&ui->ui_mutex);
 		inode->i_mtime = inode->i_ctime = ubifs_current_time(inode);
 		release = ui->dirty;
+		ui->budgeted = 1;
 		mark_inode_dirty_sync(inode);
 		mutex_unlock(&ui->ui_mutex);
 		if (release)
@@ -1556,6 +1562,7 @@ static int ubifs_vm_page_mkwrite(struct vm_area_struct *vma,
 		mutex_lock(&ui->ui_mutex);
 		inode->i_mtime = inode->i_ctime = ubifs_current_time(inode);
 		release = ui->dirty;
+		ui->budgeted = 1;
 		mark_inode_dirty_sync(inode);
 		mutex_unlock(&ui->ui_mutex);
 		if (release)
diff --git a/fs/ubifs/ioctl.c b/fs/ubifs/ioctl.c
index 3c7b29d..f015b81 100644
--- a/fs/ubifs/ioctl.c
+++ b/fs/ubifs/ioctl.c
@@ -128,6 +128,7 @@ static int setflags(struct inode *inode, int flags)
 	ubifs_set_inode_flags(inode);
 	inode->i_ctime = ubifs_current_time(inode);
 	release = ui->dirty;
+	ui->budgeted = 1;
 	mark_inode_dirty_sync(inode);
 	mutex_unlock(&ui->ui_mutex);
 
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 2491fff..5fa21d6 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -331,6 +331,7 @@ static int ubifs_write_inode(struct inode *inode, struct writeback_control *wbc)
 	}
 
 	ui->dirty = 0;
+	ui->budgeted = 0;
 	mutex_unlock(&ui->ui_mutex);
 	ubifs_release_dirty_inode_budget(c, ui);
 	return err;
@@ -386,12 +387,23 @@ done:
 static void ubifs_dirty_inode(struct inode *inode, int flags)
 {
         struct ubifs_inode *ui = ubifs_inode(inode);
+	int need_unlock = 0;
 
-	ubifs_assert(mutex_is_locked(&ui->ui_mutex));
+	if (unlikely(!mutex_is_locked(&ui->ui_mutex))) {
+		/* We need to lock ui_mutex to access ui->budgeted */
+		mutex_lock(&ui->ui_mutex);
+		need_unlock = 1;
+	}
+
+	/* Check the budget for this inode */
+	ubifs_assert(ui->budgeted);
 	if (!ui->dirty) {
 		ui->dirty = 1;
 		dbg_gen("inode %lu",  inode->i_ino);
 	}
+
+	if (need_unlock)
+		mutex_unlock(&ui->ui_mutex);
 }
 
 static int ubifs_statfs(struct dentry *dentry, struct kstatfs *buf)
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 9754bb6..28392a6 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -410,6 +410,7 @@ struct ubifs_inode {
 	unsigned int xattr_cnt;
 	unsigned int xattr_names;
 	unsigned int dirty:1;
+	unsigned int budgeted:1;
 	unsigned int xattr:1;
 	unsigned int bulk_read:1;
 	unsigned int compr_type:2;
-- 
1.8.4.2


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

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

* [PATCH 13/25] ubifs: introduce a field named as budgeted to ubifs_inode
@ 2015-07-21  8:37   ` Dongsheng Yang
  0 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, linux-mtd, Dongsheng Yang

There is a long-term pain in ubifs, we have to introduce a
ui_mutex in ubifs_inode to solve two problems below:

1: make some process atomic, such as ubifs_rename.
2: make sure we budget space for inode before dirting it.

About 1, it's true and we have to do it.

About 2, we can do it better.
	There is a ubifs_assert(mutex_is_locked(&ui->mutex)) in
ubifs_dirty_inode(). But there is probably some processes
are very long, and we can not make all of it into a pair of
lock/unlock ui->mutex.

E.g: dquot_disable().
	It would mark the quota files as dirty and write the
inode back. We can do a budget before this function, but we
can not make the whole dquot_disable() into mutex_lock/mutex_unlock.
Because we need to lock the ui_mutex in dquot_disable().

So, this commit introduce a ui->budgeted to allow us to make
budgeting and dirting in two different lock windows.

Result:
	ubifs_budget_space()
	mutex_lock();
	ui->budgeted = 1;
	mutex_unlock();
	...
	dquot_disable();

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

diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index dc8bf0b..113c3a6 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -307,6 +307,7 @@ static int write_begin_slow(struct address_space *mapping,
 			 * budget we allocated.
 			 */
 			ubifs_release_dirty_inode_budget(c, ui);
+		ui->budgeted = 1;
 	}
 
 	*pagep = page;
@@ -357,6 +358,7 @@ static int allocate_budget(struct ubifs_info *c, struct page *page,
 		 * we need to budget the inode change.
 		 */
 		req.dirtied_ino = 1;
+		ui->budgeted = 1;
 	} else {
 		if (PageChecked(page))
 			/*
@@ -384,6 +386,7 @@ static int allocate_budget(struct ubifs_info *c, struct page *page,
 				 * needs a budget.
 				 */
 				req.dirtied_ino = 1;
+			ui->budgeted = 1;
 		}
 	}
 
@@ -1237,6 +1240,7 @@ static int do_setattr(struct ubifs_info *c, struct inode *inode,
 	do_attr_changes(inode, attr);
 
 	release = ui->dirty;
+	ui->budgeted = 1;
 	if (attr->ia_valid & ATTR_SIZE)
 		/*
 		 * Inode length changed, so we have to make sure
@@ -1397,6 +1401,7 @@ static int ubifs_update_time(struct inode *inode, struct timespec *time,
 		iflags |= I_DIRTY_SYNC;
 
 	release = ui->dirty;
+	ui->budgeted = 1;
 	__mark_inode_dirty(inode, iflags);
 	mutex_unlock(&ui->ui_mutex);
 	if (release)
@@ -1430,6 +1435,7 @@ static int update_mctime(struct inode *inode)
 		mutex_lock(&ui->ui_mutex);
 		inode->i_mtime = inode->i_ctime = ubifs_current_time(inode);
 		release = ui->dirty;
+		ui->budgeted = 1;
 		mark_inode_dirty_sync(inode);
 		mutex_unlock(&ui->ui_mutex);
 		if (release)
@@ -1556,6 +1562,7 @@ static int ubifs_vm_page_mkwrite(struct vm_area_struct *vma,
 		mutex_lock(&ui->ui_mutex);
 		inode->i_mtime = inode->i_ctime = ubifs_current_time(inode);
 		release = ui->dirty;
+		ui->budgeted = 1;
 		mark_inode_dirty_sync(inode);
 		mutex_unlock(&ui->ui_mutex);
 		if (release)
diff --git a/fs/ubifs/ioctl.c b/fs/ubifs/ioctl.c
index 3c7b29d..f015b81 100644
--- a/fs/ubifs/ioctl.c
+++ b/fs/ubifs/ioctl.c
@@ -128,6 +128,7 @@ static int setflags(struct inode *inode, int flags)
 	ubifs_set_inode_flags(inode);
 	inode->i_ctime = ubifs_current_time(inode);
 	release = ui->dirty;
+	ui->budgeted = 1;
 	mark_inode_dirty_sync(inode);
 	mutex_unlock(&ui->ui_mutex);
 
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 2491fff..5fa21d6 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -331,6 +331,7 @@ static int ubifs_write_inode(struct inode *inode, struct writeback_control *wbc)
 	}
 
 	ui->dirty = 0;
+	ui->budgeted = 0;
 	mutex_unlock(&ui->ui_mutex);
 	ubifs_release_dirty_inode_budget(c, ui);
 	return err;
@@ -386,12 +387,23 @@ done:
 static void ubifs_dirty_inode(struct inode *inode, int flags)
 {
         struct ubifs_inode *ui = ubifs_inode(inode);
+	int need_unlock = 0;
 
-	ubifs_assert(mutex_is_locked(&ui->ui_mutex));
+	if (unlikely(!mutex_is_locked(&ui->ui_mutex))) {
+		/* We need to lock ui_mutex to access ui->budgeted */
+		mutex_lock(&ui->ui_mutex);
+		need_unlock = 1;
+	}
+
+	/* Check the budget for this inode */
+	ubifs_assert(ui->budgeted);
 	if (!ui->dirty) {
 		ui->dirty = 1;
 		dbg_gen("inode %lu",  inode->i_ino);
 	}
+
+	if (need_unlock)
+		mutex_unlock(&ui->ui_mutex);
 }
 
 static int ubifs_statfs(struct dentry *dentry, struct kstatfs *buf)
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 9754bb6..28392a6 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -410,6 +410,7 @@ struct ubifs_inode {
 	unsigned int xattr_cnt;
 	unsigned int xattr_names;
 	unsigned int dirty:1;
+	unsigned int budgeted:1;
 	unsigned int xattr:1;
 	unsigned int bulk_read:1;
 	unsigned int compr_type:2;
-- 
1.8.4.2

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

* [PATCH 14/25] ubifs: implement IO functions for quota files
  2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
                   ` (12 preceding siblings ...)
  2015-07-21  8:37   ` Dongsheng Yang
@ 2015-07-21  8:37 ` Dongsheng Yang
  2015-07-21  8:37 ` [PATCH 15/25] ubifs: disable quota in ubifs_put_super Dongsheng Yang
                   ` (15 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, linux-mtd, 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 | 206 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 206 insertions(+)

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 5fa21d6..4e60330 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -929,6 +929,207 @@ 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;
+	loff_t i_size = i_size_read(inode);
+	char *block_buf;
+	struct ubifs_data_node *dn;
+	int ret, err = 0;
+
+	if (off > i_size)
+		goto out;
+
+	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;
+	}
+
+	if (offset) {
+		/* Read the un-aligned data in first block */
+		tocopy = sb->s_blocksize - offset;
+		if (toread < tocopy)
+			tocopy = toread;
+
+		ret = read_block(inode, block_buf, block, dn);
+		if (ret) {
+			err = ret;
+			if (err != ENOENT) {
+				goto free_buf;
+			}
+		}
+
+		memcpy(data, block_buf + offset, tocopy);
+
+		block++;
+		toread -= tocopy;
+		data += tocopy;
+		tocopy = 0;
+	}
+
+	while (toread > 0) {
+		tocopy = sb->s_blocksize < toread ?
+				sb->s_blocksize : toread;
+
+		/* Break to read the last block */
+		if (tocopy < sb->s_blocksize)
+			break;
+
+		ret = read_block(inode, data, block, dn);
+		if (ret) {
+			err = ret;
+			if (err != -ENOENT)
+				goto free_buf;
+		}
+		block++;;
+		toread -= tocopy;
+		data += tocopy;
+		tocopy = 0;
+	}
+
+	if (tocopy) {
+		/* Read the data in last block */
+		ret = read_block(inode, block_buf, block, dn);
+		if (ret) {
+			err = ret;
+			if (err != ENOENT) {
+				goto free_buf;
+			}
+		}
+
+		memcpy(data, block_buf, 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;
+	unsigned long blocks = len >> 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 = {};
+	int dirtied_block = 0, new_block = 0;
+
+	if (off + len > inode->i_size)
+		new_block = (off + len - inode->i_size) >> UBIFS_BLOCK_SHIFT;
+	dirtied_block = blocks - new_block;
+	if (offset)
+		dirtied_block += 1;
+	req.dirtied_block_num = dirtied_block;
+	req.new_block_num = new_block;
+
+	err = ubifs_budget_space(c, &req);
+	if (err)
+		goto out;
+
+	if (offset) {
+		struct ubifs_data_node *dn;
+		char *block_buf;
+
+		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;
+			kfree(dn);
+			goto release_budget;
+		}
+
+		/* Write the un-aligned data in first block */
+		tocopy = sb->s_blocksize - offset;
+		if (towrite < tocopy)
+			tocopy = towrite;
+
+		ret = read_block(inode, block_buf, block, dn);
+		if (ret) {
+			err = ret;
+			if (err != ENOENT) {
+				kfree(block_buf);
+				kfree(dn);
+				goto release_budget;
+			}
+		}
+
+		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) {
+			kfree(block_buf);
+			kfree(dn);
+			goto release_budget;
+		}
+
+		block++;
+		towrite -= tocopy;
+		data += tocopy;
+	}
+
+	while (towrite > 0) {
+		tocopy = sb->s_blocksize < towrite ?
+				sb->s_blocksize : towrite;
+
+		data_key_init(c, &key, inode->i_ino, block);
+		err = ubifs_jnl_write_data(c, inode, &key, data, tocopy);
+		if (err)
+			break;
+		block++;;
+		towrite -= tocopy;
+		data += tocopy;
+	}
+
+	err = inode->i_sb->s_op->write_inode(inode, NULL);
+release_budget:
+	/* quota write success, we have to release the 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.
  *
@@ -1928,6 +2129,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] 52+ messages in thread

* [PATCH 15/25] ubifs: disable quota in ubifs_put_super
  2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
                   ` (13 preceding siblings ...)
  2015-07-21  8:37 ` [PATCH 14/25] ubifs: implement IO functions for quota files Dongsheng Yang
@ 2015-07-21  8:37 ` Dongsheng Yang
  2015-07-21  8:37 ` [PATCH 16/25] ubifs: write quota back in ubifs_sync Dongsheng Yang
                   ` (14 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, linux-mtd, 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 | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 4e60330..e53cd40 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -2003,6 +2003,34 @@ static void ubifs_put_super(struct super_block *sb)
 
 	ubifs_msg(c, "un-mount UBI device %d", c->vi.ubi_num);
 
+	if (!c->ro_mount) {
+		struct quota_info *dqopt = sb_dqopt(sb);
+		struct inode *inodes[MAXQUOTAS] = {};
+		struct inode *tmp = NULL;
+		struct ubifs_inode *ui = NULL;
+		struct ubifs_budget_req req = {};
+		int cnt = 0;
+		int index = 0;
+
+		for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+			if (!sb_has_quota_loaded(sb, cnt))
+				continue;
+			req.dirtied_ino += 1;
+			inodes[index++] = dqopt->files[cnt];
+		}
+		ubifs_budget_space(c, &req);
+
+		for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+			tmp = inodes[cnt];
+			if (!tmp)
+				break;
+			ui = ubifs_inode(tmp);
+			mutex_lock(&ui->ui_mutex);
+			ui->budgeted = 1;
+			mutex_unlock(&ui->ui_mutex);
+		}
+		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] 52+ messages in thread

* [PATCH 16/25] ubifs: write quota back in ubifs_sync
  2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
                   ` (14 preceding siblings ...)
  2015-07-21  8:37 ` [PATCH 15/25] ubifs: disable quota in ubifs_put_super Dongsheng Yang
@ 2015-07-21  8:37 ` Dongsheng Yang
  2015-07-21  8:37   ` Dongsheng Yang
                   ` (13 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, linux-mtd, Dongsheng Yang

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 e53cd40..b8cc291 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -479,6 +479,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] 52+ messages in thread

* [PATCH 17/25] ubifs: suspend & resume quota properly in ubifs_remount
  2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
@ 2015-07-21  8:37   ` Dongsheng Yang
  2015-07-21  8:37 ` [PATCH 02/25] ubi: introduce a interface to get cdev in ubi_volume Dongsheng Yang
                     ` (28 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, Dongsheng Yang, linux-mtd

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 b8cc291..0638436 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -2125,6 +2125,7 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
 			ubifs_msg(c, "cannot re-mount R/W - UBI volume is R/O");
 			return -EROFS;
 		}
+		dquot_resume(sb, -1);
 		err = ubifs_remount_rw(c);
 		if (err)
 			return err;
@@ -2133,6 +2134,7 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
 			ubifs_msg(c, "cannot re-mount R/O due to prior errors");
 			return -EROFS;
 		}
+		dquot_suspend(sb, -1);
 		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] 52+ messages in thread

* [PATCH 17/25] ubifs: suspend & resume quota properly in ubifs_remount
@ 2015-07-21  8:37   ` Dongsheng Yang
  0 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, linux-mtd, Dongsheng Yang

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 b8cc291..0638436 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -2125,6 +2125,7 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
 			ubifs_msg(c, "cannot re-mount R/W - UBI volume is R/O");
 			return -EROFS;
 		}
+		dquot_resume(sb, -1);
 		err = ubifs_remount_rw(c);
 		if (err)
 			return err;
@@ -2133,6 +2134,7 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
 			ubifs_msg(c, "cannot re-mount R/O due to prior errors");
 			return -EROFS;
 		}
+		dquot_suspend(sb, -1);
 		ubifs_remount_ro(c);
 	}
 
-- 
1.8.4.2

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

* [PATCH 18/25] ubifs: record quota information about inode in ubifs_new_inode
  2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
                   ` (16 preceding siblings ...)
  2015-07-21  8:37   ` Dongsheng Yang
@ 2015-07-21  8:37 ` Dongsheng Yang
  2015-07-21  8:37 ` [PATCH 19/25] ubifs: free quota inode information in ubifs_evict_inode Dongsheng Yang
                   ` (11 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, linux-mtd, 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 | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 27060fc..01cbc8b 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,12 +91,18 @@ 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);
-	ui = ubifs_inode(inode);
 	if (!inode)
 		return ERR_PTR(-ENOMEM);
 
+	dquot_initialize(inode);
+        err = dquot_alloc_inode(inode);
+        if (err)
+                goto fail_drop;
+
+	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()').
@@ -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] 52+ messages in thread

* [PATCH 19/25] ubifs: free quota inode information in ubifs_evict_inode
  2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
                   ` (17 preceding siblings ...)
  2015-07-21  8:37 ` [PATCH 18/25] ubifs: record quota information about inode in ubifs_new_inode Dongsheng Yang
@ 2015-07-21  8:37 ` Dongsheng Yang
  2015-07-21  8:37 ` [PATCH 20/25] ubifs: alloc quota space in ubifs_write_begin Dongsheng Yang
                   ` (10 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, linux-mtd, 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 0638436..60deed2 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] 52+ messages in thread

* [PATCH 20/25] ubifs: alloc quota space in ubifs_write_begin
  2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
                   ` (18 preceding siblings ...)
  2015-07-21  8:37 ` [PATCH 19/25] ubifs: free quota inode information in ubifs_evict_inode Dongsheng Yang
@ 2015-07-21  8:37 ` Dongsheng Yang
  2015-07-21  8:37 ` [PATCH 21/25] ubifs: free quota space in do_truncation and unlink Dongsheng Yang
                   ` (9 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, linux-mtd, Dongsheng Yang

Besides inode, quota also limit the space. When
use 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 | 27 +++++++++++++++++++++++----
 1 file changed, 23 insertions(+), 4 deletions(-)

diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 113c3a6..0c03a88 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -53,6 +53,7 @@
 #include <linux/mount.h>
 #include <linux/namei.h>
 #include <linux/slab.h>
+#include <linux/quotaops.h>
 
 int read_block(struct inode *inode, void *addr, unsigned int block,
 		      struct ubifs_data_node *dn)
@@ -434,8 +435,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);
@@ -443,10 +446,19 @@ 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;
+	ret = dquot_alloc_space_nodirty(inode, quota_size);
+	if (unlikely(ret))
+		goto err;
+
 	/* Try out the fast-path part first */
 	page = grab_cache_page_write_begin(mapping, index, flags);
-	if (unlikely(!page))
-		return -ENOMEM;
+	if (unlikely(!page)) {
+		ret = -ENOMEM;
+		goto free_quot;
+	}
 
 	if (!PageUptodate(page)) {
 		/* The page is not loaded from the flash */
@@ -500,7 +512,9 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
 		unlock_page(page);
 		page_cache_release(page);
 
-		return write_begin_slow(mapping, pos, len, pagep, flags);
+		ret = write_begin_slow(mapping, pos, len, pagep, flags);
+		if (unlikely(ret))
+			goto free_quot;
 	}
 
 	/*
@@ -510,7 +524,12 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
 	 * otherwise. This is an optimization (slightly hacky though).
 	 */
 	*pagep = page;
-	return 0;
+
+	return ret;
+free_quot:
+	dquot_free_space_nodirty(inode, quota_size);
+err:
+	return ret;
 
 }
 
-- 
1.8.4.2


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

* [PATCH 21/25] ubifs: free quota space in do_truncation and unlink
  2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
                   ` (19 preceding siblings ...)
  2015-07-21  8:37 ` [PATCH 20/25] ubifs: alloc quota space in ubifs_write_begin Dongsheng Yang
@ 2015-07-21  8:37 ` Dongsheng Yang
  2015-07-21  8:37 ` [PATCH 22/25] ubifs: adapt quota space informatin in do_setattr Dongsheng Yang
                   ` (8 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, linux-mtd, Dongsheng Yang

In truncation and unlink, 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/dir.c  | 4 ++++
 fs/ubifs/file.c | 4 ++++
 2 files changed, 8 insertions(+)

diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 01cbc8b..b83ebb6 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -574,6 +574,7 @@ static int ubifs_unlink(struct inode *dir, struct dentry *dentry)
 	int err, budgeted = 1;
 	struct ubifs_budget_req req = { .mod_dent = 1, .dirtied_ino = 2 };
 	unsigned int saved_nlink = inode->i_nlink;
+	loff_t quota_size = inode->i_size;
 
 	/*
 	 * Budget request settings: deletion direntry, deletion inode (+1 for
@@ -607,8 +608,11 @@ static int ubifs_unlink(struct inode *dir, struct dentry *dentry)
 	err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 1, 0);
 	if (err)
 		goto out_cancel;
+
 	unlock_2_inodes(dir, inode);
 
+	dquot_free_space_nodirty(inode, quota_size);
+
 	if (budgeted)
 		ubifs_release_budget(c, &req);
 	else {
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 0c03a88..b907f197 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1130,6 +1130,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);
 
@@ -1209,6 +1210,9 @@ 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;
+	dquot_free_space_nodirty(inode, quota_size);
 
 out_budg:
 	if (budgeted)
-- 
1.8.4.2


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

* [PATCH 22/25] ubifs: adapt quota space informatin in do_setattr
  2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
                   ` (20 preceding siblings ...)
  2015-07-21  8:37 ` [PATCH 21/25] ubifs: free quota space in do_truncation and unlink Dongsheng Yang
@ 2015-07-21  8:37 ` Dongsheng Yang
  2015-07-21  8:37 ` [PATCH 23/25] ubifs: transfer quota information in changing owner or group Dongsheng Yang
                   ` (7 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, linux-mtd, 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 | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index b907f197..aac10bd 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1249,6 +1249,13 @@ 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 (new_size > inode->i_size) {
+			err = dquot_alloc_space_nodirty(inode, new_size - inode->i_size);
+			if (err)
+				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] 52+ messages in thread

* [PATCH 23/25] ubifs: transfer quota information in changing owner or group
  2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
                   ` (21 preceding siblings ...)
  2015-07-21  8:37 ` [PATCH 22/25] ubifs: adapt quota space informatin in do_setattr Dongsheng Yang
@ 2015-07-21  8:37 ` Dongsheng Yang
  2015-07-21  8:37 ` [PATCH 24/25] ubifs: implement ubifs_qctl_operations for quotactl Dongsheng Yang
                   ` (6 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, linux-mtd, 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 aac10bd..e9844ef 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1304,6 +1304,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] 52+ messages in thread

* [PATCH 24/25] ubifs: implement ubifs_qctl_operations for quotactl
  2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
                   ` (22 preceding siblings ...)
  2015-07-21  8:37 ` [PATCH 23/25] ubifs: transfer quota information in changing owner or group Dongsheng Yang
@ 2015-07-21  8:37 ` Dongsheng Yang
  2015-07-21  8:37 ` [PATCH 25/25] ubifs: make ubifs to support quota Dongsheng Yang
                   ` (5 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, linux-mtd, Dongsheng Yang

To make ubifs support quota, we have to provide a qctl_operations
to quotactl. But we can not use the default operations. The problem
is quota_off function. We have to do a budget at first before
disabling quota.

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

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 60deed2..00451b0 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -2278,6 +2278,62 @@ static struct ubifs_info *alloc_ubifs_info(struct ubi_volume_desc *ubi)
 	return c;
 }
 
+#ifdef CONFIG_QUOTA
+static int ubifs_quota_off(struct super_block *sb, int type)
+{
+	struct ubifs_budget_req req = {};
+	struct ubifs_info *c = sb->s_fs_info;
+	struct quota_info *dqopt = sb_dqopt(sb);
+	struct inode *inodes[MAXQUOTAS] = {};
+	struct inode *tmp = NULL;
+	struct ubifs_inode *ui = NULL;
+	int ret = 0;
+	int cnt = 0;
+
+	if (type == -1) {
+		for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+			if (!sb_has_quota_loaded(sb, cnt))
+				continue;
+			req.dirtied_ino += 1;
+			inodes[cnt] = dqopt->files[cnt];
+		}
+	} else {
+		if (sb_has_quota_loaded(sb, type)) {
+			req.dirtied_ino = 1;
+			inodes[cnt] = dqopt->files[type];
+		}
+	}
+
+	if (req.dirtied_ino) {
+		ret = ubifs_budget_space(c, &req);
+		if (ret)
+			return ret;
+	}
+
+	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+		tmp = inodes[cnt];
+		if (!tmp)
+			break;
+		ui = ubifs_inode(tmp);
+		mutex_lock(&ui->ui_mutex);
+		ui->budgeted = 1;
+		mutex_unlock(&ui->ui_mutex);
+	}
+
+	return dquot_disable(sb, type, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
+}
+
+static const struct quotactl_ops ubifs_qctl_operations = {
+	.quota_on	= dquot_quota_on,
+	.quota_off	= ubifs_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
+};
+#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] 52+ messages in thread

* [PATCH 25/25] ubifs: make ubifs to support quota
  2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
                   ` (23 preceding siblings ...)
  2015-07-21  8:37 ` [PATCH 24/25] ubifs: implement ubifs_qctl_operations for quotactl Dongsheng Yang
@ 2015-07-21  8:37 ` Dongsheng Yang
  2015-07-21  8:58 ` [RFC PATCH 00/25] Add quota supporting in ubifs Jan Kara
                   ` (4 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-21  8:37 UTC (permalink / raw)
  To: dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, linux-mtd, Dongsheng Yang

This commit release the quota supporting in ubifs

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

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 00451b0..d7be860 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -2382,7 +2382,11 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
 		sb->s_maxbytes = c->max_inode_sz = MAX_LFS_FILESIZE;
 	sb->s_op = &ubifs_super_operations;
 	sb->s_xattr = ubifs_xattr_handlers;
-
+#ifdef CONFIG_QUOTA
+	sb->dq_op = &dquot_operations;
+	sb->s_qcop = &ubifs_qctl_operations;
+	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] 52+ messages in thread

* Re: [RFC PATCH 00/25] Add quota supporting in ubifs
  2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
                   ` (24 preceding siblings ...)
  2015-07-21  8:37 ` [PATCH 25/25] ubifs: make ubifs to support quota Dongsheng Yang
@ 2015-07-21  8:58 ` Jan Kara
  2015-07-22  0:56   ` Dongsheng Yang
  2015-07-21 20:50 ` Richard Weinberger
                   ` (3 subsequent siblings)
  29 siblings, 1 reply; 52+ messages in thread
From: Jan Kara @ 2015-07-21  8:58 UTC (permalink / raw)
  To: Dongsheng Yang
  Cc: dedekind1, richard.weinberger, jack, linux-fsdevel, linux-mtd

  Hello,

On Tue 21-07-15 16:37:31, Dongsheng Yang wrote:
> Hi Atem, Richard and others,
> 	This is a patchset to add quota supporting in ubifs.
> [1/25] - [7/25] are working to make quotactl to support filesystems
> which are running on char device.
> 
> Others are about making ubifs to support quota
> Please help to review or test it. Any comment is welcome :).
> 
> Hi Jan Kara,
> 	I am not sure I am using the quota APIs correctly, please
> help to correct me if I am wrong.

Well, the patches for cdev handling are more for Al Viro as a VFS
maintainer. I can give you some feedback but he is the final arbiter to
decide whether those patches get merged. So please CC him in the next
posting.

								Honza

> 
> Also you can get the code from:
> https://github.com/yangdongsheng/linux.git  ubifs_quota_v1
> 
> 	My simple testing is shown as below:
> [root@atest-guest linux_compile]# mount -t ubifs -o usrquota,grpquota /dev/ubi0_0 /mnt/ubifs/
> [root@atest-guest linux_compile]# quotacheck -ug /mnt/ubifs
> [root@atest-guest linux_compile]# quotaon /mnt/ubifs
> [root@atest-guest linux_compile]# repquota /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      --       0       0       0              1     0     0 
> [root@atest-guest linux_compile]# setquota root 10 10 3 3 /mnt/ubifs
> [root@atest-guest linux_compile]# repquota /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      --       0      10      10              1     3     3 
> [root@atest-guest linux_compile]# touch /mnt/ubifs/{1,11,111}
> ubifs: warning, user file quota exceeded.
> [root@atest-guest linux_compile]# repquota /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      -+       0      10      10              4     3     3  7days
> [root@atest-guest linux_compile]# rm -rf /mnt/ubifs/1*
> [root@atest-guest linux_compile]# repquota /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      --       0      10      10              1     3     3    
> [root@atest-guest linux_compile]# dd if=/dev/urandom of=/mnt/ubifs/data bs=1K count=11
> ubifs: warning, user block quota exceeded.
> 11+0 records in
> 11+0 records out
> 11264 bytes (11 kB) copied, 0.216498 s, 52.0 kB/s
> [root@atest-guest linux_compile]# repquota /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      +-      11      10      10  7days       2     3     3   
> [root@atest-guest linux_compile]# rm -rf /mnt/ubifs/data 
> [root@atest-guest linux_compile]# repquota /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      --       0      10      10              1     3     3     
> 
> 
> Dongsheng Yang (25):
>   fs: introduce a ->s_cdev field into struct super_block
>   ubi: introduce a interface to get cdev in ubi_volume
>   ubifs: fill sb->s_cdev in ubifs_fill_super()
>   fs: super: introduce the functions to get super by cdev reference
>   fs: char_dev: introduce lookup_cdev function to find cdev by name
>   fs: dquot: skip invalidate_bdev if bdev is NULL
>   fs: quota: make quota support fs which is running on char dev
>   ubifs: fix a typo in comment of ubifs_budget_req
>   ubifs: extend budget for blocks
>   ubifs: fill ->s_dev in ubifs_fill_super
>   ubifs: export read_block() from file.c
>   ubifs: introduce quota related mount options
>   ubifs: introduce a field named as budgeted 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: suspend & resume quota properly in ubifs_remount
>   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_write_begin
>   ubifs: free quota space in do_truncation and unlink
>   ubifs: adapt quota space informatin in do_setattr
>   ubifs: transfer quota information in changing owner or group
>   ubifs: implement ubifs_qctl_operations for quotactl
>   ubifs: make ubifs to support quota
> 
>  drivers/mtd/ubi/kapi.c  |   6 +
>  fs/char_dev.c           |  72 ++++++++++
>  fs/quota/dquot.c        |   3 +-
>  fs/quota/quota.c        |  30 +++--
>  fs/super.c              |  45 +++++++
>  fs/ubifs/budget.c       |   4 +
>  fs/ubifs/debug.c        |   2 +
>  fs/ubifs/dir.c          |  24 +++-
>  fs/ubifs/file.c         |  56 +++++++-
>  fs/ubifs/ioctl.c        |   1 +
>  fs/ubifs/super.c        | 352 +++++++++++++++++++++++++++++++++++++++++++++++-
>  fs/ubifs/ubifs.h        |  19 ++-
>  include/linux/fs.h      |   5 +
>  include/linux/mtd/ubi.h |   1 +
>  14 files changed, 597 insertions(+), 23 deletions(-)
> 
> -- 
> 1.8.4.2
> 
> 
-- 
Jan Kara <jack@suse.cz>
SUSE Labs, CR

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

* Re: [PATCH 04/25] fs: super: introduce the functions to get super by cdev reference
  2015-07-21  8:37 ` [PATCH 04/25] fs: super: introduce the functions to get super by cdev reference Dongsheng Yang
@ 2015-07-21  9:04   ` Jan Kara
  2015-07-22  0:37     ` Dongsheng Yang
  0 siblings, 1 reply; 52+ messages in thread
From: Jan Kara @ 2015-07-21  9:04 UTC (permalink / raw)
  To: Dongsheng Yang
  Cc: dedekind1, richard.weinberger, jack, linux-fsdevel, linux-mtd

On Tue 21-07-15 16:37:35, Dongsheng Yang wrote:
> As we have cdev in super block 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>

Instead of duplicating the superblock searching functions, can you please
create common __get_super() function like:

struct super_block *__get_super(
		int (*compare)(struct super_block *, void *), void *key)

And it will use the compare function to check whether the sb is the right
one or not. You will then have one comparion functions for searching by
bdev used by get_super() and one comparison function for searching by cdev
used by get_super_cdev().

Similarly you can create __get_super_thawed() to avoid the duplication
there.

								Honza

> ---
>  fs/super.c         | 45 +++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/fs.h |  2 ++
>  2 files changed, 47 insertions(+)
> 
> diff --git a/fs/super.c b/fs/super.c
> index 928c20f..4a9031a 100644
> --- a/fs/super.c
> +++ b/fs/super.c
> @@ -605,6 +605,37 @@ rescan:
>  
>  EXPORT_SYMBOL(get_super);
>  
> +struct super_block *get_super_cdev(struct cdev *cdev)
> +{
> +	struct super_block *sb;
> +
> +	if (!cdev)
> +		return NULL;
> +
> +	spin_lock(&sb_lock);
> +rescan:
> +	list_for_each_entry(sb, &super_blocks, s_list) {
> +		if (hlist_unhashed(&sb->s_instances))
> +			continue;
> +		if (sb->s_cdev == cdev) {
> +			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;
> +}
> +EXPORT_SYMBOL(get_super_cdev);
> +
>  /**
>   *	get_super_thawed - get thawed superblock of a device
>   *	@bdev: device to get the superblock for
> @@ -628,6 +659,20 @@ struct super_block *get_super_thawed(struct block_device *bdev)
>  }
>  EXPORT_SYMBOL(get_super_thawed);
>  
> +struct super_block *get_super_cdev_thawed(struct cdev *cdev)
> +{
> +	while (1) {
> +		struct super_block *s = get_super_cdev(cdev);
> +		if (!s || s->s_writers.frozen == SB_UNFROZEN)
> +			return s;
> +		up_read(&s->s_umount);
> +		wait_event(s->s_writers.wait_unfrozen,
> +			   s->s_writers.frozen == SB_UNFROZEN);
> +		put_super(s);
> +	}
> +}
> +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 2f1d9499..5c7d789 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -2744,7 +2744,9 @@ 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_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.cz>
SUSE Labs, CR

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

* Re: [PATCH 05/25] fs: char_dev: introduce lookup_cdev function to find cdev by name
  2015-07-21  8:37 ` [PATCH 05/25] fs: char_dev: introduce lookup_cdev function to find cdev by name Dongsheng Yang
@ 2015-07-21  9:20   ` Jan Kara
  0 siblings, 0 replies; 52+ messages in thread
From: Jan Kara @ 2015-07-21  9:20 UTC (permalink / raw)
  To: Dongsheng Yang
  Cc: dedekind1, richard.weinberger, jack, linux-fsdevel, linux-mtd, Al Viro

On Tue 21-07-15 16:37:36, Dongsheng Yang wrote:
> Function lookup_cdev works similar 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>
> ---
>  fs/char_dev.c      | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/fs.h |  2 ++
>  2 files changed, 74 insertions(+)

Thanks for the patch.

...
> +struct cdev *lookup_cdev(const char *pathname)
> +{
> +	struct cdev *cdev;
> +	struct inode *inode;
> +	struct path path;
> +	int error;
> +
> +	if (!pathname || !*pathname)
> +		return ERR_PTR(-EINVAL);
> +
> +	error = kern_path(pathname, LOOKUP_FOLLOW, &path);
> +	if (error)
> +		return ERR_PTR(error);
> +
> +	inode = d_backing_inode(path.dentry);
> +	error = -ENODEV;
> +	if (!S_ISCHR(inode->i_mode))
> +		goto fail;
> +	error = -EACCES;
> +	if (path.mnt->mnt_flags & MNT_NODEV)
> +		goto fail;
> +	error = -ENXIO;
> +	cdev = cd_acquire(inode);
> +	if (!cdev)
> +		goto fail;
> +out:
> +	path_put(&path);
> +	return cdev;
> +fail:
> +	cdev = ERR_PTR(error);
> +	goto out;
> +}

Again I don't like the code duplication here. Can we have a common
function lookup_dev() like:

int lookup_dev(const char *pathname, struct cdev **cdevp,
	       struct block_device **bdevp)
{
	struct inode *inode;
	struct path path;
	int error;

	if (!pathname || !*pathname)
		return -EINVAL;

	error = kern_path(pathname, LOOKUP_FOLLOW, &path);
	if (error)
		return error;

	inode = d_backing_inode(path.dentry);
	error = -ENODEV;

	if (!((S_ISCHR(inode->i_mode) && cdevp) ||
	      (S_ISBLK(inode->i_mode) && bdevp)))
		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;
}

It is then easy to wrap lookup_bdev() around it. I'm not too happy about
the function prototype but I still think it's better than the duplication.
Al? Also quota code can then easily use this lookup_dev() function instead
of trying one device type and then another one...

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

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

* Re: [PATCH 11/25] ubifs: export read_block() from file.c
  2015-07-21  8:37 ` [PATCH 11/25] ubifs: export read_block() from file.c Dongsheng Yang
@ 2015-07-21 20:36   ` Richard Weinberger
  2015-07-22  0:41     ` Dongsheng Yang
  0 siblings, 1 reply; 52+ messages in thread
From: Richard Weinberger @ 2015-07-21 20:36 UTC (permalink / raw)
  To: Dongsheng Yang, dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, linux-mtd

Am 21.07.2015 um 10:37 schrieb 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>
> ---
>  fs/ubifs/file.c  | 2 +-
>  fs/ubifs/ubifs.h | 2 ++
>  2 files changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
> index 27de484..dc8bf0b 100644
> --- a/fs/ubifs/file.c
> +++ b/fs/ubifs/file.c
> @@ -54,7 +54,7 @@
>  #include <linux/namei.h>
>  #include <linux/slab.h>
>  
> -static int read_block(struct inode *inode, void *addr, unsigned int block,
> +int 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;
> diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
> index ae6723e..a6ad955 100644
> --- a/fs/ubifs/ubifs.h
> +++ b/fs/ubifs/ubifs.h
> @@ -1749,6 +1749,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 read_block(struct inode *inode, void *addr, unsigned int block,
> +		      struct ubifs_data_node *dn);

Please prefix the function name with ubifs_ to avoid namespace pollution.

Thanks,
//richard

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

* Re: [PATCH 12/25] ubifs: introduce quota related mount options
  2015-07-21  8:37 ` [PATCH 12/25] ubifs: introduce quota related mount options Dongsheng Yang
@ 2015-07-21 20:39   ` Richard Weinberger
  2015-07-22  0:41     ` Dongsheng Yang
  0 siblings, 1 reply; 52+ messages in thread
From: Richard Weinberger @ 2015-07-21 20:39 UTC (permalink / raw)
  To: Dongsheng Yang, dedekind1, jack; +Cc: linux-fsdevel, linux-mtd

Am 21.07.2015 um 10:37 schrieb Dongsheng Yang:
> This commit introduce mount options of quota, noquota,
> usrquota and grpquota. These options are used to make
> ubifs support quota. But with this commit, quota will
> not working on ubifs actually. We just introduce options
> here and will make ubifs support quota later.

Is there a reason why you didn't implement project quotas too?

Thanks,
//richard

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

* Re: [PATCH 13/25] ubifs: introduce a field named as budgeted to ubifs_inode
  2015-07-21  8:37   ` Dongsheng Yang
  (?)
@ 2015-07-21 20:47   ` Richard Weinberger
  2015-07-22  0:56     ` Dongsheng Yang
  -1 siblings, 1 reply; 52+ messages in thread
From: Richard Weinberger @ 2015-07-21 20:47 UTC (permalink / raw)
  To: Dongsheng Yang, dedekind1, jack; +Cc: linux-fsdevel, linux-mtd

Am 21.07.2015 um 10:37 schrieb Dongsheng Yang:
> There is a long-term pain in ubifs, we have to introduce a
> ui_mutex in ubifs_inode to solve two problems below:
> 
> 1: make some process atomic, such as ubifs_rename.
> 2: make sure we budget space for inode before dirting it.
> 
> About 1, it's true and we have to do it.
> 
> About 2, we can do it better.
> 	There is a ubifs_assert(mutex_is_locked(&ui->mutex)) in
> ubifs_dirty_inode(). But there is probably some processes
> are very long, and we can not make all of it into a pair of
> lock/unlock ui->mutex.
> 
> E.g: dquot_disable().
> 	It would mark the quota files as dirty and write the
> inode back. We can do a budget before this function, but we
> can not make the whole dquot_disable() into mutex_lock/mutex_unlock.
> Because we need to lock the ui_mutex in dquot_disable().
> 
> So, this commit introduce a ui->budgeted to allow us to make
> budgeting and dirting in two different lock windows.
> 
> Result:
> 	ubifs_budget_space()
> 	mutex_lock();
> 	ui->budgeted = 1;
> 	mutex_unlock();
> 	...
> 	dquot_disable();

I'm confused by this changelog.

Why do you need ui->budgeted? You set it but never read it
except in an ubifs_assert().

> Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
> ---
>  fs/ubifs/file.c  |  7 +++++++
>  fs/ubifs/ioctl.c |  1 +
>  fs/ubifs/super.c | 14 +++++++++++++-
>  fs/ubifs/ubifs.h |  1 +
>  4 files changed, 22 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
> index dc8bf0b..113c3a6 100644
> --- a/fs/ubifs/file.c
> +++ b/fs/ubifs/file.c
> @@ -307,6 +307,7 @@ static int write_begin_slow(struct address_space *mapping,
>  			 * budget we allocated.
>  			 */
>  			ubifs_release_dirty_inode_budget(c, ui);
> +		ui->budgeted = 1;
>  	}
>  
>  	*pagep = page;
> @@ -357,6 +358,7 @@ static int allocate_budget(struct ubifs_info *c, struct page *page,
>  		 * we need to budget the inode change.
>  		 */
>  		req.dirtied_ino = 1;
> +		ui->budgeted = 1;
>  	} else {
>  		if (PageChecked(page))
>  			/*
> @@ -384,6 +386,7 @@ static int allocate_budget(struct ubifs_info *c, struct page *page,
>  				 * needs a budget.
>  				 */
>  				req.dirtied_ino = 1;
> +			ui->budgeted = 1;
>  		}
>  	}
>  
> @@ -1237,6 +1240,7 @@ static int do_setattr(struct ubifs_info *c, struct inode *inode,
>  	do_attr_changes(inode, attr);
>  
>  	release = ui->dirty;
> +	ui->budgeted = 1;
>  	if (attr->ia_valid & ATTR_SIZE)
>  		/*
>  		 * Inode length changed, so we have to make sure
> @@ -1397,6 +1401,7 @@ static int ubifs_update_time(struct inode *inode, struct timespec *time,
>  		iflags |= I_DIRTY_SYNC;
>  
>  	release = ui->dirty;
> +	ui->budgeted = 1;
>  	__mark_inode_dirty(inode, iflags);
>  	mutex_unlock(&ui->ui_mutex);
>  	if (release)
> @@ -1430,6 +1435,7 @@ static int update_mctime(struct inode *inode)
>  		mutex_lock(&ui->ui_mutex);
>  		inode->i_mtime = inode->i_ctime = ubifs_current_time(inode);
>  		release = ui->dirty;
> +		ui->budgeted = 1;
>  		mark_inode_dirty_sync(inode);
>  		mutex_unlock(&ui->ui_mutex);
>  		if (release)
> @@ -1556,6 +1562,7 @@ static int ubifs_vm_page_mkwrite(struct vm_area_struct *vma,
>  		mutex_lock(&ui->ui_mutex);
>  		inode->i_mtime = inode->i_ctime = ubifs_current_time(inode);
>  		release = ui->dirty;
> +		ui->budgeted = 1;
>  		mark_inode_dirty_sync(inode);
>  		mutex_unlock(&ui->ui_mutex);
>  		if (release)
> diff --git a/fs/ubifs/ioctl.c b/fs/ubifs/ioctl.c
> index 3c7b29d..f015b81 100644
> --- a/fs/ubifs/ioctl.c
> +++ b/fs/ubifs/ioctl.c
> @@ -128,6 +128,7 @@ static int setflags(struct inode *inode, int flags)
>  	ubifs_set_inode_flags(inode);
>  	inode->i_ctime = ubifs_current_time(inode);
>  	release = ui->dirty;
> +	ui->budgeted = 1;
>  	mark_inode_dirty_sync(inode);
>  	mutex_unlock(&ui->ui_mutex);
>  
> diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
> index 2491fff..5fa21d6 100644
> --- a/fs/ubifs/super.c
> +++ b/fs/ubifs/super.c
> @@ -331,6 +331,7 @@ static int ubifs_write_inode(struct inode *inode, struct writeback_control *wbc)
>  	}
>  
>  	ui->dirty = 0;
> +	ui->budgeted = 0;
>  	mutex_unlock(&ui->ui_mutex);
>  	ubifs_release_dirty_inode_budget(c, ui);
>  	return err;
> @@ -386,12 +387,23 @@ done:
>  static void ubifs_dirty_inode(struct inode *inode, int flags)
>  {
>          struct ubifs_inode *ui = ubifs_inode(inode);
> +	int need_unlock = 0;
>  
> -	ubifs_assert(mutex_is_locked(&ui->ui_mutex));
> +	if (unlikely(!mutex_is_locked(&ui->ui_mutex))) {
> +		/* We need to lock ui_mutex to access ui->budgeted */
> +		mutex_lock(&ui->ui_mutex);
> +		need_unlock = 1;
> +	}
> +
> +	/* Check the budget for this inode */
> +	ubifs_assert(ui->budgeted);
>  	if (!ui->dirty) {
>  		ui->dirty = 1;
>  		dbg_gen("inode %lu",  inode->i_ino);
>  	}
> +
> +	if (need_unlock)
> +		mutex_unlock(&ui->ui_mutex);
>  }
>  
>  static int ubifs_statfs(struct dentry *dentry, struct kstatfs *buf)
> diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
> index 9754bb6..28392a6 100644
> --- a/fs/ubifs/ubifs.h
> +++ b/fs/ubifs/ubifs.h
> @@ -410,6 +410,7 @@ struct ubifs_inode {
>  	unsigned int xattr_cnt;
>  	unsigned int xattr_names;
>  	unsigned int dirty:1;
> +	unsigned int budgeted:1;

Please document that new flag too.

Thanks,
//richard

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

* Re: [RFC PATCH 00/25] Add quota supporting in ubifs
  2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
                   ` (25 preceding siblings ...)
  2015-07-21  8:58 ` [RFC PATCH 00/25] Add quota supporting in ubifs Jan Kara
@ 2015-07-21 20:50 ` Richard Weinberger
  2015-07-22  1:11   ` Dongsheng Yang
  2015-07-21 21:01 ` Richard Weinberger
                   ` (2 subsequent siblings)
  29 siblings, 1 reply; 52+ messages in thread
From: Richard Weinberger @ 2015-07-21 20:50 UTC (permalink / raw)
  To: Dongsheng Yang, dedekind1, jack; +Cc: linux-fsdevel, linux-mtd

Am 21.07.2015 um 10:37 schrieb Dongsheng Yang:
> Hi Atem, Richard and others,
> 	This is a patchset to add quota supporting in ubifs.
> [1/25] - [7/25] are working to make quotactl to support filesystems
> which are running on char device.
> 
> Others are about making ubifs to support quota
> Please help to review or test it. Any comment is welcome :).

How did you test this new feature? xfstests? Also wrt. powercuts?
Please also don't forget to add quota support to integchk.

Thanks,
//richard

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

* Re: [RFC PATCH 00/25] Add quota supporting in ubifs
  2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
                   ` (26 preceding siblings ...)
  2015-07-21 20:50 ` Richard Weinberger
@ 2015-07-21 21:01 ` Richard Weinberger
  2015-07-22  0:58   ` Dongsheng Yang
  2015-07-21 21:15 ` Richard Weinberger
  2015-07-22 11:23 ` Dongsheng Yang
  29 siblings, 1 reply; 52+ messages in thread
From: Richard Weinberger @ 2015-07-21 21:01 UTC (permalink / raw)
  To: Dongsheng Yang, dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, linux-mtd

Am 21.07.2015 um 10:37 schrieb Dongsheng Yang:
> Hi Atem, Richard and others,
> 	This is a patchset to add quota supporting in ubifs.
> [1/25] - [7/25] are working to make quotactl to support filesystems
> which are running on char device.
> 
> Others are about making ubifs to support quota
> Please help to review or test it. Any comment is welcome :).
> 
> Hi Jan Kara,
> 	I am not sure I am using the quota APIs correctly, please
> help to correct me if I am wrong.
> 
> Also you can get the code from:
> https://github.com/yangdongsheng/linux.git  ubifs_quota_v1

This branch contains also your atime series. Is this desired?

Thanks,
//richard

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

* Re: [RFC PATCH 00/25] Add quota supporting in ubifs
  2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
                   ` (27 preceding siblings ...)
  2015-07-21 21:01 ` Richard Weinberger
@ 2015-07-21 21:15 ` Richard Weinberger
  2015-07-22  0:58   ` Dongsheng Yang
  2015-07-22 11:23 ` Dongsheng Yang
  29 siblings, 1 reply; 52+ messages in thread
From: Richard Weinberger @ 2015-07-21 21:15 UTC (permalink / raw)
  To: Dongsheng Yang, dedekind1, jack; +Cc: linux-fsdevel, linux-mtd

Am 21.07.2015 um 10:37 schrieb Dongsheng Yang:
> Hi Atem, Richard and others,
> 	This is a patchset to add quota supporting in ubifs.
> [1/25] - [7/25] are working to make quotactl to support filesystems
> which are running on char device.
> 
> Others are about making ubifs to support quota
> Please help to review or test it. Any comment is welcome :).
> 
> Hi Jan Kara,
> 	I am not sure I am using the quota APIs correctly, please
> help to correct me if I am wrong.
> 
> Also you can get the code from:
> https://github.com/yangdongsheng/linux.git  ubifs_quota_v1
> 
> 	My simple testing is shown as below:

I get this lockdep splat. Have you seen it too?

[   63.779453]
[   63.779633] ======================================================
[   63.780006] [ INFO: possible circular locking dependency detected ]
[   63.780006] 4.2.0-rc3+ #45 Not tainted
[   63.780006] -------------------------------------------------------
[   63.780006] dd/2668 is trying to acquire lock:
[   63.780006]  (&type->s_umount_key#28){+++++.}, at: [<ffffffff81306031>] ubifs_budget_space+0x2c1/0x660
[   63.780006]
[   63.780006] but task is already holding lock:
[   63.780006]  (&sb->s_type->i_mutex_key#12){+.+.+.}, at: [<ffffffff811434c5>] generic_file_write_iter+0x35/0x1f0
[   63.780006]
[   63.780006] which lock already depends on the new lock.
[   63.780006]
[   63.780006]
[   63.780006] the existing dependency chain (in reverse order) is:
[   63.780006]
-> #2 (&sb->s_type->i_mutex_key#12){+.+.+.}:
[   63.780006]        [<ffffffff810a2103>] lock_acquire+0xd3/0x270
[   63.780006]        [<ffffffff819cee7b>] mutex_lock_nested+0x6b/0x3a0
[   63.780006]        [<ffffffff81202d23>] vfs_load_quota_inode+0x4f3/0x560
[   63.780006]        [<ffffffff81203203>] dquot_quota_on+0x53/0x60
[   63.780006]        [<ffffffff8120786a>] SyS_quotactl+0x66a/0x890
[   63.780006]        [<ffffffff819d2d57>] entry_SYSCALL_64_fastpath+0x12/0x6f
[   63.780006]
-> #1 (&s->s_dquot.dqonoff_mutex){+.+...}:
[   63.780006]        [<ffffffff810a2103>] lock_acquire+0xd3/0x270
[   63.780006]        [<ffffffff819cee7b>] mutex_lock_nested+0x6b/0x3a0
[   63.780006]        [<ffffffff81203603>] dquot_writeback_dquots+0x33/0x280
[   63.780006]        [<ffffffff812f2e3e>] ubifs_sync_fs+0x2e/0xb0
[   63.780006]        [<ffffffff811d0d54>] sync_filesystem+0x74/0xb0
[   63.780006]        [<ffffffff8119cf5f>] generic_shutdown_super+0x2f/0x100
[   63.780006]        [<ffffffff8119d281>] kill_anon_super+0x11/0x20
[   63.780006]        [<ffffffff812f22d5>] kill_ubifs_super+0x15/0x30
[   63.780006]        [<ffffffff8119d709>] deactivate_locked_super+0x39/0x70
[   63.780006]        [<ffffffff8119deb9>] deactivate_super+0x49/0x70
[   63.780006]        [<ffffffff811bcb4e>] cleanup_mnt+0x3e/0x90
[   63.780006]        [<ffffffff811bcbed>] __cleanup_mnt+0xd/0x10
[   63.780006]        [<ffffffff81076258>] task_work_run+0x88/0xb0
[   63.780006]        [<ffffffff81003abd>] do_notify_resume+0x3d/0x50
[   63.780006]        [<ffffffff819d2f2c>] int_signal+0x12/0x17
[   63.780006]
-> #0 (&type->s_umount_key#28){+++++.}:
[   63.780006]        [<ffffffff810a1a17>] __lock_acquire+0x1907/0x1ea0
[   63.780006]        [<ffffffff810a2103>] lock_acquire+0xd3/0x270
[   63.780006]        [<ffffffff819d03cc>] down_read+0x4c/0xa0
[   63.780006]        [<ffffffff81306031>] ubifs_budget_space+0x2c1/0x660
[   63.780006]        [<ffffffff812eef5d>] ubifs_write_begin+0x23d/0x500
[   63.780006]        [<ffffffff81140bda>] generic_perform_write+0xaa/0x1a0
[   63.780006]        [<ffffffff81143433>] __generic_file_write_iter+0x183/0x1e0
[   63.780006]        [<ffffffff81143574>] generic_file_write_iter+0xe4/0x1f0
[   63.780006]        [<ffffffff812eda96>] ubifs_write_iter+0xc6/0x180
[   63.780006]        [<ffffffff8119a958>] __vfs_write+0xa8/0xe0
[   63.780006]        [<ffffffff8119afb7>] vfs_write+0xa7/0x190
[   63.780006]        [<ffffffff8119bcf4>] SyS_write+0x44/0xa0
[   63.780006]        [<ffffffff819d2d57>] entry_SYSCALL_64_fastpath+0x12/0x6f
[   63.780006]
[   63.780006] other info that might help us debug this:
[   63.780006]
[   63.780006] Chain exists of:
  &type->s_umount_key#28 --> &s->s_dquot.dqonoff_mutex --> &sb->s_type->i_mutex_key#12

[   63.780006]  Possible unsafe locking scenario:
[   63.780006]
[   63.780006]        CPU0                    CPU1
[   63.780006]        ----                    ----
[   63.780006]   lock(&sb->s_type->i_mutex_key#12);
[   63.780006]                                lock(&s->s_dquot.dqonoff_mutex);
[   63.780006]                                lock(&sb->s_type->i_mutex_key#12);
[   63.780006]   lock(&type->s_umount_key#28);
[   63.780006]
[   63.780006]  *** DEADLOCK ***
[   63.780006]
[   63.780006] 2 locks held by dd/2668:
[   63.780006]  #0:  (sb_writers#8){.+.+.+}, at: [<ffffffff8119b086>] vfs_write+0x176/0x190
[   63.780006]  #1:  (&sb->s_type->i_mutex_key#12){+.+.+.}, at: [<ffffffff811434c5>] generic_file_write_iter+0x35/0x1f0
[   63.780006]
[   63.780006] stack backtrace:
[   63.780006] CPU: 2 PID: 2668 Comm: dd Not tainted 4.2.0-rc3+ #45
[   63.780006] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.7.5-0-ge51488c-20140816_022509-build35 04/01/2014
[   63.780006]  ffffffff829ef340 ffff880000037988 ffffffff819c4998 0000000000000000
[   63.780006]  ffffffff829f6f40 ffff8800000379d8 ffffffff819c0647 0000000000000002
[   63.780006]  ffff880000037a28 ffff8800000379d8 ffff8800798b97c0 ffff8800798b9fd8
[   63.780006] Call Trace:
[   63.780006]  [<ffffffff819c4998>] dump_stack+0x4c/0x65
[   63.780006]  [<ffffffff819c0647>] print_circular_bug+0x202/0x213
[   63.780006]  [<ffffffff810a1a17>] __lock_acquire+0x1907/0x1ea0
[   63.780006]  [<ffffffff810a2103>] lock_acquire+0xd3/0x270
[   63.780006]  [<ffffffff81306031>] ? ubifs_budget_space+0x2c1/0x660
[   63.780006]  [<ffffffff819d03cc>] down_read+0x4c/0xa0
[   63.780006]  [<ffffffff81306031>] ? ubifs_budget_space+0x2c1/0x660
[   63.780006]  [<ffffffff819d23c6>] ? _raw_spin_unlock+0x26/0x40
[   63.780006]  [<ffffffff81306031>] ubifs_budget_space+0x2c1/0x660
[   63.780006]  [<ffffffff819cf25b>] ? __mutex_unlock_slowpath+0xab/0x160
[   63.780006]  [<ffffffff812eef5d>] ubifs_write_begin+0x23d/0x500
[   63.780006]  [<ffffffff81140bda>] generic_perform_write+0xaa/0x1a0
[   63.780006]  [<ffffffff81143433>] __generic_file_write_iter+0x183/0x1e0
[   63.780006]  [<ffffffff81143574>] generic_file_write_iter+0xe4/0x1f0
[   63.780006]  [<ffffffff812eda96>] ubifs_write_iter+0xc6/0x180
[   63.780006]  [<ffffffff8119a958>] __vfs_write+0xa8/0xe0
[   63.780006]  [<ffffffff8119afb7>] vfs_write+0xa7/0x190
[   63.780006]  [<ffffffff8119bcf4>] SyS_write+0x44/0xa0
[   63.780006]  [<ffffffff819d2d57>] entry_SYSCALL_64_fastpath+0x12/0x6f

Thanks,
//richard

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

* Re: [PATCH 04/25] fs: super: introduce the functions to get super by cdev reference
  2015-07-21  9:04   ` Jan Kara
@ 2015-07-22  0:37     ` Dongsheng Yang
  0 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-22  0:37 UTC (permalink / raw)
  To: Jan Kara; +Cc: dedekind1, richard.weinberger, jack, linux-fsdevel, linux-mtd

On 07/21/2015 05:04 PM, Jan Kara wrote:
> On Tue 21-07-15 16:37:35, Dongsheng Yang wrote:
>> As we have cdev in super block 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>
>
> Instead of duplicating the superblock searching functions, can you please
> create common __get_super() function like:
>
> struct super_block *__get_super(
> 		int (*compare)(struct super_block *, void *), void *key)
>
> And it will use the compare function to check whether the sb is the right
> one or not. You will then have one comparion functions for searching by
> bdev used by get_super() and one comparison function for searching by cdev
> used by get_super_cdev().
>
> Similarly you can create __get_super_thawed() to avoid the duplication
> there.

Haha, that's what I wanted to do, but forgive my lazy, I will update it
in next version.

Yang
>
> 								Honza
>
>> ---
>>   fs/super.c         | 45 +++++++++++++++++++++++++++++++++++++++++++++
>>   include/linux/fs.h |  2 ++
>>   2 files changed, 47 insertions(+)
>>
>> diff --git a/fs/super.c b/fs/super.c
>> index 928c20f..4a9031a 100644
>> --- a/fs/super.c
>> +++ b/fs/super.c
>> @@ -605,6 +605,37 @@ rescan:
>>
>>   EXPORT_SYMBOL(get_super);
>>
>> +struct super_block *get_super_cdev(struct cdev *cdev)
>> +{
>> +	struct super_block *sb;
>> +
>> +	if (!cdev)
>> +		return NULL;
>> +
>> +	spin_lock(&sb_lock);
>> +rescan:
>> +	list_for_each_entry(sb, &super_blocks, s_list) {
>> +		if (hlist_unhashed(&sb->s_instances))
>> +			continue;
>> +		if (sb->s_cdev == cdev) {
>> +			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;
>> +}
>> +EXPORT_SYMBOL(get_super_cdev);
>> +
>>   /**
>>    *	get_super_thawed - get thawed superblock of a device
>>    *	@bdev: device to get the superblock for
>> @@ -628,6 +659,20 @@ struct super_block *get_super_thawed(struct block_device *bdev)
>>   }
>>   EXPORT_SYMBOL(get_super_thawed);
>>
>> +struct super_block *get_super_cdev_thawed(struct cdev *cdev)
>> +{
>> +	while (1) {
>> +		struct super_block *s = get_super_cdev(cdev);
>> +		if (!s || s->s_writers.frozen == SB_UNFROZEN)
>> +			return s;
>> +		up_read(&s->s_umount);
>> +		wait_event(s->s_writers.wait_unfrozen,
>> +			   s->s_writers.frozen == SB_UNFROZEN);
>> +		put_super(s);
>> +	}
>> +}
>> +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 2f1d9499..5c7d789 100644
>> --- a/include/linux/fs.h
>> +++ b/include/linux/fs.h
>> @@ -2744,7 +2744,9 @@ 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_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	[flat|nested] 52+ messages in thread

* Re: [PATCH 11/25] ubifs: export read_block() from file.c
  2015-07-21 20:36   ` Richard Weinberger
@ 2015-07-22  0:41     ` Dongsheng Yang
  0 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-22  0:41 UTC (permalink / raw)
  To: Richard Weinberger, dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, linux-mtd

On 07/22/2015 04:36 AM, Richard Weinberger wrote:
> Am 21.07.2015 um 10:37 schrieb 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>
>> ---
>>   fs/ubifs/file.c  | 2 +-
>>   fs/ubifs/ubifs.h | 2 ++
>>   2 files changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
>> index 27de484..dc8bf0b 100644
>> --- a/fs/ubifs/file.c
>> +++ b/fs/ubifs/file.c
>> @@ -54,7 +54,7 @@
>>   #include <linux/namei.h>
>>   #include <linux/slab.h>
>>
>> -static int read_block(struct inode *inode, void *addr, unsigned int block,
>> +int 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;
>> diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
>> index ae6723e..a6ad955 100644
>> --- a/fs/ubifs/ubifs.h
>> +++ b/fs/ubifs/ubifs.h
>> @@ -1749,6 +1749,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 read_block(struct inode *inode, void *addr, unsigned int block,
>> +		      struct ubifs_data_node *dn);
>
> Please prefix the function name with ubifs_ to avoid namespace pollution.

Good point, thanx
>
> Thanks,
> //richard
> .
>


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

* Re: [PATCH 12/25] ubifs: introduce quota related mount options
  2015-07-21 20:39   ` Richard Weinberger
@ 2015-07-22  0:41     ` Dongsheng Yang
  0 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-22  0:41 UTC (permalink / raw)
  To: Richard Weinberger, dedekind1, jack; +Cc: linux-fsdevel, linux-mtd

On 07/22/2015 04:39 AM, Richard Weinberger wrote:
> Am 21.07.2015 um 10:37 schrieb Dongsheng Yang:
>> This commit introduce mount options of quota, noquota,
>> usrquota and grpquota. These options are used to make
>> ubifs support quota. But with this commit, quota will
>> not working on ubifs actually. We just introduce options
>> here and will make ubifs support quota later.
>
> Is there a reason why you didn't implement project quotas too?

I planed to put it in the next cycle.
>
> Thanks,
> //richard
> .
>


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

* Re: [PATCH 13/25] ubifs: introduce a field named as budgeted to ubifs_inode
  2015-07-21 20:47   ` Richard Weinberger
@ 2015-07-22  0:56     ` Dongsheng Yang
  2015-07-22  6:22       ` Dongsheng Yang
  0 siblings, 1 reply; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-22  0:56 UTC (permalink / raw)
  To: Richard Weinberger, dedekind1, jack; +Cc: linux-fsdevel, linux-mtd

On 07/22/2015 04:47 AM, Richard Weinberger wrote:
> Am 21.07.2015 um 10:37 schrieb Dongsheng Yang:
>> There is a long-term pain in ubifs, we have to introduce a
>> ui_mutex in ubifs_inode to solve two problems below:
>>
>> 1: make some process atomic, such as ubifs_rename.
>> 2: make sure we budget space for inode before dirting it.
>>
>> About 1, it's true and we have to do it.
>>
>> About 2, we can do it better.
>> 	There is a ubifs_assert(mutex_is_locked(&ui->mutex)) in
>> ubifs_dirty_inode(). But there is probably some processes
>> are very long, and we can not make all of it into a pair of
>> lock/unlock ui->mutex.
>>
>> E.g: dquot_disable().
>> 	It would mark the quota files as dirty and write the
>> inode back. We can do a budget before this function, but we
>> can not make the whole dquot_disable() into mutex_lock/mutex_unlock.
>> Because we need to lock the ui_mutex in dquot_disable().
>>
>> So, this commit introduce a ui->budgeted to allow us to make
>> budgeting and dirting in two different lock windows.
>>
>> Result:
>> 	ubifs_budget_space()
>> 	mutex_lock();
>> 	ui->budgeted = 1;
>> 	mutex_unlock();
>> 	...
>> 	dquot_disable();
>
> I'm confused by this changelog.

Sorry, it is indeed confusing. Let me try to explain it more.

Currently, we have a ubifs_assert(mutex_is_locked(&ui->ui_mutex));
in ubifs_dirty_inode(). The reason of it is to make sure we have
done the budget before dirting it.

So we have to use it like that:
	struct ubifs_budget_req req = { .dirtied_ino = 1};
	ubifs_budget_space(req);
	mutex_lock(&ui->ui_mutex);
	ubifs_dirty_inode();
	mutex_unlock(&ui->ui_mutex);
We are checking the ui_mutex in ubifs_dirty_inode() to make sure
we are taking a full control of this process and we are sure there
is enough space to write this inode.


But the problem is: we can not put all process which are going to
dirty inode into the lock window, such as dquot_disable(), it will
acquire the ui_mutex in itself. (Although we can blame vfs to dirty
inode without asking ubifs is that correct)

So, I introduce a ui->budgeted here to replace ubifs_assert() in
ubifs_dirty_inode(); In ubifs_dirty_inode(), we can only check
the ui->budgeted to know whether we have done the budget for this
inode. Take the advantage of it, we can get what we want and solve
the problem I mentioned above.

I hope it more clear.

Thanx
Yang
>
> Why do you need ui->budgeted? You set it but never read it
> except in an ubifs_assert().
>
>> Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
>> ---
>>   fs/ubifs/file.c  |  7 +++++++
>>   fs/ubifs/ioctl.c |  1 +
>>   fs/ubifs/super.c | 14 +++++++++++++-
>>   fs/ubifs/ubifs.h |  1 +
>>   4 files changed, 22 insertions(+), 1 deletion(-)
>>
>> diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
>> index dc8bf0b..113c3a6 100644
>> --- a/fs/ubifs/file.c
>> +++ b/fs/ubifs/file.c
>> @@ -307,6 +307,7 @@ static int write_begin_slow(struct address_space *mapping,
>>   			 * budget we allocated.
>>   			 */
>>   			ubifs_release_dirty_inode_budget(c, ui);
>> +		ui->budgeted = 1;
>>   	}
>>
>>   	*pagep = page;
>> @@ -357,6 +358,7 @@ static int allocate_budget(struct ubifs_info *c, struct page *page,
>>   		 * we need to budget the inode change.
>>   		 */
>>   		req.dirtied_ino = 1;
>> +		ui->budgeted = 1;
>>   	} else {
>>   		if (PageChecked(page))
>>   			/*
>> @@ -384,6 +386,7 @@ static int allocate_budget(struct ubifs_info *c, struct page *page,
>>   				 * needs a budget.
>>   				 */
>>   				req.dirtied_ino = 1;
>> +			ui->budgeted = 1;
>>   		}
>>   	}
>>
>> @@ -1237,6 +1240,7 @@ static int do_setattr(struct ubifs_info *c, struct inode *inode,
>>   	do_attr_changes(inode, attr);
>>
>>   	release = ui->dirty;
>> +	ui->budgeted = 1;
>>   	if (attr->ia_valid & ATTR_SIZE)
>>   		/*
>>   		 * Inode length changed, so we have to make sure
>> @@ -1397,6 +1401,7 @@ static int ubifs_update_time(struct inode *inode, struct timespec *time,
>>   		iflags |= I_DIRTY_SYNC;
>>
>>   	release = ui->dirty;
>> +	ui->budgeted = 1;
>>   	__mark_inode_dirty(inode, iflags);
>>   	mutex_unlock(&ui->ui_mutex);
>>   	if (release)
>> @@ -1430,6 +1435,7 @@ static int update_mctime(struct inode *inode)
>>   		mutex_lock(&ui->ui_mutex);
>>   		inode->i_mtime = inode->i_ctime = ubifs_current_time(inode);
>>   		release = ui->dirty;
>> +		ui->budgeted = 1;
>>   		mark_inode_dirty_sync(inode);
>>   		mutex_unlock(&ui->ui_mutex);
>>   		if (release)
>> @@ -1556,6 +1562,7 @@ static int ubifs_vm_page_mkwrite(struct vm_area_struct *vma,
>>   		mutex_lock(&ui->ui_mutex);
>>   		inode->i_mtime = inode->i_ctime = ubifs_current_time(inode);
>>   		release = ui->dirty;
>> +		ui->budgeted = 1;
>>   		mark_inode_dirty_sync(inode);
>>   		mutex_unlock(&ui->ui_mutex);
>>   		if (release)
>> diff --git a/fs/ubifs/ioctl.c b/fs/ubifs/ioctl.c
>> index 3c7b29d..f015b81 100644
>> --- a/fs/ubifs/ioctl.c
>> +++ b/fs/ubifs/ioctl.c
>> @@ -128,6 +128,7 @@ static int setflags(struct inode *inode, int flags)
>>   	ubifs_set_inode_flags(inode);
>>   	inode->i_ctime = ubifs_current_time(inode);
>>   	release = ui->dirty;
>> +	ui->budgeted = 1;
>>   	mark_inode_dirty_sync(inode);
>>   	mutex_unlock(&ui->ui_mutex);
>>
>> diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
>> index 2491fff..5fa21d6 100644
>> --- a/fs/ubifs/super.c
>> +++ b/fs/ubifs/super.c
>> @@ -331,6 +331,7 @@ static int ubifs_write_inode(struct inode *inode, struct writeback_control *wbc)
>>   	}
>>
>>   	ui->dirty = 0;
>> +	ui->budgeted = 0;
>>   	mutex_unlock(&ui->ui_mutex);
>>   	ubifs_release_dirty_inode_budget(c, ui);
>>   	return err;
>> @@ -386,12 +387,23 @@ done:
>>   static void ubifs_dirty_inode(struct inode *inode, int flags)
>>   {
>>           struct ubifs_inode *ui = ubifs_inode(inode);
>> +	int need_unlock = 0;
>>
>> -	ubifs_assert(mutex_is_locked(&ui->ui_mutex));
>> +	if (unlikely(!mutex_is_locked(&ui->ui_mutex))) {
>> +		/* We need to lock ui_mutex to access ui->budgeted */
>> +		mutex_lock(&ui->ui_mutex);
>> +		need_unlock = 1;
>> +	}
>> +
>> +	/* Check the budget for this inode */
>> +	ubifs_assert(ui->budgeted);
>>   	if (!ui->dirty) {
>>   		ui->dirty = 1;
>>   		dbg_gen("inode %lu",  inode->i_ino);
>>   	}
>> +
>> +	if (need_unlock)
>> +		mutex_unlock(&ui->ui_mutex);
>>   }
>>
>>   static int ubifs_statfs(struct dentry *dentry, struct kstatfs *buf)
>> diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
>> index 9754bb6..28392a6 100644
>> --- a/fs/ubifs/ubifs.h
>> +++ b/fs/ubifs/ubifs.h
>> @@ -410,6 +410,7 @@ struct ubifs_inode {
>>   	unsigned int xattr_cnt;
>>   	unsigned int xattr_names;
>>   	unsigned int dirty:1;
>> +	unsigned int budgeted:1;
>
> Please document that new flag too.
>
> Thanks,
> //richard
> .
>


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

* Re: [RFC PATCH 00/25] Add quota supporting in ubifs
  2015-07-21  8:58 ` [RFC PATCH 00/25] Add quota supporting in ubifs Jan Kara
@ 2015-07-22  0:56   ` Dongsheng Yang
  0 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-22  0:56 UTC (permalink / raw)
  To: Jan Kara; +Cc: dedekind1, richard.weinberger, jack, linux-fsdevel, linux-mtd

On 07/21/2015 04:58 PM, Jan Kara wrote:
>    Hello,
>
> On Tue 21-07-15 16:37:31, Dongsheng Yang wrote:
>> Hi Atem, Richard and others,
>> 	This is a patchset to add quota supporting in ubifs.
>> [1/25] - [7/25] are working to make quotactl to support filesystems
>> which are running on char device.
>>
>> Others are about making ubifs to support quota
>> Please help to review or test it. Any comment is welcome :).
>>
>> Hi Jan Kara,
>> 	I am not sure I am using the quota APIs correctly, please
>> help to correct me if I am wrong.
>
> Well, the patches for cdev handling are more for Al Viro as a VFS
> maintainer. I can give you some feedback but he is the final arbiter to
> decide whether those patches get merged. So please CC him in the next
> posting.

Thanx, will do it in next version.
>
> 								Honza
>
>>
>> Also you can get the code from:
>> https://github.com/yangdongsheng/linux.git  ubifs_quota_v1
>>
>> 	My simple testing is shown as below:
>> [root@atest-guest linux_compile]# mount -t ubifs -o usrquota,grpquota /dev/ubi0_0 /mnt/ubifs/
>> [root@atest-guest linux_compile]# quotacheck -ug /mnt/ubifs
>> [root@atest-guest linux_compile]# quotaon /mnt/ubifs
>> [root@atest-guest linux_compile]# repquota /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      --       0       0       0              1     0     0
>> [root@atest-guest linux_compile]# setquota root 10 10 3 3 /mnt/ubifs
>> [root@atest-guest linux_compile]# repquota /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      --       0      10      10              1     3     3
>> [root@atest-guest linux_compile]# touch /mnt/ubifs/{1,11,111}
>> ubifs: warning, user file quota exceeded.
>> [root@atest-guest linux_compile]# repquota /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      -+       0      10      10              4     3     3  7days
>> [root@atest-guest linux_compile]# rm -rf /mnt/ubifs/1*
>> [root@atest-guest linux_compile]# repquota /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      --       0      10      10              1     3     3
>> [root@atest-guest linux_compile]# dd if=/dev/urandom of=/mnt/ubifs/data bs=1K count=11
>> ubifs: warning, user block quota exceeded.
>> 11+0 records in
>> 11+0 records out
>> 11264 bytes (11 kB) copied, 0.216498 s, 52.0 kB/s
>> [root@atest-guest linux_compile]# repquota /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      +-      11      10      10  7days       2     3     3
>> [root@atest-guest linux_compile]# rm -rf /mnt/ubifs/data
>> [root@atest-guest linux_compile]# repquota /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      --       0      10      10              1     3     3
>>
>>
>> Dongsheng Yang (25):
>>    fs: introduce a ->s_cdev field into struct super_block
>>    ubi: introduce a interface to get cdev in ubi_volume
>>    ubifs: fill sb->s_cdev in ubifs_fill_super()
>>    fs: super: introduce the functions to get super by cdev reference
>>    fs: char_dev: introduce lookup_cdev function to find cdev by name
>>    fs: dquot: skip invalidate_bdev if bdev is NULL
>>    fs: quota: make quota support fs which is running on char dev
>>    ubifs: fix a typo in comment of ubifs_budget_req
>>    ubifs: extend budget for blocks
>>    ubifs: fill ->s_dev in ubifs_fill_super
>>    ubifs: export read_block() from file.c
>>    ubifs: introduce quota related mount options
>>    ubifs: introduce a field named as budgeted 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: suspend & resume quota properly in ubifs_remount
>>    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_write_begin
>>    ubifs: free quota space in do_truncation and unlink
>>    ubifs: adapt quota space informatin in do_setattr
>>    ubifs: transfer quota information in changing owner or group
>>    ubifs: implement ubifs_qctl_operations for quotactl
>>    ubifs: make ubifs to support quota
>>
>>   drivers/mtd/ubi/kapi.c  |   6 +
>>   fs/char_dev.c           |  72 ++++++++++
>>   fs/quota/dquot.c        |   3 +-
>>   fs/quota/quota.c        |  30 +++--
>>   fs/super.c              |  45 +++++++
>>   fs/ubifs/budget.c       |   4 +
>>   fs/ubifs/debug.c        |   2 +
>>   fs/ubifs/dir.c          |  24 +++-
>>   fs/ubifs/file.c         |  56 +++++++-
>>   fs/ubifs/ioctl.c        |   1 +
>>   fs/ubifs/super.c        | 352 +++++++++++++++++++++++++++++++++++++++++++++++-
>>   fs/ubifs/ubifs.h        |  19 ++-
>>   include/linux/fs.h      |   5 +
>>   include/linux/mtd/ubi.h |   1 +
>>   14 files changed, 597 insertions(+), 23 deletions(-)
>>
>> --
>> 1.8.4.2
>>
>>


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

* Re: [RFC PATCH 00/25] Add quota supporting in ubifs
  2015-07-21 21:01 ` Richard Weinberger
@ 2015-07-22  0:58   ` Dongsheng Yang
  0 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-22  0:58 UTC (permalink / raw)
  To: Richard Weinberger, dedekind1, richard.weinberger, jack
  Cc: linux-fsdevel, linux-mtd

On 07/22/2015 05:01 AM, Richard Weinberger wrote:
> Am 21.07.2015 um 10:37 schrieb Dongsheng Yang:
>> Hi Atem, Richard and others,
>> 	This is a patchset to add quota supporting in ubifs.
>> [1/25] - [7/25] are working to make quotactl to support filesystems
>> which are running on char device.
>>
>> Others are about making ubifs to support quota
>> Please help to review or test it. Any comment is welcome :).
>>
>> Hi Jan Kara,
>> 	I am not sure I am using the quota APIs correctly, please
>> help to correct me if I am wrong.
>>
>> Also you can get the code from:
>> https://github.com/yangdongsheng/linux.git  ubifs_quota_v1
>
> This branch contains also your atime series. Is this desired?

Indeed, will remove it later.

Thanx for your reminder. :)
>
> Thanks,
> //richard
> .
>


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

* Re: [RFC PATCH 00/25] Add quota supporting in ubifs
  2015-07-21 21:15 ` Richard Weinberger
@ 2015-07-22  0:58   ` Dongsheng Yang
  2015-07-22  6:58     ` Richard Weinberger
  0 siblings, 1 reply; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-22  0:58 UTC (permalink / raw)
  To: Richard Weinberger, dedekind1, jack; +Cc: linux-fsdevel, linux-mtd

On 07/22/2015 05:15 AM, Richard Weinberger wrote:
> Am 21.07.2015 um 10:37 schrieb Dongsheng Yang:
>> Hi Atem, Richard and others,
>> 	This is a patchset to add quota supporting in ubifs.
>> [1/25] - [7/25] are working to make quotactl to support filesystems
>> which are running on char device.
>>
>> Others are about making ubifs to support quota
>> Please help to review or test it. Any comment is welcome :).
>>
>> Hi Jan Kara,
>> 	I am not sure I am using the quota APIs correctly, please
>> help to correct me if I am wrong.
>>
>> Also you can get the code from:
>> https://github.com/yangdongsheng/linux.git  ubifs_quota_v1
>>
>> 	My simple testing is shown as below:
>
> I get this lockdep splat. Have you seen it too?

OMG, could you share the script to trigger it?
>
> [   63.779453]
> [   63.779633] ======================================================
> [   63.780006] [ INFO: possible circular locking dependency detected ]
> [   63.780006] 4.2.0-rc3+ #45 Not tainted
> [   63.780006] -------------------------------------------------------
> [   63.780006] dd/2668 is trying to acquire lock:
> [   63.780006]  (&type->s_umount_key#28){+++++.}, at: [<ffffffff81306031>] ubifs_budget_space+0x2c1/0x660
> [   63.780006]
> [   63.780006] but task is already holding lock:
> [   63.780006]  (&sb->s_type->i_mutex_key#12){+.+.+.}, at: [<ffffffff811434c5>] generic_file_write_iter+0x35/0x1f0
> [   63.780006]
> [   63.780006] which lock already depends on the new lock.
> [   63.780006]
> [   63.780006]
> [   63.780006] the existing dependency chain (in reverse order) is:
> [   63.780006]
> -> #2 (&sb->s_type->i_mutex_key#12){+.+.+.}:
> [   63.780006]        [<ffffffff810a2103>] lock_acquire+0xd3/0x270
> [   63.780006]        [<ffffffff819cee7b>] mutex_lock_nested+0x6b/0x3a0
> [   63.780006]        [<ffffffff81202d23>] vfs_load_quota_inode+0x4f3/0x560
> [   63.780006]        [<ffffffff81203203>] dquot_quota_on+0x53/0x60
> [   63.780006]        [<ffffffff8120786a>] SyS_quotactl+0x66a/0x890
> [   63.780006]        [<ffffffff819d2d57>] entry_SYSCALL_64_fastpath+0x12/0x6f
> [   63.780006]
> -> #1 (&s->s_dquot.dqonoff_mutex){+.+...}:
> [   63.780006]        [<ffffffff810a2103>] lock_acquire+0xd3/0x270
> [   63.780006]        [<ffffffff819cee7b>] mutex_lock_nested+0x6b/0x3a0
> [   63.780006]        [<ffffffff81203603>] dquot_writeback_dquots+0x33/0x280
> [   63.780006]        [<ffffffff812f2e3e>] ubifs_sync_fs+0x2e/0xb0
> [   63.780006]        [<ffffffff811d0d54>] sync_filesystem+0x74/0xb0
> [   63.780006]        [<ffffffff8119cf5f>] generic_shutdown_super+0x2f/0x100
> [   63.780006]        [<ffffffff8119d281>] kill_anon_super+0x11/0x20
> [   63.780006]        [<ffffffff812f22d5>] kill_ubifs_super+0x15/0x30
> [   63.780006]        [<ffffffff8119d709>] deactivate_locked_super+0x39/0x70
> [   63.780006]        [<ffffffff8119deb9>] deactivate_super+0x49/0x70
> [   63.780006]        [<ffffffff811bcb4e>] cleanup_mnt+0x3e/0x90
> [   63.780006]        [<ffffffff811bcbed>] __cleanup_mnt+0xd/0x10
> [   63.780006]        [<ffffffff81076258>] task_work_run+0x88/0xb0
> [   63.780006]        [<ffffffff81003abd>] do_notify_resume+0x3d/0x50
> [   63.780006]        [<ffffffff819d2f2c>] int_signal+0x12/0x17
> [   63.780006]
> -> #0 (&type->s_umount_key#28){+++++.}:
> [   63.780006]        [<ffffffff810a1a17>] __lock_acquire+0x1907/0x1ea0
> [   63.780006]        [<ffffffff810a2103>] lock_acquire+0xd3/0x270
> [   63.780006]        [<ffffffff819d03cc>] down_read+0x4c/0xa0
> [   63.780006]        [<ffffffff81306031>] ubifs_budget_space+0x2c1/0x660
> [   63.780006]        [<ffffffff812eef5d>] ubifs_write_begin+0x23d/0x500
> [   63.780006]        [<ffffffff81140bda>] generic_perform_write+0xaa/0x1a0
> [   63.780006]        [<ffffffff81143433>] __generic_file_write_iter+0x183/0x1e0
> [   63.780006]        [<ffffffff81143574>] generic_file_write_iter+0xe4/0x1f0
> [   63.780006]        [<ffffffff812eda96>] ubifs_write_iter+0xc6/0x180
> [   63.780006]        [<ffffffff8119a958>] __vfs_write+0xa8/0xe0
> [   63.780006]        [<ffffffff8119afb7>] vfs_write+0xa7/0x190
> [   63.780006]        [<ffffffff8119bcf4>] SyS_write+0x44/0xa0
> [   63.780006]        [<ffffffff819d2d57>] entry_SYSCALL_64_fastpath+0x12/0x6f
> [   63.780006]
> [   63.780006] other info that might help us debug this:
> [   63.780006]
> [   63.780006] Chain exists of:
>    &type->s_umount_key#28 --> &s->s_dquot.dqonoff_mutex --> &sb->s_type->i_mutex_key#12
>
> [   63.780006]  Possible unsafe locking scenario:
> [   63.780006]
> [   63.780006]        CPU0                    CPU1
> [   63.780006]        ----                    ----
> [   63.780006]   lock(&sb->s_type->i_mutex_key#12);
> [   63.780006]                                lock(&s->s_dquot.dqonoff_mutex);
> [   63.780006]                                lock(&sb->s_type->i_mutex_key#12);
> [   63.780006]   lock(&type->s_umount_key#28);
> [   63.780006]
> [   63.780006]  *** DEADLOCK ***
> [   63.780006]
> [   63.780006] 2 locks held by dd/2668:
> [   63.780006]  #0:  (sb_writers#8){.+.+.+}, at: [<ffffffff8119b086>] vfs_write+0x176/0x190
> [   63.780006]  #1:  (&sb->s_type->i_mutex_key#12){+.+.+.}, at: [<ffffffff811434c5>] generic_file_write_iter+0x35/0x1f0
> [   63.780006]
> [   63.780006] stack backtrace:
> [   63.780006] CPU: 2 PID: 2668 Comm: dd Not tainted 4.2.0-rc3+ #45
> [   63.780006] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.7.5-0-ge51488c-20140816_022509-build35 04/01/2014
> [   63.780006]  ffffffff829ef340 ffff880000037988 ffffffff819c4998 0000000000000000
> [   63.780006]  ffffffff829f6f40 ffff8800000379d8 ffffffff819c0647 0000000000000002
> [   63.780006]  ffff880000037a28 ffff8800000379d8 ffff8800798b97c0 ffff8800798b9fd8
> [   63.780006] Call Trace:
> [   63.780006]  [<ffffffff819c4998>] dump_stack+0x4c/0x65
> [   63.780006]  [<ffffffff819c0647>] print_circular_bug+0x202/0x213
> [   63.780006]  [<ffffffff810a1a17>] __lock_acquire+0x1907/0x1ea0
> [   63.780006]  [<ffffffff810a2103>] lock_acquire+0xd3/0x270
> [   63.780006]  [<ffffffff81306031>] ? ubifs_budget_space+0x2c1/0x660
> [   63.780006]  [<ffffffff819d03cc>] down_read+0x4c/0xa0
> [   63.780006]  [<ffffffff81306031>] ? ubifs_budget_space+0x2c1/0x660
> [   63.780006]  [<ffffffff819d23c6>] ? _raw_spin_unlock+0x26/0x40
> [   63.780006]  [<ffffffff81306031>] ubifs_budget_space+0x2c1/0x660
> [   63.780006]  [<ffffffff819cf25b>] ? __mutex_unlock_slowpath+0xab/0x160
> [   63.780006]  [<ffffffff812eef5d>] ubifs_write_begin+0x23d/0x500
> [   63.780006]  [<ffffffff81140bda>] generic_perform_write+0xaa/0x1a0
> [   63.780006]  [<ffffffff81143433>] __generic_file_write_iter+0x183/0x1e0
> [   63.780006]  [<ffffffff81143574>] generic_file_write_iter+0xe4/0x1f0
> [   63.780006]  [<ffffffff812eda96>] ubifs_write_iter+0xc6/0x180
> [   63.780006]  [<ffffffff8119a958>] __vfs_write+0xa8/0xe0
> [   63.780006]  [<ffffffff8119afb7>] vfs_write+0xa7/0x190
> [   63.780006]  [<ffffffff8119bcf4>] SyS_write+0x44/0xa0
> [   63.780006]  [<ffffffff819d2d57>] entry_SYSCALL_64_fastpath+0x12/0x6f
>
> Thanks,
> //richard
> .
>


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

* Re: [RFC PATCH 00/25] Add quota supporting in ubifs
  2015-07-21 20:50 ` Richard Weinberger
@ 2015-07-22  1:11   ` Dongsheng Yang
  0 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-22  1:11 UTC (permalink / raw)
  To: Richard Weinberger, dedekind1, jack; +Cc: linux-fsdevel, linux-mtd

On 07/22/2015 04:50 AM, Richard Weinberger wrote:
> Am 21.07.2015 um 10:37 schrieb Dongsheng Yang:
>> Hi Atem, Richard and others,
>> 	This is a patchset to add quota supporting in ubifs.
>> [1/25] - [7/25] are working to make quotactl to support filesystems
>> which are running on char device.
>>
>> Others are about making ubifs to support quota
>> Please help to review or test it. Any comment is welcome :).
>
> How did you test this new feature? xfstests? Also wrt. powercuts?

I did not try powercuts, and I did not try some more full testing so
far. That's why I marked it as RFC :). I want to get the opinions as
early as possible. Then will do some more testing later.
> Please also don't forget to add quota support to integchk.

Thanx for your reminding. :)

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


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

* Re: [PATCH 13/25] ubifs: introduce a field named as budgeted to ubifs_inode
  2015-07-22  0:56     ` Dongsheng Yang
@ 2015-07-22  6:22       ` Dongsheng Yang
  0 siblings, 0 replies; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-22  6:22 UTC (permalink / raw)
  To: Richard Weinberger, dedekind1, jack; +Cc: linux-fsdevel, linux-mtd

On 07/22/2015 08:56 AM, Dongsheng Yang wrote:
> On 07/22/2015 04:47 AM, Richard Weinberger wrote:
>> Am 21.07.2015 um 10:37 schrieb Dongsheng Yang:
>>> There is a long-term pain in ubifs, we have to introduce a
>>> ui_mutex in ubifs_inode to solve two problems below:
>>>
>>> 1: make some process atomic, such as ubifs_rename.
>>> 2: make sure we budget space for inode before dirting it.
>>>
>>> About 1, it's true and we have to do it.
>>>
>>> About 2, we can do it better.
>>>     There is a ubifs_assert(mutex_is_locked(&ui->mutex)) in
>>> ubifs_dirty_inode(). But there is probably some processes
>>> are very long, and we can not make all of it into a pair of
>>> lock/unlock ui->mutex.
>>>
>>> E.g: dquot_disable().
>>>     It would mark the quota files as dirty and write the
>>> inode back. We can do a budget before this function, but we
>>> can not make the whole dquot_disable() into mutex_lock/mutex_unlock.
>>> Because we need to lock the ui_mutex in dquot_disable().
>>>
>>> So, this commit introduce a ui->budgeted to allow us to make
>>> budgeting and dirting in two different lock windows.
>>>
>>> Result:
>>>     ubifs_budget_space()
>>>     mutex_lock();
>>>     ui->budgeted = 1;
>>>     mutex_unlock();
>>>     ...
>>>     dquot_disable();

On my second thought of it, I have to find out another solution
for it. My patch here can not solve it and would cause some
other problem.

Sorry for the noise.

Yang

>>
>> I'm confused by this changelog.
>
> Sorry, it is indeed confusing. Let me try to explain it more.
>
> Currently, we have a ubifs_assert(mutex_is_locked(&ui->ui_mutex));
> in ubifs_dirty_inode(). The reason of it is to make sure we have
> done the budget before dirting it.
>
> So we have to use it like that:
>      struct ubifs_budget_req req = { .dirtied_ino = 1};
>      ubifs_budget_space(req);
>      mutex_lock(&ui->ui_mutex);
>      ubifs_dirty_inode();
>      mutex_unlock(&ui->ui_mutex);
> We are checking the ui_mutex in ubifs_dirty_inode() to make sure
> we are taking a full control of this process and we are sure there
> is enough space to write this inode.
>
>
> But the problem is: we can not put all process which are going to
> dirty inode into the lock window, such as dquot_disable(), it will
> acquire the ui_mutex in itself. (Although we can blame vfs to dirty
> inode without asking ubifs is that correct)
>
> So, I introduce a ui->budgeted here to replace ubifs_assert() in
> ubifs_dirty_inode(); In ubifs_dirty_inode(), we can only check
> the ui->budgeted to know whether we have done the budget for this
> inode. Take the advantage of it, we can get what we want and solve
> the problem I mentioned above.
>
> I hope it more clear.
>
> Thanx
> Yang
>>
>> Why do you need ui->budgeted? You set it but never read it
>> except in an ubifs_assert().
>>
>>> Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
>>> ---
>>>   fs/ubifs/file.c  |  7 +++++++
>>>   fs/ubifs/ioctl.c |  1 +
>>>   fs/ubifs/super.c | 14 +++++++++++++-
>>>   fs/ubifs/ubifs.h |  1 +
>>>   4 files changed, 22 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
>>> index dc8bf0b..113c3a6 100644
>>> --- a/fs/ubifs/file.c
>>> +++ b/fs/ubifs/file.c
>>> @@ -307,6 +307,7 @@ static int write_begin_slow(struct address_space
>>> *mapping,
>>>                * budget we allocated.
>>>                */
>>>               ubifs_release_dirty_inode_budget(c, ui);
>>> +        ui->budgeted = 1;
>>>       }
>>>
>>>       *pagep = page;
>>> @@ -357,6 +358,7 @@ static int allocate_budget(struct ubifs_info *c,
>>> struct page *page,
>>>            * we need to budget the inode change.
>>>            */
>>>           req.dirtied_ino = 1;
>>> +        ui->budgeted = 1;
>>>       } else {
>>>           if (PageChecked(page))
>>>               /*
>>> @@ -384,6 +386,7 @@ static int allocate_budget(struct ubifs_info *c,
>>> struct page *page,
>>>                    * needs a budget.
>>>                    */
>>>                   req.dirtied_ino = 1;
>>> +            ui->budgeted = 1;
>>>           }
>>>       }
>>>
>>> @@ -1237,6 +1240,7 @@ static int do_setattr(struct ubifs_info *c,
>>> struct inode *inode,
>>>       do_attr_changes(inode, attr);
>>>
>>>       release = ui->dirty;
>>> +    ui->budgeted = 1;
>>>       if (attr->ia_valid & ATTR_SIZE)
>>>           /*
>>>            * Inode length changed, so we have to make sure
>>> @@ -1397,6 +1401,7 @@ static int ubifs_update_time(struct inode
>>> *inode, struct timespec *time,
>>>           iflags |= I_DIRTY_SYNC;
>>>
>>>       release = ui->dirty;
>>> +    ui->budgeted = 1;
>>>       __mark_inode_dirty(inode, iflags);
>>>       mutex_unlock(&ui->ui_mutex);
>>>       if (release)
>>> @@ -1430,6 +1435,7 @@ static int update_mctime(struct inode *inode)
>>>           mutex_lock(&ui->ui_mutex);
>>>           inode->i_mtime = inode->i_ctime = ubifs_current_time(inode);
>>>           release = ui->dirty;
>>> +        ui->budgeted = 1;
>>>           mark_inode_dirty_sync(inode);
>>>           mutex_unlock(&ui->ui_mutex);
>>>           if (release)
>>> @@ -1556,6 +1562,7 @@ static int ubifs_vm_page_mkwrite(struct
>>> vm_area_struct *vma,
>>>           mutex_lock(&ui->ui_mutex);
>>>           inode->i_mtime = inode->i_ctime = ubifs_current_time(inode);
>>>           release = ui->dirty;
>>> +        ui->budgeted = 1;
>>>           mark_inode_dirty_sync(inode);
>>>           mutex_unlock(&ui->ui_mutex);
>>>           if (release)
>>> diff --git a/fs/ubifs/ioctl.c b/fs/ubifs/ioctl.c
>>> index 3c7b29d..f015b81 100644
>>> --- a/fs/ubifs/ioctl.c
>>> +++ b/fs/ubifs/ioctl.c
>>> @@ -128,6 +128,7 @@ static int setflags(struct inode *inode, int flags)
>>>       ubifs_set_inode_flags(inode);
>>>       inode->i_ctime = ubifs_current_time(inode);
>>>       release = ui->dirty;
>>> +    ui->budgeted = 1;
>>>       mark_inode_dirty_sync(inode);
>>>       mutex_unlock(&ui->ui_mutex);
>>>
>>> diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
>>> index 2491fff..5fa21d6 100644
>>> --- a/fs/ubifs/super.c
>>> +++ b/fs/ubifs/super.c
>>> @@ -331,6 +331,7 @@ static int ubifs_write_inode(struct inode *inode,
>>> struct writeback_control *wbc)
>>>       }
>>>
>>>       ui->dirty = 0;
>>> +    ui->budgeted = 0;
>>>       mutex_unlock(&ui->ui_mutex);
>>>       ubifs_release_dirty_inode_budget(c, ui);
>>>       return err;
>>> @@ -386,12 +387,23 @@ done:
>>>   static void ubifs_dirty_inode(struct inode *inode, int flags)
>>>   {
>>>           struct ubifs_inode *ui = ubifs_inode(inode);
>>> +    int need_unlock = 0;
>>>
>>> -    ubifs_assert(mutex_is_locked(&ui->ui_mutex));
>>> +    if (unlikely(!mutex_is_locked(&ui->ui_mutex))) {
>>> +        /* We need to lock ui_mutex to access ui->budgeted */
>>> +        mutex_lock(&ui->ui_mutex);
>>> +        need_unlock = 1;
>>> +    }
>>> +
>>> +    /* Check the budget for this inode */
>>> +    ubifs_assert(ui->budgeted);
>>>       if (!ui->dirty) {
>>>           ui->dirty = 1;
>>>           dbg_gen("inode %lu",  inode->i_ino);
>>>       }
>>> +
>>> +    if (need_unlock)
>>> +        mutex_unlock(&ui->ui_mutex);
>>>   }
>>>
>>>   static int ubifs_statfs(struct dentry *dentry, struct kstatfs *buf)
>>> diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
>>> index 9754bb6..28392a6 100644
>>> --- a/fs/ubifs/ubifs.h
>>> +++ b/fs/ubifs/ubifs.h
>>> @@ -410,6 +410,7 @@ struct ubifs_inode {
>>>       unsigned int xattr_cnt;
>>>       unsigned int xattr_names;
>>>       unsigned int dirty:1;
>>> +    unsigned int budgeted:1;
>>
>> Please document that new flag too.
>>
>> Thanks,
>> //richard
>> .
>>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> .
>


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

* Re: [RFC PATCH 00/25] Add quota supporting in ubifs
  2015-07-22  0:58   ` Dongsheng Yang
@ 2015-07-22  6:58     ` Richard Weinberger
  0 siblings, 0 replies; 52+ messages in thread
From: Richard Weinberger @ 2015-07-22  6:58 UTC (permalink / raw)
  To: Dongsheng Yang, dedekind1, jack; +Cc: linux-fsdevel, linux-mtd

Hi!

Am 22.07.2015 um 02:58 schrieb Dongsheng Yang:
>> I get this lockdep splat. Have you seen it too?
> 
> OMG, could you share the script to trigger it?

Bash history says:
  495  mount -t ubifs /dev/ubi0_0 /mnt -o usrquota,grpquota
  496  quotacheck -ug /mnt
  497  quotaon /mnt
  498  setquota root 10 10 3 3 /mnt
  499  dd if=/dev/urandom of=/mnt/xx bs=1M

So, basically your testing. :)
But on my UBI/FS testbad I have locked enabled by default.

BTW: If you face this splat you can ignore it:
http://lists.infradead.org/pipermail/linux-mtd/2015-July/060056.html

Thanks,
//richard

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

* Re: [RFC PATCH 00/25] Add quota supporting in ubifs
  2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
                   ` (28 preceding siblings ...)
  2015-07-21 21:15 ` Richard Weinberger
@ 2015-07-22 11:23 ` Dongsheng Yang
  2015-07-22 14:13   ` Jan Kara
  29 siblings, 1 reply; 52+ messages in thread
From: Dongsheng Yang @ 2015-07-22 11:23 UTC (permalink / raw)
  To: jack; +Cc: linux-fsdevel, linux-mtd, Dongsheng Yang

Hi Jan,
	I met an error message in my testing:
[104236.956171] __quota_error: 3600 callbacks suppressed
[104236.958772] Quota error (device ubifs): free_dqentry: Quota 
structure has offset to other block (0) than it should (5)

What does that mean? What's the kind of error? Could you give me
a clue for it?

Thanx a lot
Yang


On 07/21/2015 04:37 PM, Dongsheng Yang wrote:
> Hi Atem, Richard and others,
> 	This is a patchset to add quota supporting in ubifs.
> [1/25] - [7/25] are working to make quotactl to support filesystems
> which are running on char device.
>
> Others are about making ubifs to support quota
> Please help to review or test it. Any comment is welcome :).
>
> Hi Jan Kara,
> 	I am not sure I am using the quota APIs correctly, please
> help to correct me if I am wrong.
>
> Also you can get the code from:
> https://github.com/yangdongsheng/linux.git  ubifs_quota_v1
>
> 	My simple testing is shown as below:
> [root@atest-guest linux_compile]# mount -t ubifs -o usrquota,grpquota /dev/ubi0_0 /mnt/ubifs/
> [root@atest-guest linux_compile]# quotacheck -ug /mnt/ubifs
> [root@atest-guest linux_compile]# quotaon /mnt/ubifs
> [root@atest-guest linux_compile]# repquota /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      --       0       0       0              1     0     0
> [root@atest-guest linux_compile]# setquota root 10 10 3 3 /mnt/ubifs
> [root@atest-guest linux_compile]# repquota /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      --       0      10      10              1     3     3
> [root@atest-guest linux_compile]# touch /mnt/ubifs/{1,11,111}
> ubifs: warning, user file quota exceeded.
> [root@atest-guest linux_compile]# repquota /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      -+       0      10      10              4     3     3  7days
> [root@atest-guest linux_compile]# rm -rf /mnt/ubifs/1*
> [root@atest-guest linux_compile]# repquota /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      --       0      10      10              1     3     3
> [root@atest-guest linux_compile]# dd if=/dev/urandom of=/mnt/ubifs/data bs=1K count=11
> ubifs: warning, user block quota exceeded.
> 11+0 records in
> 11+0 records out
> 11264 bytes (11 kB) copied, 0.216498 s, 52.0 kB/s
> [root@atest-guest linux_compile]# repquota /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      +-      11      10      10  7days       2     3     3
> [root@atest-guest linux_compile]# rm -rf /mnt/ubifs/data
> [root@atest-guest linux_compile]# repquota /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      --       0      10      10              1     3     3
>
>
> Dongsheng Yang (25):
>    fs: introduce a ->s_cdev field into struct super_block
>    ubi: introduce a interface to get cdev in ubi_volume
>    ubifs: fill sb->s_cdev in ubifs_fill_super()
>    fs: super: introduce the functions to get super by cdev reference
>    fs: char_dev: introduce lookup_cdev function to find cdev by name
>    fs: dquot: skip invalidate_bdev if bdev is NULL
>    fs: quota: make quota support fs which is running on char dev
>    ubifs: fix a typo in comment of ubifs_budget_req
>    ubifs: extend budget for blocks
>    ubifs: fill ->s_dev in ubifs_fill_super
>    ubifs: export read_block() from file.c
>    ubifs: introduce quota related mount options
>    ubifs: introduce a field named as budgeted 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: suspend & resume quota properly in ubifs_remount
>    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_write_begin
>    ubifs: free quota space in do_truncation and unlink
>    ubifs: adapt quota space informatin in do_setattr
>    ubifs: transfer quota information in changing owner or group
>    ubifs: implement ubifs_qctl_operations for quotactl
>    ubifs: make ubifs to support quota
>
>   drivers/mtd/ubi/kapi.c  |   6 +
>   fs/char_dev.c           |  72 ++++++++++
>   fs/quota/dquot.c        |   3 +-
>   fs/quota/quota.c        |  30 +++--
>   fs/super.c              |  45 +++++++
>   fs/ubifs/budget.c       |   4 +
>   fs/ubifs/debug.c        |   2 +
>   fs/ubifs/dir.c          |  24 +++-
>   fs/ubifs/file.c         |  56 +++++++-
>   fs/ubifs/ioctl.c        |   1 +
>   fs/ubifs/super.c        | 352 +++++++++++++++++++++++++++++++++++++++++++++++-
>   fs/ubifs/ubifs.h        |  19 ++-
>   include/linux/fs.h      |   5 +
>   include/linux/mtd/ubi.h |   1 +
>   14 files changed, 597 insertions(+), 23 deletions(-)
>


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

* Re: [RFC PATCH 00/25] Add quota supporting in ubifs
  2015-07-22 11:23 ` Dongsheng Yang
@ 2015-07-22 14:13   ` Jan Kara
  0 siblings, 0 replies; 52+ messages in thread
From: Jan Kara @ 2015-07-22 14:13 UTC (permalink / raw)
  To: Dongsheng Yang; +Cc: jack, linux-fsdevel, linux-mtd

On Wed 22-07-15 19:23:54, Dongsheng Yang wrote:
> Hi Jan,
> 	I met an error message in my testing:
> [104236.956171] __quota_error: 3600 callbacks suppressed
> [104236.958772] Quota error (device ubifs): free_dqentry: Quota
> structure has offset to other block (0) than it should (5)
> 
> What does that mean? What's the kind of error? Could you give me
> a clue for it?

Each struct dquot has dq_off set to an offset of quota structure in the
quota file. On disk there is a radix tree for indexing quota structures and
this message complains that dq_off isn't the offset, where the lookup in
the radix tree would lead you. Actually from the message it seems dq_off is
within block 0, which really looks bogus... So you should investigate how
the value got there. 

								Honza

> On 07/21/2015 04:37 PM, Dongsheng Yang wrote:
> >Hi Atem, Richard and others,
> >	This is a patchset to add quota supporting in ubifs.
> >[1/25] - [7/25] are working to make quotactl to support filesystems
> >which are running on char device.
> >
> >Others are about making ubifs to support quota
> >Please help to review or test it. Any comment is welcome :).
> >
> >Hi Jan Kara,
> >	I am not sure I am using the quota APIs correctly, please
> >help to correct me if I am wrong.
> >
> >Also you can get the code from:
> >https://github.com/yangdongsheng/linux.git  ubifs_quota_v1
> >
> >	My simple testing is shown as below:
> >[root@atest-guest linux_compile]# mount -t ubifs -o usrquota,grpquota /dev/ubi0_0 /mnt/ubifs/
> >[root@atest-guest linux_compile]# quotacheck -ug /mnt/ubifs
> >[root@atest-guest linux_compile]# quotaon /mnt/ubifs
> >[root@atest-guest linux_compile]# repquota /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      --       0       0       0              1     0     0
> >[root@atest-guest linux_compile]# setquota root 10 10 3 3 /mnt/ubifs
> >[root@atest-guest linux_compile]# repquota /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      --       0      10      10              1     3     3
> >[root@atest-guest linux_compile]# touch /mnt/ubifs/{1,11,111}
> >ubifs: warning, user file quota exceeded.
> >[root@atest-guest linux_compile]# repquota /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      -+       0      10      10              4     3     3  7days
> >[root@atest-guest linux_compile]# rm -rf /mnt/ubifs/1*
> >[root@atest-guest linux_compile]# repquota /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      --       0      10      10              1     3     3
> >[root@atest-guest linux_compile]# dd if=/dev/urandom of=/mnt/ubifs/data bs=1K count=11
> >ubifs: warning, user block quota exceeded.
> >11+0 records in
> >11+0 records out
> >11264 bytes (11 kB) copied, 0.216498 s, 52.0 kB/s
> >[root@atest-guest linux_compile]# repquota /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      +-      11      10      10  7days       2     3     3
> >[root@atest-guest linux_compile]# rm -rf /mnt/ubifs/data
> >[root@atest-guest linux_compile]# repquota /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      --       0      10      10              1     3     3
> >
> >
> >Dongsheng Yang (25):
> >   fs: introduce a ->s_cdev field into struct super_block
> >   ubi: introduce a interface to get cdev in ubi_volume
> >   ubifs: fill sb->s_cdev in ubifs_fill_super()
> >   fs: super: introduce the functions to get super by cdev reference
> >   fs: char_dev: introduce lookup_cdev function to find cdev by name
> >   fs: dquot: skip invalidate_bdev if bdev is NULL
> >   fs: quota: make quota support fs which is running on char dev
> >   ubifs: fix a typo in comment of ubifs_budget_req
> >   ubifs: extend budget for blocks
> >   ubifs: fill ->s_dev in ubifs_fill_super
> >   ubifs: export read_block() from file.c
> >   ubifs: introduce quota related mount options
> >   ubifs: introduce a field named as budgeted 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: suspend & resume quota properly in ubifs_remount
> >   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_write_begin
> >   ubifs: free quota space in do_truncation and unlink
> >   ubifs: adapt quota space informatin in do_setattr
> >   ubifs: transfer quota information in changing owner or group
> >   ubifs: implement ubifs_qctl_operations for quotactl
> >   ubifs: make ubifs to support quota
> >
> >  drivers/mtd/ubi/kapi.c  |   6 +
> >  fs/char_dev.c           |  72 ++++++++++
> >  fs/quota/dquot.c        |   3 +-
> >  fs/quota/quota.c        |  30 +++--
> >  fs/super.c              |  45 +++++++
> >  fs/ubifs/budget.c       |   4 +
> >  fs/ubifs/debug.c        |   2 +
> >  fs/ubifs/dir.c          |  24 +++-
> >  fs/ubifs/file.c         |  56 +++++++-
> >  fs/ubifs/ioctl.c        |   1 +
> >  fs/ubifs/super.c        | 352 +++++++++++++++++++++++++++++++++++++++++++++++-
> >  fs/ubifs/ubifs.h        |  19 ++-
> >  include/linux/fs.h      |   5 +
> >  include/linux/mtd/ubi.h |   1 +
> >  14 files changed, 597 insertions(+), 23 deletions(-)
> >
> 
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

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

end of thread, other threads:[~2015-07-22 14:13 UTC | newest]

Thread overview: 52+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-21  8:37 [RFC PATCH 00/25] Add quota supporting in ubifs Dongsheng Yang
2015-07-21  8:37 ` [PATCH 01/25] fs: introduce a ->s_cdev field into struct super_block Dongsheng Yang
2015-07-21  8:37 ` [PATCH 02/25] ubi: introduce a interface to get cdev in ubi_volume Dongsheng Yang
2015-07-21  8:37 ` [PATCH 03/25] ubifs: fill sb->s_cdev in ubifs_fill_super() Dongsheng Yang
2015-07-21  8:37 ` [PATCH 04/25] fs: super: introduce the functions to get super by cdev reference Dongsheng Yang
2015-07-21  9:04   ` Jan Kara
2015-07-22  0:37     ` Dongsheng Yang
2015-07-21  8:37 ` [PATCH 05/25] fs: char_dev: introduce lookup_cdev function to find cdev by name Dongsheng Yang
2015-07-21  9:20   ` Jan Kara
2015-07-21  8:37 ` [PATCH 06/25] fs: dquot: skip invalidate_bdev if bdev is NULL Dongsheng Yang
2015-07-21  8:37 ` [PATCH 07/25] fs: quota: make quota support fs which is running on char dev Dongsheng Yang
2015-07-21  8:37   ` Dongsheng Yang
2015-07-21  8:37 ` [PATCH 08/25] ubifs: fix a typo in comment of ubifs_budget_req Dongsheng Yang
2015-07-21  8:37   ` Dongsheng Yang
2015-07-21  8:37 ` [PATCH 09/25] ubifs: extend budget for blocks Dongsheng Yang
2015-07-21  8:37   ` Dongsheng Yang
2015-07-21  8:37 ` [PATCH 10/25] ubifs: fill ->s_dev in ubifs_fill_super Dongsheng Yang
2015-07-21  8:37 ` [PATCH 11/25] ubifs: export read_block() from file.c Dongsheng Yang
2015-07-21 20:36   ` Richard Weinberger
2015-07-22  0:41     ` Dongsheng Yang
2015-07-21  8:37 ` [PATCH 12/25] ubifs: introduce quota related mount options Dongsheng Yang
2015-07-21 20:39   ` Richard Weinberger
2015-07-22  0:41     ` Dongsheng Yang
2015-07-21  8:37 ` [PATCH 13/25] ubifs: introduce a field named as budgeted to ubifs_inode Dongsheng Yang
2015-07-21  8:37   ` Dongsheng Yang
2015-07-21 20:47   ` Richard Weinberger
2015-07-22  0:56     ` Dongsheng Yang
2015-07-22  6:22       ` Dongsheng Yang
2015-07-21  8:37 ` [PATCH 14/25] ubifs: implement IO functions for quota files Dongsheng Yang
2015-07-21  8:37 ` [PATCH 15/25] ubifs: disable quota in ubifs_put_super Dongsheng Yang
2015-07-21  8:37 ` [PATCH 16/25] ubifs: write quota back in ubifs_sync Dongsheng Yang
2015-07-21  8:37 ` [PATCH 17/25] ubifs: suspend & resume quota properly in ubifs_remount Dongsheng Yang
2015-07-21  8:37   ` Dongsheng Yang
2015-07-21  8:37 ` [PATCH 18/25] ubifs: record quota information about inode in ubifs_new_inode Dongsheng Yang
2015-07-21  8:37 ` [PATCH 19/25] ubifs: free quota inode information in ubifs_evict_inode Dongsheng Yang
2015-07-21  8:37 ` [PATCH 20/25] ubifs: alloc quota space in ubifs_write_begin Dongsheng Yang
2015-07-21  8:37 ` [PATCH 21/25] ubifs: free quota space in do_truncation and unlink Dongsheng Yang
2015-07-21  8:37 ` [PATCH 22/25] ubifs: adapt quota space informatin in do_setattr Dongsheng Yang
2015-07-21  8:37 ` [PATCH 23/25] ubifs: transfer quota information in changing owner or group Dongsheng Yang
2015-07-21  8:37 ` [PATCH 24/25] ubifs: implement ubifs_qctl_operations for quotactl Dongsheng Yang
2015-07-21  8:37 ` [PATCH 25/25] ubifs: make ubifs to support quota Dongsheng Yang
2015-07-21  8:58 ` [RFC PATCH 00/25] Add quota supporting in ubifs Jan Kara
2015-07-22  0:56   ` Dongsheng Yang
2015-07-21 20:50 ` Richard Weinberger
2015-07-22  1:11   ` Dongsheng Yang
2015-07-21 21:01 ` Richard Weinberger
2015-07-22  0:58   ` Dongsheng Yang
2015-07-21 21:15 ` Richard Weinberger
2015-07-22  0:58   ` Dongsheng Yang
2015-07-22  6:58     ` Richard Weinberger
2015-07-22 11:23 ` Dongsheng Yang
2015-07-22 14:13   ` Jan Kara

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.