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

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

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ 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 ] ~

  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 mnt_idmap *idmap, struct inode *dir,
 37                        struct dentry *dentry, umode_t mode, dev_t rdev)
 38 {
 39         struct inode *inode;
 40 
 41         if (!old_valid_dev(rdev))
 42                 return -EINVAL;
 43 
 44         inode = minix_new_inode(dir, mode);
 45         if (IS_ERR(inode))
 46                 return PTR_ERR(inode);
 47 
 48         minix_set_inode(inode, rdev);
 49         mark_inode_dirty(inode);
 50         return add_nondir(dentry, inode);
 51 }
 52 
 53 static int minix_tmpfile(struct mnt_idmap *idmap, struct inode *dir,
 54                          struct file *file, umode_t mode)
 55 {
 56         struct inode *inode = minix_new_inode(dir, mode);
 57 
 58         if (IS_ERR(inode))
 59                 return finish_open_simple(file, PTR_ERR(inode));
 60         minix_set_inode(inode, 0);
 61         mark_inode_dirty(inode);
 62         d_tmpfile(file, inode);
 63         return finish_open_simple(file, 0);
 64 }
 65 
 66 static int minix_create(struct mnt_idmap *idmap, struct inode *dir,
 67                         struct dentry *dentry, umode_t mode, bool excl)
 68 {
 69         return minix_mknod(&nop_mnt_idmap, dir, dentry, mode, 0);
 70 }
 71 
 72 static int minix_symlink(struct mnt_idmap *idmap, struct inode *dir,
 73                          struct dentry *dentry, const char *symname)
 74 {
 75         int i = strlen(symname)+1;
 76         struct inode * inode;
 77         int err;
 78 
 79         if (i > dir->i_sb->s_blocksize)
 80                 return -ENAMETOOLONG;
 81 
 82         inode = minix_new_inode(dir, S_IFLNK | 0777);
 83         if (IS_ERR(inode))
 84                 return PTR_ERR(inode);
 85 
 86         minix_set_inode(inode, 0);
 87         err = page_symlink(inode, symname, i);
 88         if (unlikely(err)) {
 89                 inode_dec_link_count(inode);
 90                 iput(inode);
 91                 return err;
 92         }
 93         return add_nondir(dentry, inode);
 94 }
 95 
 96 static int minix_link(struct dentry * old_dentry, struct inode * dir,
 97         struct dentry *dentry)
 98 {
 99         struct inode *inode = d_inode(old_dentry);
100 
101         inode_set_ctime_current(inode);
102         inode_inc_link_count(inode);
103         ihold(inode);
104         return add_nondir(dentry, inode);
105 }
106 
107 static int minix_mkdir(struct mnt_idmap *idmap, struct inode *dir,
108                        struct dentry *dentry, umode_t mode)
109 {
110         struct inode * inode;
111         int err;
112 
113         inode = minix_new_inode(dir, S_IFDIR | mode);
114         if (IS_ERR(inode))
115                 return PTR_ERR(inode);
116 
117         inode_inc_link_count(dir);
118         minix_set_inode(inode, 0);
119         inode_inc_link_count(inode);
120 
121         err = minix_make_empty(inode, dir);
122         if (err)
123                 goto out_fail;
124 
125         err = minix_add_link(dentry, inode);
126         if (err)
127                 goto out_fail;
128 
129         d_instantiate(dentry, inode);
130 out:
131         return err;
132 
133 out_fail:
134         inode_dec_link_count(inode);
135         inode_dec_link_count(inode);
136         iput(inode);
137         inode_dec_link_count(dir);
138         goto out;
139 }
140 
141 static int minix_unlink(struct inode * dir, struct dentry *dentry)
142 {
143         struct inode * inode = d_inode(dentry);
144         struct page * page;
145         struct minix_dir_entry * de;
146         int err;
147 
148         de = minix_find_entry(dentry, &page);
149         if (!de)
150                 return -ENOENT;
151         err = minix_delete_entry(de, page);
152         unmap_and_put_page(page, de);
153 
154         if (err)
155                 return err;
156         inode_set_ctime_to_ts(inode, inode_get_ctime(dir));
157         inode_dec_link_count(inode);
158         return 0;
159 }
160 
161 static int minix_rmdir(struct inode * dir, struct dentry *dentry)
162 {
163         struct inode * inode = d_inode(dentry);
164         int err = -ENOTEMPTY;
165 
166         if (minix_empty_dir(inode)) {
167                 err = minix_unlink(dir, dentry);
168                 if (!err) {
169                         inode_dec_link_count(dir);
170                         inode_dec_link_count(inode);
171                 }
172         }
173         return err;
174 }
175 
176 static int minix_rename(struct mnt_idmap *idmap,
177                         struct inode *old_dir, struct dentry *old_dentry,
178                         struct inode *new_dir, struct dentry *new_dentry,
179                         unsigned int flags)
180 {
181         struct inode * old_inode = d_inode(old_dentry);
182         struct inode * new_inode = d_inode(new_dentry);
183         struct page * dir_page = NULL;
184         struct minix_dir_entry * dir_de = NULL;
185         struct page * old_page;
186         struct minix_dir_entry * old_de;
187         int err = -ENOENT;
188 
189         if (flags & ~RENAME_NOREPLACE)
190                 return -EINVAL;
191 
192         old_de = minix_find_entry(old_dentry, &old_page);
193         if (!old_de)
194                 goto out;
195 
196         if (S_ISDIR(old_inode->i_mode)) {
197                 err = -EIO;
198                 dir_de = minix_dotdot(old_inode, &dir_page);
199                 if (!dir_de)
200                         goto out_old;
201         }
202 
203         if (new_inode) {
204                 struct page * new_page;
205                 struct minix_dir_entry * new_de;
206 
207                 err = -ENOTEMPTY;
208                 if (dir_de && !minix_empty_dir(new_inode))
209                         goto out_dir;
210 
211                 err = -ENOENT;
212                 new_de = minix_find_entry(new_dentry, &new_page);
213                 if (!new_de)
214                         goto out_dir;
215                 err = minix_set_link(new_de, new_page, old_inode);
216                 unmap_and_put_page(new_page, new_de);
217                 if (err)
218                         goto out_dir;
219                 inode_set_ctime_current(new_inode);
220                 if (dir_de)
221                         drop_nlink(new_inode);
222                 inode_dec_link_count(new_inode);
223         } else {
224                 err = minix_add_link(new_dentry, old_inode);
225                 if (err)
226                         goto out_dir;
227                 if (dir_de)
228                         inode_inc_link_count(new_dir);
229         }
230 
231         err = minix_delete_entry(old_de, old_page);
232         if (err)
233                 goto out_dir;
234 
235         mark_inode_dirty(old_inode);
236 
237         if (dir_de) {
238                 err = minix_set_link(dir_de, dir_page, new_dir);
239                 if (!err)
240                         inode_dec_link_count(old_dir);
241         }
242 out_dir:
243         if (dir_de)
244                 unmap_and_put_page(dir_page, dir_de);
245 out_old:
246         unmap_and_put_page(old_page, old_de);
247 out:
248         return err;
249 }
250 
251 /*
252  * directories can handle most operations...
253  */
254 const struct inode_operations minix_dir_inode_operations = {
255         .create         = minix_create,
256         .lookup         = minix_lookup,
257         .link           = minix_link,
258         .unlink         = minix_unlink,
259         .symlink        = minix_symlink,
260         .mkdir          = minix_mkdir,
261         .rmdir          = minix_rmdir,
262         .mknod          = minix_mknod,
263         .rename         = minix_rename,
264         .getattr        = minix_getattr,
265         .tmpfile        = minix_tmpfile,
266 };
267 

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