Commit cac7505b authored by Alessandro Rubini's avatar Alessandro Rubini

sdbfs: added sdbfs_info, to keep names out of the sdb record

Signed-off-by: Alessandro Rubini's avatarAlessandro Rubini <rubini@gnudd.com>
parent 7abdd04d
...@@ -40,28 +40,22 @@ static int sdbfs_readdir(struct file * filp, ...@@ -40,28 +40,22 @@ static int sdbfs_readdir(struct file * filp,
{ {
struct inode *ino = filp->f_dentry->d_inode; struct inode *ino = filp->f_dentry->d_inode;
struct sdbfs_inode *inode; struct sdbfs_inode *inode;
struct sdb_device *s_d; struct sdbfs_info *info;
unsigned long file_off = filp->f_pos; unsigned long file_off = filp->f_pos;
unsigned long offset = ino->i_ino & ~1; unsigned long offset = ino->i_ino & ~1;
int i, j, n; int i, n;
printk("%s\n", __func__); printk("%s\n", __func__);
inode = container_of(ino, struct sdbfs_inode, ino); inode = container_of(ino, struct sdbfs_inode, ino);
n = be16_to_cpu(inode->s_i.sdb_records) - 1; n = inode->nfiles;
for (i = file_off; i < n; i++) { for (i = file_off; i < n; i++) {
char s[20];
offset += SDB_SIZE; /* new inode number */
offset += SDB_SIZE; info = inode->files + i;
s_d = (struct sdb_device *)inode->files + i; if (filldir(dirent, info->name, info->namelen,
strncpy(s, s_d->sdb_component.product.name, 19); offset, offset, DT_UNKNOWN) < 0)
for (j = 19; j; j--) {
s[j] = '\0';
if (s[j-1] != ' ')
break;
}
if (filldir(dirent, s, j, offset, offset, DT_UNKNOWN) < 0)
return i; return i;
filp->f_pos++; filp->f_pos++;
} }
...@@ -86,8 +80,8 @@ static ssize_t sdbfs_read(struct file *f, char __user *buf, size_t count, ...@@ -86,8 +80,8 @@ static ssize_t sdbfs_read(struct file *f, char __user *buf, size_t count,
ssize_t i, done; ssize_t i, done;
inode = container_of(ino, struct sdbfs_inode, ino); inode = container_of(ino, struct sdbfs_inode, ino);
start = be64_to_cpu(inode->s_d.sdb_component.addr_first); start = be64_to_cpu(inode->info.s_d.sdb_component.addr_first);
size = be64_to_cpu(inode->s_d.sdb_component.addr_last) + 1 - start; size = be64_to_cpu(inode->info.s_d.sdb_component.addr_last) + 1 - start;
if (*offp > size) if (*offp > size)
return 0; return 0;
...@@ -128,18 +122,17 @@ static struct dentry *sdbfs_lookup(struct inode *dir, ...@@ -128,18 +122,17 @@ static struct dentry *sdbfs_lookup(struct inode *dir,
{ {
struct inode *ino = NULL; struct inode *ino = NULL;
struct sdbfs_inode *inode = container_of(dir, struct sdbfs_inode, ino); struct sdbfs_inode *inode = container_of(dir, struct sdbfs_inode, ino);
struct sdb_device *s_d; struct sdbfs_info *info;
unsigned long inum = dir->i_ino & ~1; unsigned long inum = dir->i_ino & ~1;
int i, n, len; int i, n, len;
n = be16_to_cpu(inode->s_i.sdb_records) - 1; n = inode->nfiles;
len = dentry->d_name.len;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
s_d = (struct sdb_device *)inode->files + i; info = inode->files + i;
len = strlen(s_d->sdb_component.product.name); if (info->namelen != len)
if (len != dentry->d_name.len)
continue; continue;
if (!strncmp(s_d->sdb_component.product.name, if (!strncmp(info->name, dentry->d_name.name, len))
dentry->d_name.name, len))
break; break;
} }
if (i != n) if (i != n)
...@@ -186,9 +179,9 @@ static struct inode *sdbfs_iget(struct super_block *sb, int inum) ...@@ -186,9 +179,9 @@ static struct inode *sdbfs_iget(struct super_block *sb, int inum)
struct inode *ino; struct inode *ino;
struct sdbfs_dev *sd = sb->s_fs_info; struct sdbfs_dev *sd = sb->s_fs_info;
struct sdbfs_inode *inode; struct sdbfs_inode *inode;
struct sdbfs_info *info;
uint32_t offset; uint32_t offset;
int i, j, n, len; int i, j, n, len;
uint8_t *s;
int type; int type;
printk("%s: inum %i\n", __func__, inum); printk("%s: inum %i\n", __func__, inum);
...@@ -202,18 +195,18 @@ static struct inode *sdbfs_iget(struct super_block *sb, int inum) ...@@ -202,18 +195,18 @@ static struct inode *sdbfs_iget(struct super_block *sb, int inum)
offset = inum & ~1; offset = inum & ~1;
inode = container_of(ino, struct sdbfs_inode, ino); inode = container_of(ino, struct sdbfs_inode, ino);
n = sd->ops->read(sd, offset, &inode->s_d, SDB_SIZE); n = sd->ops->read(sd, offset, &inode->info.s_d, SDB_SIZE);
if (n != SDB_SIZE) if (n != SDB_SIZE)
return ERR_PTR(-EIO); return ERR_PTR(-EIO);
sdbfs_fix_endian(sd, &inode->s_d, SDB_SIZE); sdbfs_fix_endian(sd, &inode->info.s_d, SDB_SIZE);
set_nlink(ino, 1); set_nlink(ino, 1);
ino->i_size = be64_to_cpu(inode->s_d.sdb_component.addr_last) ino->i_size = be64_to_cpu(inode->info.s_d.sdb_component.addr_last)
- be64_to_cpu(inode->s_d.sdb_component.addr_first) + 1; - be64_to_cpu(inode->info.s_d.sdb_component.addr_first) + 1;
ino->i_mtime.tv_sec = ino->i_atime.tv_sec = ino->i_ctime.tv_sec = 0; ino->i_mtime.tv_sec = ino->i_atime.tv_sec = ino->i_ctime.tv_sec = 0;
ino->i_mtime.tv_nsec = ino->i_atime.tv_nsec = ino->i_ctime.tv_nsec = 0; ino->i_mtime.tv_nsec = ino->i_atime.tv_nsec = ino->i_ctime.tv_nsec = 0;
type = inode->s_d.sdb_component.product.record_type; type = inode->info.s_d.sdb_component.product.record_type;
switch (type) { switch (type) {
case sdb_type_interconnect: case sdb_type_interconnect:
printk("%s: interconnect\n", __func__); printk("%s: interconnect\n", __func__);
...@@ -221,25 +214,33 @@ static struct inode *sdbfs_iget(struct super_block *sb, int inum) ...@@ -221,25 +214,33 @@ static struct inode *sdbfs_iget(struct super_block *sb, int inum)
ino->i_op = &sdbfs_dir_iops; ino->i_op = &sdbfs_dir_iops;
ino->i_fop = &sdbfs_dir_fops; ino->i_fop = &sdbfs_dir_fops;
/* We are an interconnect, so read the other records too */ /* We are an interconnect, so read the other records too */
len = be16_to_cpu(inode->s_i.sdb_records) * SDB_SIZE; inode->nfiles = be16_to_cpu(inode->info.s_i.sdb_records);
inode->files = kmalloc(len, GFP_KERNEL); len = inode->nfiles * sizeof(*info);
BUG_ON(!inode->files); inode->files = kzalloc(len, GFP_KERNEL);
if (!inode->files) {
/* FIXME: iput? */
return ERR_PTR(-ENOMEM);
}
/* FIXME: add dot and dotdot, and maybe named-dot */ /* FIXME: add dot and dotdot, and maybe named-dot */
n = sd->ops->read(sd, offset + SDB_SIZE, inode->files, len); for (i = 0; i < inode->nfiles; i++) {
if (n != len) offset += SDB_SIZE;
return ERR_PTR(-EIO); info = inode->files + i;
sdbfs_fix_endian(sd, inode->files, len); n = sd->ops->read(sd, offset, &info->s_d, SDB_SIZE);
if (n != SDB_SIZE) {
for (i = 0; i < len / SDB_SIZE; i++) { /* FIXME: iput? */
/* zero-terminate: the lost type is not a problem */ kfree(inode->files);
s = (struct sdb_device *)(inode->files)[i] return ERR_PTR(-EIO);
.sdb_component.product.name; }
sdbfs_fix_endian(sd, &info->s_d, SDB_SIZE);
strncpy(info->name,
info->s_d.sdb_component.product.name, 19);
for (j = 19; j; j--) { for (j = 19; j; j--) {
s[j] = '\0'; info->name[j] = '\0';
if (s[j-1] != ' ') if (info->name[j-1] != ' ')
break; break;
} }
info->namelen = j;
} }
break; break;
...@@ -252,7 +253,7 @@ static struct inode *sdbfs_iget(struct super_block *sb, int inum) ...@@ -252,7 +253,7 @@ static struct inode *sdbfs_iget(struct super_block *sb, int inum)
case sdb_type_bridge: case sdb_type_bridge:
printk("%s: bridge to %llx (unsupported yet)\n", __func__, printk("%s: bridge to %llx (unsupported yet)\n", __func__,
ntohll(inode->s_b.sdb_child)); ntohll(inode->info.s_b.sdb_child));
break; break;
default: default:
......
...@@ -12,13 +12,21 @@ ...@@ -12,13 +12,21 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/sdb.h> #include <linux/sdb.h>
struct sdbfs_inode { struct sdbfs_info {
/* unnamed union to save typing */
union { union {
struct sdb_device s_d; struct sdb_device s_d;
struct sdb_interconnect s_i; struct sdb_interconnect s_i;
struct sdb_bridge s_b; struct sdb_bridge s_b;
}; };
struct sdb_device *files; /* Only used for directories */ char name[20]; /* 19 + terminator */
int namelen;
};
struct sdbfs_inode {
struct sdbfs_info info;
int nfiles;
struct sdbfs_info *files; /* for directories */
struct inode ino; struct inode ino;
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment