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

TOMOYO Linux Cross Reference
Linux/fs/minix/namei.c

Version: ~ [ linux-5.5-rc7 ] ~ [ linux-5.4.13 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.97 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.166 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.210 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.210 ] ~ [ 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.81 ] ~ [ 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-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ 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 // SPDX-License-Identifier: GPL-2.0
  2 /*
  3  *  linux/fs/minix/namei.c
  4  *
  5  *  Copyright (C) 1991, 1992  Linus Torvalds
  6  */
  7 
  8 #include "minix.h"
  9 
 10 static int add_nondir(struct dentry *dentry, struct inode *inode)
 11 {
 12         int err = minix_add_link(dentry, inode);
 13         if (!err) {
 14                 d_instantiate(dentry, inode);
 15                 return 0;
 16         }
 17         inode_dec_link_count(inode);
 18         iput(inode);
 19         return err;
 20 }
 21 
 22 static struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry, unsigned int flags)
 23 {
 24         struct inode * inode = NULL;
 25         ino_t ino;
 26 
 27         if (dentry->d_name.len > minix_sb(dir->i_sb)->s_namelen)
 28                 return ERR_PTR(-ENAMETOOLONG);
 29 
 30         ino = minix_inode_by_name(dentry);
 31         if (ino)
 32                 inode = minix_iget(dir->i_sb, ino);
 33         return d_splice_alias(inode, dentry);
 34 }
 35 
 36 static int minix_mknod(struct inode * dir, struct dentry *dentry, umode_t mode, dev_t rdev)
 37 {
 38         int error;
 39         struct inode *inode;
 40 
 41         if (!old_valid_dev(rdev))
 42                 return -EINVAL;
 43 
 44         inode = minix_new_inode(dir, mode, &error);
 45 
 46         if (inode) {
 47                 minix_set_inode(inode, rdev);
 48                 mark_inode_dirty(inode);
 49                 error = add_nondir(dentry, inode);
 50         }
 51         return error;
 52 }
 53 
 54 static int minix_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
 55 {
 56         int error;
 57         struct inode *inode = minix_new_inode(dir, mode, &error);
 58         if (inode) {
 59                 minix_set_inode(inode, 0);
 60                 mark_inode_dirty(inode);
 61                 d_tmpfile(dentry, inode);
 62         }
 63         return error;
 64 }
 65 
 66 static int minix_create(struct inode *dir, struct dentry *dentry, umode_t mode,
 67                 bool excl)
 68 {
 69         return minix_mknod(dir, dentry, mode, 0);
 70 }
 71 
 72 static int minix_symlink(struct inode * dir, struct dentry *dentry,
 73           const char * symname)
 74 {
 75         int err = -ENAMETOOLONG;
 76         int i = strlen(symname)+1;
 77         struct inode * inode;
 78 
 79         if (i > dir->i_sb->s_blocksize)
 80                 goto out;
 81 
 82         inode = minix_new_inode(dir, S_IFLNK | 0777, &err);
 83         if (!inode)
 84                 goto out;
 85 
 86         minix_set_inode(inode, 0);
 87         err = page_symlink(inode, symname, i);
 88         if (err)
 89                 goto out_fail;
 90 
 91         err = add_nondir(dentry, inode);
 92 out:
 93         return err;
 94 
 95 out_fail:
 96         inode_dec_link_count(inode);
 97         iput(inode);
 98         goto out;
 99 }
