/* 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;
-#ifndef HAVE_ADD_TO_PAGE_CACHE_LRU
- struct pagevec lru_pvec;
-#endif
- 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);
- ll_pagevec_init(&lru_pvec, 0);
- 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);
- if (ll_pagevec_add(&lru_pvec, page) == 0)
- ll_pagevec_lru_add_file(&lru_pvec);
- } else {
- CDEBUG(D_VFSTRACE, "page %lu add to page cache failed:"
- " %d\n", offset, ret);
- }
- page_cache_release(page);
- }
- ll_pagevec_lru_add_file(&lru_pvec);
+ if (ret == 0)
+ unlock_page(page);
+ else
+ 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)
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,
* In fact, page cannot be locked here at all, because
* ll_dir_filler() does synchronous io.
*/
- wait_on_page(page);
- if (PageUptodate(page)) {
+ wait_on_page_locked(page);
+ if (PageUptodate(page)) {
dp = kmap(page);
if (BITS_PER_LONG == 32 && hash64) {
*start = le64_to_cpu(dp->ldp_hash_start) >> 32;
}
} else {
- TREE_READ_UNLOCK_IRQ(mapping);
+ spin_unlock_irq(&mapping->tree_lock);
page = NULL;
}
return page;
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;
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 {
GOTO(out_unlock, page);
}
- wait_on_page(page);
- (void)kmap(page);
- if (!PageUptodate(page)) {
- CERROR("page not updated: "DFID" at "LPU64": rc %d\n",
- PFID(ll_inode2fid(dir)), hash, -5);
- goto fail;
- }
+ wait_on_page_locked(page);
+ (void)kmap(page);
+ if (!PageUptodate(page)) {
+ CERROR("page not updated: "DFID" at "LPU64": rc %d\n",
+ PFID(ll_inode2fid(dir)), hash, -5);
+ goto fail;
+ }
if (!PageChecked(page))
ll_check_page(dir, page);
if (PageError(page)) {
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;
#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)
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;
}
filp->f_version = inode->i_version;
#ifdef HAVE_TOUCH_ATIME_1ARG
+#ifdef HAVE_F_PATH_MNT
+ path.mnt = filp->f_path.mnt;
+#else
path.mnt = filp->f_vfsmnt;
+#endif
path.dentry = filp->f_dentry;
touch_atime(&path);
#else
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)
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);
}
}
/* 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 "
}
progress:
+ /* On error, the request should be considered as completed */
+ if (hpk.hpk_errval > 0)
+ hpk.hpk_flags |= HP_FLAG_COMPLETED;
rc = obd_iocontrol(LL_IOC_HSM_PROGRESS, sbi->ll_md_exp, sizeof(hpk),
&hpk, NULL);
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. "
}
-static int copy_and_ioctl(int cmd, struct obd_export *exp, void *data, int len)
+static int copy_and_ioctl(int cmd, struct obd_export *exp,
+ const void __user *data, size_t size)
{
- void *ptr;
- int rc;
+ void *copy;
+ int rc;
- OBD_ALLOC(ptr, len);
- if (ptr == NULL)
- return -ENOMEM;
- if (copy_from_user(ptr, data, len)) {
- OBD_FREE(ptr, len);
- return -EFAULT;
- }
- rc = obd_iocontrol(cmd, exp, len, data, NULL);
- OBD_FREE(ptr, len);
- return rc;
+ OBD_ALLOC(copy, size);
+ if (copy == NULL)
+ return -ENOMEM;
+
+ if (copy_from_user(copy, data, size)) {
+ rc = -EFAULT;
+ goto out;
+ }
+
+ rc = obd_iocontrol(cmd, exp, size, copy, NULL);
+out:
+ OBD_FREE(copy, size);
+
+ return rc;
}
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;
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 */
* 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))
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);
}
/* Compute the whole struct size */
totalsize = hur_len(hur);
OBD_FREE_PTR(hur);
+
+ /* Make sure the size is reasonable */
+ if (totalsize >= MDS_MAXREQSIZE)
+ RETURN(-E2BIG);
+
OBD_ALLOC_LARGE(hur, totalsize);
if (hur == NULL)
RETURN(-ENOMEM);
RETURN(-EFAULT);
}
- rc = obd_iocontrol(cmd, ll_i2mdexp(inode), totalsize,
- hur, NULL);
+ if (hur->hur_request.hr_action == HUA_RELEASE) {
+ const struct lu_fid *fid;
+ struct inode *f;
+ int i;
+
+ for (i = 0; i < hur->hur_request.hr_itemcount; i++) {
+ fid = &hur->hur_user_item[i].hui_fid;
+ f = search_inode_for_lustre(inode->i_sb, fid);
+ if (IS_ERR(f)) {
+ rc = PTR_ERR(f);
+ break;
+ }
+
+ rc = ll_hsm_release(f);
+ iput(f);
+ if (rc != 0)
+ break;
+ }
+ } else {
+ rc = obd_iocontrol(cmd, ll_i2mdexp(inode), totalsize,
+ hur, NULL);
+ }
OBD_FREE_LARGE(hur, totalsize);
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);