1 /* 2 * linux/fs/ext2/namei.c 3 * 4 * Rewrite to pagecache. Almost all code had been changed, so blame me 5 * if the things go wrong. Please, send bug reports to 6 * viro@parcelfarce.linux.theplanet.co.uk 7 * 8 * Stuff here is basically a glue between the VFS and generic UNIXish 9 * filesystem that keeps everything in pagecache. All knowledge of the 10 * directory layout is in fs/ext2/dir.c - it turned out to be easily separatable 11 * and it's easier to debug that way. In principle we might want to 12 * generalize that a bit and turn it into a library. Or not. 13 * 14 * The only non-static object here is ext2_dir_inode_operations. 15 * 16 * TODO: get rid of kmap() use, add readahead. 17 * 18 * Copyright (C) 1992, 1993, 1994, 1995 19 * Remy Card (card@masi.ibp.fr) 20 * Laboratoire MASI - Institut Blaise Pascal 21 * Universite Pierre et Marie Curie (Paris VI) 22 * 23 * from 24 * 25 * linux/fs/minix/namei.c 26 * 27 * Copyright (C) 1991, 1992 Linus Torvalds 28 * 29 * Big-endian to little-endian byte-swapping/bitmaps by 30 * David S. Miller (davem@caip.rutgers.edu), 1995 31 */ 32 33 #include <linux/pagemap.h> 34 #include "ext2.h" 35 #include "xattr.h" 36 #include "acl.h" 37 38 /* 39 * Couple of helper functions - make the code slightly cleaner. 40 */ 41 42 static inline void ext2_inc_count(struct inode *inode) 43 { 44 inode->i_nlink++; 45 mark_inode_dirty(inode); 46 } 47 48 static inline void ext2_dec_count(struct inode *inode) 49 { 50 inode->i_nlink--; 51 mark_inode_dirty(inode); 52 } 53 54 static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode) 55 { 56 int err = ext2_add_link(dentry, inode); 57 if (!err) { 58 d_instantiate(dentry, inode); 59 return 0; 60 } 61 ext2_dec_count(inode); 62 iput(inode); 63 return err; 64 } 65 66 /* 67 * Methods themselves. 68 */ 69 70 static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd) 71 { 72 struct inode * inode; 73 ino_t ino; 74 75 if (dentry->d_name.len > EXT2_NAME_LEN) 76 return ERR_PTR(-ENAMETOOLONG); 77 78 ino = ext2_inode_by_name(dir, dentry); 79 inode = NULL; 80 if (ino) { 81 inode = iget(dir->i_sb, ino); 82 if (!inode) 83 return ERR_PTR(-EACCES); 84 } 85 if (inode) 86 return d_splice_alias(inode, dentry); 87 d_add(dentry, inode); 88 return NULL; 89 } 90 91 struct dentry *ext2_get_parent(struct dentry *child) 92 { 93 unsigned long ino; 94 struct dentry *parent; 95 struct inode *inode; 96 struct dentry dotdot; 97 98 dotdot.d_name.name = ".."; 99 dotdot.d_name.len = 2; 100 101 ino = ext2_inode_by_name(child->d_inode, &dotdot); 102 if (!ino) 103 return ERR_PTR(-ENOENT); 104 inode = iget(child->d_inode->i_sb, ino); 105 106 if (!inode) 107 return ERR_PTR(-EACCES); 108 parent = d_alloc_anon(inode); 109 if (!parent) { 110 iput(inode); 111 parent = ERR_PTR(-ENOMEM); 112 } 113 return parent; 114 } 115 116 /* 117 * By the time this is called, we already have created 118 * the directory cache entry for the new file, but it 119 * is so far negative - it has no inode. 120 * 121 * If the create succeeds, we fill in the inode information 122 * with d_instantiate(). 123 */ 124 static int ext2_create (struct inode * dir, struct dentry * dentry, int mode, struct nameidata *nd) 125 { 126 struct inode * inode = ext2_new_inode (dir, mode); 127 int err = PTR_ERR(inode); 128 if (!IS_ERR(inode)) { 129 inode->i_op = &ext2_file_inode_operations; 130 inode->i_fop = &ext2_file_operations; 131 if (test_opt(inode->i_sb, NOBH)) 132 inode->i_mapping->a_ops = &ext2_nobh_aops; 133 else 134 inode->i_mapping->a_ops = &ext2_aops; 135 mark_inode_dirty(inode); 136 err = ext2_add_nondir(dentry, inode); 137 } 138 return err; 139 } 140 141 static int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t rdev) 142 { 143 struct inode * inode; 144 int err; 145 146 if (!new_valid_dev(rdev)) 147 return -EINVAL; 148 149 inode = ext2_new_inode (dir, mode); 150 err = PTR_ERR(inode); 151 if (!IS_ERR(inode)) { 152 init_special_inode(inode, inode->i_mode, rdev); 153 #ifdef CONFIG_EXT2_FS_XATTR 154 inode->i_op = &ext2_special_inode_operations; 155 #endif 156 mark_inode_dirty(inode); 157 err = ext2_add_nondir(dentry, inode); 158 } 159 return err; 160 } 161 162 static int ext2_symlink (struct inode * dir, struct dentry * dentry, 163 const char * symname) 164 { 165 struct super_block * sb = dir->i_sb; 166 int err = -ENAMETOOLONG; 167 unsigned l = strlen(symname)+1; 168 struct inode * inode; 169 170 if (l > sb->s_blocksize) 171 goto out; 172 173 inode = ext2_new_inode (dir, S_IFLNK | S_IRWXUGO); 174 err = PTR_ERR(inode); 175 if (IS_ERR(inode)) 176 goto out; 177 178 if (l > sizeof (EXT2_I(inode)->i_data)) { 179 /* slow symlink */ 180 inode->i_op = &ext2_symlink_inode_operations; 181 if (test_opt(inode->i_sb, NOBH)) 182 inode->i_mapping->a_ops = &ext2_nobh_aops; 183 else 184 inode->i_mapping->a_ops = &ext2_aops; 185 err = page_symlink(inode, symname, l); 186 if (err) 187 goto out_fail; 188 } else { 189 /* fast symlink */ 190 inode->i_op = &ext2_fast_symlink_inode_operations; 191 memcpy((char*)(EXT2_I(inode)->i_data),symname,l); 192 inode->i_size = l-1; 193 } 194 mark_inode_dirty(inode); 195 196 err = ext2_add_nondir(dentry, inode); 197 out: 198 return err; 199 200 out_fail: 201 ext2_dec_count(inode); 202 iput (inode); 203 goto out; 204 } 205 206 static int ext2_link (struct dentry * old_dentry, struct inode * dir, 207 struct dentry *dentry) 208 { 209 struct inode *inode = old_dentry->d_inode; 210 211 if (inode->i_nlink >= EXT2_LINK_MAX) 212 return -EMLINK; 213 214 inode->i_ctime = CURRENT_TIME_SEC; 215 ext2_inc_count(inode); 216 atomic_inc(&inode->i_count); 217 218 return ext2_add_nondir(dentry, inode); 219 } 220 221 static int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode) 222 { 223 struct inode * inode; 224 int err = -EMLINK; 225 226 if (dir->i_nlink >= EXT2_LINK_MAX) 227 goto out; 228 229 ext2_inc_count(dir); 230 231 inode = ext2_new_inode (dir, S_IFDIR | mode); 232 err = PTR_ERR(inode); 233 if (IS_ERR(inode)) 234 goto out_dir; 235 236 inode->i_op = &ext2_dir_inode_operations; 237 inode->i_fop = &ext2_dir_operations; 238 if (test_opt(inode->i_sb, NOBH)) 239 inode->i_mapping->a_ops = &ext2_nobh_aops; 240 else 241 inode->i_mapping->a_ops = &ext2_aops; 242 243 ext2_inc_count(inode); 244 245 err = ext2_make_empty(inode, dir); 246 if (err) 247 goto out_fail; 248 249 err = ext2_add_link(dentry, inode); 250 if (err) 251 goto out_fail; 252 253 d_instantiate(dentry, inode); 254 out: 255 return err; 256 257 out_fail: 258 ext2_dec_count(inode); 259 ext2_dec_count(inode); 260 iput(inode); 261 out_dir: 262 ext2_dec_count(dir); 263 goto out; 264 } 265 266 static int ext2_unlink(struct inode * dir, struct dentry *dentry) 267 { 268 struct inode * inode = dentry->d_inode; 269 struct ext2_dir_entry_2 * de; 270 struct page * page; 271 int err = -ENOENT; 272 273 de = ext2_find_entry (dir, dentry, &page); 274 if (!de) 275 goto out; 276 277 err = ext2_delete_entry (de, page); 278 if (err) 279 goto out; 280 281 inode->i_ctime = dir->i_ctime; 282 ext2_dec_count(inode); 283 err = 0; 284 out: 285 return err; 286 } 287 288 static int ext2_rmdir (struct inode * dir, struct dentry *dentry) 289 { 290 struct inode * inode = dentry->d_inode; 291 int err = -ENOTEMPTY; 292 293 if (ext2_empty_dir(inode)) { 294 err = ext2_unlink(dir, dentry); 295 if (!err) { 296 inode->i_size = 0; 297 ext2_dec_count(inode); 298 ext2_dec_count(dir); 299 } 300 } 301 return err; 302 } 303 304 static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry, 305 struct inode * new_dir, struct dentry * new_dentry ) 306 { 307 struct inode * old_inode = old_dentry->d_inode; 308 struct inode * new_inode = new_dentry->d_inode; 309 struct page * dir_page = NULL; 310 struct ext2_dir_entry_2 * dir_de = NULL; 311 struct page * old_page; 312 struct ext2_dir_entry_2 * old_de; 313 int err = -ENOENT; 314 315 old_de = ext2_find_entry (old_dir, old_dentry, &old_page); 316 if (!old_de) 317 goto out; 318 319 if (S_ISDIR(old_inode->i_mode)) { 320 err = -EIO; 321 dir_de = ext2_dotdot(old_inode, &dir_page); 322 if (!dir_de) 323 goto out_old; 324 } 325 326 if (new_inode) { 327 struct page *new_page; 328 struct ext2_dir_entry_2 *new_de; 329 330 err = -ENOTEMPTY; 331 if (dir_de && !ext2_empty_dir (new_inode)) 332 goto out_dir; 333 334 err = -ENOENT; 335 new_de = ext2_find_entry (new_dir, new_dentry, &new_page); 336 if (!new_de) 337 goto out_dir; 338 ext2_inc_count(old_inode); 339 ext2_set_link(new_dir, new_de, new_page, old_inode); 340 new_inode->i_ctime = CURRENT_TIME_SEC; 341 if (dir_de) 342 new_inode->i_nlink--; 343 ext2_dec_count(new_inode); 344 } else { 345 if (dir_de) { 346 err = -EMLINK; 347 if (new_dir->i_nlink >= EXT2_LINK_MAX) 348 goto out_dir; 349 } 350 ext2_inc_count(old_inode); 351 err = ext2_add_link(new_dentry, old_inode); 352 if (err) { 353 ext2_dec_count(old_inode); 354 goto out_dir; 355 } 356 if (dir_de) 357 ext2_inc_count(new_dir); 358 } 359 360 /* 361 * Like most other Unix systems, set the ctime for inodes on a 362 * rename. 363 * ext2_dec_count() will mark the inode dirty. 364 */ 365 old_inode->i_ctime = CURRENT_TIME_SEC; 366 367 ext2_delete_entry (old_de, old_page); 368 ext2_dec_count(old_inode); 369 370 if (dir_de) { 371 ext2_set_link(old_inode, dir_de, dir_page, new_dir); 372 ext2_dec_count(old_dir); 373 } 374 return 0; 375 376 377 out_dir: 378 if (dir_de) { 379 kunmap(dir_page); 380 page_cache_release(dir_page); 381 } 382 out_old: 383 kunmap(old_page); 384 page_cache_release(old_page); 385 out: 386 return err; 387 } 388 389 struct inode_operations ext2_dir_inode_operations = { 390 .create = ext2_create, 391 .lookup = ext2_lookup, 392 .link = ext2_link, 393 .unlink = ext2_unlink, 394 .symlink = ext2_symlink, 395 .mkdir = ext2_mkdir, 396 .rmdir = ext2_rmdir, 397 .mknod = ext2_mknod, 398 .rename = ext2_rename, 399 #ifdef CONFIG_EXT2_FS_XATTR 400 .setxattr = generic_setxattr, 401 .getxattr = generic_getxattr, 402 .listxattr = ext2_listxattr, 403 .removexattr = generic_removexattr, 404 #endif 405 .setattr = ext2_setattr, 406 .permission = ext2_permission, 407 }; 408 409 struct inode_operations ext2_special_inode_operations = { 410 #ifdef CONFIG_EXT2_FS_XATTR 411 .setxattr = generic_setxattr, 412 .getxattr = generic_getxattr, 413 .listxattr = ext2_listxattr, 414 .removexattr = generic_removexattr, 415 #endif 416 .setattr = ext2_setattr, 417 .permission = ext2_permission, 418 }; 419