diff --git a/fs/hmdfs/file_cloud.c b/fs/hmdfs/file_cloud.c index b7386be449d4b85f43f280a3bd95b65982970327..8c98656f86554b0c47c96f02d9a44af4c9a2a517 100644 --- a/fs/hmdfs/file_cloud.c +++ b/fs/hmdfs/file_cloud.c @@ -35,6 +35,7 @@ struct cloud_readpages_work { struct file *filp; loff_t pos; int cnt; + struct cred *cred; struct work_struct work; struct page *pages[0]; }; @@ -91,7 +92,7 @@ int hmdfs_file_open_cloud(struct inode *inode, struct file *file) } lower_file = file_open_root(&root_path, dir_path, - file->f_flags, file->f_mode); + file->f_flags | O_DIRECT, file->f_mode); path_put(&root_path); if (IS_ERR(lower_file)) { hmdfs_info("file_open_root failed: %ld", PTR_ERR(lower_file)); @@ -163,16 +164,20 @@ static void cloud_readpages_work_func(struct work_struct *work) void *pages_buf; int idx, ret; ssize_t read_len; + const struct cred *old_cred; struct cloud_readpages_work *cr_work; cr_work = container_of(work, struct cloud_readpages_work, work); read_len = cr_work->cnt * HMDFS_PAGE_SIZE; + old_cred = override_creds(cr_work->cred); pages_buf = vmap(cr_work->pages, cr_work->cnt, VM_MAP, PAGE_KERNEL); if (!pages_buf) goto out; + trace_hmdfs_readpages_cloud_work_begin(cr_work->cnt, cr_work->pos); ret = kernel_read(cr_work->filp, pages_buf, read_len, &cr_work->pos); + trace_hmdfs_readpages_cloud_work_end(cr_work->cnt, cr_work->pos); if (ret < 0) goto out_vunmap; @@ -186,6 +191,7 @@ static void cloud_readpages_work_func(struct work_struct *work) SetPageUptodate(cr_work->pages[idx]); unlock_page(cr_work->pages[idx]); } + revert_creds(old_cred); kfree(cr_work); } @@ -194,6 +200,7 @@ static int prepare_cloud_readpage_work(struct file *filp, int cnt, { struct cloud_readpages_work *cr_work; struct hmdfs_file_info *gfi = filp->private_data; + struct cred *cred = NULL; cr_work = kzalloc(sizeof(*cr_work) + sizeof(cr_work->pages[0]) * cnt, @@ -206,7 +213,12 @@ static int prepare_cloud_readpage_work(struct file *filp, int cnt, if (gfi) cr_work->filp = gfi->lower_file; else - cr_work->filp = filp; + goto out; + + cred = prepare_creds(); + if (!cred) + goto out; + cr_work->cred = cred; cr_work->pos = (loff_t)(vec[0]->index) << HMDFS_PAGE_OFFSET; cr_work->cnt = cnt; memcpy(cr_work->pages, vec, cnt * sizeof(*vec)); @@ -214,6 +226,9 @@ static int prepare_cloud_readpage_work(struct file *filp, int cnt, INIT_WORK(&cr_work->work, cloud_readpages_work_func); schedule_work(&cr_work->work); return 0; +out: + kfree(cr_work); + return -ENOMEM; } static int hmdfs_readpages_cloud(struct file *filp, diff --git a/fs/hmdfs/file_local.c b/fs/hmdfs/file_local.c index c9aaaaa9ebc9d06916015750e577a8fceab5513b..c563ea44ade1a60713d312b434f39c8c98e3ec59 100644 --- a/fs/hmdfs/file_local.c +++ b/fs/hmdfs/file_local.c @@ -36,7 +36,12 @@ int hmdfs_file_open_local(struct inode *inode, struct file *file) } hmdfs_get_lower_path(file->f_path.dentry, &lower_path); - lower_file = dentry_open(&lower_path, file->f_flags, cred); + if (inode->i_mapping != NULL && + inode->i_mapping->a_ops == &hmdfs_aops_cloud) + lower_file = dentry_open(&lower_path, file->f_flags | O_DIRECT, + cred); + else + lower_file = dentry_open(&lower_path, file->f_flags, cred); hmdfs_put_lower_path(&lower_path); if (IS_ERR(lower_file)) { err = PTR_ERR(lower_file); @@ -86,11 +91,13 @@ ssize_t hmdfs_do_read_iter(struct file *file, struct iov_iter *iter, if (!iov_iter_count(iter)) return 0; - if (file->f_inode->i_mapping->a_ops == &hmdfs_aops_cloud) { + if (file->f_inode->i_mapping != NULL && + file->f_inode->i_mapping->a_ops == &hmdfs_aops_cloud) { iocb = container_of(ppos, struct kiocb, ki_pos); ret = generic_file_read_iter(iocb, iter); - } else + } else { ret = vfs_iter_read(lower_file, iter, ppos, 0); + } hmdfs_file_accessed(file); return ret; diff --git a/fs/hmdfs/hmdfs_trace.h b/fs/hmdfs/hmdfs_trace.h index 15bedbaa5cfaf938a31d4bd2d00f85f37d694d5b..6b26662ccd2ef8b6892ba28b0b670a2cc577e62d 100644 --- a/fs/hmdfs/hmdfs_trace.h +++ b/fs/hmdfs/hmdfs_trace.h @@ -546,6 +546,46 @@ TRACE_EVENT(hmdfs_readpages_cloud, __entry->nr_pages, __entry->err) ); +TRACE_EVENT(hmdfs_readpages_cloud_work_begin, + + TP_PROTO(int cnt, loff_t pos), + + TP_ARGS(cnt, pos), + + TP_STRUCT__entry( + __field(int, cnt) + __field(loff_t, pos) + ), + + TP_fast_assign( + __entry->cnt = cnt; + __entry->pos = pos; + ), + + TP_printk("cnt:%d, pos:%llx", + __entry->cnt, __entry->pos) +); + +TRACE_EVENT(hmdfs_readpages_cloud_work_end, + + TP_PROTO(int cnt, loff_t pos), + + TP_ARGS(cnt, pos), + + TP_STRUCT__entry( + __field(int, cnt) + __field(loff_t, pos) + ), + + TP_fast_assign( + __entry->cnt = cnt; + __entry->pos = pos; + ), + + TP_printk("cnt:%d, pos:%llx", + __entry->cnt, __entry->pos) +); + TRACE_EVENT(hmdfs_client_recv_readpage, TP_PROTO(struct hmdfs_peer *con, unsigned long long remote_ino, diff --git a/fs/hmdfs/inode_cloud_merge.c b/fs/hmdfs/inode_cloud_merge.c index d0b5e58f9fbe00115ff6000aab77aafb1048624a..b3139fbf0da08cac6d3fbae12c278ba1b739372c 100644 --- a/fs/hmdfs/inode_cloud_merge.c +++ b/fs/hmdfs/inode_cloud_merge.c @@ -79,6 +79,7 @@ static struct inode *fill_inode_merge(struct super_block *sb, goto bad_inode; } + inode->i_mapping->a_ops = &hmdfs_aops_cloud; unlock_new_inode(inode); out: dput(fst_lo_d);