* [PATCH 00/14] xfs: Support for interacting with multiple user namespaces
@ 2013-03-13 22:21 Eric W. Biederman
[not found] ` <87boan3prc.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
0 siblings, 1 reply; 16+ messages in thread
From: Eric W. Biederman @ 2013-03-13 22:21 UTC (permalink / raw)
To: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA
Cc: Alex Elder, Linux Containers, Dave Chinner,
xfs-VZNHf3L845pBDgjK7y7TUQ, Ben Myers
Or replace uids, gids, and projids with kuids, kgids, and kprojids
In support of user namespaces I have introduced into the kernel kuids,
kgids, and kprojids. The most important characteristic of these ids is
that they are not assignment compatible with uids, gids, and projids
coming from userspace nor are they assignment compatible with uids, gids
or projids stored on disk. This assignment incompatibility makes it
easy to ensure that conversions are introduced at the edge of userspace
and at the interface between on-disk and in-memory data structures.
Getting all of the conversions in all of the right places is important
because if one is missed it can easily become a permission check that
compares the wrong values.
While doing these conversions I have learned time and time again that if
I do not push kuids and kgids down into every in memory data structure I
can find there will be important conversions that are missed.
Converting xfs is an interesting challenge because of the way xfs
handles it's inode data is very atypical. XFS does two things no other
filesystem in linux does. XFS dumps it's in-memory inode structure
directly into the on-disk journal without any conversion. After an
inode has been evicted from vfs inode cache XFS continues to cache the
inode for a time, so that if the inode is needed before all of the
state for the inode has been written to disk an uptodate copy can be
obtained from the in-memory cached inode.
Interacting with users in different user namespaces for filesystems for
the most part is easy. The vfs data structures hand off kuids and kgids
to the filesystem. The filesystem then places those kuids and kgids in
it's in memory data structures (if it has any beyond struct inode).
When data is read from disk the uid and gid values are converted from
values in the initial user namespace to kuid and kgid values. When data
is written to disk the kuids and kgids are converted into uid and gid
values in the initial user namespace.
The initial user namespace is chosen for data on disk, because that is
the user namespace that the data on disk uses for unconverted
filesystems.
When interacting with userspace processes the values are stored
in the current user namespace, which is different for each process.
For example in this chunk of code that has caused some questions what is
happening is:
+ if (mask & FSX_PROJID) {
+ projid = make_kprojid(current_user_ns(), fa->fsx_projid);
+ if (!projid_valid(projid))
+ return XFS_ERROR(EINVAL);
fsx_projid is coming from userspace so we convert it from whatever the
userspace value is in the current user namespace to a kprojid.
+ /*
+ * Disallow 32bit project ids when projid32bit feature is not enabled.
+ */
+ if ((from_kprojid(&init_user_ns, projid) > (__uint16_t)-1) &&
The disk might only support 16bit project ids. So the kprojid is
converted into a projid in the initial user namespace to see what the
value we will eventually try to store on-disk is. If the on-disk value
is larger than (2^16-1) an error is flagged.
+ !xfs_sb_version_hasprojid32bit(&ip->i_mount->m_sb))
+ return XFS_ERROR(EINVAL);
+ }
In earlier versions of this patchset I have run afoul of the fact that the
in-memory inode is dumped to disk making a change to that data structure an
ABI change, and then I ran afoul of the fact that despite the fact that
struct xfs_inode survives the embedded struct inode may be evicted from the
vfs and become invalid and all of it's contents stomped with
inode_init_always.
Given the number of ioctls that xfs supports it would be irresponsible to
do anything except insist that kuids, kgids, and kprojids are used in all of
in memory data structures of xfs, as otherwise it becomes trivially easy to
miss a needed conversion with the advent of a new ioctl.
It has been suggested that kuids, and kgids are a vfs construct and should
stop at the vfs and should not be used in xfs data structures. They are
not a vfs construct they are a kernel construct and are used everywhere in
the kernel. xfs does not get to be an exception.
To put kuids, kgids, and kprojids in all of the xfs data structures without
breaking the on-disk ABI, this patchset moves struct xfs_icdinode from
struct xfs_inode to xfs_log_item, and introduces a set of conversion
functions. Introducing the separation between on-disk and in-memory format
that is needed to properly perform this conversion.
I have a few additional patches not included in this posting sitting in my
development tree that removes the extra copie that this change introduces
into xfs_inode_item_format.
xfstests in this instance are boring the same 17 tests keep failing both
before and after my changes.
I don't care through which tree these changes are merged. If you would
like to take these in through xfs tree that would be great. Otherwise I
will be happy to take these changes through my user namespace tree.
Eric
Eric W. Biederman (14):
xfs: Convert uids and gids in xfs acls to/from kuids and kgids
xfs: Separate the in core and the logged inode.
xfs: Store projectid as a single variable.
xfs: Update inode uids, gids, and projids to be kuids, kgids, and kprojids
xfs: Update xfs_ioctl_setattr to handle projids in any user namespace
xfs: Use kuids and kgids in xfs_setattr_nonsize
xfs: Update ioctl(XFS_IOC_FREE_EOFBLOCKS) to handle callers in any userspace
xfs: Use kprojids when allocating inodes.
xfs: Modify xfs_qm_vop_dqalloc to take kuids, kgids, and kprojids.
xfs: Push struct kqid into xfs_qm_scall_qmlim and xfs_qm_scall_getquota
xfs: Modify xfs_qm_dqget to take a struct kqid.
xfs: Remember the kqid for a quota
xfs: Use q_id instead of q_core.d_id.
xfs: Enable building with user namespaces enabled.
fs/xfs/xfs_acl.c | 23 ++++++-
fs/xfs/xfs_dquot.c | 39 ++++++++----
fs/xfs/xfs_dquot.h | 13 +++-
fs/xfs/xfs_icache.c | 14 ++--
fs/xfs/xfs_icache.h | 11 +++-
fs/xfs/xfs_inode.c | 160 +++++++++++++++++++++++++++++++++-------------
fs/xfs/xfs_inode.h | 51 +++++++++------
fs/xfs/xfs_inode_item.c | 3 +-
fs/xfs/xfs_inode_item.h | 1 +
fs/xfs/xfs_ioctl.c | 52 ++++++++++++---
fs/xfs/xfs_iops.c | 14 ++--
fs/xfs/xfs_itable.c | 47 +++++++-------
fs/xfs/xfs_qm.c | 83 ++++++++++++------------
fs/xfs/xfs_qm.h | 4 +-
fs/xfs/xfs_qm_bhv.c | 2 +-
fs/xfs/xfs_qm_syscalls.c | 24 ++++---
fs/xfs/xfs_quota.h | 4 +-
fs/xfs/xfs_quotaops.c | 20 +-----
fs/xfs/xfs_rename.c | 2 +-
fs/xfs/xfs_trace.h | 2 +-
fs/xfs/xfs_trans_dquot.c | 8 +--
fs/xfs/xfs_utils.c | 2 +-
fs/xfs/xfs_utils.h | 2 +-
fs/xfs/xfs_vnodeops.c | 14 ++--
init/Kconfig | 1 -
25 files changed, 366 insertions(+), 230 deletions(-)
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 01/14] xfs: Convert uids and gids in xfs acls to/from kuids and kgids
[not found] ` <87boan3prc.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
@ 2013-03-13 22:23 ` Eric W. Biederman
2013-03-13 22:23 ` [PATCH 02/14] xfs: Separate the in core and the logged inode Eric W. Biederman
` (10 more replies)
2013-03-14 6:18 ` [PATCH 00/14] xfs: Support for interacting with multiple user namespaces Dave Chinner
1 sibling, 11 replies; 16+ messages in thread
From: Eric W. Biederman @ 2013-03-13 22:23 UTC (permalink / raw)
To: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA
Cc: Alex Elder, Linux Containers, Dave Chinner,
xfs-VZNHf3L845pBDgjK7y7TUQ, Ben Myers, Eric W. Biederman
From: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
- When reading from disk convert on disk uids and gids to kuids and kgids
- When writing to the disk convert in memory kuids and kgids to uids and gids.
- Don't write e_id as that field only exists when user namespace
support is disabled.
- Use uid_eq when testing to see if current_fsuid() is allowed to set the
acls for a file.
Cc: Ben Myers <bpm-sJ/iWh9BUns@public.gmane.org>
Cc: Alex Elder <elder-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: Dave Chinner <david-FqsqvQoI3Ljby3iVrkZq2A@public.gmane.org>
Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
fs/xfs/xfs_acl.c | 23 +++++++++++++++++++----
1 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
index 1d32f1d..ca2aade 100644
--- a/fs/xfs/xfs_acl.c
+++ b/fs/xfs/xfs_acl.c
@@ -64,14 +64,17 @@ xfs_acl_from_disk(struct xfs_acl *aclp)
switch (acl_e->e_tag) {
case ACL_USER:
+ acl_e->e_uid = make_kuid(&init_user_ns,
+ be32_to_cpu(ace->ae_id));
+ break;
case ACL_GROUP:
- acl_e->e_id = be32_to_cpu(ace->ae_id);
+ acl_e->e_gid = make_kgid(&init_user_ns,
+ be32_to_cpu(ace->ae_id));
break;
case ACL_USER_OBJ:
case ACL_GROUP_OBJ:
case ACL_MASK:
case ACL_OTHER:
- acl_e->e_id = ACL_UNDEFINED_ID;
break;
default:
goto fail;
@@ -97,8 +100,20 @@ xfs_acl_to_disk(struct xfs_acl *aclp, const struct posix_acl *acl)
acl_e = &acl->a_entries[i];
ace->ae_tag = cpu_to_be32(acl_e->e_tag);
- ace->ae_id = cpu_to_be32(acl_e->e_id);
ace->ae_perm = cpu_to_be16(acl_e->e_perm);
+ switch(acl_e->e_tag) {
+ case ACL_USER:
+ ace->ae_id = cpu_to_be32(
+ from_kuid(&init_user_ns, acl_e->e_uid));
+ break;
+ case ACL_GROUP:
+ ace->ae_id = cpu_to_be32(
+ from_kgid(&init_user_ns, acl_e->e_gid));
+ break;
+ default:
+ ace->ae_id = cpu_to_be32(ACL_UNDEFINED_ID);
+ break;
+ }
}
}
@@ -355,7 +370,7 @@ xfs_xattr_acl_set(struct dentry *dentry, const char *name,
return -EINVAL;
if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode))
return value ? -EACCES : 0;
- if ((current_fsuid() != inode->i_uid) && !capable(CAP_FOWNER))
+ if ((!uid_eq(current_fsuid(), inode->i_uid)) && !capable(CAP_FOWNER))
return -EPERM;
if (!value)
--
1.7.5.4
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 02/14] xfs: Separate the in core and the logged inode.
2013-03-13 22:23 ` [PATCH 01/14] xfs: Convert uids and gids in xfs acls to/from kuids and kgids Eric W. Biederman
@ 2013-03-13 22:23 ` Eric W. Biederman
2013-03-13 22:23 ` [PATCH 03/14] xfs: Store projectid as a single variable Eric W. Biederman
` (9 subsequent siblings)
10 siblings, 0 replies; 16+ messages in thread
From: Eric W. Biederman @ 2013-03-13 22:23 UTC (permalink / raw)
To: linux-fsdevel
Cc: Linux Containers, Serge E. Hallyn, xfs, Ben Myers, Alex Elder,
Dave Chinner, Eric W. Biederman
From: "Eric W. Biederman" <ebiederm@xmission.com>
Add xfs_inode_from_disk xfs_inode_to_disk and xfs_inode_to_log to
handle changes.
Add an extra copy of struct xfs_icdinode into struct
xfs_inode_log_item ultimately it will be the only copy but for the
moment it is a temporary copy.
In struct xfs_inode change the type of i_d to an anonymous structure
with all of the same members as struct xfs_icdinode.
Modify the two places that create a pointer to ip->i_d as
a shortcut to get shorter names to use ip->i_d directly.
Cc: Ben Myers <bpm@sgi.com>
Cc: Alex Elder <elder@kernel.org>
Cc: Dave Chinner <david@fromorbit.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
fs/xfs/xfs_icache.c | 2 +-
fs/xfs/xfs_inode.c | 138 ++++++++++++++++++++++++++++++++++-------------
fs/xfs/xfs_inode.h | 31 ++++++++++-
fs/xfs/xfs_inode_item.c | 3 +-
fs/xfs/xfs_inode_item.h | 1 +
fs/xfs/xfs_itable.c | 45 +++++++--------
6 files changed, 155 insertions(+), 65 deletions(-)
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index 96e344e..1213f07 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -82,7 +82,7 @@ xfs_inode_alloc(
memset(&ip->i_df, 0, sizeof(xfs_ifork_t));
ip->i_flags = 0;
ip->i_delayed_blks = 0;
- memset(&ip->i_d, 0, sizeof(xfs_icdinode_t));
+ memset(&ip->i_d, 0, sizeof(ip->i_d));
return ip;
}
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 4f20165..469b9b3 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -832,40 +832,104 @@ xfs_iformat_btree(
return 0;
}
-STATIC void
-xfs_dinode_from_disk(
- xfs_icdinode_t *to,
- xfs_dinode_t *from)
-{
- to->di_magic = be16_to_cpu(from->di_magic);
- to->di_mode = be16_to_cpu(from->di_mode);
- to->di_version = from ->di_version;
- to->di_format = from->di_format;
- to->di_onlink = be16_to_cpu(from->di_onlink);
- to->di_uid = be32_to_cpu(from->di_uid);
- to->di_gid = be32_to_cpu(from->di_gid);
- to->di_nlink = be32_to_cpu(from->di_nlink);
- to->di_projid_lo = be16_to_cpu(from->di_projid_lo);
- to->di_projid_hi = be16_to_cpu(from->di_projid_hi);
- memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad));
- to->di_flushiter = be16_to_cpu(from->di_flushiter);
- to->di_atime.t_sec = be32_to_cpu(from->di_atime.t_sec);
- to->di_atime.t_nsec = be32_to_cpu(from->di_atime.t_nsec);
- to->di_mtime.t_sec = be32_to_cpu(from->di_mtime.t_sec);
- to->di_mtime.t_nsec = be32_to_cpu(from->di_mtime.t_nsec);
- to->di_ctime.t_sec = be32_to_cpu(from->di_ctime.t_sec);
- to->di_ctime.t_nsec = be32_to_cpu(from->di_ctime.t_nsec);
- to->di_size = be64_to_cpu(from->di_size);
- to->di_nblocks = be64_to_cpu(from->di_nblocks);
- to->di_extsize = be32_to_cpu(from->di_extsize);
- to->di_nextents = be32_to_cpu(from->di_nextents);
- to->di_anextents = be16_to_cpu(from->di_anextents);
- to->di_forkoff = from->di_forkoff;
- to->di_aformat = from->di_aformat;
- to->di_dmevmask = be32_to_cpu(from->di_dmevmask);
- to->di_dmstate = be16_to_cpu(from->di_dmstate);
- to->di_flags = be16_to_cpu(from->di_flags);
- to->di_gen = be32_to_cpu(from->di_gen);
+static void xfs_inode_from_disk(struct xfs_inode *to, struct xfs_dinode *from)
+{
+ to->i_d.di_magic = be16_to_cpu(from->di_magic);
+ to->i_d.di_mode = be16_to_cpu(from->di_mode);
+ to->i_d.di_version = from ->di_version;
+ to->i_d.di_format = from->di_format;
+ to->i_d.di_onlink = be16_to_cpu(from->di_onlink);
+ to->i_d.di_uid = be32_to_cpu(from->di_uid);
+ to->i_d.di_gid = be32_to_cpu(from->di_gid);
+ to->i_d.di_nlink = be32_to_cpu(from->di_nlink);
+ to->i_d.di_projid_lo = be16_to_cpu(from->di_projid_lo);
+ to->i_d.di_projid_hi = be16_to_cpu(from->di_projid_hi);
+ memcpy(to->i_d.di_pad, from->di_pad, sizeof(to->i_d.di_pad));
+ to->i_d.di_flushiter = be16_to_cpu(from->di_flushiter);
+ to->i_d.di_atime.t_sec = be32_to_cpu(from->di_atime.t_sec);
+ to->i_d.di_atime.t_nsec = be32_to_cpu(from->di_atime.t_nsec);
+ to->i_d.di_mtime.t_sec = be32_to_cpu(from->di_mtime.t_sec);
+ to->i_d.di_mtime.t_nsec = be32_to_cpu(from->di_mtime.t_nsec);
+ to->i_d.di_ctime.t_sec = be32_to_cpu(from->di_ctime.t_sec);
+ to->i_d.di_ctime.t_nsec = be32_to_cpu(from->di_ctime.t_nsec);
+ to->i_d.di_size = be64_to_cpu(from->di_size);
+ to->i_d.di_nblocks = be64_to_cpu(from->di_nblocks);
+ to->i_d.di_extsize = be32_to_cpu(from->di_extsize);
+ to->i_d.di_nextents = be32_to_cpu(from->di_nextents);
+ to->i_d.di_anextents = be16_to_cpu(from->di_anextents);
+ to->i_d.di_forkoff = from->di_forkoff;
+ to->i_d.di_aformat = from->di_aformat;
+ to->i_d.di_dmevmask = be32_to_cpu(from->di_dmevmask);
+ to->i_d.di_dmstate = be16_to_cpu(from->di_dmstate);
+ to->i_d.di_flags = be16_to_cpu(from->di_flags);
+ to->i_d.di_gen = be32_to_cpu(from->di_gen);
+}
+
+static void xfs_inode_to_disk(struct xfs_dinode *to, struct xfs_inode *from)
+{
+ to->di_magic = cpu_to_be16(from->i_d.di_magic);
+ to->di_mode = cpu_to_be16(from->i_d.di_mode);
+ to->di_version = from->i_d.di_version;
+ to->di_format = from->i_d.di_format;
+ to->di_onlink = cpu_to_be16(from->i_d.di_onlink);
+ to->di_uid = cpu_to_be32(from->i_d.di_uid);
+ to->di_gid = cpu_to_be32(from->i_d.di_gid);
+ to->di_nlink = cpu_to_be32(from->i_d.di_nlink);
+ to->di_projid_lo = cpu_to_be16(from->i_d.di_projid_lo);
+ to->di_projid_hi = cpu_to_be16(from->i_d.di_projid_hi);
+ memcpy(to->di_pad, from->i_d.di_pad, sizeof(to->di_pad));
+ to->di_flushiter = cpu_to_be16(from->i_d.di_flushiter);
+ to->di_atime.t_sec = cpu_to_be32(from->i_d.di_atime.t_sec);
+ to->di_atime.t_nsec = cpu_to_be32(from->i_d.di_atime.t_nsec);
+ to->di_mtime.t_sec = cpu_to_be32(from->i_d.di_mtime.t_sec);
+ to->di_mtime.t_nsec = cpu_to_be32(from->i_d.di_mtime.t_nsec);
+ to->di_ctime.t_sec = cpu_to_be32(from->i_d.di_ctime.t_sec);
+ to->di_ctime.t_nsec = cpu_to_be32(from->i_d.di_ctime.t_nsec);
+ to->di_size = cpu_to_be64(from->i_d.di_size);
+ to->di_nblocks = cpu_to_be64(from->i_d.di_nblocks);
+ to->di_extsize = cpu_to_be32(from->i_d.di_extsize);
+ to->di_nextents = cpu_to_be32(from->i_d.di_nextents);
+ to->di_anextents = cpu_to_be16(from->i_d.di_anextents);
+ to->di_forkoff = from->i_d.di_forkoff;
+ to->di_aformat = from->i_d.di_aformat;
+ to->di_dmevmask = cpu_to_be32(from->i_d.di_dmevmask);
+ to->di_dmstate = cpu_to_be16(from->i_d.di_dmstate);
+ to->di_flags = cpu_to_be16(from->i_d.di_flags);
+ to->di_gen = cpu_to_be32(from->i_d.di_gen);
+}
+
+void xfs_inode_to_log(struct xfs_icdinode *to, struct xfs_inode *from)
+{
+ /* xfs_inode_to_disk without the endian changes */
+ to->di_magic = from->i_d.di_magic;
+ to->di_mode = from->i_d.di_mode;
+ to->di_version = from->i_d.di_version;
+ to->di_format = from->i_d.di_format;
+ to->di_onlink = from->i_d.di_onlink;
+ to->di_uid = from->i_d.di_uid;
+ to->di_gid = from->i_d.di_gid;
+ to->di_nlink = from->i_d.di_nlink;
+ to->di_projid_lo = from->i_d.di_projid_lo;
+ to->di_projid_hi = from->i_d.di_projid_hi;
+ memcpy(to->di_pad, from->i_d.di_pad, sizeof(to->di_pad));
+ to->di_flushiter = from->i_d.di_flushiter;
+ to->di_atime.t_sec = from->i_d.di_atime.t_sec;
+ to->di_atime.t_nsec = from->i_d.di_atime.t_nsec;
+ to->di_mtime.t_sec = from->i_d.di_mtime.t_sec;
+ to->di_mtime.t_nsec = from->i_d.di_mtime.t_nsec;
+ to->di_ctime.t_sec = from->i_d.di_ctime.t_sec;
+ to->di_ctime.t_nsec = from->i_d.di_ctime.t_nsec;
+ to->di_size = from->i_d.di_size;
+ to->di_nblocks = from->i_d.di_nblocks;
+ to->di_extsize = from->i_d.di_extsize;
+ to->di_nextents = from->i_d.di_nextents;
+ to->di_anextents = from->i_d.di_anextents;
+ to->di_forkoff = from->i_d.di_forkoff;
+ to->di_aformat = from->i_d.di_aformat;
+ to->di_dmevmask = from->i_d.di_dmevmask;
+ to->di_dmstate = from->i_d.di_dmstate;
+ to->di_flags = from->i_d.di_flags;
+ to->di_gen = from->i_d.di_gen;
}
void
@@ -948,9 +1012,7 @@ uint
xfs_ip2xflags(
xfs_inode_t *ip)
{
- xfs_icdinode_t *dic = &ip->i_d;
-
- return _xfs_dic2xflags(dic->di_flags) |
+ return _xfs_dic2xflags(ip->i_d.di_flags) |
(XFS_IFORK_Q(ip) ? XFS_XFLAG_HASATTR : 0);
}
@@ -1012,7 +1074,7 @@ xfs_iread(
* Otherwise, just get the truly permanent information.
*/
if (dip->di_mode) {
- xfs_dinode_from_disk(&ip->i_d, dip);
+ xfs_inode_from_disk(ip, dip);
error = xfs_iformat(ip, dip);
if (error) {
#ifdef DEBUG
@@ -2800,7 +2862,7 @@ xfs_iflush_int(
* because if the inode is dirty at all the core must
* be.
*/
- xfs_dinode_to_disk(dip, &ip->i_d);
+ xfs_inode_to_disk(dip, ip);
/* Wrap, we never let the log put out DI_MAX_FLUSH */
if (ip->i_d.di_flushiter == DI_MAX_FLUSH)
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 237e7f6..977f1d8 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -243,7 +243,34 @@ typedef struct xfs_inode {
unsigned long i_flags; /* see defined flags below */
unsigned int i_delayed_blks; /* count of delay alloc blks */
- xfs_icdinode_t i_d; /* most of ondisk inode */
+ struct {
+ u16 di_magic; /* inode magic # = XFS_DINODE_MAGIC */
+ u16 di_mode; /* mode and type of file */
+ s8 di_version; /* inode version */
+ s8 di_format; /* format of di_c data */
+ u16 di_onlink; /* old number of links to file */
+ u32 di_uid; /* owner's user id */
+ u32 di_gid; /* owner's group id */
+ u32 di_nlink; /* number of links to file */
+ u16 di_projid_lo; /* lower part of owner's project id */
+ u16 di_projid_hi; /* higher part of owner's project id */
+ u8 di_pad[6]; /* unused, zeroed space */
+ u16 di_flushiter; /* incremented on flush */
+ xfs_ictimestamp_t di_atime; /* time last accessed */
+ xfs_ictimestamp_t di_mtime; /* time last modified */
+ xfs_ictimestamp_t di_ctime; /* time created/inode modified */
+ xfs_fsize_t di_size; /* number of bytes in file */
+ xfs_drfsbno_t di_nblocks; /* # of direct & btree blocks used */
+ xfs_extlen_t di_extsize; /* basic/minimum extent size for file */
+ xfs_extnum_t di_nextents; /* number of extents in data fork */
+ xfs_aextnum_t di_anextents; /* number of extents in attribute fork*/
+ u8 di_forkoff; /* attr fork offs, <<3 for 64b align */
+ s8 di_aformat; /* format of attr fork's data */
+ u32 di_dmevmask; /* DMIG event mask */
+ u16 di_dmstate; /* DMIG state info */
+ u16 di_flags; /* random flags, XFS_DIFLAG_... */
+ u32 di_gen; /* generation number */
+ } i_d; /* most of ondisk inode */
/* VFS inode */
struct inode i_vnode; /* embedded VFS inode */
@@ -550,6 +577,8 @@ do { \
#define XFS_IGET_UNTRUSTED 0x2
#define XFS_IGET_DONTCACHE 0x4
+void xfs_inode_to_log(struct xfs_icdinode *to, struct xfs_inode *from);
+
int xfs_imap_to_bp(struct xfs_mount *, struct xfs_trans *,
struct xfs_imap *, struct xfs_dinode **,
struct xfs_buf **, uint, uint);
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index f034bd1..6be81b6 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -178,7 +178,7 @@ xfs_inode_item_format(
vecp++;
nvecs = 1;
- vecp->i_addr = &ip->i_d;
+ vecp->i_addr = &iip->ili_d;
vecp->i_len = sizeof(struct xfs_icdinode);
vecp->i_type = XLOG_REG_TYPE_ICORE;
vecp++;
@@ -212,6 +212,7 @@ xfs_inode_item_format(
memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
}
}
+ xfs_inode_to_log(&iip->ili_d, ip);
switch (ip->i_d.di_format) {
case XFS_DINODE_FMT_EXTENTS:
diff --git a/fs/xfs/xfs_inode_item.h b/fs/xfs/xfs_inode_item.h
index 779812f..9e66a39 100644
--- a/fs/xfs/xfs_inode_item.h
+++ b/fs/xfs/xfs_inode_item.h
@@ -138,6 +138,7 @@ struct xfs_mount;
typedef struct xfs_inode_log_item {
xfs_log_item_t ili_item; /* common portion */
struct xfs_inode *ili_inode; /* inode ptr */
+ struct xfs_icdinode ili_d; /* most of ondisk inode */
xfs_lsn_t ili_flush_lsn; /* lsn at last flush */
xfs_lsn_t ili_last_lsn; /* lsn at last transaction */
unsigned short ili_lock_flags; /* lock flags */
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index 2ea7d40..dfb7f71 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -60,7 +60,6 @@ xfs_bulkstat_one_int(
int *ubused, /* bytes used by me */
int *stat) /* BULKSTAT_RV_... */
{
- struct xfs_icdinode *dic; /* dinode core info pointer */
struct xfs_inode *ip; /* incore inode pointer */
struct xfs_bstat *buf; /* return buffer */
int error = 0; /* error value */
@@ -85,36 +84,34 @@ xfs_bulkstat_one_int(
ASSERT(ip != NULL);
ASSERT(ip->i_imap.im_blkno != 0);
- dic = &ip->i_d;
-
/* xfs_iget returns the following without needing
* further change.
*/
- buf->bs_nlink = dic->di_nlink;
- buf->bs_projid_lo = dic->di_projid_lo;
- buf->bs_projid_hi = dic->di_projid_hi;
+ buf->bs_nlink = ip->i_d.di_nlink;
+ buf->bs_projid_lo = ip->i_d.di_projid_lo;
+ buf->bs_projid_hi = ip->i_d.di_projid_hi;
buf->bs_ino = ino;
- buf->bs_mode = dic->di_mode;
- buf->bs_uid = dic->di_uid;
- buf->bs_gid = dic->di_gid;
- buf->bs_size = dic->di_size;
- buf->bs_atime.tv_sec = dic->di_atime.t_sec;
- buf->bs_atime.tv_nsec = dic->di_atime.t_nsec;
- buf->bs_mtime.tv_sec = dic->di_mtime.t_sec;
- buf->bs_mtime.tv_nsec = dic->di_mtime.t_nsec;
- buf->bs_ctime.tv_sec = dic->di_ctime.t_sec;
- buf->bs_ctime.tv_nsec = dic->di_ctime.t_nsec;
+ buf->bs_mode = ip->i_d.di_mode;
+ buf->bs_uid = ip->i_d.di_uid;
+ buf->bs_gid = ip->i_d.di_gid;
+ buf->bs_size = ip->i_d.di_size;
+ buf->bs_atime.tv_sec = ip->i_d.di_atime.t_sec;
+ buf->bs_atime.tv_nsec = ip->i_d.di_atime.t_nsec;
+ buf->bs_mtime.tv_sec = ip->i_d.di_mtime.t_sec;
+ buf->bs_mtime.tv_nsec = ip->i_d.di_mtime.t_nsec;
+ buf->bs_ctime.tv_sec = ip->i_d.di_ctime.t_sec;
+ buf->bs_ctime.tv_nsec = ip->i_d.di_ctime.t_nsec;
buf->bs_xflags = xfs_ip2xflags(ip);
- buf->bs_extsize = dic->di_extsize << mp->m_sb.sb_blocklog;
- buf->bs_extents = dic->di_nextents;
- buf->bs_gen = dic->di_gen;
+ buf->bs_extsize = ip->i_d.di_extsize << mp->m_sb.sb_blocklog;
+ buf->bs_extents = ip->i_d.di_nextents;
+ buf->bs_gen = ip->i_d.di_gen;
memset(buf->bs_pad, 0, sizeof(buf->bs_pad));
- buf->bs_dmevmask = dic->di_dmevmask;
- buf->bs_dmstate = dic->di_dmstate;
- buf->bs_aextents = dic->di_anextents;
+ buf->bs_dmevmask = ip->i_d.di_dmevmask;
+ buf->bs_dmstate = ip->i_d.di_dmstate;
+ buf->bs_aextents = ip->i_d.di_anextents;
buf->bs_forkoff = XFS_IFORK_BOFF(ip);
- switch (dic->di_format) {
+ switch (ip->i_d.di_format) {
case XFS_DINODE_FMT_DEV:
buf->bs_rdev = ip->i_df.if_u2.if_rdev;
buf->bs_blksize = BLKDEV_IOSIZE;
@@ -130,7 +127,7 @@ xfs_bulkstat_one_int(
case XFS_DINODE_FMT_BTREE:
buf->bs_rdev = 0;
buf->bs_blksize = mp->m_sb.sb_blocksize;
- buf->bs_blocks = dic->di_nblocks + ip->i_delayed_blks;
+ buf->bs_blocks = ip->i_d.di_nblocks + ip->i_delayed_blks;
break;
}
xfs_iunlock(ip, XFS_ILOCK_SHARED);
--
1.7.5.4
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 03/14] xfs: Store projectid as a single variable.
2013-03-13 22:23 ` [PATCH 01/14] xfs: Convert uids and gids in xfs acls to/from kuids and kgids Eric W. Biederman
2013-03-13 22:23 ` [PATCH 02/14] xfs: Separate the in core and the logged inode Eric W. Biederman
@ 2013-03-13 22:23 ` Eric W. Biederman
2013-03-13 22:23 ` [PATCH 04/14] xfs: Update inode uids, gids, and projids to be kuids, kgids, and kprojids Eric W. Biederman
` (8 subsequent siblings)
10 siblings, 0 replies; 16+ messages in thread
From: Eric W. Biederman @ 2013-03-13 22:23 UTC (permalink / raw)
To: linux-fsdevel
Cc: Alex Elder, Linux Containers, xfs, Ben Myers, Eric W. Biederman,
Serge E. Hallyn
From: "Eric W. Biederman" <ebiederm@xmission.com>
xfs_get_projid is torturous to read and when you don't have the
justification of maintaining an on-disk ABI there is really no point.
So merge di_projid_lo and di_projid_hi in xfs_inode into di_projid.
That is cheaper to read and cheaper to write and can handle future
needs. Update all callers of xfs_get_projid and xfs_set_projid to use
i_d.di_projid instead.
Cc: Ben Myers <bpm@sgi.com>
Cc: Alex Elder <elder@kernel.org>
Cc: Dave Chinner <david@fromorbit.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
fs/xfs/xfs_icache.c | 2 +-
fs/xfs/xfs_inode.c | 18 +++++++++---------
fs/xfs/xfs_inode.h | 22 +---------------------
fs/xfs/xfs_ioctl.c | 8 ++++----
fs/xfs/xfs_iops.c | 2 +-
fs/xfs/xfs_itable.c | 4 ++--
fs/xfs/xfs_qm.c | 10 +++++-----
fs/xfs/xfs_qm_bhv.c | 2 +-
fs/xfs/xfs_rename.c | 2 +-
fs/xfs/xfs_vnodeops.c | 6 +++---
10 files changed, 28 insertions(+), 48 deletions(-)
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index 1213f07..1f62227 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -1210,7 +1210,7 @@ xfs_inode_match_id(
return 0;
if (eofb->eof_flags & XFS_EOF_FLAGS_PRID &&
- xfs_get_projid(ip) != eofb->eof_prid)
+ ip->i_d.di_projid != eofb->eof_prid)
return 0;
return 1;
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 469b9b3..f6c9652 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -842,8 +842,8 @@ static void xfs_inode_from_disk(struct xfs_inode *to, struct xfs_dinode *from)
to->i_d.di_uid = be32_to_cpu(from->di_uid);
to->i_d.di_gid = be32_to_cpu(from->di_gid);
to->i_d.di_nlink = be32_to_cpu(from->di_nlink);
- to->i_d.di_projid_lo = be16_to_cpu(from->di_projid_lo);
- to->i_d.di_projid_hi = be16_to_cpu(from->di_projid_hi);
+ to->i_d.di_projid = (((u32)be16_to_cpu(from->di_projid_hi)) << 16) |
+ be16_to_cpu(from->di_projid_lo);
memcpy(to->i_d.di_pad, from->di_pad, sizeof(to->i_d.di_pad));
to->i_d.di_flushiter = be16_to_cpu(from->di_flushiter);
to->i_d.di_atime.t_sec = be32_to_cpu(from->di_atime.t_sec);
@@ -875,8 +875,8 @@ static void xfs_inode_to_disk(struct xfs_dinode *to, struct xfs_inode *from)
to->di_uid = cpu_to_be32(from->i_d.di_uid);
to->di_gid = cpu_to_be32(from->i_d.di_gid);
to->di_nlink = cpu_to_be32(from->i_d.di_nlink);
- to->di_projid_lo = cpu_to_be16(from->i_d.di_projid_lo);
- to->di_projid_hi = cpu_to_be16(from->i_d.di_projid_hi);
+ to->di_projid_lo = cpu_to_be16(from->i_d.di_projid & 0xffff);
+ to->di_projid_hi = cpu_to_be16(from->i_d.di_projid >> 16);
memcpy(to->di_pad, from->i_d.di_pad, sizeof(to->di_pad));
to->di_flushiter = cpu_to_be16(from->i_d.di_flushiter);
to->di_atime.t_sec = cpu_to_be32(from->i_d.di_atime.t_sec);
@@ -909,8 +909,8 @@ void xfs_inode_to_log(struct xfs_icdinode *to, struct xfs_inode *from)
to->di_uid = from->i_d.di_uid;
to->di_gid = from->i_d.di_gid;
to->di_nlink = from->i_d.di_nlink;
- to->di_projid_lo = from->i_d.di_projid_lo;
- to->di_projid_hi = from->i_d.di_projid_hi;
+ to->di_projid_lo = from->i_d.di_projid & 0xffff;
+ to->di_projid_hi = from->i_d.di_projid >> 16;
memcpy(to->di_pad, from->i_d.di_pad, sizeof(to->di_pad));
to->di_flushiter = from->i_d.di_flushiter;
to->di_atime.t_sec = from->i_d.di_atime.t_sec;
@@ -1112,7 +1112,7 @@ xfs_iread(
if (ip->i_d.di_version == 1) {
ip->i_d.di_nlink = ip->i_d.di_onlink;
ip->i_d.di_onlink = 0;
- xfs_set_projid(ip, 0);
+ ip->i_d.di_projid = 0;
}
ip->i_delayed_blks = 0;
@@ -1261,7 +1261,7 @@ xfs_ialloc(
ASSERT(ip->i_d.di_nlink == nlink);
ip->i_d.di_uid = current_fsuid();
ip->i_d.di_gid = current_fsgid();
- xfs_set_projid(ip, prid);
+ ip->i_d.di_projid = prid;
memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
/*
@@ -2895,7 +2895,7 @@ xfs_iflush_int(
memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
memset(&(dip->di_pad[0]), 0,
sizeof(dip->di_pad));
- ASSERT(xfs_get_projid(ip) == 0);
+ ASSERT(ip->i_d.di_projid == 0);
}
}
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 977f1d8..a722f7a 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -252,8 +252,7 @@ typedef struct xfs_inode {
u32 di_uid; /* owner's user id */
u32 di_gid; /* owner's group id */
u32 di_nlink; /* number of links to file */
- u16 di_projid_lo; /* lower part of owner's project id */
- u16 di_projid_hi; /* higher part of owner's project id */
+ projid_t di_projid; /* owner's project id */
u8 di_pad[6]; /* unused, zeroed space */
u16 di_flushiter; /* incremented on flush */
xfs_ictimestamp_t di_atime; /* time last accessed */
@@ -382,25 +381,6 @@ xfs_iflags_test_and_set(xfs_inode_t *ip, unsigned short flags)
}
/*
- * Project quota id helpers (previously projid was 16bit only
- * and using two 16bit values to hold new 32bit projid was chosen
- * to retain compatibility with "old" filesystems).
- */
-static inline prid_t
-xfs_get_projid(struct xfs_inode *ip)
-{
- return (prid_t)ip->i_d.di_projid_hi << 16 | ip->i_d.di_projid_lo;
-}
-
-static inline void
-xfs_set_projid(struct xfs_inode *ip,
- prid_t projid)
-{
- ip->i_d.di_projid_hi = (__uint16_t) (projid >> 16);
- ip->i_d.di_projid_lo = (__uint16_t) (projid & 0xffff);
-}
-
-/*
* In-core inode flags.
*/
#define XFS_IRECLAIM (1 << 0) /* started reclaiming this inode */
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index d681e34..79e9b13 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -815,7 +815,7 @@ xfs_ioc_fsgetxattr(
xfs_ilock(ip, XFS_ILOCK_SHARED);
fa.fsx_xflags = xfs_ip2xflags(ip);
fa.fsx_extsize = ip->i_d.di_extsize << ip->i_mount->m_sb.sb_blocklog;
- fa.fsx_projid = xfs_get_projid(ip);
+ fa.fsx_projid = ip->i_d.di_projid;
if (attr) {
if (ip->i_afp) {
@@ -986,7 +986,7 @@ xfs_ioctl_setattr(
if (mask & FSX_PROJID) {
if (XFS_IS_QUOTA_RUNNING(mp) &&
XFS_IS_PQUOTA_ON(mp) &&
- xfs_get_projid(ip) != fa->fsx_projid) {
+ ip->i_d.di_projid != fa->fsx_projid) {
ASSERT(tp);
code = xfs_qm_vop_chown_reserve(tp, ip, udqp, gdqp,
capable(CAP_FOWNER) ?
@@ -1104,12 +1104,12 @@ xfs_ioctl_setattr(
* Change the ownerships and register quota modifications
* in the transaction.
*/
- if (xfs_get_projid(ip) != fa->fsx_projid) {
+ if (ip->i_d.di_projid != fa->fsx_projid) {
if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_PQUOTA_ON(mp)) {
olddquot = xfs_qm_vop_chown(tp, ip,
&ip->i_gdquot, gdqp);
}
- xfs_set_projid(ip, fa->fsx_projid);
+ ip->i_d.di_projid = fa->fsx_projid;
/*
* We may have to rev the inode as well as
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index d82efaa..a69ddfd 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -516,7 +516,7 @@ xfs_setattr_nonsize(
*/
ASSERT(udqp == NULL);
ASSERT(gdqp == NULL);
- error = xfs_qm_vop_dqalloc(ip, uid, gid, xfs_get_projid(ip),
+ error = xfs_qm_vop_dqalloc(ip, uid, gid, ip->i_d.di_projid,
qflags, &udqp, &gdqp);
if (error)
return error;
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index dfb7f71..3529f2e 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -88,8 +88,8 @@ xfs_bulkstat_one_int(
* further change.
*/
buf->bs_nlink = ip->i_d.di_nlink;
- buf->bs_projid_lo = ip->i_d.di_projid_lo;
- buf->bs_projid_hi = ip->i_d.di_projid_hi;
+ buf->bs_projid_lo = (u16)(ip->i_d.di_projid & 0xffff);
+ buf->bs_projid_hi = (u16)(ip->i_d.di_projid >> 16);
buf->bs_ino = ino;
buf->bs_mode = ip->i_d.di_mode;
buf->bs_uid = ip->i_d.di_uid;
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index e5b5cf9..c0904fc 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -530,7 +530,7 @@ xfs_qm_dqattach_locked(
xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP,
flags & XFS_QMOPT_DQALLOC,
ip->i_udquot, &ip->i_gdquot) :
- xfs_qm_dqattach_one(ip, xfs_get_projid(ip), XFS_DQ_PROJ,
+ xfs_qm_dqattach_one(ip, ip->i_d.di_projid, XFS_DQ_PROJ,
flags & XFS_QMOPT_DQALLOC,
ip->i_udquot, &ip->i_gdquot);
/*
@@ -1172,7 +1172,7 @@ xfs_qm_dqusage_adjust(
}
if (XFS_IS_PQUOTA_ON(mp)) {
- error = xfs_qm_quotacheck_dqadjust(ip, xfs_get_projid(ip),
+ error = xfs_qm_quotacheck_dqadjust(ip, ip->i_d.di_projid,
XFS_DQ_PROJ, nblks, rtblks);
if (error)
goto error0;
@@ -1704,7 +1704,7 @@ xfs_qm_vop_dqalloc(
gq = xfs_qm_dqhold(ip->i_gdquot);
}
} else if ((flags & XFS_QMOPT_PQUOTA) && XFS_IS_PQUOTA_ON(mp)) {
- if (xfs_get_projid(ip) != prid) {
+ if (ip->i_d.di_projid != prid) {
xfs_iunlock(ip, lockflags);
if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)prid,
XFS_DQ_PROJ,
@@ -1819,7 +1819,7 @@ xfs_qm_vop_chown_reserve(
}
if (XFS_IS_OQUOTA_ON(ip->i_mount) && gdqp) {
if (XFS_IS_PQUOTA_ON(ip->i_mount) &&
- xfs_get_projid(ip) != be32_to_cpu(gdqp->q_core.d_id))
+ ip->i_d.di_projid != be32_to_cpu(gdqp->q_core.d_id))
prjflags = XFS_QMOPT_ENOSPC;
if (prjflags ||
@@ -1917,7 +1917,7 @@ xfs_qm_vop_create_dqattach(
ASSERT(ip->i_gdquot == NULL);
ASSERT(XFS_IS_OQUOTA_ON(mp));
ASSERT((XFS_IS_GQUOTA_ON(mp) ?
- ip->i_d.di_gid : xfs_get_projid(ip)) ==
+ ip->i_d.di_gid : ip->i_d.di_projid) ==
be32_to_cpu(gdqp->q_core.d_id));
ip->i_gdquot = xfs_qm_dqhold(gdqp);
diff --git a/fs/xfs/xfs_qm_bhv.c b/fs/xfs/xfs_qm_bhv.c
index 2d02eac..7d44746 100644
--- a/fs/xfs/xfs_qm_bhv.c
+++ b/fs/xfs/xfs_qm_bhv.c
@@ -79,7 +79,7 @@ xfs_qm_statvfs(
xfs_mount_t *mp = ip->i_mount;
xfs_dquot_t *dqp;
- if (!xfs_qm_dqget(mp, NULL, xfs_get_projid(ip), XFS_DQ_PROJ, 0, &dqp)) {
+ if (!xfs_qm_dqget(mp, NULL, ip->i_d.di_projid, XFS_DQ_PROJ, 0, &dqp)) {
xfs_fill_statvfs_from_dquot(statp, dqp);
xfs_qm_dqput(dqp);
}
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c
index 30ff5f4..4e87258 100644
--- a/fs/xfs/xfs_rename.c
+++ b/fs/xfs/xfs_rename.c
@@ -171,7 +171,7 @@ xfs_rename(
* tree quota mechanism would be circumvented.
*/
if (unlikely((target_dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) &&
- (xfs_get_projid(target_dp) != xfs_get_projid(src_ip)))) {
+ (target_dp->i_d.di_projid != src_ip->i_d.di_projid))) {
error = XFS_ERROR(EXDEV);
goto error_return;
}
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 77ad748..1a9ee2c 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -741,7 +741,7 @@ xfs_create(
return XFS_ERROR(EIO);
if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
- prid = xfs_get_projid(dp);
+ prid = dp->i_d.di_projid;
else
prid = XFS_PROJID_DEFAULT;
@@ -1305,7 +1305,7 @@ xfs_link(
* the tree quota mechanism could be circumvented.
*/
if (unlikely((tdp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) &&
- (xfs_get_projid(tdp) != xfs_get_projid(sip)))) {
+ (tdp->i_d.di_projid != sip->i_d.di_projid))) {
error = XFS_ERROR(EXDEV);
goto error_return;
}
@@ -1402,7 +1402,7 @@ xfs_symlink(
udqp = gdqp = NULL;
if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
- prid = xfs_get_projid(dp);
+ prid = dp->i_d.di_projid;
else
prid = XFS_PROJID_DEFAULT;
--
1.7.5.4
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 04/14] xfs: Update inode uids, gids, and projids to be kuids, kgids, and kprojids
2013-03-13 22:23 ` [PATCH 01/14] xfs: Convert uids and gids in xfs acls to/from kuids and kgids Eric W. Biederman
2013-03-13 22:23 ` [PATCH 02/14] xfs: Separate the in core and the logged inode Eric W. Biederman
2013-03-13 22:23 ` [PATCH 03/14] xfs: Store projectid as a single variable Eric W. Biederman
@ 2013-03-13 22:23 ` Eric W. Biederman
2013-03-13 22:23 ` [PATCH 05/14] xfs: Update xfs_ioctl_setattr to handle projids in any user namespace Eric W. Biederman
` (7 subsequent siblings)
10 siblings, 0 replies; 16+ messages in thread
From: Eric W. Biederman @ 2013-03-13 22:23 UTC (permalink / raw)
To: linux-fsdevel
Cc: Linux Containers, Serge E. Hallyn, xfs, Ben Myers, Alex Elder,
Dave Chinner, Eric W. Biederman
From: "Eric W. Biederman" <ebiederm@xmission.com>
Update i_projid on struct xfs_inode to be of type kprojid_t.
Update the logic in xfs_inode_from_disk when the values are read from
disk to convert their on-disk values into the internal kernel
representation.
Update xfs_inode_to_disk and xfs_inode_to_log to convert from the
internal kernel representation to the on-disk values when updating the
on-disk fields.
Update comparisons against these fields to use uid_eq, gid_eq
and projid_eq.
Cc: Ben Myers <bpm@sgi.com>
Cc: Alex Elder <elder@kernel.org>
Cc: Dave Chinner <david@fromorbit.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
fs/xfs/xfs_icache.c | 6 +++---
fs/xfs/xfs_inode.c | 37 +++++++++++++++++++++++--------------
fs/xfs/xfs_inode.h | 6 +++---
fs/xfs/xfs_ioctl.c | 8 ++++----
fs/xfs/xfs_itable.c | 10 ++++++----
fs/xfs/xfs_qm.c | 20 ++++++++++----------
fs/xfs/xfs_rename.c | 2 +-
fs/xfs/xfs_vnodeops.c | 2 +-
8 files changed, 51 insertions(+), 40 deletions(-)
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index 1f62227..03a4427 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -1202,15 +1202,15 @@ xfs_inode_match_id(
struct xfs_eofblocks *eofb)
{
if (eofb->eof_flags & XFS_EOF_FLAGS_UID &&
- ip->i_d.di_uid != eofb->eof_uid)
+ !uid_eq(ip->i_d.di_uid, eofb->eof_uid))
return 0;
if (eofb->eof_flags & XFS_EOF_FLAGS_GID &&
- ip->i_d.di_gid != eofb->eof_gid)
+ !gid_eq(ip->i_d.di_gid, eofb->eof_gid))
return 0;
if (eofb->eof_flags & XFS_EOF_FLAGS_PRID &&
- ip->i_d.di_projid != eofb->eof_prid)
+ !projid_eq(ip->i_d.di_projid, eofb->eof_prid))
return 0;
return 1;
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index f6c9652..8d77e49 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -834,16 +834,18 @@ xfs_iformat_btree(
static void xfs_inode_from_disk(struct xfs_inode *to, struct xfs_dinode *from)
{
+ projid_t projid;
to->i_d.di_magic = be16_to_cpu(from->di_magic);
to->i_d.di_mode = be16_to_cpu(from->di_mode);
to->i_d.di_version = from ->di_version;
to->i_d.di_format = from->di_format;
to->i_d.di_onlink = be16_to_cpu(from->di_onlink);
- to->i_d.di_uid = be32_to_cpu(from->di_uid);
- to->i_d.di_gid = be32_to_cpu(from->di_gid);
+ to->i_d.di_uid = make_kuid(&init_user_ns, be32_to_cpu(from->di_uid));
+ to->i_d.di_gid = make_kgid(&init_user_ns, be32_to_cpu(from->di_gid));
to->i_d.di_nlink = be32_to_cpu(from->di_nlink);
- to->i_d.di_projid = (((u32)be16_to_cpu(from->di_projid_hi)) << 16) |
+ projid = (((u32)be16_to_cpu(from->di_projid_hi)) << 16) |
be16_to_cpu(from->di_projid_lo);
+ to->i_d.di_projid = make_kprojid(&init_user_ns, projid);
memcpy(to->i_d.di_pad, from->di_pad, sizeof(to->i_d.di_pad));
to->i_d.di_flushiter = be16_to_cpu(from->di_flushiter);
to->i_d.di_atime.t_sec = be32_to_cpu(from->di_atime.t_sec);
@@ -867,16 +869,19 @@ static void xfs_inode_from_disk(struct xfs_inode *to, struct xfs_dinode *from)
static void xfs_inode_to_disk(struct xfs_dinode *to, struct xfs_inode *from)
{
+ uid_t uid = from_kuid(&init_user_ns, from->i_d.di_uid);
+ gid_t gid = from_kgid(&init_user_ns, from->i_d.di_gid);
+ projid_t projid = from_kprojid(&init_user_ns, from->i_d.di_projid);
to->di_magic = cpu_to_be16(from->i_d.di_magic);
to->di_mode = cpu_to_be16(from->i_d.di_mode);
to->di_version = from->i_d.di_version;
to->di_format = from->i_d.di_format;
to->di_onlink = cpu_to_be16(from->i_d.di_onlink);
- to->di_uid = cpu_to_be32(from->i_d.di_uid);
- to->di_gid = cpu_to_be32(from->i_d.di_gid);
+ to->di_uid = cpu_to_be32(uid);
+ to->di_gid = cpu_to_be32(gid);
to->di_nlink = cpu_to_be32(from->i_d.di_nlink);
- to->di_projid_lo = cpu_to_be16(from->i_d.di_projid & 0xffff);
- to->di_projid_hi = cpu_to_be16(from->i_d.di_projid >> 16);
+ to->di_projid_lo = cpu_to_be16(projid & 0xffff);
+ to->di_projid_hi = cpu_to_be16(projid >> 16);
memcpy(to->di_pad, from->i_d.di_pad, sizeof(to->di_pad));
to->di_flushiter = cpu_to_be16(from->i_d.di_flushiter);
to->di_atime.t_sec = cpu_to_be32(from->i_d.di_atime.t_sec);
@@ -901,16 +906,19 @@ static void xfs_inode_to_disk(struct xfs_dinode *to, struct xfs_inode *from)
void xfs_inode_to_log(struct xfs_icdinode *to, struct xfs_inode *from)
{
/* xfs_inode_to_disk without the endian changes */
+ uid_t uid = from_kuid(&init_user_ns, from->i_d.di_uid);
+ gid_t gid = from_kgid(&init_user_ns, from->i_d.di_gid);
+ projid_t projid = from_kprojid(&init_user_ns, from->i_d.di_projid);
to->di_magic = from->i_d.di_magic;
to->di_mode = from->i_d.di_mode;
to->di_version = from->i_d.di_version;
to->di_format = from->i_d.di_format;
to->di_onlink = from->i_d.di_onlink;
- to->di_uid = from->i_d.di_uid;
- to->di_gid = from->i_d.di_gid;
+ to->di_uid = uid;
+ to->di_gid = gid;
to->di_nlink = from->i_d.di_nlink;
- to->di_projid_lo = from->i_d.di_projid & 0xffff;
- to->di_projid_hi = from->i_d.di_projid >> 16;
+ to->di_projid_lo = projid & 0xffff;
+ to->di_projid_hi = projid >> 16;
memcpy(to->di_pad, from->i_d.di_pad, sizeof(to->di_pad));
to->di_flushiter = from->i_d.di_flushiter;
to->di_atime.t_sec = from->i_d.di_atime.t_sec;
@@ -1112,7 +1120,7 @@ xfs_iread(
if (ip->i_d.di_version == 1) {
ip->i_d.di_nlink = ip->i_d.di_onlink;
ip->i_d.di_onlink = 0;
- ip->i_d.di_projid = 0;
+ ip->i_d.di_projid = make_kprojid(&init_user_ns, 0);
}
ip->i_delayed_blks = 0;
@@ -1299,7 +1307,7 @@ xfs_ialloc(
*/
if ((irix_sgid_inherit) &&
(ip->i_d.di_mode & S_ISGID) &&
- (!in_group_p((gid_t)ip->i_d.di_gid))) {
+ (!in_group_p(ip->i_d.di_gid))) {
ip->i_d.di_mode &= ~S_ISGID;
}
@@ -2895,7 +2903,8 @@ xfs_iflush_int(
memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
memset(&(dip->di_pad[0]), 0,
sizeof(dip->di_pad));
- ASSERT(ip->i_d.di_projid == 0);
+ ASSERT(projid_eq(ip->i_d.di_projid,
+ make_kprojid(&init_user_ns, 0)));
}
}
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index a722f7a..095bcbb 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -249,10 +249,10 @@ typedef struct xfs_inode {
s8 di_version; /* inode version */
s8 di_format; /* format of di_c data */
u16 di_onlink; /* old number of links to file */
- u32 di_uid; /* owner's user id */
- u32 di_gid; /* owner's group id */
+ kuid_t di_uid; /* owner's user id */
+ kgid_t di_gid; /* owner's group id */
u32 di_nlink; /* number of links to file */
- projid_t di_projid; /* owner's project id */
+ kprojid_t di_projid; /* owner's project id */
u8 di_pad[6]; /* unused, zeroed space */
u16 di_flushiter; /* incremented on flush */
xfs_ictimestamp_t di_atime; /* time last accessed */
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 79e9b13..1dd72d9 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -815,7 +815,7 @@ xfs_ioc_fsgetxattr(
xfs_ilock(ip, XFS_ILOCK_SHARED);
fa.fsx_xflags = xfs_ip2xflags(ip);
fa.fsx_extsize = ip->i_d.di_extsize << ip->i_mount->m_sb.sb_blocklog;
- fa.fsx_projid = ip->i_d.di_projid;
+ fa.fsx_projid = from_kprojid_munged(current_user_ns(), ip->i_d.di_projid);
if (attr) {
if (ip->i_afp) {
@@ -975,7 +975,7 @@ xfs_ioctl_setattr(
* to the file owner ID, except in cases where the
* CAP_FSETID capability is applicable.
*/
- if (current_fsuid() != ip->i_d.di_uid && !capable(CAP_FOWNER)) {
+ if (!uid_eq(current_fsuid(), ip->i_d.di_uid) && !capable(CAP_FOWNER)) {
code = XFS_ERROR(EPERM);
goto error_return;
}
@@ -986,7 +986,7 @@ xfs_ioctl_setattr(
if (mask & FSX_PROJID) {
if (XFS_IS_QUOTA_RUNNING(mp) &&
XFS_IS_PQUOTA_ON(mp) &&
- ip->i_d.di_projid != fa->fsx_projid) {
+ !projid_eq(ip->i_d.di_projid, fa->fsx_projid)) {
ASSERT(tp);
code = xfs_qm_vop_chown_reserve(tp, ip, udqp, gdqp,
capable(CAP_FOWNER) ?
@@ -1104,7 +1104,7 @@ xfs_ioctl_setattr(
* Change the ownerships and register quota modifications
* in the transaction.
*/
- if (ip->i_d.di_projid != fa->fsx_projid) {
+ if (!projid_eq(ip->i_d.di_projid, fa->fsx_projid)) {
if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_PQUOTA_ON(mp)) {
olddquot = xfs_qm_vop_chown(tp, ip,
&ip->i_gdquot, gdqp);
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index 3529f2e..6e57195 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -63,6 +63,7 @@ xfs_bulkstat_one_int(
struct xfs_inode *ip; /* incore inode pointer */
struct xfs_bstat *buf; /* return buffer */
int error = 0; /* error value */
+ projid_t projid;
*stat = BULKSTAT_RV_NOTHING;
@@ -88,12 +89,13 @@ xfs_bulkstat_one_int(
* further change.
*/
buf->bs_nlink = ip->i_d.di_nlink;
- buf->bs_projid_lo = (u16)(ip->i_d.di_projid & 0xffff);
- buf->bs_projid_hi = (u16)(ip->i_d.di_projid >> 16);
+ projid = from_kprojid_munged(current_user_ns(), ip->i_d.di_projid);
+ buf->bs_projid_lo = projid & 0xffff;
+ buf->bs_projid_hi = projid >> 16;
buf->bs_ino = ino;
buf->bs_mode = ip->i_d.di_mode;
- buf->bs_uid = ip->i_d.di_uid;
- buf->bs_gid = ip->i_d.di_gid;
+ buf->bs_uid = from_kuid_munged(current_user_ns(), ip->i_d.di_uid);
+ buf->bs_gid = from_kgid_munged(current_user_ns(), ip->i_d.di_gid);
buf->bs_size = ip->i_d.di_size;
buf->bs_atime.tv_sec = ip->i_d.di_atime.t_sec;
buf->bs_atime.tv_nsec = ip->i_d.di_atime.t_nsec;
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index c0904fc..3324dd3 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -1649,7 +1649,7 @@ xfs_qm_vop_dqalloc(
uq = gq = NULL;
if ((flags & XFS_QMOPT_UQUOTA) && XFS_IS_UQUOTA_ON(mp)) {
- if (ip->i_d.di_uid != uid) {
+ if (!uid_eq(ip->i_d.di_uid, uid)) {
/*
* What we need is the dquot that has this uid, and
* if we send the inode to dqget, the uid of the inode
@@ -1684,7 +1684,7 @@ xfs_qm_vop_dqalloc(
}
}
if ((flags & XFS_QMOPT_GQUOTA) && XFS_IS_GQUOTA_ON(mp)) {
- if (ip->i_d.di_gid != gid) {
+ if (!gid_eq(ip->i_d.di_gid, gid)) {
xfs_iunlock(ip, lockflags);
if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)gid,
XFS_DQ_GROUP,
@@ -1704,7 +1704,7 @@ xfs_qm_vop_dqalloc(
gq = xfs_qm_dqhold(ip->i_gdquot);
}
} else if ((flags & XFS_QMOPT_PQUOTA) && XFS_IS_PQUOTA_ON(mp)) {
- if (ip->i_d.di_projid != prid) {
+ if (!projid_eq(ip->i_d.di_projid, prid)) {
xfs_iunlock(ip, lockflags);
if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)prid,
XFS_DQ_PROJ,
@@ -1805,7 +1805,7 @@ xfs_qm_vop_chown_reserve(
XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS;
if (XFS_IS_UQUOTA_ON(mp) && udqp &&
- ip->i_d.di_uid != (uid_t)be32_to_cpu(udqp->q_core.d_id)) {
+ !uid_eq(ip->i_d.di_uid, (uid_t)be32_to_cpu(udqp->q_core.d_id))) {
delblksudq = udqp;
/*
* If there are delayed allocation blocks, then we have to
@@ -1819,12 +1819,12 @@ xfs_qm_vop_chown_reserve(
}
if (XFS_IS_OQUOTA_ON(ip->i_mount) && gdqp) {
if (XFS_IS_PQUOTA_ON(ip->i_mount) &&
- ip->i_d.di_projid != be32_to_cpu(gdqp->q_core.d_id))
+ !projid_eq(ip->i_d.di_projid, be32_to_cpu(gdqp->q_core.d_id)))
prjflags = XFS_QMOPT_ENOSPC;
if (prjflags ||
(XFS_IS_GQUOTA_ON(ip->i_mount) &&
- ip->i_d.di_gid != be32_to_cpu(gdqp->q_core.d_id))) {
+ !gid_eq(ip->i_d.di_gid, be32_to_cpu(gdqp->q_core.d_id)))) {
delblksgdq = gdqp;
if (delblks) {
ASSERT(ip->i_gdquot);
@@ -1908,7 +1908,7 @@ xfs_qm_vop_create_dqattach(
if (udqp) {
ASSERT(ip->i_udquot == NULL);
ASSERT(XFS_IS_UQUOTA_ON(mp));
- ASSERT(ip->i_d.di_uid == be32_to_cpu(udqp->q_core.d_id));
+ ASSERT(uid_eq(ip->i_d.di_uid, be32_to_cpu(udqp->q_core.d_id)));
ip->i_udquot = xfs_qm_dqhold(udqp);
xfs_trans_mod_dquot(tp, udqp, XFS_TRANS_DQ_ICOUNT, 1);
@@ -1916,9 +1916,9 @@ xfs_qm_vop_create_dqattach(
if (gdqp) {
ASSERT(ip->i_gdquot == NULL);
ASSERT(XFS_IS_OQUOTA_ON(mp));
- ASSERT((XFS_IS_GQUOTA_ON(mp) ?
- ip->i_d.di_gid : ip->i_d.di_projid) ==
- be32_to_cpu(gdqp->q_core.d_id));
+ ASSERT(XFS_IS_GQUOTA_ON(mp) ?
+ gid_eq(ip->i_d.di_gid, be32_to_cpu(gdqp->q_core.d_id)):
+ projid_eq(ip->i_d.di_projid, be32_to_cpu(gdqp->q_core.d_id)));
ip->i_gdquot = xfs_qm_dqhold(gdqp);
xfs_trans_mod_dquot(tp, gdqp, XFS_TRANS_DQ_ICOUNT, 1);
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c
index 4e87258..b919704 100644
--- a/fs/xfs/xfs_rename.c
+++ b/fs/xfs/xfs_rename.c
@@ -171,7 +171,7 @@ xfs_rename(
* tree quota mechanism would be circumvented.
*/
if (unlikely((target_dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) &&
- (target_dp->i_d.di_projid != src_ip->i_d.di_projid))) {
+ !projid_eq(target_dp->i_d.di_projid, src_ip->i_d.di_projid))) {
error = XFS_ERROR(EXDEV);
goto error_return;
}
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 1a9ee2c..dab0ab3 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -1305,7 +1305,7 @@ xfs_link(
* the tree quota mechanism could be circumvented.
*/
if (unlikely((tdp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) &&
- (tdp->i_d.di_projid != sip->i_d.di_projid))) {
+ !projid_eq(tdp->i_d.di_projid, sip->i_d.di_projid))) {
error = XFS_ERROR(EXDEV);
goto error_return;
}
--
1.7.5.4
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 05/14] xfs: Update xfs_ioctl_setattr to handle projids in any user namespace
2013-03-13 22:23 ` [PATCH 01/14] xfs: Convert uids and gids in xfs acls to/from kuids and kgids Eric W. Biederman
` (2 preceding siblings ...)
2013-03-13 22:23 ` [PATCH 04/14] xfs: Update inode uids, gids, and projids to be kuids, kgids, and kprojids Eric W. Biederman
@ 2013-03-13 22:23 ` Eric W. Biederman
2013-03-13 22:23 ` [PATCH 07/14] xfs: Update ioctl(XFS_IOC_FREE_EOFBLOCKS) to handle callers in any userspace Eric W. Biederman
` (6 subsequent siblings)
10 siblings, 0 replies; 16+ messages in thread
From: Eric W. Biederman @ 2013-03-13 22:23 UTC (permalink / raw)
To: linux-fsdevel
Cc: Linux Containers, Serge E. Hallyn, xfs, Ben Myers, Alex Elder,
Dave Chinner, Eric W. Biederman
From: "Eric W. Biederman" <ebiederm@xmission.com>
- Convert the userspace value in fa->fsx_projid into a kprojid and
store it in the variable projid.
- Verify that xfs can store the projid after it is converted into
xfs's user namespace.
- Replace uses of fa->fsx_projid with projid throughout
xfs_ioctl_setattr.
Cc: Ben Myers <bpm@sgi.com>
Cc: Alex Elder <elder@kernel.org>
Cc: Dave Chinner <david@fromorbit.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
fs/xfs/xfs_ioctl.c | 26 ++++++++++++++++++--------
1 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 1dd72d9..9aeecfb 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -925,6 +925,7 @@ xfs_ioctl_setattr(
struct xfs_dquot *gdqp = NULL;
struct xfs_dquot *olddquot = NULL;
int code;
+ kprojid_t projid = INVALID_PROJID;
trace_xfs_ioctl_setattr(ip);
@@ -934,11 +935,20 @@ xfs_ioctl_setattr(
return XFS_ERROR(EIO);
/*
- * Disallow 32bit project ids when projid32bit feature is not enabled.
+ * Verify the specifid project id is valid.
*/
- if ((mask & FSX_PROJID) && (fa->fsx_projid > (__uint16_t)-1) &&
- !xfs_sb_version_hasprojid32bit(&ip->i_mount->m_sb))
- return XFS_ERROR(EINVAL);
+ if (mask & FSX_PROJID) {
+ projid = make_kprojid(current_user_ns(), fa->fsx_projid);
+ if (!projid_valid(projid))
+ return XFS_ERROR(EINVAL);
+
+ /*
+ * Disallow 32bit project ids when projid32bit feature is not enabled.
+ */
+ if ((from_kprojid(&init_user_ns, projid) > (__uint16_t)-1) &&
+ !xfs_sb_version_hasprojid32bit(&ip->i_mount->m_sb))
+ return XFS_ERROR(EINVAL);
+ }
/*
* If disk quotas is on, we make sure that the dquots do exist on disk,
@@ -950,7 +960,7 @@ xfs_ioctl_setattr(
*/
if (XFS_IS_QUOTA_ON(mp) && (mask & FSX_PROJID)) {
code = xfs_qm_vop_dqalloc(ip, ip->i_d.di_uid,
- ip->i_d.di_gid, fa->fsx_projid,
+ ip->i_d.di_gid, projid,
XFS_QMOPT_PQUOTA, &udqp, &gdqp);
if (code)
return code;
@@ -986,7 +996,7 @@ xfs_ioctl_setattr(
if (mask & FSX_PROJID) {
if (XFS_IS_QUOTA_RUNNING(mp) &&
XFS_IS_PQUOTA_ON(mp) &&
- !projid_eq(ip->i_d.di_projid, fa->fsx_projid)) {
+ !projid_eq(ip->i_d.di_projid, projid)) {
ASSERT(tp);
code = xfs_qm_vop_chown_reserve(tp, ip, udqp, gdqp,
capable(CAP_FOWNER) ?
@@ -1104,12 +1114,12 @@ xfs_ioctl_setattr(
* Change the ownerships and register quota modifications
* in the transaction.
*/
- if (!projid_eq(ip->i_d.di_projid, fa->fsx_projid)) {
+ if (!projid_eq(ip->i_d.di_projid, projid)) {
if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_PQUOTA_ON(mp)) {
olddquot = xfs_qm_vop_chown(tp, ip,
&ip->i_gdquot, gdqp);
}
- ip->i_d.di_projid = fa->fsx_projid;
+ ip->i_d.di_projid = projid;
/*
* We may have to rev the inode as well as
--
1.7.5.4
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 06/14] xfs: Use kuids and kgids in xfs_setattr_nonsize
[not found] ` <1363213395-10988-1-git-send-email-ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
@ 2013-03-13 22:23 ` Eric W. Biederman
2013-03-13 22:23 ` [PATCH 11/14] xfs: Modify xfs_qm_dqget to take a struct kqid Eric W. Biederman
2013-03-13 22:23 ` [PATCH 14/14] xfs: Enable building with user namespaces enabled Eric W. Biederman
2 siblings, 0 replies; 16+ messages in thread
From: Eric W. Biederman @ 2013-03-13 22:23 UTC (permalink / raw)
To: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA
Cc: Alex Elder, Linux Containers, Dave Chinner,
xfs-VZNHf3L845pBDgjK7y7TUQ, Ben Myers, Eric W. Biederman
From: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
Cc: Ben Myers <bpm-sJ/iWh9BUns@public.gmane.org>
Cc: Alex Elder <elder-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: Dave Chinner <david-FqsqvQoI3Ljby3iVrkZq2A@public.gmane.org>
Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
fs/xfs/xfs_iops.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index a69ddfd..e9dcf48 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -466,8 +466,8 @@ xfs_setattr_nonsize(
int mask = iattr->ia_valid;
xfs_trans_t *tp;
int error;
- uid_t uid = 0, iuid = 0;
- gid_t gid = 0, igid = 0;
+ kuid_t uid = GLOBAL_ROOT_UID, iuid = GLOBAL_ROOT_UID;
+ kgid_t gid = GLOBAL_ROOT_GID, igid = GLOBAL_ROOT_GID;
struct xfs_dquot *udqp = NULL, *gdqp = NULL;
struct xfs_dquot *olddquot1 = NULL, *olddquot2 = NULL;
@@ -549,8 +549,8 @@ xfs_setattr_nonsize(
* going to change.
*/
if (XFS_IS_QUOTA_RUNNING(mp) &&
- ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) ||
- (XFS_IS_GQUOTA_ON(mp) && igid != gid))) {
+ ((XFS_IS_UQUOTA_ON(mp) && !uid_eq(iuid, uid)) ||
+ (XFS_IS_GQUOTA_ON(mp) && !gid_eq(igid, gid)))) {
ASSERT(tp);
error = xfs_qm_vop_chown_reserve(tp, ip, udqp, gdqp,
capable(CAP_FOWNER) ?
@@ -580,7 +580,7 @@ xfs_setattr_nonsize(
* Change the ownerships and register quota modifications
* in the transaction.
*/
- if (iuid != uid) {
+ if (!uid_eq(iuid, uid)) {
if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_UQUOTA_ON(mp)) {
ASSERT(mask & ATTR_UID);
ASSERT(udqp);
@@ -590,7 +590,7 @@ xfs_setattr_nonsize(
ip->i_d.di_uid = uid;
inode->i_uid = uid;
}
- if (igid != gid) {
+ if (!gid_eq(igid, gid)) {
if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_GQUOTA_ON(mp)) {
ASSERT(!XFS_IS_PQUOTA_ON(mp));
ASSERT(mask & ATTR_GID);
--
1.7.5.4
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 07/14] xfs: Update ioctl(XFS_IOC_FREE_EOFBLOCKS) to handle callers in any userspace
2013-03-13 22:23 ` [PATCH 01/14] xfs: Convert uids and gids in xfs acls to/from kuids and kgids Eric W. Biederman
` (3 preceding siblings ...)
2013-03-13 22:23 ` [PATCH 05/14] xfs: Update xfs_ioctl_setattr to handle projids in any user namespace Eric W. Biederman
@ 2013-03-13 22:23 ` Eric W. Biederman
2013-03-13 22:23 ` [PATCH 08/14] xfs: Use kprojids when allocating inodes Eric W. Biederman
` (5 subsequent siblings)
10 siblings, 0 replies; 16+ messages in thread
From: Eric W. Biederman @ 2013-03-13 22:23 UTC (permalink / raw)
To: linux-fsdevel
Cc: Linux Containers, Serge E. Hallyn, xfs, Ben Myers, Alex Elder,
Dave Chinner, Eric W. Biederman
From: "Eric W. Biederman" <ebiederm@xmission.com>
- Modify the ioctl to convert from uids, gid, and projids in the
current user namespace to kuids, kgids, and kprojids, and to report
an error if the conversion fails.
- Create struct xfs_internal_eofblocks to hold the same information as
struct xfs_eofblocks but with uids, gids, and projids stored as
kuids, kgids, and kprojids preventing confusion.
- Pass struct xfs_interanl_eofblocks into xfs_icache_free_eofblocks
and it's helpers ensuring there will not be confusing about which
user namespace identifiers that need to be compared are in.
Cc: Ben Myers <bpm@sgi.com>
Cc: Alex Elder <elder@kernel.org>
Cc: Dave Chinner <david@fromorbit.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
fs/xfs/xfs_icache.c | 8 ++++----
fs/xfs/xfs_icache.h | 11 ++++++++++-
fs/xfs/xfs_ioctl.c | 22 +++++++++++++++++++++-
3 files changed, 35 insertions(+), 6 deletions(-)
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index 03a4427..032c28c 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -1199,7 +1199,7 @@ xfs_reclaim_inodes_count(
STATIC int
xfs_inode_match_id(
struct xfs_inode *ip,
- struct xfs_eofblocks *eofb)
+ struct xfs_internal_eofblocks *eofb)
{
if (eofb->eof_flags & XFS_EOF_FLAGS_UID &&
!uid_eq(ip->i_d.di_uid, eofb->eof_uid))
@@ -1210,7 +1210,7 @@ xfs_inode_match_id(
return 0;
if (eofb->eof_flags & XFS_EOF_FLAGS_PRID &&
- !projid_eq(ip->i_d.di_projid, eofb->eof_prid))
+ !projid_eq(ip->i_d.di_projid, eofb->eof_projid))
return 0;
return 1;
@@ -1224,7 +1224,7 @@ xfs_inode_free_eofblocks(
void *args)
{
int ret;
- struct xfs_eofblocks *eofb = args;
+ struct xfs_internal_eofblocks *eofb = args;
if (!xfs_can_free_eofblocks(ip, false)) {
/* inode could be preallocated or append-only */
@@ -1263,7 +1263,7 @@ xfs_inode_free_eofblocks(
int
xfs_icache_free_eofblocks(
struct xfs_mount *mp,
- struct xfs_eofblocks *eofb)
+ struct xfs_internal_eofblocks *eofb)
{
int flags = SYNC_TRYLOCK;
diff --git a/fs/xfs/xfs_icache.h b/fs/xfs/xfs_icache.h
index e0f138c..260dc27 100644
--- a/fs/xfs/xfs_icache.h
+++ b/fs/xfs/xfs_icache.h
@@ -35,9 +35,18 @@ void xfs_reclaim_inodes_nr(struct xfs_mount *mp, int nr_to_scan);
void xfs_inode_set_reclaim_tag(struct xfs_inode *ip);
+struct xfs_internal_eofblocks {
+ u32 eof_version;
+ u32 eof_flags;
+ kuid_t eof_uid;
+ kgid_t eof_gid;
+ kprojid_t eof_projid;
+ u64 eof_min_file_size;
+};
+
void xfs_inode_set_eofblocks_tag(struct xfs_inode *ip);
void xfs_inode_clear_eofblocks_tag(struct xfs_inode *ip);
-int xfs_icache_free_eofblocks(struct xfs_mount *, struct xfs_eofblocks *);
+int xfs_icache_free_eofblocks(struct xfs_mount *, struct xfs_internal_eofblocks *);
void xfs_eofblocks_worker(struct work_struct *);
int xfs_sync_inode_grab(struct xfs_inode *ip);
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 9aeecfb..8c933e5 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -1615,6 +1615,7 @@ xfs_file_ioctl(
case XFS_IOC_FREE_EOFBLOCKS: {
struct xfs_eofblocks eofb;
+ struct xfs_internal_eofblocks keofb;
if (copy_from_user(&eofb, arg, sizeof(eofb)))
return -XFS_ERROR(EFAULT);
@@ -1629,7 +1630,26 @@ xfs_file_ioctl(
memchr_inv(eofb.pad64, 0, sizeof(eofb.pad64)))
return -XFS_ERROR(EINVAL);
- error = xfs_icache_free_eofblocks(mp, &eofb);
+ keofb.eof_version = eofb.eof_version;
+ keofb.eof_flags = eofb.eof_flags;
+ if (eofb.eof_flags & XFS_EOF_FLAGS_UID) {
+ keofb.eof_uid = make_kuid(current_user_ns(), eofb.eof_uid);
+ if (!uid_valid(keofb.eof_uid))
+ return -XFS_ERROR(EINVAL);
+ }
+ if (eofb.eof_flags & XFS_EOF_FLAGS_GID) {
+ keofb.eof_gid = make_kgid(current_user_ns(), eofb.eof_gid);
+ if (!gid_valid(keofb.eof_gid))
+ return -XFS_ERROR(EINVAL);
+ }
+ if (eofb.eof_flags & XFS_EOF_FLAGS_PRID) {
+ keofb.eof_projid = make_kprojid(current_user_ns(), eofb.eof_prid);
+ if (!projid_valid(keofb.eof_projid))
+ return -XFS_ERROR(EINVAL);
+ }
+ keofb.eof_min_file_size = eofb.eof_min_file_size;
+
+ error = xfs_icache_free_eofblocks(mp, &keofb);
return -error;
}
--
1.7.5.4
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 08/14] xfs: Use kprojids when allocating inodes.
2013-03-13 22:23 ` [PATCH 01/14] xfs: Convert uids and gids in xfs acls to/from kuids and kgids Eric W. Biederman
` (4 preceding siblings ...)
2013-03-13 22:23 ` [PATCH 07/14] xfs: Update ioctl(XFS_IOC_FREE_EOFBLOCKS) to handle callers in any userspace Eric W. Biederman
@ 2013-03-13 22:23 ` Eric W. Biederman
2013-03-13 22:23 ` [PATCH 09/14] xfs: Modify xfs_qm_vop_dqalloc to take kuids, kgids, and kprojids Eric W. Biederman
` (4 subsequent siblings)
10 siblings, 0 replies; 16+ messages in thread
From: Eric W. Biederman @ 2013-03-13 22:23 UTC (permalink / raw)
To: linux-fsdevel
Cc: Linux Containers, Serge E. Hallyn, xfs, Ben Myers, Alex Elder,
Dave Chinner, Eric W. Biederman
From: "Eric W. Biederman" <ebiederm@xmission.com>
In xfs_create and xfs_symlink compute the desired kprojid and pass it
down into xfs_ialloc.
Cc: Ben Myers <bpm@sgi.com>
Cc: Alex Elder <elder@kernel.org>
Cc: Dave Chinner <david@fromorbit.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
fs/xfs/xfs_inode.c | 5 +++--
fs/xfs/xfs_inode.h | 2 +-
fs/xfs/xfs_qm.c | 4 +++-
fs/xfs/xfs_utils.c | 2 +-
fs/xfs/xfs_utils.h | 2 +-
fs/xfs/xfs_vnodeops.c | 8 ++++----
6 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 8d77e49..bed6947 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -1226,7 +1226,7 @@ xfs_ialloc(
umode_t mode,
xfs_nlink_t nlink,
xfs_dev_t rdev,
- prid_t prid,
+ kprojid_t prid,
int okalloc,
xfs_buf_t **ialloc_context,
xfs_inode_t **ipp)
@@ -1290,7 +1290,8 @@ xfs_ialloc(
/*
* Project ids won't be stored on disk if we are using a version 1 inode.
*/
- if ((prid != 0) && (ip->i_d.di_version == 1))
+ if (!projid_eq(prid, make_kprojid(&init_user_ns, 0)) &&
+ (ip->i_d.di_version == 1))
xfs_bump_ino_vers2(tp, ip);
if (pip && XFS_INHERIT_GID(pip)) {
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 095bcbb..efe279e 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -516,7 +516,7 @@ int xfs_isilocked(xfs_inode_t *, uint);
uint xfs_ilock_map_shared(xfs_inode_t *);
void xfs_iunlock_map_shared(xfs_inode_t *, uint);
int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, umode_t,
- xfs_nlink_t, xfs_dev_t, prid_t, int,
+ xfs_nlink_t, xfs_dev_t, kprojid_t, int,
struct xfs_buf **, xfs_inode_t **);
uint xfs_ip2xflags(struct xfs_inode *);
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index 3324dd3..861e4e8 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -777,7 +777,9 @@ xfs_qm_qino_alloc(
return error;
}
- error = xfs_dir_ialloc(&tp, NULL, S_IFREG, 1, 0, 0, 1, ip, &committed);
+ error = xfs_dir_ialloc(&tp, NULL, S_IFREG, 1, 0,
+ make_kprojid(&init_user_ns, 0),
+ 1, ip, &committed);
if (error) {
xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES |
XFS_TRANS_ABORT);
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c
index 0025c78..f0a9f1d 100644
--- a/fs/xfs/xfs_utils.c
+++ b/fs/xfs/xfs_utils.c
@@ -54,7 +54,7 @@ xfs_dir_ialloc(
umode_t mode,
xfs_nlink_t nlink,
xfs_dev_t rdev,
- prid_t prid, /* project id */
+ kprojid_t prid, /* project id */
int okalloc, /* ok to allocate new space */
xfs_inode_t **ipp, /* pointer to inode; it will be
locked. */
diff --git a/fs/xfs/xfs_utils.h b/fs/xfs/xfs_utils.h
index 5eeab46..7757f7c 100644
--- a/fs/xfs/xfs_utils.h
+++ b/fs/xfs/xfs_utils.h
@@ -19,7 +19,7 @@
#define __XFS_UTILS_H__
extern int xfs_dir_ialloc(xfs_trans_t **, xfs_inode_t *, umode_t, xfs_nlink_t,
- xfs_dev_t, prid_t, int, xfs_inode_t **, int *);
+ xfs_dev_t, kprojid_t, int, xfs_inode_t **, int *);
extern int xfs_droplink(xfs_trans_t *, xfs_inode_t *);
extern int xfs_bumplink(xfs_trans_t *, xfs_inode_t *);
extern void xfs_bump_ino_vers2(xfs_trans_t *, xfs_inode_t *);
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index dab0ab3..863b979 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -728,7 +728,7 @@ xfs_create(
bool unlock_dp_on_error = false;
uint cancel_flags;
int committed;
- prid_t prid;
+ kprojid_t prid;
struct xfs_dquot *udqp = NULL;
struct xfs_dquot *gdqp = NULL;
uint resblks;
@@ -743,7 +743,7 @@ xfs_create(
if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
prid = dp->i_d.di_projid;
else
- prid = XFS_PROJID_DEFAULT;
+ prid = make_kprojid(&init_user_ns, XFS_PROJID_DEFAULT);
/*
* Make sure that we have allocated dquot(s) on disk.
@@ -1379,7 +1379,7 @@ xfs_symlink(
int byte_cnt;
int n;
xfs_buf_t *bp;
- prid_t prid;
+ kprojid_t prid;
struct xfs_dquot *udqp, *gdqp;
uint resblks;
@@ -1404,7 +1404,7 @@ xfs_symlink(
if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
prid = dp->i_d.di_projid;
else
- prid = XFS_PROJID_DEFAULT;
+ prid = make_kprojid(&init_user_ns, XFS_PROJID_DEFAULT);
/*
* Make sure that we have allocated dquot(s) on disk.
--
1.7.5.4
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 09/14] xfs: Modify xfs_qm_vop_dqalloc to take kuids, kgids, and kprojids.
2013-03-13 22:23 ` [PATCH 01/14] xfs: Convert uids and gids in xfs acls to/from kuids and kgids Eric W. Biederman
` (5 preceding siblings ...)
2013-03-13 22:23 ` [PATCH 08/14] xfs: Use kprojids when allocating inodes Eric W. Biederman
@ 2013-03-13 22:23 ` Eric W. Biederman
2013-03-13 22:23 ` [PATCH 10/14] xfs: Push struct kqid into xfs_qm_scall_qmlim and xfs_qm_scall_getquota Eric W. Biederman
` (3 subsequent siblings)
10 siblings, 0 replies; 16+ messages in thread
From: Eric W. Biederman @ 2013-03-13 22:23 UTC (permalink / raw)
To: linux-fsdevel
Cc: Linux Containers, Serge E. Hallyn, xfs, Ben Myers, Alex Elder,
Dave Chinner, Eric W. Biederman
From: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Ben Myers <bpm@sgi.com>
Cc: Alex Elder <elder@kernel.org>
Cc: Dave Chinner <david@fromorbit.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
fs/xfs/xfs_qm.c | 6 +++---
fs/xfs/xfs_quota.h | 4 ++--
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index 861e4e8..308592e 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -1616,9 +1616,9 @@ xfs_qm_write_sb_changes(
int
xfs_qm_vop_dqalloc(
struct xfs_inode *ip,
- uid_t uid,
- gid_t gid,
- prid_t prid,
+ kuid_t uid,
+ kgid_t gid,
+ kprojid_t prid,
uint flags,
struct xfs_dquot **O_udqpp,
struct xfs_dquot **O_gdqpp)
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h
index b50ec5b..f48f801 100644
--- a/fs/xfs/xfs_quota.h
+++ b/fs/xfs/xfs_quota.h
@@ -311,7 +311,7 @@ extern int xfs_trans_reserve_quota_bydquots(struct xfs_trans *,
struct xfs_mount *, struct xfs_dquot *,
struct xfs_dquot *, long, long, uint);
-extern int xfs_qm_vop_dqalloc(struct xfs_inode *, uid_t, gid_t, prid_t, uint,
+extern int xfs_qm_vop_dqalloc(struct xfs_inode *, kuid_t, kgid_t, kprojid_t, uint,
struct xfs_dquot **, struct xfs_dquot **);
extern void xfs_qm_vop_create_dqattach(struct xfs_trans *, struct xfs_inode *,
struct xfs_dquot *, struct xfs_dquot *);
@@ -332,7 +332,7 @@ extern void xfs_qm_unmount_quotas(struct xfs_mount *);
#else
static inline int
-xfs_qm_vop_dqalloc(struct xfs_inode *ip, uid_t uid, gid_t gid, prid_t prid,
+xfs_qm_vop_dqalloc(struct xfs_inode *ip, kuid_t uid, kgid_t gid, kprojid_t prid,
uint flags, struct xfs_dquot **udqp, struct xfs_dquot **gdqp)
{
*udqp = NULL;
--
1.7.5.4
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 10/14] xfs: Push struct kqid into xfs_qm_scall_qmlim and xfs_qm_scall_getquota
2013-03-13 22:23 ` [PATCH 01/14] xfs: Convert uids and gids in xfs acls to/from kuids and kgids Eric W. Biederman
` (6 preceding siblings ...)
2013-03-13 22:23 ` [PATCH 09/14] xfs: Modify xfs_qm_vop_dqalloc to take kuids, kgids, and kprojids Eric W. Biederman
@ 2013-03-13 22:23 ` Eric W. Biederman
2013-03-13 22:23 ` [PATCH 12/14] xfs: Remember the kqid for a quota Eric W. Biederman
` (2 subsequent siblings)
10 siblings, 0 replies; 16+ messages in thread
From: Eric W. Biederman @ 2013-03-13 22:23 UTC (permalink / raw)
To: linux-fsdevel
Cc: Linux Containers, Serge E. Hallyn, xfs, Ben Myers, Alex Elder,
Dave Chinner, Eric W. Biederman
From: "Eric W. Biederman" <ebiederm@xmission.com>
- In xfs_qm_scall_getquota map the quota id into the callers
user namespace in the returned struct fs_disk_quota
- Add a helper is_superquota and use it in xfs_qm_scall_setqlimi
to see if we are setting the superusers quota limit. Setting
the superuses quota limit on xfs sets the default quota limits
for all users.
- Move xfs_quota_type into xfs_qm_syscalls.c where it is now used.
Cc: Ben Myers <bpm@sgi.com>
Cc: Alex Elder <elder@kernel.org>
Cc: Dave Chinner <david@fromorbit.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
fs/xfs/xfs_dquot.h | 6 ++++++
fs/xfs/xfs_qm.h | 4 ++--
fs/xfs/xfs_qm_syscalls.c | 40 +++++++++++++++++++++++++++++-----------
fs/xfs/xfs_quotaops.c | 20 ++------------------
4 files changed, 39 insertions(+), 31 deletions(-)
diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
index c694a84..2c197da 100644
--- a/fs/xfs/xfs_dquot.h
+++ b/fs/xfs/xfs_dquot.h
@@ -163,4 +163,10 @@ static inline struct xfs_dquot *xfs_qm_dqhold(struct xfs_dquot *dqp)
extern const struct xfs_buf_ops xfs_dquot_buf_ops;
+/* Is this root's quota in the specified user namespace? */
+static inline bool is_superquota(struct kqid id, struct user_namespace *ns)
+{
+ return qid_eq(id, make_kqid(ns, id.type, 0));
+}
+
#endif /* __XFS_DQUOT_H__ */
diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
index 44b858b..ce478dc 100644
--- a/fs/xfs/xfs_qm.h
+++ b/fs/xfs/xfs_qm.h
@@ -114,9 +114,9 @@ extern void xfs_qm_dqrele_all_inodes(xfs_mount_t *, uint);
/* quota ops */
extern int xfs_qm_scall_trunc_qfiles(xfs_mount_t *, uint);
-extern int xfs_qm_scall_getquota(xfs_mount_t *, xfs_dqid_t, uint,
+extern int xfs_qm_scall_getquota(xfs_mount_t *, struct kqid,
fs_disk_quota_t *);
-extern int xfs_qm_scall_setqlim(xfs_mount_t *, xfs_dqid_t, uint,
+extern int xfs_qm_scall_setqlim(xfs_mount_t *, struct kqid,
fs_disk_quota_t *);
extern int xfs_qm_scall_getqstat(xfs_mount_t *, fs_quota_stat_t *);
extern int xfs_qm_scall_quotaon(xfs_mount_t *, uint);
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index cf9a340..8ad5488 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -48,6 +48,19 @@ STATIC int xfs_qm_log_quotaoff_end(xfs_mount_t *, xfs_qoff_logitem_t *,
STATIC uint xfs_qm_export_flags(uint);
STATIC uint xfs_qm_export_qtype_flags(uint);
+STATIC int
+xfs_quota_type(int type)
+{
+ switch (type) {
+ case USRQUOTA:
+ return XFS_DQ_USER;
+ case GRPQUOTA:
+ return XFS_DQ_GROUP;
+ default:
+ return XFS_DQ_PROJ;
+ }
+}
+
/*
* Turn off quota accounting and/or enforcement for all udquots and/or
* gdquots. Called only at unmount time.
@@ -473,8 +486,7 @@ xfs_qm_scall_getqstat(
int
xfs_qm_scall_setqlim(
xfs_mount_t *mp,
- xfs_dqid_t id,
- uint type,
+ struct kqid id,
fs_disk_quota_t *newlim)
{
struct xfs_quotainfo *q = mp->m_quotainfo;
@@ -483,12 +495,16 @@ xfs_qm_scall_setqlim(
xfs_trans_t *tp;
int error;
xfs_qcnt_t hard, soft;
+ bool superquota;
if (newlim->d_fieldmask & ~XFS_DQ_MASK)
return EINVAL;
if ((newlim->d_fieldmask & XFS_DQ_MASK) == 0)
return 0;
+ /* Is this quota id for root? */
+ superquota = is_superquota(id, &init_user_ns);
+
tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SETQLIM);
error = xfs_trans_reserve(tp, 0, XFS_QM_SETQLIM_LOG_RES(mp),
0, 0, XFS_DEFAULT_LOG_COUNT);
@@ -509,7 +525,9 @@ xfs_qm_scall_setqlim(
* Get the dquot (locked), and join it to the transaction.
* Allocate the dquot if this doesn't exist.
*/
- if ((error = xfs_qm_dqget(mp, NULL, id, type, XFS_QMOPT_DQALLOC, &dqp))) {
+ if ((error = xfs_qm_dqget(mp, NULL, from_kqid(&init_user_ns, id),
+ xfs_quota_type(id.type),
+ XFS_QMOPT_DQALLOC, &dqp))) {
xfs_trans_cancel(tp, XFS_TRANS_ABORT);
ASSERT(error != ENOENT);
goto out_unlock;
@@ -529,7 +547,7 @@ xfs_qm_scall_setqlim(
if (hard == 0 || hard >= soft) {
ddq->d_blk_hardlimit = cpu_to_be64(hard);
ddq->d_blk_softlimit = cpu_to_be64(soft);
- if (id == 0) {
+ if (superquota) {
q->qi_bhardlimit = hard;
q->qi_bsoftlimit = soft;
}
@@ -545,7 +563,7 @@ xfs_qm_scall_setqlim(
if (hard == 0 || hard >= soft) {
ddq->d_rtb_hardlimit = cpu_to_be64(hard);
ddq->d_rtb_softlimit = cpu_to_be64(soft);
- if (id == 0) {
+ if (superquota) {
q->qi_rtbhardlimit = hard;
q->qi_rtbsoftlimit = soft;
}
@@ -562,7 +580,7 @@ xfs_qm_scall_setqlim(
if (hard == 0 || hard >= soft) {
ddq->d_ino_hardlimit = cpu_to_be64(hard);
ddq->d_ino_softlimit = cpu_to_be64(soft);
- if (id == 0) {
+ if (superquota) {
q->qi_ihardlimit = hard;
q->qi_isoftlimit = soft;
}
@@ -580,7 +598,7 @@ xfs_qm_scall_setqlim(
if (newlim->d_fieldmask & FS_DQ_RTBWARNS)
ddq->d_rtbwarns = cpu_to_be16(newlim->d_rtbwarns);
- if (id == 0) {
+ if (superquota) {
/*
* Timelimits for the super user set the relative time
* the other users can be over quota for this file system.
@@ -715,8 +733,7 @@ error0:
int
xfs_qm_scall_getquota(
struct xfs_mount *mp,
- xfs_dqid_t id,
- uint type,
+ struct kqid id,
struct fs_disk_quota *dst)
{
struct xfs_dquot *dqp;
@@ -727,7 +744,8 @@ xfs_qm_scall_getquota(
* we aren't passing the XFS_QMOPT_DOALLOC flag. If it doesn't
* exist, we'll get ENOENT back.
*/
- error = xfs_qm_dqget(mp, NULL, id, type, 0, &dqp);
+ error = xfs_qm_dqget(mp, NULL, from_kqid(&init_user_ns, id),
+ xfs_quota_type(id.type), 0, &dqp);
if (error)
return error;
@@ -743,7 +761,7 @@ xfs_qm_scall_getquota(
memset(dst, 0, sizeof(*dst));
dst->d_version = FS_DQUOT_VERSION;
dst->d_flags = xfs_qm_export_qtype_flags(dqp->q_core.d_flags);
- dst->d_id = be32_to_cpu(dqp->q_core.d_id);
+ dst->d_id = from_kqid_munged(current_user_ns(), id);
dst->d_blk_hardlimit =
XFS_FSB_TO_BB(mp, be64_to_cpu(dqp->q_core.d_blk_hardlimit));
dst->d_blk_softlimit =
diff --git a/fs/xfs/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c
index 71926d6..4d88faa 100644
--- a/fs/xfs/xfs_quotaops.c
+++ b/fs/xfs/xfs_quotaops.c
@@ -27,20 +27,6 @@
#include "xfs_qm.h"
#include <linux/quota.h>
-
-STATIC int
-xfs_quota_type(int type)
-{
- switch (type) {
- case USRQUOTA:
- return XFS_DQ_USER;
- case GRPQUOTA:
- return XFS_DQ_GROUP;
- default:
- return XFS_DQ_PROJ;
- }
-}
-
STATIC int
xfs_fs_get_xstate(
struct super_block *sb,
@@ -107,8 +93,7 @@ xfs_fs_get_dqblk(
if (!XFS_IS_QUOTA_ON(mp))
return -ESRCH;
- return -xfs_qm_scall_getquota(mp, from_kqid(&init_user_ns, qid),
- xfs_quota_type(qid.type), fdq);
+ return -xfs_qm_scall_getquota(mp, qid, fdq);
}
STATIC int
@@ -126,8 +111,7 @@ xfs_fs_set_dqblk(
if (!XFS_IS_QUOTA_ON(mp))
return -ESRCH;
- return -xfs_qm_scall_setqlim(mp, from_kqid(&init_user_ns, qid),
- xfs_quota_type(qid.type), fdq);
+ return -xfs_qm_scall_setqlim(mp, qid, fdq);
}
const struct quotactl_ops xfs_quotactl_operations = {
--
1.7.5.4
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 11/14] xfs: Modify xfs_qm_dqget to take a struct kqid.
[not found] ` <1363213395-10988-1-git-send-email-ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
2013-03-13 22:23 ` [PATCH 06/14] xfs: Use kuids and kgids in xfs_setattr_nonsize Eric W. Biederman
@ 2013-03-13 22:23 ` Eric W. Biederman
2013-03-13 22:23 ` [PATCH 14/14] xfs: Enable building with user namespaces enabled Eric W. Biederman
2 siblings, 0 replies; 16+ messages in thread
From: Eric W. Biederman @ 2013-03-13 22:23 UTC (permalink / raw)
To: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA
Cc: Alex Elder, Linux Containers, Dave Chinner,
xfs-VZNHf3L845pBDgjK7y7TUQ, Ben Myers, Eric W. Biederman
From: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
- Modify xfs_qm_dqget, xfs_qm_dqattach_one, and xfs_qm_qutoacheck_dqadjust
to take a struct kqid instead of an id and type pair.
- Modify their callers to pass them a struct kqid.
- Move xfs_qutoa_type into xfs_dquot.c where it is now used.
Cc: Ben Myers <bpm-sJ/iWh9BUns@public.gmane.org>
Cc: Alex Elder <elder-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: Dave Chinner <david-FqsqvQoI3Ljby3iVrkZq2A@public.gmane.org>
Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
fs/xfs/xfs_dquot.c | 24 +++++++++++++++++++-----
fs/xfs/xfs_dquot.h | 4 ++--
fs/xfs/xfs_qm.c | 42 +++++++++++++++++++-----------------------
fs/xfs/xfs_qm_bhv.c | 2 +-
fs/xfs/xfs_qm_syscalls.c | 20 ++------------------
5 files changed, 43 insertions(+), 49 deletions(-)
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 8025eb2..51e1c31 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -63,6 +63,19 @@ static struct kmem_zone *xfs_qm_dqzone;
static struct lock_class_key xfs_dquot_other_class;
+STATIC int
+xfs_quota_type(int type)
+{
+ switch (type) {
+ case USRQUOTA:
+ return XFS_DQ_USER;
+ case GRPQUOTA:
+ return XFS_DQ_GROUP;
+ default:
+ return XFS_DQ_PROJ;
+ }
+}
+
/*
* This is called to free all the memory associated with a dquot
*/
@@ -696,20 +709,21 @@ int
xfs_qm_dqget(
xfs_mount_t *mp,
xfs_inode_t *ip, /* locked inode (optional) */
- xfs_dqid_t id, /* uid/projid/gid depending on type */
- uint type, /* XFS_DQ_USER/XFS_DQ_PROJ/XFS_DQ_GROUP */
+ struct kqid qid, /* uid/projid/gid depending on type */
uint flags, /* DQALLOC, DQSUSER, DQREPAIR, DOWARN */
xfs_dquot_t **O_dqpp) /* OUT : locked incore dquot */
{
struct xfs_quotainfo *qi = mp->m_quotainfo;
+ uint id = from_kqid(&init_user_ns, qid);
+ uint type = xfs_quota_type(qid.type);
struct radix_tree_root *tree = XFS_DQUOT_TREE(qi, type);
struct xfs_dquot *dqp;
int error;
ASSERT(XFS_IS_QUOTA_RUNNING(mp));
- if ((! XFS_IS_UQUOTA_ON(mp) && type == XFS_DQ_USER) ||
- (! XFS_IS_PQUOTA_ON(mp) && type == XFS_DQ_PROJ) ||
- (! XFS_IS_GQUOTA_ON(mp) && type == XFS_DQ_GROUP)) {
+ if ((! XFS_IS_UQUOTA_ON(mp) && qid.type == USRQUOTA) ||
+ (! XFS_IS_PQUOTA_ON(mp) && qid.type == PRJQUOTA) ||
+ (! XFS_IS_GQUOTA_ON(mp) && qid.type == GRPQUOTA)) {
return (ESRCH);
}
diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
index 2c197da..3566548 100644
--- a/fs/xfs/xfs_dquot.h
+++ b/fs/xfs/xfs_dquot.h
@@ -147,8 +147,8 @@ extern void xfs_qm_adjust_dqtimers(xfs_mount_t *,
xfs_disk_dquot_t *);
extern void xfs_qm_adjust_dqlimits(xfs_mount_t *,
xfs_disk_dquot_t *);
-extern int xfs_qm_dqget(xfs_mount_t *, xfs_inode_t *,
- xfs_dqid_t, uint, uint, xfs_dquot_t **);
+extern int xfs_qm_dqget(xfs_mount_t *, xfs_inode_t *, struct kqid,
+ uint, xfs_dquot_t **);
extern void xfs_qm_dqput(xfs_dquot_t *);
extern void xfs_dqlock2(struct xfs_dquot *, struct xfs_dquot *);
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index 308592e..31711ed 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -367,8 +367,7 @@ xfs_qm_unmount_quotas(
STATIC int
xfs_qm_dqattach_one(
xfs_inode_t *ip,
- xfs_dqid_t id,
- uint type,
+ struct kqid id,
uint doalloc,
xfs_dquot_t *udqhint, /* hint */
xfs_dquot_t **IO_idqpp)
@@ -397,7 +396,7 @@ xfs_qm_dqattach_one(
* the user dquot.
*/
if (udqhint) {
- ASSERT(type == XFS_DQ_GROUP || type == XFS_DQ_PROJ);
+ ASSERT(id.type == GRPQUOTA || id.type == PRJQUOTA);
xfs_dqlock(udqhint);
/*
@@ -408,7 +407,7 @@ xfs_qm_dqattach_one(
* hold the ilock.
*/
dqp = udqhint->q_gdquot;
- if (dqp && be32_to_cpu(dqp->q_core.d_id) == id) {
+ if (dqp && qid_eq(make_kqid(&init_user_ns, id.type, be32_to_cpu(dqp->q_core.d_id)), id)) {
ASSERT(*IO_idqpp == NULL);
*IO_idqpp = xfs_qm_dqhold(dqp);
@@ -432,7 +431,7 @@ xfs_qm_dqattach_one(
* disk and we didn't ask it to allocate;
* ESRCH if quotas got turned off suddenly.
*/
- error = xfs_qm_dqget(ip->i_mount, ip, id, type,
+ error = xfs_qm_dqget(ip->i_mount, ip, id,
doalloc | XFS_QMOPT_DOWARN, &dqp);
if (error)
return error;
@@ -516,7 +515,7 @@ xfs_qm_dqattach_locked(
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
if (XFS_IS_UQUOTA_ON(mp)) {
- error = xfs_qm_dqattach_one(ip, ip->i_d.di_uid, XFS_DQ_USER,
+ error = xfs_qm_dqattach_one(ip, make_kqid_uid(ip->i_d.di_uid),
flags & XFS_QMOPT_DQALLOC,
NULL, &ip->i_udquot);
if (error)
@@ -527,10 +526,10 @@ xfs_qm_dqattach_locked(
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
if (XFS_IS_OQUOTA_ON(mp)) {
error = XFS_IS_GQUOTA_ON(mp) ?
- xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP,
+ xfs_qm_dqattach_one(ip, make_kqid_gid(ip->i_d.di_gid),
flags & XFS_QMOPT_DQALLOC,
ip->i_udquot, &ip->i_gdquot) :
- xfs_qm_dqattach_one(ip, ip->i_d.di_projid, XFS_DQ_PROJ,
+ xfs_qm_dqattach_one(ip, make_kqid_projid(ip->i_d.di_projid),
flags & XFS_QMOPT_DQALLOC,
ip->i_udquot, &ip->i_gdquot);
/*
@@ -1016,8 +1015,7 @@ out:
STATIC int
xfs_qm_quotacheck_dqadjust(
struct xfs_inode *ip,
- xfs_dqid_t id,
- uint type,
+ struct kqid id,
xfs_qcnt_t nblks,
xfs_qcnt_t rtblks)
{
@@ -1025,7 +1023,7 @@ xfs_qm_quotacheck_dqadjust(
struct xfs_dquot *dqp;
int error;
- error = xfs_qm_dqget(mp, ip, id, type,
+ error = xfs_qm_dqget(mp, ip, id,
XFS_QMOPT_DQALLOC | XFS_QMOPT_DOWARN, &dqp);
if (error) {
/*
@@ -1160,22 +1158,22 @@ xfs_qm_dqusage_adjust(
* and quotaoffs don't race. (Quotachecks happen at mount time only).
*/
if (XFS_IS_UQUOTA_ON(mp)) {
- error = xfs_qm_quotacheck_dqadjust(ip, ip->i_d.di_uid,
- XFS_DQ_USER, nblks, rtblks);
+ error = xfs_qm_quotacheck_dqadjust(ip, make_kqid_uid(ip->i_d.di_uid),
+ nblks, rtblks);
if (error)
goto error0;
}
if (XFS_IS_GQUOTA_ON(mp)) {
- error = xfs_qm_quotacheck_dqadjust(ip, ip->i_d.di_gid,
- XFS_DQ_GROUP, nblks, rtblks);
+ error = xfs_qm_quotacheck_dqadjust(ip, make_kqid_gid(ip->i_d.di_gid),
+ nblks, rtblks);
if (error)
goto error0;
}
if (XFS_IS_PQUOTA_ON(mp)) {
- error = xfs_qm_quotacheck_dqadjust(ip, ip->i_d.di_projid,
- XFS_DQ_PROJ, nblks, rtblks);
+ error = xfs_qm_quotacheck_dqadjust(ip, make_kqid_projid(ip->i_d.di_projid),
+ nblks, rtblks);
if (error)
goto error0;
}
@@ -1662,8 +1660,7 @@ xfs_qm_vop_dqalloc(
* holding ilock.
*/
xfs_iunlock(ip, lockflags);
- if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t) uid,
- XFS_DQ_USER,
+ if ((error = xfs_qm_dqget(mp, NULL, make_kqid_uid(uid),
XFS_QMOPT_DQALLOC |
XFS_QMOPT_DOWARN,
&uq))) {
@@ -1688,8 +1685,7 @@ xfs_qm_vop_dqalloc(
if ((flags & XFS_QMOPT_GQUOTA) && XFS_IS_GQUOTA_ON(mp)) {
if (!gid_eq(ip->i_d.di_gid, gid)) {
xfs_iunlock(ip, lockflags);
- if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)gid,
- XFS_DQ_GROUP,
+ if ((error = xfs_qm_dqget(mp, NULL, make_kqid_gid(gid),
XFS_QMOPT_DQALLOC |
XFS_QMOPT_DOWARN,
&gq))) {
@@ -1708,8 +1704,8 @@ xfs_qm_vop_dqalloc(
} else if ((flags & XFS_QMOPT_PQUOTA) && XFS_IS_PQUOTA_ON(mp)) {
if (!projid_eq(ip->i_d.di_projid, prid)) {
xfs_iunlock(ip, lockflags);
- if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)prid,
- XFS_DQ_PROJ,
+ if ((error = xfs_qm_dqget(mp, NULL,
+ make_kqid_projid(prid),
XFS_QMOPT_DQALLOC |
XFS_QMOPT_DOWARN,
&gq))) {
diff --git a/fs/xfs/xfs_qm_bhv.c b/fs/xfs/xfs_qm_bhv.c
index 7d44746..dda0f7a 100644
--- a/fs/xfs/xfs_qm_bhv.c
+++ b/fs/xfs/xfs_qm_bhv.c
@@ -79,7 +79,7 @@ xfs_qm_statvfs(
xfs_mount_t *mp = ip->i_mount;
xfs_dquot_t *dqp;
- if (!xfs_qm_dqget(mp, NULL, ip->i_d.di_projid, XFS_DQ_PROJ, 0, &dqp)) {
+ if (!xfs_qm_dqget(mp, NULL, make_kqid_projid(ip->i_d.di_projid), 0, &dqp)) {
xfs_fill_statvfs_from_dquot(statp, dqp);
xfs_qm_dqput(dqp);
}
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index 8ad5488..03876dc 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -48,19 +48,6 @@ STATIC int xfs_qm_log_quotaoff_end(xfs_mount_t *, xfs_qoff_logitem_t *,
STATIC uint xfs_qm_export_flags(uint);
STATIC uint xfs_qm_export_qtype_flags(uint);
-STATIC int
-xfs_quota_type(int type)
-{
- switch (type) {
- case USRQUOTA:
- return XFS_DQ_USER;
- case GRPQUOTA:
- return XFS_DQ_GROUP;
- default:
- return XFS_DQ_PROJ;
- }
-}
-
/*
* Turn off quota accounting and/or enforcement for all udquots and/or
* gdquots. Called only at unmount time.
@@ -525,9 +512,7 @@ xfs_qm_scall_setqlim(
* Get the dquot (locked), and join it to the transaction.
* Allocate the dquot if this doesn't exist.
*/
- if ((error = xfs_qm_dqget(mp, NULL, from_kqid(&init_user_ns, id),
- xfs_quota_type(id.type),
- XFS_QMOPT_DQALLOC, &dqp))) {
+ if ((error = xfs_qm_dqget(mp, NULL, id, XFS_QMOPT_DQALLOC, &dqp))) {
xfs_trans_cancel(tp, XFS_TRANS_ABORT);
ASSERT(error != ENOENT);
goto out_unlock;
@@ -744,8 +729,7 @@ xfs_qm_scall_getquota(
* we aren't passing the XFS_QMOPT_DOALLOC flag. If it doesn't
* exist, we'll get ENOENT back.
*/
- error = xfs_qm_dqget(mp, NULL, from_kqid(&init_user_ns, id),
- xfs_quota_type(id.type), 0, &dqp);
+ error = xfs_qm_dqget(mp, NULL, id, 0, &dqp);
if (error)
return error;
--
1.7.5.4
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 12/14] xfs: Remember the kqid for a quota
2013-03-13 22:23 ` [PATCH 01/14] xfs: Convert uids and gids in xfs acls to/from kuids and kgids Eric W. Biederman
` (7 preceding siblings ...)
2013-03-13 22:23 ` [PATCH 10/14] xfs: Push struct kqid into xfs_qm_scall_qmlim and xfs_qm_scall_getquota Eric W. Biederman
@ 2013-03-13 22:23 ` Eric W. Biederman
2013-03-13 22:23 ` [PATCH 13/14] xfs: Use q_id instead of q_core.d_id Eric W. Biederman
[not found] ` <1363213395-10988-1-git-send-email-ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
10 siblings, 0 replies; 16+ messages in thread
From: Eric W. Biederman @ 2013-03-13 22:23 UTC (permalink / raw)
To: linux-fsdevel
Cc: Linux Containers, Serge E. Hallyn, xfs, Ben Myers, Alex Elder,
Dave Chinner, Eric W. Biederman
From: "Eric W. Biederman" <ebiederm@xmission.com>
- Add q_id to struct xfs_quota
- Modify xfs_qm_dqread to take a struct kqid, allowing xfs_qm_dqread to
set q_id on fresh quota structures.
- Modify xfs_qm_dqget and xfs_qm_init_quota_info to pass a kqid
to xfs_qm_dqread
Cc: Ben Myers <bpm@sgi.com>
Cc: Alex Elder <elder@kernel.org>
Cc: Dave Chinner <david@fromorbit.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
fs/xfs/xfs_dquot.c | 12 ++++++------
fs/xfs/xfs_dquot.h | 3 ++-
fs/xfs/xfs_qm.c | 9 +++++----
3 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 51e1c31..00d4b87 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -581,8 +581,7 @@ xfs_qm_dqtobp(
int
xfs_qm_dqread(
struct xfs_mount *mp,
- xfs_dqid_t id,
- uint type,
+ struct kqid id,
uint flags,
struct xfs_dquot **O_dqpp)
{
@@ -596,8 +595,9 @@ xfs_qm_dqread(
dqp = kmem_zone_zalloc(xfs_qm_dqzone, KM_SLEEP);
- dqp->dq_flags = type;
- dqp->q_core.d_id = cpu_to_be32(id);
+ dqp->q_id = id;
+ dqp->dq_flags = xfs_quota_type(id.type);
+ dqp->q_core.d_id = cpu_to_be32(from_kqid(&init_user_ns, id));
dqp->q_mount = mp;
INIT_LIST_HEAD(&dqp->q_lru);
mutex_init(&dqp->q_qlock);
@@ -615,7 +615,7 @@ xfs_qm_dqread(
* Make sure group quotas have a different lock class than user
* quotas.
*/
- if (!(type & XFS_DQ_USER))
+ if (id.type != USRQUOTA)
lockdep_set_class(&dqp->q_qlock, &xfs_dquot_other_class);
XFS_STATS_INC(xs_qm_dquot);
@@ -779,7 +779,7 @@ restart:
if (ip)
xfs_iunlock(ip, XFS_ILOCK_EXCL);
- error = xfs_qm_dqread(mp, id, type, flags, &dqp);
+ error = xfs_qm_dqread(mp, qid, flags, &dqp);
if (ip)
xfs_ilock(ip, XFS_ILOCK_EXCL);
diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
index 3566548..0b6020e 100644
--- a/fs/xfs/xfs_dquot.h
+++ b/fs/xfs/xfs_dquot.h
@@ -36,6 +36,7 @@ struct xfs_trans;
* The incore dquot structure
*/
typedef struct xfs_dquot {
+ struct kqid q_id; /* quota identifier */
uint dq_flags; /* various flags (XFS_DQ_*) */
struct list_head q_lru; /* global free list of dquots */
struct xfs_mount*q_mount; /* filesystem this relates to */
@@ -138,7 +139,7 @@ static inline xfs_dquot_t *xfs_inode_dquot(struct xfs_inode *ip, int type)
XFS_DQ_TO_QINF(dqp)->qi_uquotaip : \
XFS_DQ_TO_QINF(dqp)->qi_gquotaip)
-extern int xfs_qm_dqread(struct xfs_mount *, xfs_dqid_t, uint,
+extern int xfs_qm_dqread(struct xfs_mount *, struct kqid,
uint, struct xfs_dquot **);
extern void xfs_qm_dqdestroy(xfs_dquot_t *);
extern int xfs_qm_dqflush(struct xfs_dquot *, struct xfs_buf **);
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index 31711ed..363a662 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -673,10 +673,11 @@ xfs_qm_init_quotainfo(
* Since we may not have done a quotacheck by this point, just read
* the dquot without attaching it to any hashtables or lists.
*/
- error = xfs_qm_dqread(mp, 0,
- XFS_IS_UQUOTA_RUNNING(mp) ? XFS_DQ_USER :
- (XFS_IS_GQUOTA_RUNNING(mp) ? XFS_DQ_GROUP :
- XFS_DQ_PROJ),
+ error = xfs_qm_dqread(mp,
+ make_kqid(&init_user_ns,
+ XFS_IS_UQUOTA_RUNNING(mp) ? USRQUOTA :
+ (XFS_IS_GQUOTA_RUNNING(mp) ? GRPQUOTA :
+ PRJQUOTA), 0),
XFS_QMOPT_DOWARN, &dqp);
if (!error) {
xfs_disk_dquot_t *ddqp = &dqp->q_core;
--
1.7.5.4
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 13/14] xfs: Use q_id instead of q_core.d_id.
2013-03-13 22:23 ` [PATCH 01/14] xfs: Convert uids and gids in xfs acls to/from kuids and kgids Eric W. Biederman
` (8 preceding siblings ...)
2013-03-13 22:23 ` [PATCH 12/14] xfs: Remember the kqid for a quota Eric W. Biederman
@ 2013-03-13 22:23 ` Eric W. Biederman
[not found] ` <1363213395-10988-1-git-send-email-ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
10 siblings, 0 replies; 16+ messages in thread
From: Eric W. Biederman @ 2013-03-13 22:23 UTC (permalink / raw)
To: linux-fsdevel
Cc: Linux Containers, Serge E. Hallyn, xfs, Ben Myers, Alex Elder,
Dave Chinner, Eric W. Biederman
From: "Eric W. Biederman" <ebiederm@xmission.com>
- Use qid_lt on q_id when compariting two quota entries for order.
- Use qid_eq or !qid_eq when comparing a quota entry for equality or inequality.
- Use is_superquota when testing for the magic quota id of 0.
- Use make_kqid_uid, make_kqid_gid, and make_kqid_projid when comparing
a quota id against a uids, gids, or projids as appropriate.
- For tracing use from_kqid and map to the init user namespace.
Tracers outside of the initial user namespace are not allowed.
- For generating ondisk values continue to use q_core.d_id.
- For cases where we want an index and don't care which quota
it is continue to use be32_to_cpu(...->q_core.d_id)
Cc: Ben Myers <bpm@sgi.com>
Cc: Alex Elder <elder@kernel.org>
Cc: Dave Chinner <david@fromorbit.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
fs/xfs/xfs_dquot.c | 3 +--
fs/xfs/xfs_qm.c | 18 +++++++++---------
fs/xfs/xfs_trace.h | 2 +-
fs/xfs/xfs_trans_dquot.c | 8 ++------
4 files changed, 13 insertions(+), 18 deletions(-)
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 00d4b87..6b306d7 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -1086,8 +1086,7 @@ xfs_dqlock2(
{
if (d1 && d2) {
ASSERT(d1 != d2);
- if (be32_to_cpu(d1->q_core.d_id) >
- be32_to_cpu(d2->q_core.d_id)) {
+ if (qid_lt(d2->q_id, d1->q_id)) {
mutex_lock(&d2->q_qlock);
mutex_lock_nested(&d1->q_qlock, XFS_QLOCK_NESTED);
} else {
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index 363a662..ccf2689 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -407,7 +407,7 @@ xfs_qm_dqattach_one(
* hold the ilock.
*/
dqp = udqhint->q_gdquot;
- if (dqp && qid_eq(make_kqid(&init_user_ns, id.type, be32_to_cpu(dqp->q_core.d_id)), id)) {
+ if (dqp && qid_eq(dqp->q_id, id)) {
ASSERT(*IO_idqpp == NULL);
*IO_idqpp = xfs_qm_dqhold(dqp);
@@ -1057,7 +1057,7 @@ xfs_qm_quotacheck_dqadjust(
*
* There are no timers for the default values set in the root dquot.
*/
- if (dqp->q_core.d_id) {
+ if (!is_superquota(dqp->q_id, &init_user_ns)) {
xfs_qm_adjust_dqlimits(mp, &dqp->q_core);
xfs_qm_adjust_dqtimers(mp, &dqp->q_core);
}
@@ -1804,7 +1804,7 @@ xfs_qm_vop_chown_reserve(
XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS;
if (XFS_IS_UQUOTA_ON(mp) && udqp &&
- !uid_eq(ip->i_d.di_uid, (uid_t)be32_to_cpu(udqp->q_core.d_id))) {
+ !qid_eq(make_kqid_uid(ip->i_d.di_uid), udqp->q_id)) {
delblksudq = udqp;
/*
* If there are delayed allocation blocks, then we have to
@@ -1818,12 +1818,12 @@ xfs_qm_vop_chown_reserve(
}
if (XFS_IS_OQUOTA_ON(ip->i_mount) && gdqp) {
if (XFS_IS_PQUOTA_ON(ip->i_mount) &&
- !projid_eq(ip->i_d.di_projid, be32_to_cpu(gdqp->q_core.d_id)))
+ !qid_eq(make_kqid_projid(ip->i_d.di_projid), gdqp->q_id))
prjflags = XFS_QMOPT_ENOSPC;
if (prjflags ||
(XFS_IS_GQUOTA_ON(ip->i_mount) &&
- !gid_eq(ip->i_d.di_gid, be32_to_cpu(gdqp->q_core.d_id)))) {
+ !qid_eq(make_kqid_gid(ip->i_d.di_gid), gdqp->q_id))) {
delblksgdq = gdqp;
if (delblks) {
ASSERT(ip->i_gdquot);
@@ -1907,7 +1907,7 @@ xfs_qm_vop_create_dqattach(
if (udqp) {
ASSERT(ip->i_udquot == NULL);
ASSERT(XFS_IS_UQUOTA_ON(mp));
- ASSERT(uid_eq(ip->i_d.di_uid, be32_to_cpu(udqp->q_core.d_id)));
+ ASSERT(qid_eq(make_kqid_uid(ip->i_d.di_uid), udqp->q_id));
ip->i_udquot = xfs_qm_dqhold(udqp);
xfs_trans_mod_dquot(tp, udqp, XFS_TRANS_DQ_ICOUNT, 1);
@@ -1915,9 +1915,9 @@ xfs_qm_vop_create_dqattach(
if (gdqp) {
ASSERT(ip->i_gdquot == NULL);
ASSERT(XFS_IS_OQUOTA_ON(mp));
- ASSERT(XFS_IS_GQUOTA_ON(mp) ?
- gid_eq(ip->i_d.di_gid, be32_to_cpu(gdqp->q_core.d_id)):
- projid_eq(ip->i_d.di_projid, be32_to_cpu(gdqp->q_core.d_id)));
+ ASSERT(qid_eq(XFS_IS_GQUOTA_ON(mp) ?
+ make_kqid_gid(ip->i_d.di_gid) :
+ make_kqid_projid(ip->i_d.di_projid), gdqp->q_id));
ip->i_gdquot = xfs_qm_dqhold(gdqp);
xfs_trans_mod_dquot(tp, gdqp, XFS_TRANS_DQ_ICOUNT, 1);
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index 16a8129..a694663 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -713,7 +713,7 @@ DECLARE_EVENT_CLASS(xfs_dquot_class,
), \
TP_fast_assign(
__entry->dev = dqp->q_mount->m_super->s_dev;
- __entry->id = be32_to_cpu(dqp->q_core.d_id);
+ __entry->id = from_kqid(&init_user_ns, dqp->q_id);
__entry->flags = dqp->dq_flags;
__entry->nrefs = dqp->q_nrefs;
__entry->res_bcount = dqp->q_res_bcount;
diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
index 642c2d6..76a5761 100644
--- a/fs/xfs/xfs_trans_dquot.c
+++ b/fs/xfs/xfs_trans_dquot.c
@@ -578,11 +578,7 @@ xfs_quota_warn(
/* no warnings for project quotas - we just return ENOSPC later */
if (dqp->dq_flags & XFS_DQ_PROJ)
return;
- quota_send_warning(make_kqid(&init_user_ns,
- (dqp->dq_flags & XFS_DQ_USER) ?
- USRQUOTA : GRPQUOTA,
- be32_to_cpu(dqp->q_core.d_id)),
- mp->m_super->s_dev, type);
+ quota_send_warning(dqp->q_id, mp->m_super->s_dev, type);
}
/*
@@ -638,7 +634,7 @@ xfs_trans_dqresv(
}
if ((flags & XFS_QMOPT_FORCE_RES) == 0 &&
- dqp->q_core.d_id &&
+ !is_superquota(dqp->q_id, &init_user_ns) &&
((XFS_IS_UQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISUDQ(dqp)) ||
(XFS_IS_OQUOTA_ENFORCED(dqp->q_mount) &&
(XFS_QM_ISPDQ(dqp) || XFS_QM_ISGDQ(dqp))))) {
--
1.7.5.4
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 14/14] xfs: Enable building with user namespaces enabled.
[not found] ` <1363213395-10988-1-git-send-email-ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
2013-03-13 22:23 ` [PATCH 06/14] xfs: Use kuids and kgids in xfs_setattr_nonsize Eric W. Biederman
2013-03-13 22:23 ` [PATCH 11/14] xfs: Modify xfs_qm_dqget to take a struct kqid Eric W. Biederman
@ 2013-03-13 22:23 ` Eric W. Biederman
2 siblings, 0 replies; 16+ messages in thread
From: Eric W. Biederman @ 2013-03-13 22:23 UTC (permalink / raw)
To: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA
Cc: Alex Elder, Linux Containers, Dave Chinner,
xfs-VZNHf3L845pBDgjK7y7TUQ, Ben Myers, Eric W. Biederman
From: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
Not that all of the types holding uids, gids, and projectids
have been converted it is safe to allow users in different
user namespaces to access an xfs filesystem.
Cc: Ben Myers <bpm-sJ/iWh9BUns@public.gmane.org>
Cc: Alex Elder <elder-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: Dave Chinner <david-FqsqvQoI3Ljby3iVrkZq2A@public.gmane.org>
Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
init/Kconfig | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/init/Kconfig b/init/Kconfig
index 22616cd..b5a9ff8 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1068,7 +1068,6 @@ config UIDGID_CONVERTED
default y
# Filesystems
- depends on XFS_FS = n
config UIDGID_STRICT_TYPE_CHECKS
bool "Require conversions between uid/gids and their internal representation"
--
1.7.5.4
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH 00/14] xfs: Support for interacting with multiple user namespaces
[not found] ` <87boan3prc.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
2013-03-13 22:23 ` [PATCH 01/14] xfs: Convert uids and gids in xfs acls to/from kuids and kgids Eric W. Biederman
@ 2013-03-14 6:18 ` Dave Chinner
1 sibling, 0 replies; 16+ messages in thread
From: Dave Chinner @ 2013-03-14 6:18 UTC (permalink / raw)
To: Eric W. Biederman
Cc: Alex Elder, Linux Containers, xfs-VZNHf3L845pBDgjK7y7TUQ,
Ben Myers, linux-fsdevel-u79uwXL29TY76Z2rM5mHXA
On Wed, Mar 13, 2013 at 03:21:11PM -0700, Eric W. Biederman wrote:
>
> Or replace uids, gids, and projids with kuids, kgids, and kprojids
>
> In support of user namespaces I have introduced into the kernel kuids,
> kgids, and kprojids. The most important characteristic of these ids is
> that they are not assignment compatible with uids, gids, and projids
> coming from userspace nor are they assignment compatible with uids, gids
> or projids stored on disk. This assignment incompatibility makes it
> easy to ensure that conversions are introduced at the edge of userspace
> and at the interface between on-disk and in-memory data structures.
TL;DR:
Compared to the last version of this patchset I NACKed, this version
increases the per-inode memory footprint by over 100 bytes (i.e. by
more than 10%), introduces a double copy of the inode core data into
the *hottest path in XFS*, breaks log recovery and fails to address
a single NACK I gave for the previous round of the patch set.
So, NACK.
> Converting xfs is an interesting challenge because of the way xfs
> handles it's inode data is very atypical.
That you have to tell people that find it strange an unusual
immediately indicates that you do not really understand the design
and structure of the XFS code. This makes your refusal to listen to
feedback from someone who is a subject matter expert all the more
difficult to understand.
I'll accept that you might forget something mentioned in a review
when you post an update, but to ignore a second NACK for the same
patch and posting it a third time unchanged is not the best way to
make friends and influence people....
And given that you didn't respond to a single review comment I made
on the previous version of the patch, well, I have my doubts you are
going to respond this time, either. In previous reviews comments I
have:
- outlined exactly how to provide a minimally invasive patch
set that provides full namespace support as a first step
in getting XFS to support namespaces.
- told you where the ondisk/in-memory boundaries are.
- told you that certain IDs are filesystem internal and not
subject to namespaces.
- asked questions about how filesystems utilities are
supposed to deal with namespaces (i.e. userspace impacts
of ioctl interface changes).
And you haven't responded to any of them. You can't selectively
ignore review comments you don't like and then magically expect the
reviewers to accept an almost-identical-but-even-more-broken patch
set the next time around.
> Given the number of ioctls that xfs supports it would be irresponsible to
> do anything except insist that kuids, kgids, and kprojids are used in all of
> in memory data structures of xfs, as otherwise it becomes trivially easy to
> miss a needed conversion with the advent of a new ioctl.
Eric, your rhetoric looks so fine and shiny on the wall, but it is
utterly worthless. You're telling us that userspace interface are
absolutely necessary, but haven't provided any analysis, description
or justification so we can judge the impact of the changes or review
why you think the only way such changes can be made is your way.
Nor have you provided any regression tests to verify that this shiny
new namespace support is working as the maker has intended. IOWs,
I've got no idea what the impact of changing all the ioctls will be,
no way to verify it is correct and you sure as hell aren't going out
of your way to make it easy for us to understand the impact, either.
Further, I'm pretty sure that you are not even aware of the scope of
the issues that namespace awareness raise for some of these XFS
ioctls. I've previously asked some questions about behaviours of
them, but like most of my other review comments you have ignored
those questions.
So, before we go changing anything ioctl related, here's some
questions you need to answer:
- if you run bulkstat, what do we do with inodes that
contain a ID owned by a namespace outside the current
namespace?
- Can we even check the on-disk inode IDs are valid within a
specific namespace within the kernel?
- open_by_handle() would appear to allow root in any
namespace to open any file in the filesystem it has a
valid handle for regardless of the namespace. Is this
allowable? The output of bulkstat can be fed directly to
open_by_handle(), so if bulkstat can return inodes outside
the namespace, open-by-handle can open them and we can do
invisible IO on them.
- Further, we can extract and set attributes directly by
handle and, IIRC, that includes security/trusted namespace
attributes....
- On the same measure, the handles used by XFS handle
interfaces are identical to NFS handles and use the same
code for decoding and dentry lookup. So, what do handle
restrictions mean for NFS servers?
- have you considered that fs/fhandle.c raises many of these
same issues?
- and seeing xfsdump and xfs_fsr use bulkstat and handles,
what do new limitations on these interfaces mean for these
utilities?
- How does xfs_dump/xfs_restore work if we convert all ids
based on the current namespace? e.g. dump in one
namespace, restore in another.
- How does xfs_dump/xfs_restore work if we *don't* convert
all ids (i.e. export the on-disk values)?
- How do we document/communicate all these constraints/
behaviours to users who might be completely unaware of
them?
IOWs, simply converting IDs the ioctls take in or emit is only a
small part of the larger question of how they are supposed to behave
in namespace containers. These questions need to be answered *in
detail* and with *regression tests* before we accept any changes to
the ioctl interfaces.
Eric, I'm not trying to be difficult here - I'm holding the bar at
the same height as it gets held for any significant XFS change that
impacts userspace interfaces and behaviour. You don't maintain the
XFS code, so you can just walk away once namespaces are "done" and
not care that you've left a mess behind.
And if you leave a mess, I'm the person who will have to clean it
up. I don't want to have to clean up your mess, so I'm going to keep
saying no until you can introduce namespace support without making a
mess....
-Dave.
--
Dave Chinner
david-FqsqvQoI3Ljby3iVrkZq2A@public.gmane.org
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2013-03-14 6:18 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-13 22:21 [PATCH 00/14] xfs: Support for interacting with multiple user namespaces Eric W. Biederman
[not found] ` <87boan3prc.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
2013-03-13 22:23 ` [PATCH 01/14] xfs: Convert uids and gids in xfs acls to/from kuids and kgids Eric W. Biederman
2013-03-13 22:23 ` [PATCH 02/14] xfs: Separate the in core and the logged inode Eric W. Biederman
2013-03-13 22:23 ` [PATCH 03/14] xfs: Store projectid as a single variable Eric W. Biederman
2013-03-13 22:23 ` [PATCH 04/14] xfs: Update inode uids, gids, and projids to be kuids, kgids, and kprojids Eric W. Biederman
2013-03-13 22:23 ` [PATCH 05/14] xfs: Update xfs_ioctl_setattr to handle projids in any user namespace Eric W. Biederman
2013-03-13 22:23 ` [PATCH 07/14] xfs: Update ioctl(XFS_IOC_FREE_EOFBLOCKS) to handle callers in any userspace Eric W. Biederman
2013-03-13 22:23 ` [PATCH 08/14] xfs: Use kprojids when allocating inodes Eric W. Biederman
2013-03-13 22:23 ` [PATCH 09/14] xfs: Modify xfs_qm_vop_dqalloc to take kuids, kgids, and kprojids Eric W. Biederman
2013-03-13 22:23 ` [PATCH 10/14] xfs: Push struct kqid into xfs_qm_scall_qmlim and xfs_qm_scall_getquota Eric W. Biederman
2013-03-13 22:23 ` [PATCH 12/14] xfs: Remember the kqid for a quota Eric W. Biederman
2013-03-13 22:23 ` [PATCH 13/14] xfs: Use q_id instead of q_core.d_id Eric W. Biederman
[not found] ` <1363213395-10988-1-git-send-email-ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
2013-03-13 22:23 ` [PATCH 06/14] xfs: Use kuids and kgids in xfs_setattr_nonsize Eric W. Biederman
2013-03-13 22:23 ` [PATCH 11/14] xfs: Modify xfs_qm_dqget to take a struct kqid Eric W. Biederman
2013-03-13 22:23 ` [PATCH 14/14] xfs: Enable building with user namespaces enabled Eric W. Biederman
2013-03-14 6:18 ` [PATCH 00/14] xfs: Support for interacting with multiple user namespaces Dave Chinner
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).