You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'for-linus-2' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull second vfs update from Al Viro:
"Now that net-next went in... Here's the next big chunk - killing
->aio_read() and ->aio_write().
There'll be one more pile today (direct_IO changes and
generic_write_checks() cleanups/fixes), but I'd prefer to keep that
one separate"
* 'for-linus-2' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (37 commits)
->aio_read and ->aio_write removed
pcm: another weird API abuse
infinibad: weird APIs switched to ->write_iter()
kill do_sync_read/do_sync_write
fuse: use iov_iter_get_pages() for non-splice path
fuse: switch to ->read_iter/->write_iter
switch drivers/char/mem.c to ->read_iter/->write_iter
make new_sync_{read,write}() static
coredump: accept any write method
switch /dev/loop to vfs_iter_write()
serial2002: switch to __vfs_read/__vfs_write
ashmem: use __vfs_read()
export __vfs_read()
autofs: switch to __vfs_write()
new helper: __vfs_write()
switch hugetlbfs to ->read_iter()
coda: switch to ->read_iter/->write_iter
ncpfs: switch to ->read_iter/->write_iter
net/9p: remove (now-)unused helpers
p9_client_attach(): set fid->uid correctly
...
This commit is contained in:
@@ -68,14 +68,10 @@ int v9fs_file_open(struct inode *inode, struct file *file);
|
||||
void v9fs_inode2stat(struct inode *inode, struct p9_wstat *stat);
|
||||
int v9fs_uflags2omode(int uflags, int extended);
|
||||
|
||||
ssize_t v9fs_file_readn(struct file *, char *, char __user *, u32, u64);
|
||||
ssize_t v9fs_fid_readn(struct p9_fid *, char *, char __user *, u32, u64);
|
||||
void v9fs_blank_wstat(struct p9_wstat *wstat);
|
||||
int v9fs_vfs_setattr_dotl(struct dentry *, struct iattr *);
|
||||
int v9fs_file_fsync_dotl(struct file *filp, loff_t start, loff_t end,
|
||||
int datasync);
|
||||
ssize_t v9fs_file_write_internal(struct inode *, struct p9_fid *,
|
||||
const char __user *, size_t, loff_t *, int);
|
||||
int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode);
|
||||
int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode);
|
||||
static inline void v9fs_invalidate_inode_attr(struct inode *inode)
|
||||
|
||||
+37
-43
@@ -51,12 +51,11 @@
|
||||
*/
|
||||
static int v9fs_fid_readpage(struct p9_fid *fid, struct page *page)
|
||||
{
|
||||
int retval;
|
||||
loff_t offset;
|
||||
char *buffer;
|
||||
struct inode *inode;
|
||||
struct inode *inode = page->mapping->host;
|
||||
struct bio_vec bvec = {.bv_page = page, .bv_len = PAGE_SIZE};
|
||||
struct iov_iter to;
|
||||
int retval, err;
|
||||
|
||||
inode = page->mapping->host;
|
||||
p9_debug(P9_DEBUG_VFS, "\n");
|
||||
|
||||
BUG_ON(!PageLocked(page));
|
||||
@@ -65,16 +64,16 @@ static int v9fs_fid_readpage(struct p9_fid *fid, struct page *page)
|
||||
if (retval == 0)
|
||||
return retval;
|
||||
|
||||
buffer = kmap(page);
|
||||
offset = page_offset(page);
|
||||
iov_iter_bvec(&to, ITER_BVEC | READ, &bvec, 1, PAGE_SIZE);
|
||||
|
||||
retval = v9fs_fid_readn(fid, buffer, NULL, PAGE_CACHE_SIZE, offset);
|
||||
if (retval < 0) {
|
||||
retval = p9_client_read(fid, page_offset(page), &to, &err);
|
||||
if (err) {
|
||||
v9fs_uncache_page(inode, page);
|
||||
retval = err;
|
||||
goto done;
|
||||
}
|
||||
|
||||
memset(buffer + retval, 0, PAGE_CACHE_SIZE - retval);
|
||||
zero_user(page, retval, PAGE_SIZE - retval);
|
||||
flush_dcache_page(page);
|
||||
SetPageUptodate(page);
|
||||
|
||||
@@ -82,7 +81,6 @@ static int v9fs_fid_readpage(struct p9_fid *fid, struct page *page)
|
||||
retval = 0;
|
||||
|
||||
done:
|
||||
kunmap(page);
|
||||
unlock_page(page);
|
||||
return retval;
|
||||
}
|
||||
@@ -161,41 +159,32 @@ static void v9fs_invalidate_page(struct page *page, unsigned int offset,
|
||||
|
||||
static int v9fs_vfs_writepage_locked(struct page *page)
|
||||
{
|
||||
char *buffer;
|
||||
int retval, len;
|
||||
loff_t offset, size;
|
||||
mm_segment_t old_fs;
|
||||
struct v9fs_inode *v9inode;
|
||||
struct inode *inode = page->mapping->host;
|
||||
struct v9fs_inode *v9inode = V9FS_I(inode);
|
||||
loff_t size = i_size_read(inode);
|
||||
struct iov_iter from;
|
||||
struct bio_vec bvec;
|
||||
int err, len;
|
||||
|
||||
v9inode = V9FS_I(inode);
|
||||
size = i_size_read(inode);
|
||||
if (page->index == size >> PAGE_CACHE_SHIFT)
|
||||
len = size & ~PAGE_CACHE_MASK;
|
||||
else
|
||||
len = PAGE_CACHE_SIZE;
|
||||
|
||||
set_page_writeback(page);
|
||||
bvec.bv_page = page;
|
||||
bvec.bv_offset = 0;
|
||||
bvec.bv_len = len;
|
||||
iov_iter_bvec(&from, ITER_BVEC | WRITE, &bvec, 1, len);
|
||||
|
||||
buffer = kmap(page);
|
||||
offset = page_offset(page);
|
||||
|
||||
old_fs = get_fs();
|
||||
set_fs(get_ds());
|
||||
/* We should have writeback_fid always set */
|
||||
BUG_ON(!v9inode->writeback_fid);
|
||||
|
||||
retval = v9fs_file_write_internal(inode,
|
||||
v9inode->writeback_fid,
|
||||
(__force const char __user *)buffer,
|
||||
len, &offset, 0);
|
||||
if (retval > 0)
|
||||
retval = 0;
|
||||
set_page_writeback(page);
|
||||
|
||||
p9_client_write(v9inode->writeback_fid, page_offset(page), &from, &err);
|
||||
|
||||
set_fs(old_fs);
|
||||
kunmap(page);
|
||||
end_page_writeback(page);
|
||||
return retval;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int v9fs_vfs_writepage(struct page *page, struct writeback_control *wbc)
|
||||
@@ -261,16 +250,21 @@ static int v9fs_launder_page(struct page *page)
|
||||
static ssize_t
|
||||
v9fs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, loff_t pos)
|
||||
{
|
||||
/*
|
||||
* FIXME
|
||||
* Now that we do caching with cache mode enabled, We need
|
||||
* to support direct IO
|
||||
*/
|
||||
p9_debug(P9_DEBUG_VFS, "v9fs_direct_IO: v9fs_direct_IO (%pD) off/no(%lld/%lu) EINVAL\n",
|
||||
iocb->ki_filp,
|
||||
(long long)pos, iter->nr_segs);
|
||||
|
||||
return -EINVAL;
|
||||
struct file *file = iocb->ki_filp;
|
||||
ssize_t n;
|
||||
int err = 0;
|
||||
if (rw & WRITE) {
|
||||
n = p9_client_write(file->private_data, pos, iter, &err);
|
||||
if (n) {
|
||||
struct inode *inode = file_inode(file);
|
||||
loff_t i_size = i_size_read(inode);
|
||||
if (pos + n > i_size)
|
||||
inode_add_bytes(inode, pos + n - i_size);
|
||||
}
|
||||
} else {
|
||||
n = p9_client_read(file->private_data, pos, iter, &err);
|
||||
}
|
||||
return n ? n : err;
|
||||
}
|
||||
|
||||
static int v9fs_write_begin(struct file *filp, struct address_space *mapping,
|
||||
|
||||
+11
-4
@@ -33,6 +33,7 @@
|
||||
#include <linux/inet.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/uio.h>
|
||||
#include <net/9p/9p.h>
|
||||
#include <net/9p/client.h>
|
||||
|
||||
@@ -115,6 +116,7 @@ static int v9fs_dir_readdir(struct file *file, struct dir_context *ctx)
|
||||
int buflen;
|
||||
int reclen = 0;
|
||||
struct p9_rdir *rdir;
|
||||
struct kvec kvec;
|
||||
|
||||
p9_debug(P9_DEBUG_VFS, "name %pD\n", file);
|
||||
fid = file->private_data;
|
||||
@@ -124,16 +126,21 @@ static int v9fs_dir_readdir(struct file *file, struct dir_context *ctx)
|
||||
rdir = v9fs_alloc_rdir_buf(file, buflen);
|
||||
if (!rdir)
|
||||
return -ENOMEM;
|
||||
kvec.iov_base = rdir->buf;
|
||||
kvec.iov_len = buflen;
|
||||
|
||||
while (1) {
|
||||
if (rdir->tail == rdir->head) {
|
||||
err = v9fs_file_readn(file, rdir->buf, NULL,
|
||||
buflen, ctx->pos);
|
||||
if (err <= 0)
|
||||
struct iov_iter to;
|
||||
int n;
|
||||
iov_iter_kvec(&to, READ | ITER_KVEC, &kvec, 1, buflen);
|
||||
n = p9_client_read(file->private_data, ctx->pos, &to,
|
||||
&err);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
rdir->head = 0;
|
||||
rdir->tail = err;
|
||||
rdir->tail = n;
|
||||
}
|
||||
while (rdir->head < rdir->tail) {
|
||||
p9stat_init(&st);
|
||||
|
||||
+54
-260
@@ -36,6 +36,8 @@
|
||||
#include <linux/utsname.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/uio.h>
|
||||
#include <linux/slab.h>
|
||||
#include <net/9p/9p.h>
|
||||
#include <net/9p/client.h>
|
||||
|
||||
@@ -285,6 +287,7 @@ static int v9fs_file_getlock(struct file *filp, struct file_lock *fl)
|
||||
fl->fl_end = glock.start + glock.length - 1;
|
||||
fl->fl_pid = glock.proc_id;
|
||||
}
|
||||
kfree(glock.client_id);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -363,63 +366,6 @@ out_err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* v9fs_fid_readn - read from a fid
|
||||
* @fid: fid to read
|
||||
* @data: data buffer to read data into
|
||||
* @udata: user data buffer to read data into
|
||||
* @count: size of buffer
|
||||
* @offset: offset at which to read data
|
||||
*
|
||||
*/
|
||||
ssize_t
|
||||
v9fs_fid_readn(struct p9_fid *fid, char *data, char __user *udata, u32 count,
|
||||
u64 offset)
|
||||
{
|
||||
int n, total, size;
|
||||
|
||||
p9_debug(P9_DEBUG_VFS, "fid %d offset %llu count %d\n",
|
||||
fid->fid, (long long unsigned)offset, count);
|
||||
n = 0;
|
||||
total = 0;
|
||||
size = fid->iounit ? fid->iounit : fid->clnt->msize - P9_IOHDRSZ;
|
||||
do {
|
||||
n = p9_client_read(fid, data, udata, offset, count);
|
||||
if (n <= 0)
|
||||
break;
|
||||
|
||||
if (data)
|
||||
data += n;
|
||||
if (udata)
|
||||
udata += n;
|
||||
|
||||
offset += n;
|
||||
count -= n;
|
||||
total += n;
|
||||
} while (count > 0 && n == size);
|
||||
|
||||
if (n < 0)
|
||||
total = n;
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
/**
|
||||
* v9fs_file_readn - read from a file
|
||||
* @filp: file pointer to read
|
||||
* @data: data buffer to read data into
|
||||
* @udata: user data buffer to read data into
|
||||
* @count: size of buffer
|
||||
* @offset: offset at which to read data
|
||||
*
|
||||
*/
|
||||
ssize_t
|
||||
v9fs_file_readn(struct file *filp, char *data, char __user *udata, u32 count,
|
||||
u64 offset)
|
||||
{
|
||||
return v9fs_fid_readn(filp->private_data, data, udata, count, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* v9fs_file_read - read from a file
|
||||
* @filp: file pointer to read
|
||||
@@ -430,69 +376,22 @@ v9fs_file_readn(struct file *filp, char *data, char __user *udata, u32 count,
|
||||
*/
|
||||
|
||||
static ssize_t
|
||||
v9fs_file_read(struct file *filp, char __user *udata, size_t count,
|
||||
loff_t * offset)
|
||||
v9fs_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
|
||||
{
|
||||
int ret;
|
||||
struct p9_fid *fid;
|
||||
size_t size;
|
||||
struct p9_fid *fid = iocb->ki_filp->private_data;
|
||||
int ret, err;
|
||||
|
||||
p9_debug(P9_DEBUG_VFS, "count %zu offset %lld\n", count, *offset);
|
||||
fid = filp->private_data;
|
||||
p9_debug(P9_DEBUG_VFS, "count %zu offset %lld\n",
|
||||
iov_iter_count(to), iocb->ki_pos);
|
||||
|
||||
size = fid->iounit ? fid->iounit : fid->clnt->msize - P9_IOHDRSZ;
|
||||
if (count > size)
|
||||
ret = v9fs_file_readn(filp, NULL, udata, count, *offset);
|
||||
else
|
||||
ret = p9_client_read(fid, NULL, udata, *offset, count);
|
||||
|
||||
if (ret > 0)
|
||||
*offset += ret;
|
||||
ret = p9_client_read(fid, iocb->ki_pos, to, &err);
|
||||
if (!ret)
|
||||
return err;
|
||||
|
||||
iocb->ki_pos += ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
v9fs_file_write_internal(struct inode *inode, struct p9_fid *fid,
|
||||
const char __user *data, size_t count,
|
||||
loff_t *offset, int invalidate)
|
||||
{
|
||||
int n;
|
||||
loff_t i_size;
|
||||
size_t total = 0;
|
||||
loff_t origin = *offset;
|
||||
unsigned long pg_start, pg_end;
|
||||
|
||||
p9_debug(P9_DEBUG_VFS, "data %p count %d offset %x\n",
|
||||
data, (int)count, (int)*offset);
|
||||
|
||||
do {
|
||||
n = p9_client_write(fid, NULL, data+total, origin+total, count);
|
||||
if (n <= 0)
|
||||
break;
|
||||
count -= n;
|
||||
total += n;
|
||||
} while (count > 0);
|
||||
|
||||
if (invalidate && (total > 0)) {
|
||||
pg_start = origin >> PAGE_CACHE_SHIFT;
|
||||
pg_end = (origin + total - 1) >> PAGE_CACHE_SHIFT;
|
||||
if (inode->i_mapping && inode->i_mapping->nrpages)
|
||||
invalidate_inode_pages2_range(inode->i_mapping,
|
||||
pg_start, pg_end);
|
||||
*offset += total;
|
||||
i_size = i_size_read(inode);
|
||||
if (*offset > i_size) {
|
||||
inode_add_bytes(inode, *offset - i_size);
|
||||
i_size_write(inode, *offset);
|
||||
}
|
||||
}
|
||||
if (n < 0)
|
||||
return n;
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
/**
|
||||
* v9fs_file_write - write to a file
|
||||
* @filp: file pointer to write
|
||||
@@ -502,35 +401,45 @@ v9fs_file_write_internal(struct inode *inode, struct p9_fid *fid,
|
||||
*
|
||||
*/
|
||||
static ssize_t
|
||||
v9fs_file_write(struct file *filp, const char __user * data,
|
||||
size_t count, loff_t *offset)
|
||||
v9fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
|
||||
{
|
||||
struct file *file = iocb->ki_filp;
|
||||
ssize_t retval = 0;
|
||||
loff_t origin = *offset;
|
||||
loff_t origin = iocb->ki_pos;
|
||||
size_t count = iov_iter_count(from);
|
||||
int err = 0;
|
||||
|
||||
|
||||
retval = generic_write_checks(filp, &origin, &count, 0);
|
||||
retval = generic_write_checks(file, &origin, &count, 0);
|
||||
if (retval)
|
||||
goto out;
|
||||
return retval;
|
||||
|
||||
iov_iter_truncate(from, count);
|
||||
|
||||
retval = -EINVAL;
|
||||
if ((ssize_t) count < 0)
|
||||
goto out;
|
||||
retval = 0;
|
||||
if (!count)
|
||||
goto out;
|
||||
return 0;
|
||||
|
||||
retval = v9fs_file_write_internal(file_inode(filp),
|
||||
filp->private_data,
|
||||
data, count, &origin, 1);
|
||||
/* update offset on successful write */
|
||||
if (retval > 0)
|
||||
*offset = origin;
|
||||
out:
|
||||
return retval;
|
||||
retval = p9_client_write(file->private_data, origin, from, &err);
|
||||
if (retval > 0) {
|
||||
struct inode *inode = file_inode(file);
|
||||
loff_t i_size;
|
||||
unsigned long pg_start, pg_end;
|
||||
pg_start = origin >> PAGE_CACHE_SHIFT;
|
||||
pg_end = (origin + retval - 1) >> PAGE_CACHE_SHIFT;
|
||||
if (inode->i_mapping && inode->i_mapping->nrpages)
|
||||
invalidate_inode_pages2_range(inode->i_mapping,
|
||||
pg_start, pg_end);
|
||||
origin += retval;
|
||||
i_size = i_size_read(inode);
|
||||
iocb->ki_pos = origin;
|
||||
if (origin > i_size) {
|
||||
inode_add_bytes(inode, origin - i_size);
|
||||
i_size_write(inode, origin);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static int v9fs_file_fsync(struct file *filp, loff_t start, loff_t end,
|
||||
int datasync)
|
||||
{
|
||||
@@ -657,44 +566,6 @@ out_unlock:
|
||||
return VM_FAULT_NOPAGE;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
v9fs_direct_read(struct file *filp, char __user *udata, size_t count,
|
||||
loff_t *offsetp)
|
||||
{
|
||||
loff_t size, offset;
|
||||
struct inode *inode;
|
||||
struct address_space *mapping;
|
||||
|
||||
offset = *offsetp;
|
||||
mapping = filp->f_mapping;
|
||||
inode = mapping->host;
|
||||
if (!count)
|
||||
return 0;
|
||||
size = i_size_read(inode);
|
||||
if (offset < size)
|
||||
filemap_write_and_wait_range(mapping, offset,
|
||||
offset + count - 1);
|
||||
|
||||
return v9fs_file_read(filp, udata, count, offsetp);
|
||||
}
|
||||
|
||||
/**
|
||||
* v9fs_cached_file_read - read from a file
|
||||
* @filp: file pointer to read
|
||||
* @data: user data buffer to read data into
|
||||
* @count: size of buffer
|
||||
* @offset: offset at which to read data
|
||||
*
|
||||
*/
|
||||
static ssize_t
|
||||
v9fs_cached_file_read(struct file *filp, char __user *data, size_t count,
|
||||
loff_t *offset)
|
||||
{
|
||||
if (filp->f_flags & O_DIRECT)
|
||||
return v9fs_direct_read(filp, data, count, offset);
|
||||
return new_sync_read(filp, data, count, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* v9fs_mmap_file_read - read from a file
|
||||
* @filp: file pointer to read
|
||||
@@ -704,84 +575,12 @@ v9fs_cached_file_read(struct file *filp, char __user *data, size_t count,
|
||||
*
|
||||
*/
|
||||
static ssize_t
|
||||
v9fs_mmap_file_read(struct file *filp, char __user *data, size_t count,
|
||||
loff_t *offset)
|
||||
v9fs_mmap_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
|
||||
{
|
||||
/* TODO: Check if there are dirty pages */
|
||||
return v9fs_file_read(filp, data, count, offset);
|
||||
return v9fs_file_read_iter(iocb, to);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
v9fs_direct_write(struct file *filp, const char __user * data,
|
||||
size_t count, loff_t *offsetp)
|
||||
{
|
||||
loff_t offset;
|
||||
ssize_t retval;
|
||||
struct inode *inode;
|
||||
struct address_space *mapping;
|
||||
|
||||
offset = *offsetp;
|
||||
mapping = filp->f_mapping;
|
||||
inode = mapping->host;
|
||||
if (!count)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&inode->i_mutex);
|
||||
retval = filemap_write_and_wait_range(mapping, offset,
|
||||
offset + count - 1);
|
||||
if (retval)
|
||||
goto err_out;
|
||||
/*
|
||||
* After a write we want buffered reads to be sure to go to disk to get
|
||||
* the new data. We invalidate clean cached page from the region we're
|
||||
* about to write. We do this *before* the write so that if we fail
|
||||
* here we fall back to buffered write
|
||||
*/
|
||||
if (mapping->nrpages) {
|
||||
pgoff_t pg_start = offset >> PAGE_CACHE_SHIFT;
|
||||
pgoff_t pg_end = (offset + count - 1) >> PAGE_CACHE_SHIFT;
|
||||
|
||||
retval = invalidate_inode_pages2_range(mapping,
|
||||
pg_start, pg_end);
|
||||
/*
|
||||
* If a page can not be invalidated, fall back
|
||||
* to buffered write.
|
||||
*/
|
||||
if (retval) {
|
||||
if (retval == -EBUSY)
|
||||
goto buff_write;
|
||||
goto err_out;
|
||||
}
|
||||
}
|
||||
retval = v9fs_file_write(filp, data, count, offsetp);
|
||||
err_out:
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
return retval;
|
||||
|
||||
buff_write:
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
return new_sync_write(filp, data, count, offsetp);
|
||||
}
|
||||
|
||||
/**
|
||||
* v9fs_cached_file_write - write to a file
|
||||
* @filp: file pointer to write
|
||||
* @data: data buffer to write data from
|
||||
* @count: size of buffer
|
||||
* @offset: offset at which to write data
|
||||
*
|
||||
*/
|
||||
static ssize_t
|
||||
v9fs_cached_file_write(struct file *filp, const char __user * data,
|
||||
size_t count, loff_t *offset)
|
||||
{
|
||||
|
||||
if (filp->f_flags & O_DIRECT)
|
||||
return v9fs_direct_write(filp, data, count, offset);
|
||||
return new_sync_write(filp, data, count, offset);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* v9fs_mmap_file_write - write to a file
|
||||
* @filp: file pointer to write
|
||||
@@ -791,14 +590,13 @@ v9fs_cached_file_write(struct file *filp, const char __user * data,
|
||||
*
|
||||
*/
|
||||
static ssize_t
|
||||
v9fs_mmap_file_write(struct file *filp, const char __user *data,
|
||||
size_t count, loff_t *offset)
|
||||
v9fs_mmap_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
|
||||
{
|
||||
/*
|
||||
* TODO: invalidate mmaps on filp's inode between
|
||||
* offset and offset+count
|
||||
*/
|
||||
return v9fs_file_write(filp, data, count, offset);
|
||||
return v9fs_file_write_iter(iocb, from);
|
||||
}
|
||||
|
||||
static void v9fs_mmap_vm_close(struct vm_area_struct *vma)
|
||||
@@ -843,8 +641,6 @@ static const struct vm_operations_struct v9fs_mmap_file_vm_ops = {
|
||||
|
||||
const struct file_operations v9fs_cached_file_operations = {
|
||||
.llseek = generic_file_llseek,
|
||||
.read = v9fs_cached_file_read,
|
||||
.write = v9fs_cached_file_write,
|
||||
.read_iter = generic_file_read_iter,
|
||||
.write_iter = generic_file_write_iter,
|
||||
.open = v9fs_file_open,
|
||||
@@ -856,8 +652,6 @@ const struct file_operations v9fs_cached_file_operations = {
|
||||
|
||||
const struct file_operations v9fs_cached_file_operations_dotl = {
|
||||
.llseek = generic_file_llseek,
|
||||
.read = v9fs_cached_file_read,
|
||||
.write = v9fs_cached_file_write,
|
||||
.read_iter = generic_file_read_iter,
|
||||
.write_iter = generic_file_write_iter,
|
||||
.open = v9fs_file_open,
|
||||
@@ -870,8 +664,8 @@ const struct file_operations v9fs_cached_file_operations_dotl = {
|
||||
|
||||
const struct file_operations v9fs_file_operations = {
|
||||
.llseek = generic_file_llseek,
|
||||
.read = v9fs_file_read,
|
||||
.write = v9fs_file_write,
|
||||
.read_iter = v9fs_file_read_iter,
|
||||
.write_iter = v9fs_file_write_iter,
|
||||
.open = v9fs_file_open,
|
||||
.release = v9fs_dir_release,
|
||||
.lock = v9fs_file_lock,
|
||||
@@ -881,8 +675,8 @@ const struct file_operations v9fs_file_operations = {
|
||||
|
||||
const struct file_operations v9fs_file_operations_dotl = {
|
||||
.llseek = generic_file_llseek,
|
||||
.read = v9fs_file_read,
|
||||
.write = v9fs_file_write,
|
||||
.read_iter = v9fs_file_read_iter,
|
||||
.write_iter = v9fs_file_write_iter,
|
||||
.open = v9fs_file_open,
|
||||
.release = v9fs_dir_release,
|
||||
.lock = v9fs_file_lock_dotl,
|
||||
@@ -893,8 +687,8 @@ const struct file_operations v9fs_file_operations_dotl = {
|
||||
|
||||
const struct file_operations v9fs_mmap_file_operations = {
|
||||
.llseek = generic_file_llseek,
|
||||
.read = v9fs_mmap_file_read,
|
||||
.write = v9fs_mmap_file_write,
|
||||
.read_iter = v9fs_mmap_file_read_iter,
|
||||
.write_iter = v9fs_mmap_file_write_iter,
|
||||
.open = v9fs_file_open,
|
||||
.release = v9fs_dir_release,
|
||||
.lock = v9fs_file_lock,
|
||||
@@ -904,8 +698,8 @@ const struct file_operations v9fs_mmap_file_operations = {
|
||||
|
||||
const struct file_operations v9fs_mmap_file_operations_dotl = {
|
||||
.llseek = generic_file_llseek,
|
||||
.read = v9fs_mmap_file_read,
|
||||
.write = v9fs_mmap_file_write,
|
||||
.read_iter = v9fs_mmap_file_read_iter,
|
||||
.write_iter = v9fs_mmap_file_write_iter,
|
||||
.open = v9fs_file_open,
|
||||
.release = v9fs_dir_release,
|
||||
.lock = v9fs_file_lock_dotl,
|
||||
|
||||
+25
-55
@@ -15,6 +15,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/uio.h>
|
||||
#include <net/9p/9p.h>
|
||||
#include <net/9p/client.h>
|
||||
|
||||
@@ -25,50 +26,34 @@ ssize_t v9fs_fid_xattr_get(struct p9_fid *fid, const char *name,
|
||||
void *buffer, size_t buffer_size)
|
||||
{
|
||||
ssize_t retval;
|
||||
int msize, read_count;
|
||||
u64 offset = 0, attr_size;
|
||||
u64 attr_size;
|
||||
struct p9_fid *attr_fid;
|
||||
struct kvec kvec = {.iov_base = buffer, .iov_len = buffer_size};
|
||||
struct iov_iter to;
|
||||
int err;
|
||||
|
||||
iov_iter_kvec(&to, READ | ITER_KVEC, &kvec, 1, buffer_size);
|
||||
|
||||
attr_fid = p9_client_xattrwalk(fid, name, &attr_size);
|
||||
if (IS_ERR(attr_fid)) {
|
||||
retval = PTR_ERR(attr_fid);
|
||||
p9_debug(P9_DEBUG_VFS, "p9_client_attrwalk failed %zd\n",
|
||||
retval);
|
||||
attr_fid = NULL;
|
||||
goto error;
|
||||
}
|
||||
if (!buffer_size) {
|
||||
/* request to get the attr_size */
|
||||
retval = attr_size;
|
||||
goto error;
|
||||
return retval;
|
||||
}
|
||||
if (attr_size > buffer_size) {
|
||||
retval = -ERANGE;
|
||||
goto error;
|
||||
}
|
||||
msize = attr_fid->clnt->msize;
|
||||
while (attr_size) {
|
||||
if (attr_size > (msize - P9_IOHDRSZ))
|
||||
read_count = msize - P9_IOHDRSZ;
|
||||
if (!buffer_size) /* request to get the attr_size */
|
||||
retval = attr_size;
|
||||
else
|
||||
read_count = attr_size;
|
||||
read_count = p9_client_read(attr_fid, ((char *)buffer)+offset,
|
||||
NULL, offset, read_count);
|
||||
if (read_count < 0) {
|
||||
/* error in xattr read */
|
||||
retval = read_count;
|
||||
goto error;
|
||||
}
|
||||
offset += read_count;
|
||||
attr_size -= read_count;
|
||||
retval = -ERANGE;
|
||||
} else {
|
||||
iov_iter_truncate(&to, attr_size);
|
||||
retval = p9_client_read(attr_fid, 0, &to, &err);
|
||||
if (err)
|
||||
retval = err;
|
||||
}
|
||||
/* Total read xattr bytes */
|
||||
retval = offset;
|
||||
error:
|
||||
if (attr_fid)
|
||||
p9_client_clunk(attr_fid);
|
||||
p9_client_clunk(attr_fid);
|
||||
return retval;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -120,8 +105,11 @@ int v9fs_xattr_set(struct dentry *dentry, const char *name,
|
||||
int v9fs_fid_xattr_set(struct p9_fid *fid, const char *name,
|
||||
const void *value, size_t value_len, int flags)
|
||||
{
|
||||
u64 offset = 0;
|
||||
int retval, msize, write_count;
|
||||
struct kvec kvec = {.iov_base = (void *)value, .iov_len = value_len};
|
||||
struct iov_iter from;
|
||||
int retval;
|
||||
|
||||
iov_iter_kvec(&from, WRITE | ITER_KVEC, &kvec, 1, value_len);
|
||||
|
||||
p9_debug(P9_DEBUG_VFS, "name = %s value_len = %zu flags = %d\n",
|
||||
name, value_len, flags);
|
||||
@@ -135,29 +123,11 @@ int v9fs_fid_xattr_set(struct p9_fid *fid, const char *name,
|
||||
* On success fid points to xattr
|
||||
*/
|
||||
retval = p9_client_xattrcreate(fid, name, value_len, flags);
|
||||
if (retval < 0) {
|
||||
if (retval < 0)
|
||||
p9_debug(P9_DEBUG_VFS, "p9_client_xattrcreate failed %d\n",
|
||||
retval);
|
||||
goto err;
|
||||
}
|
||||
msize = fid->clnt->msize;
|
||||
while (value_len) {
|
||||
if (value_len > (msize - P9_IOHDRSZ))
|
||||
write_count = msize - P9_IOHDRSZ;
|
||||
else
|
||||
write_count = value_len;
|
||||
write_count = p9_client_write(fid, ((char *)value)+offset,
|
||||
NULL, offset, write_count);
|
||||
if (write_count < 0) {
|
||||
/* error in xattr write */
|
||||
retval = write_count;
|
||||
goto err;
|
||||
}
|
||||
offset += write_count;
|
||||
value_len -= write_count;
|
||||
}
|
||||
retval = 0;
|
||||
err:
|
||||
else
|
||||
p9_client_write(fid, 0, &from, &retval);
|
||||
p9_client_clunk(fid);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -23,11 +23,9 @@
|
||||
|
||||
const struct file_operations adfs_file_operations = {
|
||||
.llseek = generic_file_llseek,
|
||||
.read = new_sync_read,
|
||||
.read_iter = generic_file_read_iter,
|
||||
.mmap = generic_file_mmap,
|
||||
.fsync = generic_file_fsync,
|
||||
.write = new_sync_write,
|
||||
.write_iter = generic_file_write_iter,
|
||||
.splice_read = generic_file_splice_read,
|
||||
};
|
||||
|
||||
@@ -969,9 +969,7 @@ int affs_file_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
|
||||
}
|
||||
const struct file_operations affs_file_operations = {
|
||||
.llseek = generic_file_llseek,
|
||||
.read = new_sync_read,
|
||||
.read_iter = generic_file_read_iter,
|
||||
.write = new_sync_write,
|
||||
.write_iter = generic_file_write_iter,
|
||||
.mmap = generic_file_mmap,
|
||||
.open = affs_file_open,
|
||||
|
||||
@@ -31,8 +31,6 @@ const struct file_operations afs_file_operations = {
|
||||
.open = afs_open,
|
||||
.release = afs_release,
|
||||
.llseek = generic_file_llseek,
|
||||
.read = new_sync_read,
|
||||
.write = new_sync_write,
|
||||
.read_iter = generic_file_read_iter,
|
||||
.write_iter = afs_file_write,
|
||||
.mmap = generic_file_readonly_mmap,
|
||||
|
||||
@@ -692,8 +692,7 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
|
||||
nr_events *= 2;
|
||||
|
||||
/* Prevent overflows */
|
||||
if ((nr_events > (0x10000000U / sizeof(struct io_event))) ||
|
||||
(nr_events > (0x10000000U / sizeof(struct kiocb)))) {
|
||||
if (nr_events > (0x10000000U / sizeof(struct io_event))) {
|
||||
pr_debug("ENOMEM: nr_events too high\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
@@ -1356,8 +1355,6 @@ SYSCALL_DEFINE1(io_destroy, aio_context_t, ctx)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
typedef ssize_t (aio_rw_op)(struct kiocb *, const struct iovec *,
|
||||
unsigned long, loff_t);
|
||||
typedef ssize_t (rw_iter_op)(struct kiocb *, struct iov_iter *);
|
||||
|
||||
static int aio_setup_vectored_rw(int rw, char __user *buf, size_t len,
|
||||
@@ -1386,7 +1383,6 @@ static ssize_t aio_run_iocb(struct kiocb *req, unsigned opcode,
|
||||
ssize_t ret;
|
||||
int rw;
|
||||
fmode_t mode;
|
||||
aio_rw_op *rw_op;
|
||||
rw_iter_op *iter_op;
|
||||
struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs;
|
||||
struct iov_iter iter;
|
||||
@@ -1396,7 +1392,6 @@ static ssize_t aio_run_iocb(struct kiocb *req, unsigned opcode,
|
||||
case IOCB_CMD_PREADV:
|
||||
mode = FMODE_READ;
|
||||
rw = READ;
|
||||
rw_op = file->f_op->aio_read;
|
||||
iter_op = file->f_op->read_iter;
|
||||
goto rw_common;
|
||||
|
||||
@@ -1404,14 +1399,13 @@ static ssize_t aio_run_iocb(struct kiocb *req, unsigned opcode,
|
||||
case IOCB_CMD_PWRITEV:
|
||||
mode = FMODE_WRITE;
|
||||
rw = WRITE;
|
||||
rw_op = file->f_op->aio_write;
|
||||
iter_op = file->f_op->write_iter;
|
||||
goto rw_common;
|
||||
rw_common:
|
||||
if (unlikely(!(file->f_mode & mode)))
|
||||
return -EBADF;
|
||||
|
||||
if (!rw_op && !iter_op)
|
||||
if (!iter_op)
|
||||
return -EINVAL;
|
||||
|
||||
if (opcode == IOCB_CMD_PREADV || opcode == IOCB_CMD_PWRITEV)
|
||||
@@ -1431,21 +1425,10 @@ rw_common:
|
||||
|
||||
len = ret;
|
||||
|
||||
/* XXX: move/kill - rw_verify_area()? */
|
||||
/* This matches the pread()/pwrite() logic */
|
||||
if (req->ki_pos < 0) {
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (rw == WRITE)
|
||||
file_start_write(file);
|
||||
|
||||
if (iter_op) {
|
||||
ret = iter_op(req, &iter);
|
||||
} else {
|
||||
ret = rw_op(req, iter.iov, iter.nr_segs, req->ki_pos);
|
||||
}
|
||||
ret = iter_op(req, &iter);
|
||||
|
||||
if (rw == WRITE)
|
||||
file_end_write(file);
|
||||
|
||||
@@ -213,7 +213,7 @@ void autofs4_clean_ino(struct autofs_info *);
|
||||
|
||||
static inline int autofs_prepare_pipe(struct file *pipe)
|
||||
{
|
||||
if (!pipe->f_op->write)
|
||||
if (!(pipe->f_mode & FMODE_CAN_WRITE))
|
||||
return -EINVAL;
|
||||
if (!S_ISFIFO(file_inode(pipe)->i_mode))
|
||||
return -EINVAL;
|
||||
|
||||
+1
-1
@@ -70,7 +70,7 @@ static int autofs4_write(struct autofs_sb_info *sbi,
|
||||
|
||||
mutex_lock(&sbi->pipe_mutex);
|
||||
while (bytes &&
|
||||
(wr = file->f_op->write(file,data,bytes,&file->f_pos)) > 0) {
|
||||
(wr = __vfs_write(file,data,bytes,&file->f_pos)) > 0) {
|
||||
data += wr;
|
||||
bytes -= wr;
|
||||
}
|
||||
|
||||
@@ -23,9 +23,7 @@
|
||||
|
||||
const struct file_operations bfs_file_operations = {
|
||||
.llseek = generic_file_llseek,
|
||||
.read = new_sync_read,
|
||||
.read_iter = generic_file_read_iter,
|
||||
.write = new_sync_write,
|
||||
.write_iter = generic_file_write_iter,
|
||||
.mmap = generic_file_mmap,
|
||||
.splice_read = generic_file_splice_read,
|
||||
|
||||
@@ -1659,8 +1659,6 @@ const struct file_operations def_blk_fops = {
|
||||
.open = blkdev_open,
|
||||
.release = blkdev_close,
|
||||
.llseek = block_llseek,
|
||||
.read = new_sync_read,
|
||||
.write = new_sync_write,
|
||||
.read_iter = blkdev_read_iter,
|
||||
.write_iter = blkdev_write_iter,
|
||||
.mmap = generic_file_mmap,
|
||||
|
||||
@@ -2806,8 +2806,6 @@ out:
|
||||
|
||||
const struct file_operations btrfs_file_operations = {
|
||||
.llseek = btrfs_file_llseek,
|
||||
.read = new_sync_read,
|
||||
.write = new_sync_write,
|
||||
.read_iter = generic_file_read_iter,
|
||||
.splice_read = generic_file_splice_read,
|
||||
.write_iter = btrfs_file_write_iter,
|
||||
|
||||
@@ -1331,8 +1331,6 @@ const struct file_operations ceph_file_fops = {
|
||||
.open = ceph_open,
|
||||
.release = ceph_release,
|
||||
.llseek = ceph_llseek,
|
||||
.read = new_sync_read,
|
||||
.write = new_sync_write,
|
||||
.read_iter = ceph_read_iter,
|
||||
.write_iter = ceph_write_iter,
|
||||
.mmap = ceph_mmap,
|
||||
|
||||
@@ -906,8 +906,6 @@ const struct inode_operations cifs_symlink_inode_ops = {
|
||||
};
|
||||
|
||||
const struct file_operations cifs_file_ops = {
|
||||
.read = new_sync_read,
|
||||
.write = new_sync_write,
|
||||
.read_iter = cifs_loose_read_iter,
|
||||
.write_iter = cifs_file_write_iter,
|
||||
.open = cifs_open,
|
||||
@@ -926,8 +924,6 @@ const struct file_operations cifs_file_ops = {
|
||||
};
|
||||
|
||||
const struct file_operations cifs_file_strict_ops = {
|
||||
.read = new_sync_read,
|
||||
.write = new_sync_write,
|
||||
.read_iter = cifs_strict_readv,
|
||||
.write_iter = cifs_strict_writev,
|
||||
.open = cifs_open,
|
||||
@@ -947,8 +943,6 @@ const struct file_operations cifs_file_strict_ops = {
|
||||
|
||||
const struct file_operations cifs_file_direct_ops = {
|
||||
/* BB reevaluate whether they can be done with directio, no cache */
|
||||
.read = new_sync_read,
|
||||
.write = new_sync_write,
|
||||
.read_iter = cifs_user_readv,
|
||||
.write_iter = cifs_user_writev,
|
||||
.open = cifs_open,
|
||||
@@ -967,8 +961,6 @@ const struct file_operations cifs_file_direct_ops = {
|
||||
};
|
||||
|
||||
const struct file_operations cifs_file_nobrl_ops = {
|
||||
.read = new_sync_read,
|
||||
.write = new_sync_write,
|
||||
.read_iter = cifs_loose_read_iter,
|
||||
.write_iter = cifs_file_write_iter,
|
||||
.open = cifs_open,
|
||||
@@ -986,8 +978,6 @@ const struct file_operations cifs_file_nobrl_ops = {
|
||||
};
|
||||
|
||||
const struct file_operations cifs_file_strict_nobrl_ops = {
|
||||
.read = new_sync_read,
|
||||
.write = new_sync_write,
|
||||
.read_iter = cifs_strict_readv,
|
||||
.write_iter = cifs_strict_writev,
|
||||
.open = cifs_open,
|
||||
@@ -1006,8 +996,6 @@ const struct file_operations cifs_file_strict_nobrl_ops = {
|
||||
|
||||
const struct file_operations cifs_file_direct_nobrl_ops = {
|
||||
/* BB reevaluate whether they can be done with directio, no cache */
|
||||
.read = new_sync_read,
|
||||
.write = new_sync_write,
|
||||
.read_iter = cifs_user_readv,
|
||||
.write_iter = cifs_user_writev,
|
||||
.open = cifs_open,
|
||||
|
||||
+13
-25
@@ -27,19 +27,14 @@
|
||||
#include "coda_int.h"
|
||||
|
||||
static ssize_t
|
||||
coda_file_read(struct file *coda_file, char __user *buf, size_t count, loff_t *ppos)
|
||||
coda_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
|
||||
{
|
||||
struct coda_file_info *cfi;
|
||||
struct file *host_file;
|
||||
struct file *coda_file = iocb->ki_filp;
|
||||
struct coda_file_info *cfi = CODA_FTOC(coda_file);
|
||||
|
||||
cfi = CODA_FTOC(coda_file);
|
||||
BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
|
||||
host_file = cfi->cfi_container;
|
||||
|
||||
if (!host_file->f_op->read)
|
||||
return -EINVAL;
|
||||
|
||||
return host_file->f_op->read(host_file, buf, count, ppos);
|
||||
return vfs_iter_read(cfi->cfi_container, to, &iocb->ki_pos);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
@@ -64,32 +59,25 @@ coda_file_splice_read(struct file *coda_file, loff_t *ppos,
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
coda_file_write(struct file *coda_file, const char __user *buf, size_t count, loff_t *ppos)
|
||||
coda_file_write_iter(struct kiocb *iocb, struct iov_iter *to)
|
||||
{
|
||||
struct inode *host_inode, *coda_inode = file_inode(coda_file);
|
||||
struct coda_file_info *cfi;
|
||||
struct file *coda_file = iocb->ki_filp;
|
||||
struct inode *coda_inode = file_inode(coda_file);
|
||||
struct coda_file_info *cfi = CODA_FTOC(coda_file);
|
||||
struct file *host_file;
|
||||
ssize_t ret;
|
||||
|
||||
cfi = CODA_FTOC(coda_file);
|
||||
BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
|
||||
|
||||
host_file = cfi->cfi_container;
|
||||
|
||||
if (!host_file->f_op->write)
|
||||
return -EINVAL;
|
||||
|
||||
host_inode = file_inode(host_file);
|
||||
file_start_write(host_file);
|
||||
mutex_lock(&coda_inode->i_mutex);
|
||||
|
||||
ret = host_file->f_op->write(host_file, buf, count, ppos);
|
||||
|
||||
coda_inode->i_size = host_inode->i_size;
|
||||
ret = vfs_iter_write(cfi->cfi_container, to, &iocb->ki_pos);
|
||||
coda_inode->i_size = file_inode(host_file)->i_size;
|
||||
coda_inode->i_blocks = (coda_inode->i_size + 511) >> 9;
|
||||
coda_inode->i_mtime = coda_inode->i_ctime = CURRENT_TIME_SEC;
|
||||
mutex_unlock(&coda_inode->i_mutex);
|
||||
file_end_write(host_file);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -231,8 +219,8 @@ int coda_fsync(struct file *coda_file, loff_t start, loff_t end, int datasync)
|
||||
|
||||
const struct file_operations coda_file_operations = {
|
||||
.llseek = generic_file_llseek,
|
||||
.read = coda_file_read,
|
||||
.write = coda_file_write,
|
||||
.read_iter = coda_file_read_iter,
|
||||
.write_iter = coda_file_write_iter,
|
||||
.mmap = coda_file_mmap,
|
||||
.open = coda_open,
|
||||
.release = coda_release,
|
||||
|
||||
+1
-1
@@ -657,7 +657,7 @@ void do_coredump(const siginfo_t *siginfo)
|
||||
*/
|
||||
if (!uid_eq(inode->i_uid, current_fsuid()))
|
||||
goto close_fail;
|
||||
if (!cprm.file->f_op->write)
|
||||
if (!(cprm.file->f_mode & FMODE_CAN_WRITE))
|
||||
goto close_fail;
|
||||
if (do_truncate(cprm.file->f_path.dentry, 0, 0, cprm.file))
|
||||
goto close_fail;
|
||||
|
||||
@@ -358,9 +358,7 @@ const struct file_operations ecryptfs_dir_fops = {
|
||||
|
||||
const struct file_operations ecryptfs_main_fops = {
|
||||
.llseek = generic_file_llseek,
|
||||
.read = new_sync_read,
|
||||
.read_iter = ecryptfs_read_update_atime,
|
||||
.write = new_sync_write,
|
||||
.write_iter = generic_file_write_iter,
|
||||
.iterate = ecryptfs_readdir,
|
||||
.unlocked_ioctl = ecryptfs_unlocked_ioctl,
|
||||
|
||||
@@ -67,8 +67,6 @@ static int exofs_flush(struct file *file, fl_owner_t id)
|
||||
|
||||
const struct file_operations exofs_file_operations = {
|
||||
.llseek = generic_file_llseek,
|
||||
.read = new_sync_read,
|
||||
.write = new_sync_write,
|
||||
.read_iter = generic_file_read_iter,
|
||||
.write_iter = generic_file_write_iter,
|
||||
.mmap = generic_file_mmap,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user