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