#include "lafs.h"
#include <linux/random.h>
#include <linux/delay.h>
+#include <linux/slab.h>
/* Supporting an async 'iget' - as required by the cleaner -
* is slightly non-trivial.
{
struct fs_md *i = &li->md.fs;
struct fs_metadata *l = &lai->metadata[0].fs;
+ int nlen;
+
i->usagetable = le16_to_cpu(l->snapshot_usage_table);
decode_time(&ino->i_mtime, le64_to_cpu(l->update_time));
i->cblocks_used = le64_to_cpu(l->blocks_used);
i->quota_inums[2] = le32_to_cpu(l->quota_inodes[2]);
i->quota_inodes[0] = i->quota_inodes[1]
= i->quota_inodes[2] = NULL;
- memcpy(i->name, l->name, 64);
- i->name[64] = 0;
+ nlen = li->metadata_size - offsetof(struct la_inode,
+ metadata[0].fs.name);
+ if (nlen == 0)
+ i->name = NULL;
+ else {
+ /* Need to unmap the dblock to kmalloc because
+ * the mapping makes us 'atomic'
+ */
+ unmap_dblock(b, lai);
+ i->name = kmalloc(nlen+1, GFP_KERNEL);
+ lai = map_dblock(b);
+ l = &lai->metadata[0].fs;
+ err = -ENOMEM;
+ if (!i->name)
+ goto out;
+ memcpy(i->name, l->name, nlen);
+ i->name[nlen] = 0;
+ }
/* Make this look like a directory */
ino->i_mode = S_IFDIR;
ino->i_uid = 0;
l->quota_inodes[2] = 0;
l->snapshot_usage_table = 0;
l->pad = 0;
- memset(l->name, 0, sizeof(l->name));
- /* FIXME real name?? */
- strlcpy(l->name, "Secondary", sizeof(l->name));
+ /* name will be zero length and not used */
break;
}
case TypeInodeMap:
{
struct fs_md *i = &li->md.fs;
struct fs_metadata *l = &lai->metadata[0].fs;
+ int nlen;
+
l->snapshot_usage_table = cpu_to_le16(i->usagetable);
l->update_time = cpu_to_le64(encode_time(&ino->i_mtime));
l->blocks_used = cpu_to_le64(i->cblocks_used);
l->quota_inodes[0] = cpu_to_le32(i->quota_inums[0]);
l->quota_inodes[1] = cpu_to_le32(i->quota_inums[1]);
l->quota_inodes[2] = cpu_to_le32(i->quota_inums[2]);
- memcpy(l->name, i->name, 64);
+ nlen = lai->metadata_size - offsetof(struct la_inode,
+ metadata[0].fs.name);
+ memset(l->name, 0, nlen);
+ if (i->name == NULL)
+ nlen = 0;
+ else if (strlen(i->name) < nlen)
+ nlen = strlen(i->name);
+ memcpy(l->name, i->name, nlen);
break;
}
fs = fs_from_sb(sb);
for (s = 1; s < fs->maxsnapshot; s++) {
+ int nlen;
+
if (fs->ss[s].root_addr == 0)
continue;
if (fs->ss[s].root) {
struct lafs_inode *li = LAFSI(fs->ss[s].root);
- if (strcmp(li->md.fs.name, op.snapshot) == 0)
+ if (li->md.fs.name &&
+ strcmp(li->md.fs.name, op.snapshot) == 0)
/* found it */
break;
}
if (err)
continue;
lai = (struct la_inode *)page_address(p);
- printk("ss %d is %.64s\n", s, lai->metadata[0].fs.name);
- if (strncmp(lai->metadata[0].fs.name, op.snapshot, 64) != 0)
+ nlen = le16_to_cpu(lai->metadata_size) -
+ offsetof(struct la_inode, metadata[0].fs.name);
+ printk("ss %d is %.*s\n", s, nlen, lai->metadata[0].fs.name);
+ if (strncmp(lai->metadata[0].fs.name, op.snapshot, nlen) != 0)
continue;
/* FIXME more checks? */
/* Found it */
md->quota_inodes[0] = NULL;
md->quota_inodes[1] = NULL;
md->quota_inodes[2] = NULL;
- md->name[0] = '\0';
+ md->name = NULL;
lafs_dirty_dblock(inodb);
lafs_dirty_inode(ino);
/* We use a checkpoint to commit this change,
{
struct lafs_inode *lai = container_of(head, struct lafs_inode,
md.rcu);
+ if (lai->type == TypeInodeFile)
+ kfree(lai->md.fs.name);
kfree(lai);
}
+
void lafs_destroy_inode(struct inode *inode)
{
struct datablock *db;