Skip to content

Commit

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

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs:
  fs/9p: Add hardlink support to .u extension
  9P2010.L handshake: .L protocol negotiation
  9P2010.L handshake: Remove "dotu" variable
  9P2010.L handshake: Add mount option
  9P2010.L handshake: Add VFS flags
  net/9p: Handle mount errors correctly.
  net/9p: Remove MAX_9P_CHAN limit
  net/9p: Add multi channel support.
  • Loading branch information
torvalds committed Mar 5, 2010
2 parents e213e26 + 5717144 commit b13d3c6
Show file tree
Hide file tree
Showing 12 changed files with 238 additions and 144 deletions.
2 changes: 1 addition & 1 deletion fs/9p/fid.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry)
if (access == V9FS_ACCESS_SINGLE)
return ERR_PTR(-EPERM);

if (v9fs_extended(v9ses))
if (v9fs_proto_dotu(v9ses))
uname = NULL;
else
uname = v9ses->uname;
Expand Down
8 changes: 4 additions & 4 deletions fs/9p/v9fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
list_add(&v9ses->slist, &v9fs_sessionlist);
spin_unlock(&v9fs_sessionlist_lock);

v9ses->flags = V9FS_EXTENDED | V9FS_ACCESS_USER;
v9ses->flags = V9FS_PROTO_2000U | V9FS_ACCESS_USER;
strcpy(v9ses->uname, V9FS_DEFUSER);
strcpy(v9ses->aname, V9FS_DEFANAME);
v9ses->uid = ~0;
Expand All @@ -262,13 +262,13 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
goto error;
}

if (!v9ses->clnt->dotu)
v9ses->flags &= ~V9FS_EXTENDED;
if (!p9_is_proto_dotu(v9ses->clnt))
v9ses->flags &= ~V9FS_PROTO_2000U;

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

