EXIT;
return ERR_PTR(-ENOMEM);
}
- memset(oa, 0, sizeof(*oa));
+
oa->o_id = id;
oa->o_valid = valid;
if ((err = OBP(conn->oc_dev, getattr)(conn, oa))) {
BUG();
de->inode = cpu_to_le32(inode->i_ino);
ext2_set_de_type (de, inode);
+ dir->i_mtime = dir->i_ctime = CURRENT_TIME;
err = ext2_commit_chunk(page, from, to);
UnlockPage(page);
ext2_put_page(page);
- dir->i_mtime = dir->i_ctime = CURRENT_TIME;
- obdfs_change_inode(dir);
}
/*
goto out_page;
name_len = EXT2_DIR_REC_LEN(de->name_len);
rec_len = le16_to_cpu(de->rec_len);
+ if ( n==npages && rec_len == 0) {
+ printk("Fatal dir behaviour\n");
+ goto out_page;
+ }
if (!de->inode && rec_len >= reclen)
goto got_it;
if (rec_len >= name_len + reclen)
memcpy (de->name, name, namelen);
de->inode = cpu_to_le32(inode->i_ino);
ext2_set_de_type (de, inode);
- err = ext2_commit_chunk(page, from, to);
dir->i_mtime = dir->i_ctime = CURRENT_TIME;
- obdfs_change_inode(dir);
+ err = ext2_commit_chunk(page, from, to);
+
+ // change_inode happens with the commit_chunk
+ // obdfs_change_inode(dir);
/* OFFSET_CACHE */
out_unlock:
UnlockPage(page);
if (pde)
pde->rec_len = cpu_to_le16(to-from);
dir->inode = 0;
+ inode->i_ctime = inode->i_mtime = CURRENT_TIME;
err = ext2_commit_chunk(page, from, to);
UnlockPage(page);
ext2_put_page(page);
- inode->i_ctime = inode->i_mtime = CURRENT_TIME;
- obdfs_change_inode(inode);
return err;
}
static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode)
{
- int err = ext2_add_link(dentry, inode);
+ int err;
+ err = ext2_add_link(dentry, inode);
if (!err) {
d_instantiate(dentry, inode);
return 0;
/* methods */
static struct dentry *obdfs_lookup(struct inode * dir, struct dentry *dentry)
{
- struct inode * inode;
+ struct obdo *oa;
+ struct inode * inode = NULL;
ino_t ino;
+ ENTRY;
if (dentry->d_name.len > EXT2_NAME_LEN)
return ERR_PTR(-ENAMETOOLONG);
ino = ext2_inode_by_name(dir, dentry);
- inode = NULL;
- if (ino) {
- inode = iget(dir->i_sb, ino);
- if (!inode)
- return ERR_PTR(-EACCES);
- }
+ if (!ino)
+ goto negative;
+
+ oa = obdo_fromid(IID(dir), ino, OBD_MD_FLNOTOBD | OBD_MD_FLBLOCKS);
+ if ( IS_ERR(oa) ) {
+ printk(__FUNCTION__ ": obdo_fromid failed\n");
+ EXIT;
+ return ERR_PTR(-EACCES);
+ }
+
+ inode = iget4(dir->i_sb, ino, NULL, oa);
+ obdo_free(oa);
+
+ if (!inode)
+ return ERR_PTR(-EACCES);
+
+ negative:
d_add(dentry, inode);
return NULL;
}
return ERR_PTR(err);
}
- inode = iget(dir->i_sb, (ino_t)oa->o_id);
+ inode = iget4(dir->i_sb, (ino_t)oa->o_id, NULL, oa);
+ obdo_free(oa);
if (!inode) {
printk("new_inode -fatal: %ld\n", (long)oa->o_id);
IOPS(dir, destroy)(IID(dir), oa);
- obdo_free(oa);
EXIT;
return ERR_PTR(-EIO);
}
if (!list_empty(&inode->i_dentry)) {
- printk("new_inode -fatal: aliases %ld, ct %d lnk %d\n", (long)oa->o_id,
- atomic_read(&inode->i_count), inode->i_nlink);
+ printk("new_inode -fatal: aliases %ld, ct %d lnk %d\n",
+ (long)oa->o_id,
+ atomic_read(&inode->i_count),
+ inode->i_nlink);
IOPS(dir, destroy)(IID(dir), oa);
- obdo_free(oa);
iput(inode);
EXIT;
return ERR_PTR(-EIO);
}
- obdo_free(oa);
EXIT;
return inode;
inode->i_op = &obdfs_file_inode_operations;
inode->i_fop = &obdfs_file_operations;
inode->i_mapping->a_ops = &obdfs_aops;
- obdfs_change_inode(inode);
err = ext2_add_nondir(dentry, inode);
}
return err;
void obdfs_change_inode(struct inode *inode);
-/* SYNCHRONOUS I/O for an inode */
+/* SYNCHRONOUS I/O to object storage for an inode -- object attr will be updated too */
static int obdfs_brw(int rw, struct inode *inode, struct page *page, int create)
{
obd_count num_obdo = 1;
return -EIO;
}
- oa = obdo_fromid(IID(inode), inode->i_ino, OBD_MD_FLNOTOBD);
- if ( IS_ERR(oa) ) {
+ oa = obdo_alloc();
+ if ( !oa ) {
EXIT;
- return PTR_ERR(oa);
+ return -ENOMEM;
}
+ oa->o_valid = OBD_MD_FLNOTOBD;
obdfs_from_inode(oa, inode);
err = IOPS(inode, brw)(rw, IID(inode), num_obdo, &oa, &bufs_per_obdo,
&page, &count, &offset, &flags);
-
if ( !err )
obdfs_to_inode(inode, oa); /* copy o_blocks to i_blocks */
obdo_free(oa);
-
EXIT;
return err;
} /* obdfs_brw */
int rc;
ENTRY;
-
+
+ if ( ((inode->i_size + PAGE_CACHE_SIZE -1)>>PAGE_SHIFT)
+ <= page->index) {
+ memset(kmap(page), 0, PAGE_CACHE_SIZE);
+ goto readpage_out;
+ }
+
if (Page_Uptodate(page)) {
EXIT;
goto readpage_out;
unsigned long blocksize_bits;
unsigned long root_ino;
int scratch;
+ struct obdo *oa;
ENTRY;
/* make root inode */
CDEBUG(D_INFO, "\n");
- root = iget(sb, root_ino);
- if (!root || is_bad_inode(root)) {
- printk("OBDFS: bad iget for root\n");
+ oa = obdo_fromid(&sbi->osi_conn, root_ino,
+ OBD_MD_FLNOTOBD | OBD_MD_FLBLOCKS);
+ CDEBUG(D_INFO, "\n");
+ if ( IS_ERR(oa) ) {
+ printk(__FUNCTION__ ": obdo_fromid failed\n");
+ iput(root);
+ EXIT;
+ goto ERR;
+ }
+ CDEBUG(D_INFO, "\n");
+ root = iget4(sb, root_ino, NULL, oa);
+ obdo_free(oa);
+ CDEBUG(D_INFO, "\n");
+ if (!root) {
+ printk("OBDFS: bad iget4 for root\n");
sb->s_dev = 0;
err = -ENOENT;
EXIT;
} /* obdfs_put_super */
-/* all filling in of inodes postponed until lookup */
-static void obdfs_read_inode(struct inode *inode)
-{
- struct obdo *oa;
- ENTRY;
- oa = obdo_fromid(IID(inode), inode->i_ino,
- OBD_MD_FLNOTOBD | OBD_MD_FLBLOCKS);
- if ( IS_ERR(oa) ) {
- printk(__FUNCTION__ ": obdo_fromid failed\n");
- EXIT;
- return /* PTR_ERR(oa) */;
- }
-
- ODEBUG(oa);
- obdfs_to_inode(inode, oa);
- INIT_LIST_HEAD(obdfs_iplist(inode)); /* list of dirty pages on inode */
- INIT_LIST_HEAD(obdfs_islist(inode)); /* list of inodes in superblock */
-
- obdo_free(oa);
- /* OIDEBUG(inode); */
-
- if (S_ISREG(inode->i_mode)) {
- inode->i_op = &obdfs_file_inode_operations;
- inode->i_fop = &obdfs_file_operations;
- inode->i_mapping->a_ops = &obdfs_aops;
- EXIT;
- } else if (S_ISDIR(inode->i_mode)) {
- inode->i_op = &obdfs_dir_inode_operations;
- inode->i_fop = &obdfs_dir_operations;
- inode->i_mapping->a_ops = &obdfs_aops;
- EXIT;
- } else if (S_ISLNK(inode->i_mode)) {
- if (inode->i_blocks) {
- inode->i_op = &obdfs_symlink_inode_operations;
- inode->i_mapping->a_ops = &obdfs_aops;
- }else {
- inode->i_op = &obdfs_fast_symlink_inode_operations;
- }
- EXIT;
- } else {
- init_special_inode(inode, inode->i_mode,
- ((int *)obdfs_i2info(inode)->oi_inline)[0]);
- }
-
- return;
-}
-
void obdfs_do_change_inode(struct inode *inode, int mask)
{
struct obdo *oa;
return err;
}
+static inline void obdfs_read_inode2(struct inode *inode, void *opaque)
+{
+ struct obdo *oa = opaque;
+
+ ENTRY;
+ obdfs_to_inode(inode, oa);
+
+ INIT_LIST_HEAD(obdfs_iplist(inode)); /* list of dirty pages on inode */
+ INIT_LIST_HEAD(obdfs_islist(inode)); /* list of inodes in superblock */
+
+ /* OIDEBUG(inode); */
+
+ if (S_ISREG(inode->i_mode)) {
+ inode->i_op = &obdfs_file_inode_operations;
+ inode->i_fop = &obdfs_file_operations;
+ inode->i_mapping->a_ops = &obdfs_aops;
+ EXIT;
+ } else if (S_ISDIR(inode->i_mode)) {
+ inode->i_op = &obdfs_dir_inode_operations;
+ inode->i_fop = &obdfs_dir_operations;
+ inode->i_mapping->a_ops = &obdfs_aops;
+ EXIT;
+ } else if (S_ISLNK(inode->i_mode)) {
+ if (inode->i_blocks) {
+ inode->i_op = &obdfs_symlink_inode_operations;
+ inode->i_mapping->a_ops = &obdfs_aops;
+ }else {
+ inode->i_op = &obdfs_fast_symlink_inode_operations;
+ }
+ EXIT;
+ } else {
+ init_special_inode(inode, inode->i_mode,
+ ((int *)obdfs_i2info(inode)->oi_inline)[0]);
+ }
+
+ EXIT;
+ return;
+}
+
/* exported operations */
struct super_operations obdfs_super_operations =
{
- read_inode: obdfs_read_inode,
+ read_inode2: obdfs_read_inode2,
put_inode: obdfs_put_inode,
delete_inode: obdfs_delete_inode,
put_super: obdfs_put_super,
statfs: obdfs_statfs
};
+
struct file_system_type obdfs_fs_type = {
"obdfs", 0, obdfs_read_super, NULL
};
return register_filesystem(&obdfs_fs_type);
}
+
struct address_space_operations obdfs_aops = {
readpage: obdfs_readpage,
writepage: obdfs_writepage,