static int lofs_fsync(struct file *file, struct dentry *dentry, int datasync) { int rc = -EINVAL; struct file *lower_file = lofs_file_to_lower(file); struct dentry *lower_dentry = lofs_dentry_to_lower(dentry); struct inode *lower_inode = lower_dentry->d_inode; if (lower_file->f_op && lower_file->f_op->fsync) { LOCK_INODE(lower_inode); rc = lower_file->f_op->fsync(lower_file, lower_dentry, datasync); UNLOCK_INODE(lower_inode); } return rc; }
/* * Create no-name-pipeline. */ BOOL sys_pipe(struct pipe_rw_desc * p_rw) { struct m_inode * p; struct pipe_rw_desc tmp; if(!p_rw) { k_printf("pipe: pipe-structure is NULL."); return FALSE; } /* 分配索引节点和文件表项,失败则退回 */ if(!(p=ialloc(0))) goto pipe_false_ret_1; if(-1 == (tmp.rdesc = find_file_table(p, O_RONLY))) goto pipe_false_ret_2; if(-1 == (tmp.wdesc = find_file_table(p, O_WONLY))) goto pipe_false_ret_3; /* * 对于管道文件,我们将其内存节点引用计数设置为2。 * 实际上这是修改,因为在iget()中,我们已经设置过了。 */ p->count = 2; /* * 将索引节点解锁。注意再次使用时,要先加锁,使用完解锁。 */ UNLOCK_INODE(p); ds2fs_memcpy(p_rw, &tmp, sizeof(struct pipe_rw_desc)); return TRUE; pipe_false_ret_3: current->file[tmp.rdesc]->count = 0; current->file[tmp.rdesc] = NULL; pipe_false_ret_2: ifree(p->dev, p->nrinode); iput(p); pipe_false_ret_1: tmp.rdesc = -1; tmp.wdesc = -1; ds2fs_memcpy(p_rw, &tmp, sizeof(struct pipe_rw_desc)); return FALSE; }
extern ssize_t vnode_shadow_iop_listxattr( struct dentry *dentry, char *name, size_t size ) { DENT_T *rdent; VNODE_T *cvp; ssize_t rsize; #if defined(RATL_SUSE) LOCK_INODE(dentry->d_inode); #endif rdent = REALDENTRY_LOCKED(dentry, &cvp); rsize = vnlayer_do_listxattr(rdent, name, size); REALDENTRY_UNLOCK(dentry, cvp); #if defined(RATL_SUSE) UNLOCK_INODE(dentry->d_inode); #endif return rsize; }
/* This is really VOP_SETATTR() in sheep's clothing */ int vnode_iop_notify_change( DENT_T *dent_p, struct iattr * iattr_p ) { VNODE_T *vp; VATTR_T *vap; VNODE_T *cvp; int err = 0; DENT_T *rdent; CALL_DATA_T cd; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) mdki_boolean_t tooksem = FALSE; #endif if (iattr_p->ia_valid & ATTR_SIZE) { ASSERT_I_SEM_MINE(dent_p->d_inode); } if (MDKI_INOISMVFS(dent_p->d_inode)) { vap = VATTR_ALLOC(); if (vap != NULL) { vnode_iop_iattr2vattr(iattr_p, vap); /* reject attempts to use setattr to change object type */ vap->va_mask &= ~AT_TYPE; mdki_linux_init_call_data(&cd); vp = ITOV(dent_p->d_inode); err = VOP_SETATTR(vp, vap, 0, &cd); err = mdki_errno_unix_to_linux(err); /* Any underlying cleartxt got its inode truncated via changeattr * if there's a need to change its size. */ if (!err) mdki_linux_vattr_pullup(vp, vap, vap->va_mask); VATTR_FREE(vap); mdki_linux_destroy_call_data(&cd); } else { err = -ENOMEM; } } else { rdent = REALDENTRY_LOCKED(dent_p, &cvp); VNODE_DGET(rdent); if (rdent && rdent->d_inode) { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) err = inode_setattr(dent_p->d_inode, iattr_p); if (err == 0) { if (iattr_p->ia_valid & ATTR_SIZE) { LOCK_INODE(rdent->d_inode); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) #if !defined RHEL_UPDATE || RHEL_UPDATE < 5 down_write(&rdent->d_inode->i_alloc_sem); #endif #endif /* * be paranoid and record the 'taken'ness in case * the called function squashes ia_valid (as is * done in nfs_setattr). */ tooksem = TRUE; } err = MDKI_NOTIFY_CHANGE(rdent, CVN_TO_VFSMNT(cvp), iattr_p); if (tooksem) { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) #if !defined(RHEL_UPDATE) || RHEL_UPDATE < 5 up_write(&rdent->d_inode->i_alloc_sem); #endif #endif UNLOCK_INODE(rdent->d_inode); } } #else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) */ err = simple_setattr(dent_p, iattr_p); if (err == 0) err = MDKI_NOTIFY_CHANGE(rdent, CVN_TO_VFSMNT(cvp), iattr_p); #endif /* else LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) */ } else { /* It looks as though someone removed the realdentry on us. * I am not sure why this should happen. */ err = -ENOENT; } if (rdent) { VNODE_DPUT(rdent); REALDENTRY_UNLOCK(dent_p, cvp); } } return err; }
/* * 进程根目录和工作目录初始化。 */ void proc_dir_init(unsigned char dev, unsigned int nrinode) { current->root_dir = current->current_dir = iget(dev, nrinode); UNLOCK_INODE(current->root_dir); /* 解锁 */ }