Whamcloud - gitweb
git://git.whamcloud.com
/
fs
/
lustre-release.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
| inline |
side by side
LU-3363 api: HSM import uses new released pattern
[fs/lustre-release.git]
/
lustre
/
llite
/
file.c
diff --git
a/lustre/llite/file.c
b/lustre/llite/file.c
index
85c3944
..
8c06a27
100644
(file)
--- a/
lustre/llite/file.c
+++ b/
lustre/llite/file.c
@@
-54,7
+54,7
@@
struct ll_file_data *ll_file_data_get(void)
{
struct ll_file_data *fd;
- OBD_SLAB_ALLOC_PTR_GFP(fd, ll_file_data_slab,
CFS_ALLOC
_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(fd, ll_file_data_slab,
__GFP
_IO);
if (fd == NULL)
return NULL;
@@
-119,8
+119,9
@@
out:
}
static int ll_close_inode_openhandle(struct obd_export *md_exp,
- struct inode *inode,
- struct obd_client_handle *och)
+ struct inode *inode,
+ struct obd_client_handle *och,
+ const __u64 *data_version)
{
struct obd_export *exp = ll_i2mdexp(inode);
struct md_op_data *op_data;
@@
-144,7
+145,14
@@
static int ll_close_inode_openhandle(struct obd_export *md_exp,
if (op_data == NULL)
GOTO(out, rc = -ENOMEM); // XXX We leak openhandle and request here.
- ll_prepare_close(inode, op_data, och);
+ ll_prepare_close(inode, op_data, och);
+ if (data_version != NULL) {
+ /* Pass in data_version implies release. */
+ op_data->op_bias |= MDS_HSM_RELEASE;
+ op_data->op_data_version = *data_version;
+ op_data->op_lease_handle = och->och_lease_handle;
+ op_data->op_attr.ia_valid |= ATTR_SIZE | ATTR_BLOCKS;
+ }
epoch_close = (op_data->op_flags & MF_EPOCH_CLOSE);
rc = md_close(md_exp, op_data, och->och_mod, &req);
if (rc == -EAGAIN) {
@@
-173,8
+181,6
@@
static int ll_close_inode_openhandle(struct obd_export *md_exp,
spin_unlock(&lli->lli_lock);
}
- ll_finish_md_op_data(op_data);
-
if (rc == 0) {
rc = ll_objects_destroy(req, inode);
if (rc)
@@
-182,6
+188,14
@@
static int ll_close_inode_openhandle(struct obd_export *md_exp,
inode->i_ino, rc);
}
+ if (rc == 0 && op_data->op_bias & MDS_HSM_RELEASE) {
+ struct mdt_body *body;
+ body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
+ if (!(body->valid & OBD_MD_FLRELEASED))
+ rc = -EBUSY;
+ }
+
+ ll_finish_md_op_data(op_data);
EXIT;
out:
@@
-233,7
+247,7
@@
int ll_md_real_close(struct inode *inode, int flags)
if (och) { /* There might be a race and somebody have freed this och
already */
rc = ll_close_inode_openhandle(ll_i2sbi(inode)->ll_md_exp,
-
inode, och
);
+
inode, och, NULL
);
}
RETURN(rc);
@@
-251,6
+265,24
@@
int ll_md_close(struct obd_export *md_exp, struct inode *inode,
if (unlikely(fd->fd_flags & LL_FILE_GROUP_LOCKED))
ll_put_grouplock(inode, file, fd->fd_grouplock.cg_gid);
+ if (fd->fd_lease_och != NULL) {
+ bool lease_broken;
+
+ /* Usually the lease is not released when the
+ * application crashed, we need to release here. */
+ rc = ll_lease_close(fd->fd_lease_och, inode, &lease_broken);
+ CDEBUG(rc ? D_ERROR : D_INODE, "Clean up lease "DFID" %d/%d\n",
+ PFID(&lli->lli_fid), rc, lease_broken);
+
+ fd->fd_lease_och = NULL;
+ }
+
+ if (fd->fd_och != NULL) {
+ rc = ll_close_inode_openhandle(md_exp, inode, fd->fd_och, NULL);
+ fd->fd_och = NULL;
+ GOTO(out, rc);
+ }
+
/* Let's see if we have good enough OPEN lock on the file and if
we can skip talking to MDS */
if (file->f_dentry->d_inode) { /* Can this ever be false? */
@@
-287,11
+319,12
@@
int ll_md_close(struct obd_export *md_exp, struct inode *inode,
file, file->f_dentry, file->f_dentry->d_name.name);
}
- LUSTRE_FPRIVATE(file) = NULL;
- ll_file_data_put(fd);
- ll_capa_close(inode);
+out:
+ LUSTRE_FPRIVATE(file) = NULL;
+ ll_file_data_put(fd);
+ ll_capa_close(inode);
-
RETURN(rc);
+ RETURN(rc);
}
/* While this returns an error code, fput() the caller does not, so we need
@@
-360,8
+393,6
@@
static int ll_intent_file_open(struct file *file, void *lmm,
{
struct ll_sb_info *sbi = ll_i2sbi(file->f_dentry->d_inode);
struct dentry *parent = file->f_dentry->d_parent;
- const char *name = file->f_dentry->d_name.name;
- const int len = file->f_dentry->d_name.len;
struct md_op_data *op_data;
struct ptlrpc_request *req;
__u32 opc = LUSTRE_OPC_ANY;
@@
-386,9
+417,10
@@
static int ll_intent_file_open(struct file *file, void *lmm,
opc = LUSTRE_OPC_CREATE;
}
- op_data = ll_prep_md_op_data(NULL, parent->d_inode,
- file->f_dentry->d_inode, name, len,
- O_RDWR, opc, NULL);
+ op_data = ll_prep_md_op_data(NULL, parent->d_inode,
+ file->f_dentry->d_inode, NULL, 0,
+ O_RDWR, opc, NULL);
+
if (IS_ERR(op_data))
RETURN(PTR_ERR(op_data));
@@
-443,24
+475,20
@@
void ll_ioepoch_open(struct ll_inode_info *lli, __u64 ioepoch)
}
}
-static int ll_och_fill(struct obd_export *md_exp, struct l
l_inode_info *lli
,
-
struct lookup_intent *it,
struct obd_client_handle *och)
+static int ll_och_fill(struct obd_export *md_exp, struct l
ookup_intent *it
,
+ struct obd_client_handle *och)
{
- struct ptlrpc_request *req = it->d.lustre.it_data;
- struct mdt_body *body;
-
- LASSERT(och);
-
- body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
- LASSERT(body != NULL); /* reply already checked out */
+ struct ptlrpc_request *req = it->d.lustre.it_data;
+ struct mdt_body *body;
- memcpy(&och->och_fh, &body->handle, sizeof(body->handle));
- och->och_magic = OBD_CLIENT_HANDLE_MAGIC;
- och->och_fid = lli->lli_fid;
- och->och_flags = it->it_flags;
- ll_ioepoch_open(lli, body->ioepoch);
+ body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
+ och->och_fh = body->handle;
+ och->och_fid = body->fid1;
+ och->och_lease_handle.cookie = it->d.lustre.it_lock_handle;
+ och->och_magic = OBD_CLIENT_HANDLE_MAGIC;
+ och->och_flags = it->it_flags;
-
return md_set_open_replay_data(md_exp, och, req);
+ return md_set_open_replay_data(md_exp, och, req);
}
int ll_local_open(struct file *file, struct lookup_intent *it,
@@
-479,21
+507,19
@@
int ll_local_open(struct file *file, struct lookup_intent *it,
struct mdt_body *body;
int rc;
-
rc = ll_och_fill(ll_i2sbi(inode)->ll_md_exp, lli
, it, och);
-
if (rc
)
-
RETURN(rc);
+
rc = ll_och_fill(ll_i2sbi(inode)->ll_md_exp
, it, och);
+
if (rc != 0
)
+ RETURN(rc);
- body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
- if ((it->it_flags & FMODE_WRITE) &&
- (body->valid & OBD_MD_FLSIZE))
- CDEBUG(D_INODE, "Epoch "LPU64" opened on "DFID"\n",
- lli->lli_ioepoch, PFID(&lli->lli_fid));
- }
+ body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
+ ll_ioepoch_open(lli, body->ioepoch);
+ }
+
+ LUSTRE_FPRIVATE(file) = fd;
+ ll_readahead_init(inode, &fd->fd_ras);
+ fd->fd_omode = it->it_flags & (FMODE_READ | FMODE_WRITE | FMODE_EXEC);
- LUSTRE_FPRIVATE(file) = fd;
- ll_readahead_init(inode, &fd->fd_ras);
- fd->fd_omode = it->it_flags;
- RETURN(0);
+ RETURN(0);
}
/* Open a file, and (for the very first open) create objects on the OSTs at
@@
-695,6
+721,201
@@
out_openerr:
return rc;
}
+static int ll_md_blocking_lease_ast(struct ldlm_lock *lock,
+ struct ldlm_lock_desc *desc, void *data, int flag)
+{
+ int rc;
+ struct lustre_handle lockh;
+ ENTRY;
+
+ switch (flag) {
+ case LDLM_CB_BLOCKING:
+ ldlm_lock2handle(lock, &lockh);
+ rc = ldlm_cli_cancel(&lockh, LCF_ASYNC);
+ if (rc < 0) {
+ CDEBUG(D_INODE, "ldlm_cli_cancel: %d\n", rc);
+ RETURN(rc);
+ }
+ break;
+ case LDLM_CB_CANCELING:
+ /* do nothing */
+ break;
+ }
+ RETURN(0);
+}
+
+/**
+ * Acquire a lease and open the file.
+ */
+struct obd_client_handle *ll_lease_open(struct inode *inode, struct file *file,
+ fmode_t fmode, __u64 open_flags)
+{
+ struct lookup_intent it = { .it_op = IT_OPEN };
+ struct ll_sb_info *sbi = ll_i2sbi(inode);
+ struct md_op_data *op_data;
+ struct ptlrpc_request *req;
+ struct lustre_handle old_handle = { 0 };
+ struct obd_client_handle *och = NULL;
+ int rc;
+ int rc2;
+ ENTRY;
+
+ if (fmode != FMODE_WRITE && fmode != FMODE_READ)
+ RETURN(ERR_PTR(-EINVAL));
+
+ if (file != NULL) {
+ struct ll_inode_info *lli = ll_i2info(inode);
+ struct ll_file_data *fd = LUSTRE_FPRIVATE(file);
+ struct obd_client_handle **och_p;
+ __u64 *och_usecount;
+
+ if (!(fmode & file->f_mode) || (file->f_mode & FMODE_EXEC))
+ RETURN(ERR_PTR(-EPERM));
+
+ /* Get the openhandle of the file */
+ rc = -EBUSY;
+ mutex_lock(&lli->lli_och_mutex);
+ if (fd->fd_lease_och != NULL) {
+ mutex_unlock(&lli->lli_och_mutex);
+ RETURN(ERR_PTR(rc));
+ }
+
+ if (fd->fd_och == NULL) {
+ if (file->f_mode & FMODE_WRITE) {
+ LASSERT(lli->lli_mds_write_och != NULL);
+ och_p = &lli->lli_mds_write_och;
+ och_usecount = &lli->lli_open_fd_write_count;
+ } else {
+ LASSERT(lli->lli_mds_read_och != NULL);
+ och_p = &lli->lli_mds_read_och;
+ och_usecount = &lli->lli_open_fd_read_count;
+ }
+ if (*och_usecount == 1) {
+ fd->fd_och = *och_p;
+ *och_p = NULL;
+ *och_usecount = 0;
+ rc = 0;
+ }
+ }
+ mutex_unlock(&lli->lli_och_mutex);
+ if (rc < 0) /* more than 1 opener */
+ RETURN(ERR_PTR(rc));
+
+ LASSERT(fd->fd_och != NULL);
+ old_handle = fd->fd_och->och_fh;
+ }
+
+ OBD_ALLOC_PTR(och);
+ if (och == NULL)
+ RETURN(ERR_PTR(-ENOMEM));
+
+ op_data = ll_prep_md_op_data(NULL, inode, inode, NULL, 0, 0,
+ LUSTRE_OPC_ANY, NULL);
+ if (IS_ERR(op_data))
+ GOTO(out, rc = PTR_ERR(op_data));
+
+ /* To tell the MDT this openhandle is from the same owner */
+ op_data->op_handle = old_handle;
+
+ it.it_flags = fmode | open_flags;
+ it.it_flags |= MDS_OPEN_LOCK | MDS_OPEN_BY_FID | MDS_OPEN_LEASE;
+ rc = md_intent_lock(sbi->ll_md_exp, op_data, NULL, 0, &it, 0, &req,
+ ll_md_blocking_lease_ast,
+ /* LDLM_FL_NO_LRU: To not put the lease lock into LRU list, otherwise
+ * it can be cancelled which may mislead applications that the lease is
+ * broken;
+ * LDLM_FL_EXCL: Set this flag so that it won't be matched by normal
+ * open in ll_md_blocking_ast(). Otherwise as ll_md_blocking_lease_ast
+ * doesn't deal with openhandle, so normal openhandle will be leaked. */
+ LDLM_FL_NO_LRU | LDLM_FL_EXCL);
+ ll_finish_md_op_data(op_data);
+ if (req != NULL) {
+ ptlrpc_req_finished(req);
+ it_clear_disposition(&it, DISP_ENQ_COMPLETE);
+ }
+ if (rc < 0)
+ GOTO(out_release_it, rc);
+
+ if (it_disposition(&it, DISP_LOOKUP_NEG))
+ GOTO(out_release_it, rc = -ENOENT);
+
+ rc = it_open_error(DISP_OPEN_OPEN, &it);
+ if (rc)
+ GOTO(out_release_it, rc);
+
+ LASSERT(it_disposition(&it, DISP_ENQ_OPEN_REF));
+ ll_och_fill(sbi->ll_md_exp, &it, och);
+
+ if (!it_disposition(&it, DISP_OPEN_LEASE)) /* old server? */
+ GOTO(out_close, rc = -EOPNOTSUPP);
+
+ /* already get lease, handle lease lock */
+ ll_set_lock_data(sbi->ll_md_exp, inode, &it, NULL);
+ if (it.d.lustre.it_lock_mode == 0 ||
+ it.d.lustre.it_lock_bits != MDS_INODELOCK_OPEN) {
+ /* open lock must return for lease */
+ CERROR(DFID "lease granted but no open lock, %d/%Lu.\n",
+ PFID(ll_inode2fid(inode)), it.d.lustre.it_lock_mode,
+ it.d.lustre.it_lock_bits);
+ GOTO(out_close, rc = -EPROTO);
+ }
+
+ ll_intent_release(&it);
+ RETURN(och);
+
+out_close:
+ rc2 = ll_close_inode_openhandle(sbi->ll_md_exp, inode, och, NULL);
+ if (rc2)
+ CERROR("Close openhandle returned %d\n", rc2);
+
+ /* cancel open lock */
+ if (it.d.lustre.it_lock_mode != 0) {
+ ldlm_lock_decref_and_cancel(&och->och_lease_handle,
+ it.d.lustre.it_lock_mode);
+ it.d.lustre.it_lock_mode = 0;
+ }
+out_release_it:
+ ll_intent_release(&it);
+out:
+ OBD_FREE_PTR(och);
+ RETURN(ERR_PTR(rc));
+}
+EXPORT_SYMBOL(ll_lease_open);
+
+/**
+ * Release lease and close the file.
+ * It will check if the lease has ever broken.
+ */
+int ll_lease_close(struct obd_client_handle *och, struct inode *inode,
+ bool *lease_broken)
+{
+ struct ldlm_lock *lock;
+ bool cancelled = true;
+ int rc;
+ ENTRY;
+
+ lock = ldlm_handle2lock(&och->och_lease_handle);
+ if (lock != NULL) {
+ lock_res_and_lock(lock);
+ cancelled = ldlm_is_cancel(lock);
+ unlock_res_and_lock(lock);
+ ldlm_lock_put(lock);
+ }
+
+ CDEBUG(D_INODE, "lease for "DFID" broken? %d\n",
+ PFID(&ll_i2info(inode)->lli_fid), cancelled);
+
+ if (!cancelled)
+ ldlm_cli_cancel(&och->och_lease_handle, 0);
+ if (lease_broken != NULL)
+ *lease_broken = cancelled;
+
+ rc = ll_close_inode_openhandle(ll_i2sbi(inode)->ll_md_exp, inode, och,
+ NULL);
+ RETURN(rc);
+}
+EXPORT_SYMBOL(ll_lease_close);
+
/* Fills the obdo with the attributes for the lsm */
static int ll_lsm_getattr(struct lov_stripe_md *lsm, struct obd_export *exp,
struct obd_capa *capa, struct obdo *obdo,
@@
-883,9
+1104,7
@@
restart:
cio->cui_iov = args->u.normal.via_iov;
cio->cui_nrsegs = args->u.normal.via_nrsegs;
cio->cui_tot_nrsegs = cio->cui_nrsegs;
-#ifndef HAVE_FILE_WRITEV
cio->cui_iocb = args->u.normal.via_iocb;
-#endif
if ((iot == CIT_WRITE) &&
!(cio->cui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) {
if (mutex_lock_interruptible(&lli->
@@
-927,7
+1146,7
@@
out:
cl_io_fini(env, io);
/* If any bit been read/written (result != 0), we just return
* short read/write instead of restart io. */
- if (
result == 0
&& io->ci_need_restart) {
+ if (
(result == 0 || result == -ENODATA)
&& io->ci_need_restart) {
CDEBUG(D_VFSTRACE, "Restart %s on %s from %lld, count:%zd\n",
iot == CIT_READ ? "read" : "write",
file->f_dentry->d_name.name, *ppos, count);
@@
-984,56
+1203,6
@@
static int ll_file_get_iov_count(const struct iovec *iov,
return 0;
}
-#ifdef HAVE_FILE_READV
-static ssize_t ll_file_readv(struct file *file, const struct iovec *iov,
- unsigned long nr_segs, loff_t *ppos)
-{
- struct lu_env *env;
- struct vvp_io_args *args;
- size_t count;
- ssize_t result;
- int refcheck;
- ENTRY;
-
- result = ll_file_get_iov_count(iov, &nr_segs, &count);
- if (result)
- RETURN(result);
-
- env = cl_env_get(&refcheck);
- if (IS_ERR(env))
- RETURN(PTR_ERR(env));
-
- args = vvp_env_args(env, IO_NORMAL);
- args->u.normal.via_iov = (struct iovec *)iov;
- args->u.normal.via_nrsegs = nr_segs;
-
- result = ll_file_io_generic(env, args, file, CIT_READ, ppos, count);
- cl_env_put(env, &refcheck);
- RETURN(result);
-}
-
-static ssize_t ll_file_read(struct file *file, char *buf, size_t count,
- loff_t *ppos)
-{
- struct lu_env *env;
- struct iovec *local_iov;
- ssize_t result;
- int refcheck;
- ENTRY;
-
- env = cl_env_get(&refcheck);
- if (IS_ERR(env))
- RETURN(PTR_ERR(env));
-
- local_iov = &vvp_env_info(env)->vti_local_iov;
- local_iov->iov_base = (void __user *)buf;
- local_iov->iov_len = count;
- result = ll_file_readv(file, local_iov, 1, ppos);
- cl_env_put(env, &refcheck);
- RETURN(result);
-}
-
-#else
static ssize_t ll_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
unsigned long nr_segs, loff_t pos)
{
@@
-1091,62
+1260,11
@@
static ssize_t ll_file_read(struct file *file, char *buf, size_t count,
cl_env_put(env, &refcheck);
RETURN(result);
}
-#endif
/*
* Write to a file (through the page cache).
+ * AIO stuff
*/
-#ifdef HAVE_FILE_WRITEV
-static ssize_t ll_file_writev(struct file *file, const struct iovec *iov,
- unsigned long nr_segs, loff_t *ppos)
-{
- struct lu_env *env;
- struct vvp_io_args *args;
- size_t count;
- ssize_t result;
- int refcheck;
- ENTRY;
-
- result = ll_file_get_iov_count(iov, &nr_segs, &count);
- if (result)
- RETURN(result);
-
- env = cl_env_get(&refcheck);
- if (IS_ERR(env))
- RETURN(PTR_ERR(env));
-
- args = vvp_env_args(env, IO_NORMAL);
- args->u.normal.via_iov = (struct iovec *)iov;
- args->u.normal.via_nrsegs = nr_segs;
-
- result = ll_file_io_generic(env, args, file, CIT_WRITE, ppos, count);
- cl_env_put(env, &refcheck);
- RETURN(result);
-}
-
-static ssize_t ll_file_write(struct file *file, const char *buf, size_t count,
- loff_t *ppos)
-{
- struct lu_env *env;
- struct iovec *local_iov;
- ssize_t result;
- int refcheck;
- ENTRY;
-
- env = cl_env_get(&refcheck);
- if (IS_ERR(env))
- RETURN(PTR_ERR(env));
-
- local_iov = &vvp_env_info(env)->vti_local_iov;
- local_iov->iov_base = (void __user *)buf;
- local_iov->iov_len = count;
-
- result = ll_file_writev(file, local_iov, 1, ppos);
- cl_env_put(env, &refcheck);
- RETURN(result);
-}
-
-#else /* AIO stuff */
static ssize_t ll_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
unsigned long nr_segs, loff_t pos)
{
@@
-1204,37
+1322,7
@@
static ssize_t ll_file_write(struct file *file, const char *buf, size_t count,
cl_env_put(env, &refcheck);
RETURN(result);
}
-#endif
-
-#ifdef HAVE_KERNEL_SENDFILE
-/*
- * Send file content (through pagecache) somewhere with helper
- */
-static ssize_t ll_file_sendfile(struct file *in_file, loff_t *ppos,size_t count,
- read_actor_t actor, void *target)
-{
- struct lu_env *env;
- struct vvp_io_args *args;
- ssize_t result;
- int refcheck;
- ENTRY;
-
- env = cl_env_get(&refcheck);
- if (IS_ERR(env))
- RETURN(PTR_ERR(env));
-
- args = vvp_env_args(env, IO_SENDFILE);
- args->u.sendfile.via_target = target;
- args->u.sendfile.via_actor = actor;
-
- result = ll_file_io_generic(env, args, in_file, CIT_READ, ppos, count);
- cl_env_put(env, &refcheck);
- RETURN(result);
-}
-#endif
-
-#ifdef HAVE_KERNEL_SPLICE_READ
/*
* Send file content (through pagecache) somewhere with helper
*/
@@
-1260,7
+1348,6
@@
static ssize_t ll_file_splice_read(struct file *in_file, loff_t *ppos,
cl_env_put(env, &refcheck);
RETURN(result);
}
-#endif
static int ll_lov_recreate(struct inode *inode, struct ost_id *oi,
obd_count ost_idx)
@@
-1278,7
+1365,7
@@
static int ll_lov_recreate(struct inode *inode, struct ost_id *oi,
RETURN(-ENOMEM);
lsm = ccc_inode_lsm_get(inode);
-
if (lsm == NULL
)
+
if (!lsm_has_objects(lsm)
)
GOTO(out, rc = -ENOENT);
lsm_size = sizeof(*lsm) + (sizeof(struct lov_oinfo) *
@@
-1434,6
+1521,12
@@
int ll_lov_getstripe_ea_info(struct inode *inode, const char *filename,
* passing it to userspace.
*/
if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC)) {
+ int stripe_count;
+
+ stripe_count = le16_to_cpu(lmm->lmm_stripe_count);
+ if (le32_to_cpu(lmm->lmm_pattern) & LOV_PATTERN_F_RELEASED)
+ stripe_count = 0;
+
/* if function called for directory - we should
* avoid swab not existent lsm objects */
if (lmm->lmm_magic == cpu_to_le32(LOV_MAGIC_V1)) {
@@
-1441,13
+1534,13
@@
int ll_lov_getstripe_ea_info(struct inode *inode, const char *filename,
if (S_ISREG(body->mode))
lustre_swab_lov_user_md_objects(
((struct lov_user_md_v1 *)lmm)->lmm_objects,
-
((struct lov_user_md_v1 *)lmm)->lmm_
stripe_count);
+ stripe_count);
} else if (lmm->lmm_magic == cpu_to_le32(LOV_MAGIC_V3)) {
lustre_swab_lov_user_md_v3((struct lov_user_md_v3 *)lmm);
if (S_ISREG(body->mode))
lustre_swab_lov_user_md_objects(
((struct lov_user_md_v3 *)lmm)->lmm_objects,
-
((struct lov_user_md_v3 *)lmm)->lmm_
stripe_count);
+ stripe_count);
}
}
@@
-1644,18
+1737,17
@@
int ll_release_openhandle(struct dentry *dentry, struct lookup_intent *it)
if (!och)
GOTO(out, rc = -ENOMEM);
- ll_och_fill(ll_i2sbi(inode)->ll_md_exp,
- ll_i2info(inode), it, och);
+ ll_och_fill(ll_i2sbi(inode)->ll_md_exp, it, och);
rc = ll_close_inode_openhandle(ll_i2sbi(inode)->ll_md_exp,
-
inode, och
);
-
out:
-
/* this one is in place of ll_file_open */
-
if (it_disposition(it, DISP_ENQ_OPEN_REF)) {
-
ptlrpc_req_finished(it->d.lustre.it_data);
-
it_clear_disposition(it, DISP_ENQ_OPEN_REF);
-
}
-
RETURN(rc);
+
inode, och, NULL
);
+out:
+ /* this one is in place of ll_file_open */
+ if (it_disposition(it, DISP_ENQ_OPEN_REF)) {
+ ptlrpc_req_finished(it->d.lustre.it_data);
+ it_clear_disposition(it, DISP_ENQ_OPEN_REF);
+ }
+ RETURN(rc);
}
/**
@@
-1833,20
+1925,18
@@
int ll_data_version(struct inode *inode, __u64 *data_version,
/* If no stripe, we consider version is 0. */
lsm = ccc_inode_lsm_get(inode);
- if (
lsm == NULL
) {
+ if (
!lsm_has_objects(lsm)
) {
*data_version = 0;
CDEBUG(D_INODE, "No object for inode\n");
-
RETURN(
0);
+
GOTO(out, rc =
0);
}
OBD_ALLOC_PTR(obdo);
- if (obdo == NULL) {
- ccc_inode_lsm_put(inode, lsm);
- RETURN(-ENOMEM);
- }
+ if (obdo == NULL)
+ GOTO(out, rc = -ENOMEM);
rc = ll_lsm_getattr(lsm, sbi->ll_dt_exp, NULL, obdo, 0, extent_lock);
- if (
!rc
) {
+ if (
rc == 0
) {
if (!(obdo->o_valid & OBD_MD_FLDATAVERSION))
rc = -EOPNOTSUPP;
else
@@
-1854,11
+1944,59
@@
int ll_data_version(struct inode *inode, __u64 *data_version,
}
OBD_FREE_PTR(obdo);
+ EXIT;
+out:
ccc_inode_lsm_put(inode, lsm);
-
RETURN(rc);
}
+/*
+ * Trigger a HSM release request for the provided inode.
+ */
+int ll_hsm_release(struct inode *inode)
+{
+ struct cl_env_nest nest;
+ struct lu_env *env;
+ struct obd_client_handle *och = NULL;
+ __u64 data_version = 0;
+ int rc;
+ ENTRY;
+
+ CDEBUG(D_INODE, "%s: Releasing file "DFID".\n",
+ ll_get_fsname(inode->i_sb, NULL, 0),
+ PFID(&ll_i2info(inode)->lli_fid));
+
+ och = ll_lease_open(inode, NULL, FMODE_WRITE, MDS_OPEN_RELEASE);
+ if (IS_ERR(och))
+ GOTO(out, rc = PTR_ERR(och));
+
+ /* Grab latest data_version and [am]time values */
+ rc = ll_data_version(inode, &data_version, 1);
+ if (rc != 0)
+ GOTO(out, rc);
+
+ env = cl_env_nested_get(&nest);
+ if (IS_ERR(env))
+ GOTO(out, rc = PTR_ERR(env));
+
+ ll_merge_lvb(env, inode);
+ cl_env_nested_put(&nest, env);
+
+ /* Release the file.
+ * NB: lease lock handle is released in mdc_hsm_release_pack() because
+ * we still need it to pack l_remote_handle to MDT. */
+ rc = ll_close_inode_openhandle(ll_i2sbi(inode)->ll_md_exp, inode, och,
+ &data_version);
+ och = NULL;
+
+ EXIT;
+out:
+ if (och != NULL && !IS_ERR(och)) /* close the file */
+ ll_lease_close(och, inode, NULL);
+
+ return rc;
+}
+
struct ll_swap_stack {
struct iattr ia1, ia2;
__u64 dv1, dv2;
@@
-1886,8
+2024,8
@@
static int ll_swap_layouts(struct file *file1, struct file *file2,
if (!S_ISREG(llss->inode2->i_mode))
GOTO(free, rc = -EINVAL);
- if (
ll_permission(llss->inode1, MAY_WRITE, NULL
) ||
-
ll_permission(llss->inode2, MAY_WRITE, NULL
))
+ if (
inode_permission(llss->inode1, MAY_WRITE
) ||
+
inode_permission(llss->inode2, MAY_WRITE
))
GOTO(free, rc = -EPERM);
if (llss->inode2->i_sb != llss->inode1->i_sb)
@@
-1967,12
+2105,12
@@
static int ll_swap_layouts(struct file *file1, struct file *file2,
rc = -ENOMEM;
op_data = ll_prep_md_op_data(NULL, llss->inode1, llss->inode2, NULL, 0,
0, LUSTRE_OPC_ANY, &msl);
- if (
op_data != NULL) {
- rc = obd_iocontrol(LL_IOC_LOV_SWAP_LAYOUTS,
- ll_i2mdexp(llss->inode1),
- sizeof(*op_data), op_data, NULL);
-
ll_finish_md_op_data(op_data
);
- }
+ if (
IS_ERR(op_data))
+ GOTO(free, rc = PTR_ERR(op_data));
+
+ rc = obd_iocontrol(LL_IOC_LOV_SWAP_LAYOUTS, ll_i2mdexp(llss->inode1),
+
sizeof(*op_data), op_data, NULL
);
+ ll_finish_md_op_data(op_data);
putgl:
if (gid != 0) {
@@
-2020,6
+2158,86
@@
free:
RETURN(rc);
}
+static int ll_hsm_state_set(struct inode *inode, struct hsm_state_set *hss)
+{
+ struct md_op_data *op_data;
+ int rc;
+
+ /* Non-root users are forbidden to set or clear flags which are
+ * NOT defined in HSM_USER_MASK. */
+ if (((hss->hss_setmask | hss->hss_clearmask) & ~HSM_USER_MASK) &&
+ !cfs_capable(CFS_CAP_SYS_ADMIN))
+ RETURN(-EPERM);
+
+ op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, 0,
+ LUSTRE_OPC_ANY, hss);
+ if (IS_ERR(op_data))
+ RETURN(PTR_ERR(op_data));
+
+ rc = obd_iocontrol(LL_IOC_HSM_STATE_SET, ll_i2mdexp(inode),
+ sizeof(*op_data), op_data, NULL);
+
+ ll_finish_md_op_data(op_data);
+
+ RETURN(rc);
+}
+
+static int ll_hsm_import(struct inode *inode, struct file *file,
+ struct hsm_user_import *hui)
+{
+ struct hsm_state_set *hss = NULL;
+ struct iattr *attr = NULL;
+ int rc;
+ ENTRY;
+
+ if (!S_ISREG(inode->i_mode))
+ RETURN(-EINVAL);
+
+ /* set HSM flags */
+ OBD_ALLOC_PTR(hss);
+ if (hss == NULL)
+ GOTO(out, rc = -ENOMEM);
+
+ hss->hss_valid = HSS_SETMASK | HSS_ARCHIVE_ID;
+ hss->hss_archive_id = hui->hui_archive_id;
+ hss->hss_setmask = HS_ARCHIVED | HS_EXISTS | HS_RELEASED;
+ rc = ll_hsm_state_set(inode, hss);
+ if (rc != 0)
+ GOTO(out, rc);
+
+ OBD_ALLOC_PTR(attr);
+ if (attr == NULL)
+ GOTO(out, rc = -ENOMEM);
+
+ attr->ia_mode = hui->hui_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
+ attr->ia_mode |= S_IFREG;
+ attr->ia_uid = hui->hui_uid;
+ attr->ia_gid = hui->hui_gid;
+ attr->ia_size = hui->hui_size;
+ attr->ia_mtime.tv_sec = hui->hui_mtime;
+ attr->ia_mtime.tv_nsec = hui->hui_mtime_ns;
+ attr->ia_atime.tv_sec = hui->hui_atime;
+ attr->ia_atime.tv_nsec = hui->hui_atime_ns;
+
+ attr->ia_valid = ATTR_SIZE | ATTR_MODE | ATTR_FORCE |
+ ATTR_UID | ATTR_GID |
+ ATTR_MTIME | ATTR_MTIME_SET |
+ ATTR_ATIME | ATTR_ATIME_SET;
+
+ rc = ll_setattr_raw(file->f_dentry, attr, true);
+ if (rc == -ENODATA)
+ rc = 0;
+
+out:
+ if (hss != NULL)
+ OBD_FREE_PTR(hss);
+
+ if (attr != NULL)
+ OBD_FREE_PTR(attr);
+
+ RETURN(rc);
+}
+
long ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct inode *inode = file->f_dentry->d_inode;
@@
-2069,7
+2287,7
@@
long ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
struct file *file2;
struct lustre_swap_layouts lsl;
- if (c
fs_c
opy_from_user(&lsl, (char *)arg,
+ if (copy_from_user(&lsl, (char *)arg,
sizeof(struct lustre_swap_layouts)))
RETURN(-EFAULT);
@@
-2166,9
+2384,9
@@
long ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, 0,
LUSTRE_OPC_ANY, hus);
- if (
op_data == NULL
) {
+ if (
IS_ERR(op_data)
) {
OBD_FREE_PTR(hus);
- RETURN(
-ENOMEM
);
+ RETURN(
PTR_ERR(op_data)
);
}
rc = obd_iocontrol(cmd, ll_i2mdexp(inode), sizeof(*op_data),
@@
-2182,37
+2400,19
@@
long ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
RETURN(rc);
}
case LL_IOC_HSM_STATE_SET: {
- struct md_op_data *op_data;
struct hsm_state_set *hss;
int rc;
OBD_ALLOC_PTR(hss);
if (hss == NULL)
RETURN(-ENOMEM);
+
if (copy_from_user(hss, (char *)arg, sizeof(*hss))) {
OBD_FREE_PTR(hss);
RETURN(-EFAULT);
}
- /* Non-root users are forbidden to set or clear flags which are
- * NOT defined in HSM_USER_MASK. */
- if (((hss->hss_setmask | hss->hss_clearmask) & ~HSM_USER_MASK)
- && !cfs_capable(CFS_CAP_SYS_ADMIN)) {
- OBD_FREE_PTR(hss);
- RETURN(-EPERM);
- }
-
- op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, 0,
- LUSTRE_OPC_ANY, hss);
- if (op_data == NULL) {
- OBD_FREE_PTR(hss);
- RETURN(-ENOMEM);
- }
-
- rc = obd_iocontrol(cmd, ll_i2mdexp(inode), sizeof(*op_data),
- op_data, NULL);
-
- ll_finish_md_op_data(op_data);
+ rc = ll_hsm_state_set(inode, hss);
OBD_FREE_PTR(hss);
RETURN(rc);
@@
-2228,21
+2428,121
@@
long ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, 0,
LUSTRE_OPC_ANY, hca);
- if (
op_data == NULL
) {
+ if (
IS_ERR(op_data)
) {
OBD_FREE_PTR(hca);
- RETURN(
-ENOMEM
);
+ RETURN(
PTR_ERR(op_data)
);
}
rc = obd_iocontrol(cmd, ll_i2mdexp(inode), sizeof(*op_data),
op_data, NULL);
- if (c
fs_c
opy_to_user((char *)arg, hca, sizeof(*hca)))
+ if (copy_to_user((char *)arg, hca, sizeof(*hca)))
rc = -EFAULT;
ll_finish_md_op_data(op_data);
OBD_FREE_PTR(hca);
RETURN(rc);
}
+ case LL_IOC_SET_LEASE: {
+ struct ll_inode_info *lli = ll_i2info(inode);
+ struct obd_client_handle *och = NULL;
+ bool lease_broken;
+ fmode_t mode = 0;
+
+ switch (arg) {
+ case F_WRLCK:
+ if (!(file->f_mode & FMODE_WRITE))
+ RETURN(-EPERM);
+ mode = FMODE_WRITE;
+ break;
+ case F_RDLCK:
+ if (!(file->f_mode & FMODE_READ))
+ RETURN(-EPERM);
+ mode = FMODE_READ;
+ break;
+ case F_UNLCK:
+ mutex_lock(&lli->lli_och_mutex);
+ if (fd->fd_lease_och != NULL) {
+ och = fd->fd_lease_och;
+ fd->fd_lease_och = NULL;
+ }
+ mutex_unlock(&lli->lli_och_mutex);
+
+ if (och != NULL) {
+ mode = och->och_flags &(FMODE_READ|FMODE_WRITE);
+ rc = ll_lease_close(och, inode, &lease_broken);
+ if (rc == 0 && lease_broken)
+ mode = 0;
+ } else {
+ rc = -ENOLCK;
+ }
+
+ /* return the type of lease or error */
+ RETURN(rc < 0 ? rc : (int)mode);
+ default:
+ RETURN(-EINVAL);
+ }
+
+ CDEBUG(D_INODE, "Set lease with mode %d\n", mode);
+
+ /* apply for lease */
+ och = ll_lease_open(inode, file, mode, 0);
+ if (IS_ERR(och))
+ RETURN(PTR_ERR(och));
+
+ rc = 0;
+ mutex_lock(&lli->lli_och_mutex);
+ if (fd->fd_lease_och == NULL) {
+ fd->fd_lease_och = och;
+ och = NULL;
+ }
+ mutex_unlock(&lli->lli_och_mutex);
+ if (och != NULL) {
+ /* impossible now that only excl is supported for now */
+ ll_lease_close(och, inode, &lease_broken);
+ rc = -EBUSY;
+ }
+ RETURN(rc);
+ }
+ case LL_IOC_GET_LEASE: {
+ struct ll_inode_info *lli = ll_i2info(inode);
+ struct ldlm_lock *lock = NULL;
+
+ rc = 0;
+ mutex_lock(&lli->lli_och_mutex);
+ if (fd->fd_lease_och != NULL) {
+ struct obd_client_handle *och = fd->fd_lease_och;
+
+ lock = ldlm_handle2lock(&och->och_lease_handle);
+ if (lock != NULL) {
+ lock_res_and_lock(lock);
+ if (!ldlm_is_cancel(lock))
+ rc = och->och_flags &
+ (FMODE_READ | FMODE_WRITE);
+ unlock_res_and_lock(lock);
+ ldlm_lock_put(lock);
+ }
+ }
+ mutex_unlock(&lli->lli_och_mutex);
+ RETURN(rc);
+ }
+ case LL_IOC_HSM_IMPORT: {
+ struct hsm_user_import *hui;
+
+ OBD_ALLOC_PTR(hui);
+ if (hui == NULL)
+ RETURN(-ENOMEM);
+
+ if (copy_from_user(hui, (void *)arg, sizeof(*hui))) {
+ OBD_FREE_PTR(hui);
+ RETURN(-EFAULT);
+ }
+
+ rc = ll_hsm_import(inode, file, hui);
+
+ OBD_FREE_PTR(hui);
+ RETURN(rc);
+ }
default: {
int err;
@@
-2506,18
+2806,20
@@
int ll_fsync(struct file *file, struct dentry *dentry, int datasync)
int ll_file_flock(struct file *file, int cmd, struct file_lock *file_lock)
{
- struct inode *inode = file->f_dentry->d_inode;
- struct ll_sb_info *sbi = ll_i2sbi(inode);
- struct ldlm_enqueue_info einfo = { .ei_type = LDLM_FLOCK,
- .ei_cb_cp =ldlm_flock_completion_ast,
- .ei_cbdata = file_lock };
- struct md_op_data *op_data;
- struct lustre_handle lockh = {0};
- ldlm_policy_data_t flock = {{0}};
- int flags = 0;
- int rc;
+ struct inode *inode = file->f_dentry->d_inode;
+ struct ll_sb_info *sbi = ll_i2sbi(inode);
+ struct ldlm_enqueue_info einfo = {
+ .ei_type = LDLM_FLOCK,
+ .ei_cb_cp = ldlm_flock_completion_ast,
+ .ei_cbdata = file_lock,
+ };
+ struct md_op_data *op_data;
+ struct lustre_handle lockh = {0};
+ ldlm_policy_data_t flock = {{0}};
+ int flags = 0;
+ int rc;
int rc2 = 0;
-
ENTRY;
+ ENTRY;
CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu file_lock=%p\n",
inode->i_ino, file_lock);
@@
-2691,7
+2993,8
@@
int ll_have_md_lock(struct inode *inode, __u64 *bits, ldlm_mode_t l_req_mode)
}
ldlm_mode_t ll_take_md_lock(struct inode *inode, __u64 bits,
- struct lustre_handle *lockh, __u64 flags)
+ struct lustre_handle *lockh, __u64 flags,
+ ldlm_mode_t mode)
{
ldlm_policy_data_t policy = { .l_inodebits = {bits}};
struct lu_fid *fid;
@@
-2701,10
+3004,10
@@
ldlm_mode_t ll_take_md_lock(struct inode *inode, __u64 bits,
fid = &ll_i2info(inode)->lli_fid;
CDEBUG(D_INFO, "trying to match res "DFID"\n", PFID(fid));
-
rc = md_lock_match(ll_i2mdexp(inode), LDLM_FL_BLOCK_GRANTED|flags,
- fid, LDLM_IBITS, &policy,
- LCK_CR|LCK_CW|LCK_PR|LCK_PW, lockh);
-
RETURN(rc);
+ rc = md_lock_match(ll_i2mdexp(inode), LDLM_FL_BLOCK_GRANTED|flags,
+ fid, LDLM_IBITS, &policy,
mode, lockh);
+
+ RETURN(rc);
}
static int ll_inode_revalidate_fini(struct inode *inode, int rc)
@@
-2824,13
+3127,13
@@
out:
}
int ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it,
-
__u64 ibits)
+ __u64 ibits)
{
-
struct inode
*inode = dentry->d_inode;
-
int
rc;
-
ENTRY;
+
struct inode
*inode = dentry->d_inode;
+
int
rc;
+ ENTRY;
-
rc = __ll_inode_revalidate_it(dentry, it, ibits);
+ rc = __ll_inode_revalidate_it(dentry, it, ibits);
if (rc != 0)
RETURN(rc);
@@
-2840,9
+3143,17
@@
int ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it,
LTIME_S(inode->i_mtime) = ll_i2info(inode)->lli_lvb.lvb_mtime;
LTIME_S(inode->i_ctime) = ll_i2info(inode)->lli_lvb.lvb_ctime;
} else {
- rc = ll_glimpse_size(inode);
+ /* In case of restore, the MDT has the right size and has
+ * already send it back without granting the layout lock,
+ * inode is up-to-date so glimpse is useless.
+ * Also to glimpse we need the layout, in case of a running
+ * restore the MDT holds the layout lock so the glimpse will
+ * block up to the end of restore (getattr will block)
+ */
+ if (!(ll_i2info(inode)->lli_flags & LLIF_FILE_RESTORING))
+ rc = ll_glimpse_size(inode);
}
-
RETURN(rc);
+ RETURN(rc);
}
int ll_getattr_it(struct vfsmount *mnt, struct dentry *de,
@@
-3013,55
+3324,33
@@
int ll_inode_permission(struct inode *inode, int mask, struct nameidata *nd)
RETURN(rc);
}
-#ifdef HAVE_FILE_READV
-#define READ_METHOD readv
-#define READ_FUNCTION ll_file_readv
-#define WRITE_METHOD writev
-#define WRITE_FUNCTION ll_file_writev
-#else
-#define READ_METHOD aio_read
-#define READ_FUNCTION ll_file_aio_read
-#define WRITE_METHOD aio_write
-#define WRITE_FUNCTION ll_file_aio_write
-#endif
-
/* -o localflock - only provides locally consistent flock locks */
struct file_operations ll_file_operations = {
.read = ll_file_read,
-
.READ_METHOD = READ_FUNCTION
,
+
.aio_read = ll_file_aio_read
,
.write = ll_file_write,
-
.WRITE_METHOD = WRITE_FUNCTION
,
+
.aio_write = ll_file_aio_write
,
.unlocked_ioctl = ll_file_ioctl,
.open = ll_file_open,
.release = ll_file_release,
.mmap = ll_file_mmap,
.llseek = ll_file_seek,
-#ifdef HAVE_KERNEL_SENDFILE
- .sendfile = ll_file_sendfile,
-#endif
-#ifdef HAVE_KERNEL_SPLICE_READ
.splice_read = ll_file_splice_read,
-#endif
.fsync = ll_fsync,
.flush = ll_flush
};
struct file_operations ll_file_operations_flock = {
.read = ll_file_read,
-
.READ_METHOD = READ_FUNCTION
,
+
.aio_read = ll_file_aio_read
,
.write = ll_file_write,
-
.WRITE_METHOD = WRITE_FUNCTION
,
+
.aio_write = ll_file_aio_write
,
.unlocked_ioctl = ll_file_ioctl,
.open = ll_file_open,
.release = ll_file_release,
.mmap = ll_file_mmap,
.llseek = ll_file_seek,
-#ifdef HAVE_KERNEL_SENDFILE
- .sendfile = ll_file_sendfile,
-#endif
-#ifdef HAVE_KERNEL_SPLICE_READ
.splice_read = ll_file_splice_read,
-#endif
.fsync = ll_fsync,
.flush = ll_flush,
.flock = ll_file_flock,
@@
-3071,20
+3360,15
@@
struct file_operations ll_file_operations_flock = {
/* These are for -o noflock - to return ENOSYS on flock calls */
struct file_operations ll_file_operations_noflock = {
.read = ll_file_read,
-
.READ_METHOD = READ_FUNCTION
,
+
.aio_read = ll_file_aio_read
,
.write = ll_file_write,
-
.WRITE_METHOD = WRITE_FUNCTION
,
+
.aio_write = ll_file_aio_write
,
.unlocked_ioctl = ll_file_ioctl,
.open = ll_file_open,
.release = ll_file_release,
.mmap = ll_file_mmap,
.llseek = ll_file_seek,
-#ifdef HAVE_KERNEL_SENDFILE
- .sendfile = ll_file_sendfile,
-#endif
-#ifdef HAVE_KERNEL_SPLICE_READ
.splice_read = ll_file_splice_read,
-#endif
.fsync = ll_fsync,
.flush = ll_flush,
.flock = ll_file_noflock,
@@
-3255,7
+3539,11
@@
static int ll_layout_fetch(struct inode *inode, struct ldlm_lock *lock)
int rc;
ENTRY;
- if (lock->l_lvb_data != NULL)
+ CDEBUG(D_INODE, DFID" LVB_READY=%d l_lvb_data=%p l_lvb_len=%d\n",
+ PFID(ll_inode2fid(inode)), !!(lock->l_flags & LDLM_FL_LVB_READY),
+ lock->l_lvb_data, lock->l_lvb_len);
+
+ if ((lock->l_lvb_data != NULL) && (lock->l_flags & LDLM_FL_LVB_READY))
RETURN(0);
/* if layout lock was granted right away, the layout is returned
@@
-3291,15
+3579,13
@@
static int ll_layout_fetch(struct inode *inode, struct ldlm_lock *lock)
memcpy(lvbdata, lmm, lmmsize);
lock_res_and_lock(lock);
- if (lock->l_lvb_data
== NULL) {
-
lock->l_lvb_data = lvbdata
;
- lock->l_lvb_len = lmmsize;
-
lvbdata = NULL
;
- }
+ if (lock->l_lvb_data
!= NULL)
+
OBD_FREE_LARGE(lock->l_lvb_data, lock->l_lvb_len)
;
+
+
lock->l_lvb_data = lvbdata
;
+ lock->l_lvb_len = lmmsize;
unlock_res_and_lock(lock);
- if (lvbdata != NULL)
- OBD_FREE_LARGE(lvbdata, lmmsize);
EXIT;
out:
@@
-3331,7
+3617,7
@@
static int ll_layout_lock_set(struct lustre_handle *lockh, ldlm_mode_t mode,
LASSERT(ldlm_has_layout(lock));
LDLM_DEBUG(lock, "File %p/"DFID" being reconfigured: %d.\n",
- inode, PFID(&lli->lli_fid), reconf);
+
inode, PFID(&lli->lli_fid), reconf);
/* in case this is a caching lock and reinstate with new inode */
md_set_lock_data(sbi->ll_md_exp, &lockh->cookie, inode, NULL);
@@
-3341,6
+3627,7
@@
static int ll_layout_lock_set(struct lustre_handle *lockh, ldlm_mode_t mode,
unlock_res_and_lock(lock);
/* checking lvb_ready is racy but this is okay. The worst case is
* that multi processes may configure the file on the same time. */
+
if (lvb_ready || !reconf) {
rc = -ENODATA;
if (lvb_ready) {
@@
-3437,11
+3724,12
@@
int ll_layout_refresh(struct inode *inode, __u32 *gen)
struct lookup_intent it;
struct lustre_handle lockh;
ldlm_mode_t mode;
- struct ldlm_enqueue_info einfo = { .ei_type = LDLM_IBITS,
- .ei_mode = LCK_CR,
- .ei_cb_bl = ll_md_blocking_ast,
- .ei_cb_cp = ldlm_completion_ast,
- .ei_cbdata = NULL };
+ struct ldlm_enqueue_info einfo = {
+ .ei_type = LDLM_IBITS,
+ .ei_mode = LCK_CR,
+ .ei_cb_bl = ll_md_blocking_ast,
+ .ei_cb_cp = ldlm_completion_ast,
+ };
int rc;
ENTRY;
@@
-3455,7
+3743,8
@@
int ll_layout_refresh(struct inode *inode, __u32 *gen)
/* mostly layout lock is caching on the local side, so try to match
* it before grabbing layout lock mutex. */
- mode = ll_take_md_lock(inode, MDS_INODELOCK_LAYOUT, &lockh, 0);
+ mode = ll_take_md_lock(inode, MDS_INODELOCK_LAYOUT, &lockh, 0,
+ LCK_CR | LCK_CW | LCK_PR | LCK_PW);
if (mode != 0) { /* hit cached lock */
rc = ll_layout_lock_set(&lockh, mode, inode, gen, false);
if (rc == 0)
@@
-3470,7
+3759,8
@@
int ll_layout_refresh(struct inode *inode, __u32 *gen)
again:
/* try again. Maybe somebody else has done this. */
- mode = ll_take_md_lock(inode, MDS_INODELOCK_LAYOUT, &lockh, 0);
+ mode = ll_take_md_lock(inode, MDS_INODELOCK_LAYOUT, &lockh, 0,
+ LCK_CR | LCK_CW | LCK_PR | LCK_PW);
if (mode != 0) { /* hit cached lock */
rc = ll_layout_lock_set(&lockh, mode, inode, gen, true);
if (rc == -EAGAIN)
@@
-3519,3
+3809,32
@@
again:
RETURN(rc);
}
+
+/**
+ * This function send a restore request to the MDT
+ */
+int ll_layout_restore(struct inode *inode)
+{
+ struct hsm_user_request *hur;
+ int len, rc;
+ ENTRY;
+
+ len = sizeof(struct hsm_user_request) +
+ sizeof(struct hsm_user_item);
+ OBD_ALLOC(hur, len);
+ if (hur == NULL)
+ RETURN(-ENOMEM);
+
+ hur->hur_request.hr_action = HUA_RESTORE;
+ hur->hur_request.hr_archive_id = 0;
+ hur->hur_request.hr_flags = 0;
+ memcpy(&hur->hur_user_item[0].hui_fid, &ll_i2info(inode)->lli_fid,
+ sizeof(hur->hur_user_item[0].hui_fid));
+ hur->hur_user_item[0].hui_extent.length = -1;
+ hur->hur_request.hr_itemcount = 1;
+ rc = obd_iocontrol(LL_IOC_HSM_REQUEST, cl_i2sbi(inode)->ll_md_exp,
+ len, hur, NULL);
+ OBD_FREE(hur, len);
+ RETURN(rc);
+}
+