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