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 int minix_hash(struct dentry *dentry, struct qstr *qstr) 22 { 23 unsigned long hash; 24 int i; 25 const unsigned char *name; 26 27 i = minix_sb(dentry->d_inode->i_sb)->s_namelen; 28 if (i >= qstr->len) 29 return 0; 30 /* Truncate the name in place, avoids having to define a compare 31 function. */ 32 qstr->len = i; 33 name = qstr->name; 34 hash = init_name_hash(); 35 while (i--) 36 hash = partial_name_hash(*name++, hash); 37 qstr->hash = end_name_hash(hash); 38 return 0; 39 } 40 41 struct dentry_operations minix_dentry_operations = { 42 .d_hash = minix_hash, 43 }; 44 45 static struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd) 46 { 47 struct inode * inode = NULL; 48 ino_t ino; 49 50 dentry->d_op = dir->i_sb->s_root->d_op; 51 52 if (dentry->d_name.len > minix_sb(dir->i_sb)->s_namelen) 53 return ERR_PTR(-ENAMETOOLONG); 54 55 ino = minix_inode_by_name(dentry); 56 if (ino) { 57 inode = minix_iget(dir->i_sb, ino); 58 if (IS_ERR(inode)) 59 return ERR_CAST(inode); 60 } 61 d_add(dentry, inode); 62 return NULL; 63 } 64 65 static int minix_mknod(struct inode * dir, struct dentry *dentry, int mode, dev_t rdev) 66 { 67 int error; 68 struct inode *inode; 69 70 if (!old_valid_dev(rdev)) 71 return -EINVAL; 72 73 inode = minix_new_inode(dir, &error); 74 75 if (inode) { 76 inode->i_mode = mode; 77 minix_set_inode(inode, rdev); 78 mark_inode_dirty(inode); 79 error = add_nondir(dentry, inode); 80 } 81 return error; 82 } 83 84 static int minix_create(struct inode * dir, struct dentry *dentry, int mode, 85 struct nameidata *nd) 86 { 87 return minix_mknod(dir, dentry, mode, 0); 88 } 89 90 static int minix_symlink(struct inode * dir, struct dentry *dentry, 91 const char * symname) 92 { 93 int err = -ENAMETOOLONG; 94 int i = strlen(symname)+1; 95 struct inode * inode; 96 97 if (i > dir->i_sb->s_blocksize) 98 goto out; 99 100 inode = minix_new_inode(dir, &err); 101 if (!inode) 102 goto out; 103 104 inode->i_mode = S_IFLNK | 0777; 105 minix_set_inode(inode, 0); 106 err = page_symlink(inode, symname, i); 107 if (err) 108 goto out_fail; 109 110 err = add_nondir(dentry, inode); 111 out: 112 return err; 113 114 out_fail: 115 inode_dec_link_count(inode); 116 iput(inode); 117 goto out; 118 } 119 120 static int minix_link(struct dentry * old_dentry, struct inode * dir, 121 struct dentry *dentry) 122 { 123 struct inode *inode = old_dentry->d_inode; 124 125 if (inode->i_nlink >= minix_sb(inode->i_sb)->s_link_max) 126 return -EMLINK; 127 128 inode->i_ctime = CURRENT_TIME_SEC; 129 inode_inc_link_count(inode); 130 atomic_inc(&inode->i_count); 131 return add_nondir(dentry, inode); 132 } 133 134 static int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode) 135 { 136 struct inode * inode; 137 int err = -EMLINK; 138 139 if (dir->i_nlink >= minix_sb(dir->i_sb)->s_link_max) 140 goto out; 141 142 inode_inc_link_count(dir); 143 144 inode = minix_new_inode(dir, &err); 145 if (!inode) 146 goto out_dir; 147 148 inode->i_mode = S_IFDIR | mode; 149 if (dir->i_mode & S_ISGID) 150 inode->i_mode |= S_ISGID; 151 minix_set_inode(inode, 0); 152 153 inode_inc_link_count(inode); 154 155 err = minix_make_empty(inode, dir); 156 if (err) 157 goto out_fail; 158 159 err = minix_add_link(dentry, inode); 160 if (err) 161 goto out_fail; 162 163 d_instantiate(dentry, inode); 164 out: 165 return err; 166 167 out_fail: 168 inode_dec_link_count(inode); 169 inode_dec_link_count(inode); 170 iput(inode); 171 out_dir: 172 inode_dec_link_count(dir); 173 goto out; 174 } 175 176 static int minix_unlink(struct inode * dir, struct dentry *dentry) 177 { 178 int err = -ENOENT; 179 struct inode * inode = dentry->d_inode; 180 struct page * page; 181 struct minix_dir_entry * de; 182 183 de = minix_find_entry(dentry, &page); 184 if (!de) 185 goto end_unlink; 186 187 err = minix_delete_entry(de, page); 188 if (err) 189 goto end_unlink; 190 191 inode->i_ctime = dir->i_ctime; 192 inode_dec_link_count(inode); 193 end_unlink: 194 return err; 195 } 196 197 static int minix_rmdir(struct inode * dir, struct dentry *dentry) 198 { 199 struct inode * inode = dentry->d_inode; 200 int err = -ENOTEMPTY; 201 202 if (minix_empty_dir(inode)) { 203 err = minix_unlink(dir, dentry); 204 if (!err) { 205 inode_dec_link_count(dir); 206 inode_dec_link_count(inode); 207 } 208 } 209 return err; 210 } 211 212 static int minix_rename(struct inode * old_dir, struct dentry *old_dentry, 213 struct inode * new_dir, struct dentry *new_dentry) 214 { 215 struct minix_sb_info * info = minix_sb(old_dir->i_sb); 216 struct inode * old_inode = old_dentry->d_inode; 217 struct inode * new_inode = new_dentry->d_inode; 218 struct page * dir_page = NULL; 219 struct minix_dir_entry * dir_de = NULL; 220 struct page * old_page; 221 struct minix_dir_entry * old_de; 222 int err = -ENOENT; 223 224 old_de = minix_find_entry(old_dentry, &old_page); 225 if (!old_de) 226 goto out; 227 228 if (S_ISDIR(old_inode->i_mode)) { 229 err = -EIO; 230 dir_de = minix_dotdot(old_inode, &dir_page); 231 if (!dir_de) 232 goto out_old; 233 } 234 235 if (new_inode) { 236 struct page * new_page; 237 struct minix_dir_entry * new_de; 238 239 err = -ENOTEMPTY; 240 if (dir_de && !minix_empty_dir(new_inode)) 241 goto out_dir; 242 243 err = -ENOENT; 244 new_de = minix_find_entry(new_dentry, &new_page); 245 if (!new_de) 246 goto out_dir; 247 inode_inc_link_count(old_inode); 248 minix_set_link(new_de, new_page, old_inode); 249 new_inode->i_ctime = CURRENT_TIME_SEC; 250 if (dir_de) 251 drop_nlink(new_inode); 252 inode_dec_link_count(new_inode); 253 } else { 254 if (dir_de) { 255 err = -EMLINK; 256 if (new_dir->i_nlink >= info->s_link_max) 257 goto out_dir; 258 } 259 inode_inc_link_count(old_inode); 260 err = minix_add_link(new_dentry, old_inode); 261 if (err) { 262 inode_dec_link_count(old_inode); 263 goto out_dir; 264 } 265 if (dir_de) 266 inode_inc_link_count(new_dir); 267 } 268 269 minix_delete_entry(old_de, old_page); 270 inode_dec_link_count(old_inode); 271 272 if (dir_de) { 273 minix_set_link(dir_de, dir_page, new_dir); 274 inode_dec_link_count(old_dir); 275 } 276 return 0; 277 278 out_dir: 279 if (dir_de) { 280 kunmap(dir_page); 281 page_cache_release(dir_page); 282 } 283 out_old: 284 kunmap(old_page); 285 page_cache_release(old_page); 286 out: 287 return err; 288 } 289 290 /* 291 * directories can handle most operations... 292 */ 293 const struct inode_operations minix_dir_inode_operations = { 294 .create = minix_create, 295 .lookup = minix_lookup, 296 .link = minix_link, 297 .unlink = minix_unlink, 298 .symlink = minix_symlink, 299 .mkdir = minix_mkdir, 300 .rmdir = minix_rmdir, 301 .mknod = minix_mknod, 302 .rename = minix_rename, 303 .getattr = minix_getattr, 304 }; 305