static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr, int non_block) { struct gfs2_skip_data data; unsigned long hash = (unsigned long)no_addr; data.no_addr = no_addr; data.skipped = 0; data.non_block = non_block; return iget5_locked(sb, hash, iget_test, iget_set, &data); }
static struct inode *get_cramfs_inode(struct super_block *sb, struct cramfs_inode * cramfs_inode) { struct inode *inode = iget5_locked(sb, CRAMINO(cramfs_inode), cramfs_iget5_test, cramfs_iget5_set, cramfs_inode); if (inode && (inode->i_state & I_NEW)) { unlock_new_inode(inode); } return inode; }
struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 blkno, unsigned flags, int sysfile_type) { struct inode *inode = NULL; struct super_block *sb = osb->sb; struct ocfs2_find_inode_args args; trace_ocfs2_iget_begin((unsigned long long)blkno, flags, sysfile_type); /* Ok. By now we've either got the offsets passed to us by the * caller, or we just pulled them off the bh. Lets do some * sanity checks to make sure they're OK. */ if (blkno == 0) { inode = ERR_PTR(-EINVAL); mlog_errno(PTR_ERR(inode)); goto bail; } args.fi_blkno = blkno; args.fi_flags = flags; args.fi_ino = ino_from_blkno(sb, blkno); args.fi_sysfile_type = sysfile_type; inode = iget5_locked(sb, args.fi_ino, ocfs2_find_actor, ocfs2_init_locked_inode, &args); /* inode was *not* in the inode cache. 2.6.x requires * us to do our own read_inode call and unlock it * afterwards. */ if (inode == NULL) { inode = ERR_PTR(-ENOMEM); mlog_errno(PTR_ERR(inode)); goto bail; } trace_ocfs2_iget5_locked(inode->i_state); if (inode->i_state & I_NEW) { ocfs2_read_locked_inode(inode, &args); unlock_new_inode(inode); } if (is_bad_inode(inode)) { iput(inode); inode = ERR_PTR(-ESTALE); goto bail; } bail: if (!IS_ERR(inode)) { trace_ocfs2_iget_end(inode, (unsigned long long)OCFS2_I(inode)->ip_blkno); } return inode; }
/* * Front-end to lookup the inode-cache maintained by the VFS using the PVFS2 * file handle instead of the inode number. * Problem with iget() is well-documented in that it can lead to possible * collissions especially for a file-system with 64 bit handles since inode->i_ino * is only a scalar field (32 bits). So the trick now is to use iget4_locked (OR) iget5_locked * if the kernel defines one and set inode number to be just a hash for the * handle * @sb: the file system super block instance * @ref: The PVFS2 object for which we are trying to locate an inode structure * @keep_locked : indicates whether the inode must be simply allocated and not filled * in with the results from a ->getattr. i.e. if keep_locked is set to 0, we do a getattr() and * unlock the inode and if set to 1, we do not issue a getattr() and keep it locked * * Boy, this function is so ugly with all these macros. I wish I could find a better * way to reduce the macro clutter. */ struct inode *pvfs2_iget_common(struct super_block *sb, PVFS_object_ref *ref, int keep_locked) { struct inode *inode = NULL; unsigned long hash; #if defined(HAVE_IGET5_LOCKED) || defined(HAVE_IGET4_LOCKED) hash = pvfs2_handle_hash(ref); #if defined(HAVE_IGET5_LOCKED) inode = iget5_locked(sb, hash, pvfs2_test_inode, pvfs2_set_inode, ref); #elif defined(HAVE_IGET4_LOCKED) inode = iget4_locked(sb, hash, pvfs2_test_inode, ref); #endif #else hash = (unsigned long) ref->handle; #ifdef HAVE_IGET_LOCKED inode = iget_locked(sb, hash); #else /* iget() internally issues a call to read_inode() */ inode = iget(sb, hash); #endif #endif if (!keep_locked) { #if defined(HAVE_IGET5_LOCKED) || defined(HAVE_IGET4_LOCKED) || defined(HAVE_IGET_LOCKED) if (inode && (inode->i_state & I_NEW)) { inode->i_ino = hash; /* needed for stat etc */ /* iget4_locked and iget_locked dont invoke the set_inode callback. * So we work around that by stashing the pvfs object reference * in the inode specific private part for 2.4 kernels and invoking * the setcallback explicitly for 2.6 kernels. */ #if defined(HAVE_IGET4_LOCKED) || defined(HAVE_IGET_LOCKED) if (PVFS2_I(inode)) { pvfs2_set_inode(inode, ref); } else { #ifdef PVFS2_LINUX_KERNEL_2_4 inode->u.generic_ip = (void *) ref; #endif } #endif /* issue a call to read the inode */ pvfs2_read_inode(inode); unlock_new_inode(inode); } #endif } gossip_debug(GOSSIP_INODE_DEBUG, "iget handle %llu, fsid %d hash %ld i_ino %lu\n", ref->handle, ref->fs_id, hash, inode->i_ino); return inode; }
struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 blkno, int flags) { struct inode *inode = NULL; struct super_block *sb = osb->sb; struct ocfs2_find_inode_args args; mlog_entry("(blkno = %llu)\n", (unsigned long long)blkno); /* Ok. By now we've either got the offsets passed to us by the * caller, or we just pulled them off the bh. Lets do some * sanity checks to make sure they're OK. */ if (blkno == 0) { inode = ERR_PTR(-EINVAL); mlog_errno(PTR_ERR(inode)); goto bail; } args.fi_blkno = blkno; args.fi_flags = flags; args.fi_ino = ino_from_blkno(sb, blkno); inode = iget5_locked(sb, args.fi_ino, ocfs2_find_actor, ocfs2_init_locked_inode, &args); /* inode was *not* in the inode cache. 2.6.x requires * us to do our own read_inode call and unlock it * afterwards. */ if (inode && inode->i_state & I_NEW) { mlog(0, "Inode was not in inode cache, reading it.\n"); ocfs2_read_locked_inode(inode, &args); unlock_new_inode(inode); } if (inode == NULL) { inode = ERR_PTR(-ENOMEM); mlog_errno(PTR_ERR(inode)); goto bail; } if (is_bad_inode(inode)) { iput(inode); inode = ERR_PTR(-ESTALE); goto bail; } bail: if (!IS_ERR(inode)) { mlog(0, "returning inode with number %llu\n", (unsigned long long)OCFS2_I(inode)->ip_blkno); mlog_exit_ptr(inode); } return inode; }
static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr) { struct inode *inode; repeat: inode = iget5_locked(sb, no_addr, iget_test, iget_set, &no_addr); if (!inode) return inode; if (is_bad_inode(inode)) { iput(inode); goto repeat; } return inode; }
struct inode *ovl_get_inode(struct super_block *sb, struct inode *realinode) { struct inode *inode; inode = iget5_locked(sb, (unsigned long) realinode, ovl_inode_test, ovl_inode_set, realinode); if (inode && inode->i_state & I_NEW) { ovl_fill_inode(inode, realinode->i_mode, realinode->i_rdev); set_nlink(inode, realinode->i_nlink); unlock_new_inode(inode); } return inode; }
struct inode *ceph_get_inode(struct super_block *sb, struct ceph_vino vino) { struct inode *inode; ino_t t = ceph_vino_to_ino(vino); inode = iget5_locked(sb, t, ceph_ino_compare, ceph_set_ino_cb, &vino); if (inode == NULL) return ERR_PTR(-ENOMEM); if (inode->i_state & I_NEW) { dout("get_inode created new inode %p %llx.%llx ino %llx\n", inode, ceph_vinop(inode), (u64)inode->i_ino); unlock_new_inode(inode); } dout("get_inode on %lu=%llx.%llx got %p\n", inode->i_ino, vino.ino, vino.snap, inode); return inode; }
/* convert a fid to an inode. */ struct inode *coda_fid_to_inode(struct CodaFid *fid, struct super_block *sb) { struct inode *inode; unsigned long hash = coda_f2i(fid); if ( !sb ) { printk("coda_fid_to_inode: no sb!\n"); return NULL; } inode = iget5_locked(sb, hash, coda_test_inode, coda_fail_inode, fid); if ( !inode ) return NULL; /* we should never see newly created inodes because we intentionally * fail in the initialization callback */ BUG_ON(inode->i_state & I_NEW); return inode; }
static struct inode *get_cramfs_inode(struct super_block *sb, struct cramfs_inode * cramfs_inode) { struct inode *inode = iget5_locked(sb, CRAMINO(cramfs_inode), cramfs_iget5_test, cramfs_iget5_set, cramfs_inode); static struct timespec zerotime; if (inode && (inode->i_state & I_NEW)) { inode->i_mode = cramfs_inode->mode; inode->i_uid = cramfs_inode->uid; inode->i_size = cramfs_inode->size; inode->i_blocks = (cramfs_inode->size - 1) / 512 + 1; inode->i_blksize = PAGE_CACHE_SIZE; inode->i_gid = cramfs_inode->gid; /* Struct copy intentional */ inode->i_mtime = inode->i_atime = inode->i_ctime = zerotime; inode->i_ino = CRAMINO(cramfs_inode); /* inode->i_nlink is left 1 - arguably wrong for directories, but it's the best we can do without reading the directory contents. 1 yields the right result in GNU find, even without -noleaf option. */ if (S_ISREG(inode->i_mode)) { inode->i_fop = &generic_ro_fops; inode->i_data.a_ops = &cramfs_aops; } else if (S_ISDIR(inode->i_mode)) { inode->i_op = &cramfs_dir_inode_operations; inode->i_fop = &cramfs_directory_operations; } else if (S_ISLNK(inode->i_mode)) { inode->i_op = &page_symlink_inode_operations; inode->i_data.a_ops = &cramfs_aops; } else { inode->i_size = 0; inode->i_blocks = 0; init_special_inode(inode, inode->i_mode, old_decode_dev(cramfs_inode->size)); } unlock_new_inode(inode); } return inode; }
static struct inode *__ecryptfs_get_inode(struct inode *lower_inode, struct super_block *sb) { struct inode *inode; if (lower_inode->i_sb != ecryptfs_superblock_to_lower(sb)) return ERR_PTR(-EXDEV); if (!igrab(lower_inode)) return ERR_PTR(-ESTALE); inode = iget5_locked(sb, (unsigned long)lower_inode, ecryptfs_inode_test, ecryptfs_inode_set, lower_inode); if (!inode) { iput(lower_inode); return ERR_PTR(-EACCES); } if (!(inode->i_state & I_NEW)) iput(lower_inode); return inode; }
static struct inode *_scfs_get_inode(struct inode *lower_inode, struct super_block *sb) { struct inode *inode; if (lower_inode->i_sb != SCFS_S(sb)->lower_sb) return ERR_PTR(-EXDEV); if (!igrab(lower_inode)) return ERR_PTR(-ESTALE); inode = iget5_locked(sb, (unsigned long)lower_inode->i_ino, scfs_inode_test, scfs_inode_set, lower_inode); if (!inode) { iput(lower_inode); return ERR_PTR(-EACCES); } if (!(inode->i_state & I_NEW)) iput(lower_inode); return inode; }
struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid, int generation, struct fuse_attr *attr) { struct inode *inode; struct fuse_inode *fi; struct fuse_conn *fc = get_fuse_conn_super(sb); int retried = 0; retry: inode = iget5_locked(sb, nodeid, fuse_inode_eq, fuse_inode_set, &nodeid); if (!inode) return NULL; if ((inode->i_state & I_NEW)) { #ifdef KERNEL_2_6_8_PLUS inode->i_flags |= S_NOATIME|S_NOCMTIME; #else inode->i_flags |= S_NOATIME; #endif inode->i_generation = generation; inode->i_data.backing_dev_info = &fc->bdi; fuse_init_inode(inode, attr); unlock_new_inode(inode); } else if ((inode->i_mode ^ attr->mode) & S_IFMT) { BUG_ON(retried); /* Inode has changed type, any I/O on the old should fail */ make_bad_inode(inode); iput(inode); retried = 1; goto retry; } fi = get_fuse_inode(inode); fi->nlookup ++; fuse_change_attributes(inode, attr); return inode; }
struct inode *ovl_get_inode(struct dentry *dentry, struct dentry *upperdentry) { struct dentry *lowerdentry = ovl_dentry_lower(dentry); struct inode *realinode = upperdentry ? d_inode(upperdentry) : NULL; struct inode *inode; if (!realinode) realinode = d_inode(lowerdentry); if (!S_ISDIR(realinode->i_mode) && (upperdentry || (lowerdentry && ovl_indexdir(dentry->d_sb)))) { struct inode *key = d_inode(lowerdentry ?: upperdentry); unsigned int nlink; inode = iget5_locked(dentry->d_sb, (unsigned long) key, ovl_inode_test, ovl_inode_set, key); if (!inode) goto out_nomem; if (!(inode->i_state & I_NEW)) { /* * Verify that the underlying files stored in the inode * match those in the dentry. */ if (!ovl_verify_inode(inode, lowerdentry, upperdentry)) { iput(inode); inode = ERR_PTR(-ESTALE); goto out; } dput(upperdentry); goto out; } nlink = ovl_get_nlink(lowerdentry, upperdentry, realinode->i_nlink); set_nlink(inode, nlink); } else {
struct inode * coda_iget(struct super_block * sb, struct CodaFid * fid, struct coda_vattr * attr) { struct inode *inode; struct coda_inode_info *cii; unsigned long hash = coda_f2i(fid); inode = iget5_locked(sb, hash, coda_test_inode, coda_set_inode, fid); if (!inode) return ERR_PTR(-ENOMEM); if (inode->i_state & I_NEW) { cii = ITOC(inode); /* we still need to set i_ino for things like stat(2) */ inode->i_ino = hash; cii->c_mapcount = 0; unlock_new_inode(inode); } /* always replace the attributes, type might have changed */ coda_fill_inode(inode, attr); return inode; }
struct inode *fuse_iget(struct super_block *sb, u64 nodeid, int generation, struct fuse_attr *attr, u64 attr_valid, u64 attr_version) { struct inode *inode; struct fuse_inode *fi; struct fuse_conn *fc = get_fuse_conn_super(sb); retry: inode = iget5_locked(sb, nodeid, fuse_inode_eq, fuse_inode_set, &nodeid); if (!inode) return NULL; if ((inode->i_state & I_NEW)) { inode->i_flags |= S_NOATIME; if (!fc->writeback_cache || !S_ISREG(inode->i_mode)) inode->i_flags |= S_NOCMTIME; inode->i_generation = generation; inode->i_data.backing_dev_info = &fc->bdi; fuse_init_inode(inode, attr); unlock_new_inode(inode); } else if ((inode->i_mode ^ attr->mode) & S_IFMT) { /* Inode has changed type, any I/O on the old should fail */ make_bad_inode(inode); iput(inode); goto retry; } fi = get_fuse_inode(inode); spin_lock(&fc->lock); fi->nlookup++; spin_unlock(&fc->lock); fuse_change_attributes(inode, attr, attr_valid, attr_version); return inode; }
static struct inode *sdcardfskk_iget(struct super_block *sb, struct inode *lower_inode) { struct sdcardfskk_inode_info *info; struct inode *inode; /* the new inode to return */ int err; inode = iget5_locked(sb, /* our superblock */ /* * hashval: we use inode number, but we can * also use "(unsigned long)lower_inode" * instead. */ lower_inode->i_ino, /* hashval */ sdcardfskk_inode_test, /* inode comparison function */ sdcardfskk_inode_set, /* inode init function */ lower_inode); /* data passed to test+set fxns */ if (!inode) { err = -EACCES; iput(lower_inode); return ERR_PTR(err); } /* if found a cached inode, then just return it */ if (!(inode->i_state & I_NEW)) return inode; /* initialize new inode */ info = SDCARDFSKK_I(inode); inode->i_ino = lower_inode->i_ino; if (!igrab(lower_inode)) { err = -ESTALE; return ERR_PTR(err); } sdcardfskk_set_lower_inode(inode, lower_inode); inode->i_version++; /* use different set of inode ops for symlinks & directories */ if (S_ISDIR(lower_inode->i_mode)) inode->i_op = &sdcardfskk_dir_iops; else if (S_ISLNK(lower_inode->i_mode)) inode->i_op = &sdcardfskk_symlink_iops; else inode->i_op = &sdcardfskk_main_iops; /* use different set of file ops for directories */ if (S_ISDIR(lower_inode->i_mode)) inode->i_fop = &sdcardfskk_dir_fops; else inode->i_fop = &sdcardfskk_main_fops; inode->i_mapping->a_ops = &sdcardfskk_aops; inode->i_atime.tv_sec = 0; inode->i_atime.tv_nsec = 0; inode->i_mtime.tv_sec = 0; inode->i_mtime.tv_nsec = 0; inode->i_ctime.tv_sec = 0; inode->i_ctime.tv_nsec = 0; /* properly initialize special inodes */ if (S_ISBLK(lower_inode->i_mode) || S_ISCHR(lower_inode->i_mode) || S_ISFIFO(lower_inode->i_mode) || S_ISSOCK(lower_inode->i_mode)) init_special_inode(inode, lower_inode->i_mode, lower_inode->i_rdev); /* all well, copy inode attributes, don't need to hold i_mutex here */ sdcardfskk_copy_inode_attr(inode, lower_inode); fsstack_copy_inode_size(inode, lower_inode); fix_derived_permission(inode); unlock_new_inode(inode); return inode; }
/* * inode retrieval */ inline int afs_iget(struct super_block *sb, struct afs_fid *fid, struct inode **_inode) { struct afs_iget_data data = { .fid = *fid }; struct afs_super_info *as; struct afs_vnode *vnode; struct inode *inode; int ret; _enter(",{%u,%u,%u},,", fid->vid, fid->vnode, fid->unique); as = sb->s_fs_info; data.volume = as->volume; inode = iget5_locked(sb, fid->vnode, afs_iget5_test, afs_iget5_set, &data); if (!inode) { _leave(" = -ENOMEM"); return -ENOMEM; } vnode = AFS_FS_I(inode); /* deal with an existing inode */ if (!(inode->i_state & I_NEW)) { ret = afs_vnode_fetch_status(vnode); if (ret==0) *_inode = inode; else iput(inode); _leave(" = %d", ret); return ret; } #ifdef AFS_CACHING_SUPPORT /* set up caching before reading the status, as fetch-status reads the * first page of symlinks to see if they're really mntpts */ cachefs_acquire_cookie(vnode->volume->cache, NULL, vnode, &vnode->cache); #endif /* okay... it's a new inode */ inode->i_flags |= S_NOATIME; vnode->flags |= AFS_VNODE_CHANGED; ret = afs_inode_fetch_status(inode); if (ret<0) goto bad_inode; /* success */ unlock_new_inode(inode); *_inode = inode; _leave(" = 0 [CB { v=%u x=%lu t=%u }]", vnode->cb_version, vnode->cb_timeout.timo_jif, vnode->cb_type); return 0; /* failure */ bad_inode: make_bad_inode(inode); unlock_new_inode(inode); iput(inode); _leave(" = %d [bad]", ret); return ret; } /* end afs_iget() */
/* * This is our front-end to iget that looks up inodes by file handle * instead of inode number. */ struct inode * nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) { struct nfs_find_desc desc = { .fh = fh, .fattr = fattr }; struct inode *inode = ERR_PTR(-ENOENT); unsigned long hash; nfs_attr_check_mountpoint(sb, fattr); if (((fattr->valid & NFS_ATTR_FATTR_FILEID) == 0) && !nfs_attr_use_mounted_on_fileid(fattr)) goto out_no_inode; if ((fattr->valid & NFS_ATTR_FATTR_TYPE) == 0) goto out_no_inode; hash = nfs_fattr_to_ino_t(fattr); inode = iget5_locked(sb, hash, nfs_find_actor, nfs_init_locked, &desc); if (inode == NULL) { inode = ERR_PTR(-ENOMEM); goto out_no_inode; } if (inode->i_state & I_NEW) { struct nfs_inode *nfsi = NFS_I(inode); unsigned long now = jiffies; /* We set i_ino for the few things that still rely on it, * such as stat(2) */ inode->i_ino = hash; /* We can't support update_atime(), since the server will reset it */ inode->i_flags |= S_NOATIME|S_NOCMTIME; inode->i_mode = fattr->mode; if ((fattr->valid & NFS_ATTR_FATTR_MODE) == 0 && nfs_server_capable(inode, NFS_CAP_MODE)) nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL; /* Why so? Because we want revalidate for devices/FIFOs, and * that's precisely what we have in nfs_file_inode_operations. */ inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->file_inode_ops; if (S_ISREG(inode->i_mode)) { inode->i_fop = NFS_SB(sb)->nfs_client->rpc_ops->file_ops; inode->i_data.a_ops = &nfs_file_aops; inode->i_data.backing_dev_info = &NFS_SB(sb)->backing_dev_info; } else if (S_ISDIR(inode->i_mode)) { inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->dir_inode_ops; inode->i_fop = &nfs_dir_operations; inode->i_data.a_ops = &nfs_dir_aops; if (nfs_server_capable(inode, NFS_CAP_READDIRPLUS)) set_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(inode)->flags); /* Deal with crossing mountpoints */ if (fattr->valid & NFS_ATTR_FATTR_MOUNTPOINT || fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) { if (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) inode->i_op = &nfs_referral_inode_operations; else inode->i_op = &nfs_mountpoint_inode_operations; inode->i_fop = NULL; inode->i_flags |= S_AUTOMOUNT; } } else if (S_ISLNK(inode->i_mode)) inode->i_op = &nfs_symlink_inode_operations; else init_special_inode(inode, inode->i_mode, fattr->rdev); memset(&inode->i_atime, 0, sizeof(inode->i_atime)); memset(&inode->i_mtime, 0, sizeof(inode->i_mtime)); memset(&inode->i_ctime, 0, sizeof(inode->i_ctime)); nfsi->change_attr = 0; inode->i_size = 0; inode->i_nlink = 0; inode->i_uid = -2; inode->i_gid = -2; inode->i_blocks = 0; memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf)); nfsi->read_cache_jiffies = fattr->time_start; nfsi->attr_gencount = fattr->gencount; if (fattr->valid & NFS_ATTR_FATTR_ATIME) inode->i_atime = fattr->atime; else if (nfs_server_capable(inode, NFS_CAP_ATIME)) nfsi->cache_validity |= NFS_INO_INVALID_ATTR; if (fattr->valid & NFS_ATTR_FATTR_MTIME) inode->i_mtime = fattr->mtime; else if (nfs_server_capable(inode, NFS_CAP_MTIME)) nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_DATA; if (fattr->valid & NFS_ATTR_FATTR_CTIME) inode->i_ctime = fattr->ctime; else if (nfs_server_capable(inode, NFS_CAP_CTIME)) nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL; if (fattr->valid & NFS_ATTR_FATTR_CHANGE) nfsi->change_attr = fattr->change_attr; else if (nfs_server_capable(inode, NFS_CAP_CHANGE_ATTR)) nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_DATA; if (fattr->valid & NFS_ATTR_FATTR_SIZE) inode->i_size = nfs_size_to_loff_t(fattr->size); else nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_DATA | NFS_INO_REVAL_PAGECACHE; if (fattr->valid & NFS_ATTR_FATTR_NLINK) inode->i_nlink = fattr->nlink; else if (nfs_server_capable(inode, NFS_CAP_NLINK)) nfsi->cache_validity |= NFS_INO_INVALID_ATTR; if (fattr->valid & NFS_ATTR_FATTR_OWNER) #ifdef CONFIG_ROOT_NFS_UID if ((fattr->uid) && (fattr->uid == (uid_t) (NFS_CLIENT(inode)->cl_rootuid))) inode->i_uid = 0; else inode->i_uid = fattr->uid; #else inode->i_uid = fattr->uid; #endif else if (nfs_server_capable(inode, NFS_CAP_OWNER)) nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL; if (fattr->valid & NFS_ATTR_FATTR_GROUP) #ifdef CONFIG_ROOT_NFS_UID if ((fattr->gid) && (fattr->gid == (gid_t) (NFS_CLIENT(inode)->cl_rootgid))) inode->i_gid = 0; else inode->i_gid = fattr->gid; #else inode->i_gid = fattr->gid; #endif else if (nfs_server_capable(inode, NFS_CAP_OWNER_GROUP))
static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr) { unsigned long hash = (unsigned long)no_addr; return iget5_locked(sb, hash, iget_test, iget_set, &no_addr); }
struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 blkno, unsigned flags, int sysfile_type) { int rc = -ESTALE; struct inode *inode = NULL; struct super_block *sb = osb->sb; struct ocfs2_find_inode_args args; journal_t *journal = OCFS2_SB(sb)->journal->j_journal; trace_ocfs2_iget_begin((unsigned long long)blkno, flags, sysfile_type); /* Ok. By now we've either got the offsets passed to us by the * caller, or we just pulled them off the bh. Lets do some * sanity checks to make sure they're OK. */ if (blkno == 0) { inode = ERR_PTR(-EINVAL); mlog_errno(PTR_ERR(inode)); goto bail; } args.fi_blkno = blkno; args.fi_flags = flags; args.fi_ino = ino_from_blkno(sb, blkno); args.fi_sysfile_type = sysfile_type; inode = iget5_locked(sb, args.fi_ino, ocfs2_find_actor, ocfs2_init_locked_inode, &args); /* inode was *not* in the inode cache. 2.6.x requires * us to do our own read_inode call and unlock it * afterwards. */ if (inode == NULL) { inode = ERR_PTR(-ENOMEM); mlog_errno(PTR_ERR(inode)); goto bail; } trace_ocfs2_iget5_locked(inode->i_state); if (inode->i_state & I_NEW) { rc = ocfs2_read_locked_inode(inode, &args); unlock_new_inode(inode); } if (is_bad_inode(inode)) { iput(inode); inode = ERR_PTR(rc); goto bail; } /* * Set transaction id's of transactions that have to be committed * to finish f[data]sync. We set them to currently running transaction * as we cannot be sure that the inode or some of its metadata isn't * part of the transaction - the inode could have been reclaimed and * now it is reread from disk. */ if (journal) { transaction_t *transaction; tid_t tid; struct ocfs2_inode_info *oi = OCFS2_I(inode); read_lock(&journal->j_state_lock); if (journal->j_running_transaction) transaction = journal->j_running_transaction; else transaction = journal->j_committing_transaction; if (transaction) tid = transaction->t_tid; else tid = journal->j_commit_sequence; read_unlock(&journal->j_state_lock); oi->i_sync_tid = tid; oi->i_datasync_tid = tid; } bail: if (!IS_ERR(inode)) { trace_ocfs2_iget_end(inode, (unsigned long long)OCFS2_I(inode)->ip_blkno); } return inode; }
/* * Create an inode for a dynamic root directory or an autocell dynamic * automount dir. */ struct inode *afs_iget_pseudo_dir(struct super_block *sb, bool root) { struct afs_iget_data data; struct afs_super_info *as; struct afs_vnode *vnode; struct inode *inode; static atomic_t afs_autocell_ino; _enter(""); as = sb->s_fs_info; if (as->volume) { data.volume = as->volume; data.fid.vid = as->volume->vid; } if (root) { data.fid.vnode = 1; data.fid.unique = 1; } else { data.fid.vnode = atomic_inc_return(&afs_autocell_ino); data.fid.unique = 0; } inode = iget5_locked(sb, data.fid.vnode, afs_iget5_pseudo_dir_test, afs_iget5_set, &data); if (!inode) { _leave(" = -ENOMEM"); return ERR_PTR(-ENOMEM); } _debug("GOT INODE %p { ino=%lu, vl=%x, vn=%x, u=%x }", inode, inode->i_ino, data.fid.vid, data.fid.vnode, data.fid.unique); vnode = AFS_FS_I(inode); /* there shouldn't be an existing inode */ BUG_ON(!(inode->i_state & I_NEW)); inode->i_size = 0; inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO; if (root) { inode->i_op = &afs_dynroot_inode_operations; inode->i_fop = &afs_dynroot_file_operations; } else { inode->i_op = &afs_autocell_inode_operations; } set_nlink(inode, 2); inode->i_uid = GLOBAL_ROOT_UID; inode->i_gid = GLOBAL_ROOT_GID; inode->i_ctime.tv_sec = get_seconds(); inode->i_ctime.tv_nsec = 0; inode->i_atime = inode->i_mtime = inode->i_ctime; inode->i_blocks = 0; inode_set_iversion_raw(inode, 0); inode->i_generation = 0; set_bit(AFS_VNODE_PSEUDODIR, &vnode->flags); if (!root) { set_bit(AFS_VNODE_MOUNTPOINT, &vnode->flags); inode->i_flags |= S_AUTOMOUNT; } inode->i_flags |= S_NOATIME; unlock_new_inode(inode); _leave(" = %p", inode); return inode; }
struct inode *nilfs_ilookup(struct super_block *sb, struct nilfs_root *root, unsigned long ino) { struct nilfs_iget_args args = { .ino = ino, .root = root, .cno = 0, .for_gc = 0 }; return ilookup5(sb, ino, nilfs_iget_test, &args); } struct inode *nilfs_iget_locked(struct super_block *sb, struct nilfs_root *root, unsigned long ino) { struct nilfs_iget_args args = { .ino = ino, .root = root, .cno = 0, .for_gc = 0 }; return iget5_locked(sb, ino, nilfs_iget_test, nilfs_iget_set, &args); } struct inode *nilfs_iget(struct super_block *sb, struct nilfs_root *root, unsigned long ino) { struct inode *inode; int err; inode = nilfs_iget_locked(sb, root, ino); if (unlikely(!inode)) return ERR_PTR(-ENOMEM); if (!(inode->i_state & I_NEW)) return inode; err = __nilfs_read_inode(sb, root, ino, inode); if (unlikely(err)) { iget_failed(inode); return ERR_PTR(err); } unlock_new_inode(inode); return inode; } struct inode *nilfs_iget_for_gc(struct super_block *sb, unsigned long ino, __u64 cno) { struct nilfs_iget_args args = { .ino = ino, .root = NULL, .cno = cno, .for_gc = 1 }; struct inode *inode; int err; inode = iget5_locked(sb, ino, nilfs_iget_test, nilfs_iget_set, &args); if (unlikely(!inode)) return ERR_PTR(-ENOMEM); if (!(inode->i_state & I_NEW)) return inode; err = nilfs_init_gcinode(inode); if (unlikely(err)) { iget_failed(inode); return ERR_PTR(err); } unlock_new_inode(inode); return inode; } void nilfs_write_inode_common(struct inode *inode, struct nilfs_inode *raw_inode, int has_bmap) { struct nilfs_inode_info *ii = NILFS_I(inode); raw_inode->i_mode = cpu_to_le16(inode->i_mode); raw_inode->i_uid = cpu_to_le32(inode->i_uid); raw_inode->i_gid = cpu_to_le32(inode->i_gid); raw_inode->i_links_count = cpu_to_le16(inode->i_nlink); raw_inode->i_size = cpu_to_le64(inode->i_size); raw_inode->i_ctime = cpu_to_le64(inode->i_ctime.tv_sec); raw_inode->i_mtime = cpu_to_le64(inode->i_mtime.tv_sec); raw_inode->i_ctime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec); raw_inode->i_mtime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec); raw_inode->i_blocks = cpu_to_le64(inode->i_blocks); raw_inode->i_flags = cpu_to_le32(ii->i_flags); raw_inode->i_generation = cpu_to_le32(inode->i_generation); if (NILFS_ROOT_METADATA_FILE(inode->i_ino)) { struct the_nilfs *nilfs = inode->i_sb->s_fs_info; /* zero-fill unused portion in the case of super root block */ raw_inode->i_xattr = 0; raw_inode->i_pad = 0; memset((void *)raw_inode + sizeof(*raw_inode), 0, nilfs->ns_inode_size - sizeof(*raw_inode)); } if (has_bmap) nilfs_bmap_write(ii->i_bmap, raw_inode); else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) raw_inode->i_device_code = cpu_to_le64(huge_encode_dev(inode->i_rdev)); /* When extending inode, nilfs->ns_inode_size should be checked for substitutions of appended fields */ } void nilfs_update_inode(struct inode *inode, struct buffer_head *ibh) { ino_t ino = inode->i_ino; struct nilfs_inode_info *ii = NILFS_I(inode); struct inode *ifile = ii->i_root->ifile; struct nilfs_inode *raw_inode; raw_inode = nilfs_ifile_map_inode(ifile, ino, ibh); if (test_and_clear_bit(NILFS_I_NEW, &ii->i_state)) memset(raw_inode, 0, NILFS_MDT(ifile)->mi_entry_size); set_bit(NILFS_I_INODE_DIRTY, &ii->i_state); nilfs_write_inode_common(inode, raw_inode, 0); /* XXX: call with has_bmap = 0 is a workaround to avoid deadlock of bmap. This delays update of i_bmap to just before writing */ nilfs_ifile_unmap_inode(ifile, ino, ibh); } #define NILFS_MAX_TRUNCATE_BLOCKS 16384 /* 64MB for 4KB block */ static void nilfs_truncate_bmap(struct nilfs_inode_info *ii, unsigned long from) { unsigned long b; int ret; if (!test_bit(NILFS_I_BMAP, &ii->i_state)) return; repeat: ret = nilfs_bmap_last_key(ii->i_bmap, &b); if (ret == -ENOENT) return; else if (ret < 0) goto failed; if (b < from) return; b -= min_t(unsigned long, NILFS_MAX_TRUNCATE_BLOCKS, b - from); ret = nilfs_bmap_truncate(ii->i_bmap, b); nilfs_relax_pressure_in_lock(ii->vfs_inode.i_sb); if (!ret || (ret == -ENOMEM && nilfs_bmap_truncate(ii->i_bmap, b) == 0)) goto repeat; failed: nilfs_warning(ii->vfs_inode.i_sb, __func__, "failed to truncate bmap (ino=%lu, err=%d)", ii->vfs_inode.i_ino, ret); } void nilfs_truncate(struct inode *inode) { unsigned long blkoff; unsigned int blocksize; struct nilfs_transaction_info ti; struct super_block *sb = inode->i_sb; struct nilfs_inode_info *ii = NILFS_I(inode); if (!test_bit(NILFS_I_BMAP, &ii->i_state)) return; if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) return; blocksize = sb->s_blocksize; blkoff = (inode->i_size + blocksize - 1) >> sb->s_blocksize_bits; nilfs_transaction_begin(sb, &ti, 0); /* never fails */ block_truncate_page(inode->i_mapping, inode->i_size, nilfs_get_block); nilfs_truncate_bmap(ii, blkoff); inode->i_mtime = inode->i_ctime = CURRENT_TIME; if (IS_SYNC(inode)) nilfs_set_transaction_flag(NILFS_TI_SYNC); nilfs_mark_inode_dirty(inode); nilfs_set_file_dirty(inode, 0); nilfs_transaction_commit(sb); /* May construct a logical segment and may fail in sync mode. But truncate has no return value. */ }
/* * inode retrieval */ struct inode *afs_iget(struct super_block *sb, struct key *key, struct afs_fid *fid, struct afs_file_status *status, struct afs_callback *cb) { struct afs_iget_data data = { .fid = *fid }; struct afs_super_info *as; struct afs_vnode *vnode; struct inode *inode; int ret; _enter(",{%x:%u.%u},,", fid->vid, fid->vnode, fid->unique); as = sb->s_fs_info; data.volume = as->volume; inode = iget5_locked(sb, fid->vnode, afs_iget5_test, afs_iget5_set, &data); if (!inode) { _leave(" = -ENOMEM"); return ERR_PTR(-ENOMEM); } _debug("GOT INODE %p { vl=%x vn=%x, u=%x }", inode, fid->vid, fid->vnode, fid->unique); vnode = AFS_FS_I(inode); /* deal with an existing inode */ if (!(inode->i_state & I_NEW)) { _leave(" = %p", inode); return inode; } if (!status) { /* it's a remotely extant inode */ set_bit(AFS_VNODE_CB_BROKEN, &vnode->flags); ret = afs_vnode_fetch_status(vnode, NULL, key); if (ret < 0) goto bad_inode; } else { /* it's an inode we just created */ memcpy(&vnode->status, status, sizeof(vnode->status)); if (!cb) { /* it's a symlink we just created (the fileserver * didn't give us a callback) */ vnode->cb_version = 0; vnode->cb_expiry = 0; vnode->cb_type = 0; vnode->cb_expires = get_seconds(); } else { vnode->cb_version = cb->version; vnode->cb_expiry = cb->expiry; vnode->cb_type = cb->type; vnode->cb_expires = vnode->cb_expiry + get_seconds(); } } /* set up caching before mapping the status, as map-status reads the * first page of symlinks to see if they're really mountpoints */ inode->i_size = vnode->status.size; #ifdef CONFIG_AFS_FSCACHE vnode->cache = fscache_acquire_cookie(vnode->volume->cache, &afs_vnode_cache_index_def, vnode, true); #endif ret = afs_inode_map_status(vnode, key); if (ret < 0) goto bad_inode; /* success */ clear_bit(AFS_VNODE_UNSET, &vnode->flags); inode->i_flags |= S_NOATIME; unlock_new_inode(inode); _leave(" = %p [CB { v=%u t=%u }]", inode, vnode->cb_version, vnode->cb_type); return inode; /* failure */ bad_inode: #ifdef CONFIG_AFS_FSCACHE fscache_relinquish_cookie(vnode->cache, 0); vnode->cache = NULL; #endif iget_failed(inode); _leave(" = %d [bad]", ret); return ERR_PTR(ret); }