X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fsmfs%2Ffile.c;h=d7806bb70bf6b34d8a82d51e0144728c1f7b5de5;hb=c1f0d31d6bca15ae08f44a8b76eac2f849436b39;hp=eaf190164cad096e51d3f2bfdb1d556b6677e2be;hpb=070152d89a5c07d5e4e66f74f1fd51083ed75cf3;p=fs%2Flustre-release.git diff --git a/lustre/smfs/file.c b/lustre/smfs/file.c index eaf1901..d7806bb 100644 --- a/lustre/smfs/file.c +++ b/lustre/smfs/file.c @@ -1,5 +1,25 @@ -/* - * file.c +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * lustre/smfs/inode.c + * Lustre filesystem abstraction routines + * + * Copyright (C) 2004 Cluster File Systems, Inc. + * + * This file is part of Lustre, http://www.lustre.org. + * + * Lustre is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * Lustre is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Lustre; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define DEBUG_SUBSYSTEM S_SM @@ -11,448 +31,534 @@ #include #include #include +#include +#include +#include +#include +#include #include -#include "smfs_internal.h" - -/* instantiate a file handle to the cache file */ -void smfs_prepare_cachefile(struct inode *inode, - struct file *file, - struct inode *cache_inode, - struct file *cache_file, - struct dentry *cache_dentry) +#include +#include +#include + +#include "smfs_internal.h" + +static ssize_t smfs_write(struct file *filp, const char *buf, size_t count, + loff_t *ppos) { - ENTRY; - cache_file->f_pos = file->f_pos; - cache_file->f_mode = file->f_mode; - cache_file->f_flags = file->f_flags; - cache_file->f_count = file->f_count; - cache_file->f_owner = file->f_owner; - cache_file->f_error = file->f_error; - cache_file->f_op = inode->i_fop; - cache_file->f_dentry = cache_dentry; - cache_file->f_dentry->d_inode = cache_inode; - cache_file->f_vfsmnt = file->f_vfsmnt; - cache_file->private_data = file->private_data; - cache_file->f_it = file->f_it; - cache_file->f_reada = file->f_reada; - cache_file->f_ramax = file->f_ramax; - cache_file->f_raend = file->f_raend; - cache_file->f_ralen = file->f_ralen; - cache_file->f_rawin = file->f_rawin; - EXIT; + struct inode *cache_inode = I2CI(filp->f_dentry->d_inode); + struct smfs_file_info *sfi; + loff_t *cache_ppos = NULL; + int rc = 0; + struct hook_write_msg msg = { + .dentry = filp->f_dentry, + .count = count, + .pos = *ppos + }; + + ENTRY; + + LASSERT(cache_inode); + LASSERT(cache_inode->i_fop->write); + + sfi = F2SMFI(filp); + 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; + + RETURN(rc); } -/* update file structs*/ -void smfs_update_file(struct file *file, - struct file *cache_file) + +int smfs_ioctl(struct inode * inode, struct file * filp, + unsigned int cmd, unsigned long arg) { - ENTRY; - file->f_pos = cache_file->f_pos; - file->f_mode = cache_file->f_mode; - file->f_flags = cache_file->f_flags; - file->f_count = cache_file->f_count; - file->f_owner = cache_file->f_owner; - file->f_reada = cache_file->f_reada; - file->f_ramax = cache_file->f_ramax; - file->f_raend = cache_file->f_raend; - file->f_ralen = cache_file->f_ralen; - file->f_rawin = cache_file->f_rawin; - EXIT; + struct inode *cache_inode = I2CI(filp->f_dentry->d_inode); + struct smfs_file_info *sfi; + ssize_t rc = 0; + + ENTRY; + + LASSERT(cache_inode); + LASSERT(cache_inode->i_fop->ioctl); + + sfi = F2SMFI(filp); + if (sfi->magic != SMFS_FILE_MAGIC) + LBUG(); + + pre_smfs_inode(inode, cache_inode); + + 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); + + RETURN(rc); } -static ssize_t smfs_write (struct file *filp, const char *buf, - size_t count, loff_t *ppos) +static ssize_t smfs_read(struct file *filp, char *buf, + size_t count, loff_t *ppos) { - struct inode *cache_inode; - struct dentry *dentry = filp->f_dentry; - struct inode *inode = dentry->d_inode; - struct file open_file; - struct dentry open_dentry; - loff_t tmp_ppos; - loff_t *cache_ppos; - int rc = 0; - - ENTRY; - - cache_inode = I2CI(inode); - - if (!cache_inode) - RETURN(-ENOENT); - - if (ppos != &(filp->f_pos)) { - cache_ppos = &tmp_ppos; - } else { - cache_ppos = &open_file.f_pos; - } - *cache_ppos = *ppos; - - smfs_prepare_cachefile(inode, filp, cache_inode, - &open_file, &open_dentry); - pre_smfs_inode(inode, cache_inode); - - if (cache_inode->i_fop->write) - rc = cache_inode->i_fop->write(&open_file, buf, count, cache_ppos); - - *ppos = *cache_ppos; - post_smfs_inode(inode, cache_inode); - smfs_update_file(filp, &open_file); - - RETURN(rc); + struct inode *cache_inode = I2CI(filp->f_dentry->d_inode); + struct smfs_file_info *sfi; + loff_t *cache_ppos = NULL; + ssize_t rc = 0; + + ENTRY; + + LASSERT(cache_inode); + LASSERT(cache_inode->i_fop->read); + + sfi = F2SMFI(filp); + 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); } -int smfs_ioctl(struct inode * inode, struct file * filp, - unsigned int cmd, unsigned long arg) +static loff_t smfs_llseek(struct file *file, loff_t offset, int origin) { - struct inode *cache_inode; - struct dentry *dentry = filp->f_dentry; - struct file open_file; - struct dentry open_dentry; - ssize_t rc = 0; - - ENTRY; - - cache_inode = I2CI(dentry->d_inode); - if (!cache_inode) - RETURN(-ENOENT); - - smfs_prepare_cachefile(inode, filp, cache_inode, - &open_file, &open_dentry); - - if (cache_inode->i_fop->ioctl) - rc = cache_inode->i_fop->ioctl(cache_inode, &open_file, cmd, arg); - - post_smfs_inode(inode, cache_inode); - smfs_update_file(filp, &open_file); + struct inode *cache_inode = I2CI(file->f_dentry->d_inode); + struct smfs_file_info *sfi; + ssize_t rc = 0; + + ENTRY; + + LASSERT(cache_inode); + LASSERT(cache_inode->i_fop->llseek); + + sfi = F2SMFI(file); + if (sfi->magic != SMFS_FILE_MAGIC) + LBUG(); + + pre_smfs_inode(file->f_dentry->d_inode, cache_inode); + + 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); + RETURN(rc); } -static ssize_t smfs_read (struct file *filp, char *buf, - size_t count, loff_t *ppos) +static int smfs_mmap(struct file *file, struct vm_area_struct *vma) { - struct inode *cache_inode; - struct dentry *dentry = filp->f_dentry; - struct inode *inode = dentry->d_inode; - struct file open_file; - struct dentry open_dentry; - loff_t tmp_ppos; - loff_t *cache_ppos; - ssize_t rc = 0; - - ENTRY; - - cache_inode = I2CI(dentry->d_inode); - if (!cache_inode) - RETURN(-ENOENT); - - if (ppos != &(filp->f_pos)) { - cache_ppos = &tmp_ppos; - } else { - cache_ppos = &open_file.f_pos; - } - *cache_ppos = *ppos; - - - smfs_prepare_cachefile(inode, filp, cache_inode, - &open_file, &open_dentry); - - - pre_smfs_inode(inode, cache_inode); - if (cache_inode->i_fop->read) - rc = cache_inode->i_fop->read(&open_file, buf, count, cache_ppos); - - *ppos = *cache_ppos; - post_smfs_inode(inode, cache_inode); - smfs_update_file(filp, &open_file); - RETURN(rc); + struct inode *inode = file->f_dentry->d_inode; + struct smfs_file_info *sfi; + struct inode *cache_inode = I2CI(inode); + int rc = 0; + ENTRY; + + LASSERT(cache_inode); + + sfi = F2SMFI(file); + if (sfi->magic != SMFS_FILE_MAGIC) + LBUG(); + + if (cache_inode->i_mapping == &cache_inode->i_data) + inode->i_mapping = cache_inode->i_mapping; + + pre_smfs_inode(inode, cache_inode); + + rc = cache_inode->i_fop->mmap(sfi->c_file, vma); + + post_smfs_inode(inode, cache_inode); + duplicate_file(file, sfi->c_file); + + RETURN(rc); } -static loff_t smfs_llseek(struct file *file, - loff_t offset, - int origin) +static int smfs_init_cache_file(struct inode *inode, struct file *filp) { - struct inode *cache_inode; - struct dentry *dentry = file->f_dentry; - struct file open_file; - struct dentry open_dentry; - ssize_t rc = 0; - - ENTRY; - - cache_inode = I2CI(dentry->d_inode); - if (!cache_inode) - RETURN(-ENOENT); - - smfs_prepare_cachefile(dentry->d_inode, file, cache_inode, - &open_file, &open_dentry); - - pre_smfs_inode(dentry->d_inode, cache_inode); - if (cache_inode->i_fop->llseek) - rc = cache_inode->i_fop->llseek(&open_file, offset, origin); - - post_smfs_inode(dentry->d_inode, cache_inode); - smfs_update_file(file, &open_file); - + struct smfs_file_info *sfi = NULL; + struct file *cache_filp = NULL; + struct dentry *cache_dentry = NULL; + int rc = 0; + ENTRY; + + OBD_ALLOC(sfi, sizeof(struct smfs_file_info)); + if (!sfi) + RETURN(-ENOMEM); + + cache_filp = get_empty_filp(); + 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) { + 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) + LBUG(); + + filp->private_data = sfi; + + RETURN(0); +err_exit: + if (sfi) + OBD_FREE(sfi, sizeof(struct smfs_file_info)); + if (cache_filp) + put_filp(cache_filp); RETURN(rc); } -static int smfs_mmap(struct file * file, struct vm_area_struct * vma) +static int smfs_cleanup_cache_file(struct file *filp) { - struct inode *inode = file->f_dentry->d_inode; - struct inode *cache_inode = NULL; - struct file open_file; - struct dentry open_dentry; - int rc = 0; - - cache_inode = I2CI(inode); - if (!cache_inode) - RETURN(-ENOENT); - - smfs_prepare_cachefile(inode, file, cache_inode, - &open_file, &open_dentry); - - if (cache_inode->i_mapping == &cache_inode->i_data) - inode->i_mapping = cache_inode->i_mapping; + struct smfs_file_info *sfi = NULL; + + ENTRY; + + if (!filp) + RETURN(0); + + sfi = F2SMFI(filp); + + post_smfs_dentry(sfi->c_file->f_dentry); + + put_filp(sfi->c_file); + + OBD_FREE(sfi, sizeof(struct smfs_file_info)); - pre_smfs_inode(inode, cache_inode); - if (cache_inode->i_fop->mmap) - rc = cache_inode->i_fop->mmap(&open_file, vma); - - post_smfs_inode(inode, cache_inode); - smfs_update_file(file, &open_file); - - RETURN(rc); + filp->private_data = NULL; + + RETURN(0); } -static int smfs_open(struct inode * inode, struct file * filp) +int smfs_open(struct inode *inode, struct file *filp) { - struct inode *cache_inode = NULL; - struct file open_file; - struct dentry open_dentry; - int rc = 0; - - cache_inode = I2CI(inode); - if (!cache_inode) - RETURN(-ENOENT); - - smfs_prepare_cachefile(inode, filp, cache_inode, - &open_file, &open_dentry); - - pre_smfs_inode(inode, cache_inode); - if (cache_inode->i_fop->open) - rc = cache_inode->i_fop->open(cache_inode, &open_file); - - post_smfs_inode(inode, cache_inode); - smfs_update_file(filp, &open_file); - - RETURN(rc); + struct inode *cache_inode = I2CI(inode); + int rc = 0; + + ENTRY; + + LASSERT(cache_inode); + + if ((rc = smfs_init_cache_file(inode, filp))) + RETURN(rc); + //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)); + } + RETURN(rc); } -static int smfs_release(struct inode * inode, struct file * filp) + +int smfs_release(struct inode *inode, struct file *filp) { - struct inode *cache_inode = NULL; - struct file open_file; - struct dentry open_dentry; - int rc = 0; - - cache_inode = I2CI(inode); - if (!cache_inode) - RETURN(-ENOENT); - - smfs_prepare_cachefile(inode, filp, cache_inode, - &open_file, &open_dentry); - - pre_smfs_inode(inode, cache_inode); - if (cache_inode->i_fop->release) - rc = cache_inode->i_fop->release(cache_inode, &open_file); - - post_smfs_inode(inode, cache_inode); - smfs_update_file(filp, &open_file); - - RETURN(rc); + struct inode *cache_inode = I2CI(inode); + struct file *cache_file = NULL; + struct smfs_file_info *sfi = NULL; + int rc = 0; + + ENTRY; + + 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, cache_file); + + post_smfs_inode(inode, cache_inode); + + smfs_cleanup_cache_file(filp); + + RETURN(rc); } -int smfs_fsync(struct file * file, - struct dentry *dentry, - int datasync) + +int smfs_fsync(struct file *file, struct dentry *dentry, int datasync) { - struct inode *inode = dentry->d_inode; - struct inode *cache_inode; - struct file open_file; - struct dentry open_dentry; - int rc = 0; - - cache_inode = I2CI(inode); - if (!cache_inode) - RETURN(-ENOENT); - - smfs_prepare_cachefile(inode, file, cache_inode, - &open_file, &open_dentry); - - pre_smfs_inode(inode, cache_inode); - if (cache_inode->i_fop->fsync) - rc = cache_inode->i_fop->fsync(&open_file, &open_dentry, datasync); - - post_smfs_inode(inode, cache_inode); - smfs_update_file(file, &open_file); - - RETURN(rc); + struct smfs_file_info *sfi = NULL; + struct dentry *cache_dentry = NULL; + struct file *cache_file = NULL; + struct inode *cache_inode = I2CI(dentry->d_inode); + int rc = 0; + + ENTRY; + + LASSERT(cache_inode); + LASSERT(cache_inode->i_fop->fsync); + + cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry); + if (!cache_dentry) + RETURN(-ENOMEM); + + if (file) { + sfi = F2SMFI(file); + if (sfi->magic != SMFS_FILE_MAGIC) + LBUG(); + cache_file = sfi->c_file; + } + + pre_smfs_inode(dentry->d_inode, cache_inode); + + 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); } struct file_operations smfs_file_fops = { - llseek: smfs_llseek, - read: smfs_read, - write: smfs_write, - ioctl: smfs_ioctl, - mmap: smfs_mmap, - open: smfs_open, - release: smfs_release, - fsync: smfs_fsync, + llseek: smfs_llseek, + read: smfs_read, + write: smfs_write, + ioctl: smfs_ioctl, + mmap: smfs_mmap, + open: smfs_open, + release: smfs_release, + fsync: smfs_fsync, }; -static void smfs_prepare_cache_dentry(struct dentry *dentry, struct inode *inode) +static void smfs_truncate(struct inode *inode) { - atomic_set(&dentry->d_count, 1); - dentry->d_vfs_flags = 0; - dentry->d_flags = 0; - dentry->d_inode = inode; - dentry->d_op = NULL; - dentry->d_fsdata = NULL; - dentry->d_mounted = 0; - INIT_LIST_HEAD(&dentry->d_hash); - INIT_LIST_HEAD(&dentry->d_lru); - INIT_LIST_HEAD(&dentry->d_subdirs); - INIT_LIST_HEAD(&dentry->d_alias); + struct inode *cache_inode = I2CI(inode); + + if (!cache_inode || !cache_inode->i_op->truncate) + return; + + pre_smfs_inode(inode, cache_inode); + + cache_inode->i_op->truncate(cache_inode); + + post_smfs_inode(inode, cache_inode); + + return; } -static void smfs_truncate(struct inode * 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, + }; + + ENTRY; + + LASSERT(cache_inode); + LASSERT(cache_inode->i_op->setattr); - cache_inode = I2CI(inode); + cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry); + if (!cache_dentry) + RETURN(-ENOMEM); - if (!cache_inode) - return; - - if (cache_inode->i_op->truncate) - cache_inode->i_op->truncate(cache_inode); + handle = smfs_trans_start(dentry->d_inode, FSFILT_OP_SETATTR, NULL); + if (IS_ERR(handle) ) { + rc = -ENOSPC; + goto exit; + } - post_smfs_inode(inode, cache_inode); + pre_smfs_inode(dentry->d_inode, cache_inode); - return; -} - -int smfs_setattr(struct dentry *dentry, struct iattr *attr) -{ - struct inode *cache_inode; - struct dentry open_dentry; - - int rc = 0; - - cache_inode = I2CI(dentry->d_inode); - - if (!cache_inode) - RETURN(-ENOENT); - smfs_prepare_cache_dentry(&open_dentry, cache_inode); - - pre_smfs_inode(dentry->d_inode, cache_inode); - if (cache_inode->i_op->setattr) - rc = cache_inode->i_op->setattr(&open_dentry, attr); - - post_smfs_inode(dentry->d_inode, cache_inode); - - RETURN(rc); -} - + 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); + 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) + const void *value, size_t size, int flags) { - struct inode *cache_inode; - struct dentry open_dentry; - int rc = 0; + struct inode *cache_inode = I2CI(dentry->d_inode); + struct dentry *cache_dentry = NULL; + struct hook_xattr_msg msg = { + .name = (char*)name, + }; + int rc = 0; + + ENTRY; + + LASSERT(cache_inode); + LASSERT(cache_inode->i_op->setxattr); + + cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry); + if (!cache_dentry) + RETURN(-ENOMEM); - cache_inode = I2CI(dentry->d_inode); + pre_smfs_inode(dentry->d_inode, cache_inode); + SMFS_PRE_HOOK(dentry->d_inode, HOOK_SETXATTR, &msg); - if (!cache_inode) - RETURN(-ENOENT); + 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); - pre_smfs_inode(dentry->d_inode, cache_inode); - smfs_prepare_cache_dentry(&open_dentry, cache_inode); - - if (cache_inode->i_op->setattr) - rc = cache_inode->i_op->setxattr(&open_dentry, name, value, size, flags); + RETURN(rc); +} - post_smfs_inode(dentry->d_inode, cache_inode); - RETURN(rc); -} - int smfs_getxattr(struct dentry *dentry, const char *name, - void *buffer, size_t size) + void *buffer, size_t size) +{ + struct inode *cache_inode = I2CI(dentry->d_inode); + struct dentry *cache_dentry; + struct hook_xattr_msg msg = { + .name = (char*)name, + }; + int rc = 0; + + 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); + 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); + + RETURN(rc); +} + +ssize_t smfs_listxattr(struct dentry *dentry, char *buffer, size_t size) { - struct inode *cache_inode; - struct dentry open_dentry; - int rc = 0; + struct inode *cache_inode = I2CI(dentry->d_inode); + struct dentry *cache_dentry; + int rc = 0; + struct hook_xattr_msg msg = { + .name = NULL, + }; + + ENTRY; + + LASSERT(cache_inode); + LASSERT(cache_inode->i_op->listxattr); - cache_inode = I2CI(dentry->d_inode); + cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry); + if (!cache_dentry) + RETURN(-ENOMEM); - if (!cache_inode) - RETURN(-ENOENT); + pre_smfs_inode(dentry->d_inode, cache_inode); + SMFS_PRE_HOOK(dentry->d_inode, HOOK_LISTXATTR, &msg); - smfs_prepare_cache_dentry(&open_dentry, cache_inode); - pre_smfs_inode(dentry->d_inode, cache_inode); - - if (cache_inode->i_op->setattr) - rc = cache_inode->i_op->getxattr(&open_dentry, name, buffer, size); + rc = cache_inode->i_op->listxattr(cache_dentry, buffer, size); - post_smfs_inode(dentry->d_inode, cache_inode); - RETURN(rc); + SMFS_POST_HOOK(dentry->d_inode, HOOK_LISTXATTR, &msg, rc); + post_smfs_inode(dentry->d_inode, cache_inode); + post_smfs_dentry(cache_dentry); + + RETURN(rc); } -ssize_t smfs_listxattr(struct dentry *dentry, char *buffer, size_t size) +int smfs_removexattr(struct dentry *dentry, const char *name) { - struct inode *cache_inode; - struct dentry open_dentry; - int rc = 0; + struct inode *cache_inode = I2CI(dentry->d_inode); + struct dentry *cache_dentry; + int rc = 0; + struct hook_xattr_msg msg = { + .name = (char*)name, + }; + ENTRY; + + LASSERT(cache_inode); + LASSERT(cache_inode->i_op->removexattr); - cache_inode = I2CI(dentry->d_inode); + cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry); + if (!cache_dentry) + RETURN(-ENOMEM); - if (!cache_inode) - RETURN(-ENOENT); + pre_smfs_inode(dentry->d_inode, cache_inode); + SMFS_PRE_HOOK(dentry->d_inode, HOOK_REMOVEXATTR, &msg); - smfs_prepare_cache_dentry(&open_dentry, cache_inode); - pre_smfs_inode(dentry->d_inode, cache_inode); - - if (cache_inode->i_op->listxattr) - rc = cache_inode->i_op->listxattr(&open_dentry, buffer, size); + rc = cache_inode->i_op->removexattr(cache_dentry, name); - post_smfs_inode(dentry->d_inode, cache_inode); - RETURN(rc); -} + SMFS_POST_HOOK(dentry->d_inode, HOOK_REMOVEXATTR, &msg, rc); + post_smfs_inode(dentry->d_inode, cache_inode); + post_smfs_dentry(cache_dentry); -int smfs_removexattr(struct dentry *dentry, const char *name) + RETURN(rc); +} + +int smfs_permission(struct inode *inode, int mask, struct nameidata *nd) { - struct inode *cache_inode; - struct dentry open_dentry; - int rc = 0; + struct inode *cache_inode = I2CI(inode); + int rc = 0; + + ENTRY; + + LASSERT(cache_inode); + LASSERT(cache_inode->i_op->permission); - cache_inode = I2CI(dentry->d_inode); + pre_smfs_inode(inode, cache_inode); - if (!cache_inode) - RETURN(-ENOENT); + rc = cache_inode->i_op->permission(cache_inode, mask, nd); - smfs_prepare_cache_dentry(&open_dentry, cache_inode); - pre_smfs_inode(dentry->d_inode, cache_inode); - - if (cache_inode->i_op->removexattr) - rc = cache_inode->i_op->removexattr(&open_dentry, name); + post_smfs_inode(inode, cache_inode); - post_smfs_inode(dentry->d_inode, cache_inode); - RETURN(rc); + 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, };