From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Eric W. Biederman" Subject: [PATCH review 07/16] xfs: Update ioctl(XFS_IOC_FREE_EOFBLOCKS) to handle callers in any userspace Date: Sun, 17 Feb 2013 17:11:00 -0800 Message-ID: <1361149870-27732-7-git-send-email-ebiederm@xmission.com> References: <87txpaph4n.fsf@xmission.com> <1361149870-27732-1-git-send-email-ebiederm@xmission.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Cc: Alex Elder , Linux Containers , Dave Chinner , linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Ben Myers , "Eric W. Biederman" To: Return-path: In-Reply-To: <1361149870-27732-1-git-send-email-ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: containers-bounces-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org Errors-To: containers-bounces-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org List-Id: linux-fsdevel.vger.kernel.org From: "Eric W. Biederman" - 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 Cc: Alex Elder Cc: Dave Chinner Signed-off-by: "Eric W. Biederman" --- 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 0583649..e4cdc02 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(VFS_I(ip)->i_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_projid, eofb->eof_prid)) + !projid_eq(ip->i_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 4a55f50..1a74b56 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