From b2c8b3ea871e478ac144f617d015d3aa55fc3aa8 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Tue, 4 Feb 2014 15:45:11 +0000 Subject: GFS2: Allocate block for xattr at inode alloc time, if required This is another step towards improving the allocation of xattr blocks at inode allocation time. Here we take advantage of Christoph's recent work on ACLs to allocate a block for the xattrs early if we know that we will be adding ACLs to the inode later on. The advantage of that is that it is much more likely that we'll get a contiguous run of two blocks where the first is the inode and the second is the xattr block. We still have to fall back to the original system in case we don't get the requested two contiguous blocks, or in case the ACLs are too large to fit into the block. Future patches will move more of the ACL setting code further up the gfs2_inode_create() function. Also, I'd like to be able to do the same thing with the xattrs from LSMs in due course, too. That way we should be able to slowly reduce the number of independent transactions, at least in the most common cases. Signed-off-by: Steven Whitehouse --- include/uapi/linux/gfs2_ondisk.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/uapi') diff --git a/include/uapi/linux/gfs2_ondisk.h b/include/uapi/linux/gfs2_ondisk.h index 0f24c07aed51..310020816809 100644 --- a/include/uapi/linux/gfs2_ondisk.h +++ b/include/uapi/linux/gfs2_ondisk.h @@ -347,9 +347,9 @@ struct gfs2_leaf { * metadata header. Each inode, if it has extended attributes, will * have either a single block containing the extended attribute headers * or a single indirect block pointing to blocks containing the - * extended attribure headers. + * extended attribute headers. * - * The maximim size of the data part of an extended attribute is 64k + * The maximum size of the data part of an extended attribute is 64k * so the number of blocks required depends upon block size. Since the * block size also determines the number of pointers in an indirect * block, its a fairly complicated calculation to work out the maximum -- cgit v1.2.3 From 44aaada9d144a46d3de48ad81093f69d17fae96f Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Fri, 7 Feb 2014 11:23:22 +0000 Subject: GFS2: Add meta readahead field in directory entries The intent of this new field in the directory entry is to allow a subsequent lookup to know how many blocks, which are contiguous with the inode, contain metadata which relates to the inode. This will then allow the issuing of a single read to read these blocks, rather than reading the inode first, and then issuing a second read for the metadata. This only works under some fairly strict conditions, since we do not have back pointers from inodes to directory entries we must ensure that the blocks referenced in this way will always belong to the inode. This rules out being able to use this system for indirect blocks, as these can change as a result of truncate/rewrite. So the idea here is to restrict this to xattr blocks only for the time being. For most inodes, that means only a single block. Also, when using ACLs and/or SELinux or other LSMs, these will be added at inode creation time so that they will be contiguous with the inode on disk and also will almost always be needed when we read the inode in for permissions checks. Once an xattr block for an inode is allocated, it will never change until the inode is deallocated. This patch adds the new field, a further patch will add the readahead in due course. Signed-off-by: Steven Whitehouse --- fs/gfs2/dir.c | 9 +++++++++ include/uapi/linux/gfs2_ondisk.h | 8 +++++++- 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'include/uapi') diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index fa32655449c8..ffcfdd18d485 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c @@ -1684,6 +1684,14 @@ static int dir_new_leaf(struct inode *inode, const struct qstr *name) return 0; } +static u16 gfs2_inode_ra_len(const struct gfs2_inode *ip) +{ + u64 where = ip->i_no_addr + 1; + if (ip->i_eattr == where) + return 1; + return 0; +} + /** * gfs2_dir_add - Add new filename into directory * @inode: The directory inode @@ -1721,6 +1729,7 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name, dent = gfs2_init_dirent(inode, dent, name, bh); gfs2_inum_out(nip, dent); dent->de_type = cpu_to_be16(IF2DT(nip->i_inode.i_mode)); + dent->de_rahead = cpu_to_be16(gfs2_inode_ra_len(nip)); tv = CURRENT_TIME; if (ip->i_diskflags & GFS2_DIF_EXHASH) { leaf = (struct gfs2_leaf *)bh->b_data; diff --git a/include/uapi/linux/gfs2_ondisk.h b/include/uapi/linux/gfs2_ondisk.h index 310020816809..db3fdd083882 100644 --- a/include/uapi/linux/gfs2_ondisk.h +++ b/include/uapi/linux/gfs2_ondisk.h @@ -304,7 +304,13 @@ struct gfs2_dirent { __be16 de_rec_len; __be16 de_name_len; __be16 de_type; - __u8 __pad[14]; + union { + __u8 __pad[14]; + struct { + __be16 de_rahead; + __u8 pad2[12]; + }; + }; }; /* -- cgit v1.2.3