struct dentry *cache_dentry = NULL;
struct dentry *cache_parent = NULL;
void *handle = NULL;
+ struct inode *cache_inode = NULL;
int rc = 0;
ENTRY;
cache_dir = I2CI(dir);
- if (!cache_dir)
- RETURN(-ENOENT);
+ LASSERT(cache_dir && cache_dir->i_op->create);
- handle = smfs_trans_start(dir, FSFILT_OP_CREATE, NULL);
- if (IS_ERR(handle))
- RETURN(-ENOSPC);
-
- lock_kernel();
- SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_CREATE, handle,
- PRE_HOOK, rc, exit);
-
+ //lock_kernel();
cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
pre_smfs_inode(dir, cache_dir);
+ handle = smfs_trans_start(dir, FSFILT_OP_CREATE, NULL);
+ if (IS_ERR(handle))
+ GOTO(exit, rc = -ENOSPC);
+
+ SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_CREATE, handle,
+ PRE_HOOK, rc, exit);
+
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
- if (cache_dir && cache_dir->i_op->create)
- rc = cache_dir->i_op->create(cache_dir, cache_dentry,
- mode);
+ rc = cache_dir->i_op->create(cache_dir, cache_dentry, mode);
#else
- if (cache_dir && cache_dir->i_op->create)
- rc = cache_dir->i_op->create(cache_dir, cache_dentry,
- mode, nd);
+ rc = cache_dir->i_op->create(cache_dir, cache_dentry, mode, nd);
#endif
+ cache_inode = cache_dentry->d_inode;
+
if (rc)
GOTO(exit, rc);
- SMFS_GET_INODE(dir->i_sb, cache_dentry->d_inode, dir, inode,
- rc, exit);
+ SMFS_IGET(dir, cache_inode->i_ino, inode, rc, exit);
d_instantiate(dentry, inode);
- post_smfs_inode(dir, cache_dir);
-
+
SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_CREATE, handle,
POST_HOOK, rc, exit);
+
+ post_smfs_inode(dir, cache_dir);
+
exit:
- unlock_kernel();
+ //unlock_kernel();
post_smfs_dentry(cache_dentry);
post_smfs_dentry(cache_parent);
smfs_trans_commit(dir, handle, 0);
struct inode *inode = NULL;
struct dentry *cache_dentry = NULL;
struct dentry *cache_parent = NULL;
- struct dentry *rc = NULL;
- void *handle = NULL;
- int rc2 = 0;
+ struct dentry *rdentry = NULL;
+ int rc = 0;
ENTRY;
- if (!(cache_dir = I2CI(dir)))
+ cache_dir = I2CI(dir);
+ if (!cache_dir || !cache_dir->i_op->lookup)
RETURN(ERR_PTR(-ENOENT));
/* preparing artificial backing fs dentries. */
cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
if (!cache_dentry || !cache_parent)
- GOTO(exit, rc = ERR_PTR(-ENOMEM));
+ RETURN (ERR_PTR(-ENOMEM));
- if (!cache_dir && cache_dir->i_op->lookup)
- GOTO(exit, rc = ERR_PTR(-ENOENT));
-
- SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_LOOKUP, handle,
- PRE_HOOK, rc2, exit);
+ SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_LOOKUP, NULL,
+ PRE_HOOK, rc, exit);
/* perform lookup in backing fs. */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
- rc = cache_dir->i_op->lookup(cache_dir, cache_dentry);
+ rdentry = cache_dir->i_op->lookup(cache_dir, cache_dentry);
#else
- rc = cache_dir->i_op->lookup(cache_dir, cache_dentry, nd);
+ rdentry = cache_dir->i_op->lookup(cache_dir, cache_dentry, nd);
#endif
- if (rc && IS_ERR(rc))
- GOTO(exit, rc);
+ cache_inode = cache_dentry->d_inode;
- if ((cache_inode = rc ? rc->d_inode : cache_dentry->d_inode)) {
- if (IS_ERR(cache_inode)) {
- dentry->d_inode = cache_inode;
- GOTO(exit, rc = NULL);
- }
- SMFS_GET_INODE(dir->i_sb, cache_inode, dir, inode, rc2, exit);
+ if (rdentry) {
+ if (IS_ERR(rdentry))
+ GOTO(exit, rdentry);
+
+ cache_inode = rdentry->d_inode;
+ dput(rdentry);
+ rdentry = NULL;
}
-
+
+ if (cache_inode)
+ SMFS_IGET(dir, cache_inode->i_ino, inode, rc, exit);
+
+
+ //rdentry = d_splice_alias(inode, dentry);
d_add(dentry, inode);
- rc = NULL;
+ //CDEBUG(D_INODE, "dir %p (inode %p)\n", dir, cache_dir);
- SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_LOOKUP, handle, POST_HOOK, rc2,
+ SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_LOOKUP, NULL, POST_HOOK, rc,
exit);
exit:
- if (rc2 < 0)
- rc = ERR_PTR(rc2);
post_smfs_dentry(cache_dentry);
post_smfs_dentry(cache_parent);
- smfs_trans_commit(dir, handle, 0);
- RETURN(rc);
+ return rdentry;
}
static int smfs_link(struct dentry *old_dentry,
struct inode *dir, struct dentry *dentry)
{
struct inode *cache_old_inode = NULL;
- struct inode *cache_dir = I2CI(dir);
- struct inode *inode = NULL;
+ struct inode *cache_dir = NULL;
+ struct inode *old_inode = NULL;
struct dentry *cache_dentry = NULL;
struct dentry *cache_old_dentry = NULL;
struct dentry *cache_parent = NULL;
void *handle = NULL;
int rc = 0;
- inode = old_dentry->d_inode;
- cache_old_inode = I2CI(inode);
+ ENTRY;
- handle = smfs_trans_start(dir, FSFILT_OP_LINK, NULL);
- if (IS_ERR(handle))
- RETURN(-ENOSPC);
+ cache_dir = I2CI(dir);
+ if (!cache_dir || !cache_dir->i_op->link)
+ GOTO(exit, rc = -ENOENT);
- lock_kernel();
- SMFS_HOOK(dir, old_dentry, NULL, NULL, HOOK_LINK, handle,
- PRE_HOOK, rc, exit);
+ old_inode = old_dentry->d_inode;
+ cache_old_inode = I2CI(old_inode);
+ if (!cache_old_inode)
+ GOTO(exit, rc = -ENOENT);
cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
-
if (!cache_parent || !cache_dentry)
GOTO(exit, rc = -ENOMEM);
old_dentry);
if (!cache_old_dentry)
GOTO(exit, rc = -ENOMEM);
-
+
pre_smfs_inode(dir, cache_dir);
- pre_smfs_inode(inode, cache_old_dentry->d_inode);
+ pre_smfs_inode(old_inode, cache_old_inode);
- if (cache_dir->i_op->link)
- rc = cache_dir->i_op->link(cache_old_dentry, cache_dir,
+ handle = smfs_trans_start(dir, FSFILT_OP_LINK, NULL);
+ if (IS_ERR(handle))
+ GOTO(exit, rc = -ENOSPC);
+
+ //lock_kernel();
+ SMFS_HOOK(dir, old_dentry, NULL, NULL, HOOK_LINK, handle,
+ PRE_HOOK, rc, exit);
+
+ rc = cache_dir->i_op->link(cache_old_dentry, cache_dir,
cache_dentry);
if (rc)
GOTO(exit, rc);
- atomic_inc(&inode->i_count);
- post_smfs_inode(inode, cache_old_dentry->d_inode);
- d_instantiate(dentry, inode);
+ atomic_inc(&old_inode->i_count);
+ d_instantiate(dentry, old_inode);
+
+ post_smfs_inode(old_inode, cache_old_inode);
post_smfs_inode(dir, cache_dir);
SMFS_HOOK(dir, old_dentry, dentry, NULL, HOOK_LINK, handle,
POST_HOOK, rc, exit);
exit:
- unlock_kernel();
+ //unlock_kernel();
post_smfs_dentry(cache_dentry);
post_smfs_dentry(cache_parent);
post_smfs_dentry(cache_old_dentry);
int rc = 0;
int mode = 0;
- if (!cache_dir || !cache_inode)
+ ENTRY;
+
+ if (!cache_dir || !cache_inode || !cache_dir->i_op->unlink)
RETURN(-ENOENT);
- handle = smfs_trans_start(dir, FSFILT_OP_UNLINK, NULL);
- if (IS_ERR(handle))
- RETURN(-ENOSPC);
-
- SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_UNLINK, handle, PRE_HOOK, rc,
- exit);
-
cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
cache_dentry = pre_smfs_dentry(cache_parent, cache_inode, dentry);
if (!cache_parent || !cache_dentry)
GOTO(exit, rc = -ENOMEM);
- lock_kernel();
+ //lock_kernel();
pre_smfs_inode(dir, cache_dir);
pre_smfs_inode(dentry->d_inode, cache_inode);
- if (cache_dir->i_op->unlink)
- rc = cache_dir->i_op->unlink(cache_dir, cache_dentry);
+
+ handle = smfs_trans_start(dir, FSFILT_OP_UNLINK, NULL);
+ if (IS_ERR(handle))
+ GOTO(exit, rc = -ENOSPC);
+
+ SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_UNLINK, handle, PRE_HOOK, rc,
+ exit);
+
+ rc = cache_dir->i_op->unlink(cache_dir, cache_dentry);
+ if (rc)
+ GOTO(exit, rc);
+
post_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
post_smfs_inode(dir, cache_dir);
- unlock_kernel();
+ //unlock_kernel();
SMFS_HOOK(dir, dentry, &mode, NULL, HOOK_UNLINK, handle, POST_HOOK,
rc, exit);
exit:
+ smfs_trans_commit(dir, handle, 0);
post_smfs_dentry(cache_dentry);
post_smfs_dentry(cache_parent);
- smfs_trans_commit(dir, handle, 0);
RETURN(rc);
}
void *handle = NULL;
int rc = 0, tgt_len;
- if (!cache_dir)
- RETURN(-ENOENT);
-
- handle = smfs_trans_start(dir, FSFILT_OP_SYMLINK, NULL);
- if (IS_ERR(handle))
- RETURN(-ENOSPC);
+ ENTRY;
- lock_kernel();
- SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_SYMLINK, handle, PRE_HOOK, rc,
- exit);
+ if (!cache_dir || !cache_dir->i_op->symlink)
+ RETURN(-ENOENT);
cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
GOTO(exit, rc = -ENOMEM);
pre_smfs_inode(dir, cache_dir);
- if (cache_dir->i_op->symlink)
- rc = cache_dir->i_op->symlink(cache_dir, cache_dentry, symname);
-
+
+ handle = smfs_trans_start(dir, FSFILT_OP_SYMLINK, NULL);
+ if (IS_ERR(handle))
+ GOTO(exit, rc = -ENOSPC);
+
+ //lock_kernel();
+ SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_SYMLINK, handle, PRE_HOOK, rc,
+ exit);
+
+ rc = cache_dir->i_op->symlink(cache_dir, cache_dentry, symname);
+ if (rc)
+ GOTO(exit, rc);
+
+ SMFS_IGET(dir, cache_dentry->d_inode->i_ino, inode, rc, exit);
+
+ d_instantiate(dentry, inode);
post_smfs_inode(dir, cache_dir);
- SMFS_GET_INODE(dir->i_sb, cache_dentry->d_inode, dir, inode, rc, exit);
- if (inode)
- d_instantiate(dentry, inode);
- else
- rc = -ENOENT;
-
tgt_len = strlen(symname) + 1;
-
SMFS_HOOK(dir, dentry, (char *)symname, &tgt_len, HOOK_SYMLINK, handle,
POST_HOOK, rc, exit);
+
exit:
- unlock_kernel();
+ //unlock_kernel();
+ smfs_trans_commit(dir, handle, 0);
post_smfs_dentry(cache_dentry);
post_smfs_dentry(cache_parent);
- smfs_trans_commit(dir, handle, 0);
RETURN(rc);
}
void *handle = NULL;
int rc = 0;
- if (!cache_dir)
+ ENTRY;
+
+ if (!cache_dir || !cache_dir->i_op->mkdir)
RETURN(-ENOENT);
- handle = smfs_trans_start(dir, FSFILT_OP_MKDIR, NULL);
- if (IS_ERR(handle))
- RETURN(-ENOSPC);
-
- lock_kernel();
-
- SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_MKDIR, handle, PRE_HOOK, rc,
- exit);
-
cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
pre_smfs_inode(dir, cache_dir);
- if (cache_dir->i_op->mkdir)
- rc = cache_dir->i_op->mkdir(cache_dir, cache_dentry, mode);
+ handle = smfs_trans_start(dir, FSFILT_OP_MKDIR, NULL);
+ if (IS_ERR(handle))
+ GOTO(exit, rc = -ENOSPC);
+
+ //lock_kernel();
+
+ SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_MKDIR, handle, PRE_HOOK, rc,
+ exit);
+
+ rc = cache_dir->i_op->mkdir(cache_dir, cache_dentry, mode);
if (rc)
GOTO(exit, rc);
- SMFS_GET_INODE(dir->i_sb, cache_dentry->d_inode, dir, inode, rc, exit);
+ SMFS_IGET(dir, cache_dentry->d_inode->i_ino, inode, rc, exit);
+
d_instantiate(dentry, inode);
post_smfs_inode(dir, cache_dir);
SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_MKDIR, handle, POST_HOOK, rc,
exit);
exit:
- unlock_kernel();
+ //unlock_kernel();
+ smfs_trans_commit(dir, handle, 0);
post_smfs_dentry(cache_dentry);
post_smfs_dentry(cache_parent);
- smfs_trans_commit(dir, handle, 0);
RETURN(rc);
}
void *handle = NULL;
int rc = 0, mode = S_IFDIR;
- if (!cache_dir)
+ ENTRY;
+
+ if (!cache_dir || !cache_dir->i_op->rmdir)
RETURN(-ENOENT);
- handle = smfs_trans_start(dir, FSFILT_OP_RMDIR, NULL);
- if (IS_ERR(handle) ) {
- CERROR("smfs_do_mkdir: no space for transaction\n");
- RETURN(-ENOSPC);
- }
-
- lock_kernel();
-
- SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_RMDIR, handle, PRE_HOOK, rc,
- exit);
-
cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
cache_dentry = pre_smfs_dentry(cache_parent, cache_inode, dentry);
pre_smfs_inode(dir, cache_dir);
pre_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
- if (cache_dir->i_op->rmdir)
- rc = cache_dir->i_op->rmdir(cache_dir, cache_dentry);
+
+ handle = smfs_trans_start(dir, FSFILT_OP_RMDIR, NULL);
+ if (IS_ERR(handle) ) {
+ CERROR("smfs_do_mkdir: no space for transaction\n");
+ GOTO(exit, rc = -ENOSPC);
+ }
+ //lock_kernel();
+
+ SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_RMDIR, handle, PRE_HOOK, rc,
+ exit);
+
+ rc = cache_dir->i_op->rmdir(cache_dir, cache_dentry);
+ if (rc)
+ GOTO(exit, rc);
+
post_smfs_inode(dir, cache_dir);
post_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
- unlock_kernel();
+ //unlock_kernel();
SMFS_HOOK(dir, dentry, &mode, NULL, HOOK_RMDIR, handle, POST_HOOK,
rc, exit);
exit:
+ smfs_trans_commit(dir, handle, 0);
post_smfs_dentry(cache_dentry);
post_smfs_dentry(cache_parent);
- smfs_trans_commit(dir, handle, 0);
RETURN(rc);
}
void *handle = NULL;
int rc = 0;
- if (!cache_dir)
+ ENTRY;
+
+ if (!cache_dir || !cache_dir->i_op->mknod)
RETURN(-ENOENT);
- handle = smfs_trans_start(dir, FSFILT_OP_MKNOD, NULL);
- if (IS_ERR(handle)) {
- CERROR("smfs_do_mkdir: no space for transaction\n");
- RETURN(-ENOSPC);
- }
-
- lock_kernel();
- SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_MKNOD, handle, PRE_HOOK, rc,
- exit);
-
cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry->d_parent);
cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
+
if (!cache_parent || !cache_dentry)
GOTO(exit, rc = -ENOMEM);
pre_smfs_inode(dir, cache_dir);
pre_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
- if (!cache_dir->i_op->mknod)
- RETURN(-ENOENT);
+ handle = smfs_trans_start(dir, FSFILT_OP_MKNOD, NULL);
+ if (IS_ERR(handle)) {
+ CERROR("smfs_do_mkdir: no space for transaction\n");
+ GOTO(exit, rc = -ENOSPC);
+ }
- if ((rc = cache_dir->i_op->mknod(cache_dir, cache_dentry,
- mode, rdev)))
+ //lock_kernel();
+ SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_MKNOD, handle, PRE_HOOK, rc,
+ exit);
+
+ rc = cache_dir->i_op->mknod(cache_dir, cache_dentry, mode, rdev);
+ if (rc)
GOTO(exit, rc);
- SMFS_GET_INODE(dir->i_sb, cache_dentry->d_inode, dir, inode, rc, exit);
+ SMFS_IGET(dir, cache_dentry->d_inode->i_ino, inode, rc, exit);
d_instantiate(dentry, inode);
- pre_smfs_inode(dir, cache_dir);
- pre_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
+ post_smfs_inode(dir, cache_dir);
+ post_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_MKNOD, handle, POST_HOOK, rc,
exit);
exit:
- unlock_kernel();
+ //unlock_kernel();
+ smfs_trans_commit(dir, handle, 0);
post_smfs_dentry(cache_dentry);
post_smfs_dentry(cache_parent);
- smfs_trans_commit(dir, handle, 0);
RETURN(rc);
}
void *handle = NULL;
int rc = 0;
- if (!cache_old_dir || !cache_new_dir || !cache_old_inode)
+ ENTRY;
+
+ if (!cache_old_dir || !cache_new_dir || !cache_old_inode
+ || !cache_old_dir->i_op->rename)
RETURN(-ENOENT);
- handle = smfs_trans_start(old_dir, FSFILT_OP_RENAME, NULL);
- if (IS_ERR(handle)) {
- CERROR("smfs_do_mkdir: no space for transaction\n");
- RETURN(-ENOSPC);
- }
- lock_kernel();
-
-
- SMFS_HOOK(old_dir, old_dentry, new_dir, new_dentry, HOOK_RENAME,
- handle, PRE_HOOK, rc, exit);
-
cache_old_parent = pre_smfs_dentry(NULL, cache_old_dir, old_dentry);
cache_old_dentry = pre_smfs_dentry(cache_old_parent, cache_old_inode,
GOTO(exit, rc = -ENOMEM);
cache_new_parent = pre_smfs_dentry(NULL, cache_new_dir, new_dentry);
-
cache_new_dentry = pre_smfs_dentry(cache_new_parent, cache_new_inode,
new_dentry);
pre_smfs_inode(old_dir, cache_old_dir);
pre_smfs_inode(new_dir, cache_new_dir);
- if (cache_old_dir->i_op->rename)
- rc = cache_old_dir->i_op->rename(cache_old_dir, cache_old_dentry,
- cache_new_dir, cache_new_dentry);
+ handle = smfs_trans_start(old_dir, FSFILT_OP_RENAME, NULL);
+ if (IS_ERR(handle)) {
+ CERROR("smfs_do_mkdir: no space for transaction\n");
+ GOTO(exit, rc = -ENOSPC);
+ }
+ //lock_kernel();
+
+ SMFS_HOOK(old_dir, old_dentry, new_dir, new_dentry, HOOK_RENAME,
+ handle, PRE_HOOK, rc, exit);
+
+ rc = cache_old_dir->i_op->rename(cache_old_dir, cache_old_dentry,
+ cache_new_dir, cache_new_dentry);
post_smfs_inode(old_dir, cache_old_dir);
post_smfs_inode(new_dir, cache_new_dir);
+ if (new_dentry->d_inode)
+ post_smfs_inode(new_dentry->d_inode, cache_new_dentry->d_inode);
+
SMFS_HOOK(old_dir, old_dentry, new_dir, new_dentry, HOOK_RENAME, handle,
POST_HOOK, rc, exit);
- if (new_dentry->d_inode)
- post_smfs_inode(new_dentry->d_inode, cache_new_dentry->d_inode);
+
exit:
- unlock_kernel();
+ //unlock_kernel();
+ smfs_trans_commit(old_dir, handle, 0);
post_smfs_dentry(cache_old_dentry);
post_smfs_dentry(cache_old_parent);
post_smfs_dentry(cache_new_dentry);
post_smfs_dentry(cache_new_parent);
- smfs_trans_commit(old_dir, handle, 0);
RETURN(rc);
}
struct inode *cache_inode = NULL;
struct smfs_file_info *sfi = NULL;
loff_t tmp_ppos;
- loff_t *cache_ppos;
+ loff_t *cache_ppos = NULL;
int rc = 0;
+ ENTRY;
+
cache_inode = I2CI(dentry->d_inode);
- if (!cache_inode)
+ if (!cache_inode || !cache_inode->i_fop->read)
RETURN(-EINVAL);
sfi = F2SMFI(filp);
- if (sfi->magic != SMFS_FILE_MAGIC) BUG();
+ if (sfi->magic != SMFS_FILE_MAGIC)
+ BUG();
if (ppos != &(filp->f_pos))
cache_ppos = &tmp_ppos;
else
cache_ppos = &sfi->c_file->f_pos;
+
*cache_ppos = *ppos;
- if (cache_inode->i_fop->read)
- rc = cache_inode->i_fop->read(sfi->c_file, buf, size,
- cache_ppos);
+ rc = cache_inode->i_fop->read(sfi->c_file, buf, size, cache_ppos);
+ if (rc)
+ RETURN(rc);
+
*ppos = *cache_ppos;
+
duplicate_file(filp, sfi->c_file);
+
RETURN(rc);
}
struct smfs_file_info *sfi = NULL;
int rc = 0;
+ ENTRY;
+
cache_inode = I2CI(dentry->d_inode);
- if (!cache_inode)
+ if (!cache_inode || !cache_inode->i_fop->readdir)
RETURN(-EINVAL);
sfi = F2SMFI(filp);
SMFS_HOOK(dentry->d_inode, filp, dirent, filldir, HOOK_READDIR, NULL,
PRE_HOOK, rc, exit);
- if (cache_inode->i_fop->readdir)
- rc = cache_inode->i_fop->readdir(sfi->c_file, dirent, filldir);
+ rc = cache_inode->i_fop->readdir(sfi->c_file, dirent, filldir);
+ CDEBUG(D_INODE,"readdir rc=%u\n",rc);
+ if (rc < 0)
+ RETURN(rc);
+
+ duplicate_file(filp, sfi->c_file);
SMFS_HOOK(dentry->d_inode, filp, dirent, filldir, HOOK_READDIR, NULL,
POST_HOOK, rc, exit);
- duplicate_file(filp, sfi->c_file);
exit:
if (rc > 0)
rc = 0;
\layout Standard
LVFS has fsfilt operations for SMFS.
- SMFS store copy of fsfilt operations from backstore filesystem, gets fsfilt
- operations for itself and pass each call to backstore filesysem.
+ SMFS store copy of fsfilt operations from backstore filesystem.
+ If it gets fsfilt operations then it is passed to backstore filesysem.
-\layout Comment
-
-should I give more info?
\layout Subsubsection
Transactions handling
stuff to it.
To solve this SMFS pass transaction handler to plugin, so it can do transaction
in right way.
-
-\layout Comment
-
-details?
+ Also plugin should provide method to calculate extra size for transaction.
\layout Subsection
Backstore filesystem
\layout Enumerate
Backstore FS is mounted by SMFS while initialization, if mount is failed
- SMFS initialization is also failed (maybe in that case we need to mount
- backstore FS directly instead of SMFS?)
+ SMFS initialization is also failed.
\layout Enumerate
SMFS creates own superblock using backstore one and fsfilter operations
SMFS creates own inode operations for each inode.
When some operations in invoked SMFS calls real filesystem method to complete
it.
- There are additional actions for making SMFS inode and real inode consistent.
+
+\layout Standard
+
+There are additional actions for making SMFS inode and real inode consistent.
+ These actions are needed before real operation to create artificial objects
+ and after - to copy changes from backfs inode.
+
\layout Subsubsection
File operations
SMFS creates own filp, duplicate backstore FS filp and dentry.
They are used in file operations following by backstore operation call.
-
+ To do file operations we create artificial file object before calling of
+ real operation.
\layout Section
Next options is passed to smfs and descript backstore FS completely:
\layout Standard
-smfs dev=/mnt type=ext3
+smfs dev=/mnt type=ldiskfs
\layout Subsection
SMFS plugins/upcalls
Inode operations
\layout Standard
+Each inode operaion uses backfs inode structure, this structure is created
+ while several fs operations are invoked.
+ Logic of all operations is next:
+\layout Itemize
+
+There is smfs dentry for each operation passed as parameter
+\layout Itemize
+
+SMFS creates artificial dentries for using they in backstore fs operation
+\layout Itemize
+
+after operation there is backstore fs inode in backfs_dentry->d_inode
+\layout Itemize
+
+if SMFS inode not exits it is created here and connected to backfs inode
+\layout Itemize
+
+several fields are copied from backstore fs inode to smfs one
+\layout Itemize
+
+all artificial dentries are cleared.
+\layout Standard
+
+
+\emph on
+Artificial dentry handling
+\layout LyX-Code
+
+struct dentry *pre_smfs_dentry(struct dentry *parent_dentry, struct inode
+ *cache_inode,
+\layout LyX-Code
+
+ struct dentry *dentry) {
+\layout LyX-Code
+
+ struct dentry *cache_dentry = NULL;
+\layout LyX-Code
+
+ cache_dentry = d_alloc(parent_dentry, &dentry->d_name);
+\layout LyX-Code
+
+ if (!cache_dentry)
+\layout LyX-Code
+
+ RETURN(NULL);
+\layout LyX-Code
+
+ if (!parent_dentry)
+\layout LyX-Code
+
+ cache_dentry->d_parent = cache_dentry;
+\layout LyX-Code
+
+ if (cache_inode)
+\layout LyX-Code
+
+ d_add(cache_dentry, cache_inode);
+\layout LyX-Code
+
+ RETURN(cache_dentry);
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+\layout LyX-Code
+
+void post_smfs_dentry(struct dentry *cache_dentry) {
+\layout LyX-Code
+
+ if (!cache_dentry)
+\layout LyX-Code
+
+ return;
+\layout LyX-Code
+
+ d_unalloc(cache_dentry);
+\layout LyX-Code
+
+}
+\layout Standard
+
+For inode operation we have parent inode and dentry for operation.
+ So SMFS has to create artificial parent dentry with backfs_inode connected
+ to it and artificial dentry for ext3 operation.
+ This is done with pre_smfs_dentry() method.
+\layout Standard
+
+After successfull creation SMFS will do backfs operation and gets filled
+ artificial dentry.
+ Next step is getting SMFS inode from cache using ext3 inode number.
+ If inode is found it is connected to smfs dentry and operation can be counted
+ as completed.
+ SMFS clean all artificial dentries and exits.
+\layout Standard
+
+
+\emph on
+duplicate_inode details
+\layout Standard
+
+
+\begin_inset ERT
+status Open
+
+\layout Standard
+
+\backslash
+lst{../../include/linux/lustre_smfs.h}{Duplicate
+\backslash
+_inode()}{firstline=297,lastline=316}
+\end_inset
+
+
+\layout Standard
+
+
+\emph on
+Inode operations
+\layout Standard
+
\begin_inset ERT
status Open
\layout Subsubsection
File operations
+\layout Standard
+
+SMFS creates artificial struct file object for each SMFS file struct and
+ use it for backstore fs operations.
+ Backstore struct file is created in open() method and connected to private
+ field in smfs struct file.
+ This struct will be released in smfs_release().
+\layout Standard
+
+When created and modified this struct file is duplicated to smfs one:
+\layout Standard
+
+
+\emph on
+duplicate_file
+\layout Standard
+
+
+\begin_inset ERT
+status Open
+
+\layout Standard
+
+\backslash
+lst{../../include/linux/lustre_smfs.h}{duplicate
+\backslash
+_file()}{firstline=343,lastline=362}
+\end_inset
+
+
\layout Paragraph
Common case (write/read/llseek/mmap/ioctl/readdir)
Transaction MUST be commited where it was started.
It is not allowed to start it in pre_hook and commit in post_hook.
-\layout Subsubsection
-
-Special case: write operation
-\layout Standard
-
-Write operation cannot be encapsulated in SMFS transaction because really
- this operation starts transactions for each prepare_write/commit_write
- so current transaction can be easily overflowed.
- At the moment SMFS do nothing with write, but plugin like KML do log for
- write operation.
- Therefore in case of crush we will not be able to restore KML log synced
- with FS operations.
\layout Subsection
Locking
SMFS will return 0 in case of successfull registration or error code otherwise.
+\layout Subsubsection*
+
+Plugin deregistration
+\layout Standard
+
+SMFS provide following method for deregistration:
+\layout LyX-Code
+
+void * smfs_deregister_plugin (int type);
+\layout Standard
+
+SMFS will return private plugin data from struct smfs_plugin in case of
+ successfull registration or NULL pointer otherwise.
+
\layout Paragraph*
Plugins operation
Plugin's hook function must have the same type:
\layout LyX-Code
-typedef int smfs_hook_func (int opcode, void * parameter);
+typedef int (*smfs_plg_hook) (int opcode, void * parameter, void * plg_private);
\layout Standard
Parameter can contains:
handle - fsfilt transaction if exists
\layout Standard
+
+\emph on
+Plg_private
+\emph default
+is private plugin data.
+\layout Standard
+
There are opcodes for now:
\layout LyX-Code
etc.
\layout LyX-Code
-smfs_helper(int code, void * parameter);
+smfs_helper(int code, void * parameter, void * plg_private);
\layout Standard
Where
struct inode *cache_inode;
struct smfs_file_info *sfi;
loff_t tmp_ppos;
- loff_t *cache_ppos;
+ loff_t *cache_ppos = NULL;
int rc = 0;
ENTRY;
cache_inode = I2CI(filp->f_dentry->d_inode);
- if (!cache_inode)
+ if (!cache_inode || !cache_inode->i_fop->write)
RETURN(-ENOENT);
sfi = F2SMFI(filp);
else {
tmp_ppos = *ppos;
}
+
SMFS_HOOK(filp->f_dentry->d_inode, filp->f_dentry, &count, &tmp_ppos,
HOOK_WRITE, NULL, PRE_HOOK, rc, exit);
} else {
cache_ppos = &sfi->c_file->f_pos;
}
+
*cache_ppos = *ppos;
pre_smfs_inode(filp->f_dentry->d_inode, cache_inode);
- if (cache_inode->i_fop->write) {
- rc = cache_inode->i_fop->write(sfi->c_file, buf,
- count, cache_ppos);
- }
-
+ rc = cache_inode->i_fop->write(sfi->c_file, buf, count,
+ cache_ppos);
+
SMFS_HOOK(filp->f_dentry->d_inode, filp->f_dentry, ppos, &count,
HOOK_WRITE, NULL, POST_HOOK, rc, exit);
+
exit:
post_smfs_inode(filp->f_dentry->d_inode, cache_inode);
*ppos = *cache_ppos;
ENTRY;
cache_inode = I2CI(filp->f_dentry->d_inode);
- if (!cache_inode)
+ if (!cache_inode || !cache_inode->i_fop->ioctl)
RETURN(-ENOENT);
sfi = F2SMFI(filp);
pre_smfs_inode(inode, cache_inode);
- if (cache_inode->i_fop->ioctl) {
- rc = cache_inode->i_fop->ioctl(cache_inode,
- sfi->c_file, cmd, arg);
- }
-
+ rc = cache_inode->i_fop->ioctl(cache_inode, sfi->c_file, cmd, arg);
+
post_smfs_inode(inode, cache_inode);
duplicate_file(filp, sfi->c_file);
struct inode *cache_inode;
struct smfs_file_info *sfi;
loff_t tmp_ppos;
- loff_t *cache_ppos;
+ loff_t *cache_ppos = NULL;
ssize_t rc = 0;
ENTRY;
cache_inode = I2CI(filp->f_dentry->d_inode);
- if (!cache_inode)
+ if (!cache_inode || !cache_inode->i_fop->read)
RETURN(-ENOENT);
sfi = F2SMFI(filp);
pre_smfs_inode(filp->f_dentry->d_inode, cache_inode);
- if (cache_inode->i_fop->read) {
- rc = cache_inode->i_fop->read(sfi->c_file, buf,
- count, cache_ppos);
- }
-
+ rc = cache_inode->i_fop->read(sfi->c_file, buf, count, cache_ppos);
+
*ppos = *cache_ppos;
post_smfs_inode(filp->f_dentry->d_inode, cache_inode);
duplicate_file(filp, sfi->c_file);
ENTRY;
cache_inode = I2CI(file->f_dentry->d_inode);
- if (!cache_inode)
+ if (!cache_inode || !cache_inode->i_fop->llseek)
RETURN(-ENOENT);
sfi = F2SMFI(file);
pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
- if (cache_inode->i_fop->llseek) {
- rc = cache_inode->i_fop->llseek(sfi->c_file,
- offset, origin);
- }
-
+ rc = cache_inode->i_fop->llseek(sfi->c_file, offset, origin);
+
post_smfs_inode(file->f_dentry->d_inode, cache_inode);
duplicate_file(file, sfi->c_file);
inode->i_mapping = cache_inode->i_mapping;
pre_smfs_inode(inode, cache_inode);
- if (cache_inode->i_fop->mmap)
- rc = cache_inode->i_fop->mmap(sfi->c_file, vma);
+
+ rc = cache_inode->i_fop->mmap(sfi->c_file, vma);
post_smfs_inode(inode, cache_inode);
duplicate_file(file, sfi->c_file);
struct inode *cache_inode = NULL;
int rc = 0;
ENTRY;
-
+
cache_inode = I2CI(inode);
if (!cache_inode)
RETURN(-ENOENT);
-
+
if ((rc = smfs_init_cache_file(inode, filp)))
RETURN(rc);
- if (cache_inode->i_fop->open)
+ if (cache_inode->i_fop->open) {
rc = cache_inode->i_fop->open(cache_inode, F2CF(filp));
-
- duplicate_file(filp, F2CF(filp));
+ duplicate_file(filp, F2CF(filp));
+ }
RETURN(rc);
}
cache_inode = I2CI(inode);
if (!cache_inode)
- RETURN(-ENOENT);
+ RETURN(-ENOENT);
+
if (filp) {
sfi = F2SMFI(filp);
if (sfi->magic != SMFS_FILE_MAGIC)
LBUG();
cache_file = sfi->c_file;
}
+
if (cache_inode->i_fop->release)
rc = cache_inode->i_fop->release(cache_inode, cache_file);
post_smfs_inode(inode, cache_inode);
smfs_cleanup_cache_file(filp);
+
RETURN(rc);
}
int rc = 0;
cache_inode = I2CI(dentry->d_inode);
- if (!cache_inode)
+ if (!cache_inode || !cache_inode->i_fop->fsync)
RETURN(-ENOENT);
cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
pre_smfs_inode(dentry->d_inode, cache_inode);
- if (cache_inode->i_fop->fsync) {
- rc = cache_inode->i_fop->fsync(cache_file,
- cache_dentry, datasync);
+ rc = cache_inode->i_fop->fsync(cache_file,
+ cache_dentry, datasync);
- }
post_smfs_inode(dentry->d_inode, cache_inode);
duplicate_file(file, cache_file);
post_smfs_dentry(cache_dentry);
static void smfs_truncate(struct inode *inode)
{
- struct inode *cache_inode;
-
- cache_inode = I2CI(inode);
+ struct inode *cache_inode = I2CI(inode);
- if (!cache_inode)
- return;
-
- if (!cache_inode)
+ if (!cache_inode || !cache_inode->i_op->truncate)
return;
pre_smfs_inode(inode, cache_inode);
- if (cache_inode->i_op->truncate)
- cache_inode->i_op->truncate(cache_inode);
+
+ cache_inode->i_op->truncate(cache_inode);
post_smfs_inode(inode, cache_inode);
int rc = 0;
cache_inode = I2CI(dentry->d_inode);
- if (!cache_inode)
+ if (!cache_inode || !cache_inode->i_op->setattr)
RETURN(-ENOENT);
cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
handle = smfs_trans_start(dentry->d_inode, FSFILT_OP_SETATTR, NULL);
if (IS_ERR(handle) ) {
CERROR("smfs_do_mkdir: no space for transaction\n");
- RETURN(-ENOSPC);
+ GOTO(exit, rc = -ENOSPC);
}
pre_smfs_inode(dentry->d_inode, cache_inode);
-
- if (cache_inode->i_op->setattr)
- rc = cache_inode->i_op->setattr(cache_dentry, attr);
+
+ SMFS_HOOK(dentry->d_inode, dentry, attr, NULL, HOOK_SETATTR, NULL,
+ PRE_HOOK, rc, exit);
+
+ rc = cache_inode->i_op->setattr(cache_dentry, attr);
+
+ post_smfs_dentry(cache_dentry);
SMFS_HOOK(dentry->d_inode, dentry, attr, NULL, HOOK_SETATTR, NULL,
POST_HOOK, rc, exit);
+
+ post_smfs_inode(dentry->d_inode, cache_inode);
exit:
- post_smfs_inode(dentry->d_inode, cache_inode);
- post_smfs_dentry(cache_dentry);
smfs_trans_commit(dentry->d_inode, handle, 0);
RETURN(rc);
}
int rc = 0;
cache_inode = I2CI(dentry->d_inode);
- if (!cache_inode)
+ if (!cache_inode || !cache_inode->i_op->setxattr)
RETURN(-ENOENT);
cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
pre_smfs_inode(dentry->d_inode, cache_inode);
- if (cache_inode->i_op->setxattr)
- rc = cache_inode->i_op->setxattr(cache_dentry, name, value,
- size, flags);
+ rc = cache_inode->i_op->setxattr(cache_dentry, name, value,
+ size, flags);
post_smfs_inode(dentry->d_inode, cache_inode);
post_smfs_dentry(cache_dentry);
int rc = 0;
cache_inode = I2CI(dentry->d_inode);
- if (!cache_inode)
+ if (!cache_inode || !cache_inode->i_op->getattr)
RETURN(-ENOENT);
cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
pre_smfs_inode(dentry->d_inode, cache_inode);
- if (cache_inode->i_op->getattr)
- rc = cache_inode->i_op->getxattr(cache_dentry, name, buffer,
- size);
+ rc = cache_inode->i_op->getxattr(cache_dentry, name, buffer,
+ size);
post_smfs_inode(dentry->d_inode, cache_inode);
post_smfs_dentry(cache_dentry);
int rc = 0;
cache_inode = I2CI(dentry->d_inode);
- if (!cache_inode)
+ if (!cache_inode || !cache_inode->i_op->listxattr)
RETURN(-ENOENT);
cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
pre_smfs_inode(dentry->d_inode, cache_inode);
- if (cache_inode->i_op->listxattr)
- rc = cache_inode->i_op->listxattr(cache_dentry, buffer, size);
+ rc = cache_inode->i_op->listxattr(cache_dentry, buffer, size);
post_smfs_inode(dentry->d_inode, cache_inode);
post_smfs_dentry(cache_dentry);
int rc = 0;
cache_inode = I2CI(dentry->d_inode);
- if (!cache_inode)
+ if (!cache_inode || !cache_inode->i_op->removexattr)
RETURN(-ENOENT);
cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
pre_smfs_inode(dentry->d_inode, cache_inode);
- if (cache_inode->i_op->removexattr)
- rc = cache_inode->i_op->removexattr(cache_dentry, name);
+ rc = cache_inode->i_op->removexattr(cache_dentry, name);
post_smfs_inode(dentry->d_inode, cache_inode);
post_smfs_dentry(cache_dentry);
/* getting backing fs inode. */
ino = sargs ? sargs->s_ino : inode->i_ino;
+ //ino = sargs->s_ino;
cache_inode = iget(S2CSB(inode->i_sb), ino);
-
+
OBD_ALLOC(inode->u.generic_ip,
sizeof(struct smfs_inode_info));
LASSERT(inode->u.generic_ip);
I2CI(inode) = cache_inode;
- CDEBUG(D_INODE, "cache_inode i_count ino %lu i_count %d\n",
+ CDEBUG(D_INODE, "cache_inode %lu i_count %d\n",
cache_inode->i_ino, atomic_read(&cache_inode->i_count));
post_smfs_inode(inode, cache_inode);
if (I2SMI(inode)) {
struct inode *cache_inode = I2CI(inode);
+ CDEBUG(D_INODE, "Clear_info: cache_inode %lu\n", cache_inode->i_ino);
+
LASSERTF(((atomic_read(&cache_inode->i_count) == 1) ||
cache_inode == cache_inode->i_sb->s_root->d_inode),
- "inode %p cache inode %p %lu i_count %d != 0 \n",
+ "inode %p cache inode %p #%lu i_count %d != 1 \n",
inode, cache_inode, cache_inode->i_ino,
atomic_read(&cache_inode->i_count));
-
- if (cache_inode != cache_inode->i_sb->s_root->d_inode)
- iput(cache_inode);
+
+ //if (cache_inode != cache_inode->i_sb->s_root->d_inode)
+ iput(cache_inode);
OBD_FREE(inode->u.generic_ip,
sizeof(struct smfs_inode_info));
}
}
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
static void smfs_read_inode2(struct inode *inode, void *opaque)
{
ENTRY;
EXIT;
}
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
static int smfs_test_inode(struct inode *inode, unsigned long ino,
void *opaque)
#else
{
struct smfs_iget_args *sargs = (struct smfs_iget_args*)opaque;
- LASSERT(sargs);
-
- if (!sargs)
- return 1;
-
- if (inode->i_ino != sargs->s_ino)
+ if (!sargs || (inode->i_ino != sargs->s_ino))
return 0;
#ifdef CONFIG_SNAPFS
!smfs_snap_test_inode(inode, opaque))
return 0;
#endif
- if (I2SMI(inode)) {
- struct inode *cache_inode = I2CI(inode);
-
- /* this is needed to make symatry between smfs_put_inode(). */
- LASSERT(cache_inode != NULL);
- igrab(cache_inode);
-
- LASSERTF(cache_inode->i_ino == inode->i_ino,
- "inode ino %lu != cache ino %lu",
- cache_inode->i_ino, inode->i_ino);
- } else {
- smfs_init_inode_info(inode, opaque);
- }
return 1;
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
int smfs_set_inode(struct inode *inode, void *opaque)
{
- smfs_read_inode2(inode, opaque);
+ //smfs_read_inode2(inode, opaque);
return 0;
}
inode = iget5_locked(sb, hash, smfs_test_inode,
smfs_set_inode, sargs);
if (inode) {
- if (inode->i_state & I_NEW)
+ if (inode->i_state & I_NEW) {
+ smfs_init_inode_info(inode, (void*)sargs);
unlock_new_inode(inode);
+ }
+ inode->i_ino = hash;
CDEBUG(D_VFSTRACE, "inode: %lu/%u(%p) index %d "
"ino %d\n", inode->i_ino, inode->i_generation,
inode, sargs->s_index, sargs->s_ino);
- inode->i_ino = hash;
}
+
return inode;
}
#else
inode = iget4(sb, hash, smfs_test_inode, sargs);
if (inode) {
struct inode *cache_inode = I2CI(inode);
- LASSERTF((inode->i_ino == cache_inode->i_ino),
- "inode %p ino %lu != cache inode %p ino %lu",
- inode, inode->i_ino, cache_inode, cache_inode->i_ino);
- CDEBUG(D_VFSTRACE, "inode: %lu/%u(%p)\n", inode->i_ino,
+
+ CDEBUG(D_VFSTRACE, "new inode: %lu/%u(%p)\n", inode->i_ino,
inode->i_generation, inode);
}
return inode;
sargs.s_ino = hash;
sargs.s_inode = dir;
sargs.s_index = index;
+ CDEBUG(D_VFSTRACE, "get_inode: %lu\n", hash);
+
inode = smfs_iget(sb, hash, &sargs);
RETURN(inode);
cache_inode = I2CI(inode);
LASSERT(cache_inode != NULL);
+
+ CDEBUG(D_INODE,"Write inode %lu\n",inode->i_ino);
pre_smfs_inode(inode, cache_inode);
- if (S2CSB(inode->i_sb)->s_op->write_inode)
- S2CSB(inode->i_sb)->s_op->write_inode(cache_inode, wait);
+
+ if (cache_inode->i_sb->s_op->write_inode)
+ cache_inode->i_sb->s_op->write_inode(cache_inode, wait);
post_smfs_inode(inode, cache_inode);
EXIT;
post_smfs_inode(inode, cache_inode);
EXIT;
}
-
static void smfs_put_inode(struct inode *inode)
{
+#if 0
struct inode *cache_inode;
ENTRY;
smfs_clear_inode_info(inode);
EXIT;
+#endif
}
static void smfs_clear_inode(struct inode *inode)
if (!*opt_left)
return -ENODATA;
+
left = strchr(opt_left, ',');
if (left == opt_left)
return -EINVAL;
list_add(&tmp_opt->list, &option_list);
if (*opt_left == ',') opt_left ++; /*after ','*/
*option = tmp_opt;
+ printk("Option: %s=%s\n", tmp_opt->opt, tmp_opt->value);
return 0;
}
+
+char *smfs_options(char *data, char **devstr, char **namestr,
+ char *opts, int *flags)
+{
+ struct option *opt_value = NULL;
+ char *pos;
+
+ LASSERT(opts && flags);
+ init_option(data);
+
+ while (!(get_opt(&opt_value, &pos))) {
+ if (!strcmp(opt_value->opt, "dev")) {
+ if (devstr != NULL)
+ *devstr = opt_value->value;
+ } else if (!strcmp(opt_value->opt, "type")) {
+ if (namestr != NULL)
+ *namestr = opt_value->value;
+ } else if (!strcmp(opt_value->opt, "kml")) {
+ *flags |= SM_DO_REC;
+ } else if (!strcmp(opt_value->opt, "cache")) {
+ *flags |= SM_CACHE_HOOK;
+ } else if (!strcmp(opt_value->opt, "snap")) {
+ *flags |= SM_DO_COW;
+ } else if (!strcmp(opt_value->opt, "options")) {
+ if (strlen(opts) == 0)
+ sprintf((char *)opts + strlen(opts), "%s",
+ opt_value->value);
+ else
+ sprintf((char *)opts + strlen(opts), ",%s",
+ opt_value->value);
+ } else {
+ /* FIXME-WANGDI: how about the opt_value->value */
+ if (strlen(opts) == 0)
+ sprintf((char *)opts + strlen(opts), "%s",
+ opt_value->opt);
+ else
+ sprintf((char *)opts + strlen(opts), ",%s",
+ opt_value->opt);
+ }
+ }
+ return pos;
+}
+
--- /dev/null
+/* SMFS plugin stuff */
+#define SMFS_PLG_DUMMY 0
+#define SMFS_PLG_KML 1
+#define SMFS_PLG_LRU 2
+#define SMFS_PLG_COW 3
+#define SMFS_PLG_MAX 4
+
+typedef int (*smfs_plg_hook)(int hook_code, void *arg, void * priv);
+typedef int (*smfs_plg_func) (int help_code, void *arg, void * priv);
+
+struct smfs_plugin {
+ struct list_head plg_list;
+ int plg_type;
+
+ smfs_plg_hook plg_pre_op;
+ smfs_plg_hook plg_post_op;
+ smfs_plg_func plg_helper;
+ void * plg_private;
+};
+
+#define HOOK_CREATE 1
+#define HOOK_LOOKUP 2
+#define HOOK_LINK 3
+#define HOOK_UNLINK 4
+#define HOOK_SYMLINK 5
+#define HOOK_MKDIR 6
+#define HOOK_RMDIR 7
+#define HOOK_MKNOD 8
+#define HOOK_RENAME 9
+#define HOOK_SETATTR 10
+#define HOOK_WRITE 11
+#define HOOK_READDIR 12
+#define HOOK_MAX 13
+
+struct hook_data {
+ struct inode * dir;
+ struct dentry * dentry;
+ int ret_code;
+};
+
+struct hook_data_rename {
+ struct hook_data data;
+ struct inode * new_dir;
+ struct inode * new_dentry;
+};
+
+struct hook_data_readdir {
+ struct hook_data data;
+ struct file * filp;
+ void * dirent;
+ filldir_t filldir;
+};
+
+struct hook_data_setattr {
+ struct hook_data data;
+ struct iattr *attr;
+};
+
+
+#define SMFS_PRE_HOOK (op, data) \
+do { \
+ struct list_head *hlist = &smfs_plg_list; \
+ struct smfs_plugin *plugin; \
+ \
+ list_for_each_entry(plugin, hlist, plg_list) { \
+ if (plugin->plg_pre_op) \
+ plugin->plg_pre_op(op, data, \
+ plg->plg_private); \
+ } \
+} while(0)
+
+#define SMFS_POST_HOOK (op, data, rc) \
+do { \
+ struct list_head *hlist = &smfs_plg_list; \
+ struct smfs_plugin *plugin; \
+ \
+ list_for_each_entry(plugin, hlist, plg_list) { \
+ if (plugin->plg_post_op) \
+ plugin->plg_post_op(op, data, \
+ plg->plg_private); \
+ } \
+} while(0)
+
+#define PLG_EXIT 0
+#define PLG_TRANS_SIZE 1
+#define PLG_TEST_INODE 2
+#define PLG_SET_INODE 3
+#define PLG_HELPER_MAX 4
+
+#define SMFS_PLG_HELP (op, data) \
+do { \
+ struct list_head *hlist = &smfs_plg_list; \
+ struct smfs_plugin *plugin; \
+ \
+ list_for_each_entry(plugin, hlist, plg_list) { \
+ if (plugin->plg_helper) \
+ plugin->plg_helper(op, data, \
+ plg->plg_private); \
+ } \
+} while(0)
+
+int smfs_register_plugin(struct smfs_plugin *);
+void * smfs_deregister_plugin(int);
+
+
+
+
+
+
+
#ifndef __LINUX_SMFS_H
#define __LINUX_SMFS_H
-//#include <linux/lustre_fsfilt.h>
+#include "smfs_api.h"
#define SMFSDEV_NAME "/dev/smfsconf"
#define SMFS_PSDEV_MINOR 250
#define SMFS_PSDEV_MAJOR 10
rc = 0;
RETURN(rc);
}
-#define HOOK_CREATE 1
-#define HOOK_LOOKUP 2
-#define HOOK_LINK 3
-#define HOOK_UNLINK 4
-#define HOOK_SYMLINK 5
-#define HOOK_MKDIR 6
-#define HOOK_RMDIR 7
-#define HOOK_MKNOD 8
-#define HOOK_RENAME 9
-#define HOOK_SETATTR 10
-#define HOOK_WRITE 11
-#define HOOK_READDIR 12
-#define HOOK_MAX 12
#define PRE_HOOK 0
#define POST_HOOK 1
GOTO(label, rc); \
} while(0) \
-#define SMFS_GET_INODE(sb, cache_inode, dir, inode, rc, label) \
+#define SMFS_IGET(dir, hash, inode, rc, label) \
do { \
- LASSERT(cache_inode); \
- inode = smfs_get_inode(sb, cache_inode->i_ino, dir, 0); \
- iput(cache_inode); \
+ inode = smfs_get_inode(dir->i_sb, hash, dir, 0); \
if (!inode) \
GOTO(label, rc = -ENOENT); \
-} while(0)
-
+} while(0)
#if CONFIG_SNAPFS
int smfs_cow_init(struct super_block *sb);
#include <linux/lustre_smfs.h>
#include "smfs_internal.h"
-static char *smfs_options(char *data, char **devstr,
- char **namestr, char *opts,
- int *flags)
-{
- struct option *opt_value = NULL;
- char *pos;
-
- LASSERT(opts && flags);
-
- while (!(get_opt(&opt_value, &pos))) {
- if (!strcmp(opt_value->opt, "dev")) {
- if (devstr != NULL)
- *devstr = opt_value->value;
- } else if (!strcmp(opt_value->opt, "type")) {
- if (namestr != NULL)
- *namestr = opt_value->value;
- } else if (!strcmp(opt_value->opt, "kml")) {
- *flags |= SM_DO_REC;
- } else if (!strcmp(opt_value->opt, "cache")) {
- *flags |= SM_CACHE_HOOK;
- } else if (!strcmp(opt_value->opt, "snap")) {
- *flags |= SM_DO_COW;
- } else if (!strcmp(opt_value->opt, "options")) {
- if (strlen(opts) == 0)
- sprintf((char *)opts + strlen(opts), "%s",
- opt_value->value);
- else
- sprintf((char *)opts + strlen(opts), ",%s",
- opt_value->value);
- } else {
- /* FIXME-WANGDI: how about the opt_value->value */
- if (strlen(opts) == 0)
- sprintf((char *)opts + strlen(opts), "%s",
- opt_value->opt);
- else
- sprintf((char *)opts + strlen(opts), ",%s",
- opt_value->opt);
- }
- }
- return pos;
-}
-
-struct super_block *smfs_get_sb_by_path(char *path, int len)
-{
- struct super_block *sb;
- struct nameidata nd;
- int error = 0;
-
- ENTRY;
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
- if (path_init(path, LOOKUP_FOLLOW, &nd)) {
-#else
- if (path_lookup(path, LOOKUP_FOLLOW, &nd)) {
-#endif
- error = path_walk(path, &nd);
- if (error) {
- path_release(&nd);
- RETURN(NULL);
- }
- } else {
- RETURN(NULL);
- }
- /* FIXME-WANGDI: add some check code here. */
- sb = nd.dentry->d_sb;
- path_release(&nd);
- RETURN(sb);
-}
+struct list_head smfs_plg_list;
static struct smfs_super_info *smfs_init_smb(struct super_block *sb)
{
static int smfs_umount_cache(struct smfs_super_info *smb)
{
- struct dentry *root = smb->smsi_sb->s_root;
+ //struct dentry *root = smb->smsi_sb->s_root;
- dput(root);
- if (atomic_read(&root->d_inode->i_count) == 0)
- igrab(root->d_inode);
+ //dput(root);
+ //if (atomic_read(&root->d_inode->i_count) == 0)
+ // igrab(root->d_inode);
mntput(smb->smsi_mnt);
smfs_cleanup_sm_ops(smb);
{
ENTRY;
INIT_LIST_HEAD(&smb->smsi_hook_list);
+ INIT_LIST_HEAD(&smfs_plg_list);
RETURN(0);
}
}
EXIT;
}
-
static void smfs_cleanup_smb(struct super_block *sb)
{
struct smfs_super_info *smb;
RETURN(0);
}
+extern char* smfs_options(char*, char**, char**, char*, int *);
+
int smfs_fill_super(struct super_block *sb, void *data, int silent)
{
struct inode *root_inode = NULL;
memset((void *)page, 0, PAGE_SIZE);
opts = (char *)page;
- init_option(data);
cache_data = smfs_options(data, &devstr, &typestr, opts,
&smb->smsi_flags);
if (*cache_data) {
}
duplicate_sb(sb, smb->smsi_sb);
+ sb->s_bdev = smb->smsi_sb->s_bdev;
sm_set_sb_ops(smb->smsi_sb, sb);
err = smfs_init_hook_ops(smb);
}
/* init the root_inode of smfs. */
- dget(S2CSB(sb)->s_root);
+ //dget(S2CSB(sb)->s_root);
root_ino = S2CSB(sb)->s_root->d_inode->i_ino;
root_inode = smfs_get_inode(sb, root_ino, NULL, 0);
CDEBUG(D_SUPER, "sb %lx, &sb->u.generic_sbp: %lx\n",
(ulong)sb, (ulong)&sb->u.generic_sbp);
#else
- CDEBUG(D_SUPER, "sb %lx, &sb->s_fs_info: %lx\n",
- (ulong)sb, (ulong)&sb->s_fs_info);
+ CDEBUG(D_SUPER, "sb %lx(%p), &sb->s_fs_info: %lx\n",
+ (ulong)sb, smb->smsi_sb, (ulong)&sb->s_fs_info);
#endif
+
out_err:
cleanup_option();
if (err)
list_del(p);
RETURN(found);
}
- }
+ }
+
RETURN(NULL);
}
fsfilt->fs_commit(inode->i_sb, inode, handle, force_sync);
}
+
+int smfs_register_plugin(struct smfs_plugin * new_plugin)
+{
+ struct smfs_plugin * plg = NULL;
+ struct list_head * plist = &smfs_plg_list;
+
+ ENTRY;
+
+ list_for_each_entry(plg, plist, plg_list) {
+ if (plg->plg_type == new_plugin->plg_type) {
+ CWARN("Plugin is already registered\n");
+ RETURN(-EEXIST);
+ }
+ }
+
+ OBD_ALLOC(plg, sizeof(*plg));
+ if (!plg) {
+ CWARN("Cannot allocate memory for plugin\n");
+ RETURN(-ENOMEM);
+ }
+
+ memcpy(plg, new_plugin, sizeof(*plg));
+ list_add_tail(&plg->plg_list, plist);
+
+ RETURN(0);
+}
+
+void * smfs_deregister_plugin(int type)
+{
+ struct smfs_plugin * plg = NULL;
+ struct list_head * plist = &smfs_plg_list;
+ void * priv = NULL;
+
+ ENTRY;
+ list_for_each_entry(plg, plist, plg_list) {
+ if (plg->plg_type == type) {
+ list_del(&plg->plg_list);
+ priv = plg->plg_private;
+ OBD_FREE(plg, sizeof(*plg));
+ break;
+ }
+ }
+
+ RETURN(priv);
+}
+
+
{
struct inode *cache_inode = I2CI(dentry->d_inode);
struct dentry *cache_dentry;
- int rc = 0;
+ int rc = -ENOMEM;
ENTRY;
- if (!cache_inode)
+ if (!cache_inode || !cache_inode->i_op->readlink)
RETURN(-ENOENT);
cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
- if (!cache_dentry)
- GOTO(exit, rc = -ENOMEM);
- if (cache_inode->i_op && cache_inode->i_op->readlink)
- rc = cache_inode->i_op->readlink(cache_dentry, buffer, buflen);
- GOTO(exit, rc);
-exit:
+ if (cache_dentry)
+ rc = cache_inode->i_op->readlink(cache_dentry, buffer,
+ buflen);
+
post_smfs_dentry(cache_dentry);
return rc;
}
{
struct inode *cache_inode = I2CI(dentry->d_inode);
struct dentry *cache_dentry;
- int rc = 0;
+ int rc = -ENOMEM;
ENTRY;
- if (!cache_inode)
+ if (!cache_inode || !cache_inode->i_op->follow_link)
RETURN(-ENOENT);
cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
- if (!cache_dentry)
- GOTO(exit, rc = -ENOMEM);
-
- if (cache_inode->i_op && cache_inode->i_op->follow_link)
+ if (cache_dentry)
rc = cache_inode->i_op->follow_link(cache_dentry, nd);
-exit:
+
post_smfs_dentry(cache_dentry);
- return rc;
+ RETURN(rc);
}
struct inode_operations smfs_sym_iops = {
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
* vim:expandtab:shiftwidth=8:tabstop=8:
*
- * lustre/smfs/inode.c
+ * lustre/smfs/sysctl.c
* Lustre filesystem abstraction routines
*
* Copyright (C) 2002, 2003 Cluster File Systems, Inc.