Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 201787
b: refs/heads/master
c: f085312
h: refs/heads/master
i:
  201785: e086011
  201783: 2cf1591
v: v3
  • Loading branch information
Sripathi Kodi authored and Eric Van Hensbergen committed Aug 2, 2010
1 parent d7d4037 commit e95378d
Show file tree
Hide file tree
Showing 8 changed files with 322 additions and 35 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9ffaf63e34821ea60b2e1c8593f968d73728f82b
refs/heads/master: f085312204f384a0277a66c3c48ba8f9edcd58f2
1 change: 1 addition & 0 deletions trunk/fs/9p/v9fs_vfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode);
void v9fs_clear_inode(struct inode *inode);
ino_t v9fs_qid2ino(struct p9_qid *qid);
void v9fs_stat2inode(struct p9_wstat *, struct inode *, struct super_block *);
void v9fs_stat2inode_dotl(struct p9_stat_dotl *, struct inode *);
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_wstat *stat);
Expand Down
177 changes: 161 additions & 16 deletions trunk/fs/9p/vfs_inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -396,23 +396,14 @@ void v9fs_clear_inode(struct inode *inode)
#endif
}

/**
* v9fs_inode_from_fid - populate an inode by issuing a attribute request
* @v9ses: session information
* @fid: fid to issue attribute request for
* @sb: superblock on which to create inode
*
*/

static struct inode *
v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
v9fs_inode(struct v9fs_session_info *v9ses, struct p9_fid *fid,
struct super_block *sb)
{
int err, umode;
struct inode *ret;
struct inode *ret = NULL;
struct p9_wstat *st;

ret = NULL;
st = p9_client_stat(fid);
if (IS_ERR(st))
return ERR_CAST(st);
Expand All @@ -433,15 +424,62 @@ v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
#endif
p9stat_free(st);
kfree(st);

return ret;

error:
p9stat_free(st);
kfree(st);
return ERR_PTR(err);
}

static struct inode *
v9fs_inode_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid,
struct super_block *sb)
{
struct inode *ret = NULL;
int err;
struct p9_stat_dotl *st;

st = p9_client_getattr_dotl(fid, P9_STATS_BASIC);
if (IS_ERR(st))
return ERR_CAST(st);

ret = v9fs_get_inode(sb, st->st_mode);
if (IS_ERR(ret)) {
err = PTR_ERR(ret);
goto error;
}

v9fs_stat2inode_dotl(st, ret);
ret->i_ino = v9fs_qid2ino(&st->qid);
#ifdef CONFIG_9P_FSCACHE
v9fs_vcookie_set_qid(ret, &st->qid);
v9fs_cache_inode_get_cookie(ret);
#endif
kfree(st);
return ret;
error:
kfree(st);
return ERR_PTR(err);
}

/**
* v9fs_inode_from_fid - Helper routine to populate an inode by
* issuing a attribute request
* @v9ses: session information
* @fid: fid to issue attribute request for
* @sb: superblock on which to create inode
*
*/
static inline struct inode *
v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
struct super_block *sb)
{
if (v9fs_proto_dotl(v9ses))
return v9fs_inode_dotl(v9ses, fid, sb);
else
return v9fs_inode(v9ses, fid, sb);
}

/**
* v9fs_remove - helper function to remove files and directories
* @dir: directory inode that is being deleted
Expand Down Expand Up @@ -853,6 +891,42 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
return 0;
}

static int
v9fs_vfs_getattr_dotl(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat)
{
int err;
struct v9fs_session_info *v9ses;
struct p9_fid *fid;
struct p9_stat_dotl *st;

P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry);
err = -EPERM;
v9ses = v9fs_inode2v9ses(dentry->d_inode);
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
return simple_getattr(mnt, dentry, stat);

fid = v9fs_fid_lookup(dentry);
if (IS_ERR(fid))
return PTR_ERR(fid);

/* Ask for all the fields in stat structure. Server will return
* whatever it supports
*/

st = p9_client_getattr_dotl(fid, P9_STATS_ALL);
if (IS_ERR(st))
return PTR_ERR(st);

v9fs_stat2inode_dotl(st, dentry->d_inode);
generic_fillattr(dentry->d_inode, stat);
/* Change block size to what the server returned */
stat->blksize = st->st_blksize;

kfree(st);
return 0;
}

/**
* v9fs_vfs_setattr - set file metadata
* @dentry: file whose metadata to set
Expand Down Expand Up @@ -979,6 +1053,77 @@ v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode,
inode->i_blocks = (i_size_read(inode) + 512 - 1) >> 9;
}

/**
* v9fs_stat2inode_dotl - populate an inode structure with stat info
* @stat: stat structure
* @inode: inode to populate
* @sb: superblock of filesystem
*
*/

