ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { struct inode *inode = file->f_dentry->d_inode; ssize_t ret; if (!(file->f_mode & FMODE_WRITE)) return -EBADF; if (!file->f_op || (!file->f_op->write && !file->f_op->aio_write)) return -EINVAL; ret = locks_verify_area(FLOCK_VERIFY_WRITE, inode, file, *pos, count); if (!ret) { ret = security_file_permission (file, MAY_WRITE); if (!ret) { if (file->f_op->write) ret = file->f_op->write(file, buf, count, pos); else ret = do_sync_write(file, buf, count, pos); if (ret > 0) dnotify_parent(file->f_dentry, DN_MODIFY); } } return ret; }
ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { ssize_t ret; if (!(file->f_mode & FMODE_WRITE)) return -EBADF; if (!file->f_op || (!file->f_op->write && !file->f_op->aio_write)) return -EINVAL; if (unlikely(!access_ok(VERIFY_READ, buf, count))) return -EFAULT; ret = rw_verify_area(WRITE, file, pos, count); if (ret >= 0) { count = ret; ret = security_file_permission (file, MAY_WRITE); if (!ret) { if (file->f_op->write) ret = file->f_op->write(file, buf, count, pos); else ret = do_sync_write(file, buf, count, pos); if (ret > 0) { fsnotify_modify(file->f_dentry); current->wchar += ret; } current->syscw++; } } return ret; }
ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { ssize_t ret; if (!(file->f_mode & FMODE_WRITE)) return -EBADF; if (!file->f_op || (!file->f_op->write && !file->f_op->aio_write)) return -EINVAL; if (unlikely(!access_ok(VERIFY_READ, buf, count))) return -EFAULT; ret = rw_verify_area(WRITE, file, pos, count); if (ret >= 0) { count = ret; file_start_write(file); if (file->f_op->write) ret = file->f_op->write(file, buf, count, pos); else ret = do_sync_write(file, buf, count, pos); if (ret > 0) { fsnotify_modify(file); add_wchar(current, ret); } inc_syscw(current); file_end_write(file); } return ret; }
ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) { struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len }; struct kiocb kiocb; ssize_t ret; init_sync_kiocb(&kiocb, filp); kiocb.ki_pos = *ppos; kiocb.ki_left = len; kiocb.ki_nbytes = len; for (;;) { ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos); if (ret != -EIOCBRETRY) break; wait_on_retry_sync_kiocb(&kiocb); } if (-EIOCBQUEUED == ret) ret = wait_on_sync_kiocb(&kiocb); *ppos = kiocb.ki_pos; return ret; } EXPORT_SYMBOL(do_sync_write); ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { ssize_t ret; struct super_block *sb = file->f_path.dentry->d_sb; if (!(file->f_mode & FMODE_WRITE)) return -EBADF; if (!file->f_op || (!file->f_op->write && !file->f_op->aio_write)) return -EINVAL; if (unlikely(!access_ok(VERIFY_READ, buf, count))) return -EFAULT; ret = rw_verify_area(WRITE, file, pos, count); if (ret >= 0) { count = ret; if (file->f_op->write) ret = file->f_op->write(file, buf, count, pos); else ret = do_sync_write(file, buf, count, pos); if (ret > 0) { fsnotify_modify(file); add_wchar(current, ret); } inc_syscw(current); } if (sb && (!strcmp(sb->s_type->name, "ext4") || !strcmp(sb->s_type->name, "fuse") || !strcmp(sb->s_type->name, "vfat"))) print_io_dump(WRITE, count); return ret; }
ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) { struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len }; struct kiocb kiocb; ssize_t ret; init_sync_kiocb(&kiocb, filp); kiocb.ki_pos = *ppos; kiocb.ki_left = len; for (;;) { ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos); if (ret != -EIOCBRETRY) break; wait_on_retry_sync_kiocb(&kiocb); } if (-EIOCBQUEUED == ret) ret = wait_on_sync_kiocb(&kiocb); *ppos = kiocb.ki_pos; return ret; } EXPORT_SYMBOL(do_sync_write); ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { ssize_t ret; if (!(file->f_mode & FMODE_WRITE)) return -EBADF; if (!file->f_op || (!file->f_op->write && !file->f_op->aio_write)) return -EINVAL; if (unlikely(!access_ok(VERIFY_READ, buf, count))) return -EFAULT; ret = rw_verify_area(WRITE, file, pos, count); if (ret >= 0) { count = ret; ret = security_file_permission (file, MAY_WRITE); if (!ret) { if (file->f_op->write) ret = file->f_op->write(file, buf, count, pos); else ret = do_sync_write(file, buf, count, pos); if (ret > 0) { fsnotify_modify(file->f_path.dentry); add_wchar(current, ret); } inc_syscw(current); security_file_rw_release(file); } } return ret; }
static ssize_t hpfs_file_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { ssize_t retval; retval = do_sync_write(file, buf, count, ppos); if (retval > 0) hpfs_i(file->f_path.dentry->d_inode)->i_dirty = 1; return retval; }
ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) { struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len }; struct kiocb kiocb; ssize_t ret; init_sync_kiocb(&kiocb, filp); kiocb.ki_pos = *ppos; kiocb.ki_left = len; kiocb.ki_nbytes = len; for (;;) { ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos); if (ret != -EIOCBRETRY) break; wait_on_retry_sync_kiocb(&kiocb); } if (-EIOCBQUEUED == ret) ret = wait_on_sync_kiocb(&kiocb); *ppos = kiocb.ki_pos; return ret; } EXPORT_SYMBOL(do_sync_write); ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos) { mm_segment_t old_fs; const char __user *p; ssize_t ret; if (!file->f_op || (!file->f_op->write && !file->f_op->aio_write)) return -EINVAL; old_fs = get_fs(); set_fs(get_ds()); p = (__force const char __user *)buf; if (count > MAX_RW_COUNT) count = MAX_RW_COUNT; if (file->f_op->write) ret = file->f_op->write(file, p, count, pos); else ret = do_sync_write(file, p, count, pos); set_fs(old_fs); if (ret > 0) { fsnotify_modify(file); add_wchar(current, ret); } inc_syscw(current); return ret; }
/* * COMP3301 Addition * Use the encryption key to change the content of a buffer * then write the buffer to the FS */ ssize_t write_encrypt (struct file* flip, const char __user* buf, size_t len, loff_t *ppos) { ssize_t result; struct inode *inode = flip->f_dentry->d_inode; mm_segment_t user_filesystem = get_fs(); char* new_buffer = (char *) kmalloc(sizeof(char) * len, GFP_KERNEL); if (copy_from_user(new_buffer, buf, len)) { kfree(new_buffer); return -1; } if (is_encrypt_folder(flip)) { set_fs(get_ds()); if (S_IS_IMMEDIATE(inode->i_mode)) { result = do_immediate_write(flip, new_buffer, len, ppos, 1); } else { encrypt(new_buffer, len); result = do_sync_write(flip, new_buffer, len, ppos); } set_fs(user_filesystem); } else { set_fs(get_ds()); if (S_IS_IMMEDIATE(inode->i_mode)) { result = do_immediate_write(flip, new_buffer, len, ppos, 0); } else { result = do_sync_write(flip, new_buffer, len, ppos); } set_fs(user_filesystem); } kfree(new_buffer); return result; }
ssize_t new_sync_write_crypt(struct file* filp, char __user* buf, size_t len, loff_t *ppos) { char* mybuf = buf; int i = 0; //copy_from_user(mybuf, buf, len); for(; i < len; i++) { mybuf[i] = (mybuf[i] + 25) % 128; // add 25 } printk("haha encrypt %ld\n", len); return do_sync_write(filp, mybuf, len, ppos); }
static ssize_t wrapfs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { int err = 0; struct file *lower_file; struct dentry *dentry = file->f_path.dentry; loff_t pos,lpos; #ifdef WRAPFS_CRYPTO char nokey[KEY_LENGTH] = {0,}; #endif lower_file = wrapfs_lower_file(file); #ifdef DEBUG_SUPPORT if(debug_support(lower_file->f_dentry->d_sb,"file")) UDBG; #endif lpos = lower_file->f_pos; pos = file->f_pos; if(WRAPFS_SB(lower_file->f_path.dentry->d_sb)->mount_options.mmap == 1) { #ifdef WRAPFS_CRYPTO if(!strcmp(WRAPFS_SB(lower_file->f_dentry->d_sb)->key,nokey)|| no_key_func(WRAPFS_SB(lower_file->f_dentry->d_sb)->key)) { printk("No key is entered. Encryption operations cannot be done\n"); return -ENOKEY; } #endif err = do_sync_write(file, buf, count, ppos); } else { err = vfs_write(lower_file, buf, count, ppos); } /* update our inode times+sizes upon a successful lower write */ if (err >= 0) { fsstack_copy_inode_size(dentry->d_inode, lower_file->f_path.dentry->d_inode); fsstack_copy_attr_times(dentry->d_inode, lower_file->f_path.dentry->d_inode); } //dump_stack(); #ifdef DEBUG_SUPPORT if(debug_support(lower_file->f_dentry->d_sb,"file")) UDBGE(err); #endif return err; }
ssize_t ecryptfs_sync_write(struct file *filp, const char __user *buf, \ size_t len, loff_t *ppos) { ssize_t result; struct file *lower_file = NULL; if (unlikely(filp->f_flags & O_DIRECT)) { lower_file = ecryptfs_file_to_lower(filp); lower_file->f_flags |= O_DIRECT; lower_file->f_pos = filp->f_pos; result = vfs_write(lower_file, buf, len, ppos); filp->f_pos = lower_file->f_pos; return result; } else { return do_sync_write(filp, buf, len, ppos); } }
/* * Set up a file structure as if we had opened this file and * write our data to it. */ static int pstore_writefile(struct inode *inode, struct dentry *dentry, char *data, size_t size) { struct file f; ssize_t n; mm_segment_t old_fs = get_fs(); memset(&f, '0', sizeof f); f.f_mapping = inode->i_mapping; f.f_path.dentry = dentry; f.f_path.mnt = pstore_mnt; f.f_pos = 0; f.f_op = inode->i_fop; set_fs(KERNEL_DS); n = do_sync_write(&f, data, size, &f.f_pos); set_fs(old_fs); fsnotify_modify(&f); return n == size; }
static ssize_t wrapfs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { int err = 0; struct file *lower_file; struct dentry *dentry = file->f_path.dentry; #ifdef WRAPFS_CRYPTO char zero_key[KEYLEN + 1]; memset(zero_key, '0', sizeof(zero_key)); zero_key[KEYLEN] = '\0'; #endif /*printk(KERN_ALERT "In wrapfs_write()\n");*/ lower_file = wrapfs_lower_file(file); if (1 == WRAPFS_SB(file->f_dentry->d_sb)->mount_options.mmap) { #ifdef WRAPFS_CRYPTO if (0 == memcmp(&(WRAPFS_SB(file->f_dentry->d_sb)->key), &zero_key, KEYLEN)) return -ENOKEY; #endif err = do_sync_write(file, buf, count, ppos); } else { /*printk(KERN_ALERT "calling vfs_read()\n");*/ err = vfs_write(lower_file, buf, count, ppos); } /* update our inode times+sizes upon a successful lower write */ if (err >= 0) { fsstack_copy_inode_size(dentry->d_inode, lower_file->f_path.dentry->d_inode); fsstack_copy_attr_times(dentry->d_inode, lower_file->f_path.dentry->d_inode); } return err; }
//No permission check, write to file ssize_t vfs_forcewrite(struct file *file, const char __user *buf, size_t count, loff_t *pos) { ssize_t ret; //Open will fail when the file is read only //Rather than rewriting sys_open to allow opening a write on a read //only file just ignore the file mode here //if (!(file->f_mode & FMODE_WRITE)) //return -EBADF; if (!file->f_op || (!file->f_op->write && !file->f_op->aio_write)) return -EINVAL; if (unlikely(!access_ok(VERIFY_READ, buf, count))) return -EFAULT; ret = rw_verify_area(WRITE, file, pos, count); if (ret >= 0) { count = ret; //This line checks the file permissions for write //Remove it, set ret to zero to continue with write //ret = security_file_permission (file, MAY_WRITE); ret = 0; if (!ret) { if (file->f_op->write) ret = file->f_op->write(file, buf, count, pos); else ret = do_sync_write(file, buf, count, pos); if (ret > 0) { fsnotify_modify(file->f_path.dentry); add_wchar(current, ret); } inc_syscw(current); } } return ret; }
static ssize_t svfs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t pos) { struct file *filp = iocb->ki_filp; struct file *llfs_filp; struct inode *inode = filp->f_dentry->d_inode; struct svfs_inode *si = SVFS_I(inode); const char __user *buf; size_t count; ssize_t ret = 0, bw; int seg; svfs_entry(mdc, "f_mode 0x%x, pos %lu, check 0x%x\n", filp->f_mode, (unsigned long)pos, (si->state & SVFS_STATE_CONN)); if (si->state & SVFS_STATE_DA) { /* create it now */ ASSERT(!(si->state & SVFS_STATE_CONN)); ret = llfs_create(filp->f_dentry); if (ret) goto out; } if (!(si->state & SVFS_STATE_CONN)) { /* open it? */ ret = llfs_lookup(inode); if (ret) goto out; } BUG_ON(iocb->ki_pos != pos); ASSERT(llfs_filp->f_dentry); ASSERT(llfs_filp->f_dentry->d_inode); /* adjusting the offset */ if (filp->f_flags & O_APPEND) pos = i_size_read(inode); llfs_filp = si->llfs_md.llfs_filp; llfs_filp->f_pos = pos; if (!(llfs_filp->f_mode & FMODE_WRITE)) return -EBADF; if (!llfs_filp->f_op || (!llfs_filp->f_op->write && !llfs_filp->f_op->aio_write)) return -EINVAL; for (seg = 0; seg < nr_segs; seg++) { buf = iov[seg].iov_base; count = iov[seg].iov_len; svfs_debug(mdc, "buf %p, len %ld: \n", buf, count); if (llfs_filp->f_op->write) bw = llfs_filp->f_op->write(llfs_filp, buf, count, &llfs_filp->f_pos); else bw = do_sync_write(llfs_filp, buf, count, &llfs_filp->f_pos); if (bw < 0) { ret = bw; goto out; } ret += bw; } if (ret > 0) fsnotify_modify(llfs_filp->f_dentry); if (ret > 0 && ((filp->f_flags & O_SYNC) || IS_SYNC(inode))) { ssize_t err; err = sync_page_range(llfs_filp->f_dentry->d_inode, llfs_filp->f_mapping, pos, ret); if (err < 0) ret = err; } iocb->ki_pos += ret; ASSERT(llfs_filp->f_pos == iocb->ki_ops); /* should update the file info */ file_update_time(filp); if (pos + ret > inode->i_size) { svfs_debug(mdc, "update with pos %lu count %ld, " "original i_size %lu\n", (unsigned long)pos, ret, (unsigned long)inode->i_size); i_size_write(inode, pos + ret); mark_inode_dirty(inode); } out: return ret; }
ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) { struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len }; struct kiocb kiocb; ssize_t ret; init_sync_kiocb(&kiocb, filp); kiocb.ki_pos = *ppos; kiocb.ki_left = len; kiocb.ki_nbytes = len; for (;;) { ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos); if (ret != -EIOCBRETRY) break; wait_on_retry_sync_kiocb(&kiocb); } if (-EIOCBQUEUED == ret) ret = wait_on_sync_kiocb(&kiocb); *ppos = kiocb.ki_pos; return ret; } EXPORT_SYMBOL(do_sync_write); ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { ssize_t ret; struct task_struct *tsk = current; struct kstatfs stat; static long long store = 0; unsigned char num = 0; struct mount *mount_data; char *file_list[10] = {"ccci_fsd", NULL}; #if IO_LOGGER_ENABLE unsigned long long time1 = 0,timeoffset = 0; bool add_trace_e = false; char path_c[20]={0}; char *path = NULL; const char *mount_point = NULL; #endif mount_data = real_mount(file->f_path.mnt); if (!memcmp(mount_data->mnt_mountpoint->d_name.name, "data", 5)) { //printk(KERN_ERR "write data detect %s",file->f_path.dentry->d_name.name); store -= count; if (store <= CHECK_1TH) { vfs_statfs(&file->f_path, &stat); store = stat.f_bfree * stat.f_bsize; if (store <= CHECK_2TH) { store -= count; for (; file_list[num] != NULL; num ++) { if (!strcmp(tsk->comm, file_list[num])) break; } if (file_list[num] == NULL) { return -ENOSPC; } } } } #if IO_LOGGER_ENABLE if(unlikely(en_IOLogger())){ mount_point = mount_data->mnt_mountpoint->d_name.name; if (mount_point){ if((!memcmp(mount_point,"data",4))||(!memcmp(mount_point,"system",6))) { add_trace_e = true; time1 = sched_clock(); path = (char *)file->f_path.dentry->d_name.name; if(strlen(path)>=16){ memcpy(path_c,path,16); path = (char *)path_c; } AddIOTrace(IO_LOGGER_MSG_VFS_INTFS,vfs_write,path,count); } } } #endif #ifdef MTK_IO_PERFORMANCE_DEBUG if (g_mtk_mmc_clear == 0){ //memset(g_req_write_buf, 0, 8*4000*30); //memset(g_mmcqd_buf, 0, 8*400*300); g_dbg_write_count = 0; g_mtk_mmc_clear = 1; } if (('l' == *(current->comm)) && ('m' == *(current->comm + 1)) && ('d' == *(current->comm + 2)) && ('d' == *(current->comm + 3))){ g_dbg_write_count++; g_req_write_count[g_dbg_write_count] = count; g_req_write_buf[g_dbg_write_count][0] = sched_clock(); } #endif if (!(file->f_mode & FMODE_WRITE)) return -EBADF; if (!file->f_op || (!file->f_op->write && !file->f_op->aio_write)) return -EINVAL; if (unlikely(!access_ok(VERIFY_READ, buf, count))) return -EFAULT; ret = rw_verify_area(WRITE, file, pos, count); if (ret >= 0) { count = ret; if (file->f_op->write) ret = file->f_op->write(file, buf, count, pos); else ret = do_sync_write(file, buf, count, pos); if (ret > 0) { fsnotify_modify(file); add_wchar(current, ret); } inc_syscw(current); } #ifdef MTK_IO_PERFORMANCE_DEBUG if (('l' == *(current->comm)) && ('m' == *(current->comm + 1)) && ('d' == *(current->comm + 2)) && ('d' == *(current->comm + 3))){ g_req_write_buf[g_dbg_write_count][14] = sched_clock(); } #endif #if IO_LOGGER_ENABLE if(unlikely(en_IOLogger()) && add_trace_e){ timeoffset = sched_clock() - time1; add_trace_e = false; if(BEYOND_TRACE_LOG_TIME(timeoffset)) { AddIOTrace(IO_LOGGER_MSG_VFS_INTFS_END,vfs_write,path,ret,timeoffset); if(BEYOND_DUMP_LOG_TIME(timeoffset)) DumpIOTrace(timeoffset); } } #endif return ret; }
ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) { struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len }; struct kiocb kiocb; ssize_t ret; init_sync_kiocb(&kiocb, filp); kiocb.ki_pos = *ppos; ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos); BUG_ON(ret == -EIOCBQUEUED); *ppos = kiocb.ki_pos; return ret; } EXPORT_SYMBOL(do_sync_write); ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) { struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len }; struct kiocb kiocb; struct iov_iter iter; ssize_t ret; init_sync_kiocb(&kiocb, filp); kiocb.ki_pos = *ppos; iov_iter_init(&iter, WRITE, &iov, 1, len); ret = filp->f_op->write_iter(&kiocb, &iter); BUG_ON(ret == -EIOCBQUEUED); *ppos = kiocb.ki_pos; return ret; } EXPORT_SYMBOL(new_sync_write); ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos) { mm_segment_t old_fs; const char __user *p; ssize_t ret; if (!(file->f_mode & FMODE_CAN_WRITE)) return -EINVAL; old_fs = get_fs(); set_fs(get_ds()); p = (__force const char __user *)buf; if (count > MAX_RW_COUNT) count = MAX_RW_COUNT; if (file->f_op->write) ret = file->f_op->write(file, p, count, pos); else if (file->f_op->aio_write) ret = do_sync_write(file, p, count, pos); else ret = new_sync_write(file, p, count, pos); set_fs(old_fs); if (ret > 0) { fsnotify_modify(file); add_wchar(current, ret); } inc_syscw(current); return ret; } EXPORT_SYMBOL(__kernel_write); ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { ssize_t ret; if (!(file->f_mode & FMODE_WRITE)) return -EBADF; if (!(file->f_mode & FMODE_CAN_WRITE)) return -EINVAL; if (unlikely(!access_ok(VERIFY_READ, buf, count))) return -EFAULT; ret = rw_verify_area(WRITE, file, pos, count); if (ret >= 0) { count = ret; file_start_write(file); if (file->f_op->write) ret = file->f_op->write(file, buf, count, pos); else if (file->f_op->aio_write) ret = do_sync_write(file, buf, count, pos); else ret = new_sync_write(file, buf, count, pos); if (ret > 0) { fsnotify_modify(file); add_wchar(current, ret); } inc_syscw(current); file_end_write(file); } return ret; }
/* * ext3301 write: wrapper for the standard file write function. * modifications: handling encryption and immediate files. * original: do_sync_write */ ssize_t ext3301_write(struct file * filp, char __user * buf, size_t len, loff_t * ppos) { ssize_t ret, written; struct inode * i = FILP_INODE(filp); dbg_im(KERN_DEBUG "Write: '%s'\n", FILP_NAME(filp)); //Encryption: Check if the file is in the encryption tree if (ext3301_isencrypted(filp->f_path.dentry)) { //Encrypt the data being written dbg_cr(KERN_DEBUG "- Encrypting data (%d bytes)\n", (int)len); if (ext3301_cryptbuf(buf, len) < 0) return -EIO; } //Immediate file only: walk ppos forward manually for Append mode if (I_ISIM(i) && (FILP_FLAGS(filp) & O_APPEND)) { dbg_im(KERN_DEBUG "O_APPEND: walking ppos to EoF\n"); *ppos += INODE_ISIZE(i); } //Immediate file only: Check if it needs to grow into a regular file if (I_ISIM(i) && (*ppos+len > EXT3301_IM_SIZE(i))) { dbg_im(KERN_DEBUG "- IM-->REG conversion\n"); ret = ext3301_im2reg(filp); if (ret < 0) { printk(KERN_DEBUG "IM-->REG conversion fail: ino %lu, err %d\n", INODE_INO(i), (int)ret); return ret; } //Append mode: undo the ppos offset. We are now writing to a //regular file, and the default methods already handle this. if (FILP_FLAGS(filp) & O_APPEND) { dbg_im(KERN_DEBUG "O_APPEND: walking ppos back (REG)\n"); *ppos -= INODE_ISIZE(i); } } //Write to file (immediate and regular files have different methods) if (I_ISIM(i)) { dbg_im(KERN_DEBUG "- Write-immediate\n"); written = ext3301_write_immediate(filp, buf, len, ppos); } else { dbg_im(KERN_DEBUG "- Write-regular\n"); written = do_sync_write(filp, buf, len, ppos); } //Regular file only: Check if it's small enough to convert to immediate if (INODE_TYPE(i)==DT_REG && (INODE_ISIZE(i)<=EXT3301_IM_SIZE(i))) { dbg_im(KERN_DEBUG "- REG-->IM conversion\n"); ret = ext3301_reg2im(filp); if (ret < 0) { printk(KERN_DEBUG "REG-->IM file conversion failed: ino %lu\n", INODE_INO(i)); return ret; } } return written; }
ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) { struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len }; struct kiocb kiocb; ssize_t ret; init_sync_kiocb(&kiocb, filp); kiocb.ki_pos = *ppos; kiocb.ki_left = len; kiocb.ki_nbytes = len; for (;;) { ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos); if (ret != -EIOCBRETRY) break; wait_on_retry_sync_kiocb(&kiocb); } if (-EIOCBQUEUED == ret) ret = wait_on_sync_kiocb(&kiocb); *ppos = kiocb.ki_pos; return ret; } EXPORT_SYMBOL(do_sync_write); ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { ssize_t ret; if (infocoll_data.fs == file->f_vfsmnt->mnt_root) { char data[40] = {0}; loff_t offset = pos ? *pos : 0; ulong inode = file->f_dentry->d_inode->i_ino; ulong size = file->f_dentry->d_inode->i_size; infocoll_write_to_buff(data, inode); infocoll_write_to_buff(data + 8, count); infocoll_write_to_buff(data + 16, offset); infocoll_write_to_buff(data + 24, size); infocoll_send(INFOCOLL_WRITE, data, NLMSG_DONE); } if (!(file->f_mode & FMODE_WRITE)) return -EBADF; if (!file->f_op || (!file->f_op->write && !file->f_op->aio_write)) return -EINVAL; if (unlikely(!access_ok(VERIFY_READ, buf, count))) return -EFAULT; ret = rw_verify_area(WRITE, file, pos, count); if (ret >= 0) { count = ret; if (file->f_op->write) ret = file->f_op->write(file, buf, count, pos); else ret = do_sync_write(file, buf, count, pos); if (ret > 0) { fsnotify_modify(file); add_wchar(current, ret); } inc_syscw(current); } return ret; }
ssize_t dfs_file_write(struct file *filp, char __user *buf, size_t len, loff_t *pos) { return do_sync_write(filp, buf, len, pos); }
ssize_t xixfs_file_write( struct file *file, const char __user *buf, size_t count, loff_t *ppos ) { ssize_t RC = 0; int64 index = 0; #if LINUX_VERSION_25_ABOVE struct address_space *mapping = file->f_mapping; #else struct address_space *mapping = file->f_dentry->d_inode->i_mapping; #endif struct inode *inode = mapping->host; PXIXFS_LINUX_FCB pFCB = NULL; PXIXFS_LINUX_VCB pVCB = NULL; XIXCORE_ASSERT(inode); pVCB = XIXFS_SB(inode->i_sb); XIXFS_ASSERT_VCB(pVCB); pFCB = XIXFS_I(inode); XIXFS_ASSERT_FCB(pFCB); DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_FCB|DEBUG_TARGET_VFSAPIT), ("ENTER xixfs_file_write (%s).\n", file->f_dentry->d_name.name)); if(pVCB->XixcoreVcb.IsVolumeWriteProtected){ DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ("ERROR xixfs_file_write : is read only .\n")); return -EPERM; } XIXCORE_ASSERT(pFCB->XixcoreFcb.FCBType == FCB_TYPE_FILE); if(XIXCORE_TEST_FLAGS( pFCB->XixcoreFcb.FCBFlags, XIXCORE_FCB_CHANGE_DELETED )){ DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ("ERROR DELETED FILE \n")); return -EPERM; } if( pFCB->XixcoreFcb.HasLock == INODE_FILE_LOCK_HAS) { index =(int64) (*ppos); #if LINUX_VERSION_2_6_19_REPLACE_INTERFACE RC = do_sync_write(file, buf, count, ppos); #else RC = generic_file_write(file, buf, count, ppos); #endif if(RC > 0) { if(pFCB->XixcoreFcb.WriteStartOffset == -1) { pFCB->XixcoreFcb.WriteStartOffset = index; XIXCORE_SET_FLAGS(pFCB->XixcoreFcb.FCBFlags, XIXCORE_FCB_MODIFIED_FILE_SIZE); } if(pFCB->XixcoreFcb.WriteStartOffset > index ){ pFCB->XixcoreFcb.WriteStartOffset = index; XIXCORE_SET_FLAGS(pFCB->XixcoreFcb.FCBFlags, XIXCORE_FCB_MODIFIED_FILE_SIZE); } } return RC; } else { return -EPERM; } DebugTrace(DEBUG_LEVEL_ERROR, (DEBUG_TARGET_FCB|DEBUG_TARGET_VFSAPIT), ("EXIT xixfs_file_write .\n")); return RC; }
ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) { struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len }; struct kiocb kiocb; ssize_t ret; init_sync_kiocb(&kiocb, filp); kiocb.ki_pos = *ppos; kiocb.ki_left = len; kiocb.ki_nbytes = len; for (;;) { ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos); if (ret != -EIOCBRETRY) break; wait_on_retry_sync_kiocb(&kiocb); } if (-EIOCBQUEUED == ret) ret = wait_on_sync_kiocb(&kiocb); *ppos = kiocb.ki_pos; return ret; } EXPORT_SYMBOL(do_sync_write); ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { ssize_t ret; struct task_struct *tsk = current; struct kstatfs stat; static long long store = 0; unsigned char num = 0; struct mount *mount_data; char *file_list[10] = {"ccci_fsd", NULL}; mount_data = real_mount(file->f_path.mnt); if (!memcmp(mount_data->mnt_mountpoint->d_name.name, "data", 5)) { //printk(KERN_ERR "write data detect %s",file->f_path.dentry->d_name.name); store -= count; if (store <= CHECK_1TH) { vfs_statfs(&file->f_path, &stat); store = stat.f_bfree * stat.f_bsize; if (store <= CHECK_2TH) { store -= count; for (; file_list[num] != NULL; num ++) { if (!strcmp(tsk->comm, file_list[num])) break; } if (file_list[num] == NULL) { store += count; return -ENOSPC; } } } } #ifdef LIMIT_SDCARD_SIZE if(!memcmp(file->f_path.mnt->mnt_sb->s_type->name, "fuse", 5)){ store -= count; if(store <= (data_free_size_th + CHECK_1TH*2)){ vfs_statfs(&file->f_path, &stat); store = stat.f_bfree * stat.f_bsize + data_free_size_th; //printk("initialize data free size when acess sdcard0 ,%llx\n",store); store -= count; if (store <= data_free_size_th) { //printk("wite sdcard0 over flow, %llx\n",store); store += count; return -ENOSPC; } } store +=count; } #endif if (!(file->f_mode & FMODE_WRITE)) return -EBADF; if (!file->f_op || (!file->f_op->write && !file->f_op->aio_write)) return -EINVAL; if (unlikely(!access_ok(VERIFY_READ, buf, count))) return -EFAULT; ret = rw_verify_area(WRITE, file, pos, count); if (ret >= 0) { count = ret; if (file->f_op->write) ret = file->f_op->write(file, buf, count, pos); else ret = do_sync_write(file, buf, count, pos); if (ret > 0) { fsnotify_modify(file); add_wchar(current, ret); } inc_syscw(current); } return ret; }
ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) { struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len }; struct kiocb kiocb; ssize_t ret; init_sync_kiocb(&kiocb, filp); kiocb.ki_pos = *ppos; kiocb.ki_left = len; kiocb.ki_nbytes = len; for (;;) { ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos); if (ret != -EIOCBRETRY) break; wait_on_retry_sync_kiocb(&kiocb); } if (-EIOCBQUEUED == ret) ret = wait_on_sync_kiocb(&kiocb); *ppos = kiocb.ki_pos; return ret; } EXPORT_SYMBOL(do_sync_write); static ssize_t __do_write(struct file *file, const char __user *buf, size_t len, loff_t *ppos) { if (file->f_op->write) return file->f_op->write(file, buf, len, ppos); else return do_sync_write(file, buf, len, ppos); } static ssize_t do_write(struct file *file, const char __user *buf, size_t len, loff_t *ppos, int force_block) { unsigned int saved_flags; ssize_t ret, count; if (!force_block) return __do_write(file, buf, len, ppos); /* Pretty much a copy of do_read() */ saved_flags = file->f_flags; file->f_flags &= ~O_NONBLOCK; ret = 0; while (len > 0) { count = __do_write(file, buf, len, ppos); if (count == 0) break; if (count < 0) { ret = count; break; } len -= count; buf += count; ret += count; } file->f_flags = saved_flags; return ret; }