Skip to content

Commit

Permalink
support to stats file with copy_to_user
Browse files Browse the repository at this point in the history
  • Loading branch information
beraldoleal committed May 8, 2013
1 parent ed65bf3 commit 8c5a582
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 17 deletions.
74 changes: 62 additions & 12 deletions inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,27 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("Beraldo Leal");

static struct packet_type netsfs_pseudo_proto;
static const struct file_operations netsfs_file_operations;
static struct dentry *netsfs_root;
static const struct inode_operations netsfs_file_inode_operations;

struct netsfs_file_private {
netsfs_file_type_t type;
};

static ssize_t netsfs_file_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
ssize_t length;
char line[100];

length = -ENOMEM;
length = sprintf(line, "type: %d\n", ((struct netsfs_file_private *) file->f_dentry->d_inode->i_private)->type);
if (length >0)
length = simple_read_from_buffer(buf, count, ppos, line, length);

return length;
}

const struct inode_operations netsfs_dir_inode_operations = {
.create = netsfs_create,
.lookup = simple_lookup,
Expand All @@ -54,15 +71,27 @@ struct super_operations netsfs_ops = {
.show_options = generic_show_options,
};

static const struct file_operations netsfs_file_operations = {
.read = netsfs_file_read,
};

const match_table_t tokens = {
{Opt_mode, "mode=%o"},
{Opt_err, NULL}
};

struct netsfs_dir_private {
u64 count; // how many frames/packets
u64 errors; // how many errors
loff_t bytes; // total bytes
};



extern void netsfs_inc_inode_size(struct inode *inode, loff_t inc)
{
loff_t oldsize, newsize;
struct netsfs_dir_private *private;

printk(KERN_INFO "%s: Updating inode %lu size to %lld\n",
THIS_MODULE->name,
Expand All @@ -74,6 +103,14 @@ extern void netsfs_inc_inode_size(struct inode *inode, loff_t inc)
newsize = oldsize + inc;
i_size_write(inode, newsize);
spin_unlock(&inode->i_lock);

if (inode->i_private == NULL) {
private = kmalloc(sizeof(struct netsfs_dir_private), GFP_KERNEL);
private->bytes = newsize;
inode->i_private = private; // LOCK HERE
}else{
((struct netsfs_dir_private *) inode->i_private)->bytes = newsize;
}
}


Expand Down Expand Up @@ -114,7 +151,8 @@ struct inode *netsfs_get_inode(struct super_block *sb,
* File creation. Allocate an inode, and we're done..
*/
/* SMP-safe */
extern int netsfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
extern int netsfs_mknod(struct inode *dir, struct dentry *dentry, int mode,
dev_t dev)
{
struct inode *inode;
int error = -ENOSPC;
Expand Down Expand Up @@ -150,20 +188,23 @@ extern int netsfs_mkdir(struct inode * dir, struct dentry * dentry, int mode)

retval = netsfs_mknod(dir, dentry, mode | S_IFDIR, 0);

if (!retval)
if (!retval) {
inc_nlink(dir);

printk("%s:%s:%d - End. inode->i_ino == %lu, dentry->d_iname == %s\n",
THIS_MODULE->name,
__FUNCTION__,
__LINE__,
dir->i_ino,
dentry->d_iname);
printk("%s:%s:%d - End. inode->i_ino == %lu, dentry->d_iname == %s\n",
THIS_MODULE->name,
__FUNCTION__,
__LINE__,
dir->i_ino,
dentry->d_iname);
}

return retval;


}

extern int netsfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)
extern int netsfs_create(struct inode *dir, struct dentry *dentry, int mode,
struct nameidata *nd)
{
return netsfs_mknod(dir, dentry, mode | S_IFREG, 0);
}
Expand Down Expand Up @@ -222,7 +263,7 @@ extern int netsfs_symlink(struct inode * dir, struct dentry *dentry, const char


extern int netsfs_create_by_name(const char *name, mode_t mode, struct dentry *parent,
struct dentry **dentry, void *data)
struct dentry **dentry, void *data, netsfs_file_type_t type)
{
int error = 0;

Expand Down Expand Up @@ -257,6 +298,15 @@ extern int netsfs_create_by_name(const char *name, mode_t mode, struct dentry *p
// break;
default:
error = netsfs_create(parent->d_inode, *dentry, mode, data);
if (!error) {
if ((*dentry)->d_inode->i_private == NULL) {
(*dentry)->d_inode->i_private = kmalloc(sizeof(struct netsfs_file_private), GFP_KERNEL);
if (!(*dentry)->d_inode->i_private)
return -ENOMEM;
}
((struct netsfs_file_private *) (*dentry)->d_inode->i_private)->type = type;
}

break;
}
dput(*dentry);
Expand Down
8 changes: 7 additions & 1 deletion internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
#define NETSFS_DEFAULT_MODE 0755

#define STR(x) #x
typedef enum {
NETSFS_DIR = 0,
NETSFS_STATS = 1,
NETSFS_STREAM = 2
} netsfs_file_type_t;


struct inode *netsfs_get_inode(struct super_block *sb,
const struct inode *dir, int mode, dev_t dev);
Expand All @@ -31,7 +37,7 @@ extern int netsfs_symlink(struct inode * dir, struct dentry *dentry, const char


extern int netsfs_create_by_name(const char *name, mode_t mode, struct dentry *parent,
struct dentry **dentry, void *data);
struct dentry **dentry, void *data, netsfs_file_type_t type);


extern void netsfs_inc_inode_size(struct inode *inode, loff_t inc);
Expand Down
17 changes: 13 additions & 4 deletions proto.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,30 @@ struct netsfs_skb_info {
int len;
};

/* Top Halve.
* Work scheduled earlier is done now, here.
*/
static void netsfs_go(struct work_struct *work)
{
struct netsfs_skb_info *netsfsinfo;
struct dentry *mac_dentry, *network_dentry;
struct dentry *mac_dentry, *network_dentry, *network_stats_dentry;

netsfsinfo = container_of(work, struct netsfs_skb_info, my_work);

printk("Worker: %s %s %d\n", netsfsinfo->mac_name, netsfsinfo->network_name, netsfsinfo->len);

netsfs_create_by_name(netsfsinfo->mac_name, S_IFDIR, NULL, &mac_dentry, NULL);
if (mac_dentry)
netsfs_create_by_name(netsfsinfo->network_name, S_IFDIR, mac_dentry, &network_dentry, NULL);
netsfs_create_by_name(netsfsinfo->mac_name, S_IFDIR, NULL, &mac_dentry, NULL, NETSFS_DIR);
if (mac_dentry) {
netsfs_create_by_name("stats", S_IFREG, mac_dentry, &network_stats_dentry, NULL, NETSFS_STATS);
netsfs_create_by_name("stream", S_IFREG, mac_dentry, &network_stats_dentry, NULL, NETSFS_STREAM);
netsfs_create_by_name(netsfsinfo->network_name, S_IFDIR, mac_dentry, &network_dentry, NULL, NETSFS_DIR);
}

/* Increment size of inode */
netsfs_inc_inode_size(mac_dentry->d_inode, netsfsinfo->len);
netsfs_inc_inode_size(network_dentry->d_inode, netsfsinfo->len);


kfree( (void *) work);
}

Expand Down
1 change: 1 addition & 0 deletions proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ extern void netsfs_register_pack(void);

int netsfs_packet_handler(struct sk_buff *skb, struct net_device *dev, struct packet_type *pkt,
struct net_device *dev2);

#endif

0 comments on commit 8c5a582

Please sign in to comment.