/* * BKL held by caller. * dentry->d_inode->i_{sem,mutex} down */ STATIC int base0fs_removexattr(struct dentry *dentry, const char *name) { struct dentry *lower_dentry = NULL; int err = -ENOTSUPP; char *encoded_name; print_entry_location(); lower_dentry = DENTRY_TO_LOWER(dentry); BUG_ON(!lower_dentry); BUG_ON(!lower_dentry->d_inode); BUG_ON(!lower_dentry->d_inode->i_op); fist_dprint(18, "removexattr: name=\"%s\"\n", name); if (lower_dentry->d_inode->i_op->removexattr) { encoded_name = (char *)name; lock_inode(lower_dentry->d_inode); /* lock_kernel() already done by caller. */ err = lower_dentry->d_inode->i_op->removexattr(lower_dentry, encoded_name); /* unlock_kernel() will be done by caller. */ unlock_inode(lower_dentry->d_inode); } out: print_exit_status(err); return err; }
/* * BKL held by caller. * dentry->d_inode->i_{sem,mutex} down */ STATIC ssize_t base0fs_listxattr(struct dentry *dentry, char *list, size_t size) { struct dentry *lower_dentry = NULL; int err = -ENOTSUPP; char *encoded_list = NULL; print_entry_location(); lower_dentry = DENTRY_TO_LOWER(dentry); BUG_ON(!lower_dentry); BUG_ON(!lower_dentry->d_inode); BUG_ON(!lower_dentry->d_inode->i_op); if (lower_dentry->d_inode->i_op->listxattr) { encoded_list = list; lock_inode(lower_dentry->d_inode); /* lock_kernel() already done by caller. */ err = lower_dentry->d_inode->i_op->listxattr(lower_dentry, encoded_list, size); /* unlock_kernel() will be done by caller. */ unlock_inode(lower_dentry->d_inode); } out: print_exit_status(err); return err; }
static void read_inode(register struct inode *inode) { register struct super_block *sb = inode->i_sb; register struct super_operations *sop = sb->s_op; lock_inode(inode); if (sb && sop && sop->read_inode) sop->read_inode(inode); unlock_inode(inode); }
static void read_inode(register struct inode *inode) { struct super_block *sb = inode->i_sb; register struct super_operations *sop; lock_inode(inode); if (sb && (sop = sb->s_op) && sop->read_inode) { sop->read_inode(inode); if (inode->i_op == NULL) set_ops(inode); } unlock_inode(inode); }
void gs_later_ttl() { register Inodenum i; register Inode * ip; for (i = 1, ip = Inode_table + 1; i < Superblock.s_numinodes; i++, ip++) { /* Have a peek .... */ if ( GLOBAL_TTL(i)==L_UNKNOWN && ip->i_flags&I_INUSE ) { /* We have an unknown global ttl and a file. The file must * have been unknown thus far. */ lock_inode(i,L_READ) ; if ( ip->i_flags&I_INUSE ) { /* The file is still there, set its lifetime */ gs_set_ttl(i) ; } unlock_inode(i); } } gs_age_sweep() ; }
void gs_first_ttl() { register Inodenum i; register Inode * ip; if ( !init_done ) { bwarn("awkward lifetime initialize"); } for (i = 1, ip = Inode_table + 1; i < Superblock.s_numinodes; i++, ip++) { /* Have a peek .... */ if ( ip->i_flags&I_INUSE ) { lock_inode(i,L_READ) ; if ( ip->i_flags&I_INUSE ) { /* The file is still there, set its lifetime */ SET_LOCAL_TTL(i,MAX_LIFETIME) ; SET_GLOBAL_TTL(i,MAX_LIFETIME) ; } unlock_inode(i); } } }
/* * BKL held by caller. * dentry->d_inode->i_{sem,mutex} down */ STATIC ssize_t base0fs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size) { struct dentry *lower_dentry = NULL; int err = -ENOTSUPP; /* Define these anyway so we don't need as much ifdef'ed code. */ char *encoded_name = NULL; char *encoded_value = NULL; print_entry_location(); lower_dentry = DENTRY_TO_LOWER(dentry); BUG_ON(!lower_dentry); BUG_ON(!lower_dentry->d_inode); BUG_ON(!lower_dentry->d_inode->i_op); fist_dprint(18, "getxattr: name=\"%s\", value %d bytes\n", name, (int) size); if (lower_dentry->d_inode->i_op->getxattr) { encoded_name = (char *)name; encoded_value = (char *)value; lock_inode(lower_dentry->d_inode); /* lock_kernel() already done by caller. */ err = lower_dentry->d_inode->i_op->getxattr(lower_dentry, encoded_name, encoded_value, size); /* unlock_kernel() will be done by caller. */ unlock_inode(lower_dentry->d_inode); } out: print_exit_status(err); return err; }
static void build_free_list() { Inodenum i; Inode * ip; disk_addr addr; b_fsize size; disk_addr numblocks; for (ip = Inode_table+1, i = 1; i < Superblock.s_numinodes; ip++, i++) { #ifndef USER_LEVEL /* * Because we might run for a long time we should give the * interrupt queue a chance to drain by rescheduling ourselves * after each 2048 inodes */ if (!(i & 2047)) threadswitch(); #endif if (ip->i_flags&I_INUSE) /* then inode in use */ { addr = ip->i_dskaddr; DEC_DISK_ADDR_BE(&addr); size = ip->i_size; DEC_FILE_SIZE_BE(&size); if (size > Largest_file_size) { bwarn("build_free_list: inode %ld too big for cache: size = %ld", i, size); } /* empty or not present file has no disk blocks and is ok */ if (size != 0 ) { if (ip->i_flags&I_BUSY) { ip->i_flags &= ~I_BUSY ; /* Incore only flag */ } if (ip->i_flags&I_PRESENT) { if ( ip->i_flags&I_INTENT ) { /* On disk inode without file contents. Destroy. */ bwarn("destroying premature inode %ld",i) ; lock_inode(i, L_WRITE); destroy_inode(i,0,ANN_NEVER,SEND_CANWAIT); continue ; } numblocks = NUMBLKS(size); if (addr <= Superblock.s_inodetop || addr > Superblock.s_numblocks || size < 0 || addr + numblocks > Superblock.s_numblocks) { bwarn("build_free_list: Clearing contents of bad inode %ld, size %ld, addr %ld", i, size, addr); lock_inode(i, L_WRITE); destroy_contents(i,0); } else /* inode is valid, put resources on in-use lists */ { if (a_used(A_DISKBLOCKS, (Res_addr) addr, (Res_size) numblocks) < 0) { bwarn("build_free_list: Duplicate block(s). Contents of node %ld removed", i); lock_inode(i, L_WRITE); destroy_contents(i,0); } } } } else /* disk address should be null since no blocks! */ if (addr != 0) { bwarn("build_free_list: Clearing contents of bad empty file %ld, size %ld, addr %ld", i, size, addr); lock_inode(i, L_WRITE); destroy_contents(i,0); } } } /* end for */ if (a_high_fragmentation(A_DISKBLOCKS)) bwarn("heavy disk fragmentation"); }
void scribe_lock_inode_write_nested(struct inode *inode) { lock_inode(inode, SCRIBE_WRITE | SCRIBE_NESTED); }
void scribe_lock_inode_write(struct inode *inode) { lock_inode(inode, SCRIBE_WRITE); }
void scribe_lock_inode_read(struct inode *inode) { lock_inode(inode, SCRIBE_READ); }
/* * Locking the parent is needed to: * - serialize directory operations * - make sure the parent doesn't change from * under us in the middle of an operation. * * NOTE! Right now we'd rather use a "struct inode" * for this, but as I expect things to move toward * using dentries instead for most things it is * probably better to start with the conceptually * better interface of relying on a path of dentries. */ static inline struct dentry *base0fs_lock_parent(struct dentry *dentry) { struct dentry *dir = dget(dentry->d_parent); lock_inode(dir->d_inode); return dir; }
STATIC struct dentry * base0fs_lookup(inode_t *dir, struct dentry *dentry, struct nameidata* nd_unused_in_this_fxn /* XXX: fix code if ever used */ ) { int err = 0; struct dentry *lower_dir_dentry; struct dentry *lower_dentry = NULL; struct vfsmount *lower_mount; const char *name; vnode_t *this_vnode; struct dentry *this_dir; unsigned int namelen; print_entry_location(); lower_dir_dentry = base0fs_lower_dentry(dentry->d_parent); /* CPW: Moved below print_entry_location */ name = dentry->d_name.name; namelen = dentry->d_name.len; fist_checkinode(dir, "base0fs_lookup"); this_vnode = dir; this_dir = lower_dir_dentry; fist_print_dentry("base0fs_lookup IN", dentry); fist_print_dentry("base0fs_lookup: dentry->d_parent IN", dentry->d_parent); fist_print_dentry("base0fs_lookup: lower_dir_dentry IN", lower_dir_dentry); fist_print_inode("base0fs_lookup: dir IN", dir); if (lower_dir_dentry->d_inode) fist_print_inode("base0fs_lookup: lower_dir_dentry->d_inode", lower_dir_dentry->d_inode); /* must initialize dentry operations */ dentry->d_op = &base0fs_dops; ; /* increase refcount of base dentry (lookup_one[_len] will decrement) */ // THIS IS RIGHT! (don't "fix" it) // NO THIS IS WRONG IN 2.3.99-pre6. lookup_one[_len] will NOT decrement // dget(lower_dir_dentry); lock_inode(lower_dir_dentry->d_inode); /* will allocate a new lower dentry if needed */ lower_dentry = lookup_one_len(name, lower_dir_dentry, namelen); unlock_inode(lower_dir_dentry->d_inode); if (IS_ERR(lower_dentry)) { /* * this produces an unusual dentry: one that has neither an * inode, nor a private structure attached to it. All cleanup * methods (d_delete, d_release, etc) must be prepared to deal * with such dentries. Ion 09/29/2001 */ err = PTR_ERR(lower_dentry); goto out; } lower_mount = mntget(DENTRY_TO_LVFSMNT(dentry->d_parent)); ; if (lower_dentry->d_inode && lower_dentry->d_inode->i_sb) { struct super_block *lower_sb = lower_dentry->d_inode->i_sb; if (lower_sb->s_dev == sProcDev || lower_sb->s_dev == sDevDev) { d_drop(dentry); /* Don't leak our dentry. */ return lower_dentry; } } /* update parent directory's atime */ fist_copy_attr_atime(dir, lower_dir_dentry->d_inode); /* link the upper and lower dentries */ DENTRY_TO_PRIVATE_SM(dentry) = (struct base0fs_dentry_info *) KMALLOC(sizeof(struct base0fs_dentry_info), GFP_KERNEL); if (!DENTRY_TO_PRIVATE(dentry)) { err = -ENOMEM; goto out_dput; } DENTRY_TO_PRIVATE(dentry)->wdi_dentry = lower_dentry; DENTRY_TO_PRIVATE(dentry)->wdi_mnt = lower_mount; /* lookup is special: it needs to handle negative dentries */ if (!lower_dentry->d_inode) { d_add(dentry, NULL); fist_print_dentry("base0fs_lookup OUT lower_dentry", lower_dentry); goto out; } fist_dprint(6, "lookup \"%s\" -> inode %lu\n", name, lower_dentry->d_inode->i_ino); err = base0fs_interpose(lower_dentry, dentry, dir->i_sb, 1); if (err) goto out_free; fist_checkinode(dentry->d_inode, "base0fs_lookup OUT: dentry->d_inode:"); fist_checkinode(dir, "base0fs_lookup OUT: dir"); fist_print_dentry("base0fs_lookup OUT lower_dentry", lower_dentry); fist_print_inode("base0fs_lookup OUT lower_inode", lower_dentry->d_inode); /* All is well */ goto out; out_free: d_drop(dentry); /* so that our bad dentry will get destroyed */ KFREE(DENTRY_TO_PRIVATE(dentry)); DENTRY_TO_PRIVATE_SM(dentry) = NULL; /* be safe */ out_dput: if (lower_dentry) dput(lower_dentry); out: fist_print_dentry("base0fs_lookup OUT", dentry); print_exit_status(err); return ERR_PTR(err); }