X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fsmfs%2Ffile.c;h=af1e1f5f7d50f5f2d8da722726ab3eec077886e5;hb=def4ec88f48ec7204632df8ecafbe2db45627f69;hp=fce003a593c6481f16b52ea280f83cd8dbaf230b;hpb=c844b8967dee2fcc0d84372967a028616c76adcd;p=fs%2Flustre-release.git diff --git a/lustre/smfs/file.c b/lustre/smfs/file.c index fce003a..af1e1f5 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,634 +31,517 @@ #include #include #include -#include "smfs_internal.h" - -static int smfs_readpage(struct file *file, - struct page *page) +#include +#include +#include +#include +#include +#include +#include +#include + +#include "smfs_internal.h" + +static ssize_t smfs_write(struct file *filp, const char *buf, size_t count, + loff_t *ppos) { - struct inode *inode = page->mapping->host; - struct inode *cache_inode; - struct page *cache_page = NULL; - int rc = 0; - - ENTRY; - - cache_inode = I2CI(inode); - - if (!cache_inode) - RETURN(-ENOENT); - - cache_page = grab_cache_page(cache_inode->i_mapping, page->index); - - if (!cache_page) - GOTO(exit_release, rc = -ENOMEM); + struct inode *cache_inode; + struct smfs_file_info *sfi; + loff_t tmp_ppos; + loff_t *cache_ppos; + int rc = 0; + ENTRY; - if ((rc = cache_inode->i_mapping->a_ops->readpage(file, cache_page))) - GOTO(exit_release, 0); - - wait_on_page(cache_page); + cache_inode = I2CI(filp->f_dentry->d_inode); - if (!Page_Uptodate(cache_page)) - GOTO(exit_release, rc = -EIO); + if (!cache_inode) + RETURN(-ENOENT); - memcpy(kmap(page), kmap(cache_page), PAGE_CACHE_SIZE); + sfi = F2SMFI(filp); - flush_dcache_page(page); + if (sfi->magic != SMFS_FILE_MAGIC) + LBUG(); - kunmap(cache_page); - page_cache_release(cache_page); + if (ppos != &(filp->f_pos)) { + cache_ppos = &tmp_ppos; + } else { + cache_ppos = &sfi->c_file->f_pos; + } + *cache_ppos = *ppos; -exit: - kunmap(page); - SetPageUptodate(page); - UnlockPage(page); + pre_smfs_inode(filp->f_dentry->d_inode, cache_inode); - RETURN(rc); + if (cache_inode->i_fop->write) { + rc = cache_inode->i_fop->write(sfi->c_file, buf, + count, cache_ppos); + } -exit_release: - if (cache_page) - page_cache_release(cache_page); - UnlockPage(page); - RETURN(rc); + 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); + *ppos = *cache_ppos; + duplicate_file(filp, sfi->c_file); + RETURN(rc); } -static int smfs_writepage(struct page *page) +int smfs_ioctl(struct inode * inode, struct file * filp, + unsigned int cmd, unsigned long arg) { + struct inode *cache_inode; + struct smfs_file_info *sfi; + ssize_t rc = 0; - struct inode *inode = page->mapping->host; - struct inode *cache_inode; - int rc; - - ENTRY; - - cache_inode = I2CI(inode); - + ENTRY; + + cache_inode = I2CI(filp->f_dentry->d_inode); if (!cache_inode) RETURN(-ENOENT); - if (cache_inode->i_mapping->a_ops->writepage) - rc = cache_inode->i_mapping->a_ops->writepage(page); - - RETURN(rc); -} + sfi = F2SMFI(filp); + if (sfi->magic != SMFS_FILE_MAGIC) + LBUG(); -static int smfs_sync_page(struct page *page) -{ - struct inode *inode = page->mapping->host; - struct inode *cache_inode; - int rc = 0; - - cache_inode = I2CI(inode); - - if (!cache_inode) - RETURN(-ENOENT); + 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); + } - if (cache_inode->i_mapping->a_ops->sync_page) - rc = cache_inode->i_mapping->a_ops->sync_page(page); + post_smfs_inode(inode, cache_inode); + duplicate_file(filp, sfi->c_file); RETURN(rc); } -static int smfs_prepare_write(struct file *file, struct page *page, - unsigned from, unsigned to) +static ssize_t smfs_read(struct file *filp, char *buf, + size_t count, loff_t *ppos) { - struct inode *inode = page->mapping->host; - struct inode *cache_inode; - int rc = 0; - - cache_inode = I2CI(inode); - + struct inode *cache_inode; + struct smfs_file_info *sfi; + loff_t tmp_ppos; + loff_t *cache_ppos; + ssize_t rc = 0; + + ENTRY; + + cache_inode = I2CI(filp->f_dentry->d_inode); if (!cache_inode) RETURN(-ENOENT); - if (cache_inode->i_mapping->a_ops->prepare_write) - rc = cache_inode->i_mapping->a_ops->prepare_write(file, page, from, to); + sfi = F2SMFI(filp); + if (sfi->magic != SMFS_FILE_MAGIC) + LBUG(); + + 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); RETURN(rc); } -static int smfs_commit_write(struct file *file, struct page *page, - unsigned from, unsigned to) +static loff_t smfs_llseek(struct file *file, + loff_t offset, + int origin) { - struct inode *inode = page->mapping->host; - struct inode *cache_inode; - int rc = 0; - - cache_inode = I2CI(inode); - + struct inode *cache_inode; + struct smfs_file_info *sfi; + ssize_t rc = 0; + + ENTRY; + + cache_inode = I2CI(file->f_dentry->d_inode); if (!cache_inode) RETURN(-ENOENT); - if (cache_inode->i_mapping->a_ops->commit_write) - rc = cache_inode->i_mapping->a_ops->commit_write(file, page, from, to); + sfi = F2SMFI(file); + 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); + } + + post_smfs_inode(file->f_dentry->d_inode, cache_inode); + duplicate_file(file, sfi->c_file); RETURN(rc); } -static int smfs_bmap(struct address_space *mapping, long block) +static int smfs_mmap(struct file *file, struct vm_area_struct *vma) { - struct inode *inode = mapping->host; - struct inode *cache_inode; - int rc = 0; - - cache_inode = I2CI(inode); - + struct inode *inode = file->f_dentry->d_inode; + struct smfs_file_info *sfi; + struct inode *cache_inode = NULL; + int rc = 0; + ENTRY; + + cache_inode = I2CI(inode); if (!cache_inode) RETURN(-ENOENT); - if (cache_inode->i_mapping->a_ops->bmap) - rc = cache_inode->i_mapping->a_ops->bmap(mapping, block); + 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); + if (cache_inode->i_fop->mmap) + 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 int smfs_flushpage(struct page *page, unsigned long offset) +static int smfs_init_cache_file(struct inode *inode, struct file *filp) { - struct inode *inode = page->mapping->host; - struct inode *cache_inode; - int rc = 0; - - cache_inode = I2CI(inode); - - if (!cache_inode) - RETURN(-ENOENT); + 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) + GOTO(err_exit, rc = -ENOMEM); + + sfi->magic = SMFS_FILE_MAGIC; - if (cache_inode->i_mapping->a_ops->flushpage) - rc = cache_inode->i_mapping->a_ops->flushpage(page, offset); + cache_dentry = pre_smfs_dentry(NULL, I2CI(inode), filp->f_dentry); + if (!cache_dentry) + GOTO(err_exit, rc = -ENOMEM); + 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(rc); +err_exit: + if (sfi) + OBD_FREE(sfi, sizeof(struct smfs_file_info)); + if (cache_filp) + put_filp(cache_filp); RETURN(rc); } -static int smfs_releasepage(struct page *page, int wait) +static int smfs_cleanup_cache_file(struct file *filp) { - struct inode *inode = page->mapping->host; - struct inode *cache_inode; - int rc = 0; - - cache_inode = I2CI(inode); - - if (!cache_inode) - RETURN(-ENOENT); + struct smfs_file_info *sfi = NULL; + int rc = 0; + ENTRY; + + if (!filp) + RETURN(rc); + sfi = F2SMFI(filp); + + post_smfs_dentry(sfi->c_file->f_dentry); + + put_filp(sfi->c_file); - if (cache_inode->i_mapping->a_ops->releasepage) - rc = cache_inode->i_mapping->a_ops->releasepage(page, wait); + OBD_FREE(sfi, sizeof(struct smfs_file_info)); + + filp->private_data = NULL; RETURN(rc); } -static int smfs_direct_IO(int rw, struct inode *inode, struct kiobuf *iobuf, - unsigned long blocknr, int blocksize) +int smfs_open(struct inode *inode, struct file *filp) { - struct inode *cache_inode; - int rc = 0; - - cache_inode = I2CI(inode); - + struct inode *cache_inode = NULL; + int rc = 0; + ENTRY; + + cache_inode = I2CI(inode); if (!cache_inode) RETURN(-ENOENT); - if (cache_inode->i_mapping->a_ops->direct_IO) - rc = cache_inode->i_mapping->a_ops->direct_IO(rw, cache_inode, iobuf, - blocknr, blocksize); + if ((rc = smfs_init_cache_file(inode, filp))) + RETURN(rc); + + pre_smfs_inode(inode, cache_inode); + if (cache_inode->i_fop->open) + rc = cache_inode->i_fop->open(cache_inode, F2CF(filp)); + + post_smfs_inode(inode, cache_inode); + duplicate_file(filp, F2CF(filp)); RETURN(rc); } -struct address_space_operations smfs_file_aops = { - readpage: smfs_readpage, - writepage: smfs_writepage, - sync_page: smfs_sync_page, - prepare_write: smfs_prepare_write, - commit_write: smfs_commit_write, - bmap: smfs_bmap, - flushpage: smfs_flushpage, - releasepage: smfs_releasepage, - direct_IO: smfs_direct_IO, -}; - -/* 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) +int smfs_release(struct inode *inode, struct file *filp) { - 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; -} -/* update file structs*/ -void smfs_update_file(struct file *file, - struct file *cache_file) -{ - 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 = NULL; + struct file *cache_file = NULL; + struct smfs_file_info *sfi = NULL; + int rc = 0; + ENTRY; -static ssize_t smfs_write (struct file *filp, const 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); - + 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); - if (cache_inode->i_fop->write) - rc = cache_inode->i_fop->write(&open_file, buf, count, cache_ppos); - - *ppos = *cache_ppos; - duplicate_inode(cache_inode, inode); - smfs_update_file(filp, &open_file); - - RETURN(rc); + if (filp) { + sfi = F2SMFI(filp); + if (sfi->magic != SMFS_FILE_MAGIC) + LBUG(); + cache_file = sfi->c_file; + } + pre_smfs_inode(inode, cache_inode); + if (cache_inode->i_fop->release) + rc = cache_inode->i_fop->release(cache_inode, cache_file); + + post_smfs_inode(inode, cache_inode); + duplicate_file(filp, cache_file); + + smfs_cleanup_cache_file(filp); + RETURN(rc); } -int smfs_ioctl(struct inode * inode, struct file * filp, - unsigned int cmd, unsigned long arg) +int smfs_fsync(struct file *file, struct dentry *dentry, int datasync) { - 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); + struct smfs_file_info *sfi = NULL; + struct dentry *cache_dentry = NULL; + struct file *cache_file = NULL; + struct inode *cache_inode; + int rc = 0; + + cache_inode = I2CI(dentry->d_inode); if (!cache_inode) RETURN(-ENOENT); + + 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); + + if (cache_inode->i_fop->fsync) { + 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); - 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); - - duplicate_inode(cache_inode, inode); - smfs_update_file(filp, &open_file); RETURN(rc); } -static ssize_t smfs_read (struct file *filp, char *buf, - size_t count, loff_t *ppos) +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, +}; + +static void smfs_truncate(struct inode *inode) { - 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); + struct inode *cache_inode; - 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); - - - if (cache_inode->i_fop->read) - rc = cache_inode->i_fop->read(&open_file, buf, count, cache_ppos); - - *ppos = *cache_ppos; - duplicate_inode(cache_inode, inode); - smfs_update_file(filp, &open_file); - RETURN(rc); -} + cache_inode = I2CI(inode); -static loff_t smfs_llseek(struct file *file, - loff_t offset, - int origin) -{ - 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); + return; - smfs_prepare_cachefile(dentry->d_inode, file, cache_inode, - &open_file, &open_dentry); - - if (cache_inode->i_fop->llseek) - rc = cache_inode->i_fop->llseek(&open_file, offset, origin); + if (!cache_inode) + return; - duplicate_inode(cache_inode, dentry->d_inode); - smfs_update_file(file, &open_file); - - RETURN(rc); + pre_smfs_inode(inode, cache_inode); + if (cache_inode->i_op->truncate) + cache_inode->i_op->truncate(cache_inode); + + post_smfs_inode(inode, cache_inode); + + return; } -static int smfs_mmap(struct file * file, struct vm_area_struct * vma) +int smfs_setattr(struct dentry *dentry, struct iattr *attr) { - struct address_space *mapping = file->f_dentry->d_inode->i_mapping; - struct inode *inode = mapping->host; - struct inode *cache_inode = NULL; - struct file open_file; - struct dentry open_dentry; - int rc = 0; + struct inode *cache_inode; + struct dentry *cache_dentry; + void *handle = NULL; + int rc = 0; - cache_inode = I2CI(inode); + cache_inode = I2CI(dentry->d_inode); if (!cache_inode) RETURN(-ENOENT); - smfs_prepare_cachefile(inode, file, cache_inode, - &open_file, &open_dentry); - - if (cache_inode->i_fop->mmap) - rc = cache_inode->i_fop->mmap(&open_file, vma); - - duplicate_inode(cache_inode, inode); - smfs_update_file(file, &open_file); - - RETURN(rc); -} + cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry); + if (!cache_dentry) + RETURN(-ENOMEM); -static 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; + 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); + } - cache_inode = I2CI(inode); - if (!cache_inode) - RETURN(-ENOENT); + pre_smfs_inode(dentry->d_inode, cache_inode); - smfs_prepare_cachefile(inode, filp, cache_inode, - &open_file, &open_dentry); - - if (cache_inode->i_fop->open) - rc = cache_inode->i_fop->open(cache_inode, &open_file); - - duplicate_inode(cache_inode, inode); - smfs_update_file(filp, &open_file); - - RETURN(rc); + 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: + post_smfs_inode(dentry->d_inode, cache_inode); + post_smfs_dentry(cache_dentry); + smfs_trans_commit(dentry->d_inode, handle, 0); + RETURN(rc); } -static int smfs_release(struct inode * inode, struct file * filp) + +int smfs_setxattr(struct dentry *dentry, const char *name, const void *value, + size_t size, int flags) { - struct inode *cache_inode = NULL; - struct file open_file; - struct dentry open_dentry; - int rc = 0; + struct inode *cache_inode; + struct dentry *cache_dentry; + int rc = 0; - cache_inode = I2CI(inode); + 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->release) - rc = cache_inode->i_fop->release(cache_inode, &open_file); + cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry); + if (!cache_dentry) + RETURN(-ENOMEM); - duplicate_inode(cache_inode, inode); - smfs_update_file(filp, &open_file); - - RETURN(rc); -} -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; + pre_smfs_inode(dentry->d_inode, cache_inode); - cache_inode = I2CI(inode); - if (!cache_inode) - RETURN(-ENOENT); - - smfs_prepare_cachefile(inode, file, cache_inode, - &open_file, &open_dentry); - - if (cache_inode->i_fop->fsync) - rc = cache_inode->i_fop->fsync(&open_file, &open_dentry, datasync); - - duplicate_inode(cache_inode, inode); - smfs_update_file(file, &open_file); - - RETURN(rc); -} + if (cache_inode->i_op->setxattr) + rc = cache_inode->i_op->setxattr(cache_dentry, name, value, + size, flags); -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, -}; + post_smfs_inode(dentry->d_inode, cache_inode); + post_smfs_dentry(cache_dentry); -static void smfs_prepare_cache_dentry(struct dentry *dentry, 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); + RETURN(rc); } -static void smfs_truncate(struct inode * inode) +int smfs_getxattr(struct dentry *dentry, const char *name, void *buffer, + size_t size) { - struct inode *cache_inode; - - cache_inode = I2CI(inode); + struct inode *cache_inode; + struct dentry *cache_dentry; + int rc = 0; - if (!cache_inode) - return; - - if (cache_inode->i_op->truncate) - cache_inode->i_op->truncate(cache_inode); + cache_inode = I2CI(dentry->d_inode); + if (!cache_inode) + RETURN(-ENOENT); - duplicate_inode(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); - - if (cache_inode->i_op->setattr) - rc = cache_inode->i_op->setattr(&open_dentry, attr); - - duplicate_inode(cache_inode, dentry->d_inode); - - RETURN(rc); -} - -int smfs_setxattr(struct dentry *dentry, const char *name, - const void *value, size_t size, int flags) -{ - 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); - - if (cache_inode->i_op->setattr) - rc = cache_inode->i_op->setxattr(&open_dentry, name, value, size, flags); - - duplicate_inode(cache_inode, dentry->d_inode); - RETURN(rc); -} - -int smfs_getxattr(struct dentry *dentry, const char *name, - void *buffer, size_t size) -{ - struct inode *cache_inode; - struct dentry open_dentry; - int rc = 0; + 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); - if (!cache_inode) - RETURN(-ENOENT); + if (cache_inode->i_op->getattr) + rc = cache_inode->i_op->getxattr(cache_dentry, name, buffer, + size); - smfs_prepare_cache_dentry(&open_dentry, cache_inode); - - if (cache_inode->i_op->setattr) - rc = cache_inode->i_op->getxattr(&open_dentry, name, buffer, size); + post_smfs_inode(dentry->d_inode, cache_inode); + post_smfs_dentry(cache_dentry); - duplicate_inode(cache_inode, dentry->d_inode); - RETURN(rc); + 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; + struct dentry *cache_dentry; + int rc = 0; - cache_inode = I2CI(dentry->d_inode); + cache_inode = I2CI(dentry->d_inode); + if (!cache_inode) + RETURN(-ENOENT); - if (!cache_inode) - RETURN(-ENOENT); + cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry); + if (!cache_dentry) + RETURN(-ENOMEM); - smfs_prepare_cache_dentry(&open_dentry, cache_inode); - - if (cache_inode->i_op->listxattr) - rc = cache_inode->i_op->listxattr(&open_dentry, buffer, size); + pre_smfs_inode(dentry->d_inode, cache_inode); - duplicate_inode(cache_inode, dentry->d_inode); - RETURN(rc); -} + if (cache_inode->i_op->listxattr) + rc = cache_inode->i_op->listxattr(cache_dentry, buffer, size); + + post_smfs_inode(dentry->d_inode, cache_inode); + post_smfs_dentry(cache_dentry); + + RETURN(rc); +} int smfs_removexattr(struct dentry *dentry, const char *name) { - struct inode *cache_inode; - struct dentry open_dentry; - int rc = 0; + struct inode *cache_inode; + struct dentry *cache_dentry; + int rc = 0; + + cache_inode = I2CI(dentry->d_inode); + if (!cache_inode) + RETURN(-ENOENT); - 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_prepare_cache_dentry(&open_dentry, cache_inode); - - if (cache_inode->i_op->removexattr) - rc = cache_inode->i_op->removexattr(&open_dentry, name); + if (cache_inode->i_op->removexattr) + rc = cache_inode->i_op->removexattr(cache_dentry, name); - duplicate_inode(cache_inode, dentry->d_inode); - RETURN(rc); + post_smfs_inode(dentry->d_inode, cache_inode); + post_smfs_dentry(cache_dentry); + + RETURN(rc); } struct inode_operations smfs_file_iops = { - truncate: smfs_truncate, /* BKL held */ + 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 */ }; -