Commit ce62b114 authored by Trond Myklebust's avatar Trond Myklebust Committed by Trond Myklebust
Browse files

NFS: Split attribute support out from the server capabilities



There are lots of attributes, and they are crowding out the bit space.

Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
parent cc7f2dae
Loading
Loading
Loading
Loading
+12 −3
Original line number Diff line number Diff line
@@ -696,9 +696,18 @@ static int nfs_init_server(struct nfs_server *server,
	/* Initialise the client representation from the mount data */
	server->flags = ctx->flags;
	server->options = ctx->options;
	server->caps |= NFS_CAP_HARDLINKS|NFS_CAP_SYMLINKS|NFS_CAP_FILEID|
		NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER|NFS_CAP_OWNER_GROUP|
		NFS_CAP_ATIME|NFS_CAP_CTIME|NFS_CAP_MTIME;
	server->caps |= NFS_CAP_HARDLINKS | NFS_CAP_SYMLINKS;

	switch (clp->rpc_ops->version) {
	case 2:
		server->fattr_valid = NFS_ATTR_FATTR_V2;
		break;
	case 3:
		server->fattr_valid = NFS_ATTR_FATTR_V3;
		break;
	default:
		server->fattr_valid = NFS_ATTR_FATTR_V4;
	}

	if (ctx->rsize)
		server->rsize = nfs_block_size(ctx->rsize, NULL);
+31 −20
Original line number Diff line number Diff line
@@ -438,6 +438,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
		.fattr	= fattr
	};
	struct inode *inode = ERR_PTR(-ENOENT);
	u64 fattr_supported = NFS_SB(sb)->fattr_valid;
	unsigned long hash;

	nfs_attr_check_mountpoint(sb, fattr);
@@ -470,7 +471,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
		inode->i_mode = fattr->mode;
		nfsi->cache_validity = 0;
		if ((fattr->valid & NFS_ATTR_FATTR_MODE) == 0
				&& nfs_server_capable(inode, NFS_CAP_MODE))
				&& (fattr_supported & NFS_ATTR_FATTR_MODE))
			nfs_set_cache_invalid(inode, NFS_INO_INVALID_MODE);
		/* Why so? Because we want revalidate for devices/FIFOs, and
		 * that's precisely what we have in nfs_file_inode_operations.
@@ -516,15 +517,15 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
		nfsi->attr_gencount = fattr->gencount;
		if (fattr->valid & NFS_ATTR_FATTR_ATIME)
			inode->i_atime = fattr->atime;
		else if (nfs_server_capable(inode, NFS_CAP_ATIME))
		else if (fattr_supported & NFS_ATTR_FATTR_ATIME)
			nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATIME);
		if (fattr->valid & NFS_ATTR_FATTR_MTIME)
			inode->i_mtime = fattr->mtime;
		else if (nfs_server_capable(inode, NFS_CAP_MTIME))
		else if (fattr_supported & NFS_ATTR_FATTR_MTIME)
			nfs_set_cache_invalid(inode, NFS_INO_INVALID_MTIME);
		if (fattr->valid & NFS_ATTR_FATTR_CTIME)
			inode->i_ctime = fattr->ctime;
		else if (nfs_server_capable(inode, NFS_CAP_CTIME))
		else if (fattr_supported & NFS_ATTR_FATTR_CTIME)
			nfs_set_cache_invalid(inode, NFS_INO_INVALID_CTIME);
		if (fattr->valid & NFS_ATTR_FATTR_CHANGE)
			inode_set_iversion_raw(inode, fattr->change_attr);
@@ -536,26 +537,30 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
			nfs_set_cache_invalid(inode, NFS_INO_INVALID_SIZE);
		if (fattr->valid & NFS_ATTR_FATTR_NLINK)
			set_nlink(inode, fattr->nlink);
		else if (nfs_server_capable(inode, NFS_CAP_NLINK))
		else if (fattr_supported & NFS_ATTR_FATTR_NLINK)
			nfs_set_cache_invalid(inode, NFS_INO_INVALID_NLINK);
		if (fattr->valid & NFS_ATTR_FATTR_OWNER)
			inode->i_uid = fattr->uid;
		else if (nfs_server_capable(inode, NFS_CAP_OWNER))
		else if (fattr_supported & NFS_ATTR_FATTR_OWNER)
			nfs_set_cache_invalid(inode, NFS_INO_INVALID_OTHER);
		if (fattr->valid & NFS_ATTR_FATTR_GROUP)
			inode->i_gid = fattr->gid;
		else if (nfs_server_capable(inode, NFS_CAP_OWNER_GROUP))
		else if (fattr_supported & NFS_ATTR_FATTR_GROUP)
			nfs_set_cache_invalid(inode, NFS_INO_INVALID_OTHER);
		if (nfs_server_capable(inode, NFS_CAP_XATTR))
			nfs_set_cache_invalid(inode, NFS_INO_INVALID_XATTR);
		if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED)
			inode->i_blocks = fattr->du.nfs2.blocks;
		else if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) {
		else if (fattr_supported & NFS_ATTR_FATTR_BLOCKS_USED &&
			 fattr->size != 0)
			nfs_set_cache_invalid(inode, NFS_INO_INVALID_BLOCKS);
		if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) {
			/*
			 * report the blocks in 512byte units
			 */
			inode->i_blocks = nfs_calc_block_size(fattr->du.nfs3.used);
		} else if (fattr->size != 0)
		} else if (fattr_supported & NFS_ATTR_FATTR_SPACE_USED &&
			   fattr->size != 0)
			nfs_set_cache_invalid(inode, NFS_INO_INVALID_BLOCKS);

		nfs_setsecurity(inode, fattr, label);
