#include <linux/lustre_idl.h>
#include <linux/lustre_fsfilt.h>
#include <linux/lustre_smfs.h>
+#include <linux/lustre_snap.h>
#include "smfs_internal.h"
static ssize_t smfs_write(struct file *filp, const char *buf, size_t count,
loff_t *ppos)
{
- struct inode *cache_inode;
+ struct inode *cache_inode = I2CI(filp->f_dentry->d_inode);
struct smfs_file_info *sfi;
- loff_t tmp_ppos;
- loff_t *cache_ppos;
+ loff_t *cache_ppos = NULL;
int rc = 0;
+ struct hook_write_msg msg = {
+ .dentry = filp->f_dentry,
+ .count = count,
+ .pos = *ppos
+ };
+
ENTRY;
- cache_inode = I2CI(filp->f_dentry->d_inode);
-
- if (!cache_inode)
- RETURN(-ENOENT);
+ LASSERT(cache_inode);
+ LASSERT(cache_inode->i_fop->write);
sfi = F2SMFI(filp);
-
- 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;
-
- 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);
- }
-
- SMFS_KML_POST(filp->f_dentry->d_inode, filp->f_dentry,
- ppos, &count, REINT_WRITE, "write", rc, exit);
-exit:
- post_smfs_inode(filp->f_dentry->d_inode, cache_inode);
+ LASSERT(sfi->magic == SMFS_FILE_MAGIC);
+
+ if (filp->f_flags & O_APPEND)
+ msg.pos = filp->f_dentry->d_inode->i_size;
+
+ pre_smfs_file(filp, &msg.pos, &cache_ppos);
+ SMFS_PRE_HOOK(filp->f_dentry->d_inode, HOOK_WRITE, &msg);
+
+ rc = cache_inode->i_fop->write(sfi->c_file, buf, count,
+ cache_ppos);
+
+ SMFS_POST_HOOK(filp->f_dentry->d_inode, HOOK_WRITE, &msg, rc);
+ post_smfs_file(filp);
*ppos = *cache_ppos;
- duplicate_file(filp, sfi->c_file);
+
RETURN(rc);
}
int smfs_ioctl(struct inode * inode, struct file * filp,
unsigned int cmd, unsigned long arg)
{
- struct inode *cache_inode;
+ struct inode *cache_inode = I2CI(filp->f_dentry->d_inode);
struct smfs_file_info *sfi;
ssize_t rc = 0;
ENTRY;
- cache_inode = I2CI(filp->f_dentry->d_inode);
- if (!cache_inode)
- RETURN(-ENOENT);
+ LASSERT(cache_inode);
+ LASSERT(cache_inode->i_fop->ioctl);
sfi = F2SMFI(filp);
- if (sfi->magic != SMFS_FILE_MAGIC) BUG();
+ if (sfi->magic != SMFS_FILE_MAGIC)
+ LBUG();
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);
static ssize_t smfs_read(struct file *filp, char *buf,
size_t count, loff_t *ppos)
{
- struct inode *cache_inode;
+ struct inode *cache_inode = I2CI(filp->f_dentry->d_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)
- RETURN(-ENOENT);
+ LASSERT(cache_inode);
+ LASSERT(cache_inode->i_fop->read);
sfi = F2SMFI(filp);
- 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;
-
- 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);
- }
-
- *ppos = *cache_ppos;
- post_smfs_inode(filp->f_dentry->d_inode, cache_inode);
- duplicate_file(filp, sfi->c_file);
+ if (sfi->magic != SMFS_FILE_MAGIC)
+ LBUG();
+ pre_smfs_file(filp, ppos, &cache_ppos);
+ rc = cache_inode->i_fop->read(sfi->c_file, buf, count, cache_ppos);
+ post_smfs_file(filp);
+
RETURN(rc);
}
-static loff_t smfs_llseek(struct file *file,
- loff_t offset,
- int origin)
+static loff_t smfs_llseek(struct file *file, loff_t offset, int origin)
{
- struct inode *cache_inode;
+ struct inode *cache_inode = I2CI(file->f_dentry->d_inode);
struct smfs_file_info *sfi;
ssize_t rc = 0;
ENTRY;
- cache_inode = I2CI(file->f_dentry->d_inode);
- if (!cache_inode)
- RETURN(-ENOENT);
+ LASSERT(cache_inode);
+ LASSERT(cache_inode->i_fop->llseek);
sfi = F2SMFI(file);
- if (sfi->magic != SMFS_FILE_MAGIC) BUG();
+ if (sfi->magic != SMFS_FILE_MAGIC)
+ LBUG();
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);
{
struct inode *inode = file->f_dentry->d_inode;
struct smfs_file_info *sfi;
- struct inode *cache_inode = NULL;
+ struct inode *cache_inode = I2CI(inode);
int rc = 0;
ENTRY;
- cache_inode = I2CI(inode);
- if (!cache_inode)
- RETURN(-ENOENT);
-
+ LASSERT(cache_inode);
+
sfi = F2SMFI(file);
if (sfi->magic != SMFS_FILE_MAGIC)
- BUG();
+ LBUG();
if (cache_inode->i_mapping == &cache_inode->i_data)
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);
RETURN(-ENOMEM);
cache_filp = get_empty_filp();
- if (!cache_filp)
- GOTO(err_exit, rc = -ENOMEM);
+ if (!cache_filp) {
+ rc = -ENOMEM;
+ goto err_exit;
+ }
sfi->magic = SMFS_FILE_MAGIC;
cache_dentry = pre_smfs_dentry(NULL, I2CI(inode), filp->f_dentry);
- if (!cache_dentry)
- GOTO(err_exit, rc = -ENOMEM);
+ if (!cache_dentry) {
+ rc = -ENOMEM;
+ goto err_exit;
+ }
cache_filp->f_vfsmnt = filp->f_vfsmnt;
-
cache_filp->f_dentry = cache_dentry;
duplicate_file(cache_filp, filp);
-
sfi->c_file = cache_filp;
if (filp->private_data != NULL)
- BUG();
+ LBUG();
filp->private_data = sfi;
- RETURN(rc);
+ RETURN(0);
err_exit:
if (sfi)
OBD_FREE(sfi, sizeof(struct smfs_file_info));
static int smfs_cleanup_cache_file(struct file *filp)
{
struct smfs_file_info *sfi = NULL;
- int rc = 0;
+
ENTRY;
+ if (!filp)
+ RETURN(0);
+
sfi = F2SMFI(filp);
post_smfs_dentry(sfi->c_file->f_dentry);
filp->private_data = NULL;
- RETURN(rc);
+ RETURN(0);
}
int smfs_open(struct inode *inode, struct file *filp)
{
- struct inode *cache_inode = NULL;
+ struct inode *cache_inode = I2CI(inode);
int rc = 0;
+
ENTRY;
-
- cache_inode = I2CI(inode);
- if (!cache_inode)
- RETURN(-ENOENT);
-
+
+ LASSERT(cache_inode);
+
if ((rc = smfs_init_cache_file(inode, filp)))
RETURN(rc);
-
- pre_smfs_inode(inode, cache_inode);
- if (cache_inode->i_fop->open)
+ //it possible that backstore fs has no open(),
+ //but we need it to init cache filp
+ if (cache_inode->i_fop->open) {
rc = cache_inode->i_fop->open(cache_inode, F2CF(filp));
+ duplicate_file(filp, F2CF(filp));
+ }
- post_smfs_inode(inode, cache_inode);
- duplicate_file(filp, F2CF(filp));
RETURN(rc);
}
int smfs_release(struct inode *inode, struct file *filp)
{
- struct inode *cache_inode = NULL;
+ struct inode *cache_inode = I2CI(inode);
+ struct file *cache_file = NULL;
struct smfs_file_info *sfi = NULL;
int rc = 0;
+
ENTRY;
- cache_inode = I2CI(inode);
- if (!cache_inode)
- RETURN(-ENOENT);
-
- sfi = F2SMFI(filp);
- if (sfi->magic != SMFS_FILE_MAGIC)
- BUG();
-
- pre_smfs_inode(inode, cache_inode);
+ LASSERT(cache_inode);
+
+ 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, sfi->c_file);
+ rc = cache_inode->i_fop->release(cache_inode, cache_file);
post_smfs_inode(inode, cache_inode);
- duplicate_file(filp, sfi->c_file);
smfs_cleanup_cache_file(filp);
+
RETURN(rc);
}
int smfs_fsync(struct file *file, struct dentry *dentry, int datasync)
{
struct smfs_file_info *sfi = NULL;
- struct inode *cache_inode;
+ struct dentry *cache_dentry = NULL;
+ struct file *cache_file = NULL;
+ struct inode *cache_inode = I2CI(dentry->d_inode);
int rc = 0;
- cache_inode = I2CI(file->f_dentry->d_inode);
- if (!cache_inode)
- RETURN(-ENOENT);
-
- sfi = F2SMFI(file);
- if (sfi->magic != SMFS_FILE_MAGIC)
- BUG();
+ ENTRY;
+
+ LASSERT(cache_inode);
+ LASSERT(cache_inode->i_fop->fsync);
+
+ cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
+ if (!cache_dentry)
+ RETURN(-ENOMEM);
- pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
+ if (file) {
+ sfi = F2SMFI(file);
+ if (sfi->magic != SMFS_FILE_MAGIC)
+ LBUG();
+ cache_file = sfi->c_file;
+ }
- if (cache_inode->i_fop->fsync)
- rc = cache_inode->i_fop->fsync(sfi->c_file,
- sfi->c_file->f_dentry, datasync);
+ pre_smfs_inode(dentry->d_inode, cache_inode);
- post_smfs_inode(file->f_dentry->d_inode, cache_inode);
- duplicate_file(file, sfi->c_file);
+ 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);
RETURN(rc);
}
static void smfs_truncate(struct inode *inode)
{
- struct inode *cache_inode;
-
- cache_inode = I2CI(inode);
-
- if (!cache_inode)
- return;
+ struct inode *cache_inode = I2CI(inode);
- 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 smfs_setattr(struct dentry *dentry, struct iattr *attr)
{
- struct inode *cache_inode;
+ struct inode *cache_inode = I2CI(dentry->d_inode);
struct dentry *cache_dentry;
void *handle = NULL;
int rc = 0;
+ struct hook_attr_msg msg = {
+ .dentry = dentry,
+ .attr = attr,
+ };
- cache_inode = I2CI(dentry->d_inode);
- if (!cache_inode)
- RETURN(-ENOENT);
+ ENTRY;
+
+ LASSERT(cache_inode);
+ LASSERT(cache_inode->i_op->setattr);
cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
if (!cache_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);
+ rc = -ENOSPC;
+ goto exit;
}
pre_smfs_inode(dentry->d_inode, cache_inode);
-
- if (cache_inode->i_op->setattr)
- rc = cache_inode->i_op->setattr(cache_dentry, attr);
-
- SMFS_KML_POST(dentry->d_inode, dentry, attr, NULL,
- REINT_SETATTR, "setattr", rc, exit);
-exit:
+
+ SMFS_PRE_HOOK(dentry->d_inode, HOOK_SETATTR, &msg);
+
+ rc = cache_inode->i_op->setattr(cache_dentry, attr);
+
+ SMFS_POST_HOOK(dentry->d_inode, HOOK_SETATTR, &msg, rc);
+
post_smfs_inode(dentry->d_inode, cache_inode);
- post_smfs_dentry(cache_dentry);
smfs_trans_commit(dentry->d_inode, handle, 0);
+exit:
+ post_smfs_dentry(cache_dentry);
RETURN(rc);
}
-int smfs_setxattr(struct dentry *dentry, const char *name, const void *value,
- size_t size, int flags)
+int smfs_setxattr(struct dentry *dentry, const char *name,
+ const void *value, size_t size, int flags)
{
- struct inode *cache_inode;
- struct dentry *cache_dentry;
+ struct inode *cache_inode = I2CI(dentry->d_inode);
+ struct dentry *cache_dentry = NULL;
+ struct hook_xattr_msg msg = {
+ .name = (char*)name,
+ };
int rc = 0;
- cache_inode = I2CI(dentry->d_inode);
- if (!cache_inode)
- RETURN(-ENOENT);
-
+ ENTRY;
+
+ LASSERT(cache_inode);
+ LASSERT(cache_inode->i_op->setxattr);
+
cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
if (!cache_dentry)
RETURN(-ENOMEM);
pre_smfs_inode(dentry->d_inode, cache_inode);
+ SMFS_PRE_HOOK(dentry->d_inode, HOOK_SETXATTR, &msg);
- 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);
+
+ SMFS_POST_HOOK(dentry->d_inode, HOOK_SETXATTR, &msg, rc);
post_smfs_inode(dentry->d_inode, cache_inode);
post_smfs_dentry(cache_dentry);
RETURN(rc);
}
-int smfs_getxattr(struct dentry *dentry, const char *name, void *buffer,
- size_t size)
+int smfs_getxattr(struct dentry *dentry, const char *name,
+ void *buffer, size_t size)
{
- struct inode *cache_inode;
+ struct inode *cache_inode = I2CI(dentry->d_inode);
struct dentry *cache_dentry;
+ struct hook_xattr_msg msg = {
+ .name = (char*)name,
+ };
int rc = 0;
- cache_inode = I2CI(dentry->d_inode);
- if (!cache_inode)
- RETURN(-ENOENT);
-
+ ENTRY;
+
+ LASSERT(cache_inode);
+ LASSERT(cache_inode->i_op->getxattr);
+
cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
if (!cache_dentry)
RETURN(-ENOMEM);
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);
-
+ SMFS_PRE_HOOK(dentry->d_inode, HOOK_GETXATTR, &msg);
+ rc = cache_inode->i_op->getxattr(cache_dentry, name, buffer,
+ size);
+ SMFS_POST_HOOK(dentry->d_inode, HOOK_GETXATTR, &msg, rc);
post_smfs_inode(dentry->d_inode, cache_inode);
post_smfs_dentry(cache_dentry);
ssize_t smfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
{
- struct inode *cache_inode;
+ struct inode *cache_inode = I2CI(dentry->d_inode);
struct dentry *cache_dentry;
int rc = 0;
-
- cache_inode = I2CI(dentry->d_inode);
- if (!cache_inode)
- RETURN(-ENOENT);
+ struct hook_xattr_msg msg = {
+ .name = NULL,
+ };
+
+ ENTRY;
+
+ LASSERT(cache_inode);
+ LASSERT(cache_inode->i_op->listxattr);
cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
if (!cache_dentry)
RETURN(-ENOMEM);
pre_smfs_inode(dentry->d_inode, cache_inode);
+ SMFS_PRE_HOOK(dentry->d_inode, HOOK_LISTXATTR, &msg);
- 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);
+ SMFS_POST_HOOK(dentry->d_inode, HOOK_LISTXATTR, &msg, rc);
post_smfs_inode(dentry->d_inode, cache_inode);
post_smfs_dentry(cache_dentry);
int smfs_removexattr(struct dentry *dentry, const char *name)
{
- struct inode *cache_inode;
+ struct inode *cache_inode = I2CI(dentry->d_inode);
struct dentry *cache_dentry;
int rc = 0;
-
- cache_inode = I2CI(dentry->d_inode);
- if (!cache_inode)
- RETURN(-ENOENT);
+ struct hook_xattr_msg msg = {
+ .name = (char*)name,
+ };
+ ENTRY;
+
+ LASSERT(cache_inode);
+ LASSERT(cache_inode->i_op->removexattr);
cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
if (!cache_dentry)
RETURN(-ENOMEM);
pre_smfs_inode(dentry->d_inode, cache_inode);
+ SMFS_PRE_HOOK(dentry->d_inode, HOOK_REMOVEXATTR, &msg);
- if (cache_inode->i_op->removexattr)
- rc = cache_inode->i_op->removexattr(cache_dentry, name);
+ rc = cache_inode->i_op->removexattr(cache_dentry, name);
+ SMFS_POST_HOOK(dentry->d_inode, HOOK_REMOVEXATTR, &msg, rc);
post_smfs_inode(dentry->d_inode, cache_inode);
post_smfs_dentry(cache_dentry);
RETURN(rc);
}
+int smfs_permission(struct inode *inode, int mask, struct nameidata *nd)
+{
+ struct inode *cache_inode = I2CI(inode);
+ int rc = 0;
+
+ ENTRY;
+
+ LASSERT(cache_inode);
+ LASSERT(cache_inode->i_op->permission);
+
+ pre_smfs_inode(inode, cache_inode);
+
+ rc = cache_inode->i_op->permission(cache_inode, mask, nd);
+
+ post_smfs_inode(inode, cache_inode);
+
+ RETURN(rc);
+}
+
struct inode_operations smfs_file_iops = {
- truncate: smfs_truncate, /* BKL held */
- setattr: smfs_setattr, /* BKL held */
- setxattr: smfs_setxattr, /* BKL held */
- getxattr: smfs_getxattr, /* BKL held */
- listxattr: smfs_listxattr, /* BKL held */
- removexattr: smfs_removexattr, /* BKL held */
+ .truncate = smfs_truncate, /* BKL held */
+ .setattr = smfs_setattr, /* BKL held */
+ .setxattr = smfs_setxattr,
+ .getxattr = smfs_getxattr,
+ .listxattr = smfs_listxattr,
+ .removexattr = smfs_removexattr,
+ .permission = smfs_permission,
};
+
+struct inode_operations smfs_special_iops = {
+ .setattr = smfs_setattr, /* BKL held */
+ .setxattr = smfs_setxattr,
+ .getxattr = smfs_getxattr,
+ .listxattr = smfs_listxattr,
+ .removexattr = smfs_removexattr,
+ .permission = smfs_permission,
+};
+