}
static void setup_sm_file_ops(struct inode *cache_inode,
- struct inode *inode,
- struct inode_operations *cache_iops,
- struct file_operations *cache_fops,
- struct address_space_operations *cache_aops)
+ struct inode *inode,
+ struct inode_operations *cache_iops,
+ struct file_operations *cache_fops,
+ struct address_space_operations *cache_aops)
{
struct smfs_super_info *smb;
inode->i_op = cache_diops(&smfs_operations);
inode->i_fop = cache_dfops(&smfs_operations);
} else if (S_ISREG(inode->i_mode)) {
- if (!cache_fiops(&smfs_operations)) {
- setup_sm_file_ops(cache_inode, inode,
- &smfs_file_iops,
- &smfs_file_fops,
- &smfs_file_aops);
- }
+ setup_sm_file_ops(cache_inode, inode,
+ &smfs_file_iops,
+ &smfs_file_fops,
+ &smfs_file_aops);
CDEBUG(D_INODE, "inode %lu, i_op at %p\n",
inode->i_ino, inode->i_op);
inode->i_fop = cache_ffops(&smfs_operations);
}
else if (S_ISLNK(inode->i_mode)) {
- if (!cache_siops(&smfs_operations)) {
- setup_sm_symlink_ops(cache_inode, inode,
- &smfs_sym_iops, &smfs_sym_fops);
- }
+ setup_sm_symlink_ops(cache_inode, inode,
+ &smfs_sym_iops,
+ &smfs_sym_fops);
inode->i_op = cache_siops(&smfs_operations);
inode->i_fop = cache_sfops(&smfs_operations);
CDEBUG(D_INODE, "inode %lu, i_op at %p\n",
smb = S2SMI(sb);
- if (smb->ops_check & SB_OPS_CHECK)
- return;
- smb->ops_check |= SB_OPS_CHECK;
- if (!cache_sops(&smfs_operations)) {
- setup_sm_sb_ops(cache_sb, sb, &smfs_super_ops);
- }
+ setup_sm_sb_ops(cache_sb, sb, &smfs_super_ops);
+
sb->s_op = cache_sops(&smfs_operations);
return;
}
#include <linux/string.h>
#include "smfs_internal.h"
+static void duplicate_inode(struct inode *cache_inode, struct inode *inode)
+{
+
+ inode->i_mode = cache_inode->i_mode;
+ inode->i_uid = cache_inode->i_uid;
+ inode->i_gid = cache_inode->i_gid;
+ inode->i_nlink = cache_inode->i_nlink;
+ inode->i_size = cache_inode->i_size;
+ inode->i_atime = cache_inode->i_atime;
+ inode->i_ctime = cache_inode->i_ctime;
+ inode->i_mtime = cache_inode->i_mtime;
+ inode->i_blksize = cache_inode->i_blksize; /* This is the optimal IO size
+ * (for stat), not the fs block
+ * size */
+ inode->i_blocks = cache_inode->i_blocks;
+ inode->i_version = cache_inode->i_version;
+}
static void smfs_read_inode(struct inode *inode)
{
struct super_block *cache_sb;
CDEBUG(D_INODE, "read_inode ino %lu\n", inode->i_ino);
cache_sb = S2CSB(inode->i_sb);
- cache_inode = new_inode(cache_sb);
+ cache_inode = iget(cache_sb, inode->i_ino);
I2CI(inode) = cache_inode;
if(cache_sb && cache_sb->s_op->read_inode)
CDEBUG(D_INODE, "read_inode ino %lu icount %d \n",
inode->i_ino, atomic_read(&inode->i_count));
+ duplicate_inode(cache_inode, inode);
sm_set_inode_ops(cache_inode, inode);
CDEBUG(D_INODE, "read_inode ino %lu icount %d \n",
if (!fd) RETURN(-EINVAL);
- filp = filp_open(dev_path, 0, 0);
+ filp = filp_open(dev_path, FMODE_WRITE, 0);
if (!filp || !S_ISREG(filp->f_dentry->d_inode->i_mode))
RETURN(-EINVAL);
#define SIZE(a) (sizeof(a)/sizeof(a[0]))
static char *find_unused_and_set_loop_device(char *dev_path)
{
- char *loop_formats[] = { "/dev/loop%d", "/dev/loop/%d" };
+ char *loop_formats[] = { "/dev/loop/%d", "/dev/loop%d"};
struct loop_info loopinfo;
struct nameidata nd;
struct dentry *dentry;
if (path_init(dev, LOOKUP_FOLLOW, &nd)) {
error = path_walk(dev, &nd);
- if (error) {
+ if (error && error != -ENOENT) {
path_release(&nd);
SM_FREE(dev, strlen(loop_formats[i]) + 1);
RETURN(NULL);
(unsigned long)&loopinfo);
path_release(&nd);
- if (error == ENXIO) {
+ if (error == -ENXIO) {
/*find unused loop and set dev_path to loopdev*/
error = set_loop_fd(dev_path, dev);
if (error) {
char *name = NULL;
int error = 0;
- if (path_init(name, LOOKUP_FOLLOW, &nd)) {
- error = path_walk(name, &nd);
+ if (path_init(dev_path, LOOKUP_FOLLOW, &nd)) {
+ error = path_walk(dev_path, &nd);
if (error) {
path_release(&nd);
RETURN(NULL);
}
root_ino = bottom_root->d_inode->i_ino;
+ root_inode = iget(sb, root_ino);
smi = I2SMI(root_inode);
/*FIXME Intialize smi here*/
CDEBUG(D_SUPER, "readinode %p, root ino %ld, root inode at %p\n",
sb->s_op->read_inode, root_ino, root_inode);
- sb->s_root = d_alloc_root(bottom_root->d_inode);
+ sb->s_root = d_alloc_root(root_inode);
if (!sb->s_root) {
GOTO(out_err, err=-EINVAL);
(ulong) sb, (ulong) &sb->u.generic_sbp);
out_err:
+ if (root_inode)
+ iput(root_inode);
cleanup_option();
if (err)
return NULL;