void
v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode)
{

if ((stat->st_result_mask & P9_STATS_BASIC) == P9_STATS_BASIC) {
inode->i_atime.tv_sec = stat->st_atime_sec;
inode->i_atime.tv_nsec = stat->st_atime_nsec;
inode->i_mtime.tv_sec = stat->st_mtime_sec;
inode->i_mtime.tv_nsec = stat->st_mtime_nsec;
inode->i_ctime.tv_sec = stat->st_ctime_sec;
inode->i_ctime.tv_nsec = stat->st_ctime_nsec;
inode->i_uid = stat->st_uid;
inode->i_gid = stat->st_gid;
inode->i_nlink = stat->st_nlink;
inode->i_mode = stat->st_mode;
inode->i_rdev = new_decode_dev(stat->st_rdev);

if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode)))
init_special_inode(inode, inode->i_mode, inode->i_rdev);

i_size_write(inode, stat->st_size);
inode->i_blocks = stat->st_blocks;
} else {
if (stat->st_result_mask & P9_STATS_ATIME) {
inode->i_atime.tv_sec = stat->st_atime_sec;
inode->i_atime.tv_nsec = stat->st_atime_nsec;
}
if (stat->st_result_mask & P9_STATS_MTIME) {
inode->i_mtime.tv_sec = stat->st_mtime_sec;
inode->i_mtime.tv_nsec = stat->st_mtime_nsec;
}
if (stat->st_result_mask & P9_STATS_CTIME) {
inode->i_ctime.tv_sec = stat->st_ctime_sec;
inode->i_ctime.tv_nsec = stat->st_ctime_nsec;
}
if (stat->st_result_mask & P9_STATS_UID)
inode->i_uid = stat->st_uid;
if (stat->st_result_mask & P9_STATS_GID)
inode->i_gid = stat->st_gid;
if (stat->st_result_mask & P9_STATS_NLINK)
inode->i_nlink = stat->st_nlink;
if (stat->st_result_mask & P9_STATS_MODE) {
inode->i_mode = stat->st_mode;
if ((S_ISBLK(inode->i_mode)) ||
(S_ISCHR(inode->i_mode)))
init_special_inode(inode, inode->i_mode,
inode->i_rdev);
}
if (stat->st_result_mask & P9_STATS_RDEV)
inode->i_rdev = new_decode_dev(stat->st_rdev);
if (stat->st_result_mask & P9_STATS_SIZE)
i_size_write(inode, stat->st_size);
if (stat->st_result_mask & P9_STATS_BLOCKS)
inode->i_blocks = stat->st_blocks;
}
if (stat->st_result_mask & P9_STATS_GEN)
inode->i_generation = stat->st_gen;

/* Currently we don't support P9_STATS_BTIME and P9_STATS_DATA_VERSION
* because the inode structure does not have fields for them.
*/
}

