NFS: Save some space in the inode
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Tue, 28 Sep 2021 21:41:41 +0000 (17:41 -0400)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Wed, 20 Oct 2021 22:09:54 +0000 (18:09 -0400)
Save some space in the nfs_inode by setting up an anonymous union with
the fields that are peculiar to a specific type of filesystem object.

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
fs/nfs/inode.c
include/linux/nfs_fs.h

index a10572f..b81b2d2 100644 (file)
@@ -431,6 +431,22 @@ nfs_ilookup(struct super_block *sb, struct nfs_fattr *fattr, struct nfs_fh *fh)
        return inode;
 }
 
+static void nfs_inode_init_regular(struct nfs_inode *nfsi)
+{
+       atomic_long_set(&nfsi->nrequests, 0);
+       INIT_LIST_HEAD(&nfsi->commit_info.list);
+       atomic_long_set(&nfsi->commit_info.ncommit, 0);
+       atomic_set(&nfsi->commit_info.rpcs_out, 0);
+       mutex_init(&nfsi->commit_mutex);
+}
+
+static void nfs_inode_init_dir(struct nfs_inode *nfsi)
+{
+       nfsi->cache_change_attribute = 0;
+       memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
+       init_rwsem(&nfsi->rmdir_sem);
+}
+
 /*
  * This is our front-end to iget that looks up inodes by file handle
  * instead of inode number.
@@ -485,10 +501,12 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
                if (S_ISREG(inode->i_mode)) {
                        inode->i_fop = NFS_SB(sb)->nfs_client->rpc_ops->file_ops;
                        inode->i_data.a_ops = &nfs_file_aops;
+                       nfs_inode_init_regular(nfsi);
                } else if (S_ISDIR(inode->i_mode)) {
                        inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->dir_inode_ops;
                        inode->i_fop = &nfs_dir_operations;
                        inode->i_data.a_ops = &nfs_dir_aops;
+                       nfs_inode_init_dir(nfsi);
                        /* Deal with crossing mountpoints */
                        if (fattr->valid & NFS_ATTR_FATTR_MOUNTPOINT ||
                                        fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) {
@@ -514,7 +532,6 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
                inode->i_uid = make_kuid(&init_user_ns, -2);
                inode->i_gid = make_kgid(&init_user_ns, -2);
                inode->i_blocks = 0;
-               memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
                nfsi->write_io = 0;
                nfsi->read_io = 0;
 
@@ -2259,14 +2276,7 @@ static void init_once(void *foo)
        INIT_LIST_HEAD(&nfsi->open_files);
        INIT_LIST_HEAD(&nfsi->access_cache_entry_lru);
        INIT_LIST_HEAD(&nfsi->access_cache_inode_lru);
-       INIT_LIST_HEAD(&nfsi->commit_info.list);
-       atomic_long_set(&nfsi->nrequests, 0);
-       atomic_long_set(&nfsi->commit_info.ncommit, 0);
-       atomic_set(&nfsi->commit_info.rpcs_out, 0);
-       init_rwsem(&nfsi->rmdir_sem);
-       mutex_init(&nfsi->commit_mutex);
        nfs4_init_once(nfsi);
-       nfsi->cache_change_attribute = 0;
 }
 
 static int __init nfs_init_inodecache(void)
index 457b866..739ca1e 100644 (file)
@@ -155,33 +155,39 @@ struct nfs_inode {
        unsigned long           attrtimeo_timestamp;
 
        unsigned long           attr_gencount;
-       /* "Generation counter" for the attribute cache. This is
-        * bumped whenever we update the metadata on the
-        * server.
-        */
-       unsigned long           cache_change_attribute;
 
        struct rb_root          access_cache;
        struct list_head        access_cache_entry_lru;
        struct list_head        access_cache_inode_lru;
 
-       /*
-        * This is the cookie verifier used for NFSv3 readdir
-        * operations
-        */
-       __be32                  cookieverf[NFS_DIR_VERIFIER_SIZE];
-
-       atomic_long_t           nrequests;
-       struct nfs_mds_commit_info commit_info;
+       union {
+               /* Directory */
+               struct {
+                       /* "Generation counter" for the attribute cache.
+                        * This is bumped whenever we update the metadata
+                        * on the server.
+                        */
+                       unsigned long   cache_change_attribute;
+                       /*
+                        * This is the cookie verifier used for NFSv3 readdir
+                        * operations
+                        */
+                       __be32          cookieverf[NFS_DIR_VERIFIER_SIZE];
+                       /* Readers: in-flight sillydelete RPC calls */
+                       /* Writers: rmdir */
+                       struct rw_semaphore     rmdir_sem;
+               };
+               /* Regular file */
+               struct {
+                       atomic_long_t   nrequests;
+                       struct nfs_mds_commit_info commit_info;
+                       struct mutex    commit_mutex;
+               };
+       };
 
        /* Open contexts for shared mmap writes */
        struct list_head        open_files;
 
-       /* Readers: in-flight sillydelete RPC calls */
-       /* Writers: rmdir */
-       struct rw_semaphore     rmdir_sem;
-       struct mutex            commit_mutex;
-
 #if IS_ENABLED(CONFIG_NFS_V4)
        struct nfs4_cached_acl  *nfs4_acl;
         /* NFSv4 state */