X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fllite%2Fdir.c;h=2021897e2664a5720e7d98e80b43365944e093ca;hp=0496b01750248bde6a3a3e6c6c7c747a3be8fe23;hb=869790802c78a41440533512549b96ad7d478428;hpb=3ef01775bf3a61d9fa5fa9a483b7d7ecc9f9fc92 diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index 0496b01..2021897 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -143,99 +143,102 @@ /* returns the page unlocked, but with a reference */ static int ll_dir_filler(void *_hash, struct page *page0) { - struct inode *inode = page0->mapping->host; - int hash64 = ll_i2sbi(inode)->ll_flags & LL_SBI_64BIT_HASH; - struct obd_export *exp = ll_i2sbi(inode)->ll_md_exp; - struct ptlrpc_request *request; - struct mdt_body *body; - struct md_op_data *op_data; + struct inode *inode = page0->mapping->host; + int hash64 = ll_i2sbi(inode)->ll_flags & LL_SBI_64BIT_HASH; + struct obd_export *exp = ll_i2sbi(inode)->ll_md_exp; + struct ptlrpc_request *request; + struct mdt_body *body; + struct md_op_data *op_data; __u64 hash = *((__u64 *)_hash); - struct page **page_pool; - struct page *page; - struct lu_dirpage *dp; + struct page **page_pool; + struct page *page; + struct lu_dirpage *dp; int max_pages = ll_i2sbi(inode)->ll_md_brw_size >> PAGE_CACHE_SHIFT; - int nrdpgs = 0; /* number of pages read actually */ - int npages; - int i; - int rc; - ENTRY; + int nrdpgs = 0; /* number of pages read actually */ + int npages; + int i; + int rc; + ENTRY; - CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p) hash "LPU64"\n", - inode->i_ino, inode->i_generation, inode, hash); + CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p) hash "LPU64"\n", + PFID(ll_inode2fid(inode)), inode, hash); LASSERT(max_pages > 0 && max_pages <= MD_MAX_BRW_PAGES); - OBD_ALLOC(page_pool, sizeof(page) * max_pages); - if (page_pool != NULL) { - page_pool[0] = page0; - } else { - page_pool = &page0; - max_pages = 1; - } - for (npages = 1; npages < max_pages; npages++) { - page = page_cache_alloc_cold(inode->i_mapping); - if (!page) - break; - page_pool[npages] = page; - } + op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, 0, + LUSTRE_OPC_ANY, NULL); + if (IS_ERR(op_data)) + RETURN(PTR_ERR(op_data)); + + OBD_ALLOC(page_pool, sizeof(page) * max_pages); + if (page_pool != NULL) { + page_pool[0] = page0; + } else { + page_pool = &page0; + max_pages = 1; + } + for (npages = 1; npages < max_pages; npages++) { + page = page_cache_alloc_cold(inode->i_mapping); + if (!page) + break; + page_pool[npages] = page; + } - op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, 0, - LUSTRE_OPC_ANY, NULL); - op_data->op_npages = npages; - op_data->op_offset = hash; - rc = md_readpage(exp, op_data, page_pool, &request); - ll_finish_md_op_data(op_data); - if (rc == 0) { - body = req_capsule_server_get(&request->rq_pill, &RMF_MDT_BODY); - /* Checked by mdc_readpage() */ - LASSERT(body != NULL); + op_data->op_npages = npages; + op_data->op_offset = hash; + rc = md_readpage(exp, op_data, page_pool, &request); + ll_finish_md_op_data(op_data); + if (rc == 0) { + body = req_capsule_server_get(&request->rq_pill, &RMF_MDT_BODY); + /* Checked by mdc_readpage() */ + LASSERT(body != NULL); - if (body->valid & OBD_MD_FLSIZE) - cl_isize_write(inode, body->size); + if (body->valid & OBD_MD_FLSIZE) + cl_isize_write(inode, body->size); nrdpgs = (request->rq_bulk->bd_nob_transferred + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; - SetPageUptodate(page0); - } - unlock_page(page0); - ptlrpc_req_finished(request); + SetPageUptodate(page0); + } + unlock_page(page0); + ptlrpc_req_finished(request); - CDEBUG(D_VFSTRACE, "read %d/%d pages\n", nrdpgs, npages); + CDEBUG(D_VFSTRACE, "read %d/%d pages\n", nrdpgs, npages); - for (i = 1; i < npages; i++) { - unsigned long offset; - int ret; + for (i = 1; i < npages; i++) { + unsigned long offset; + int ret; - page = page_pool[i]; + page = page_pool[i]; - if (rc < 0 || i >= nrdpgs) { - page_cache_release(page); - continue; - } + if (rc < 0 || i >= nrdpgs) { + page_cache_release(page); + continue; + } - SetPageUptodate(page); + SetPageUptodate(page); dp = kmap(page); hash = le64_to_cpu(dp->ldp_hash_start); kunmap(page); - offset = hash_x_index(hash, hash64); + offset = hash_x_index(hash, hash64); prefetchw(&page->flags); ret = add_to_page_cache_lru(page, inode->i_mapping, offset, GFP_KERNEL); if (ret == 0) - unlock_page(page); + unlock_page(page); else - CDEBUG(D_VFSTRACE, "page %lu add to page cache failed:" - " %d\n", offset, ret); - page_cache_release(page); - } + CDEBUG(D_VFSTRACE, "page %lu add to page cache failed:" + " %d\n", offset, ret); + page_cache_release(page); + } - if (page_pool != &page0) - OBD_FREE(page_pool, sizeof(struct page *) * max_pages); - EXIT; - return rc; + if (page_pool != &page0) + OBD_FREE(page_pool, sizeof(struct page *) * max_pages); + + RETURN(rc); } static void ll_check_page(struct inode *dir, struct page *page) @@ -273,14 +276,14 @@ static struct page *ll_dir_page_locate(struct inode *dir, __u64 *hash, struct page *page; int found; - TREE_READ_LOCK_IRQ(mapping); + spin_lock_irq(&mapping->tree_lock); found = radix_tree_gang_lookup(&mapping->page_tree, (void **)&page, offset, 1); if (found > 0) { struct lu_dirpage *dp; page_cache_get(page); - TREE_READ_UNLOCK_IRQ(mapping); + spin_unlock_irq(&mapping->tree_lock); /* * In contrast to find_lock_page() we are sure that directory * page cannot be truncated (while DLM lock is held) and, @@ -324,7 +327,7 @@ static struct page *ll_dir_page_locate(struct inode *dir, __u64 *hash, } } else { - TREE_READ_UNLOCK_IRQ(mapping); + spin_unlock_irq(&mapping->tree_lock); page = NULL; } return page; @@ -360,8 +363,8 @@ struct page *ll_get_dir_page(struct inode *dir, __u64 hash, struct ptlrpc_request *request; struct md_op_data *op_data; - op_data = ll_prep_md_op_data(NULL, dir, NULL, NULL, 0, 0, - LUSTRE_OPC_ANY, NULL); + op_data = ll_prep_md_op_data(NULL, dir, dir, NULL, 0, 0, + LUSTRE_OPC_ANY, NULL); if (IS_ERR(op_data)) return (void *)op_data; @@ -379,8 +382,8 @@ struct page *ll_get_dir_page(struct inode *dir, __u64 hash, return ERR_PTR(rc); } - CDEBUG(D_INODE, "setting lr_lvb_inode to inode %p (%lu/%u)\n", - dir, dir->i_ino, dir->i_generation); + CDEBUG(D_INODE, "setting lr_lvb_inode to inode "DFID"(%p)\n", + PFID(ll_inode2fid(dir)), dir); md_set_lock_data(ll_i2sbi(dir)->ll_md_exp, &it.d.lustre.it_lock_handle, dir, NULL); } else { @@ -595,7 +598,7 @@ static int ll_readdir(struct file *filp, void *cookie, filldir_t filldir) struct inode *inode = filp->f_dentry->d_inode; struct ll_file_data *lfd = LUSTRE_FPRIVATE(filp); struct ll_sb_info *sbi = ll_i2sbi(inode); - __u64 pos = lfd->lfd_pos; + __u64 pos; int hash64 = sbi->ll_flags & LL_SBI_64BIT_HASH; int api32 = ll_need_32bit_api(sbi); int rc; @@ -604,8 +607,13 @@ static int ll_readdir(struct file *filp, void *cookie, filldir_t filldir) #endif ENTRY; - CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p) pos %lu/%llu " - " 32bit_api %d\n", inode->i_ino, inode->i_generation, + if (lfd != NULL) + pos = lfd->lfd_pos; + else + pos = 0; + + CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p) pos %lu/%llu " + " 32bit_api %d\n", PFID(ll_inode2fid(inode)), inode, (unsigned long)pos, i_size_read(inode), api32); if (pos == MDS_DIR_END_OFF) @@ -615,7 +623,8 @@ static int ll_readdir(struct file *filp, void *cookie, filldir_t filldir) GOTO(out, rc = 0); rc = ll_dir_read(inode, &pos, cookie, filldir); - lfd->lfd_pos = pos; + if (lfd != NULL) + lfd->lfd_pos = pos; if (pos == MDS_DIR_END_OFF) { if (api32) filp->f_pos = LL_DIR_END_OFF_32BIT; @@ -686,7 +695,7 @@ int ll_dir_setdirstripe(struct inode *dir, struct lmv_user_md *lump, op_data->op_cli_flags |= CLI_SET_MEA; err = md_create(sbi->ll_md_exp, op_data, lump, sizeof(*lump), mode, - cfs_curproc_fsuid(), cfs_curproc_fsgid(), + current_fsuid(), current_fsgid(), cfs_curproc_cap_pack(), 0, &request); ll_finish_md_op_data(op_data); if (err) @@ -826,9 +835,8 @@ int ll_dir_getstripe(struct inode *inode, struct lov_mds_md **lmmp, rc = md_getattr(sbi->ll_md_exp, op_data, &req); ll_finish_md_op_data(op_data); if (rc < 0) { - CDEBUG(D_INFO, "md_getattr failed on inode " - "%lu/%u: rc %d\n", inode->i_ino, - inode->i_generation, rc); + CDEBUG(D_INFO, "md_getattr failed on inode " + DFID": rc %d\n", PFID(ll_inode2fid(inode)), rc); GOTO(out, rc); } @@ -941,7 +949,7 @@ static int ll_ioc_copy_start(struct super_block *sb, struct hsm_copy *copy) } /* Read current file data version */ - rc = ll_data_version(inode, &data_version, 1); + rc = ll_data_version(inode, &data_version, LL_DV_RD_FLUSH); iput(inode); if (rc != 0) { CDEBUG(D_HSM, "Could not read file data version of " @@ -1025,8 +1033,7 @@ static int ll_ioc_copy_end(struct super_block *sb, struct hsm_copy *copy) GOTO(progress, rc = PTR_ERR(inode)); } - rc = ll_data_version(inode, &data_version, - copy->hc_hai.hai_action == HSMA_ARCHIVE); + rc = ll_data_version(inode, &data_version, LL_DV_RD_FLUSH); iput(inode); if (rc) { CDEBUG(D_HSM, "Could not read file data version. " @@ -1113,12 +1120,12 @@ static int quotactl_ioctl(struct ll_sb_info *sbi, struct if_quotactl *qctl) sbi->ll_flags & LL_SBI_RMT_CLIENT) RETURN(-EPERM); break; - case Q_GETQUOTA: - if (((type == USRQUOTA && cfs_curproc_euid() != id) || - (type == GRPQUOTA && !in_egroup_p(id))) && - (!cfs_capable(CFS_CAP_SYS_ADMIN) || - sbi->ll_flags & LL_SBI_RMT_CLIENT)) - RETURN(-EPERM); + case Q_GETQUOTA: + if (((type == USRQUOTA && current_euid() != id) || + (type == GRPQUOTA && !in_egroup_p(id))) && + (!cfs_capable(CFS_CAP_SYS_ADMIN) || + sbi->ll_flags & LL_SBI_RMT_CLIENT)) + RETURN(-EPERM); break; case Q_GETINFO: break; @@ -1261,8 +1268,8 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg) int rc = 0; ENTRY; - CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), cmd=%#x\n", - inode->i_ino, inode->i_generation, inode, cmd); + CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p), cmd=%#x\n", + PFID(ll_inode2fid(inode)), inode, cmd); /* asm-ppc{,64} declares TCGETS, et. al. as type 't' not 'T' */ if (_IOC_TYPE(cmd) == 'T' || _IOC_TYPE(cmd) == 't') /* tty ioctls */ @@ -1453,7 +1460,7 @@ free_lmv: * on 2.4, we use OBD_CONNECT_LVB_TYPE to detect whether the * server will support REINT_RMENTRY XXX*/ if (!(exp_connect_flags(sbi->ll_md_exp) & OBD_CONNECT_LVB_TYPE)) - return -ENOTSUPP; + RETURN(-ENOTSUPP); filename = ll_getname((const char *)arg); if (IS_ERR(filename)) @@ -1768,11 +1775,11 @@ out_rmdir: inode == inode->i_sb->s_root->d_inode) { struct ll_file_data *fd = LUSTRE_FPRIVATE(file); - LASSERT(fd != NULL); - rc = rct_add(&sbi->ll_rct, cfs_curproc_pid(), arg); - if (!rc) - fd->fd_flags |= LL_FILE_RMTACL; - RETURN(rc); + LASSERT(fd != NULL); + rc = rct_add(&sbi->ll_rct, current_pid(), arg); + if (!rc) + fd->fd_flags |= LL_FILE_RMTACL; + RETURN(rc); } else RETURN(0); } @@ -1894,6 +1901,9 @@ out_rmdir: RETURN(rc); } case LL_IOC_HSM_CT_START: + if (!cfs_capable(CFS_CAP_SYS_ADMIN)) + RETURN(-EPERM); + rc = copy_and_ioctl(cmd, sbi->ll_md_exp, (void *)arg, sizeof(struct lustre_kernelcomm)); RETURN(rc);