X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fllite%2Fdir.c;h=2549009e055cdec04f9323166c302297d183d41e;hp=930bd26b2419f0d67de8c9e144e8d34d1225cab4;hb=498ee35323fcacf829f4e77c91e7700cb3660111;hpb=665e36b780faa2144cecccd29a0d8a8196a76903 diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index 930bd26..2549009 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -221,7 +221,7 @@ static struct page *ll_dir_page_locate(struct inode *dir, __u64 hash, * radix_tree_gang_lookup() can be used to find a page with starting * hash _smaller_ than one we are looking for. */ - unsigned long offset = hash_x_index((__u32)hash); + unsigned long offset = hash_x_index((unsigned long)hash); struct page *page; int found; @@ -281,7 +281,8 @@ struct page *ll_get_dir_page(struct inode *dir, __u64 hash, int exact, ll_inode2fid(dir), LDLM_IBITS, &policy, mode, &lockh); if (!rc) { struct ldlm_enqueue_info einfo = { LDLM_IBITS, mode, - ll_md_blocking_ast, ldlm_completion_ast, NULL, dir }; + ll_md_blocking_ast, ldlm_completion_ast, + NULL, NULL, dir }; struct lookup_intent it = { .it_op = IT_READDIR }; struct ptlrpc_request *request; struct md_op_data *op_data; @@ -306,7 +307,8 @@ struct page *ll_get_dir_page(struct inode *dir, __u64 hash, int exact, } else { /* for cross-ref object, l_ast_data of the lock may not be set, * we reset it here */ - md_set_lock_data(ll_i2sbi(dir)->ll_md_exp, &lockh.cookie, dir); + md_set_lock_data(ll_i2sbi(dir)->ll_md_exp, &lockh.cookie, + dir, NULL); } ldlm_lock_dump_handle(D_OTHER, &lockh); @@ -344,7 +346,7 @@ struct page *ll_get_dir_page(struct inode *dir, __u64 hash, int exact, } } - page = read_cache_page(mapping, hash_x_index((__u32)hash), + page = read_cache_page(mapping, hash_x_index((unsigned long)hash), (filler_t*)mapping->a_ops->readpage, NULL); if (IS_ERR(page)) GOTO(out_unlock, page); @@ -393,6 +395,7 @@ int ll_readdir(struct file *filp, void *cookie, filldir_t filldir) int rc; int done; int shift; + __u16 type; ENTRY; CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p) pos %lu/%llu\n", @@ -418,7 +421,7 @@ int ll_readdir(struct file *filp, void *cookie, filldir_t filldir) if (!IS_ERR(page)) { /* - * If page is empty (end of directoryis reached), + * If page is empty (end of directory is reached), * use this value. */ __u64 hash = DIR_END_OFF; @@ -456,9 +459,9 @@ int ll_readdir(struct file *filp, void *cookie, filldir_t filldir) name = ent->lde_name; fid_le_to_cpu(&fid, &fid); ino = ll_fid_build_ino(sbi, &fid); - + type = ll_dirent_type_get(ent); done = filldir(cookie, name, namelen, - (loff_t)hash, ino, DT_UNKNOWN); + (loff_t)hash, ino, type); } next = le64_to_cpu(dp->ldp_hash_end); ll_put_page(page); @@ -490,7 +493,7 @@ int ll_readdir(struct file *filp, void *cookie, filldir_t filldir) } } - filp->f_pos = (loff_t)(__s32)pos; + filp->f_pos = (loff_t)pos; filp->f_version = inode->i_version; touch_atime(filp->f_vfsmnt, filp->f_dentry); @@ -499,16 +502,6 @@ int ll_readdir(struct file *filp, void *cookie, filldir_t filldir) RETURN(rc); } -#define QCTL_COPY(out, in) \ -do { \ - Q_COPY(out, in, qc_cmd); \ - Q_COPY(out, in, qc_type); \ - Q_COPY(out, in, qc_id); \ - Q_COPY(out, in, qc_stat); \ - Q_COPY(out, in, qc_dqinfo); \ - Q_COPY(out, in, qc_dqblk); \ -} while (0) - int ll_send_mgc_param(struct obd_export *mgc, char *string) { struct mgs_send_param *msp; @@ -615,14 +608,14 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump, goto end; /* Set root stripecount */ - sprintf(param, "%s-MDT0000.lov.stripecount=%u", fsname, + sprintf(param, "%s-MDT0000.lov.stripecount=%hd", fsname, lump->lmm_stripe_count); rc = ll_send_mgc_param(mgc->u.cli.cl_mgc_mgsexp, param); if (rc) goto end; /* Set root stripeoffset */ - sprintf(param, "%s-MDT0000.lov.stripeoffset=%u", fsname, + sprintf(param, "%s-MDT0000.lov.stripeoffset=%hd", fsname, lump->lmm_stripe_offset); rc = ll_send_mgc_param(mgc->u.cli.cl_mgc_mgsexp, param); if (rc) @@ -780,13 +773,11 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file, LASSERT(sizeof(lumv3.lmm_objects[0]) == sizeof(lumv3p->lmm_objects[0])); /* first try with v1 which is smaller than v3 */ - rc = copy_from_user(lumv1, lumv1p, sizeof(*lumv1)); - if (rc) + if (copy_from_user(lumv1, lumv1p, sizeof(*lumv1))) RETURN(-EFAULT); if (lumv1->lmm_magic == LOV_USER_MAGIC_V3) { - rc = copy_from_user(&lumv3, lumv3p, sizeof(lumv3)); - if (rc) + if (copy_from_user(&lumv3, lumv3p, sizeof(lumv3))) RETURN(-EFAULT); } @@ -847,8 +838,7 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file, lmdp = (struct lov_user_mds_data *)arg; lump = &lmdp->lmd_lmm; } - rc = copy_to_user(lump, lmm, lmmsize); - if (rc) + if (copy_to_user(lump, lmm, lmmsize)) GOTO(out_lmm, rc = -EFAULT); skip_lmm: if (cmd == IOC_MDC_GETFILEINFO || cmd == LL_IOC_MDC_GETINFO) { @@ -870,8 +860,7 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file, st.st_ino = inode->i_ino; lmdp = (struct lov_user_mds_data *)arg; - rc = copy_to_user(&lmdp->lmd_st, &st, sizeof(st)); - if (rc) + if (copy_to_user(&lmdp->lmd_st, &st, sizeof(st))) GOTO(out_lmm, rc = -EFAULT); } @@ -902,8 +891,7 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file, RETURN(rc); OBD_ALLOC(lmm, lmmsize); - rc = copy_from_user(lmm, lum, lmmsize); - if (rc) + if (copy_from_user(lmm, lum, lmmsize)) GOTO(free_lmm, rc = -EFAULT); switch (lmm->lmm_magic) { @@ -944,8 +932,7 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file, if (rc) GOTO(free_lsm, rc); - rc = copy_to_user(&lumd->lmd_st, &st, sizeof(st)); - if (rc) + if (copy_to_user(&lumd->lmd_st, &st, sizeof(st))) GOTO(free_lsm, rc = -EFAULT); EXIT; @@ -1004,7 +991,8 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file, if (!rc) { str = req_capsule_server_get(&req->rq_pill, &RMF_STRING); - rc = copy_to_user(data->ioc_pbuf1, str, data->ioc_plen1); + if (copy_to_user(data->ioc_pbuf1, str, data->ioc_plen1)) + rc = -EFAULT; } ptlrpc_req_finished(req); out_catinfo: @@ -1015,7 +1003,8 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file, struct obd_quotactl *oqctl; int rc, error = 0; - if (!cfs_capable(CFS_CAP_SYS_ADMIN)) + if (!cfs_capable(CFS_CAP_SYS_ADMIN) || + sbi->ll_flags & LL_SBI_RMT_CLIENT) RETURN(-EPERM); OBD_ALLOC_PTR(oqctl); @@ -1039,7 +1028,8 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file, struct if_quotacheck *check; int rc; - if (!cfs_capable(CFS_CAP_SYS_ADMIN)) + if (!cfs_capable(CFS_CAP_SYS_ADMIN) || + sbi->ll_flags & LL_SBI_RMT_CLIENT) RETURN(-EPERM); OBD_ALLOC_PTR(check); @@ -1067,47 +1057,39 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file, OBD_FREE_PTR(check); RETURN(rc); } -#ifdef HAVE_QUOTA_SUPPORT case OBD_IOC_QUOTACTL: { struct if_quotactl *qctl; - struct obd_quotactl *oqctl; - - int cmd, type, id, rc = 0; + int cmd, type, id, valid, rc = 0; OBD_ALLOC_PTR(qctl); if (!qctl) RETURN(-ENOMEM); - OBD_ALLOC_PTR(oqctl); - if (!oqctl) { - OBD_FREE_PTR(qctl); - RETURN(-ENOMEM); - } if (copy_from_user(qctl, (void *)arg, sizeof(*qctl))) GOTO(out_quotactl, rc = -EFAULT); cmd = qctl->qc_cmd; type = qctl->qc_type; id = qctl->qc_id; + valid = qctl->qc_valid; + switch (cmd) { + case LUSTRE_Q_INVALIDATE: + case LUSTRE_Q_FINVALIDATE: case Q_QUOTAON: case Q_QUOTAOFF: case Q_SETQUOTA: case Q_SETINFO: - if (!cfs_capable(CFS_CAP_SYS_ADMIN)) + if (!cfs_capable(CFS_CAP_SYS_ADMIN) || + sbi->ll_flags & LL_SBI_RMT_CLIENT) GOTO(out_quotactl, rc = -EPERM); break; case Q_GETQUOTA: if (((type == USRQUOTA && current->euid != id) || (type == GRPQUOTA && !in_egroup_p(id))) && - !cfs_capable(CFS_CAP_SYS_ADMIN)) + (!cfs_capable(CFS_CAP_SYS_ADMIN) || + sbi->ll_flags & LL_SBI_RMT_CLIENT)) GOTO(out_quotactl, rc = -EPERM); - - /* XXX: dqb_valid is borrowed as a flag to mark that - * only mds quota is wanted */ - if (qctl->qc_dqblk.dqb_valid) - qctl->obd_uuid = sbi->ll_md_exp->exp_obd-> - u.cli.cl_target_uuid; break; case Q_GETINFO: break; @@ -1116,69 +1098,76 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file, GOTO(out_quotactl, rc = -ENOTTY); } - QCTL_COPY(oqctl, qctl); - - if (qctl->obd_uuid.uuid[0]) { - struct obd_device *obd; - struct obd_uuid *uuid = &qctl->obd_uuid; - - obd = class_find_client_notype(uuid, - &sbi->ll_dt_exp->exp_obd->obd_uuid); - if (!obd) - GOTO(out_quotactl, rc = -ENOENT); + if (valid != QC_GENERAL) { + if (sbi->ll_flags & LL_SBI_RMT_CLIENT) + GOTO(out_quotactl, rc = -EOPNOTSUPP); if (cmd == Q_GETINFO) - oqctl->qc_cmd = Q_GETOINFO; + qctl->qc_cmd = Q_GETOINFO; else if (cmd == Q_GETQUOTA) - oqctl->qc_cmd = Q_GETOQUOTA; + qctl->qc_cmd = Q_GETOQUOTA; else GOTO(out_quotactl, rc = -EINVAL); - if (sbi->ll_md_exp->exp_obd == obd) { - rc = obd_quotactl(sbi->ll_md_exp, oqctl); - } else { - int i; - struct obd_export *exp; - struct lov_obd *lov = &sbi->ll_dt_exp-> - exp_obd->u.lov; - - for (i = 0; i < lov->desc.ld_tgt_count; i++) { - if (!lov->lov_tgts[i] || - !lov->lov_tgts[i]->ltd_active) - continue; - exp = lov->lov_tgts[i]->ltd_exp; - if (exp->exp_obd == obd) { - rc = obd_quotactl(exp, oqctl); - break; - } - } + switch (valid) { + case QC_MDTIDX: + rc = obd_iocontrol(OBD_IOC_QUOTACTL, + sbi->ll_md_exp, + sizeof(*qctl), qctl, NULL); + break; + case QC_OSTIDX: + rc = obd_iocontrol(OBD_IOC_QUOTACTL, + sbi->ll_dt_exp, + sizeof(*qctl), qctl, NULL); + break; + case QC_UUID: + rc = obd_iocontrol(OBD_IOC_QUOTACTL, + sbi->ll_md_exp, + sizeof(*qctl), qctl, NULL); + if (rc == -EAGAIN) + rc = obd_iocontrol(OBD_IOC_QUOTACTL, + sbi->ll_dt_exp, + sizeof(*qctl), qctl, + NULL); + break; + default: + rc = -EINVAL; + break; } - oqctl->qc_cmd = cmd; - QCTL_COPY(qctl, oqctl); - - if (copy_to_user((void *)arg, qctl, sizeof(*qctl))) - rc = -EFAULT; - - GOTO(out_quotactl, rc); - } - - rc = obd_quotactl(sbi->ll_md_exp, oqctl); - if (rc && rc != -EBUSY && cmd == Q_QUOTAON) { - oqctl->qc_cmd = Q_QUOTAOFF; - obd_quotactl(sbi->ll_md_exp, oqctl); + if (rc) + GOTO(out_quotactl, rc); + else + qctl->qc_cmd = cmd; + } else { + struct obd_quotactl *oqctl; + + OBD_ALLOC_PTR(oqctl); + if (!oqctl) + GOTO(out_quotactl, rc = -ENOMEM); + + QCTL_COPY(oqctl, qctl); + rc = obd_quotactl(sbi->ll_md_exp, oqctl); + if (rc) { + if (rc != -EALREADY && cmd == Q_QUOTAON) { + oqctl->qc_cmd = Q_QUOTAOFF; + obd_quotactl(sbi->ll_md_exp, oqctl); + } + OBD_FREE_PTR(oqctl); + GOTO(out_quotactl, rc); + } else { + QCTL_COPY(qctl, oqctl); + OBD_FREE_PTR(oqctl); + } } - QCTL_COPY(qctl, oqctl); - if (copy_to_user((void *)arg, qctl, sizeof(*qctl))) rc = -EFAULT; + out_quotactl: OBD_FREE_PTR(qctl); - OBD_FREE_PTR(oqctl); RETURN(rc); } -#endif /* HAVE_QUOTA_SUPPORT */ case OBD_IOC_GETNAME: { struct obd_device *obd = class_exp2obd(sbi->ll_dt_exp); if (!obd) @@ -1206,6 +1195,51 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file, RETURN(0); } #endif + case LL_IOC_GETOBDCOUNT: { + int count; + + if (copy_from_user(&count, (int *)arg, sizeof(int))) + RETURN(-EFAULT); + + if (!count) { + /* get ost count */ + struct lov_obd *lov = &sbi->ll_dt_exp->exp_obd->u.lov; + count = lov->desc.ld_tgt_count; + } else { + /* get mdt count */ + struct lmv_obd *lmv = &sbi->ll_md_exp->exp_obd->u.lmv; + count = lmv->desc.ld_tgt_count; + } + + if (copy_to_user((int *)arg, &count, sizeof(int))) + RETURN(-EFAULT); + + RETURN(0); + } + case LL_IOC_PATH2FID: + if (copy_to_user((void *)arg, &ll_i2info(inode)->lli_fid, + sizeof(struct lu_fid))) + RETURN(-EFAULT); + RETURN(0); + case OBD_IOC_CHANGELOG_CLEAR: { + struct ioc_changelog_clear *icc; + int rc; + + OBD_ALLOC_PTR(icc); + if (icc == NULL) + RETURN(-ENOMEM); + if (copy_from_user(icc, (void *)arg, sizeof(*icc))) + GOTO(icc_free, rc = -EFAULT); + + rc = obd_iocontrol(cmd, sbi->ll_md_exp, sizeof(*icc), icc,NULL); + +icc_free: + OBD_FREE_PTR(icc); + RETURN(rc); + } + case OBD_IOC_FID2PATH: + RETURN(ll_fid2path(ll_i2mdexp(inode), (void *)arg)); + default: RETURN(obd_iocontrol(cmd, sbi->ll_dt_exp,0,NULL,(void *)arg)); }