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

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

Version: ~ [ linux-5.13-rc1 ] ~ [ linux-5.12.2 ] ~ [ linux-5.11.19 ] ~ [ linux-5.10.35 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.117 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.190 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.232 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.268 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.268 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ 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.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* getroot.c: get the root dentry for an NFS mount
  2  *
  3  * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
  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.
 10  */
 11 
 12 #include <linux/module.h>
 13 #include <linux/init.h>
 14 
 15 #include <linux/time.h>
 16 #include <linux/kernel.h>
 17 #include <linux/mm.h>
 18 #include <linux/string.h>
 19 #include <linux/stat.h>
 20 #include <linux/errno.h>
 21 #include <linux/unistd.h>
 22 #include <linux/sunrpc/clnt.h>
 23 #include <linux/sunrpc/stats.h>
 24 #include <linux/nfs_fs.h>
 25 #include <linux/nfs_mount.h>
 26 #include <linux/lockd/bind.h>
 27 #include <linux/seq_file.h>
 28 #include <linux/mount.h>
 29 #include <linux/vfs.h>
 30 #include <linux/namei.h>
 31 #include <linux/security.h>
 32 
 33 #include <asm/uaccess.h>
 34 
 35 #include "internal.h"
 36 
 37 #define NFSDBG_FACILITY         NFSDBG_CLIENT
 38 
 39 /*
 40  * Set the superblock root dentry.
 41  * Note that this function frees the inode in case of error.
 42  */
 43 static int nfs_superblock_set_dummy_root(struct super_block *sb, struct inode *inode)
 44 {
 45         /* The mntroot acts as the dummy root dentry for this superblock */
 46         if (sb->s_root == NULL) {
 47                 sb->s_root = d_make_root(inode);
 48                 if (sb->s_root == NULL)
 49                         return -ENOMEM;
 50                 ihold(inode);
 51                 /*
 52                  * Ensure that this dentry is invisible to d_find_alias().
 53                  * Otherwise, it may be spliced into the tree by
 54                  * d_splice_alias if a parent directory from the same
 55                  * filesystem gets mounted at a later time.
 56                  * This again causes shrink_dcache_for_umount_subtree() to
 57                  * Oops, since the test for IS_ROOT() will fail.
 58                  */
 59                 spin_lock(&d_inode(sb->s_root)->i_lock);
 60                 spin_lock(&sb->s_root->d_lock);
 61                 hlist_del_init(&sb->s_root->d_u.d_alias);
 62                 spin_unlock(&sb->s_root->d_lock);
 63                 spin_unlock(&d_inode(sb->s_root)->i_lock);
 64         }
 65         return 0;
 66 }
 67 
 68 /*
 69  * get an NFS2/NFS3 root dentry from the root filehandle
 70  */
 71 struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh,
 72                             const char *devname)
 73 {
 74         struct nfs_server *server = NFS_SB(sb);
 75         struct nfs_fsinfo fsinfo;
 76         struct dentry *ret;
 77         struct inode *inode;
 78         void *name = kstrdup(devname, GFP_KERNEL);
 79         int error;
 80 
 81         if (!name)
 82                 return ERR_PTR(-ENOMEM);
 83 
 84         /* get the actual root for this mount */
 85         fsinfo.fattr = nfs_alloc_fattr();
 86         if (fsinfo.fattr == NULL) {
 87                 kfree(name);
 88                 return ERR_PTR(-ENOMEM);
 89         }
 90 
 91         error = server->nfs_client->rpc_ops->getroot(server, mntfh, &fsinfo);
 92         if (error < 0) {
 93                 dprintk("nfs_get_root: getattr error = %d\n", -error);
 94                 ret = ERR_PTR(error);
 95                 goto out;
 96         }
 97 
 98         inode = nfs_fhget(sb, mntfh, fsinfo.fattr, NULL);
 99         if (IS_ERR(inode)) {
100                 dprintk("nfs_get_root: get root inode failed\n");
101                 ret = ERR_CAST(inode);
102                 goto out;
103         }
104 
105         error = nfs_superblock_set_dummy_root(sb, inode);
106         if (error != 0) {
107                 ret = ERR_PTR(error);
108                 goto out;
109         }
110 
111         /* root dentries normally start off anonymous and get spliced in later
112          * if the dentry tree reaches them; however if the dentry already
113          * exists, we'll pick it up at this point and use it as the root
114          */
115         ret = d_obtain_root(inode);
116         if (IS_ERR(ret)) {
117                 dprintk("nfs_get_root: get root dentry failed\n");
118                 goto out;
119         }
120 
121         security_d_instantiate(ret, inode);
122         spin_lock(&ret->d_lock);
123         if (IS_ROOT(ret) && !ret->d_fsdata &&
124             !(ret->d_flags & DCACHE_NFSFS_RENAMED)) {
125                 ret->d_fsdata = name;
126                 name = NULL;
127         }
128         spin_unlock(&ret->d_lock);
129 out:
130         kfree(name);
131         nfs_free_fattr(fsinfo.fattr);
132         return ret;
133 }
134 

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

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | 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.

osdn.jp