/**
* v9fs_qid2ino - convert qid into inode number
* @qid: qid to hash
Expand Down Expand Up @@ -1254,7 +1399,7 @@ static const struct inode_operations v9fs_dir_inode_operations_dotl = {
.rmdir = v9fs_vfs_rmdir,
.mknod = v9fs_vfs_mknod,
.rename = v9fs_vfs_rename,
.getattr = v9fs_vfs_getattr,
.getattr = v9fs_vfs_getattr_dotl,
.setattr = v9fs_vfs_setattr,
};

Expand All @@ -1276,7 +1421,7 @@ static const struct inode_operations v9fs_file_inode_operations = {
};

static const struct inode_operations v9fs_file_inode_operations_dotl = {
.getattr = v9fs_vfs_getattr,
.getattr = v9fs_vfs_getattr_dotl,
.setattr = v9fs_vfs_setattr,
};

Expand All @@ -1292,6 +1437,6 @@ static const struct inode_operations v9fs_symlink_inode_operations_dotl = {
.readlink = generic_readlink,
.follow_link = v9fs_vfs_follow_link,
.put_link = v9fs_vfs_put_link,
.getattr = v9fs_vfs_getattr,
.getattr = v9fs_vfs_getattr_dotl,
.setattr = v9fs_vfs_setattr,
};
43 changes: 25 additions & 18 deletions trunk/fs/9p/vfs_super.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
struct inode *inode = NULL;
struct dentry *root = NULL;
struct v9fs_session_info *v9ses = NULL;
struct p9_wstat *st = NULL;
int mode = S_IRWXUGO | S_ISVTX;
struct p9_fid *fid;
int retval = 0;
Expand All @@ -124,16 +123,10 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
goto close_session;
}

st = p9_client_stat(fid);
if (IS_ERR(st)) {
retval = PTR_ERR(st);
goto clunk_fid;
}

sb = sget(fs_type, NULL, v9fs_set_super, v9ses);
if (IS_ERR(sb)) {
retval = PTR_ERR(sb);
goto free_stat;
goto clunk_fid;
}
v9fs_fill_super(sb, v9ses, flags, data);

Expand All @@ -151,22 +144,38 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
}

sb->s_root = root;
root->d_inode->i_ino = v9fs_qid2ino(&st->qid);

v9fs_stat2inode(st, root->d_inode, sb);
if (v9fs_proto_dotl(v9ses)) {
struct p9_stat_dotl *st = NULL;
st = p9_client_getattr_dotl(fid, P9_STATS_BASIC);
if (IS_ERR(st)) {
retval = PTR_ERR(st);
goto clunk_fid;
}

v9fs_stat2inode_dotl(st, root->d_inode);
kfree(st);
} else {
struct p9_wstat *st = NULL;
st = p9_client_stat(fid);
if (IS_ERR(st)) {
retval = PTR_ERR(st);
goto clunk_fid;
}

root->d_inode->i_ino = v9fs_qid2ino(&st->qid);
v9fs_stat2inode(st, root->d_inode, sb);

p9stat_free(st);
kfree(st);
}

v9fs_fid_add(root, fid);
p9stat_free(st);
kfree(st);

P9_DPRINTK(P9_DEBUG_VFS, " simple set mount, return 0\n");
simple_set_mnt(mnt, sb);
return 0;

free_stat:
p9stat_free(st);
kfree(st);

clunk_fid:
p9_client_clunk(fid);

Expand All @@ -176,8 +185,6 @@ P9_DPRINTK(P9_DEBUG_VFS, " simple set mount, return 0\n");
return retval;

release_sb:
p9stat_free(st);
kfree(st);
deactivate_locked_super(sb);
return retval;
}
Expand Down
44 changes: 44 additions & 0 deletions trunk/include/net/9p/9p.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ enum p9_msg_t {
P9_RSTATFS,
P9_TRENAME = 20,
P9_RRENAME,
P9_TGETATTR = 24,
P9_RGETATTR,
P9_TREADDIR = 40,
P9_RREADDIR,
P9_TVERSION = 100,
Expand Down Expand Up @@ -362,6 +364,48 @@ struct p9_wstat {
u32 n_muid; /* 9p2000.u extensions */
};

struct p9_stat_dotl {
u64 st_result_mask;
struct p9_qid qid;
u32 st_mode;
u32 st_uid;
u32 st_gid;
u64 st_nlink;
u64 st_rdev;
u64 st_size;
u64 st_blksize;
u64 st_blocks;
u64 st_atime_sec;
u64 st_atime_nsec;
u64 st_mtime_sec;
u64 st_mtime_nsec;
u64 st_ctime_sec;
u64 st_ctime_nsec;
u64 st_btime_sec;
u64 st_btime_nsec;
u64 st_gen;
u64 st_data_version;
};

#define P9_STATS_MODE 0x00000001ULL
#define P9_STATS_NLINK 0x00000002ULL
#define P9_STATS_UID 0x00000004ULL
#define P9_STATS_GID 0x00000008ULL
#define P9_STATS_RDEV 0x00000010ULL
#define P9_STATS_ATIME 0x00000020ULL
#define P9_STATS_MTIME 0x00000040ULL
#define P9_STATS_CTIME 0x00000080ULL
#define P9_STATS_INO 0x00000100ULL
#define P9_STATS_SIZE 0x00000200ULL
#define P9_STATS_BLOCKS 0x00000400ULL

#define P9_STATS_BTIME 0x00000800ULL
#define P9_STATS_GEN 0x00001000ULL
#define P9_STATS_DATA_VERSION 0x00002000ULL

#define P9_STATS_BASIC 0x000007ffULL /* Mask for fields up to BLOCKS */
#define P9_STATS_ALL 0x00003fffULL /* Mask for All fields above */

/* Structures for Protocol Operations */
struct p9_tstatfs {
u32 fid;
Expand Down
3 changes: 3 additions & 0 deletions trunk/include/net/9p/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,9 @@ int p9dirent_read(char *buf, int len, struct p9_dirent *dirent,
struct p9_wstat *p9_client_stat(struct p9_fid *fid);
int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst);

struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid,
u64 request_mask);

struct p9_req_t *p9_tag_lookup(struct p9_client *, u16);
void p9_client_cb(struct p9_client *c, struct p9_req_t *req);

Expand Down
Loading

0 comments on commit e95378d

Please sign in to comment.