100 
101 static int minix_link(struct dentry * old_dentry, struct inode * dir,
102         struct dentry *dentry)
103 {
104         struct inode *inode = d_inode(old_dentry);
105 
106         inode->i_ctime = current_time(inode);
107         inode_inc_link_count(inode);
108         ihold(inode);
109         return add_nondir(dentry, inode);
110 }
111 
112 static int minix_mkdir(struct inode * dir, struct dentry *dentry, umode_t mode)
113 {
114         struct inode * inode;
115         int err;
116 
117         inode_inc_link_count(dir);
118 
119         inode = minix_new_inode(dir, S_IFDIR | mode, &err);
120         if (!inode)
121                 goto out_dir;
122 
123         minix_set_inode(inode, 0);
124 
125         inode_inc_link_count(inode);
126 
127         err = minix_make_empty(inode, dir);
128         if (err)
129                 goto out_fail;
130 
131         err = minix_add_link(dentry, inode);
132         if (err)
133                 goto out_fail;
134 
135         d_instantiate(dentry, inode);
136 out:
137         return err;
138 
139 out_fail:
140         inode_dec_link_count(inode);
141         inode_dec_link_count(inode);
142         iput(inode);
143 out_dir:
144         inode_dec_link_count(dir);
145         goto out;
146 }
147 
148 static int minix_unlink(struct inode * dir, struct dentry *dentry)
149 {
150         int err = -ENOENT;
151         struct inode * inode = d_inode(dentry);
152         struct page * page;
153         struct minix_dir_entry * de;
154 
155         de = minix_find_entry(dentry, &page);
156         if (!de)
157                 goto end_unlink;
158 
159         err = minix_delete_entry(de, page);
160         if (err)
161                 goto end_unlink;
162 
163         inode->i_ctime = dir->i_ctime;
164         inode_dec_link_count(inode);
165 end_unlink:
166         return err;
167 }
168 
169 static int minix_rmdir(struct inode * dir, struct dentry *dentry)
170 {
171         struct inode * inode = d_inode(dentry);
172         int err = -ENOTEMPTY;
173 
174         if (minix_empty_dir(inode)) {
175                 err = minix_unlink(dir, dentry);
176                 if (!err) {
177                         inode_dec_link_count(dir);
178                         inode_dec_link_count(inode);
179                 }
180         }
181         return err;
182 }
183 
184 static int minix_rename(struct inode * old_dir, struct dentry *old_dentry,
185                         struct inode * new_dir, struct dentry *new_dentry,
186                         unsigned int flags)
187 {
188         struct inode * old_inode = d_inode(old_dentry);
189         struct inode * new_inode = d_inode(new_dentry);
190         struct page * dir_page = NULL;
191         struct minix_dir_entry * dir_de = NULL;
192         struct page * old_page;
193         struct minix_dir_entry * old_de;
194         int err = -ENOENT;
195 
196         if (flags & ~RENAME_NOREPLACE)
197                 return -EINVAL;
198 
199         old_de = minix_find_entry(old_dentry, &old_page);
200         if (!old_de)
201                 goto out;
202 
203         if (S_ISDIR(old_inode->i_mode)) {
204                 err = -EIO;
205                 dir_de = minix_dotdot(old_inode, &dir_page);
206                 if (!dir_de)
207                         goto out_old;
208         }
209 
210         if (new_inode) {
211                 struct page * new_page;
212                 struct minix_dir_entry * new_de;
213 
214                 err = -ENOTEMPTY;
215                 if (dir_de && !minix_empty_dir(new_inode))
216                         goto out_dir;
217 
218                 err = -ENOENT;
219                 new_de = minix_find_entry(new_dentry, &new_page);
220                 if (!new_de)
221                         goto out_dir;
222                 minix_set_link(new_de, new_page, old_inode);
223                 new_inode->i_ctime = current_time(new_inode);
224                 if (dir_de)
225                         drop_nlink(new_inode);
226                 inode_dec_link_count(new_inode);
227         } else {
228                 err = minix_add_link(new_dentry, old_inode);
229                 if (err)
230                         goto out_dir;
231                 if (dir_de)
232                         inode_inc_link_count(new_dir);
233         }
234 
235         minix_delete_entry(old_de, old_page);
236         mark_inode_dirty(old_inode);
237 
238         if (dir_de) {
239                 minix_set_link(dir_de, dir_page, new_dir);
240                 inode_dec_link_count(old_dir);
241         }
242         return 0;
243 
244 out_dir:
245         if (dir_de) {
246                 kunmap(dir_page);
247                 put_page(dir_page);
248         }
249 out_old:
250         kunmap(old_page);
251         put_page(old_page);
252 out:
253         return err;
254 }
255 
256 /*
257  * directories can handle most operations...
258  */
259 const struct inode_operations minix_dir_inode_operations = {
260         .create         = minix_create,
261         .lookup         = minix_lookup,
262         .link           = minix_link,
263         .unlink         = minix_unlink,
264         .symlink        = minix_symlink,
265         .mkdir          = minix_mkdir,
266         .rmdir          = minix_rmdir,
267         .mknod          = minix_mknod,
268         .rename         = minix_rename,
269         .getattr        = minix_getattr,
270         .tmpfile        = minix_tmpfile,
271 };
272 

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