cregit-Linux how code gets into the kernel

Release 4.11 fs/orangefs/inode.c

Directory: fs/orangefs
/*
 * (C) 2001 Clemson University and The University of Chicago
 *
 * See COPYING in top-level directory.
 */

/*
 *  Linux VFS inode operations.
 */

#include <linux/bvec.h>
#include "protocol.h"
#include "orangefs-kernel.h"
#include "orangefs-bufmap.h"


static int read_one_page(struct page *page) { int ret; int max_block; ssize_t bytes_read = 0; struct inode *inode = page->mapping->host; const __u32 blocksize = PAGE_SIZE; /* inode->i_blksize */ const __u32 blockbits = PAGE_SHIFT; /* inode->i_blkbits */ struct iov_iter to; struct bio_vec bv = {.bv_page = page, .bv_len = PAGE_SIZE}; iov_iter_bvec(&to, ITER_BVEC | READ, &bv, 1, PAGE_SIZE); gossip_debug(GOSSIP_INODE_DEBUG, "orangefs_readpage called with page %p\n", page); max_block = ((inode->i_size / blocksize) + 1); if (page->index < max_block) { loff_t blockptr_offset = (((loff_t) page->index) << blockbits); bytes_read = orangefs_inode_read(inode, &to, &blockptr_offset, inode->i_size); } /* this will only zero remaining unread portions of the page data */ iov_iter_zero(~0U, &to); /* takes care of potential aliasing */ flush_dcache_page(page); if (bytes_read < 0) { ret = bytes_read; SetPageError(page); } else { SetPageUptodate(page); if (PageError(page)) ClearPageError(page); ret = 0; } /* unlock the page after the ->readpage() routine completes */ unlock_page(page); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Marshall16877.78%125.00%
Al Viro4420.37%125.00%
Yi Liu20.93%125.00%
Kirill A. Shutemov20.93%125.00%
Total216100.00%4100.00%


static int orangefs_readpage(struct file *file, struct page *page) { return read_one_page(page); }

Contributors

PersonTokensPropCommitsCommitProp
Mike Marshall2195.45%150.00%
Yi Liu14.55%150.00%
Total22100.00%2100.00%


static int orangefs_readpages(struct file *file, struct address_space *mapping, struct list_head *pages, unsigned nr_pages) { int page_idx; int ret; gossip_debug(GOSSIP_INODE_DEBUG, "orangefs_readpages called\n"); for (page_idx = 0; page_idx < nr_pages; page_idx++) { struct page *page; page = list_entry(pages->prev, struct page, lru); list_del(&page->lru); if (!add_to_page_cache(page, mapping, page->index, readahead_gfp_mask(mapping))) { ret = read_one_page(page); gossip_debug(GOSSIP_INODE_DEBUG, "failure adding page to cache, read_one_page returned: %d\n", ret); } else { put_page(page); } } BUG_ON(!list_empty(pages)); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Marshall12994.85%125.00%
Michal Hocko42.94%125.00%
Yi Liu21.47%125.00%
Kirill A. Shutemov10.74%125.00%
Total136100.00%4100.00%


static void orangefs_invalidatepage(struct page *page, unsigned int offset, unsigned int length) { gossip_debug(GOSSIP_INODE_DEBUG, "orangefs_invalidatepage called on page %p " "(offset is %u)\n", page, offset); ClearPageUptodate(page); ClearPageMappedToDisk(page); return; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Marshall4095.24%150.00%
Yi Liu24.76%150.00%
Total42100.00%2100.00%


static int orangefs_releasepage(struct page *page, gfp_t foo) { gossip_debug(GOSSIP_INODE_DEBUG, "orangefs_releasepage called on page %p\n", page); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Marshall2492.31%150.00%
Yi Liu27.69%150.00%
Total26100.00%2100.00%

/* * Having a direct_IO entry point in the address_space_operations * struct causes the kernel to allows us to use O_DIRECT on * open. Nothing will ever call this thing, but in the future we * will need to be able to use O_DIRECT on open in order to support * AIO. Modeled after NFS, they do this too. */
static ssize_t orangefs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) { gossip_debug(GOSSIP_INODE_DEBUG, "orangefs_direct_IO: %pD\n", iocb->ki_filp); return -EINVAL; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Marshall3096.77%150.00%
Al Viro13.23%150.00%
Total31100.00%2100.00%

/** ORANGEFS2 implementation of address space operations */ const struct address_space_operations orangefs_address_operations = { .readpage = orangefs_readpage, .readpages = orangefs_readpages, .invalidatepage = orangefs_invalidatepage, .releasepage = orangefs_releasepage, .direct_IO = orangefs_direct_IO, };
static int orangefs_setattr_size(struct inode *inode, struct iattr *iattr) { struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); struct orangefs_kernel_op_s *new_op; loff_t orig_size; int ret = -EINVAL; gossip_debug(GOSSIP_INODE_DEBUG, "%s: %pU: Handle is %pU | fs_id %d | size is %llu\n", __func__, get_khandle_from_ino(inode), &orangefs_inode->refn.khandle, orangefs_inode->refn.fs_id, iattr->ia_size); /* Ensure that we have a up to date size, so we know if it changed. */ ret = orangefs_inode_getattr(inode, 0, 1); if (ret == -ESTALE) ret = -EIO; if (ret) { gossip_err("%s: orangefs_inode_getattr failed, ret:%d:.\n", __func__, ret); return ret; } orig_size = i_size_read(inode); truncate_setsize(inode, iattr->ia_size); new_op = op_alloc(ORANGEFS_VFS_OP_TRUNCATE); if (!new_op) return -ENOMEM; new_op->upcall.req.truncate.refn = orangefs_inode->refn; new_op->upcall.req.truncate.size = (__s64) iattr->ia_size; ret = service_operation(new_op, __func__, get_interruptible_flag(inode)); /* * the truncate has no downcall members to retrieve, but * the status value tells us if it went through ok or not */ gossip_debug(GOSSIP_INODE_DEBUG, "orangefs: orangefs_truncate got return value of %d\n", ret); op_release(new_op); if (ret != 0) return ret; if (orig_size != i_size_read(inode)) iattr->ia_valid |= ATTR_CTIME | ATTR_MTIME; return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Marshall17574.79%133.33%
Martin Brandenburg4920.94%133.33%
Yi Liu104.27%133.33%
Total234100.00%3100.00%

/* * Change attributes of an object referenced by dentry. */
int orangefs_setattr(struct dentry *dentry, struct iattr *iattr) { int ret = -EINVAL; struct inode *inode = dentry->d_inode; gossip_debug(GOSSIP_INODE_DEBUG, "orangefs_setattr: called on %pd\n", dentry); ret = setattr_prepare(dentry, iattr); if (ret) goto out; if ((iattr->ia_valid & ATTR_SIZE) && iattr->ia_size != i_size_read(inode)) { ret = orangefs_setattr_size(inode, iattr); if (ret) goto out; } setattr_copy(inode, iattr); mark_inode_dirty(inode); ret = orangefs_inode_setattr(inode, iattr); gossip_debug(GOSSIP_INODE_DEBUG, "orangefs_setattr: inode_setattr returned %d\n", ret); if (!ret && (iattr->ia_valid & ATTR_MODE)) /* change mod on a file that has ACLs */ ret = posix_acl_chmod(inode, inode->i_mode); out: gossip_debug(GOSSIP_INODE_DEBUG, "orangefs_setattr: returning %d\n", ret); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Marshall15395.03%125.00%
Yi Liu53.11%125.00%
Jan Kara21.24%125.00%
Al Viro10.62%125.00%
Total161100.00%4100.00%

/* * Obtain attributes of an object given a dentry */
int orangefs_getattr(const struct path *path, struct kstat *stat, u32 request_mask, unsigned int flags) { int ret = -ENOENT; struct inode *inode = path->dentry->d_inode; struct orangefs_inode_s *orangefs_inode = NULL; gossip_debug(GOSSIP_INODE_DEBUG, "orangefs_getattr: called on %pd\n", path->dentry); ret = orangefs_inode_getattr(inode, 0, 0); if (ret == 0) { generic_fillattr(inode, stat); /* override block size reported to stat */ orangefs_inode = ORANGEFS_I(inode); stat->blksize = orangefs_inode->blksize; } return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Marshall7572.82%114.29%
David Howells1716.50%114.29%
Yi Liu65.83%114.29%
Martin Brandenburg43.88%342.86%
Al Viro10.97%114.29%
Total103100.00%7100.00%


int orangefs_permission(struct inode *inode, int mask) { int ret; if (mask & MAY_NOT_BLOCK) return -ECHILD; gossip_debug(GOSSIP_INODE_DEBUG, "%s: refreshing\n", __func__); /* Make sure the permission (and other common attrs) are up to date. */ ret = orangefs_inode_getattr(inode, 0, 0); if (ret < 0) return ret; return generic_permission(inode, mask); }

Contributors

PersonTokensPropCommitsCommitProp
Martin Brandenburg64100.00%2100.00%
Total64100.00%2100.00%

/* ORANGEDS2 implementation of VFS inode operations for files */ const struct inode_operations orangefs_file_inode_operations = { .get_acl = orangefs_get_acl, .set_acl = orangefs_set_acl, .setattr = orangefs_setattr, .getattr = orangefs_getattr, .listxattr = orangefs_listxattr, .permission = orangefs_permission, };
static int orangefs_init_iops(struct inode *inode) { inode->i_mapping->a_ops = &orangefs_address_operations; switch (inode->i_mode & S_IFMT) { case S_IFREG: inode->i_op = &orangefs_file_inode_operations; inode->i_fop = &orangefs_file_operations; inode->i_blkbits = PAGE_SHIFT; break; case S_IFLNK: inode->i_op = &orangefs_symlink_inode_operations; break; case S_IFDIR: inode->i_op = &orangefs_dir_inode_operations; inode->i_fop = &orangefs_dir_operations; break; default: gossip_debug(GOSSIP_INODE_DEBUG, "%s: unsupported mode\n", __func__); return -EINVAL; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Marshall9292.00%133.33%
Yi Liu77.00%133.33%
Kirill A. Shutemov11.00%133.33%
Total100100.00%3100.00%

/* * Given a ORANGEFS object identifier (fsid, handle), convert it into a ino_t type * that will be used as a hash-index from where the handle will * be searched for in the VFS hash table of inodes. */
static inline ino_t orangefs_handle_hash(struct orangefs_object_kref *ref) { if (!ref) return 0; return orangefs_khandle_to_ino(&(ref->khandle)); }

Contributors

PersonTokensPropCommitsCommitProp
Mike Marshall2890.32%150.00%
Yi Liu39.68%150.00%
Total31100.00%2100.00%

/* * Called to set up an inode from iget5_locked. */
static int orangefs_set_inode(struct inode *inode, void *data) { struct orangefs_object_kref *ref = (struct orangefs_object_kref *) data; ORANGEFS_I(inode)->refn.fs_id = ref->fs_id; ORANGEFS_I(inode)->refn.khandle = ref->khandle; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Marshall4885.71%133.33%
Martin Brandenburg47.14%133.33%
Yi Liu47.14%133.33%
Total56100.00%3100.00%

/* * Called to determine if handles match. */
static int orangefs_test_inode(struct inode *inode, void *data) { struct orangefs_object_kref *ref = (struct orangefs_object_kref *) data; struct orangefs_inode_s *orangefs_inode = NULL; orangefs_inode = ORANGEFS_I(inode); return (!ORANGEFS_khandle_cmp(&(orangefs_inode->refn.khandle), &(ref->khandle)) && orangefs_inode->refn.fs_id == ref->fs_id); }

Contributors

PersonTokensPropCommitsCommitProp
Mike Marshall6486.49%150.00%
Yi Liu1013.51%150.00%
Total74100.00%2100.00%

/* * Front-end to lookup the inode-cache maintained by the VFS using the ORANGEFS * file handle. * * @sb: the file system super block instance. * @ref: The ORANGEFS object for which we are trying to locate an inode structure. */
struct inode *orangefs_iget(struct super_block *sb, struct orangefs_object_kref *ref) { struct inode *inode = NULL; unsigned long hash; int error; hash = orangefs_handle_hash(ref); inode = iget5_locked(sb, hash, orangefs_test_inode, orangefs_set_inode, ref); if (!inode || !(inode->i_state & I_NEW)) return inode; error = orangefs_inode_getattr(inode, 1, 1); if (error) { iget_failed(inode); return ERR_PTR(error); } inode->i_ino = hash; /* needed for stat etc */ orangefs_init_iops(inode); unlock_new_inode(inode); gossip_debug(GOSSIP_INODE_DEBUG, "iget handle %pU, fsid %d hash %ld i_ino %lu\n", &ref->khandle, ref->fs_id, hash, inode->i_ino); return inode; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Marshall13092.86%120.00%
Yi Liu64.29%120.00%
Martin Brandenburg42.86%360.00%
Total140100.00%5100.00%

/* * Allocate an inode for a newly created file and insert it into the inode hash. */
struct inode *orangefs_new_inode(struct super_block *sb, struct inode *dir, int mode, dev_t dev, struct orangefs_object_kref *ref) { unsigned long hash = orangefs_handle_hash(ref); struct inode *inode; int error; gossip_debug(GOSSIP_INODE_DEBUG, "%s:(sb is %p | MAJOR(dev)=%u | MINOR(dev)=%u mode=%o)\n", __func__, sb, MAJOR(dev), MINOR(dev), mode); inode = new_inode(sb); if (!inode) return NULL; orangefs_set_inode(inode, ref); inode->i_ino = hash; /* needed for stat etc */ error = orangefs_inode_getattr(inode, 1, 1); if (error) goto out_iput; orangefs_init_iops(inode); inode->i_mode = mode; inode->i_uid = current_fsuid(); inode->i_gid = current_fsgid(); inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode); inode->i_size = PAGE_SIZE; inode->i_rdev = dev; error = insert_inode_locked4(inode, hash, orangefs_test_inode, ref); if (error < 0) goto out_iput; gossip_debug(GOSSIP_INODE_DEBUG, "Initializing ACL's for inode %pU\n", get_khandle_from_ino(inode)); orangefs_init_acl(inode, dir); return inode; out_iput: iput(inode); return ERR_PTR(error); }

Contributors

PersonTokensPropCommitsCommitProp
Mike Marshall21092.92%225.00%
Yi Liu73.10%112.50%
Martin Brandenburg41.77%337.50%
Deepa Dinamani41.77%112.50%
Kirill A. Shutemov10.44%112.50%
Total226100.00%8100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Mike Marshall145883.08%419.05%
Martin Brandenburg1327.52%733.33%
Yi Liu824.67%14.76%
Al Viro482.74%314.29%
David Howells170.97%14.76%
Kirill A. Shutemov50.28%14.76%
Michal Hocko40.23%14.76%
Deepa Dinamani40.23%14.76%
Christoph Hellwig30.17%14.76%
Jan Kara20.11%14.76%
Total1755100.00%21100.00%
Directory: fs/orangefs
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.