Skip to content

Commit

Permalink
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/…
Browse files Browse the repository at this point in the history
…git/ericvh/v9fs

* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs: (26 commits)
  9p: add more conservative locking
  9p: fix oops in protocol stat parsing error path.
  9p: fix device file handling
  9p: Improve debug support
  9p: eliminate depricated conv functions
  9p: rework client code to use new protocol support functions
  9p: remove unnecessary tag field from p9_req_t structure
  9p: remove 9p fcall debug prints
  9p: add new protocol support code
  9p: encapsulate version function
  9p: move dirread to fs layer
  9p: adjust 9p vfs write operation
  9p: move readn meta-function from client to fs layer
  9p: consolidate read/write functions
  9p: drop broken unused error path from p9_conn_create()
  9p: make rpc code common and rework flush code
  9p: use the rcall structure passed in the request in trans_fd read_work
  9p: apply common request code to trans_fd
  9p: apply common tagpool handling to trans_fd
  9p: move request management to client code
  ...
  • Loading branch information
Linus Torvalds committed Oct 20, 2008
2 parents 52c6738 + 7eb923b commit 45e4a24
Show file tree
Hide file tree
Showing 20 changed files with 2,246 additions and 3,473 deletions.
4 changes: 2 additions & 2 deletions fs/9p/v9fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@
#include <linux/parser.h>
#include <linux/idr.h>
#include <net/9p/9p.h>
#include <net/9p/transport.h>
#include <net/9p/client.h>
#include <net/9p/transport.h>
#include "v9fs.h"
#include "v9fs_vfs.h"

Expand Down Expand Up @@ -234,7 +234,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
if (!v9ses->clnt->dotu)
v9ses->flags &= ~V9FS_EXTENDED;

v9ses->maxdata = v9ses->clnt->msize;
v9ses->maxdata = v9ses->clnt->msize - P9_IOHDRSZ;

