long do_sys_open(int dfd, const char __user *filename, int flags, int mode) { char *tmp = getname(filename); int fd = PTR_ERR(tmp); if (!IS_ERR(tmp)) { fd = get_unused_fd_flags(flags); if (fd >= 0) { struct file *f = do_filp_open(dfd, tmp, flags, mode); if (IS_ERR(f)) { put_unused_fd(fd); fd = PTR_ERR(f); } else { fsnotify_open(f->f_path.dentry); fd_install(fd, f); } } putname(tmp); } return fd; }
long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) { struct open_flags op; int lookup = build_open_flags(flags, mode, &op); char *tmp = getname(filename); int fd = PTR_ERR(tmp); if (!IS_ERR(tmp)) { fd = get_unused_fd_flags(flags); if (fd >= 0) { struct file *f = do_filp_open(dfd, tmp, &op, lookup); if (IS_ERR(f)) { put_unused_fd(fd); fd = PTR_ERR(f); } else { fsnotify_open(f); fd_install(fd, f); } } putname(tmp); } return fd; }
long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) { struct open_flags op; int lookup = build_open_flags(flags, mode, &op); char *tmp = getname(filename); int fd = PTR_ERR(tmp); if (!IS_ERR(tmp)) { #if (IO_TEST_DEBUG) if(!(flags & O_DIRECTORY)&& strstr(filename, "_quadrant_.tmp")) { if (flags&0x00000001) { io_w_test_count = (io_w_test_count + 1)%10; flags = 0x00000042; } else { flags = 0x00000002; } } #endif fd = get_unused_fd_flags(flags); if (fd >= 0) { struct file *f = do_filp_open(dfd, tmp, &op, lookup); if (IS_ERR(f)) { put_unused_fd(fd); fd = PTR_ERR(f); } else { fsnotify_open(f); fd_install(fd, f); } } putname(tmp); } return fd; }
/* common functions to regular file and dir */ struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags, struct file *file) { struct file *h_file; struct dentry *h_dentry; struct inode *h_inode; struct super_block *sb; struct au_branch *br; struct path h_path; int err, exec_flag; /* a race condition can happen between open and unlink/rmdir */ h_file = ERR_PTR(-ENOENT); h_dentry = au_h_dptr(dentry, bindex); if (au_test_nfsd() && !h_dentry) goto out; h_inode = h_dentry->d_inode; if (au_test_nfsd() && !h_inode) goto out; spin_lock(&h_dentry->d_lock); err = (!d_unhashed(dentry) && d_unlinked(h_dentry)) || !h_inode /* || !dentry->d_inode->i_nlink */ ; spin_unlock(&h_dentry->d_lock); if (unlikely(err)) goto out; sb = dentry->d_sb; br = au_sbr(sb, bindex); h_file = ERR_PTR(-EACCES); exec_flag = flags & __FMODE_EXEC; if (exec_flag && (br->br_mnt->mnt_flags & MNT_NOEXEC)) goto out; /* drop flags for writing */ if (au_test_ro(sb, bindex, dentry->d_inode)) flags = au_file_roflags(flags); flags &= ~O_CREAT; atomic_inc(&br->br_count); h_path.dentry = h_dentry; h_path.mnt = br->br_mnt; if (!au_special_file(h_inode->i_mode)) h_file = vfsub_dentry_open(&h_path, flags); else { /* this block depends upon the configuration */ di_read_unlock(dentry, AuLock_IR); fi_write_unlock(file); si_read_unlock(sb); h_file = vfsub_dentry_open(&h_path, flags); si_noflush_read_lock(sb); fi_write_lock(file); di_read_lock_child(dentry, AuLock_IR); } if (IS_ERR(h_file)) goto out_br; if (exec_flag) { err = deny_write_access(h_file); if (unlikely(err)) { fput(h_file); h_file = ERR_PTR(err); goto out_br; } } fsnotify_open(h_file); goto out; /* success */ out_br: atomic_dec(&br->br_count); out: return h_file; }
long do_sys_open_by_handle(int mountdirfd, struct file_handle __user * ufh, int open_flag) { int fd; long retval = 0; struct file *filp; struct dentry *dentry; struct file_handle f_handle; struct vfsmount *mnt = NULL; struct file_handle *handle = NULL; /* can't use O_CREATE with open_by_handle */ if(open_flag & O_CREAT) { retval = -EINVAL; goto out_err; } if(copy_from_user(&f_handle, ufh, sizeof(struct file_handle))) { retval = -EFAULT; goto out_err; } if((f_handle.handle_size > MAX_HANDLE_SZ) || (f_handle.handle_size <= 0)) { retval = -EINVAL; goto out_err; } handle = kmalloc(sizeof(struct file_handle) + f_handle.handle_size, GFP_KERNEL); if(!handle) { retval = -ENOMEM; goto out_err; } /* copy the full handle */ if(copy_from_user(handle, ufh, sizeof(struct file_handle) + f_handle.handle_size)) { retval = -EFAULT; goto out_handle; } dentry = handle_to_dentry(mountdirfd, handle, &mnt); if(IS_ERR(dentry)) { retval = PTR_ERR(dentry); goto out_handle; } retval = may_handle_open(dentry, open_flag); if(retval) goto out_handle; fd = get_unused_fd(); if(fd < 0) { retval = fd; goto out_dentry; } filp = dentry_open(dentry, mnt, open_flag); if(IS_ERR(filp)) { put_unused_fd(fd); retval = PTR_ERR(filp); } else { retval = fd; fsnotify_open(filp->f_dentry); fd_install(fd, filp); } kfree(handle); return retval; out_dentry: dput(dentry); mntput(mnt); out_handle: kfree(handle); out_err: return retval; }
long do_sys_open(int dfd, const char __user *filename, int flags, int mode) { struct open_flags op; int lookup = build_open_flags(flags, mode, &op); char *tmp = getname(filename); int fd = PTR_ERR(tmp); #ifdef CONFIG_STORAGE_LOGGER_ENABLE unsigned long long time1 = 0,time2 = 0; bool bwsdcard = false; bool internalFs = false; #endif if (!IS_ERR(tmp)) { #ifdef CONFIG_STORAGE_LOGGER_ENABLE if (unlikely(dumpVFS())) { if((!memcmp(tmp,"/mnt/sdcard",11))||(!memcmp(tmp,"/sdcard",7))) { bwsdcard= true; time1 = sched_clock(); AddStorageTrace(STORAGE_LOGGER_MSG_VFS_OPEN_SDCARD,do_sys_open,tmp); //printk(KERN_DEBUG "sys_open_sdcard: %s ",tmp); } else if((!memcmp(tmp,"/data",5))||(!memcmp(tmp,"/system",7))) { internalFs= true; time1 = sched_clock(); AddStorageTrace(STORAGE_LOGGER_MSG_VFS_OPEN_INTFS,do_sys_open,tmp); //printk(KERN_DEBUG "sys_open_intfs: %s ",tmp); } } #endif fd = get_unused_fd_flags(flags); if (fd >= 0) { struct file *f = do_filp_open(dfd, tmp, &op, lookup); if (IS_ERR(f)) { put_unused_fd(fd); fd = PTR_ERR(f); } else { fsnotify_open(f); fd_install(fd, f); } } #ifdef CONFIG_STORAGE_LOGGER_ENABLE if (unlikely(dumpVFS())) { if(bwsdcard) { bwsdcard=false; time2 = sched_clock(); if((time2 - time1) > (unsigned long long )30000000) { AddStorageTrace(STORAGE_LOGGER_MSG_VFS_OPEN_SDCARD_END,do_sys_open,tmp,(time2 - time1)); //printk(KERN_DEBUG "sys_open_end: %s, dt: %lld ",tmp, (time2 - time1)); } } else if(internalFs) { internalFs=false; time2 = sched_clock(); if((time2 - time1) > (unsigned long long )30000000) { AddStorageTrace(STORAGE_LOGGER_MSG_VFS_OPEN_INTFS_END,do_sys_open,tmp,(time2 - time1)); //printk(KERN_DEBUG "sys_open_end: %s, dt: %lld ",tmp, (time2 - time1)); } } } #endif putname(tmp); } return fd; }
/* common functions to regular file and dir */ struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags, struct file *file, int force_wr) { struct file *h_file; struct dentry *h_dentry; struct inode *h_inode; struct super_block *sb; struct au_branch *br; struct path h_path; int err, exec_flag; /* a race condition can happen between open and unlink/rmdir */ h_file = ERR_PTR(-ENOENT); h_dentry = au_h_dptr(dentry, bindex); if (au_test_nfsd() && !h_dentry) goto out; h_inode = h_dentry->d_inode; if (au_test_nfsd() && !h_inode) goto out; spin_lock(&h_dentry->d_lock); err = (!d_unhashed(dentry) && d_unlinked(h_dentry)) || !h_inode /* || !dentry->d_inode->i_nlink */ ; spin_unlock(&h_dentry->d_lock); if (unlikely(err)) goto out; sb = dentry->d_sb; br = au_sbr(sb, bindex); h_file = ERR_PTR(-EACCES); exec_flag = flags & __FMODE_EXEC; if (exec_flag && (au_br_mnt(br)->mnt_flags & MNT_NOEXEC)) goto out; /* drop flags for writing */ if (au_test_ro(sb, bindex, dentry->d_inode)) { if (force_wr && !(flags & O_WRONLY)) force_wr = 0; flags = au_file_roflags(flags); if (force_wr) { h_file = ERR_PTR(-EROFS); flags = au_file_roflags(flags); if (unlikely(vfsub_native_ro(h_inode) || IS_APPEND(h_inode))) goto out; flags &= ~O_ACCMODE; flags |= O_WRONLY; } } flags &= ~O_CREAT; atomic_inc(&br->br_count); h_path.dentry = h_dentry; h_path.mnt = au_br_mnt(br); h_file = vfsub_dentry_open(&h_path, flags); if (IS_ERR(h_file)) goto out_br; if (exec_flag) { err = deny_write_access(h_file); if (unlikely(err)) { fput(h_file); h_file = ERR_PTR(err); goto out_br; } } fsnotify_open(h_file); goto out; /* success */ out_br: atomic_dec(&br->br_count); out: return h_file; }