/* utility to rename a file */ int lustre_rename(struct dentry *dir, struct vfsmount *mnt, char *oldname, char *newname) { struct dentry *dchild_old, *dchild_new; int err = 0; ASSERT_KERNEL_CTXT("kernel doing rename outside kernel context\n"); CDEBUG(D_INODE, "renaming file %.*s to %.*s\n", (int)strlen(oldname), oldname, (int)strlen(newname), newname); dchild_old = ll_lookup_one_len(oldname, dir, strlen(oldname)); if (IS_ERR(dchild_old)) return PTR_ERR(dchild_old); if (!dchild_old->d_inode) GOTO(put_old, err = -ENOENT); dchild_new = ll_lookup_one_len(newname, dir, strlen(newname)); if (IS_ERR(dchild_new)) GOTO(put_old, err = PTR_ERR(dchild_new)); err = ll_vfs_rename(dir->d_inode, dchild_old, mnt, dir->d_inode, dchild_new, mnt); dput(dchild_new); put_old: dput(dchild_old); return err; }
/* utility to truncate a file */ int simple_truncate(struct dentry *dir, struct vfsmount *mnt, char *name, loff_t length) { struct dentry *dchild; struct iattr newattrs; int err = 0; ENTRY; CDEBUG(D_INODE, "truncating file %.*s to %lld\n", (int)strlen(name), name, (long long)length); dchild = ll_lookup_one_len(name, dir, strlen(name)); if (IS_ERR(dchild)) GOTO(out, err = PTR_ERR(dchild)); if (dchild->d_inode) { int old_mode = dchild->d_inode->i_mode; if (S_ISDIR(old_mode)) { CERROR("found %s (%lu/%u) is mode %o\n", name, dchild->d_inode->i_ino, dchild->d_inode->i_generation, old_mode); GOTO(out_dput, err = -EISDIR); } newattrs.ia_size = length; newattrs.ia_valid = ATTR_SIZE; err = l_notify_change(mnt, dchild, &newattrs); } EXIT; out_dput: dput(dchild); out: return err; }
int osd_compat_spec_lookup(struct osd_thread_info *info, struct osd_device *osd, const struct lu_fid *fid, struct osd_inode_id *id) { struct dentry *dentry; char *name; int rc = -ERESTART; ENTRY; name = oid2name(fid_oid(fid)); if (name == NULL || strlen(name) == 0) return -ERESTART; dentry = ll_lookup_one_len(name, osd_sb(osd)->s_root, strlen(name)); if (!IS_ERR(dentry)) { if (dentry->d_inode) { if (is_bad_inode(dentry->d_inode)) { rc = -EIO; } else { id->oii_ino = dentry->d_inode->i_ino; id->oii_gen = dentry->d_inode->i_generation; rc = 0; } } dput(dentry); } RETURN(rc); }
static struct inode *osd_oi_index_open(struct osd_thread_info *info, struct osd_device *osd, const char *name, struct dt_index_features *f, bool create) { struct dentry *dentry; struct inode *inode; int rc; dentry = ll_lookup_one_len(name, osd_sb(osd)->s_root, strlen(name)); if (IS_ERR(dentry)) return (void *) dentry; if (dentry->d_inode) { LASSERT(!is_bad_inode(dentry->d_inode)); inode = dentry->d_inode; atomic_inc(&inode->i_count); dput(dentry); return inode; } /* create */ dput(dentry); shrink_dcache_parent(osd_sb(osd)->s_root); if (!create) return ERR_PTR(-ENOENT); rc = osd_oi_index_create_one(info, osd, name, f); if (rc) return ERR_PTR(rc); dentry = ll_lookup_one_len(name, osd_sb(osd)->s_root, strlen(name)); if (IS_ERR(dentry)) return (void *) dentry; if (dentry->d_inode) { LASSERT(!is_bad_inode(dentry->d_inode)); inode = dentry->d_inode; atomic_inc(&inode->i_count); dput(dentry); return inode; } return ERR_PTR(-ENOENT); }
/* this function ONLY returns valid dget'd dentries with an initialized inode or errors */ struct dentry *mds_fid2dentry(struct mds_obd *mds, struct ll_fid *fid, struct vfsmount **mnt) { char fid_name[32]; unsigned long ino = fid->id; __u32 generation = fid->generation; struct inode *inode; struct dentry *result; if (ino == 0) RETURN(ERR_PTR(-ESTALE)); snprintf(fid_name, sizeof(fid_name), "0x%lx", ino); /* under ext3 this is neither supposed to return bad inodes nor NULL inodes. */ result = ll_lookup_one_len(fid_name, mds->mds_fid_de, strlen(fid_name)); if (IS_ERR(result)) RETURN(result); inode = result->d_inode; if (!inode) RETURN(ERR_PTR(-ENOENT)); if (inode->i_generation == 0 || inode->i_nlink == 0) { LCONSOLE_WARN("Found inode with zero generation or link -- this" " may indicate disk corruption (inode: %lu/%u, " "link %lu, count %d)\n", inode->i_ino, inode->i_generation,(unsigned long)inode->i_nlink, atomic_read(&inode->i_count)); dput(result); RETURN(ERR_PTR(-ENOENT)); } if (generation && inode->i_generation != generation) { /* we didn't find the right inode.. */ CDEBUG(D_INODE, "found wrong generation: inode %lu, link: %lu, " "count: %d, generation %u/%u\n", inode->i_ino, (unsigned long)inode->i_nlink, atomic_read(&inode->i_count), inode->i_generation, generation); dput(result); RETURN(ERR_PTR(-ENOENT)); } if (mnt) { *mnt = mds->mds_obt.obt_vfsmnt; mntget(*mnt); } RETURN(result); }
static int osd_remove_oi_one(struct dentry *parent, const char *name, int namelen) { struct dentry *child; int rc; child = ll_lookup_one_len(name, parent, namelen); if (IS_ERR(child)) { rc = PTR_ERR(child); } else { rc = ll_vfs_unlink(parent->d_inode, child); dput(child); } return rc == -ENOENT ? 0 : rc; }
/* utility to make a directory */ struct dentry *simple_mkdir(struct dentry *dir, struct vfsmount *mnt, const char *name, int mode, int fix) { struct dentry *dchild; int err = 0; ENTRY; // ASSERT_KERNEL_CTXT("kernel doing mkdir outside kernel context\n"); CDEBUG(D_INODE, "creating directory %.*s\n", (int)strlen(name), name); dchild = ll_lookup_one_len(name, dir, strlen(name)); if (IS_ERR(dchild)) GOTO(out_up, dchild); if (dchild->d_inode) { int old_mode = dchild->d_inode->i_mode; if (!S_ISDIR(old_mode)) { CERROR("found %s (%lu/%u) is mode %o\n", name, dchild->d_inode->i_ino, dchild->d_inode->i_generation, old_mode); GOTO(out_err, err = -ENOTDIR); } /* Fixup directory permissions if necessary */ if (fix && (old_mode & S_IALLUGO) != (mode & S_IALLUGO)) { CDEBUG(D_CONFIG, "fixing permissions on %s from %o to %o\n", name, old_mode, mode); dchild->d_inode->i_mode = (mode & S_IALLUGO) | (old_mode & ~S_IALLUGO); mark_inode_dirty(dchild->d_inode); } GOTO(out_up, dchild); } err = ll_vfs_mkdir(dir->d_inode, dchild, mnt, mode); if (err) GOTO(out_err, err); RETURN(dchild); out_err: dput(dchild); dchild = ERR_PTR(err); out_up: return dchild; }
/* utility to make a file */ struct dentry *simple_mknod(struct dentry *dir, char *name, int mode, int fix) { struct dentry *dchild; int err = 0; ENTRY; // ASSERT_KERNEL_CTXT("kernel doing mknod outside kernel context\n"); CDEBUG(D_INODE, "creating file %.*s\n", (int)strlen(name), name); dchild = ll_lookup_one_len(name, dir, strlen(name)); if (IS_ERR(dchild)) GOTO(out_up, dchild); if (dchild->d_inode) { int old_mode = dchild->d_inode->i_mode; if (!S_ISREG(old_mode)) GOTO(out_err, err = -EEXIST); /* Fixup file permissions if necessary */ if (fix && (old_mode & S_IALLUGO) != (mode & S_IALLUGO)) { CWARN("fixing permissions on %s from %o to %o\n", name, old_mode, mode); dchild->d_inode->i_mode = (mode & S_IALLUGO) | (old_mode & ~S_IALLUGO); mark_inode_dirty(dchild->d_inode); } GOTO(out_up, dchild); } err = ll_vfs_create(dir->d_inode, dchild, (mode & ~S_IFMT) | S_IFREG, NULL); if (err) GOTO(out_err, err); RETURN(dchild); out_err: dput(dchild); dchild = ERR_PTR(err); out_up: return dchild; }
int osd_last_rcvd_subdir_count(struct osd_device *osd) { struct lr_server_data lsd; struct dentry *dlast; loff_t off; int rc = 0; int count = 0; ENTRY; dlast = ll_lookup_one_len(LAST_RCVD, osd_sb(osd)->s_root, strlen(LAST_RCVD)); if (IS_ERR(dlast)) return PTR_ERR(dlast); else if (dlast->d_inode == NULL) goto out; off = 0; rc = osd_ldiskfs_read(dlast->d_inode, &lsd, sizeof(lsd), &off); if (rc == sizeof(lsd)) { CDEBUG(D_INFO, "read last_rcvd header, uuid = %s, " "subdir count = %d\n", lsd.lsd_uuid, lsd.lsd_subdir_count); count = le16_to_cpu(lsd.lsd_subdir_count); } else if (rc != 0) { CERROR("Can't read last_rcvd file, rc = %d\n", rc); if (rc > 0) rc = -EFAULT; goto out; } else { count = FILTER_SUBDIR_COUNT; } rc = count; out: dput(dlast); return rc; }
/*mds still need lov setup here*/ static int mds_cmd_setup(struct obd_device *obd, struct lustre_cfg *lcfg) { struct mds_obd *mds = &obd->u.mds; struct lvfs_run_ctxt saved; const char *dev; struct vfsmount *mnt; struct lustre_sb_info *lsi; struct lustre_mount_info *lmi; struct dentry *dentry; int rc = 0; ENTRY; CDEBUG(D_INFO, "obd %s setup \n", obd->obd_name); if (strncmp(obd->obd_name, MDD_OBD_NAME, strlen(MDD_OBD_NAME))) RETURN(0); if (lcfg->lcfg_bufcount < 5) { CERROR("invalid arg for setup %s\n", MDD_OBD_NAME); RETURN(-EINVAL); } dev = lustre_cfg_string(lcfg, 4); lmi = server_get_mount(dev); LASSERT(lmi != NULL); lsi = s2lsi(lmi->lmi_sb); mnt = lmi->lmi_mnt; /* FIXME: MDD LOV initialize objects. * we need only lmi here but not get mount * OSD did mount already, so put mount back */ cfs_atomic_dec(&lsi->lsi_mounts); mntput(mnt); cfs_init_rwsem(&mds->mds_notify_lock); obd->obd_fsops = fsfilt_get_ops(MT_STR(lsi->lsi_ldd)); mds_init_ctxt(obd, mnt); push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); dentry = simple_mkdir(current->fs->pwd, mnt, "OBJECTS", 0777, 1); if (IS_ERR(dentry)) { rc = PTR_ERR(dentry); CERROR("cannot create OBJECTS directory: rc = %d\n", rc); GOTO(err_putfs, rc); } mds->mds_objects_dir = dentry; dentry = ll_lookup_one_len("__iopen__", current->fs->pwd, strlen("__iopen__")); if (IS_ERR(dentry)) { rc = PTR_ERR(dentry); CERROR("cannot lookup __iopen__ directory: rc = %d\n", rc); GOTO(err_objects, rc); } mds->mds_fid_de = dentry; if (!dentry->d_inode || is_bad_inode(dentry->d_inode)) { rc = -ENOENT; CERROR("__iopen__ directory has no inode? rc = %d\n", rc); GOTO(err_fid, rc); } rc = mds_lov_init_objids(obd); if (rc != 0) { CERROR("cannot init lov objid rc = %d\n", rc); GOTO(err_fid, rc ); } rc = mds_lov_presetup(mds, lcfg); if (rc < 0) GOTO(err_objects, rc); /* Don't wait for mds_postrecov trying to clear orphans */ obd->obd_async_recov = 1; rc = mds_postsetup(obd); /* Bug 11557 - allow async abort_recov start FIXME can remove most of this obd_async_recov plumbing obd->obd_async_recov = 0; */ if (rc) GOTO(err_objects, rc); err_pop: pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); RETURN(rc); err_fid: dput(mds->mds_fid_de); err_objects: dput(mds->mds_objects_dir); err_putfs: fsfilt_put_ops(obd->obd_fsops); goto err_pop; }