@@ -1952,9 +1957,10 @@ EXPORT_SYMBOL_GPL(nfs_post_op_update_inode_force_wcc);
 */
static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
{
	struct nfs_server *server;
	struct nfs_server *server = NFS_SERVER(inode);
	struct nfs_inode *nfsi = NFS_I(inode);
	loff_t cur_isize, new_isize;
	u64 fattr_supported = server->fattr_valid;
	unsigned long invalid = 0;
	unsigned long now = jiffies;
	unsigned long save_cache_validity;
@@ -1998,7 +2004,6 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
		goto out_err;
	}

	server = NFS_SERVER(inode);
	/* Update the fsid? */
	if (S_ISDIR(inode->i_mode) && (fattr->valid & NFS_ATTR_FATTR_FSID) &&
			!nfs_fsid_equal(&server->fsid, &fattr->fsid) &&
@@ -2066,7 +2071,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)

	if (fattr->valid & NFS_ATTR_FATTR_MTIME) {
		inode->i_mtime = fattr->mtime;
	} else if (server->caps & NFS_CAP_MTIME) {
	} else if (fattr_supported & NFS_ATTR_FATTR_MTIME) {
		nfsi->cache_validity |=
			save_cache_validity & NFS_INO_INVALID_MTIME;
		cache_revalidated = false;
@@ -2074,7 +2079,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)

	if (fattr->valid & NFS_ATTR_FATTR_CTIME) {
		inode->i_ctime = fattr->ctime;
	} else if (server->caps & NFS_CAP_CTIME) {
	} else if (fattr_supported & NFS_ATTR_FATTR_CTIME) {
		nfsi->cache_validity |=
			save_cache_validity & NFS_INO_INVALID_CTIME;
		cache_revalidated = false;
@@ -2114,7 +2119,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)

	if (fattr->valid & NFS_ATTR_FATTR_ATIME)
		inode->i_atime = fattr->atime;
	else if (server->caps & NFS_CAP_ATIME) {
	else if (fattr_supported & NFS_ATTR_FATTR_ATIME) {
		nfsi->cache_validity |=
			save_cache_validity & NFS_INO_INVALID_ATIME;
		cache_revalidated = false;
@@ -2129,7 +2134,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
				| NFS_INO_INVALID_ACL;
			attr_changed = true;
		}
	} else if (server->caps & NFS_CAP_MODE) {
	} else if (fattr_supported & NFS_ATTR_FATTR_MODE) {
		nfsi->cache_validity |=
			save_cache_validity & NFS_INO_INVALID_MODE;
		cache_revalidated = false;
@@ -2142,7 +2147,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
			inode->i_uid = fattr->uid;
			attr_changed = true;
		}
	} else if (server->caps & NFS_CAP_OWNER) {
	} else if (fattr_supported & NFS_ATTR_FATTR_OWNER) {
		nfsi->cache_validity |=
			save_cache_validity & NFS_INO_INVALID_OTHER;
		cache_revalidated = false;
@@ -2155,7 +2160,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
			inode->i_gid = fattr->gid;
			attr_changed = true;
		}
	} else if (server->caps & NFS_CAP_OWNER_GROUP) {
	} else if (fattr_supported & NFS_ATTR_FATTR_GROUP) {
		nfsi->cache_validity |=
			save_cache_validity & NFS_INO_INVALID_OTHER;
		cache_revalidated = false;
@@ -2168,7 +2173,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
			set_nlink(inode, fattr->nlink);
			attr_changed = true;
		}
	} else if (server->caps & NFS_CAP_NLINK) {
	} else if (fattr_supported & NFS_ATTR_FATTR_NLINK) {
		nfsi->cache_validity |=
			save_cache_validity & NFS_INO_INVALID_NLINK;
		cache_revalidated = false;
@@ -2179,9 +2184,15 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
		 * report the blocks in 512byte units
		 */
		inode->i_blocks = nfs_calc_block_size(fattr->du.nfs3.used);
	} else if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED)
	} else if (fattr_supported & NFS_ATTR_FATTR_SPACE_USED) {
		nfsi->cache_validity |=
			save_cache_validity & NFS_INO_INVALID_BLOCKS;
		cache_revalidated = false;
	}

	if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED) {
		inode->i_blocks = fattr->du.nfs2.blocks;
	else {
	} else if (fattr_supported & NFS_ATTR_FATTR_BLOCKS_USED) {
		nfsi->cache_validity |=
			save_cache_validity & NFS_INO_INVALID_BLOCKS;
		cache_revalidated = false;
+25 −24
Original line number Diff line number Diff line
@@ -3869,11 +3869,8 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
		}
		memcpy(server->attr_bitmask, res.attr_bitmask, sizeof(server->attr_bitmask));
		server->caps &= ~(NFS_CAP_ACLS | NFS_CAP_HARDLINKS |
				NFS_CAP_SYMLINKS|NFS_CAP_FILEID|
				NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER|
				NFS_CAP_OWNER_GROUP|NFS_CAP_ATIME|
				NFS_CAP_CTIME|NFS_CAP_MTIME|
				NFS_CAP_SECURITY_LABEL);
				  NFS_CAP_SYMLINKS| NFS_CAP_SECURITY_LABEL);
		server->fattr_valid = NFS_ATTR_FATTR_V4;
		if (res.attr_bitmask[0] & FATTR4_WORD0_ACL &&
				res.acl_bitmask & ACL4_SUPPORT_ALLOW_ACL)
			server->caps |= NFS_CAP_ACLS;