/* for legacy mode, fall back to V9FS_ACCESS_ANY */
if (!v9fs_extended(v9ses) &&
Expand Down
6 changes: 4 additions & 2 deletions fs/9p/v9fs_vfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,11 @@ extern struct dentry_operations v9fs_cached_dentry_operations;

struct inode *v9fs_get_inode(struct super_block *sb, int mode);
ino_t v9fs_qid2ino(struct p9_qid *qid);
void v9fs_stat2inode(struct p9_stat *, struct inode *, struct super_block *);
void v9fs_stat2inode(struct p9_wstat *, struct inode *, struct super_block *);
int v9fs_dir_release(struct inode *inode, struct file *filp);
int v9fs_file_open(struct inode *inode, struct file *file);
void v9fs_inode2stat(struct inode *inode, struct p9_stat *stat);
void v9fs_inode2stat(struct inode *inode, struct p9_wstat *stat);
void v9fs_dentry_release(struct dentry *);
int v9fs_uflags2omode(int uflags, int extended);

ssize_t v9fs_file_readn(struct file *, char *, char __user *, u32, u64);
5 changes: 1 addition & 4 deletions fs/9p/vfs_addr.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@

#include "v9fs.h"
#include "v9fs_vfs.h"
#include "fid.h"

/**
* v9fs_vfs_readpage - read an entire page in from 9P
Expand All @@ -53,14 +52,12 @@ static int v9fs_vfs_readpage(struct file *filp, struct page *page)
int retval;
loff_t offset;
char *buffer;
struct p9_fid *fid;

P9_DPRINTK(P9_DEBUG_VFS, "\n");
fid = filp->private_data;
buffer = kmap(page);
offset = page_offset(page);

retval = p9_client_readn(fid, buffer, offset, PAGE_CACHE_SIZE);
retval = v9fs_file_readn(filp, buffer, NULL, offset, PAGE_CACHE_SIZE);
if (retval < 0)
goto done;

Expand Down
60 changes: 43 additions & 17 deletions fs/9p/vfs_dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
*
*/

static inline int dt_type(struct p9_stat *mistat)
static inline int dt_type(struct p9_wstat *mistat)
{
unsigned long perm = mistat->mode;
int rettype = DT_REG;
Expand All @@ -69,32 +69,58 @@ static inline int dt_type(struct p9_stat *mistat)
static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
{
int over;
struct p9_wstat st;
int err;
struct p9_fid *fid;
struct v9fs_session_info *v9ses;
struct inode *inode;
struct p9_stat *st;
int buflen;
char *statbuf;
int n, i = 0;

P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", filp->f_path.dentry->d_name.name);
inode = filp->f_path.dentry->d_inode;
v9ses = v9fs_inode2v9ses(inode);
fid = filp->private_data;
while ((st = p9_client_dirread(fid, filp->f_pos)) != NULL) {
if (IS_ERR(st))
return PTR_ERR(st);

over = filldir(dirent, st->name.str, st->name.len, filp->f_pos,
v9fs_qid2ino(&st->qid), dt_type(st));
buflen = fid->clnt->msize - P9_IOHDRSZ;
statbuf = kmalloc(buflen, GFP_KERNEL);
if (!statbuf)
return -ENOMEM;

if (over)
while (1) {
err = v9fs_file_readn(filp, statbuf, NULL, buflen,
fid->rdir_fpos);
if (err <= 0)
break;

filp->f_pos += st->size;
kfree(st);
st = NULL;
n = err;
while (i < n) {
err = p9stat_read(statbuf + i, buflen-i, &st,
fid->clnt->dotu);
if (err) {
P9_DPRINTK(P9_DEBUG_VFS, "returned %d\n", err);
err = -EIO;
p9stat_free(&st);
goto free_and_exit;
}

i += st.size+2;
fid->rdir_fpos += st.size+2;

over = filldir(dirent, st.name, strlen(st.name),
filp->f_pos, v9fs_qid2ino(&st.qid), dt_type(&st));

filp->f_pos += st.size+2;

p9stat_free(&st);

if (over) {
err = 0;
goto free_and_exit;
}
}
}

kfree(st);
return 0;
free_and_exit:
kfree(statbuf);
return err;
}


Expand Down
93 changes: 82 additions & 11 deletions fs/9p/vfs_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,23 +120,72 @@ static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl)
}

/**
* v9fs_file_read - read from a file
* 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)
{
int n, total;
struct p9_fid *fid = filp->private_data;

P9_DPRINTK(P9_DEBUG_VFS, "fid %d offset %llu count %d\n", fid->fid,
(long long unsigned) offset, count);

n = 0;
total = 0;
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 == (fid->clnt->msize - P9_IOHDRSZ));

if (n < 0)
total = n;

return total;
}

/**
* v9fs_file_read - read from a file
* @filp: file pointer to read
* @udata: user data buffer to read data into
* @count: size of buffer
* @offset: offset at which to read data
*
*/

static ssize_t
v9fs_file_read(struct file *filp, char __user * data, size_t count,
v9fs_file_read(struct file *filp, char __user *udata, size_t count,
loff_t * offset)
{
int ret;
struct p9_fid *fid;

P9_DPRINTK(P9_DEBUG_VFS, "\n");
P9_DPRINTK(P9_DEBUG_VFS, "count %d offset %lld\n", count, *offset);
fid = filp->private_data;
ret = p9_client_uread(fid, data, *offset, count);

if (count > (fid->clnt->msize - P9_IOHDRSZ))
ret = v9fs_file_readn(filp, NULL, udata, count, *offset);
else
ret = p9_client_read(fid, NULL, udata, *offset, count);

if (ret > 0)
*offset += ret;

Expand All @@ -156,27 +205,49 @@ static ssize_t
v9fs_file_write(struct file *filp, const char __user * data,
size_t count, loff_t * offset)
{
int ret;
int n, rsize, total = 0;
struct p9_fid *fid;
struct p9_client *clnt;
struct inode *inode = filp->f_path.dentry->d_inode;
int origin = *offset;

P9_DPRINTK(P9_DEBUG_VFS, "data %p count %d offset %x\n", data,
(int)count, (int)*offset);

fid = filp->private_data;
ret = p9_client_uwrite(fid, data, *offset, count);
if (ret > 0) {
invalidate_inode_pages2_range(inode->i_mapping, *offset,
*offset+ret);
*offset += ret;
clnt = fid->clnt;

rsize = fid->iounit;
if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
rsize = clnt->msize - P9_IOHDRSZ;

do {
if (count < rsize)
rsize = count;

n = p9_client_write(fid, NULL, data+total, *offset+total,
rsize);
if (n <= 0)
break;
count -= n;
total += n;
} while (count > 0);

if (total > 0) {
invalidate_inode_pages2_range(inode->i_mapping, origin,
origin+total);
*offset += total;
}

if (*offset > inode->i_size) {
inode->i_size = *offset;
inode->i_blocks = (inode->i_size + 512 - 1) >> 9;
}

return ret;
if (n < 0)
return n;

return total;
}

static const struct file_operations v9fs_cached_file_operations = {
Expand Down
Loading

0 comments on commit 45e4a24

Please sign in to comment.