/* for legacy mode, fall back to V9FS_ACCESS_ANY */
if (!v9fs_extended(v9ses) &&
if (!v9fs_proto_dotu(v9ses) &&
((v9ses->flags&V9FS_ACCESS_MASK) == V9FS_ACCESS_USER)) {

v9ses->flags &= ~V9FS_ACCESS_MASK;
Expand Down
23 changes: 15 additions & 8 deletions fs/9p/v9fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@

/**
* enum p9_session_flags - option flags for each 9P session
* @V9FS_EXTENDED: whether or not to use 9P2000.u extensions
* @V9FS_PROTO_2000U: whether or not to use 9P2000.u extensions
* @V9FS_PROTO_2010L: whether or not to use 9P2010.l extensions
* @V9FS_ACCESS_SINGLE: only the mounting user can access the hierarchy
* @V9FS_ACCESS_USER: a new attach will be issued for every user (default)
* @V9FS_ACCESS_ANY: use a single attach for all users
Expand All @@ -32,11 +33,12 @@
* Session flags reflect options selected by users at mount time
*/
enum p9_session_flags {
V9FS_EXTENDED = 0x01,
V9FS_ACCESS_SINGLE = 0x02,
V9FS_ACCESS_USER = 0x04,
V9FS_ACCESS_ANY = 0x06,
V9FS_ACCESS_MASK = 0x06,
V9FS_PROTO_2000U = 0x01,
V9FS_PROTO_2010L = 0x02,
V9FS_ACCESS_SINGLE = 0x04,
V9FS_ACCESS_USER = 0x08,
V9FS_ACCESS_ANY = 0x0C,
V9FS_ACCESS_MASK = 0x0C,
};

/* possible values of ->cache */
Expand Down Expand Up @@ -121,7 +123,12 @@ static inline struct v9fs_session_info *v9fs_inode2v9ses(struct inode *inode)
return (inode->i_sb->s_fs_info);
}

static inline int v9fs_extended(struct v9fs_session_info *v9ses)
static inline int v9fs_proto_dotu(struct v9fs_session_info *v9ses)
{
return v9ses->flags & V9FS_EXTENDED;
return v9ses->flags & V9FS_PROTO_2000U;
}

static inline int v9fs_proto_dotl(struct v9fs_session_info *v9ses)
{
return v9ses->flags & V9FS_PROTO_2010L;
}
2 changes: 1 addition & 1 deletion fs/9p/vfs_dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
while (rdir->head < rdir->tail) {
err = p9stat_read(rdir->buf + rdir->head,
buflen - rdir->head, &st,
fid->clnt->dotu);
fid->clnt->proto_version);
if (err) {
P9_DPRINTK(P9_DEBUG_VFS, "returned %d\n", err);
err = -EIO;
Expand Down
4 changes: 2 additions & 2 deletions fs/9p/vfs_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ int v9fs_file_open(struct inode *inode, struct file *file)

P9_DPRINTK(P9_DEBUG_VFS, "inode: %p file: %p \n", inode, file);
v9ses = v9fs_inode2v9ses(inode);
omode = v9fs_uflags2omode(file->f_flags, v9fs_extended(v9ses));
omode = v9fs_uflags2omode(file->f_flags, v9fs_proto_dotu(v9ses));
fid = file->private_data;
if (!fid) {
fid = v9fs_fid_clone(file->f_path.dentry);
Expand All @@ -77,7 +77,7 @@ int v9fs_file_open(struct inode *inode, struct file *file)
i_size_write(inode, 0);
inode->i_blocks = 0;
}
if ((file->f_flags & O_APPEND) && (!v9fs_extended(v9ses)))
if ((file->f_flags & O_APPEND) && (!v9fs_proto_dotu(v9ses)))
generic_file_llseek(file, 0, SEEK_END);
}

Expand Down
48 changes: 33 additions & 15 deletions fs/9p/vfs_inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ static int unixmode2p9mode(struct v9fs_session_info *v9ses, int mode)
res = mode & 0777;
if (S_ISDIR(mode))
res |= P9_DMDIR;
if (v9fs_extended(v9ses)) {
if (v9fs_proto_dotu(v9ses)) {
if (S_ISLNK(mode))
res |= P9_DMSYMLINK;
if (v9ses->nodev == 0) {
Expand Down Expand Up @@ -102,21 +102,21 @@ static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode)

if ((mode & P9_DMDIR) == P9_DMDIR)
res |= S_IFDIR;
else if ((mode & P9_DMSYMLINK) && (v9fs_extended(v9ses)))
else if ((mode & P9_DMSYMLINK) && (v9fs_proto_dotu(v9ses)))
res |= S_IFLNK;
else if ((mode & P9_DMSOCKET) && (v9fs_extended(v9ses))
else if ((mode & P9_DMSOCKET) && (v9fs_proto_dotu(v9ses))
&& (v9ses->nodev == 0))
res |= S_IFSOCK;
else if ((mode & P9_DMNAMEDPIPE) && (v9fs_extended(v9ses))
else if ((mode & P9_DMNAMEDPIPE) && (v9fs_proto_dotu(v9ses))
&& (v9ses->nodev == 0))
res |= S_IFIFO;
else if ((mode & P9_DMDEVICE) && (v9fs_extended(v9ses))
else if ((mode & P9_DMDEVICE) && (v9fs_proto_dotu(v9ses))
&& (v9ses->nodev == 0))
res |= S_IFBLK;
else
res |= S_IFREG;

if (v9fs_extended(v9ses)) {
if (v9fs_proto_dotu(v9ses)) {
if ((mode & P9_DMSETUID) == P9_DMSETUID)
res |= S_ISUID;

Expand Down Expand Up @@ -265,7 +265,7 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode)
case S_IFBLK:
case S_IFCHR:
case S_IFSOCK:
if (!v9fs_extended(v9ses)) {
if (!v9fs_proto_dotu(v9ses)) {
P9_DPRINTK(P9_DEBUG_ERROR,
"special files without extended mode\n");
err = -EINVAL;
Expand All @@ -278,7 +278,7 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode)
inode->i_fop = &v9fs_file_operations;
break;
case S_IFLNK:
if (!v9fs_extended(v9ses)) {
if (!v9fs_proto_dotu(v9ses)) {
P9_DPRINTK(P9_DEBUG_ERROR,
"extended modes used w/o 9P2000.u\n");
err = -EINVAL;
Expand All @@ -288,7 +288,7 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode)
break;
case S_IFDIR:
inc_nlink(inode);
if (v9fs_extended(v9ses))
if (v9fs_proto_dotu(v9ses))
inode->i_op = &v9fs_dir_inode_operations_ext;
else
inode->i_op = &v9fs_dir_inode_operations;
Expand Down Expand Up @@ -575,7 +575,8 @@ v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode,
flags = O_RDWR;

fid = v9fs_create(v9ses, dir, dentry, NULL, perm,
v9fs_uflags2omode(flags, v9fs_extended(v9ses)));
v9fs_uflags2omode(flags,
v9fs_proto_dotu(v9ses)));
if (IS_ERR(fid)) {
err = PTR_ERR(fid);
fid = NULL;
Expand Down Expand Up @@ -858,7 +859,7 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
if (iattr->ia_valid & ATTR_SIZE)
wstat.length = iattr->ia_size;

if (v9fs_extended(v9ses)) {
if (v9fs_proto_dotu(v9ses)) {
if (iattr->ia_valid & ATTR_UID)
wstat.n_uid = iattr->ia_uid;

Expand Down Expand Up @@ -886,6 +887,8 @@ v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode,
struct super_block *sb)
{
char ext[32];
char tag_name[14];
unsigned int i_nlink;
struct v9fs_session_info *v9ses = sb->s_fs_info;

inode->i_nlink = 1;
Expand All @@ -897,11 +900,26 @@ v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode,
inode->i_uid = v9ses->dfltuid;
inode->i_gid = v9ses->dfltgid;

if (v9fs_extended(v9ses)) {
if (v9fs_proto_dotu(v9ses)) {
inode->i_uid = stat->n_uid;
inode->i_gid = stat->n_gid;
}

if ((S_ISREG(inode->i_mode)) || (S_ISDIR(inode->i_mode))) {
if (v9fs_proto_dotu(v9ses) && (stat->extension[0] != '\0')) {
/*
* Hadlink support got added later to
* to the .u extension. So there can be
* server out there that doesn't support
* this even with .u extension. So check
* for non NULL stat->extension
*/
strncpy(ext, stat->extension, sizeof(ext));
/* HARDLINKCOUNT %u */
sscanf(ext, "%13s %u", tag_name, &i_nlink);
if (!strncmp(tag_name, "HARDLINKCOUNT", 13))
inode->i_nlink = i_nlink;
}
}
inode->i_mode = p9mode2unixmode(v9ses, stat->mode);
if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode))) {
char type = 0;
Expand Down Expand Up @@ -976,7 +994,7 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen)
if (IS_ERR(fid))
return PTR_ERR(fid);

if (!v9fs_extended(v9ses))
if (!v9fs_proto_dotu(v9ses))
return -EBADF;

st = p9_client_stat(fid);
Expand Down Expand Up @@ -1066,7 +1084,7 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
struct p9_fid *fid;

v9ses = v9fs_inode2v9ses(dir);
if (!v9fs_extended(v9ses)) {
if (!v9fs_proto_dotu(v9ses)) {
P9_DPRINTK(P9_DEBUG_ERROR, "not extended\n");
return -EPERM;
}
Expand Down
3 changes: 0 additions & 3 deletions include/linux/virtio_9p.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,4 @@
#include <linux/virtio_ids.h>
#include <linux/virtio_config.h>

/* Maximum number of virtio channels per partition (1 for now) */
#define MAX_9P_CHAN 1

#endif /* _LINUX_VIRTIO_9P_H */
18 changes: 17 additions & 1 deletion include/net/9p/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,19 @@
/* Number of requests per row */
#define P9_ROW_MAXTAG 255

/** enum p9_proto_versions - 9P protocol versions
* @p9_proto_legacy: 9P Legacy mode, pre-9P2000.u
* @p9_proto_2000u: 9P2000.u extension
* @p9_proto_2010L: 9P2010.L extension
*/

enum p9_proto_versions{
p9_proto_legacy = 0,
p9_proto_2000u = 1,
p9_proto_2010L = 2,
};


/**
* enum p9_trans_status - different states of underlying transports
* @Connected: transport is connected and healthy
Expand Down Expand Up @@ -111,6 +124,7 @@ struct p9_req_t {
* @lock: protect @fidlist
* @msize: maximum data size negotiated by protocol
* @dotu: extension flags negotiated by protocol
* @proto_version: 9P protocol version to use
* @trans_mod: module API instantiated with this client
* @trans: tranport instance state and API
* @conn: connection state information used by trans_fd
Expand All @@ -137,7 +151,7 @@ struct p9_req_t {
struct p9_client {
spinlock_t lock; /* protect client structure */
int msize;
unsigned char dotu;
unsigned char proto_version;
struct p9_trans_module *trans_mod;
enum p9_trans_status status;
void *trans;
Expand Down Expand Up @@ -209,5 +223,7 @@ int p9_parse_header(struct p9_fcall *, int32_t *, int8_t *, int16_t *, int);
int p9stat_read(char *, int, struct p9_wstat *, int);
void p9stat_free(struct p9_wstat *);

int p9_is_proto_dotu(struct p9_client *clnt);
int p9_is_proto_dotl(struct p9_client *clnt);

#endif /* NET_9P_CLIENT_H */
Loading

0 comments on commit b13d3c6

Please sign in to comment.