Message ID | 20210122151536.7982-2-s.hauer@pengutronix.de |
---|---|
State | Superseded |
Headers | show |
Series | Add quota support to UBIFS | expand |
On Fri, Jan 22, 2021 at 04:15:29PM +0100, Sascha Hauer wrote: > This patch introduces the Q_PATH flag to the quotactl cmd argument. > When given, the path given in the special argument to quotactl will > be the mount path where the filesystem is mounted, instead of a path > to the block device. > This is necessary for filesystems which do not have a block device as > backing store. Particularly this is done for upcoming UBIFS support. > > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> I hate overloading quotactl even more. Why not add a new quotactl_path syscall instead? > +static struct super_block *quotactl_sb(dev_t dev, int cmd) > { > struct super_block *sb; > bool excl = false, thawed = false; > > if (quotactl_cmd_onoff(cmd)) { > excl = true; > @@ -901,12 +887,50 @@ static struct super_block *quotactl_block(const char __user *special, int cmd) > goto retry; > } > return sb; > +} > + > +/* > + * look up a superblock on which quota ops will be performed > + * - use the name of a block device to find the superblock thereon > + */ > +static struct super_block *quotactl_block(const char __user *special, int cmd) > +{ > +#ifdef CONFIG_BLOCK > + struct filename *tmp = getname(special); > + int error; > + dev_t dev; > > + if (IS_ERR(tmp)) > + return ERR_CAST(tmp); > + error = lookup_bdev(tmp->name, &dev); > + putname(tmp); > + if (error) > + return ERR_PTR(error); > + > + return quotactl_sb(dev, cmd); > #else > return ERR_PTR(-ENODEV); > #endif Normal kernel style would be to keep the ifdef entirely outside the function. > +static struct super_block *quotactl_path(const char __user *special, int cmd) > +{ > + struct super_block *sb; > + struct path path; > + int error; > + > + error = user_path_at(AT_FDCWD, special, LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT, > + &path); This adds an overly long line. > + if (error) > + return ERR_PTR(error); > + > + sb = quotactl_sb(path.mnt->mnt_sb->s_dev, cmd); I think quotactl_sb should take the superblock directly. This will need a little refactoring of user_get_super, but will lead to much better logic.
On Fri, Jan 22, 2021 at 05:16:58PM +0000, Christoph Hellwig wrote: > On Fri, Jan 22, 2021 at 04:15:29PM +0100, Sascha Hauer wrote: > > This patch introduces the Q_PATH flag to the quotactl cmd argument. > > When given, the path given in the special argument to quotactl will > > be the mount path where the filesystem is mounted, instead of a path > > to the block device. > > This is necessary for filesystems which do not have a block device as > > backing store. Particularly this is done for upcoming UBIFS support. > > > > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> > > I hate overloading quotactl even more. Why not add a new quotactl_path > syscall instead? We can probably do that. Honza, what do you think? > > > +static struct super_block *quotactl_sb(dev_t dev, int cmd) > > { > > struct super_block *sb; > > bool excl = false, thawed = false; > > > > if (quotactl_cmd_onoff(cmd)) { > > excl = true; > > @@ -901,12 +887,50 @@ static struct super_block *quotactl_block(const char __user *special, int cmd) > > goto retry; > > } > > return sb; > > +} > > + > > +/* > > + * look up a superblock on which quota ops will be performed > > + * - use the name of a block device to find the superblock thereon > > + */ > > +static struct super_block *quotactl_block(const char __user *special, int cmd) > > +{ > > +#ifdef CONFIG_BLOCK > > + struct filename *tmp = getname(special); > > + int error; > > + dev_t dev; > > > > + if (IS_ERR(tmp)) > > + return ERR_CAST(tmp); > > + error = lookup_bdev(tmp->name, &dev); > > + putname(tmp); > > + if (error) > > + return ERR_PTR(error); > > + > > + return quotactl_sb(dev, cmd); > > #else > > return ERR_PTR(-ENODEV); > > #endif > > Normal kernel style would be to keep the ifdef entirely outside the > function. It has been like this before, so changing this should be done in an extra patch. Not sure if it's worth it though. > > > +static struct super_block *quotactl_path(const char __user *special, int cmd) > > +{ > > + struct super_block *sb; > > + struct path path; > > + int error; > > + > > + error = user_path_at(AT_FDCWD, special, LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT, > > + &path); > > This adds an overly long line. ok, will change. > > > + if (error) > > + return ERR_PTR(error); > > + > > + sb = quotactl_sb(path.mnt->mnt_sb->s_dev, cmd); > > I think quotactl_sb should take the superblock directly. This will > need a little refactoring of user_get_super, but will lead to much > better logic. What do you mean by "take"? Take the superblock as an argument to quotactl_sb() or take a reference to the superblock? Sorry, I don't really get where you aiming at. Sascha
On Mon 25-01-21 09:38:54, Sascha Hauer wrote: > On Fri, Jan 22, 2021 at 05:16:58PM +0000, Christoph Hellwig wrote: > > On Fri, Jan 22, 2021 at 04:15:29PM +0100, Sascha Hauer wrote: > > > This patch introduces the Q_PATH flag to the quotactl cmd argument. > > > When given, the path given in the special argument to quotactl will > > > be the mount path where the filesystem is mounted, instead of a path > > > to the block device. > > > This is necessary for filesystems which do not have a block device as > > > backing store. Particularly this is done for upcoming UBIFS support. > > > > > > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> > > > > I hate overloading quotactl even more. Why not add a new quotactl_path > > syscall instead? > > We can probably do that. Honza, what do you think? Hum, yes, probably it would be cleaner to add a new syscall for this so that we don't overload quotactl(2). I just didn't think of this. > > > +static struct super_block *quotactl_path(const char __user *special, int cmd) > > > +{ > > > + struct super_block *sb; > > > + struct path path; > > > + int error; > > > + > > > + error = user_path_at(AT_FDCWD, special, LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT, > > > + &path); > > > > This adds an overly long line. > > ok, will change. > > > > > > + if (error) > > > + return ERR_PTR(error); > > > + > > > + sb = quotactl_sb(path.mnt->mnt_sb->s_dev, cmd); > > > > I think quotactl_sb should take the superblock directly. This will > > need a little refactoring of user_get_super, but will lead to much > > better logic. > > What do you mean by "take"? Take the superblock as an argument to > quotactl_sb() or take a reference to the superblock? > Sorry, I don't really get where you aiming at. I think Christoph was pointing at the fact it is suboptimal to search for superblock by device number when you already have a pointer to it. And I guess he was suggesting we could pass 'sb' pointer to quotactl_sb() when we already have it. Although to be honest, I'm not sure how Christoph imagines the refactoring of user_get_super() he mentions - when we have a path looked up through user_path(), that pins the superblock the path is on so it cannot be unmounted. So perhaps quotactl_sb() can done like: ... retry: if (passed_sb) { sb = passed_sb; sb->s_count++; if (excl) down_write(&sb->s_umount); else down_read(&sb->s_umount); } else { sb = user_get_super(dev, excl); if (!sb) return ERR_PTR(-ENODEV); } ... Honza
On Mon, Jan 25, 2021 at 04:45:07PM +0100, Jan Kara wrote: > > What do you mean by "take"? Take the superblock as an argument to > > quotactl_sb() or take a reference to the superblock? > > Sorry, I don't really get where you aiming at. > > I think Christoph was pointing at the fact it is suboptimal to search for > superblock by device number when you already have a pointer to it. And I > guess he was suggesting we could pass 'sb' pointer to quotactl_sb() when we > already have it. Although to be honest, I'm not sure how Christoph imagines > the refactoring of user_get_super() he mentions - when we have a path > looked up through user_path(), that pins the superblock the path is on so > it cannot be unmounted. So perhaps quotactl_sb() can done like: I don't think we need a quotactl_sb at all, do_quotactl is in fact a pretty good abstraction as-is. For the path based one we just need to factor out a little helper to set excl and thaw and then call it like: sb = path.dentry->d_inode->i_sb; if (excl) down_write(&sb->s_umount); else down_read(&sb->s_umount); if (thawed && sb->s_writers.frozen != SB_UNFROZEN) ret = -EBUSY; else ret = do_quotactl(sb, type, cmds, id, addr, &path); if (excl) up_write(&sb->s_umount); else up_read(&sb->s_umount); as there is no good reason to bring over the somewhat strange wait until unfrozen semantics to a new syscall.
On Mon, Jan 25, 2021 at 04:45:07PM +0100, Jan Kara wrote: > On Mon 25-01-21 09:38:54, Sascha Hauer wrote: > > On Fri, Jan 22, 2021 at 05:16:58PM +0000, Christoph Hellwig wrote: > > > On Fri, Jan 22, 2021 at 04:15:29PM +0100, Sascha Hauer wrote: > > > > This patch introduces the Q_PATH flag to the quotactl cmd argument. > > > > When given, the path given in the special argument to quotactl will > > > > be the mount path where the filesystem is mounted, instead of a path > > > > to the block device. > > > > This is necessary for filesystems which do not have a block device as > > > > backing store. Particularly this is done for upcoming UBIFS support. > > > > > > > > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> > > > > > > I hate overloading quotactl even more. Why not add a new quotactl_path > > > syscall instead? > > > > We can probably do that. Honza, what do you think? > > Hum, yes, probably it would be cleaner to add a new syscall for this so > that we don't overload quotactl(2). I just didn't think of this. How should the semantics of that new syscall look like? The easiest and most obvious way would be to do it like the quotactl(2) and just replace the special argument with a path: int quotactl_path(int cmd, const char *path, int id, caddr_t addr); If we try adding a new syscall then we could completely redefine the API and avoid the shortcomings of the original quotactl(2) if there are any. Can you foresee the discussions we end up in? I am afraid I am opening a can of worms here. OTOH there might be value in keeping the new syscall compatible to the existing one, but I don't know how much this argument counts. Sascha
On Mon 25-01-21 20:42:49, Christoph Hellwig wrote: > On Mon, Jan 25, 2021 at 04:45:07PM +0100, Jan Kara wrote: > > > What do you mean by "take"? Take the superblock as an argument to > > > quotactl_sb() or take a reference to the superblock? > > > Sorry, I don't really get where you aiming at. > > > > I think Christoph was pointing at the fact it is suboptimal to search for > > superblock by device number when you already have a pointer to it. And I > > guess he was suggesting we could pass 'sb' pointer to quotactl_sb() when we > > already have it. Although to be honest, I'm not sure how Christoph imagines > > the refactoring of user_get_super() he mentions - when we have a path > > looked up through user_path(), that pins the superblock the path is on so > > it cannot be unmounted. So perhaps quotactl_sb() can done like: > > I don't think we need a quotactl_sb at all, do_quotactl is in fact a > pretty good abstraction as-is. > > For the path based one we just need to factor out a little helper > to set excl and thaw and then call it like: > > sb = path.dentry->d_inode->i_sb; > > if (excl) > down_write(&sb->s_umount); > else > down_read(&sb->s_umount); > if (thawed && sb->s_writers.frozen != SB_UNFROZEN) > ret = -EBUSY; > else > ret = do_quotactl(sb, type, cmds, id, addr, &path); > if (excl) > up_write(&sb->s_umount); > else > up_read(&sb->s_umount); > > as there is no good reason to bring over the somewhat strange wait until > unfrozen semantics to a new syscall. Well, I don't think that "wait until unfrozen" is that strange e.g. for Q_SETQUOTA - it behaves like setxattr() or any other filesystem modification operation. And IMO it is desirable that filesystem freezing is transparent for operations like these. For stuff like Q_QUOTAON, I agree that returning EBUSY makes sense but then I'm not convinced it's really simpler or more useful behavior... Honza
On Tue, Jan 26, 2021 at 02:17:52PM +0100, Jan Kara wrote: > Well, I don't think that "wait until unfrozen" is that strange e.g. for > Q_SETQUOTA - it behaves like setxattr() or any other filesystem > modification operation. And IMO it is desirable that filesystem freezing is > transparent for operations like these. For stuff like Q_QUOTAON, I agree > that returning EBUSY makes sense but then I'm not convinced it's really > simpler or more useful behavior... If we want it to behave like other syscalls we'll just need to throw in a mnt_want_write/mnt_drop_write pair. Than it behaves exactly like other syscalls.
On Tue 26-01-21 13:34:06, Christoph Hellwig wrote: > On Tue, Jan 26, 2021 at 02:17:52PM +0100, Jan Kara wrote: > > Well, I don't think that "wait until unfrozen" is that strange e.g. for > > Q_SETQUOTA - it behaves like setxattr() or any other filesystem > > modification operation. And IMO it is desirable that filesystem freezing is > > transparent for operations like these. For stuff like Q_QUOTAON, I agree > > that returning EBUSY makes sense but then I'm not convinced it's really > > simpler or more useful behavior... > > If we want it to behave like other syscalls we'll just need to throw in > a mnt_want_write/mnt_drop_write pair. Than it behaves exactly like other > syscalls. Right, we could do that. I'd just note that the "wait until unfrozen" and holding of sb->s_umount semaphore is equivalent to mnt_want_write/mnt_drop_write pair. But I agree mnt_want_write/mnt_drop_write is easier to understand and there's no reason not to use it. So I'm for that simplification in the new syscall. Honza
On Tue, Jan 26, 2021 at 05:18:29PM +0100, Jan Kara wrote: > On Tue 26-01-21 13:34:06, Christoph Hellwig wrote: > > On Tue, Jan 26, 2021 at 02:17:52PM +0100, Jan Kara wrote: > > > Well, I don't think that "wait until unfrozen" is that strange e.g. for > > > Q_SETQUOTA - it behaves like setxattr() or any other filesystem > > > modification operation. And IMO it is desirable that filesystem freezing is > > > transparent for operations like these. For stuff like Q_QUOTAON, I agree > > > that returning EBUSY makes sense but then I'm not convinced it's really > > > simpler or more useful behavior... > > > > If we want it to behave like other syscalls we'll just need to throw in > > a mnt_want_write/mnt_drop_write pair. Than it behaves exactly like other > > syscalls. > > Right, we could do that. I'd just note that the "wait until unfrozen" and > holding of sb->s_umount semaphore is equivalent to > mnt_want_write/mnt_drop_write pair. But I agree > mnt_want_write/mnt_drop_write is easier to understand and there's no reason > not to use it. So I'm for that simplification in the new syscall. Due to the user_path_at() to the mountpoint the fs won't go away, so I guess for non-exclusive, non-write quota command I don't need any additional locking. For non-exclusive, write commands I'll need a mnt_want_write/mnt_drop_write pair. What about the exclusive, write commands (Q_QUOTAON/Q_QUOTAOFF)? Sascha
On Wed 27-01-21 15:05:10, Sascha Hauer wrote: > On Tue, Jan 26, 2021 at 05:18:29PM +0100, Jan Kara wrote: > > On Tue 26-01-21 13:34:06, Christoph Hellwig wrote: > > > On Tue, Jan 26, 2021 at 02:17:52PM +0100, Jan Kara wrote: > > > > Well, I don't think that "wait until unfrozen" is that strange e.g. for > > > > Q_SETQUOTA - it behaves like setxattr() or any other filesystem > > > > modification operation. And IMO it is desirable that filesystem freezing is > > > > transparent for operations like these. For stuff like Q_QUOTAON, I agree > > > > that returning EBUSY makes sense but then I'm not convinced it's really > > > > simpler or more useful behavior... > > > > > > If we want it to behave like other syscalls we'll just need to throw in > > > a mnt_want_write/mnt_drop_write pair. Than it behaves exactly like other > > > syscalls. > > > > Right, we could do that. I'd just note that the "wait until unfrozen" and > > holding of sb->s_umount semaphore is equivalent to > > mnt_want_write/mnt_drop_write pair. But I agree > > mnt_want_write/mnt_drop_write is easier to understand and there's no reason > > not to use it. So I'm for that simplification in the new syscall. > > Due to the user_path_at() to the mountpoint the fs won't go away, so I > guess for non-exclusive, non-write quota command I don't need any > additional locking. They still need s_umount in read mode - to serialize against quotaon / quotaoff (happening either through quotactl or filesystem remount). > For non-exclusive, write commands I'll need a > mnt_want_write/mnt_drop_write pair. What about the exclusive, write > commands (Q_QUOTAON/Q_QUOTAOFF)? And these still need s_umount in write mode for similar reasons. So the only thing you really save is the "wait-for-unfreeze" code. Honza
On Tue 26-01-21 11:45:57, Sascha Hauer wrote: > On Mon, Jan 25, 2021 at 04:45:07PM +0100, Jan Kara wrote: > > On Mon 25-01-21 09:38:54, Sascha Hauer wrote: > > > On Fri, Jan 22, 2021 at 05:16:58PM +0000, Christoph Hellwig wrote: > > > > On Fri, Jan 22, 2021 at 04:15:29PM +0100, Sascha Hauer wrote: > > > > > This patch introduces the Q_PATH flag to the quotactl cmd argument. > > > > > When given, the path given in the special argument to quotactl will > > > > > be the mount path where the filesystem is mounted, instead of a path > > > > > to the block device. > > > > > This is necessary for filesystems which do not have a block device as > > > > > backing store. Particularly this is done for upcoming UBIFS support. > > > > > > > > > > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> > > > > > > > > I hate overloading quotactl even more. Why not add a new quotactl_path > > > > syscall instead? > > > > > > We can probably do that. Honza, what do you think? > > > > Hum, yes, probably it would be cleaner to add a new syscall for this so > > that we don't overload quotactl(2). I just didn't think of this. > > How should the semantics of that new syscall look like? > > The easiest and most obvious way would be to do it like the quotactl(2) > and just replace the special argument with a path: > > int quotactl_path(int cmd, const char *path, int id, caddr_t addr); Yes, that's what I meant. > If we try adding a new syscall then we could completely redefine the API > and avoid the shortcomings of the original quotactl(2) if there are any. > Can you foresee the discussions we end up in? I am afraid I am opening a > can of worms here. > OTOH there might be value in keeping the new syscall compatible to the > existing one, but I don't know how much this argument counts. That's a good question but also a can of worms as you write :). One obvious problem with quotactl() is that's it's ioctl-like interface. So we have several different operations mixed into a single syscall. Currently there are these operations: #define Q_SYNC 0x800001 /* sync disk copy of a filesystems quotas */ #define Q_QUOTAON 0x800002 /* turn quotas on */ #define Q_QUOTAOFF 0x800003 /* turn quotas off */ #define Q_GETFMT 0x800004 /* get quota format used on given filesystem */ #define Q_GETINFO 0x800005 /* get information about quota files */ #define Q_SETINFO 0x800006 /* set information about quota files */ #define Q_GETQUOTA 0x800007 /* get user quota structure */ #define Q_SETQUOTA 0x800008 /* set user quota structure */ #define Q_GETNEXTQUOTA 0x800009 /* get disk limits and usage >= ID */ <plus their XFS variants> In a puristic world they'd be 9 different syscalls ... or somewhat less because Q_GETNEXTQUOTA is a superset of Q_GETQUOTA, we could drop Q_SYNC and Q_GETFMT because they have dubious value these days so we'd be left with 6. I don't have a strong opinion whether 6 syscalls are worth the cleanliness or whether we should go with just one new quotactl_path() syscall. I've CCed linux-api in case other people have opinion. Anyway, even if we go with single quotactl_path() syscall we should remove the duplication between VFS and XFS quotactls when we are creating a new syscall. Thoughts? Honza
On Wed, Jan 27, 2021 at 03:46:46PM +0100, Jan Kara wrote: > In a puristic world they'd be 9 different syscalls ... or somewhat less > because Q_GETNEXTQUOTA is a superset of Q_GETQUOTA, we could drop Q_SYNC > and Q_GETFMT because they have dubious value these days so we'd be left > with 6. I don't have a strong opinion whether 6 syscalls are worth the > cleanliness or whether we should go with just one new quotactl_path() > syscall. I've CCed linux-api in case other people have opinion. > > Anyway, even if we go with single quotactl_path() syscall we should remove > the duplication between VFS and XFS quotactls when we are creating a new > syscall. Thoughts? I thunk the multiplexer is just fine. We don't really need Q_SYNC for a new syscall. For XFS vs classic VFS quota we probably don't need to duplicate the two data structure, but we need to make sure we catch the superset of the information if we want to disable the old ones. So I suspect just supporting evrything excpt for the global Q_SYNC and reusing do_quotactl as-is is the most maintainable and easiest to understand way forward.
diff --git a/fs/quota/quota.c b/fs/quota/quota.c index 6d16b2be5ac4..f653b27a9a4e 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c @@ -17,6 +17,7 @@ #include <linux/capability.h> #include <linux/quotaops.h> #include <linux/types.h> +#include <linux/mount.h> #include <linux/writeback.h> #include <linux/nospec.h> #include "compat.h" @@ -859,25 +860,10 @@ static bool quotactl_cmd_onoff(int cmd) (cmd == Q_XQUOTAON) || (cmd == Q_XQUOTAOFF); } -/* - * look up a superblock on which quota ops will be performed - * - use the name of a block device to find the superblock thereon - */ -static struct super_block *quotactl_block(const char __user *special, int cmd) +static struct super_block *quotactl_sb(dev_t dev, int cmd) { -#ifdef CONFIG_BLOCK struct super_block *sb; - struct filename *tmp = getname(special); bool excl = false, thawed = false; - int error; - dev_t dev; - - if (IS_ERR(tmp)) - return ERR_CAST(tmp); - error = lookup_bdev(tmp->name, &dev); - putname(tmp); - if (error) - return ERR_PTR(error); if (quotactl_cmd_onoff(cmd)) { excl = true; @@ -901,12 +887,50 @@ static struct super_block *quotactl_block(const char __user *special, int cmd) goto retry; } return sb; +} + +/* + * look up a superblock on which quota ops will be performed + * - use the name of a block device to find the superblock thereon + */ +static struct super_block *quotactl_block(const char __user *special, int cmd) +{ +#ifdef CONFIG_BLOCK + struct filename *tmp = getname(special); + int error; + dev_t dev; + if (IS_ERR(tmp)) + return ERR_CAST(tmp); + error = lookup_bdev(tmp->name, &dev); + putname(tmp); + if (error) + return ERR_PTR(error); + + return quotactl_sb(dev, cmd); #else return ERR_PTR(-ENODEV); #endif } +static struct super_block *quotactl_path(const char __user *special, int cmd) +{ + struct super_block *sb; + struct path path; + int error; + + error = user_path_at(AT_FDCWD, special, LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT, + &path); + if (error) + return ERR_PTR(error); + + sb = quotactl_sb(path.mnt->mnt_sb->s_dev, cmd); + + path_put(&path); + + return sb; +} + /* * This is the system call interface. This communicates with * the user-level programs. Currently this only supports diskquota @@ -920,6 +944,7 @@ SYSCALL_DEFINE4(quotactl, unsigned int, cmd, const char __user *, special, struct super_block *sb = NULL; struct path path, *pathp = NULL; int ret; + bool q_path; cmds = cmd >> SUBCMDSHIFT; type = cmd & SUBCMDMASK; @@ -927,6 +952,9 @@ SYSCALL_DEFINE4(quotactl, unsigned int, cmd, const char __user *, special, if (type >= MAXQUOTAS) return -EINVAL; + q_path = cmds & Q_PATH; + cmds &= ~Q_PATH; + /* * As a special case Q_SYNC can be called without a specific device. * It will iterate all superblocks that have quota enabled and call @@ -951,7 +979,11 @@ SYSCALL_DEFINE4(quotactl, unsigned int, cmd, const char __user *, special, pathp = &path; } - sb = quotactl_block(special, cmds); + if (q_path) + sb = quotactl_path(special, cmds); + else + sb = quotactl_block(special, cmds); + if (IS_ERR(sb)) { ret = PTR_ERR(sb); goto out; diff --git a/include/uapi/linux/quota.h b/include/uapi/linux/quota.h index f17c9636a859..e1787c0df601 100644 --- a/include/uapi/linux/quota.h +++ b/include/uapi/linux/quota.h @@ -71,6 +71,7 @@ #define Q_GETQUOTA 0x800007 /* get user quota structure */ #define Q_SETQUOTA 0x800008 /* set user quota structure */ #define Q_GETNEXTQUOTA 0x800009 /* get disk limits and usage >= ID */ +#define Q_PATH 0x400000 /* quotactl special arg contains mount path */ /* Quota format type IDs */ #define QFMT_VFS_OLD 1
This patch introduces the Q_PATH flag to the quotactl cmd argument. When given, the path given in the special argument to quotactl will be the mount path where the filesystem is mounted, instead of a path to the block device. This is necessary for filesystems which do not have a block device as backing store. Particularly this is done for upcoming UBIFS support. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- fs/quota/quota.c | 66 ++++++++++++++++++++++++++++---------- include/uapi/linux/quota.h | 1 + 2 files changed, 50 insertions(+), 17 deletions(-)