~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/nfs/getroot.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /fs/nfs/getroot.c (Version linux-6.11.5) and /fs/nfs/getroot.c (Version linux-5.0.21)


  1 // SPDX-License-Identifier: GPL-2.0-or-later   << 
  2 /* getroot.c: get the root dentry for an NFS m      1 /* getroot.c: get the root dentry for an NFS mount
  3  *                                                  2  *
  4  * Copyright (C) 2006 Red Hat, Inc. All Rights      3  * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
  5  * Written by David Howells (dhowells@redhat.c      4  * Written by David Howells (dhowells@redhat.com)
                                                   >>   5  *
                                                   >>   6  * This program is free software; you can redistribute it and/or
                                                   >>   7  * modify it under the terms of the GNU General Public License
                                                   >>   8  * as published by the Free Software Foundation; either version
                                                   >>   9  * 2 of the License, or (at your option) any later version.
  6  */                                                10  */
  7                                                    11 
  8 #include <linux/module.h>                          12 #include <linux/module.h>
  9 #include <linux/init.h>                            13 #include <linux/init.h>
 10                                                    14 
 11 #include <linux/time.h>                            15 #include <linux/time.h>
 12 #include <linux/kernel.h>                          16 #include <linux/kernel.h>
 13 #include <linux/mm.h>                              17 #include <linux/mm.h>
 14 #include <linux/string.h>                          18 #include <linux/string.h>
 15 #include <linux/stat.h>                            19 #include <linux/stat.h>
 16 #include <linux/errno.h>                           20 #include <linux/errno.h>
 17 #include <linux/unistd.h>                          21 #include <linux/unistd.h>
 18 #include <linux/sunrpc/clnt.h>                     22 #include <linux/sunrpc/clnt.h>
 19 #include <linux/sunrpc/stats.h>                    23 #include <linux/sunrpc/stats.h>
 20 #include <linux/nfs_fs.h>                          24 #include <linux/nfs_fs.h>
 21 #include <linux/nfs_mount.h>                       25 #include <linux/nfs_mount.h>
 22 #include <linux/lockd/bind.h>                      26 #include <linux/lockd/bind.h>
 23 #include <linux/seq_file.h>                        27 #include <linux/seq_file.h>
 24 #include <linux/mount.h>                           28 #include <linux/mount.h>
 25 #include <linux/vfs.h>                             29 #include <linux/vfs.h>
 26 #include <linux/namei.h>                           30 #include <linux/namei.h>
 27 #include <linux/security.h>                        31 #include <linux/security.h>
 28                                                    32 
 29 #include <linux/uaccess.h>                         33 #include <linux/uaccess.h>
 30                                                    34 
 31 #include "internal.h"                              35 #include "internal.h"
 32                                                    36 
 33 #define NFSDBG_FACILITY         NFSDBG_CLIENT      37 #define NFSDBG_FACILITY         NFSDBG_CLIENT
 34                                                    38 
 35 /*                                                 39 /*
 36  * Set the superblock root dentry.                 40  * Set the superblock root dentry.
 37  * Note that this function frees the inode in      41  * Note that this function frees the inode in case of error.
 38  */                                                42  */
 39 static int nfs_superblock_set_dummy_root(struc     43 static int nfs_superblock_set_dummy_root(struct super_block *sb, struct inode *inode)
 40 {                                                  44 {
 41         /* The mntroot acts as the dummy root      45         /* The mntroot acts as the dummy root dentry for this superblock */
 42         if (sb->s_root == NULL) {                  46         if (sb->s_root == NULL) {
 43                 sb->s_root = d_make_root(inode     47                 sb->s_root = d_make_root(inode);
 44                 if (sb->s_root == NULL)            48                 if (sb->s_root == NULL)
 45                         return -ENOMEM;            49                         return -ENOMEM;
 46                 ihold(inode);                      50                 ihold(inode);
 47                 /*                                 51                 /*
 48                  * Ensure that this dentry is      52                  * Ensure that this dentry is invisible to d_find_alias().
 49                  * Otherwise, it may be splice     53                  * Otherwise, it may be spliced into the tree by
 50                  * d_splice_alias if a parent      54                  * d_splice_alias if a parent directory from the same
 51                  * filesystem gets mounted at      55                  * filesystem gets mounted at a later time.
 52                  * This again causes shrink_dc     56                  * This again causes shrink_dcache_for_umount_subtree() to
 53                  * Oops, since the test for IS     57                  * Oops, since the test for IS_ROOT() will fail.
 54                  */                                58                  */
 55                 spin_lock(&d_inode(sb->s_root)     59                 spin_lock(&d_inode(sb->s_root)->i_lock);
 56                 spin_lock(&sb->s_root->d_lock)     60                 spin_lock(&sb->s_root->d_lock);
 57                 hlist_del_init(&sb->s_root->d_     61                 hlist_del_init(&sb->s_root->d_u.d_alias);
 58                 spin_unlock(&sb->s_root->d_loc     62                 spin_unlock(&sb->s_root->d_lock);
 59                 spin_unlock(&d_inode(sb->s_roo     63                 spin_unlock(&d_inode(sb->s_root)->i_lock);
 60         }                                          64         }
 61         return 0;                                  65         return 0;
 62 }                                                  66 }
 63                                                    67 
 64 /*                                                 68 /*
 65  * get an NFS2/NFS3 root dentry from the root      69  * get an NFS2/NFS3 root dentry from the root filehandle
 66  */                                                70  */
 67 int nfs_get_root(struct super_block *s, struct !!  71 struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh,
                                                   >>  72                             const char *devname)
 68 {                                                  73 {
 69         struct nfs_fs_context *ctx = nfs_fc2co !!  74         struct nfs_server *server = NFS_SB(sb);
 70         struct nfs_server *server = NFS_SB(s), << 
 71         struct nfs_fsinfo fsinfo;                  75         struct nfs_fsinfo fsinfo;
 72         struct dentry *root;                   !!  76         struct dentry *ret;
 73         struct inode *inode;                       77         struct inode *inode;
 74         char *name;                            !!  78         void *name = kstrdup(devname, GFP_KERNEL);
 75         int error = -ENOMEM;                   !!  79         int error;
 76         unsigned long kflags = 0, kflags_out = << 
 77                                                    80 
 78         name = kstrdup(fc->source, GFP_KERNEL) << 
 79         if (!name)                                 81         if (!name)
 80                 goto out;                      !!  82                 return ERR_PTR(-ENOMEM);
 81                                                    83 
 82         /* get the actual root for this mount      84         /* get the actual root for this mount */
 83         fsinfo.fattr = nfs_alloc_fattr_with_la !!  85         fsinfo.fattr = nfs_alloc_fattr();
 84         if (fsinfo.fattr == NULL)              !!  86         if (fsinfo.fattr == NULL) {
 85                 goto out_name;                 !!  87                 kfree(name);
                                                   >>  88                 return ERR_PTR(-ENOMEM);
                                                   >>  89         }
 86                                                    90 
 87         error = server->nfs_client->rpc_ops->g !!  91         error = server->nfs_client->rpc_ops->getroot(server, mntfh, &fsinfo);
 88         if (error < 0) {                           92         if (error < 0) {
 89                 dprintk("nfs_get_root: getattr     93                 dprintk("nfs_get_root: getattr error = %d\n", -error);
 90                 nfs_errorf(fc, "NFS: Couldn't  !!  94                 ret = ERR_PTR(error);
 91                 goto out_fattr;                !!  95                 goto out;
 92         }                                          96         }
 93                                                    97 
 94         inode = nfs_fhget(s, ctx->mntfh, fsinf !!  98         inode = nfs_fhget(sb, mntfh, fsinfo.fattr, NULL);
 95         if (IS_ERR(inode)) {                       99         if (IS_ERR(inode)) {
 96                 dprintk("nfs_get_root: get roo    100                 dprintk("nfs_get_root: get root inode failed\n");
 97                 error = PTR_ERR(inode);        !! 101                 ret = ERR_CAST(inode);
 98                 nfs_errorf(fc, "NFS: Couldn't  !! 102                 goto out;
 99                 goto out_fattr;                << 
100         }                                         103         }
101                                                   104 
102         error = nfs_superblock_set_dummy_root( !! 105         error = nfs_superblock_set_dummy_root(sb, inode);
103         if (error != 0)                        !! 106         if (error != 0) {
104                 goto out_fattr;                !! 107                 ret = ERR_PTR(error);
                                                   >> 108                 goto out;
                                                   >> 109         }
105                                                   110 
106         /* root dentries normally start off an    111         /* root dentries normally start off anonymous and get spliced in later
107          * if the dentry tree reaches them; ho    112          * if the dentry tree reaches them; however if the dentry already
108          * exists, we'll pick it up at this po    113          * exists, we'll pick it up at this point and use it as the root
109          */                                       114          */
110         root = d_obtain_root(inode);           !! 115         ret = d_obtain_root(inode);
111         if (IS_ERR(root)) {                    !! 116         if (IS_ERR(ret)) {
112                 dprintk("nfs_get_root: get roo    117                 dprintk("nfs_get_root: get root dentry failed\n");
113                 error = PTR_ERR(root);         !! 118                 goto out;
114                 nfs_errorf(fc, "NFS: Couldn't  << 
115                 goto out_fattr;                << 
116         }                                         119         }
117                                                   120 
118         security_d_instantiate(root, inode);   !! 121         security_d_instantiate(ret, inode);
119         spin_lock(&root->d_lock);              !! 122         spin_lock(&ret->d_lock);
120         if (IS_ROOT(root) && !root->d_fsdata & !! 123         if (IS_ROOT(ret) && !ret->d_fsdata &&
121             !(root->d_flags & DCACHE_NFSFS_REN !! 124             !(ret->d_flags & DCACHE_NFSFS_RENAMED)) {
122                 root->d_fsdata = name;         !! 125                 ret->d_fsdata = name;
123                 name = NULL;                      126                 name = NULL;
124         }                                         127         }
125         spin_unlock(&root->d_lock);            !! 128         spin_unlock(&ret->d_lock);
126         fc->root = root;                       << 
127         if (server->caps & NFS_CAP_SECURITY_LA << 
128                 kflags |= SECURITY_LSM_NATIVE_ << 
129         if (ctx->clone_data.sb) {              << 
130                 if (d_inode(fc->root)->i_fop ! << 
131                         error = -ESTALE;       << 
132                         goto error_splat_root; << 
133                 }                              << 
134                 /* clone lsm security options  << 
135                 error = security_sb_clone_mnt_ << 
136                                                << 
137                 if (error)                     << 
138                         goto error_splat_root; << 
139                 clone_server = NFS_SB(ctx->clo << 
140                 server->has_sec_mnt_opts = clo << 
141         } else {                               << 
142                 error = security_sb_set_mnt_op << 
143                                                << 
144         }                                      << 
145         if (error)                             << 
146                 goto error_splat_root;         << 
147         if (server->caps & NFS_CAP_SECURITY_LA << 
148                 !(kflags_out & SECURITY_LSM_NA << 
149                 server->caps &= ~NFS_CAP_SECUR << 
150                                                << 
151         nfs_setsecurity(inode, fsinfo.fattr);  << 
152         error = 0;                             << 
153                                                << 
154 out_fattr:                                     << 
155         nfs_free_fattr(fsinfo.fattr);          << 
156 out_name:                                      << 
157         kfree(name);                           << 
158 out:                                              129 out:
159         return error;                          !! 130         kfree(name);
160 error_splat_root:                              !! 131         nfs_free_fattr(fsinfo.fattr);
161         dput(fc->root);                        !! 132         return ret;
162         fc->root = NULL;                       << 
163         goto out_fattr;                        << 
164 }                                                 133 }
165                                                   134 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php