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

TOMOYO Linux Cross Reference
Linux/fs/sysfs/dir.c

Version: ~ [ linux-5.8 ] ~ [ linux-5.7.14 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.57 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.138 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.193 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.232 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.232 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ 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 /*
  2  * dir.c - Operations for sysfs directories.
  3  */
  4 
  5 #undef DEBUG
  6 
  7 #include <linux/fs.h>
  8 #include <linux/mount.h>
  9 #include <linux/module.h>
 10 #include <linux/kobject.h>
 11 #include "sysfs.h"
 12 
 13 static int init_dir(struct inode * inode)
 14 {
 15         inode->i_op = &simple_dir_inode_operations;
 16         inode->i_fop = &simple_dir_operations;
 17 
 18         /* directory inodes start off with i_nlink == 2 (for "." entry) */
 19         inode->i_nlink++;
 20         return 0;
 21 }
 22 
 23 
 24 static int create_dir(struct kobject * k, struct dentry * p,
 25                       const char * n, struct dentry ** d)
 26 {
 27         int error;
 28 
 29         down(&p->d_inode->i_sem);
 30         *d = sysfs_get_dentry(p,n);
 31         if (!IS_ERR(*d)) {
 32                 error = sysfs_create(*d,
 33                                          S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO,
 34                                          init_dir);
 35                 if (!error) {
 36                         (*d)->d_fsdata = k;
 37                         p->d_inode->i_nlink++;
 38                 }
 39                 dput(*d);
 40         } else
 41                 error = PTR_ERR(*d);
 42         up(&p->d_inode->i_sem);
 43         return error;
 44 }
 45 
 46 
 47 int sysfs_create_subdir(struct kobject * k, const char * n, struct dentry ** d)
 48 {
 49         return create_dir(k,k->dentry,n,d);
 50 }
 51 
 52 /**
 53  *      sysfs_create_dir - create a directory for an object.
 54  *      @parent:        parent parent object.
 55  *      @kobj:          object we're creating directory for. 
 56  */
 57 
 58 int sysfs_create_dir(struct kobject * kobj)
 59 {
 60         struct dentry * dentry = NULL;
 61         struct dentry * parent;
 62         int error = 0;
 63 
 64         if (!kobj)
 65                 return -EINVAL;
 66 
 67         if (kobj->parent)
 68                 parent = kobj->parent->dentry;
 69         else if (sysfs_mount && sysfs_mount->mnt_sb)
 70                 parent = sysfs_mount->mnt_sb->s_root;
 71         else
 72                 return -EFAULT;
 73 
 74         error = create_dir(kobj,parent,kobject_name(kobj),&dentry);
 75         if (!error)
 76                 kobj->dentry = dentry;
 77         return error;
 78 }
 79 
 80 
 81 static void remove_dir(struct dentry * d)
 82 {
 83         struct dentry * parent = dget(d->d_parent);
 84         down(&parent->d_inode->i_sem);
 85         d_delete(d);
 86         simple_rmdir(parent->d_inode,d);
 87 
 88         pr_debug(" o %s removing done (%d)\n",d->d_name.name,
 89                  atomic_read(&d->d_count));
 90 
 91         up(&parent->d_inode->i_sem);
 92         dput(parent);
 93 }
 94 
 95 void sysfs_remove_subdir(struct dentry * d)
 96 {
 97         remove_dir(d);
 98 }
 99 
100 
101 /**
102  *      sysfs_remove_dir - remove an object's directory.
103  *      @kobj:  object. 
104  *
105  *      The only thing special about this is that we remove any files in 
106  *      the directory before we remove the directory, and we've inlined
107  *      what used to be sysfs_rmdir() below, instead of calling separately.
108  */
109 
110 void sysfs_remove_dir(struct kobject * kobj)
111 {
112         struct list_head * node;
113         struct dentry * dentry = dget(kobj->dentry);
114 
115         if (!dentry)
116                 return;
117 
118         pr_debug("sysfs %s: removing dir\n",dentry->d_name.name);
119         down(&dentry->d_inode->i_sem);
120 
121         spin_lock(&dcache_lock);
122         node = dentry->d_subdirs.next;
123         while (node != &dentry->d_subdirs) {
124                 struct dentry * d = list_entry(node,struct dentry,d_child);
125                 list_del_init(node);
126 
127                 pr_debug(" o %s (%d): ",d->d_name.name,atomic_read(&d->d_count));
128                 if (d->d_inode) {
129                         d = dget_locked(d);
130                         pr_debug("removing");
131 
132                         /**
133                          * Unlink and unhash.
134                          */
135                         spin_unlock(&dcache_lock);
136                         d_delete(d);
137                         simple_unlink(dentry->d_inode,d);
138                         dput(d);
139                         spin_lock(&dcache_lock);
140                 }
141                 pr_debug(" done\n");
142                 node = dentry->d_subdirs.next;
143         }
144         list_del_init(&dentry->d_child);
145         spin_unlock(&dcache_lock);
146         up(&dentry->d_inode->i_sem);
147 
148         remove_dir(dentry);
149         /**
150          * Drop reference from dget() on entrance.
151          */
152         dput(dentry);
153 }
154 
155 void sysfs_rename_dir(struct kobject * kobj, const char *new_name)
156 {
157         struct dentry * new_dentry, * parent;
158 
159         if (!strcmp(kobject_name(kobj), new_name))
160                 return;
161 
162         if (!kobj->parent)
163                 return;
164 
165         parent = kobj->parent->dentry;
166 
167         down(&parent->d_inode->i_sem);
168 
169         new_dentry = sysfs_get_dentry(parent, new_name);
170         d_move(kobj->dentry, new_dentry);
171         kobject_set_name(kobj,new_name);
172         up(&parent->d_inode->i_sem);    
173 }
174 
175 EXPORT_SYMBOL(sysfs_create_dir);
176 EXPORT_SYMBOL(sysfs_remove_dir);
177 EXPORT_SYMBOL(sysfs_rename_dir);
178 
179 

~ [ 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