@@ -3881,25 +3878,29 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
			server->caps |= NFS_CAP_HARDLINKS;
		if (res.has_symlinks != 0)
			server->caps |= NFS_CAP_SYMLINKS;
		if (res.attr_bitmask[0] & FATTR4_WORD0_FILEID)
			server->caps |= NFS_CAP_FILEID;
		if (res.attr_bitmask[1] & FATTR4_WORD1_MODE)
			server->caps |= NFS_CAP_MODE;
		if (res.attr_bitmask[1] & FATTR4_WORD1_NUMLINKS)
			server->caps |= NFS_CAP_NLINK;
		if (res.attr_bitmask[1] & FATTR4_WORD1_OWNER)
			server->caps |= NFS_CAP_OWNER;
		if (res.attr_bitmask[1] & FATTR4_WORD1_OWNER_GROUP)
			server->caps |= NFS_CAP_OWNER_GROUP;
		if (res.attr_bitmask[1] & FATTR4_WORD1_TIME_ACCESS)
			server->caps |= NFS_CAP_ATIME;
		if (res.attr_bitmask[1] & FATTR4_WORD1_TIME_METADATA)
			server->caps |= NFS_CAP_CTIME;
		if (res.attr_bitmask[1] & FATTR4_WORD1_TIME_MODIFY)
			server->caps |= NFS_CAP_MTIME;
		if (!(res.attr_bitmask[0] & FATTR4_WORD0_FILEID))
			server->fattr_valid &= ~NFS_ATTR_FATTR_FILEID;
		if (!(res.attr_bitmask[1] & FATTR4_WORD1_MODE))
			server->fattr_valid &= ~NFS_ATTR_FATTR_MODE;
		if (!(res.attr_bitmask[1] & FATTR4_WORD1_NUMLINKS))
			server->fattr_valid &= ~NFS_ATTR_FATTR_NLINK;
		if (!(res.attr_bitmask[1] & FATTR4_WORD1_OWNER))
			server->fattr_valid &= ~(NFS_ATTR_FATTR_OWNER |
				NFS_ATTR_FATTR_OWNER_NAME);
		if (!(res.attr_bitmask[1] & FATTR4_WORD1_OWNER_GROUP))
			server->fattr_valid &= ~(NFS_ATTR_FATTR_GROUP |
				NFS_ATTR_FATTR_GROUP_NAME);
		if (!(res.attr_bitmask[1] & FATTR4_WORD1_SPACE_USED))
			server->fattr_valid &= ~NFS_ATTR_FATTR_SPACE_USED;
		if (!(res.attr_bitmask[1] & FATTR4_WORD1_TIME_ACCESS))
			server->fattr_valid &= ~NFS_ATTR_FATTR_ATIME;
		if (!(res.attr_bitmask[1] & FATTR4_WORD1_TIME_METADATA))
			server->fattr_valid &= ~NFS_ATTR_FATTR_CTIME;
		if (!(res.attr_bitmask[1] & FATTR4_WORD1_TIME_MODIFY))
			server->fattr_valid &= ~NFS_ATTR_FATTR_MTIME;
