ssize_t do_vfsub_write_u(struct file *file, const char __user *ubuf, size_t count, loff_t *ppos) { ssize_t err; LKTRTrace("%.*s, cnt %zu, pos %lld\n", AuDLNPair(file->f_dentry), count, *ppos); lockdep_off(); err = vfs_write(file, ubuf, count, ppos); lockdep_on(); if (err >= 0) au_update_fuse_h_inode(file->f_vfsmnt, file->f_dentry); /*ignore*/ return err; }
long do_vfsub_splice_to(struct file *in, loff_t *ppos, struct pipe_inode_info *pipe, size_t len, unsigned int flags) { long err; LKTRTrace("%.*s, pos %lld, len %zu, 0x%x\n", AuDLNPair(in->f_dentry), *ppos, len, flags); lockdep_off(); err = vfs_splice_to(in, ppos, pipe, len, flags); lockdep_on(); if (err >= 0) au_update_fuse_h_inode(in->f_vfsmnt, in->f_dentry); /*ignore*/ return err; }
int do_vfsub_unlink(struct inode *dir, struct dentry *dentry) { int err; LKTRTrace("i%lu, %.*s\n", dir->i_ino, AuDLNPair(dentry)); IMustLock(dir); /* vfs_unlink() locks inode */ lockdep_off(); err = vfs_unlink(dir, dentry); lockdep_on(); /* dir inode is locked */ if (!err) au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/ return err; }
struct file *vfsub_filp_open(const char *path, int oflags, int mode) { struct file *file; lockdep_off(); file = filp_open(path, oflags /* | __FMODE_NONOTIFY */, mode); lockdep_on(); if (IS_ERR(file)) goto out; vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ out: return file; }
int vfsub_fsync(struct file *file, struct path *path, int datasync) { int err; /* file can be NULL */ lockdep_off(); err = vfs_fsync(file, datasync); lockdep_on(); if (!err) { if (!path) { AuDebugOn(!file); path = &file->f_path; } vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/ } return err; }
static void call_notify_change(void *args) { struct notify_change_args *a = args; struct inode *h_inode; h_inode = a->path->dentry->d_inode; IMustLock(h_inode); *a->errp = -EPERM; if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) { lockdep_off(); *a->errp = notify_change(a->path->dentry, a->ia); lockdep_on(); if (!*a->errp) vfsub_update_h_iattr(a->path, /*did*/NULL); /*ignore*/ } AuTraceErr(*a->errp); }
int vfsub_flush(struct file *file, fl_owner_t id) { int err; err = 0; if (file->f_op && file->f_op->flush) { if (!au_test_nfs(file->f_dentry->d_sb)) err = file->f_op->flush(file, id); else { lockdep_off(); err = file->f_op->flush(file, id); lockdep_on(); } if (!err) vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ } return err; }
int vfsub_rmdir(struct inode *dir, struct path *path) { int err; struct dentry *d; IMustLock(dir); d = path->dentry; path->dentry = d->d_parent; err = security_path_rmdir(path, d); path->dentry = d; if (unlikely(err)) goto out; lockdep_off(); err = vfs_rmdir(dir, path->dentry); lockdep_on(); if (!err) { struct path tmp = { .dentry = path->dentry->d_parent, .mnt = path->mnt }; vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/ } out: return err; } /* ---------------------------------------------------------------------- */ ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count, loff_t *ppos) { ssize_t err; err = vfs_read(file, ubuf, count, ppos); if (err >= 0) vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ return err; }
ssize_t do_vfsub_read_u(struct file *file, char __user *ubuf, size_t count, loff_t *ppos) { ssize_t err; LKTRTrace("%.*s, cnt %zu, pos %lld\n", AuDLNPair(file->f_dentry), count, *ppos); if (0 /*!au_test_nfs(file->f_vfsmnt->mnt_sb)*/) err = vfs_read(file, ubuf, count, ppos); else { lockdep_off(); err = vfs_read(file, ubuf, count, ppos); lockdep_on(); } if (err >= 0) au_update_fuse_h_inode(file->f_vfsmnt, file->f_dentry); /*ignore*/ return err; }
int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path, struct inode **delegated_inode) { int err; struct dentry *d; IMustLock(dir); err = au_test_nlink(d_inode(src_dentry)); if (unlikely(err)) return err; /* we don't call may_linkat() */ d = path->dentry; path->dentry = d->d_parent; err = security_path_link(src_dentry, path, d); path->dentry = d; if (unlikely(err)) goto out; lockdep_off(); err = vfs_link(src_dentry, dir, path->dentry, delegated_inode); lockdep_on(); if (!err) { struct path tmp = *path; int did; /* fuse has different memory inode for the same inumber */ vfsub_update_h_iattr(&tmp, &did); if (did) { tmp.dentry = path->dentry->d_parent; vfsub_update_h_iattr(&tmp, /*did*/NULL); tmp.dentry = src_dentry; vfsub_update_h_iattr(&tmp, /*did*/NULL); } /*ignore*/ } out: return err; }
/** * ubi_io_write_vid_hdr - write a volume identifier header. * @ubi: UBI device description object * @pnum: the physical eraseblock number to write to * @vid_hdr: the volume identifier header to write * * This function writes the volume identifier header described by @vid_hdr to * physical eraseblock @pnum. This function automatically fills the * @vid_hdr->magic and the @vid_hdr->version fields, as well as calculates * header CRC checksum and stores it at vid_hdr->hdr_crc. * * This function returns zero in case of success and a negative error code in * case of failure. If %-EIO is returned, the physical eraseblock probably went * bad. */ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum, struct ubi_vid_hdr *vid_hdr) { int err; uint32_t crc; void *p; dbg_io("write VID header to PEB %d", pnum); ubi_assert(pnum >= 0 && pnum < ubi->peb_count); err = self_check_peb_ec_hdr(ubi, pnum); if (err) return err; vid_hdr->magic = cpu_to_be32(UBI_VID_HDR_MAGIC); vid_hdr->version = UBI_VERSION; crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_VID_HDR_SIZE_CRC); vid_hdr->hdr_crc = cpu_to_be32(crc); err = self_check_vid_hdr(ubi, pnum, vid_hdr); if (err) return err; #ifdef CONFIG_BLB { extern int blb_record_page1(struct ubi_device *ubi, int pnum, struct ubi_vid_hdr *vid_hdr, int); int vol_id = be32_to_cpu(vid_hdr->vol_id); if(vol_id < UBI_INTERNAL_VOL_START) { lockdep_off(); blb_record_page1(ubi, pnum, vid_hdr, 0); lockdep_on(); } } #endif p = (char *)vid_hdr - ubi->vid_hdr_shift; err = ubi_io_write(ubi, p, pnum, ubi->vid_hdr_aloffset, ubi->vid_hdr_alsize); return err; }
/* cf. open.c:do_sys_truncate() and do_sys_ftruncate() */ int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr, struct file *h_file) { int err; struct inode *h_inode; h_inode = h_path->dentry->d_inode; if (!h_file) { err = mnt_want_write(h_path->mnt); if (err) goto out; err = inode_permission(h_inode, MAY_WRITE); if (err) goto out_mnt; err = get_write_access(h_inode); if (err) goto out_mnt; err = break_lease(h_inode, O_WRONLY); if (err) goto out_inode; } err = locks_verify_truncate(h_inode, h_file, length); if (!err) err = security_path_truncate(h_path); if (!err) { lockdep_off(); err = do_truncate(h_path->dentry, length, attr, h_file); lockdep_on(); } out_inode: if (!h_file) put_write_access(h_inode); out_mnt: if (!h_file) mnt_drop_write(h_path->mnt); out: return err; }
int vfsub_sio_rmdir(struct inode *dir, struct path *path) { int err, do_sio, wkq_err; do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE); if (!do_sio) { lockdep_off(); err = vfsub_rmdir(dir, path); lockdep_on(); } else { struct au_vfsub_rmdir_args args = { .errp = &err, .dir = dir, .path = path }; wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args); if (unlikely(wkq_err)) err = wkq_err; } return err; }
static ssize_t do_xino_fwrite(writef_t func, struct file *file, void *buf, size_t size, loff_t *pos) { ssize_t err; mm_segment_t oldfs; lockdep_off(); oldfs = get_fs(); set_fs(KERNEL_DS); do { err = func(file, (const char __user*)buf, size, pos); } while (err == -EAGAIN || err == -EINTR); set_fs(oldfs); lockdep_on(); #if 0 if (err > 0) fsnotify_modify(file->f_dentry); #endif TraceErr(err); return err; }
int do_vfsub_rename(struct inode *src_dir, struct dentry *src_dentry, struct inode *dir, struct dentry *dentry) { int err; LKTRTrace("i%lu, %.*s, i%lu, %.*s\n", src_dir->i_ino, AuDLNPair(src_dentry), dir->i_ino, AuDLNPair(dentry)); IMustLock(dir); IMustLock(src_dir); AuDebugOn(src_dir != dir && !vfsub_is_rename_mutex_locked(dir->i_sb)); lockdep_off(); err = vfs_rename(src_dir, src_dentry, dir, dentry); lockdep_on(); if (!err) { /* dir inode is locked */ au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/ au_update_fuse_h_inode(NULL, src_dentry->d_parent); /*ignore*/ au_update_fuse_h_inode(NULL, src_dentry); /*ignore*/ } return err; }
int do_vfsub_link(struct dentry *src_dentry, struct inode *dir, struct dentry *dentry) { int err; LKTRTrace("%.*s, i%lu, %.*s\n", AuDLNPair(src_dentry), dir->i_ino, AuDLNPair(dentry)); IMustLock(dir); lockdep_off(); err = vfs_link(src_dentry, dir, dentry); lockdep_on(); if (!err) { LKTRTrace("src_i %p, dst_i %p\n", src_dentry->d_inode, dentry->d_inode); /* fuse has different memory inode for the same inumber */ au_update_fuse_h_inode(NULL, src_dentry); /*ignore*/ /* dir inode is locked */ au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/ au_update_fuse_h_inode(NULL, dentry); /*ignore*/ } return err; }
static ssize_t do_xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size, loff_t *pos) { ssize_t err; mm_segment_t oldfs; oldfs = get_fs(); set_fs(KERNEL_DS); lockdep_off(); do { /* todo: signal_pending? */ err = func(file, (const char __user *)buf, size, pos); } while (err == -EAGAIN || err == -EINTR); lockdep_on(); set_fs(oldfs); #if 0 /* reserved for future use */ if (err > 0) fsnotify_modify(file->f_dentry); #endif return err; }
/* * free a single branch */ static void au_br_do_free(struct au_branch *br) { int i; struct au_wbr *wbr; struct au_dykey **key; au_hnotify_fin_br(br); if (br->br_xino.xi_file) fput(br->br_xino.xi_file); mutex_destroy(&br->br_xino.xi_nondir_mtx); AuDebugOn(atomic_read(&br->br_count)); wbr = br->br_wbr; if (wbr) { for (i = 0; i < AuBrWh_Last; i++) dput(wbr->wbr_wh[i]); AuDebugOn(atomic_read(&wbr->wbr_wh_running)); AuRwDestroy(&wbr->wbr_wh_rwsem); } key = br->br_dykey; for (i = 0; i < AuBrDynOp; i++, key++) if (*key) au_dy_put(*key); else break; /* recursive lock, s_umount of branch's */ lockdep_off(); mntput(br->br_mnt); lockdep_on(); kfree(wbr); kfree(br); }
static void call_notify_change(void *args) { struct notify_change_args *a = args; struct inode *h_inode; LKTRTrace("%.*s, ia_valid 0x%x\n", AuDLNPair(a->h_dentry), a->ia->ia_valid); h_inode = a->h_dentry->d_inode; IMustLock(h_inode); *a->errp = -EPERM; if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) { vfsub_ignore(a->vargs); lockdep_off(); *a->errp = notify_change(a->h_dentry, a->ia); lockdep_on(); if (!*a->errp) au_update_fuse_h_inode(NULL, a->h_dentry); /*ignore*/ else vfsub_unignore(a->vargs); au_dbg_hin_list(a->vargs); } AuTraceErr(*a->errp); }
RTDECL(void) RTSpinlockAcquire(RTSPINLOCK Spinlock) { PRTSPINLOCKINTERNAL pThis = (PRTSPINLOCKINTERNAL)Spinlock; RT_ASSERT_PREEMPT_CPUID_VAR(); AssertMsg(pThis && pThis->u32Magic == RTSPINLOCK_MAGIC, ("pThis=%p u32Magic=%08x\n", pThis, pThis ? (int)pThis->u32Magic : 0)); #ifdef CONFIG_PROVE_LOCKING lockdep_off(); #endif if (pThis->fFlags & RTSPINLOCK_FLAGS_INTERRUPT_SAFE) { unsigned long fIntSaved; spin_lock_irqsave(&pThis->Spinlock, fIntSaved); pThis->fIntSaved = fIntSaved; } else spin_lock(&pThis->Spinlock); #ifdef CONFIG_PROVE_LOCKING lockdep_on(); #endif RT_ASSERT_PREEMPT_CPUID_SPIN_ACQUIRED(pThis); }
int ib_umem_odp_get(struct ib_ucontext *context, struct ib_umem *umem) { int ret_val; struct pid *our_pid; struct mm_struct *mm = get_task_mm(current); BUG_ON(!mm); /* Prevent creating ODP MRs in child processes */ rcu_read_lock(); our_pid = get_task_pid(current->group_leader, PIDTYPE_PID); rcu_read_unlock(); put_pid(our_pid); if (context->tgid != our_pid) { ret_val = -EINVAL; goto out_mm; } umem->hugetlb = 0; umem->odp_data = kzalloc(sizeof(*umem->odp_data), GFP_KERNEL); if (!umem->odp_data) { ret_val = -ENOMEM; goto out_mm; } umem->odp_data->umem = umem; mutex_init(&umem->odp_data->umem_mutex); init_completion(&umem->odp_data->notifier_completion); umem->odp_data->page_list = vzalloc(ib_umem_num_pages(umem) * sizeof(*umem->odp_data->page_list)); if (!umem->odp_data->page_list) { ret_val = -ENOMEM; goto out_odp_data; } umem->odp_data->dma_list = vzalloc(ib_umem_num_pages(umem) * sizeof(*umem->odp_data->dma_list)); if (!umem->odp_data->dma_list) { ret_val = -ENOMEM; goto out_page_list; } /* * When using MMU notifiers, we will get a * notification before the "current" task (and MM) is * destroyed. We use the umem_mutex lock to synchronize. */ down_write(&context->umem_mutex); context->odp_mrs_count++; if (likely(ib_umem_start(umem) != ib_umem_end(umem))) rbt_ib_umem_insert(&umem->odp_data->interval_tree, &context->umem_tree); downgrade_write(&context->umem_mutex); if (context->odp_mrs_count == 1) { /* * Note that at this point, no MMU notifier is running * for this context! */ INIT_HLIST_NODE(&context->mn.hlist); context->mn.ops = &ib_umem_notifiers; /* * Lock-dep detects a false positive for mmap_sem vs. * umem_mutex, due to not grasping downgrade_write correctly. */ lockdep_off(); ret_val = mmu_notifier_register(&context->mn, mm); lockdep_on(); if (ret_val) { pr_err("Failed to register mmu_notifier %d\n", ret_val); ret_val = -EBUSY; goto out_mutex; } } up_read(&context->umem_mutex); /* * Note that doing an mmput can cause a notifier for the relevant mm. * If the notifier is called while we hold the umem_mutex, this will * cause a deadlock. Therefore, we release the reference only after we * released the mutex. */ mmput(mm); return 0; out_mutex: up_read(&context->umem_mutex); vfree(umem->odp_data->dma_list); out_page_list: vfree(umem->odp_data->page_list); out_odp_data: kfree(umem->odp_data); out_mm: mmput(mm); return ret_val; }
static int unionfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) { int err = 0; struct dentry *lower_old_dentry = NULL; struct dentry *lower_new_dentry = NULL; struct dentry *lower_dir_dentry = NULL; struct dentry *old_parent, *new_parent; char *name = NULL; bool valid; unionfs_read_lock(old_dentry->d_sb, UNIONFS_SMUTEX_CHILD); old_parent = dget_parent(old_dentry); new_parent = dget_parent(new_dentry); unionfs_double_lock_parents(old_parent, new_parent); unionfs_double_lock_dentry(old_dentry, new_dentry); valid = __unionfs_d_revalidate(old_dentry, old_parent, false, 0); if (unlikely(!valid)) { err = -ESTALE; goto out; } if (new_dentry->d_inode) { valid = __unionfs_d_revalidate(new_dentry, new_parent, false, 0); if (unlikely(!valid)) { err = -ESTALE; goto out; } } lower_new_dentry = unionfs_lower_dentry(new_dentry); /* check for a whiteout in new dentry branch, and delete it */ err = check_unlink_whiteout(new_dentry, lower_new_dentry, dbstart(new_dentry)); if (err > 0) { /* whiteout found and removed successfully */ lower_dir_dentry = dget_parent(lower_new_dentry); fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); dput(lower_dir_dentry); set_nlink(dir, unionfs_get_nlinks(dir)); err = 0; } if (err) goto out; /* check if parent hierachy is needed, then link in same branch */ if (dbstart(old_dentry) != dbstart(new_dentry)) { lower_new_dentry = create_parents(dir, new_dentry, new_dentry->d_name.name, dbstart(old_dentry)); err = PTR_ERR(lower_new_dentry); if (IS_COPYUP_ERR(err)) goto docopyup; if (!lower_new_dentry || IS_ERR(lower_new_dentry)) goto out; } lower_new_dentry = unionfs_lower_dentry(new_dentry); lower_old_dentry = unionfs_lower_dentry(old_dentry); BUG_ON(dbstart(old_dentry) != dbstart(new_dentry)); lower_dir_dentry = lock_parent(lower_new_dentry); err = is_robranch(old_dentry); if (!err) { /* see Documentation/filesystems/unionfs/issues.txt */ lockdep_off(); err = vfs_link(lower_old_dentry, lower_dir_dentry->d_inode, lower_new_dentry); lockdep_on(); } unlock_dir(lower_dir_dentry); docopyup: if (IS_COPYUP_ERR(err)) { int old_bstart = dbstart(old_dentry); int bindex; for (bindex = old_bstart - 1; bindex >= 0; bindex--) { err = copyup_dentry(old_parent->d_inode, old_dentry, old_bstart, bindex, old_dentry->d_name.name, old_dentry->d_name.len, NULL, i_size_read(old_dentry->d_inode)); if (err) continue; lower_new_dentry = create_parents(dir, new_dentry, new_dentry->d_name.name, bindex); lower_old_dentry = unionfs_lower_dentry(old_dentry); lower_dir_dentry = lock_parent(lower_new_dentry); /* see Documentation/filesystems/unionfs/issues.txt */ lockdep_off(); /* do vfs_link */ err = vfs_link(lower_old_dentry, lower_dir_dentry->d_inode, lower_new_dentry); lockdep_on(); unlock_dir(lower_dir_dentry); goto check_link; } goto out; } check_link: if (err || !lower_new_dentry->d_inode) goto out; /* Its a hard link, so use the same inode */ new_dentry->d_inode = igrab(old_dentry->d_inode); d_add(new_dentry, new_dentry->d_inode); unionfs_copy_attr_all(dir, lower_new_dentry->d_parent->d_inode); fsstack_copy_inode_size(dir, lower_new_dentry->d_parent->d_inode); /* propagate number of hard-links */ set_nlink(old_dentry->d_inode, unionfs_get_nlinks(old_dentry->d_inode)); /* new dentry's ctime may have changed due to hard-link counts */ unionfs_copy_attr_times(new_dentry->d_inode); out: if (!new_dentry->d_inode) d_drop(new_dentry); kfree(name); if (!err) unionfs_postcopyup_setmnt(new_dentry); unionfs_check_inode(dir); unionfs_check_dentry(new_dentry); unionfs_check_dentry(old_dentry); unionfs_double_unlock_dentry(old_dentry, new_dentry); unionfs_double_unlock_parents(old_parent, new_parent); dput(new_parent); dput(old_parent); unionfs_read_unlock(old_dentry->d_sb); return err; }
wake_reason_t spm_go_to_dpidle(u32 spm_flags, u32 spm_data) { struct wake_status wakesta; unsigned long flags; struct mtk_irq_mask mask; wake_reason_t wr = WR_NONE; struct pcm_desc *pcmdesc = __spm_dpidle.pcmdesc; struct pwr_ctrl *pwrctrl = __spm_dpidle.pwrctrl; #if SPM_AEE_RR_REC aee_rr_rec_deepidle_val(1<<SPM_DEEPIDLE_ENTER); #endif set_pwrctrl_pcm_flags(pwrctrl, spm_flags); //pwrctrl->timer_val = 1 * 32768; spm_dpidle_before_wfi(); lockdep_off(); spin_lock_irqsave(&__spm_lock, flags); mt_irq_mask_all(&mask); mt_irq_unmask_for_sleep(SPM_IRQ0_ID); mt_cirq_clone_gic(); mt_cirq_enable(); #if SPM_AEE_RR_REC aee_rr_rec_deepidle_val(aee_rr_curr_deepidle_val()|(1<<SPM_DEEPIDLE_ENTER_UART_SLEEP)); #endif if (request_uart_to_sleep()) { wr = WR_UART_BUSY; goto RESTORE_IRQ; } __spm_reset_and_init_pcm(pcmdesc); __spm_kick_im_to_fetch(pcmdesc); __spm_init_pcm_register(); __spm_init_event_vector(pcmdesc); __spm_set_power_control(pwrctrl); __spm_set_wakeup_event(pwrctrl); spm_dpidle_pre_process(); __spm_kick_pcm_to_run(pwrctrl); #if SPM_AEE_RR_REC aee_rr_rec_deepidle_val(aee_rr_curr_deepidle_val()|(1<<SPM_DEEPIDLE_ENTER_WFI)); #endif #ifdef SPM_DEEPIDLE_PROFILE_TIME gpt_get_cnt(SPM_PROFILE_APXGPT,&dpidle_profile[1]); #endif spm_trigger_wfi_for_dpidle(pwrctrl); #ifdef SPM_DEEPIDLE_PROFILE_TIME gpt_get_cnt(SPM_PROFILE_APXGPT,&dpidle_profile[2]); #endif #if SPM_AEE_RR_REC aee_rr_rec_deepidle_val(aee_rr_curr_deepidle_val()|(1<<SPM_DEEPIDLE_LEAVE_WFI)); #endif spm_dpidle_post_process(); __spm_get_wakeup_status(&wakesta); __spm_clean_after_wakeup(); #if SPM_AEE_RR_REC aee_rr_rec_deepidle_val(aee_rr_curr_deepidle_val()|(1<<SPM_DEEPIDLE_ENTER_UART_AWAKE)); #endif request_uart_to_wakeup(); wr = __spm_output_wake_reason(&wakesta, pcmdesc, false); RESTORE_IRQ: mt_cirq_flush(); mt_cirq_disable(); mt_irq_mask_restore(&mask); spin_unlock_irqrestore(&__spm_lock, flags); lockdep_on(); spm_dpidle_after_wfi(); #if SPM_AEE_RR_REC aee_rr_rec_deepidle_val(0); #endif return wr; }
asmlinkage int vprintk(const char *fmt, va_list args) { unsigned long flags; int printed_len; char *p; static char printk_buf[1024]; static int log_level_unknown = 1; boot_delay_msec(); preempt_disable(); if (unlikely(oops_in_progress) && printk_cpu == smp_processor_id()) /* If a crash is occurring during printk() on this CPU, * make sure we can't deadlock */ zap_locks(); /* This stops the holder of console_sem just where we want him */ raw_local_irq_save(flags); lockdep_off(); spin_lock(&logbuf_lock); printk_cpu = smp_processor_id(); /* Emit the output into the temporary buffer */ printed_len = vscnprintf(printk_buf, sizeof(printk_buf), fmt, args); /* * Copy the output into log_buf. If the caller didn't provide * appropriate log level tags, we insert them here */ for (p = printk_buf; *p; p++) { if (log_level_unknown) { /* log_level_unknown signals the start of a new line */ if (printk_time) { int loglev_char; char tbuf[50], *tp; unsigned tlen; unsigned long long t; unsigned long nanosec_rem; /* * force the log level token to be * before the time output. */ if (p[0] == '<' && p[1] >='0' && p[1] <= '7' && p[2] == '>') { loglev_char = p[1]; p += 3; printed_len -= 3; } else { loglev_char = default_message_loglevel + '0'; } t = printk_clock(); nanosec_rem = do_div(t, 1000000000); tlen = sprintf(tbuf, "<%c>[%5lu.%06lu] ", loglev_char, (unsigned long)t, nanosec_rem/1000); for (tp = tbuf; tp < tbuf + tlen; tp++) emit_log_char(*tp); printed_len += tlen; } else { if (p[0] != '<' || p[1] < '0' || p[1] > '7' || p[2] != '>') { emit_log_char('<'); emit_log_char(default_message_loglevel + '0'); emit_log_char('>'); printed_len += 3; } } log_level_unknown = 0; if (!*p) break; } emit_log_char(*p); if (*p == '\n') log_level_unknown = 1; } if (!down_trylock(&console_sem)) { /* * We own the drivers. We can drop the spinlock and * let release_console_sem() print the text, maybe ... */ console_locked = 1; printk_cpu = UINT_MAX; spin_unlock(&logbuf_lock); /* * Console drivers may assume that per-cpu resources have * been allocated. So unless they're explicitly marked as * being able to cope (CON_ANYTIME) don't call them until * this CPU is officially up. */ if (cpu_online(smp_processor_id()) || have_callable_console()) { console_may_schedule = 0; release_console_sem(); } else { /* Release by hand to avoid flushing the buffer. */ console_locked = 0; up(&console_sem); } lockdep_on(); raw_local_irq_restore(flags); } else { /* * Someone else owns the drivers. We drop the spinlock, which * allows the semaphore holder to proceed and to call the * console drivers with the output which we just produced. */ printk_cpu = UINT_MAX; spin_unlock(&logbuf_lock); lockdep_on(); raw_local_irq_restore(flags); } preempt_enable(); return printed_len; }
void au_fi_mmap_unlock(struct file *file) { lockdep_off(); mutex_unlock(&au_fi(file)->fi_mmap); lockdep_on(); }
int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry, struct inode *dir, struct path *path) { int err; struct path tmp = { .mnt = path->mnt }; struct dentry *d; IMustLock(dir); IMustLock(src_dir); d = path->dentry; path->dentry = d->d_parent; tmp.dentry = src_dentry->d_parent; err = security_path_rename(&tmp, src_dentry, path, d); path->dentry = d; if (unlikely(err)) goto out; lockdep_off(); err = vfs_rename(src_dir, src_dentry, dir, path->dentry); lockdep_on(); if (!err) { int did; tmp.dentry = d->d_parent; vfsub_update_h_iattr(&tmp, &did); if (did) { tmp.dentry = src_dentry; vfsub_update_h_iattr(&tmp, /*did*/NULL); tmp.dentry = src_dentry->d_parent; vfsub_update_h_iattr(&tmp, /*did*/NULL); } /*ignore*/ } out: return err; } int vfsub_mkdir(struct inode *dir, struct path *path, int mode) { int err; struct dentry *d; IMustLock(dir); d = path->dentry; path->dentry = d->d_parent; err = security_path_mkdir(path, d, mode); path->dentry = d; if (unlikely(err)) goto out; err = vfs_mkdir(dir, path->dentry, mode); if (!err) { struct path tmp = *path; int did; vfsub_update_h_iattr(&tmp, &did); if (did) { tmp.dentry = path->dentry->d_parent; vfsub_update_h_iattr(&tmp, /*did*/NULL); } /*ignore*/ } out: return err; }
struct dentry *vfsub_lookup_hash(struct nameidata *nd) { struct path path = { .mnt = nd->path.mnt }; IMustLock(nd->path.dentry->d_inode); path.dentry = lookup_hash(nd); if (IS_ERR(path.dentry)) goto out; if (path.dentry->d_inode) vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/ out: AuTraceErrPtr(path.dentry); return path.dentry; } /* * this is "VFS:__lookup_one_len()" which was removed and merged into * VFS:lookup_one_len() by the commit. * 6a96ba5 2011-03-14 kill __lookup_one_len() * this function should always be equivalent to the corresponding part in * VFS:lookup_one_len(). */ int vfsub_name_hash(const char *name, struct qstr *this, int len) { unsigned int c; this->name = name; this->len = len; this->hash = full_name_hash(name, len); if (!len) return -EACCES; while (len--) { c = *(const unsigned char *)name++; if (c == '/' || c == '\0') return -EACCES; } return 0; } /* ---------------------------------------------------------------------- */ struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1, struct dentry *d2, struct au_hinode *hdir2) { struct dentry *d; lockdep_off(); d = lock_rename(d1, d2); lockdep_on(); au_hn_suspend(hdir1); if (hdir1 != hdir2) au_hn_suspend(hdir2); return d; } void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1, struct dentry *d2, struct au_hinode *hdir2) { au_hn_resume(hdir1); if (hdir1 != hdir2) au_hn_resume(hdir2); lockdep_off(); unlock_rename(d1, d2); lockdep_on(); }
asmlinkage int vprintk(const char *fmt, va_list args) { static int log_level_unknown = 1; static char printk_buf[1024]; unsigned long flags; int printed_len = 0; int this_cpu; char *p; boot_delay_msec(); preempt_disable(); /* This stops the holder of console_sem just where we want him */ /* 20100623,HSL@RK,audio broken,but system crash if comment */ raw_local_irq_save(flags); this_cpu = smp_processor_id(); /* * Ouch, printk recursed into itself! */ if (unlikely(printk_cpu == this_cpu)) { /* * If a crash is occurring during printk() on this CPU, * then try to get the crash message out but make sure * we can't deadlock. Otherwise just return to avoid the * recursion and return - but flag the recursion so that * it can be printed at the next appropriate moment: */ if (!oops_in_progress) { printk_recursion_bug = 1; // call printk when at printk. goto out_restore_irqs; } zap_locks(); } lockdep_off(); spin_lock(&logbuf_lock); printk_cpu = this_cpu; if (printk_recursion_bug) { printk_recursion_bug = 0; strcpy(printk_buf, printk_recursion_bug_msg); printed_len = sizeof(printk_recursion_bug_msg); } /* Emit the output into the temporary buffer */ printed_len += vscnprintf(printk_buf + printed_len, sizeof(printk_buf) - printed_len, fmt, args); //#ifdef CONFIG_DEBUG_LL // printascii(printk_buf); //#endif /* * Copy the output into log_buf. If the caller didn't provide * appropriate log level tags, we insert them here */ for (p = printk_buf; *p; p++) { if (log_level_unknown) { /* log_level_unknown signals the start of a new line */ if (printk_time) { int loglev_char; char tbuf[50], *tp; unsigned tlen; unsigned long long t; unsigned long nanosec_rem; /* * force the log level token to be * before the time output. */ if (p[0] == '<' && p[1] >='0' && p[1] <= '7' && p[2] == '>') { loglev_char = p[1]; p += 3; printed_len -= 3; } else { loglev_char = default_message_loglevel + '0'; } #if 0 t = cpu_clock(printk_cpu); nanosec_rem = do_div(t, 1000000000); tlen = sprintf(tbuf, "<%c>[%5lu.%06lu] ", loglev_char, (unsigned long)t, nanosec_rem/1000); #else nanosec_rem = nanosec_rem; t =t; tlen = sprintf(tbuf, "[%lu] ", printk_clock()); #endif for (tp = tbuf; tp < tbuf + tlen; tp++) emit_log_char(*tp); printed_len += tlen; } else { if (p[0] != '<' || p[1] < '0' || p[1] > '7' || p[2] != '>') { emit_log_char('<'); emit_log_char(default_message_loglevel + '0'); emit_log_char('>'); printed_len += 3; } } log_level_unknown = 0; if (!*p) break; } emit_log_char(*p); if (*p == '\n') log_level_unknown = 1; } /* * Try to acquire and then immediately release the * console semaphore. The release will do all the * actual magic (print out buffers, wake up klogd, * etc). * * The acquire_console_semaphore_for_printk() function * will release 'logbuf_lock' regardless of whether it * actually gets the semaphore or not. */ if (acquire_console_semaphore_for_printk(this_cpu)) release_console_sem(); lockdep_on(); out_restore_irqs: raw_local_irq_restore(flags); preempt_enable(); return printed_len; }
asmlinkage int vprintk(const char *fmt, va_list args) { int printed_len = 0; int current_log_level = default_message_loglevel; unsigned long flags; int this_cpu; char *p; boot_delay_msec(); preempt_disable(); /* This stops the holder of console_sem just where we want him */ raw_local_irq_save(flags); this_cpu = smp_processor_id(); /* * Ouch, printk recursed into itself! */ if (unlikely(printk_cpu == this_cpu)) { /* * If a crash is occurring during printk() on this CPU, * then try to get the crash message out but make sure * we can't deadlock. Otherwise just return to avoid the * recursion and return - but flag the recursion so that * it can be printed at the next appropriate moment: */ if (!oops_in_progress) { recursion_bug = 1; goto out_restore_irqs; } zap_locks(); } lockdep_off(); spin_lock(&logbuf_lock); printk_cpu = this_cpu; if (recursion_bug) { recursion_bug = 0; strcpy(printk_buf, recursion_bug_msg); printed_len = strlen(recursion_bug_msg); } /* Emit the output into the temporary buffer */ printed_len += vscnprintf(printk_buf + printed_len, sizeof(printk_buf) - printed_len, fmt, args); #ifdef CONFIG_DEBUG_LL printascii(printk_buf); #endif /* * Copy the output into log_buf. If the caller didn't provide * appropriate log level tags, we insert them here */ for (p = printk_buf; *p; p++) { if (new_text_line) { /* If a token, set current_log_level and skip over */ if (p[0] == '<' && p[1] >= '0' && p[1] <= '7' && p[2] == '>') { current_log_level = p[1] - '0'; p += 3; printed_len -= 3; } /* Always output the token */ emit_log_char('<'); emit_log_char(current_log_level + '0'); emit_log_char('>'); printed_len += 3; new_text_line = 0; if (printk_time) { /* Follow the token with the time */ char tbuf[50], *tp; unsigned tlen; unsigned long long t; unsigned long nanosec_rem; t = cpu_clock(printk_cpu); nanosec_rem = do_div(t, 1000000000); tlen = sprintf(tbuf, "[%5lu.%06lu] ", (unsigned long) t, nanosec_rem / 1000); for (tp = tbuf; tp < tbuf + tlen; tp++) emit_log_char(*tp); printed_len += tlen; } if (!*p) break; } emit_log_char(*p); if (*p == '\n') new_text_line = 1; } /* * Try to acquire and then immediately release the * console semaphore. The release will do all the * actual magic (print out buffers, wake up klogd, * etc). * * The acquire_console_semaphore_for_printk() function * will release 'logbuf_lock' regardless of whether it * actually gets the semaphore or not. */ if (acquire_console_semaphore_for_printk(this_cpu)) release_console_sem(); lockdep_on(); out_restore_irqs: raw_local_irq_restore(flags); preempt_enable(); return printed_len; }
static int __copyup_reg_data(struct dentry *dentry, struct dentry *new_lower_dentry, int new_bindex, struct dentry *old_lower_dentry, int old_bindex, struct file **copyup_file, loff_t len) { struct super_block *sb = dentry->d_sb; struct file *input_file; struct file *output_file; struct vfsmount *output_mnt; mm_segment_t old_fs; char *buf = NULL; ssize_t read_bytes, write_bytes; loff_t size; int err = 0; /* open old file */ unionfs_mntget(dentry, old_bindex); branchget(sb, old_bindex); /* dentry_open calls dput and mntput if it returns an error */ input_file = dentry_open(old_lower_dentry, unionfs_lower_mnt_idx(dentry, old_bindex), O_RDONLY | O_LARGEFILE); if (IS_ERR(input_file)) { dput(old_lower_dentry); err = PTR_ERR(input_file); goto out; } if (unlikely(!input_file->f_op || !input_file->f_op->read)) { err = -EINVAL; goto out_close_in; } /* open new file */ dget(new_lower_dentry); output_mnt = unionfs_mntget(sb->s_root, new_bindex); branchget(sb, new_bindex); output_file = dentry_open(new_lower_dentry, output_mnt, O_RDWR | O_LARGEFILE); if (IS_ERR(output_file)) { err = PTR_ERR(output_file); goto out_close_in2; } if (unlikely(!output_file->f_op || !output_file->f_op->write)) { err = -EINVAL; goto out_close_out; } /* allocating a buffer */ buf = kmalloc(PAGE_SIZE, GFP_KERNEL); if (unlikely(!buf)) { err = -ENOMEM; goto out_close_out; } input_file->f_pos = 0; output_file->f_pos = 0; old_fs = get_fs(); set_fs(KERNEL_DS); size = len; err = 0; do { if (len >= PAGE_SIZE) size = PAGE_SIZE; else if ((len < PAGE_SIZE) && (len > 0)) size = len; len -= PAGE_SIZE; read_bytes = input_file->f_op->read(input_file, (char __user *)buf, size, &input_file->f_pos); if (read_bytes <= 0) { err = read_bytes; break; } /* see Documentation/filesystems/unionfs/issues.txt */ lockdep_off(); write_bytes = output_file->f_op->write(output_file, (char __user *)buf, read_bytes, &output_file->f_pos); lockdep_on(); if ((write_bytes < 0) || (write_bytes < read_bytes)) { err = write_bytes; break; } } while ((read_bytes > 0) && (len > 0)); set_fs(old_fs); kfree(buf); if (!err) err = output_file->f_op->fsync(output_file, new_lower_dentry, 0); if (err) goto out_close_out; if (copyup_file) { *copyup_file = output_file; goto out_close_in; } out_close_out: fput(output_file); out_close_in2: branchput(sb, new_bindex); out_close_in: fput(input_file); out: branchput(sb, old_bindex); return err; }