#ifdef CONFIG_NFS_V4_SECURITY_LABEL
		if (res.attr_bitmask[2] & FATTR4_WORD2_SECURITY_LABEL)
			server->caps |= NFS_CAP_SECURITY_LABEL;
		if (!(res.attr_bitmask[2] & FATTR4_WORD2_SECURITY_LABEL))
			server->fattr_valid &= ~NFS_ATTR_FATTR_V4_SECURITY_LABEL;
#endif
		memcpy(server->attr_bitmask_nl, res.attr_bitmask,
				sizeof(server->attr_bitmask));
+2 −9
Original line number Diff line number Diff line
@@ -191,6 +191,8 @@ struct nfs_server {
	dev_t			s_dev;		/* superblock dev numbers */
	struct nfs_auth_info	auth_info;	/* parsed auth flavors */

	__u64			fattr_valid;	/* Valid attributes */

#ifdef CONFIG_NFS_FSCACHE
	struct nfs_fscache_key	*fscache_key;	/* unique key for superblock */
	struct fscache_cookie	*fscache;	/* superblock cookie */
@@ -267,16 +269,7 @@ struct nfs_server {
#define NFS_CAP_SYMLINKS	(1U << 2)
#define NFS_CAP_ACLS		(1U << 3)
#define NFS_CAP_ATOMIC_OPEN	(1U << 4)
/* #define NFS_CAP_CHANGE_ATTR	(1U << 5) */
#define NFS_CAP_LGOPEN		(1U << 5)
#define NFS_CAP_FILEID		(1U << 6)
#define NFS_CAP_MODE		(1U << 7)
#define NFS_CAP_NLINK		(1U << 8)
#define NFS_CAP_OWNER		(1U << 9)
#define NFS_CAP_OWNER_GROUP	(1U << 10)
#define NFS_CAP_ATIME		(1U << 11)
#define NFS_CAP_CTIME		(1U << 12)
#define NFS_CAP_MTIME		(1U << 13)
#define NFS_CAP_POSIX_LOCK	(1U << 14)
#define NFS_CAP_UIDGID_NOMAP	(1U << 15)
#define NFS_CAP_STATEID_NFSV41	(1U << 16)