#define DEBUG_SUBSYSTEM S_LLITE
#include <lustre_dlm.h>
#include <lustre_lite.h>
+#include <lustre_mdc.h>
#include <linux/pagemap.h>
#include <linux/file.h>
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-#include <linux/lustre_compat25.h>
-#endif
#include "llite_internal.h"
/* also used by llite/special.c:ll_special_open() */
{
struct ll_file_data *fd;
- OBD_SLAB_ALLOC(fd, ll_file_data_slab, SLAB_KERNEL, sizeof *fd);
+ OBD_SLAB_ALLOC_PTR(fd, ll_file_data_slab);
return fd;
}
static void ll_file_data_put(struct ll_file_data *fd)
{
if (fd != NULL)
- OBD_SLAB_FREE(fd, ll_file_data_slab, sizeof *fd);
+ OBD_SLAB_FREE_PTR(fd, ll_file_data_slab);
+}
+
+void ll_pack_inode2opdata(struct inode *inode, struct md_op_data *op_data,
+ struct lustre_handle *fh)
+{
+ op_data->op_fid1 = ll_i2info(inode)->lli_fid;
+ op_data->op_attr.ia_mode = inode->i_mode;
+ op_data->op_attr.ia_atime = inode->i_atime;
+ op_data->op_attr.ia_mtime = inode->i_mtime;
+ op_data->op_attr.ia_ctime = inode->i_ctime;
+ op_data->op_attr.ia_size = i_size_read(inode);
+ op_data->op_attr_blocks = inode->i_blocks;
+ ((struct ll_iattr *)&op_data->op_attr)->ia_attr_flags = inode->i_flags;
+ op_data->op_ioepoch = ll_i2info(inode)->lli_ioepoch;
+ memcpy(&op_data->op_handle, fh, sizeof(op_data->op_handle));
+ op_data->op_capa1 = ll_mdscapa_get(inode);
}
-static int ll_close_inode_openhandle(struct inode *inode,
+static void ll_prepare_close(struct inode *inode, struct md_op_data *op_data,
+ struct obd_client_handle *och)
+{
+ ENTRY;
+
+ op_data->op_attr.ia_valid = ATTR_MODE | ATTR_ATIME_SET |
+ ATTR_MTIME_SET | ATTR_CTIME_SET;
+
+ if (!(och->och_flags & FMODE_WRITE))
+ goto out;
+
+ if (!(ll_i2mdexp(inode)->exp_connect_flags & OBD_CONNECT_SOM) ||
+ !S_ISREG(inode->i_mode))
+ op_data->op_attr.ia_valid |= ATTR_SIZE | ATTR_BLOCKS;
+ else
+ ll_epoch_close(inode, op_data, &och, 0);
+
+out:
+ ll_pack_inode2opdata(inode, op_data, &och->och_fh);
+ EXIT;
+}
+
+static int ll_close_inode_openhandle(struct obd_export *md_exp,
+ struct inode *inode,
struct obd_client_handle *och)
{
+ struct obd_export *exp = ll_i2mdexp(inode);
+ struct md_op_data *op_data;
struct ptlrpc_request *req = NULL;
- struct obd_device *obd;
- struct obdo *oa;
- int rc;
+ struct obd_device *obd = class_exp2obd(exp);
+ int epoch_close = 1;
+ int seq_end = 0, rc;
ENTRY;
- obd = class_exp2obd(ll_i2mdcexp(inode));
if (obd == NULL) {
+ /*
+ * XXX: in case of LMV, is this correct to access
+ * ->exp_handle?
+ */
CERROR("Invalid MDC connection handle "LPX64"\n",
- ll_i2mdcexp(inode)->exp_handle.h_cookie);
+ ll_i2mdexp(inode)->exp_handle.h_cookie);
GOTO(out, rc = 0);
}
/*
* here we check if this is forced umount. If so this is called on
- * canceling "open lock" and we do not call mdc_close() in this case, as
+ * canceling "open lock" and we do not call md_close() in this case, as
* it will not be successful, as import is already deactivated.
*/
- if (obd->obd_no_recov)
+ if (obd->obd_force)
GOTO(out, rc = 0);
- oa = obdo_alloc();
- if (!oa)
- RETURN(-ENOMEM); // XXX We leak openhandle and request here.
-
- oa->o_id = inode->i_ino;
- oa->o_valid = OBD_MD_FLID;
- obdo_from_inode(oa, inode, OBD_MD_FLTYPE | OBD_MD_FLMODE |
- OBD_MD_FLSIZE | OBD_MD_FLBLOCKS |
- OBD_MD_FLATIME | OBD_MD_FLMTIME |
- OBD_MD_FLCTIME);
- if (0 /* ll_is_inode_dirty(inode) */) {
- oa->o_flags = MDS_BFLAG_UNCOMMITTED_WRITES;
- oa->o_valid |= OBD_MD_FLFLAGS;
- }
-
- rc = mdc_close(ll_i2mdcexp(inode), oa, och, &req);
- if (rc == EAGAIN) {
- /* We are the last writer, so the MDS has instructed us to get
- * the file size and any write cookies, then close again. */
- //ll_queue_done_writing(inode);
- rc = 0;
+ OBD_ALLOC_PTR(op_data);
+ if (op_data == NULL)
+ GOTO(out, rc = -ENOMEM); // XXX We leak openhandle and request here.
+
+ ll_prepare_close(inode, op_data, och);
+ epoch_close = (op_data->op_flags & MF_EPOCH_CLOSE);
+ rc = md_close(md_exp, op_data, och->och_mod, &req);
+ if (rc != -EAGAIN)
+ seq_end = 1;
+
+ if (rc == -EAGAIN) {
+ /* This close must have the epoch closed. */
+ LASSERT(exp->exp_connect_flags & OBD_CONNECT_SOM);
+ LASSERT(epoch_close);
+ /* MDS has instructed us to obtain Size-on-MDS attribute from
+ * OSTs and send setattr to back to MDS. */
+ rc = ll_sizeonmds_update(inode, och->och_mod,
+ &och->och_fh, op_data->op_ioepoch);
+ if (rc) {
+ CERROR("inode %lu mdc Size-on-MDS update failed: "
+ "rc = %d\n", inode->i_ino, rc);
+ rc = 0;
+ }
} else if (rc) {
CERROR("inode %lu mdc close failed: rc = %d\n",
inode->i_ino, rc);
}
-
- obdo_free(oa);
+ ll_finish_md_op_data(op_data);
if (rc == 0) {
rc = ll_objects_destroy(req, inode);
inode->i_ino, rc);
}
- ptlrpc_req_finished(req); /* This is close request */
EXIT;
out:
- mdc_clear_open_replay_data(och);
-
+
+ if ((exp->exp_connect_flags & OBD_CONNECT_SOM) && !epoch_close &&
+ S_ISREG(inode->i_mode) && (och->och_flags & FMODE_WRITE)) {
+ ll_queue_done_writing(inode, LLIF_DONE_WRITING);
+ } else {
+ if (seq_end)
+ ptlrpc_close_replay_seq(req);
+ md_clear_open_replay_data(md_exp, och);
+ /* Free @och if it is not waiting for DONE_WRITING. */
+ och->och_fh.cookie = DEAD_HANDLE_MAGIC;
+ OBD_FREE_PTR(och);
+ }
+ if (req) /* This is close request */
+ ptlrpc_req_finished(req);
return rc;
}
-int ll_mdc_real_close(struct inode *inode, int flags)
+int ll_md_real_close(struct inode *inode, int flags)
{
struct ll_inode_info *lli = ll_i2info(inode);
- int rc = 0;
struct obd_client_handle **och_p;
struct obd_client_handle *och;
__u64 *och_usecount;
-
+ int rc = 0;
ENTRY;
if (flags & FMODE_WRITE) {
} else if (flags & FMODE_EXEC) {
och_p = &lli->lli_mds_exec_och;
och_usecount = &lli->lli_open_fd_exec_count;
- } else {
+ } else {
LASSERT(flags & FMODE_READ);
och_p = &lli->lli_mds_read_och;
och_usecount = &lli->lli_open_fd_read_count;
if (och) { /* There might be a race and somebody have freed this och
already */
- rc = ll_close_inode_openhandle(inode, och);
- och->och_fh.cookie = DEAD_HANDLE_MAGIC;
- OBD_FREE(och, sizeof *och);
+ rc = ll_close_inode_openhandle(ll_i2sbi(inode)->ll_md_exp,
+ inode, och);
}
RETURN(rc);
}
-int ll_mdc_close(struct obd_export *mdc_exp, struct inode *inode,
- struct file *file)
+int ll_md_close(struct obd_export *md_exp, struct inode *inode,
+ struct file *file)
{
struct ll_file_data *fd = LUSTRE_FPRIVATE(file);
struct ll_inode_info *lli = ll_i2info(inode);
int flags = LDLM_FL_BLOCK_GRANTED | LDLM_FL_TEST_LOCK;
struct lustre_handle lockh;
struct inode *inode = file->f_dentry->d_inode;
- struct ldlm_res_id file_res_id = {.name={inode->i_ino,
- inode->i_generation}};
ldlm_policy_data_t policy = {.l_inodebits={MDS_INODELOCK_OPEN}};
down(&lli->lli_och_sem);
}
up(&lli->lli_och_sem);
- if (!ldlm_lock_match(mdc_exp->exp_obd->obd_namespace, flags,
- &file_res_id, LDLM_IBITS, &policy,lockmode,
- &lockh)) {
- rc = ll_mdc_real_close(file->f_dentry->d_inode,
- fd->fd_omode);
+ if (!md_lock_match(md_exp, flags, ll_inode2fid(inode),
+ LDLM_IBITS, &policy, lockmode,
+ &lockh)) {
+ rc = ll_md_real_close(file->f_dentry->d_inode,
+ fd->fd_omode);
}
} else {
CERROR("Releasing a file %p with negative dentry %p. Name %s",
LUSTRE_FPRIVATE(file) = NULL;
ll_file_data_put(fd);
+ ll_capa_close(inode);
RETURN(rc);
}
ENTRY;
CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n", inode->i_ino,
inode->i_generation, inode);
- ll_vfs_ops_tally(sbi, VFS_OPS_RELEASE);
/* don't do anything for / */
if (inode->i_sb->s_root == file->f_dentry)
RETURN(0);
- lprocfs_counter_incr(sbi->ll_stats, LPROC_LL_RELEASE);
-
+ ll_stats_ops_tally(sbi, LPROC_LL_RELEASE, 1);
fd = LUSTRE_FPRIVATE(file);
LASSERT(fd != NULL);
+ /* don't do anything for / */
+ if (inode->i_sb->s_root == file->f_dentry) {
+ LUSTRE_FPRIVATE(file) = NULL;
+ ll_file_data_put(fd);
+ RETURN(0);
+ }
+
if (lsm)
lov_test_and_clear_async_rc(lsm);
lli->lli_async_rc = 0;
- rc = ll_mdc_close(sbi->ll_mdc_exp, inode, file);
+ rc = ll_md_close(sbi->ll_md_exp, inode, file);
RETURN(rc);
}
int lmmsize, struct lookup_intent *itp)
{
struct ll_sb_info *sbi = ll_i2sbi(file->f_dentry->d_inode);
- struct mdc_op_data data;
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 inode *inode = file->f_dentry->d_inode;
+ struct md_op_data *op_data;
struct ptlrpc_request *req;
int rc;
if (!parent)
RETURN(-ENOENT);
- ll_prepare_mdc_op_data(&data, parent->d_inode, inode, name, len, O_RDWR);
-
/* Usually we come here only for NFSD, and we want open lock.
But we can also get here with pre 2.6.15 patchless kernels, and in
that case that lock is also ok */
if (!lmm && !lmmsize)
itp->it_flags |= MDS_OPEN_LOCK;
- rc = mdc_intent_lock(sbi->ll_mdc_exp, &data, lmm, lmmsize, itp,
- 0 /*unused */, &req, ll_mdc_blocking_ast, 0);
+ op_data = ll_prep_md_op_data(NULL, parent->d_inode,
+ file->f_dentry->d_inode, name, len,
+ O_RDWR, LUSTRE_OPC_ANY, NULL);
+ if (IS_ERR(op_data))
+ RETURN(PTR_ERR(op_data));
+
+ rc = md_intent_lock(sbi->ll_md_exp, op_data, lmm, lmmsize, itp,
+ 0 /*unused */, &req, ll_md_blocking_ast, 0);
+ ll_finish_md_op_data(op_data);
if (rc == -ESTALE) {
/* reason for keep own exit path - don`t flood log
* with messages with -ESTALE errors.
*/
- if (!it_disposition(itp, DISP_OPEN_OPEN))
+ if (!it_disposition(itp, DISP_OPEN_OPEN) ||
+ it_open_error(DISP_OPEN_OPEN, itp))
GOTO(out, rc);
ll_release_openhandle(file->f_dentry, itp);
GOTO(out_stale, rc);
}
- if (rc != 0) {
- CERROR("lock enqueue: err: %d\n", rc);
- GOTO(out, rc);
+ if (rc != 0 || it_open_error(DISP_OPEN_OPEN, itp)) {
+ rc = rc ? rc : it_open_error(DISP_OPEN_OPEN, itp);
+ CDEBUG(D_VFSTRACE, "lock enqueue: err: %d\n", rc);
+ GOTO(out, rc);
}
if (itp->d.lustre.it_lock_mode)
- mdc_set_lock_data(&itp->d.lustre.it_lock_handle,
- inode);
+ md_set_lock_data(sbi->ll_md_exp,
+ &itp->d.lustre.it_lock_handle,
+ file->f_dentry->d_inode);
- rc = ll_prep_inode(sbi->ll_osc_exp, &file->f_dentry->d_inode,
- req, DLM_REPLY_REC_OFF, NULL);
+ rc = ll_prep_inode(&file->f_dentry->d_inode, req, DLM_REPLY_REC_OFF,
+ NULL);
out:
ptlrpc_req_finished(itp->d.lustre.it_data);
RETURN(rc);
}
-
-static void ll_och_fill(struct ll_inode_info *lli, struct lookup_intent *it,
- struct obd_client_handle *och)
+static int ll_och_fill(struct obd_export *md_exp, struct ll_inode_info *lli,
+ struct lookup_intent *it, struct obd_client_handle *och)
{
struct ptlrpc_request *req = it->d.lustre.it_data;
- struct mds_body *body;
+ struct mdt_body *body;
LASSERT(och);
body = lustre_msg_buf(req->rq_repmsg, DLM_REPLY_REC_OFF, sizeof(*body));
- LASSERT(body != NULL); /* reply already checked out */
- LASSERT_REPSWABBED(req, DLM_REPLY_REC_OFF); /* and swabbed in mdc_enqueue */
+ LASSERT(body != NULL); /* reply already checked out */
+ LASSERT_REPSWABBED(req, DLM_REPLY_REC_OFF); /* and swabbed in md_enqueue */
memcpy(&och->och_fh, &body->handle, sizeof(body->handle));
och->och_magic = OBD_CLIENT_HANDLE_MAGIC;
- lli->lli_io_epoch = body->io_epoch;
+ och->och_fid = lli->lli_fid;
+ och->och_flags = it->it_flags;
+ lli->lli_ioepoch = body->ioepoch;
- mdc_set_open_replay_data(och, it->d.lustre.it_data);
+ return md_set_open_replay_data(md_exp, och, req);
}
int ll_local_open(struct file *file, struct lookup_intent *it,
struct ll_file_data *fd, struct obd_client_handle *och)
{
+ struct inode *inode = file->f_dentry->d_inode;
+ struct ll_inode_info *lli = ll_i2info(inode);
ENTRY;
LASSERT(!LUSTRE_FPRIVATE(file));
LASSERT(fd != NULL);
- if (och)
- ll_och_fill(ll_i2info(file->f_dentry->d_inode), it, och);
+ if (och) {
+ struct ptlrpc_request *req = it->d.lustre.it_data;
+ struct mdt_body *body;
+ int rc;
+
+ rc = ll_och_fill(ll_i2sbi(inode)->ll_md_exp, lli, it, och);
+ if (rc)
+ RETURN(rc);
+
+ body = lustre_msg_buf(req->rq_repmsg,
+ DLM_REPLY_REC_OFF, sizeof(*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));
+ }
+ }
+
LUSTRE_FPRIVATE(file) = fd;
- ll_readahead_init(file->f_dentry->d_inode, &fd->fd_ras);
+ ll_readahead_init(inode, &fd->fd_ras);
fd->fd_omode = it->it_flags;
-
RETURN(0);
}
* stripe MD to the MDS, or try to destroy the objects if that fails.
*
* If we already have the stripe MD locally then we don't request it in
- * mdc_open(), by passing a lmm_size = 0.
+ * md_open(), by passing a lmm_size = 0.
*
* It is up to the application to ensure no other processes open this file
* in the O_LOV_DELAY_CREATE case, or the default striping pattern will be
CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), flags %o\n", inode->i_ino,
inode->i_generation, inode, file->f_flags);
- ll_vfs_ops_tally(ll_i2sbi(inode), VFS_OPS_OPEN);
/* don't do anything for / */
if (inode->i_sb->s_root == file->f_dentry)
if (fd == NULL)
RETURN(-ENOMEM);
+ /* don't do anything for / */
+ if (inode->i_sb->s_root == file->f_dentry) {
+ LUSTRE_FPRIVATE(file) = fd;
+ RETURN(0);
+ }
+
if (!it || !it->d.lustre.it_disposition) {
/* Convert f_flags into access mode. We cannot use file->f_mode,
- * because everything but O_ACCMODE mask was stripped from it */
+ * because everything but O_ACCMODE mask was stripped from
+ * there */
if ((oit.it_flags + 1) & O_ACCMODE)
oit.it_flags++;
if (file->f_flags & O_TRUNC)
och_p = &lli->lli_mds_read_och;
och_usecount = &lli->lli_open_fd_read_count;
}
-
- LASSERTF(it->it_flags != 0, "it %p dist %d \n", it,
- it->d.lustre.it_disposition);
-
+
down(&lli->lli_och_sem);
if (*och_p) { /* Open handle is present */
if (it_disposition(it, DISP_OPEN_OPEN)) {
/* Well, there's extra open request that we do not need,
let's close it somehow. This will decref request. */
+ rc = it_open_error(DISP_OPEN_OPEN, it);
+ if (rc) {
+ ll_file_data_put(fd);
+ GOTO(out_och_free, rc);
+ }
ll_release_openhandle(file->f_dentry, it);
+ lprocfs_counter_incr(ll_i2sbi(inode)->ll_stats,
+ LPROC_LL_OPEN);
}
(*och_usecount)++;
rc = ll_local_open(file, it, fd, NULL);
-
- LASSERTF(rc == 0, "rc = %d\n", rc);
+ if (rc) {
+ up(&lli->lli_och_sem);
+ ll_file_data_put(fd);
+ RETURN(rc);
+ }
} else {
LASSERT(*och_usecount == 0);
OBD_ALLOC(*och_p, sizeof (struct obd_client_handle));
}
(*och_usecount)++;
if (!it->d.lustre.it_disposition) {
+ it->it_flags |= O_CHECK_STALE;
rc = ll_intent_file_open(file, NULL, 0, it);
+ it->it_flags &= ~O_CHECK_STALE;
if (rc) {
ll_file_data_put(fd);
GOTO(out_och_free, rc);
req = it->d.lustre.it_data;
ptlrpc_req_finished(req);
}
- mdc_set_lock_data(&it->d.lustre.it_lock_handle,
- file->f_dentry->d_inode);
+ md_set_lock_data(ll_i2sbi(inode)->ll_md_exp,
+ &it->d.lustre.it_lock_handle,
+ file->f_dentry->d_inode);
}
req = it->d.lustre.it_data;
- /* mdc_intent_lock() didn't get a request ref if there was an
+ /* md_intent_lock() didn't get a request ref if there was an
* open error, so don't do cleanup on the request here
* (bug 3430) */
/* XXX (green): Should not we bail out on any error here, not
GOTO(out_och_free, rc);
}
- lprocfs_counter_incr(ll_i2sbi(inode)->ll_stats, LPROC_LL_OPEN);
+ ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_OPEN, 1);
rc = ll_local_open(file, it, fd, *och_p);
- LASSERTF(rc == 0, "rc = %d\n", rc);
+ if (rc) {
+ up(&lli->lli_och_sem);
+ ll_file_data_put(fd);
+ GOTO(out_och_free, rc);
+ }
}
up(&lli->lli_och_sem);
if (!S_ISREG(inode->i_mode))
GOTO(out, rc);
+ ll_capa_open(inode);
+
lsm = lli->lli_smd;
if (lsm == NULL) {
if (file->f_flags & O_LOV_DELAY_CREATE ||
}
file->f_flags &= ~O_LOV_DELAY_CREATE;
GOTO(out, rc);
- out:
+out:
ptlrpc_req_finished(req);
if (req)
it_clear_disposition(it, DISP_ENQ_OPEN_REF);
- if (rc == 0) {
- ll_open_complete(inode);
- } else {
out_och_free:
+ if (rc) {
if (*och_p) {
OBD_FREE(*och_p, sizeof (struct obd_client_handle));
*och_p = NULL; /* OBD_FREE writes some magic there */
}
up(&lli->lli_och_sem);
}
+
return rc;
}
/* Fills the obdo with the attributes for the inode defined by lsm */
-int ll_lsm_getattr(struct obd_export *exp, struct lov_stripe_md *lsm,
- struct obdo *oa)
+int ll_inode_getattr(struct inode *inode, struct obdo *obdo)
{
struct ptlrpc_request_set *set;
+ struct ll_inode_info *lli = ll_i2info(inode);
+ struct lov_stripe_md *lsm = lli->lli_smd;
+
struct obd_info oinfo = { { { 0 } } };
int rc;
ENTRY;
LASSERT(lsm != NULL);
- memset(oa, 0, sizeof *oa);
oinfo.oi_md = lsm;
- oinfo.oi_oa = oa;
- oa->o_id = lsm->lsm_object_id;
- oa->o_mode = S_IFREG;
- oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLSIZE |
- OBD_MD_FLBLOCKS | OBD_MD_FLBLKSZ | OBD_MD_FLMTIME |
- OBD_MD_FLCTIME;
+ oinfo.oi_oa = obdo;
+ oinfo.oi_oa->o_id = lsm->lsm_object_id;
+ oinfo.oi_oa->o_gr = lsm->lsm_object_gr;
+ oinfo.oi_oa->o_mode = S_IFREG;
+ oinfo.oi_oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE |
+ OBD_MD_FLSIZE | OBD_MD_FLBLOCKS |
+ OBD_MD_FLBLKSZ | OBD_MD_FLATIME |
+ OBD_MD_FLMTIME | OBD_MD_FLCTIME |
+ OBD_MD_FLGROUP;
+ oinfo.oi_capa = ll_mdscapa_get(inode);
set = ptlrpc_prep_set();
if (set == NULL) {
+ CERROR("can't allocate ptlrpc set\n");
rc = -ENOMEM;
} else {
- rc = obd_getattr_async(exp, &oinfo, set);
+ rc = obd_getattr_async(ll_i2dtexp(inode), &oinfo, set);
if (rc == 0)
rc = ptlrpc_set_wait(set);
ptlrpc_set_destroy(set);
}
+ capa_put(oinfo.oi_capa);
if (rc)
RETURN(rc);
- oa->o_valid &= (OBD_MD_FLBLOCKS | OBD_MD_FLBLKSZ | OBD_MD_FLMTIME |
- OBD_MD_FLCTIME | OBD_MD_FLSIZE);
+ oinfo.oi_oa->o_valid &= (OBD_MD_FLBLOCKS | OBD_MD_FLBLKSZ |
+ OBD_MD_FLATIME | OBD_MD_FLMTIME |
+ OBD_MD_FLCTIME | OBD_MD_FLSIZE);
+
+ obdo_refresh_inode(inode, oinfo.oi_oa, oinfo.oi_oa->o_valid);
+ CDEBUG(D_INODE, "objid "LPX64" size %Lu, blocks %lu, blksize %lu\n",
+ lli->lli_smd->lsm_object_id, i_size_read(inode),
+ inode->i_blocks, inode->i_blksize);
RETURN(0);
}
{
struct ll_inode_info *lli = ll_i2info(inode);
struct lov_stripe_md *lsm = lli->lli_smd;
- struct obd_export *exp = ll_i2obdexp(inode);
+ struct obd_export *exp = ll_i2dtexp(inode);
struct {
char name[16];
struct ldlm_lock *lock;
check:
if (lsm->lsm_oinfo[stripe]->loi_id != lock->l_resource->lr_name.name[0]||
- lsm->lsm_oinfo[stripe]->loi_gr != lock->l_resource->lr_name.name[1]){
+ lsm->lsm_oinfo[stripe]->loi_gr != lock->l_resource->lr_name.name[2]){
LDLM_ERROR(lock, "resource doesn't match object "LPU64"/"LPU64,
lsm->lsm_oinfo[stripe]->loi_id,
lsm->lsm_oinfo[stripe]->loi_gr);
struct page *page;
int rc, rc2, discard = lock->l_flags & LDLM_FL_DISCARD_DATA;
struct lustre_handle lockh;
- ENTRY;
+ struct address_space *mapping = inode->i_mapping;
- memcpy(&tmpex, &lock->l_policy_data, sizeof(tmpex));
+ ENTRY;
+ tmpex = lock->l_policy_data;
CDEBUG(D_INODE|D_PAGE, "inode %lu(%p) ["LPU64"->"LPU64"] size: %llu\n",
inode->i_ino, inode, tmpex.l_extent.start, tmpex.l_extent.end,
- inode->i_size);
+ i_size_read(inode));
/* our locks are page granular thanks to osc_enqueue, we invalidate the
* whole page. */
if ((tmpex.l_extent.start & ~CFS_PAGE_MASK) != 0 ||
((tmpex.l_extent.end + 1) & ~CFS_PAGE_MASK) != 0)
- LDLM_ERROR(lock, "lock not aligned on CFS_PAGE_SIZE %lu", CFS_PAGE_SIZE);
+ LDLM_ERROR(lock, "lock not aligned on PAGE_SIZE %lu",
+ CFS_PAGE_SIZE);
LASSERT((tmpex.l_extent.start & ~CFS_PAGE_MASK) == 0);
LASSERT(((tmpex.l_extent.end + 1) & ~CFS_PAGE_MASK) == 0);
if (end < tmpex.l_extent.end >> CFS_PAGE_SHIFT)
end = ~0;
- i = inode->i_size ? (inode->i_size - 1) >> CFS_PAGE_SHIFT : 0;
+ i = i_size_read(inode) ? (__u64)(i_size_read(inode) - 1) >>
+ CFS_PAGE_SHIFT : 0;
if (i < end)
end = i;
for (i = start; i <= end; i += (j + skip)) {
j = min(count - (i % count), end - i + 1);
LASSERT(j > 0);
- LASSERT(inode->i_mapping);
- if (ll_teardown_mmaps(inode->i_mapping,
+ LASSERT(mapping);
+ if (ll_teardown_mmaps(mapping,
(__u64)i << CFS_PAGE_SHIFT,
((__u64)(i+j) << CFS_PAGE_SHIFT) - 1) )
break;
tmpex.l_extent.start, lock->l_policy_data.l_extent.end,
start, i, end);
- if (!mapping_has_pages(inode->i_mapping)) {
+ if (!mapping_has_pages(mapping)) {
CDEBUG(D_INODE|D_PAGE, "nothing left\n");
break;
}
cond_resched();
- page = find_get_page(inode->i_mapping, i);
+ page = find_get_page(mapping, i);
if (page == NULL)
continue;
LL_CDEBUG_PAGE(D_PAGE, page, "lock page idx %lu ext "LPU64"\n",
/* page->mapping to check with racing against teardown */
if (!discard && clear_page_dirty_for_io(page)) {
rc = ll_call_writepage(inode, page);
- if (rc != 0)
- CERROR("writepage of page %p failed: %d\n",
- page, rc);
/* either waiting for io to complete or reacquiring
* the lock that the failed writepage released */
lock_page(page);
+ wait_on_page_writeback(page);
+ if (rc != 0) {
+ CERROR("writepage inode %lu(%p) of page %p "
+ "failed: %d\n", inode->i_ino, inode,
+ page, rc);
+ if (rc == -ENOSPC)
+ set_bit(AS_ENOSPC, &mapping->flags);
+ else
+ set_bit(AS_EIO, &mapping->flags);
+ }
}
tmpex.l_extent.end = tmpex.l_extent.start + CFS_PAGE_SIZE - 1;
- /* check to see if another DLM lock covers this page b=2765 */
+ /* check to see if another DLM lock covers this page b=2765 */
rc2 = ldlm_lock_match(lock->l_resource->lr_namespace,
LDLM_FL_BLOCK_GRANTED|LDLM_FL_CBPENDING |
LDLM_FL_TEST_LOCK,
&lock->l_resource->lr_name, LDLM_EXTENT,
&tmpex, LCK_PR | LCK_PW, &lockh);
- if (rc2 == 0 && page->mapping != NULL) {
+
+ if (rc2 <= 0 && page->mapping != NULL) {
struct ll_async_page *llap = llap_cast_private(page);
- // checking again to account for writeback's lock_page()
+ /* checking again to account for writeback's
+ * lock_page() */
LL_CDEBUG_PAGE(D_PAGE, page, "truncating\n");
if (llap)
- ll_ra_accounting(llap, inode->i_mapping);
+ ll_ra_accounting(llap, mapping);
ll_truncate_complete_page(page);
}
unlock_page(page);
lsm->lsm_oinfo[stripe]->loi_kms = kms;
unlock_res_and_lock(lock);
lov_stripe_unlock(lsm);
- //ll_try_done_writing(inode);
iput:
iput(inode);
break;
lvb = lock->l_lvb_data;
lsm->lsm_oinfo[stripe].loi_rss = lvb->lvb_size;
- LOCK_INODE_MUTEX(inode);
lock_res_and_lock(lock);
+ ll_inode_size_lock(inode, 1);
kms = MAX(lsm->lsm_oinfo[stripe].loi_kms, lvb->lvb_size);
kms = ldlm_extent_shift_kms(NULL, kms);
if (lsm->lsm_oinfo[stripe].loi_kms != kms)
LDLM_DEBUG(lock, "updating kms from "LPU64" to "LPU64,
lsm->lsm_oinfo[stripe].loi_kms, kms);
lsm->lsm_oinfo[stripe].loi_kms = kms;
+ ll_inode_size_unlock(inode, 1);
unlock_res_and_lock(lock);
- UNLOCK_INODE_MUTEX(inode);
}
iput:
LDLM_DEBUG(lock, "i_size: %llu -> stripe number %u -> kms "LPU64
" atime "LPU64", mtime "LPU64", ctime "LPU64,
- inode->i_size, stripe, lvb->lvb_size, lvb->lvb_mtime,
+ i_size_read(inode), stripe, lvb->lvb_size, lvb->lvb_mtime,
lvb->lvb_atime, lvb->lvb_ctime);
iput:
iput(inode);
return rc;
}
+static void ll_merge_lvb(struct inode *inode)
+{
+ struct ll_inode_info *lli = ll_i2info(inode);
+ struct ll_sb_info *sbi = ll_i2sbi(inode);
+ struct ost_lvb lvb;
+ ENTRY;
+
+ ll_inode_size_lock(inode, 1);
+ inode_init_lvb(inode, &lvb);
+ obd_merge_lvb(sbi->ll_dt_exp, lli->lli_smd, &lvb, 0);
+ i_size_write(inode, lvb.lvb_size);
+ inode->i_blocks = lvb.lvb_blocks;
+ LTIME_S(inode->i_mtime) = lvb.lvb_mtime;
+ LTIME_S(inode->i_atime) = lvb.lvb_atime;
+ LTIME_S(inode->i_ctime) = lvb.lvb_ctime;
+ ll_inode_size_unlock(inode, 1);
+ EXIT;
+}
+
+int ll_local_size(struct inode *inode)
+{
+ ldlm_policy_data_t policy = { .l_extent = { 0, OBD_OBJECT_EOF } };
+ struct ll_inode_info *lli = ll_i2info(inode);
+ struct ll_sb_info *sbi = ll_i2sbi(inode);
+ struct lustre_handle lockh = { 0 };
+ int flags = 0;
+ int rc;
+ ENTRY;
+
+ if (lli->lli_smd->lsm_stripe_count == 0)
+ RETURN(0);
+
+ rc = obd_match(sbi->ll_dt_exp, lli->lli_smd, LDLM_EXTENT,
+ &policy, LCK_PR | LCK_PW, &flags, inode, &lockh);
+ if (rc < 0)
+ RETURN(rc);
+ else if (rc == 0)
+ RETURN(-ENODATA);
+
+ ll_merge_lvb(inode);
+ obd_cancel(sbi->ll_dt_exp, lli->lli_smd, LCK_PR | LCK_PW, &lockh);
+ RETURN(0);
+}
+
int ll_glimpse_ioctl(struct ll_sb_info *sbi, struct lov_stripe_md *lsm,
lstat_t *st)
{
struct lustre_handle lockh = { 0 };
- struct obd_enqueue_info einfo = { 0 };
+ struct ldlm_enqueue_info einfo = { 0 };
struct obd_info oinfo = { { { 0 } } };
struct ost_lvb lvb;
int rc;
-
+
ENTRY;
-
+
einfo.ei_type = LDLM_EXTENT;
einfo.ei_mode = LCK_PR;
- einfo.ei_flags = LDLM_FL_HAS_INTENT;
einfo.ei_cb_bl = ll_extent_lock_callback;
einfo.ei_cb_cp = ldlm_completion_ast;
einfo.ei_cb_gl = ll_glimpse_callback;
oinfo.oi_policy.l_extent.end = OBD_OBJECT_EOF;
oinfo.oi_lockh = &lockh;
oinfo.oi_md = lsm;
+ oinfo.oi_flags = LDLM_FL_HAS_INTENT;
- rc = obd_enqueue_rqset(sbi->ll_osc_exp, &oinfo, &einfo);
+ rc = obd_enqueue_rqset(sbi->ll_dt_exp, &oinfo, &einfo);
if (rc == -ENOENT)
RETURN(rc);
if (rc != 0) {
"returning -EIO\n", rc);
RETURN(rc > 0 ? -EIO : rc);
}
-
+
lov_stripe_lock(lsm);
memset(&lvb, 0, sizeof(lvb));
- obd_merge_lvb(sbi->ll_osc_exp, lsm, &lvb, 0);
+ obd_merge_lvb(sbi->ll_dt_exp, lsm, &lvb, 0);
st->st_size = lvb.lvb_size;
st->st_blocks = lvb.lvb_blocks;
st->st_mtime = lvb.lvb_mtime;
st->st_atime = lvb.lvb_atime;
st->st_ctime = lvb.lvb_ctime;
lov_stripe_unlock(lsm);
-
+
RETURN(rc);
}
struct ll_inode_info *lli = ll_i2info(inode);
struct ll_sb_info *sbi = ll_i2sbi(inode);
struct lustre_handle lockh = { 0 };
- struct obd_enqueue_info einfo = { 0 };
+ struct ldlm_enqueue_info einfo = { 0 };
struct obd_info oinfo = { { { 0 } } };
- struct ost_lvb lvb;
int rc;
ENTRY;
+ if (lli->lli_flags & LLIF_MDS_SIZE_LOCK)
+ RETURN(0);
+
CDEBUG(D_DLMTRACE, "Glimpsing inode %lu\n", inode->i_ino);
if (!lli->lli_smd) {
* acquired only if there were no conflicting locks. */
einfo.ei_type = LDLM_EXTENT;
einfo.ei_mode = LCK_PR;
- einfo.ei_flags = ast_flags | LDLM_FL_HAS_INTENT;
einfo.ei_cb_bl = ll_extent_lock_callback;
einfo.ei_cb_cp = ldlm_completion_ast;
einfo.ei_cb_gl = ll_glimpse_callback;
oinfo.oi_policy.l_extent.end = OBD_OBJECT_EOF;
oinfo.oi_lockh = &lockh;
oinfo.oi_md = lli->lli_smd;
+ oinfo.oi_flags = ast_flags | LDLM_FL_HAS_INTENT;
- rc = obd_enqueue_rqset(sbi->ll_osc_exp, &oinfo, &einfo);
+ rc = obd_enqueue_rqset(sbi->ll_dt_exp, &oinfo, &einfo);
if (rc == -ENOENT)
RETURN(rc);
if (rc != 0) {
RETURN(rc > 0 ? -EIO : rc);
}
- ll_inode_size_lock(inode, 1);
- inode_init_lvb(inode, &lvb);
- obd_merge_lvb(sbi->ll_osc_exp, lli->lli_smd, &lvb, 0);
- inode->i_size = lvb.lvb_size;
- inode->i_blocks = lvb.lvb_blocks;
- LTIME_S(inode->i_mtime) = lvb.lvb_mtime;
- LTIME_S(inode->i_atime) = lvb.lvb_atime;
- LTIME_S(inode->i_ctime) = lvb.lvb_ctime;
- ll_inode_size_unlock(inode, 1);
+ ll_merge_lvb(inode);
CDEBUG(D_DLMTRACE, "glimpse: size: %llu, blocks: %lu\n",
- inode->i_size, inode->i_blocks);
+ i_size_read(inode), inode->i_blocks);
RETURN(rc);
}
{
struct ll_sb_info *sbi = ll_i2sbi(inode);
struct ost_lvb lvb;
- struct obd_enqueue_info einfo = { 0 };
+ struct ldlm_enqueue_info einfo = { 0 };
struct obd_info oinfo = { { { 0 } } };
int rc;
ENTRY;
einfo.ei_type = LDLM_EXTENT;
einfo.ei_mode = mode;
- einfo.ei_flags = ast_flags;
einfo.ei_cb_bl = ll_extent_lock_callback;
einfo.ei_cb_cp = ldlm_completion_ast;
einfo.ei_cb_gl = ll_glimpse_callback;
oinfo.oi_policy = *policy;
oinfo.oi_lockh = lockh;
oinfo.oi_md = lsm;
+ oinfo.oi_flags = ast_flags;
- rc = obd_enqueue(sbi->ll_osc_exp, &oinfo, &einfo);
+ rc = obd_enqueue(sbi->ll_dt_exp, &oinfo, &einfo, NULL);
*policy = oinfo.oi_policy;
if (rc > 0)
rc = -EIO;
ll_inode_size_lock(inode, 1);
inode_init_lvb(inode, &lvb);
- obd_merge_lvb(sbi->ll_osc_exp, lsm, &lvb, 1);
+ obd_merge_lvb(sbi->ll_dt_exp, lsm, &lvb, 1);
if (policy->l_extent.start == 0 &&
policy->l_extent.end == OBD_OBJECT_EOF) {
* cancel the result of the truncate. Getting the
* ll_inode_size_lock() after the enqueue maintains the DLM
* -> ll_inode_size_lock() acquiring order. */
- inode->i_size = lvb.lvb_size;
+ i_size_write(inode, lvb.lvb_size);
CDEBUG(D_INODE, "inode=%lu, updating i_size %llu\n",
- inode->i_ino, inode->i_size);
+ inode->i_ino, i_size_read(inode));
}
if (rc == 0) {
(sbi->ll_flags & LL_SBI_NOLCK))
RETURN(0);
- rc = obd_cancel(sbi->ll_osc_exp, lsm, mode, lockh);
+ rc = obd_cancel(sbi->ll_dt_exp, lsm, mode, lockh);
RETURN(rc);
}
ENTRY;
CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p),size="LPSZ",offset=%Ld\n",
inode->i_ino, inode->i_generation, inode, count, *ppos);
- ll_vfs_ops_tally(sbi, VFS_OPS_READ);
-
/* "If nbyte is 0, read() will return 0 and have no other results."
* -- Single Unix Spec */
if (count == 0)
RETURN(0);
- lprocfs_counter_add(sbi->ll_stats, LPROC_LL_READ_BYTES, count);
+ ll_stats_ops_tally(sbi, LPROC_LL_READ_BYTES, count);
if (!lsm) {
/* Read on file with no objects should return zero-filled
* unguarded */
/* Read beyond end of file */
- if (*ppos >= inode->i_size)
+ if (*ppos >= i_size_read(inode))
RETURN(0);
- if (count > inode->i_size - *ppos)
- count = inode->i_size - *ppos;
+ if (count > i_size_read(inode) - *ppos)
+ count = i_size_read(inode) - *ppos;
/* Make sure to correctly adjust the file pos pointer for
* EFAULT case */
notzeroed = clear_user(buf, count);
if (sbi->ll_max_rw_chunk != 0) {
/* first, let's know the end of the current stripe */
end = *ppos;
- obd_extent_calc(sbi->ll_osc_exp, lsm, OBD_CALC_STRIPE_END,
+ obd_extent_calc(sbi->ll_dt_exp, lsm, OBD_CALC_STRIPE_END,
(obd_off *)&end);
/* correct, the end is beyond the request */
} else {
end = *ppos + count - 1;
}
-
+
node = ll_node_from_inode(inode, *ppos, end, LCK_PR);
+ if (IS_ERR(node)){
+ GOTO(out, retval = PTR_ERR(node));
+ }
+
tree.lt_fd = LUSTRE_FPRIVATE(file);
rc = ll_tree_lock(&tree, node, buf, count,
file->f_flags & O_NONBLOCK ? LDLM_FL_BLOCK_NOWAIT :0);
* correctly in the face of concurrent writes and truncates.
*/
inode_init_lvb(inode, &lvb);
- obd_merge_lvb(ll_i2sbi(inode)->ll_osc_exp, lsm, &lvb, 1);
+ obd_merge_lvb(sbi->ll_dt_exp, lsm, &lvb, 1);
kms = lvb.lvb_size;
if (*ppos + count - 1 > kms) {
/* A glimpse is necessary to determine whether we return a
* the kms size is _correct_, it is only the _minimum_ size.
* If someone does a stat they will get the correct size which
* will always be >= the kms value here. b=11081 */
- if (inode->i_size < kms)
- inode->i_size = kms;
+ if (i_size_read(inode) < kms)
+ i_size_write(inode, kms);
ll_inode_size_unlock(inode, 1);
}
chunk = end - *ppos + 1;
- CDEBUG(D_INODE,"Read ino %lu, "LPSZ" bytes, offset %lld, i_size %llu\n",
- inode->i_ino, chunk, *ppos, inode->i_size);
+ CDEBUG(D_INODE, "Read ino %lu, "LPSZ" bytes, offset %lld, i_size %llu\n",
+ inode->i_ino, chunk, *ppos, i_size_read(inode));
/* turn off the kernel's read-ahead */
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
- file->f_ramax = 0;
-#else
file->f_ra.ra_pages = 0;
-#endif
+
/* initialize read-ahead window once per syscall */
if (ra == 0) {
ra = 1;
/* BUG: 5972 */
file_accessed(file);
retval = generic_file_read(file, buf, chunk, ppos);
- ll_rw_stats_tally(ll_i2sbi(inode), current->pid, file, count, 0);
+ ll_rw_stats_tally(sbi, current->pid, file, count, 0);
ll_tree_unlock(&tree);
CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p),size="LPSZ",offset=%Ld\n",
inode->i_ino, inode->i_generation, inode, count, *ppos);
- ll_vfs_ops_tally(sbi, VFS_OPS_WRITE);
-
+
SIGNAL_MASK_ASSERT(); /* XXX BUG 1511 */
/* POSIX, but surprised the VFS doesn't check this already */
} else if (sbi->ll_max_rw_chunk != 0) {
/* first, let's know the end of the current stripe */
end = *ppos;
- obd_extent_calc(sbi->ll_osc_exp, lsm, OBD_CALC_STRIPE_END,
+ obd_extent_calc(sbi->ll_dt_exp, lsm, OBD_CALC_STRIPE_END,
(obd_off *)&end);
/* correct, the end is beyond the request */
* The i_size value gets updated in ll_extent_lock() as a consequence
* of the [0,EOF] extent lock we requested above. */
if (file->f_flags & O_APPEND) {
- *ppos = inode->i_size;
+ *ppos = i_size_read(inode);
end = *ppos + count - 1;
}
if (*ppos >= maxbytes) {
send_sig(SIGXFSZ, current, 0);
- GOTO(out, retval = -EFBIG);
+ GOTO(out_unlock, retval = -EFBIG);
}
if (*ppos + count > maxbytes)
count = maxbytes - *ppos;
retval = generic_file_write(file, buf, chunk, ppos);
ll_rw_stats_tally(ll_i2sbi(inode), current->pid, file, count, 1);
-out:
+out_unlock:
ll_tree_unlock(&tree);
+out:
if (retval > 0) {
buf += retval;
count -= retval;
up(&ll_i2info(inode)->lli_write_sem);
retval = (sum > 0) ? sum : retval;
- lprocfs_counter_add(ll_i2sbi(inode)->ll_stats, LPROC_LL_WRITE_BYTES,
- retval > 0 ? retval : 0);
+ ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_WRITE_BYTES,
+ retval > 0 ? retval : 0);
RETURN(retval);
}
/*
* Send file content (through pagecache) somewhere with helper
*/
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
static ssize_t ll_file_sendfile(struct file *in_file, loff_t *ppos,size_t count,
read_actor_t actor, void *target)
{
if (count == 0)
RETURN(0);
- lprocfs_counter_add(ll_i2sbi(inode)->ll_stats, LPROC_LL_READ_BYTES,
- count);
-
+ ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_READ_BYTES, count);
/* turn off the kernel's read-ahead */
in_file->f_ra.ra_pages = 0;
RETURN(generic_file_sendfile(in_file, ppos, count, actor, target));
node = ll_node_from_inode(inode, *ppos, *ppos + count - 1, LCK_PR);
+ if (IS_ERR(node))
+ RETURN(PTR_ERR(node));
+
tree.lt_fd = LUSTRE_FPRIVATE(in_file);
rc = ll_tree_lock(&tree, node, NULL, count,
in_file->f_flags & O_NONBLOCK?LDLM_FL_BLOCK_NOWAIT:0);
* correctly in the face of concurrent writes and truncates.
*/
inode_init_lvb(inode, &lvb);
- obd_merge_lvb(ll_i2sbi(inode)->ll_osc_exp, lsm, &lvb, 1);
+ obd_merge_lvb(ll_i2sbi(inode)->ll_dt_exp, lsm, &lvb, 1);
kms = lvb.lvb_size;
if (*ppos + count - 1 > kms) {
/* A glimpse is necessary to determine whether we return a
goto out;
} else {
/* region is within kms and, hence, within real file size (A) */
- inode->i_size = kms;
+ i_size_write(inode, kms);
ll_inode_size_unlock(inode, 1);
}
CDEBUG(D_INFO, "Send ino %lu, "LPSZ" bytes, offset %lld, i_size %llu\n",
- inode->i_ino, count, *ppos, inode->i_size);
+ inode->i_ino, count, *ppos, i_size_read(inode));
bead.lrr_start = *ppos >> CFS_PAGE_SHIFT;
bead.lrr_count = (count + CFS_PAGE_SIZE - 1) >> CFS_PAGE_SHIFT;
ll_tree_unlock(&tree);
RETURN(retval);
}
-#endif
static int ll_lov_recreate_obj(struct inode *inode, struct file *file,
unsigned long arg)
{
struct ll_inode_info *lli = ll_i2info(inode);
- struct obd_export *exp = ll_i2obdexp(inode);
+ struct obd_export *exp = ll_i2dtexp(inode);
struct ll_recreate_obj ucreatp;
struct obd_trans_info oti = { 0 };
struct obdo *oa = NULL;
if (rc) {
RETURN(-EFAULT);
}
- oa = obdo_alloc();
+ OBDO_ALLOC(oa);
if (oa == NULL)
RETURN(-ENOMEM);
- down(&lli->lli_open_sem);
+ down(&lli->lli_size_sem);
lsm = lli->lli_smd;
if (lsm == NULL)
GOTO(out, rc = -ENOENT);
GOTO(out, rc = -ENOMEM);
oa->o_id = ucreatp.lrc_id;
+ oa->o_gr = ucreatp.lrc_group;
oa->o_nlink = ucreatp.lrc_ost_idx;
oa->o_flags |= OBD_FL_RECREATE_OBJS;
- oa->o_valid = OBD_MD_FLID | OBD_MD_FLFLAGS;
+ oa->o_valid = OBD_MD_FLID | OBD_MD_FLFLAGS | OBD_MD_FLGROUP;
obdo_from_inode(oa, inode, OBD_MD_FLTYPE | OBD_MD_FLATIME |
OBD_MD_FLMTIME | OBD_MD_FLCTIME);
OBD_FREE(lsm2, lsm_size);
GOTO(out, rc);
out:
- up(&lli->lli_open_sem);
- obdo_free(oa);
+ up(&lli->lli_size_sem);
+ OBDO_FREE(oa);
return rc;
}
int ll_lov_setstripe_ea_info(struct inode *inode, struct file *file,
- int flags, struct lov_user_md *lum,
- int lum_size)
+ int flags, struct lov_user_md *lum, int lum_size)
{
struct ll_inode_info *lli = ll_i2info(inode);
struct lov_stripe_md *lsm;
int rc = 0;
ENTRY;
- down(&lli->lli_open_sem);
+ down(&lli->lli_size_sem);
lsm = lli->lli_smd;
if (lsm) {
- up(&lli->lli_open_sem);
+ up(&lli->lli_size_sem);
CDEBUG(D_IOCTL, "stripe already exists for ino %lu\n",
inode->i_ino);
RETURN(-EEXIST);
ll_release_openhandle(file->f_dentry, &oit);
out:
- up(&lli->lli_open_sem);
+ up(&lli->lli_size_sem);
ll_intent_release(&oit);
RETURN(rc);
out_req_free:
struct ptlrpc_request **request)
{
struct ll_sb_info *sbi = ll_i2sbi(inode);
- struct ll_fid fid;
- struct mds_body *body;
+ struct mdt_body *body;
struct lov_mds_md *lmm = NULL;
struct ptlrpc_request *req = NULL;
+ struct obd_capa *oc;
int rc, lmmsize;
- ll_inode2fid(&fid, inode);
-
rc = ll_get_max_mdsize(sbi, &lmmsize);
if (rc)
RETURN(rc);
- rc = mdc_getattr_name(sbi->ll_mdc_exp, &fid,
- filename, strlen(filename) + 1,
- OBD_MD_FLEASIZE | OBD_MD_FLDIREA,
- lmmsize, &req);
+ oc = ll_mdscapa_get(inode);
+ rc = md_getattr_name(sbi->ll_md_exp, ll_inode2fid(inode),
+ oc, filename, strlen(filename) + 1,
+ OBD_MD_FLEASIZE | OBD_MD_FLDIREA, lmmsize, &req);
+ capa_put(oc);
if (rc < 0) {
- CDEBUG(D_INFO, "mdc_getattr_name failed "
- "on %s: rc %d\n", filename, rc);
+ CDEBUG(D_INFO, "md_getattr_name failed "
+ "on %s: rc %d\n", filename, rc);
GOTO(out, rc);
}
- body = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF,
- sizeof(*body));
+ body = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF, sizeof(*body));
LASSERT(body != NULL); /* checked by mdc_getattr_name */
/* swabbed by mdc_getattr_name */
LASSERT_REPSWABBED(req, REPLY_REC_OFF);
GOTO(out, rc = -ENODATA);
}
- lmm = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF + 1,
- lmmsize);
+ lmm = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF + 1, lmmsize);
LASSERT(lmm != NULL);
LASSERT_REPSWABBED(req, REPLY_REC_OFF + 1);
struct lov_user_md_join *lmj;
int lmj_size, i, aindex = 0;
- rc = obd_unpackmd(sbi->ll_osc_exp, &lsm, lmm, lmmsize);
+ rc = obd_unpackmd(sbi->ll_dt_exp, &lsm, lmm, lmmsize);
if (rc < 0)
GOTO(out, rc = -ENOMEM);
- rc = obd_checkmd(sbi->ll_osc_exp, sbi->ll_mdc_exp, lsm);
+ rc = obd_checkmd(sbi->ll_dt_exp, sbi->ll_md_exp, lsm);
if (rc)
GOTO(out_free_memmd, rc);
lmj_size = sizeof(struct lov_user_md_join) +
- lsm->lsm_stripe_count *
- sizeof(struct lov_user_ost_data_join);
+ lsm->lsm_stripe_count *
+ sizeof(struct lov_user_ost_data_join);
OBD_ALLOC(lmj, lmj_size);
if (!lmj)
GOTO(out_free_memmd, rc = -ENOMEM);
lmm = (struct lov_mds_md *)lmj;
lmmsize = lmj_size;
out_free_memmd:
- obd_free_memmd(sbi->ll_osc_exp, &lsm);
+ obd_free_memmd(sbi->ll_dt_exp, &lsm);
}
out:
*lmmp = lmm;
*request = req;
return rc;
}
+
static int ll_lov_setea(struct inode *inode, struct file *file,
unsigned long arg)
{
rc = ll_lov_setstripe_ea_info(inode, file, flags, &lum, sizeof(lum));
if (rc == 0) {
put_user(0, &lump->lmm_stripe_count);
- rc = obd_iocontrol(LL_IOC_LOV_GETSTRIPE, ll_i2obdexp(inode),
+ rc = obd_iocontrol(LL_IOC_LOV_GETSTRIPE, ll_i2dtexp(inode),
0, ll_i2info(inode)->lli_smd, lump);
}
RETURN(rc);
if (!lsm)
RETURN(-ENODATA);
- return obd_iocontrol(LL_IOC_LOV_GETSTRIPE, ll_i2obdexp(inode), 0, lsm,
+ return obd_iocontrol(LL_IOC_LOV_GETSTRIPE, ll_i2dtexp(inode), 0, lsm,
(void *)arg);
}
CERROR("file %lu can not be joined to itself \n", head->i_ino);
RETURN(-EINVAL);
}
- if (head->i_size % JOIN_FILE_ALIGN) {
- CERROR("hsize %llu must be times of 64K\n", head->i_size);
+ if (i_size_read(head) % JOIN_FILE_ALIGN) {
+ CERROR("hsize %llu must be times of 64K\n", i_size_read(head));
RETURN(-EINVAL);
}
RETURN(0);
static int join_file(struct inode *head_inode, struct file *head_filp,
struct file *tail_filp)
{
- struct inode *tail_inode, *tail_parent;
struct dentry *tail_dentry = tail_filp->f_dentry;
struct lookup_intent oit = {.it_op = IT_OPEN,
.it_flags = head_filp->f_flags|O_JOIN_FILE};
+ struct ldlm_enqueue_info einfo = { LDLM_IBITS, LCK_CW,
+ ll_md_blocking_ast, ldlm_completion_ast, NULL, NULL };
+
struct lustre_handle lockh;
- struct mdc_op_data *op_data;
- __u32 hsize = head_inode->i_size >> 32;
- __u32 tsize = head_inode->i_size;
+ struct md_op_data *op_data;
int rc;
+ loff_t data;
ENTRY;
tail_dentry = tail_filp->f_dentry;
- tail_inode = tail_dentry->d_inode;
- tail_parent = tail_dentry->d_parent->d_inode;
- OBD_ALLOC_PTR(op_data);
- if (op_data == NULL) {
- RETURN(-ENOMEM);
- }
+ data = i_size_read(head_inode);
+ op_data = ll_prep_md_op_data(NULL, head_inode,
+ tail_dentry->d_parent->d_inode,
+ tail_dentry->d_name.name,
+ tail_dentry->d_name.len, 0,
+ LUSTRE_OPC_ANY, &data);
+ if (IS_ERR(op_data))
+ RETURN(PTR_ERR(op_data));
- ll_prepare_mdc_op_data(op_data, head_inode, tail_parent,
- tail_dentry->d_name.name,
- tail_dentry->d_name.len, 0);
- rc = mdc_enqueue(ll_i2mdcexp(head_inode), LDLM_IBITS, &oit, LCK_PW,
- op_data, &lockh, &tsize, 0, ldlm_completion_ast,
- ll_mdc_blocking_ast, &hsize, 0);
+ rc = md_enqueue(ll_i2mdexp(head_inode), &einfo, &oit,
+ op_data, &lockh, NULL, 0, 0);
+ ll_finish_md_op_data(op_data);
if (rc < 0)
GOTO(out, rc);
rc = oit.d.lustre.it_status;
- if (rc < 0) {
+ if (rc < 0 || it_open_error(DISP_OPEN_OPEN, &oit)) {
+ rc = rc ? rc : it_open_error(DISP_OPEN_OPEN, &oit);
ptlrpc_req_finished((struct ptlrpc_request *)
- oit.d.lustre.it_data);
+ oit.d.lustre.it_data);
GOTO(out, rc);
}
}
ll_release_openhandle(head_filp->f_dentry, &oit);
out:
- if (op_data)
- OBD_FREE_PTR(op_data);
ll_intent_release(&oit);
RETURN(rc);
}
switch (cleanup_phase) {
case 3:
ll_tree_unlock(&second_tree);
- obd_cancel_unused(ll_i2obdexp(second),
+ obd_cancel_unused(ll_i2dtexp(second),
ll_i2info(second)->lli_smd, 0, NULL);
case 2:
ll_tree_unlock(&first_tree);
- obd_cancel_unused(ll_i2obdexp(first),
+ obd_cancel_unused(ll_i2dtexp(first),
ll_i2info(first)->lli_smd, 0, NULL);
case 1:
filp_close(tail_filp, 0);
if (tail)
iput(tail);
if (head && rc == 0) {
- obd_free_memmd(ll_i2sbi(head)->ll_osc_exp,
+ obd_free_memmd(ll_i2sbi(head)->ll_dt_exp,
&hlli->lli_smd);
hlli->lli_smd = NULL;
}
if (!it_disposition(it, DISP_OPEN_OPEN))
RETURN(0);
+ LASSERT(it_open_error(DISP_OPEN_OPEN, it) == 0);
+
OBD_ALLOC(och, sizeof(*och));
if (!och)
GOTO(out, rc = -ENOMEM);
- ll_och_fill(ll_i2info(inode), it, och);
-
- rc = ll_close_inode_openhandle(inode, och);
+ ll_och_fill(ll_i2sbi(inode)->ll_md_exp,
+ ll_i2info(inode), it, och);
- OBD_FREE(och, sizeof(*och));
+ rc = ll_close_inode_openhandle(ll_i2sbi(inode)->ll_md_exp,
+ inode, och);
out:
/* this one is in place of ll_file_open */
ptlrpc_req_finished(it->d.lustre.it_data);
CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p),cmd=%x\n", inode->i_ino,
inode->i_generation, inode, cmd);
- ll_vfs_ops_tally(ll_i2sbi(inode), VFS_OPS_IOCTL);
+ ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_IOCTL, 1);
/* asm-ppc{,64} declares TCGETS, et. al. as type 't' not 'T' */
if (_IOC_TYPE(cmd) == 'T' || _IOC_TYPE(cmd) == 't') /* tty ioctls */
RETURN(-ENOTTY);
- lprocfs_counter_incr(ll_i2sbi(inode)->ll_stats, LPROC_LL_IOCTL);
switch(cmd) {
case LL_IOC_GETFLAGS:
/* Get the current value of the file flags */
case EXT3_IOC_SETVERSION_OLD:
case EXT3_IOC_SETVERSION:
*/
- default:
- RETURN(obd_iocontrol(cmd, ll_i2obdexp(inode), 0, NULL,
+ case LL_IOC_FLUSHCTX:
+ RETURN(ll_flush_ctx(inode));
+ case LL_IOC_GETFACL: {
+ struct rmtacl_ioctl_data ioc;
+
+ if (copy_from_user(&ioc, (void *)arg, sizeof(ioc)))
+ RETURN(-EFAULT);
+
+ RETURN(ll_ioctl_getfacl(inode, &ioc));
+ }
+ case LL_IOC_SETFACL: {
+ struct rmtacl_ioctl_data ioc;
+
+ if (copy_from_user(&ioc, (void *)arg, sizeof(ioc)))
+ RETURN(-EFAULT);
+
+ RETURN(ll_ioctl_setfacl(inode, &ioc));
+ }
+ default: {
+ int err;
+
+ if (LLIOC_STOP ==
+ ll_iocontrol_call(inode, file, cmd, arg, &err))
+ RETURN(err);
+
+ RETURN(obd_iocontrol(cmd, ll_i2dtexp(inode), 0, NULL,
(void *)arg));
}
+ }
}
loff_t ll_file_seek(struct file *file, loff_t offset, int origin)
struct lov_stripe_md *lsm = lli->lli_smd;
loff_t retval;
ENTRY;
- retval = offset + ((origin == 2) ? inode->i_size :
+ retval = offset + ((origin == 2) ? i_size_read(inode) :
(origin == 1) ? file->f_pos : 0);
CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), to=%Lu=%#Lx(%s)\n",
inode->i_ino, inode->i_generation, inode, retval, retval,
origin == 2 ? "SEEK_END": origin == 1 ? "SEEK_CUR" : "SEEK_SET");
- ll_vfs_ops_tally(ll_i2sbi(inode), VFS_OPS_SEEK);
- lprocfs_counter_incr(ll_i2sbi(inode)->ll_stats, LPROC_LL_LLSEEK);
-
+ ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_LLSEEK, 1);
+
if (origin == 2) { /* SEEK_END */
int nonblock = 0, rc;
}
ll_inode_size_lock(inode, 0);
- offset += inode->i_size;
+ offset += i_size_read(inode);
ll_inode_size_unlock(inode, 0);
} else if (origin == 1) { /* SEEK_CUR */
offset += file->f_pos;
}
retval = offset;
}
-
+
RETURN(retval);
}
struct inode *inode = dentry->d_inode;
struct ll_inode_info *lli = ll_i2info(inode);
struct lov_stripe_md *lsm = lli->lli_smd;
- struct ll_fid fid;
struct ptlrpc_request *req;
+ struct obd_capa *oc;
int rc, err;
ENTRY;
CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n", inode->i_ino,
inode->i_generation, inode);
- ll_vfs_ops_tally(ll_i2sbi(inode), VFS_OPS_FSYNC);
- lprocfs_counter_incr(ll_i2sbi(inode)->ll_stats, LPROC_LL_FSYNC);
+ ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_FSYNC, 1);
/* fsync's caller has already called _fdata{sync,write}, we want
* that IO to finish before calling the osc and mdc sync methods */
rc = err;
}
- ll_inode2fid(&fid, inode);
- err = mdc_sync(ll_i2sbi(inode)->ll_mdc_exp, &fid, &req);
+ oc = ll_mdscapa_get(inode);
+ err = md_sync(ll_i2sbi(inode)->ll_md_exp, ll_inode2fid(inode), oc,
+ &req);
+ capa_put(oc);
if (!rc)
rc = err;
if (!err)
ptlrpc_req_finished(req);
if (data && lsm) {
- struct obdo *oa = obdo_alloc();
-
+ struct obdo *oa;
+
+ OBDO_ALLOC(oa);
if (!oa)
RETURN(rc ? rc : -ENOMEM);
oa->o_id = lsm->lsm_object_id;
- oa->o_valid = OBD_MD_FLID;
+ oa->o_gr = lsm->lsm_object_gr;
+ oa->o_valid = OBD_MD_FLID | OBD_MD_FLGROUP;
obdo_from_inode(oa, inode, OBD_MD_FLTYPE | OBD_MD_FLATIME |
- OBD_MD_FLMTIME | OBD_MD_FLCTIME);
+ OBD_MD_FLMTIME | OBD_MD_FLCTIME |
+ OBD_MD_FLGROUP);
- err = obd_sync(ll_i2sbi(inode)->ll_osc_exp, oa, lsm,
- 0, OBD_OBJECT_EOF);
+ oc = ll_osscapa_get(inode, CAPA_OPC_OSS_WRITE);
+ err = obd_sync(ll_i2sbi(inode)->ll_dt_exp, oa, lsm,
+ 0, OBD_OBJECT_EOF, oc);
+ capa_put(oc);
if (!rc)
rc = err;
- obdo_free(oa);
+ OBDO_FREE(oa);
}
RETURN(rc);
struct inode *inode = file->f_dentry->d_inode;
struct ll_sb_info *sbi = ll_i2sbi(inode);
struct ldlm_res_id res_id =
- { .name = {inode->i_ino, inode->i_generation, LDLM_FLOCK} };
+ { .name = { fid_seq(ll_inode2fid(inode)),
+ fid_oid(ll_inode2fid(inode)),
+ fid_ver(ll_inode2fid(inode)),
+ LDLM_FLOCK} };
+ struct ldlm_enqueue_info einfo = { LDLM_FLOCK, 0, NULL,
+ ldlm_flock_completion_ast, NULL, file_lock };
struct lustre_handle lockh = {0};
ldlm_policy_data_t flock;
- ldlm_mode_t mode = 0;
int flags = 0;
int rc;
ENTRY;
CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu file_lock=%p\n",
inode->i_ino, file_lock);
- ll_vfs_ops_tally(ll_i2sbi(inode), VFS_OPS_FLOCK);
+ ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_FLOCK, 1);
+
if (file_lock->fl_flags & FL_FLOCK) {
LASSERT((cmd == F_SETLKW) || (cmd == F_SETLK));
/* set missing params for flock() calls */
switch (file_lock->fl_type) {
case F_RDLCK:
- mode = LCK_PR;
+ einfo.ei_mode = LCK_PR;
break;
case F_UNLCK:
/* An unlock request may or may not have any relation to
* information that is given with a normal read or write record
* lock request. To avoid creating another ldlm unlock (cancel)
* message we'll treat a LCK_NL flock request as an unlock. */
- mode = LCK_NL;
+ einfo.ei_mode = LCK_NL;
break;
case F_WRLCK:
- mode = LCK_PW;
+ einfo.ei_mode = LCK_PW;
break;
default:
CERROR("unknown fcntl lock type: %d\n", file_lock->fl_type);
flags = LDLM_FL_TEST_LOCK;
/* Save the old mode so that if the mode in the lock changes we
* can decrement the appropriate reader or writer refcount. */
- file_lock->fl_type = mode;
+ file_lock->fl_type = einfo.ei_mode;
break;
default:
CERROR("unknown fcntl lock command: %d\n", cmd);
CDEBUG(D_DLMTRACE, "inode=%lu, pid=%u, flags=%#x, mode=%u, "
"start="LPU64", end="LPU64"\n", inode->i_ino, flock.l_flock.pid,
- flags, mode, flock.l_flock.start, flock.l_flock.end);
+ flags, einfo.ei_mode, flock.l_flock.start, flock.l_flock.end);
- rc = ldlm_cli_enqueue(sbi->ll_mdc_exp, NULL, res_id,
- LDLM_FLOCK, &flock, mode, &flags, NULL,
- ldlm_flock_completion_ast, NULL, file_lock,
- NULL, 0, NULL, &lockh, 0);
+ rc = ldlm_cli_enqueue(sbi->ll_md_exp, NULL, &einfo, &res_id,
+ &flock, &flags, NULL, 0, NULL, &lockh, 0);
if ((file_lock->fl_flags & FL_FLOCK) && (rc == 0))
ll_flock_lock_file_wait(file, file_lock, (cmd == F_SETLKW));
#ifdef HAVE_F_OP_FLOCK
int ll_have_md_lock(struct inode *inode, __u64 bits)
{
struct lustre_handle lockh;
- struct ldlm_res_id res_id = { .name = {0} };
- struct obd_device *obddev;
ldlm_policy_data_t policy = { .l_inodebits = {bits}};
+ struct lu_fid *fid;
int flags;
ENTRY;
if (!inode)
RETURN(0);
- obddev = ll_i2mdcexp(inode)->exp_obd;
- res_id.name[0] = inode->i_ino;
- res_id.name[1] = inode->i_generation;
-
- CDEBUG(D_INFO, "trying to match res "LPU64"\n", res_id.name[0]);
+ fid = &ll_i2info(inode)->lli_fid;
+ CDEBUG(D_INFO, "trying to match res "DFID"\n", PFID(fid));
flags = LDLM_FL_BLOCK_GRANTED | LDLM_FL_CBPENDING | LDLM_FL_TEST_LOCK;
- if (ldlm_lock_match(obddev->obd_namespace, flags, &res_id, LDLM_IBITS,
- &policy, LCK_CR|LCK_CW|LCK_PR, &lockh)) {
+ if (md_lock_match(ll_i2mdexp(inode), flags, fid, LDLM_IBITS, &policy,
+ LCK_CR|LCK_CW|LCK_PR, &lockh)) {
RETURN(1);
}
{
struct inode *inode = dentry->d_inode;
struct ptlrpc_request *req = NULL;
+ struct ll_sb_info *sbi;
struct obd_export *exp;
int rc;
ENTRY;
CERROR("REPORT THIS LINE TO PETER\n");
RETURN(0);
}
+ sbi = ll_i2sbi(inode);
+
CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p),name=%s\n",
inode->i_ino, inode->i_generation, inode, dentry->d_name.name);
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0))
- lprocfs_counter_incr(ll_i2sbi(inode)->ll_stats, LPROC_LL_REVALIDATE);
-#endif
- exp = ll_i2mdcexp(inode);
+ exp = ll_i2mdexp(inode);
if (exp->exp_connect_flags & OBD_CONNECT_ATTRFID) {
struct lookup_intent oit = { .it_op = IT_GETATTR };
- struct mdc_op_data op_data;
+ struct md_op_data *op_data;
/* Call getattr by fid, so do not provide name at all. */
- ll_prepare_mdc_op_data(&op_data, dentry->d_parent->d_inode,
- dentry->d_inode, NULL, 0, 0);
- rc = mdc_intent_lock(exp, &op_data, NULL, 0,
- /* we are not interested in name
- based lookup */
- &oit, 0, &req,
- ll_mdc_blocking_ast, 0);
+ op_data = ll_prep_md_op_data(NULL, dentry->d_parent->d_inode,
+ dentry->d_inode, NULL, 0, 0,
+ LUSTRE_OPC_ANY, NULL);
+ if (IS_ERR(op_data))
+ RETURN(PTR_ERR(op_data));
+
+ oit.it_flags |= O_CHECK_STALE;
+ rc = md_intent_lock(exp, op_data, NULL, 0,
+ /* we are not interested in name
+ based lookup */
+ &oit, 0, &req,
+ ll_md_blocking_ast, 0);
+ ll_finish_md_op_data(op_data);
+ oit.it_flags &= ~O_CHECK_STALE;
if (rc < 0) {
rc = ll_inode_revalidate_fini(inode, rc);
GOTO (out, rc);
}
-
- rc = revalidate_it_finish(req, DLM_REPLY_REC_OFF, &oit, dentry);
+
+ rc = ll_revalidate_it_finish(req, DLM_REPLY_REC_OFF, &oit, dentry);
if (rc != 0) {
ll_intent_release(&oit);
GOTO(out, rc);
ll_lookup_finish_locks(&oit, dentry);
} else if (!ll_have_md_lock(dentry->d_inode,
- MDS_INODELOCK_UPDATE|MDS_INODELOCK_LOOKUP)) {
+ MDS_INODELOCK_UPDATE)) {
struct ll_sb_info *sbi = ll_i2sbi(dentry->d_inode);
- struct ll_fid fid;
obd_valid valid = OBD_MD_FLGETATTR;
+ struct obd_capa *oc;
int ealen = 0;
if (S_ISREG(inode->i_mode)) {
rc = ll_get_max_mdsize(sbi, &ealen);
- if (rc)
- RETURN(rc);
+ if (rc)
+ RETURN(rc);
valid |= OBD_MD_FLEASIZE | OBD_MD_FLMODEASIZE;
}
- ll_inode2fid(&fid, inode);
- rc = mdc_getattr(sbi->ll_mdc_exp, &fid, valid, ealen, &req);
+ /* Once OBD_CONNECT_ATTRFID is not supported, we can't find one
+ * capa for this inode. Because we only keep capas of dirs
+ * fresh. */
+ oc = ll_mdscapa_get(inode);
+ rc = md_getattr(sbi->ll_md_exp, ll_inode2fid(inode), oc, valid,
+ ealen, &req);
+ capa_put(oc);
if (rc) {
rc = ll_inode_revalidate_fini(inode, rc);
RETURN(rc);
}
- rc = ll_prep_inode(sbi->ll_osc_exp, &inode, req, REPLY_REC_OFF,
+ rc = ll_prep_inode(&inode, req, REPLY_REC_OFF,
NULL);
if (rc)
GOTO(out, rc);
}
/* if object not yet allocated, don't validate size */
- if (ll_i2info(inode)->lli_smd == NULL)
+ if (ll_i2info(inode)->lli_smd == NULL)
GOTO(out, rc = 0);
/* ll_glimpse_size will prefer locally cached writes if they extend
* the file */
rc = ll_glimpse_size(inode, 0);
-
+ EXIT;
out:
ptlrpc_req_finished(req);
- RETURN(rc);
+ return rc;
}
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
int ll_getattr_it(struct vfsmount *mnt, struct dentry *de,
struct lookup_intent *it, struct kstat *stat)
{
int res = 0;
res = ll_inode_revalidate_it(de, it);
- lprocfs_counter_incr(ll_i2sbi(inode)->ll_stats, LPROC_LL_GETATTR);
+ ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_GETATTR, 1);
if (res)
return res;
#ifdef HAVE_INODE_BLKSIZE
stat->blksize = inode->i_blksize;
#else
- stat->blksize = 1<<inode->i_blkbits;
+ stat->blksize = 1 << inode->i_blkbits;
#endif
ll_inode_size_lock(inode, 0);
- stat->size = inode->i_size;
+ stat->size = i_size_read(inode);
stat->blocks = inode->i_blocks;
ll_inode_size_unlock(inode, 0);
{
struct lookup_intent it = { .it_op = IT_GETATTR };
- ll_vfs_ops_tally(ll_i2sbi(de->d_inode), VFS_OPS_GETATTR);
return ll_getattr_it(mnt, de, &it, stat);
}
-#endif
static
int lustre_check_acl(struct inode *inode, int mask)
{
CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), mask %o\n",
inode->i_ino, inode->i_generation, inode, mask);
-
- ll_vfs_ops_tally(ll_i2sbi(inode), VFS_OPS_INODE_PERMISSION);
+ if (ll_i2sbi(inode)->ll_flags & LL_SBI_RMT_CLIENT)
+ return lustre_check_remote_perm(inode, mask);
+
+ ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_INODE_PERM, 1);
return generic_permission(inode, mask, lustre_check_acl);
}
#else
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
int ll_inode_permission(struct inode *inode, int mask, struct nameidata *nd)
-#else
-int ll_inode_permission(struct inode *inode, int mask)
-#endif
{
int mode = inode->i_mode;
int rc;
CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), mask %o\n",
inode->i_ino, inode->i_generation, inode, mask);
- ll_vfs_ops_tally(ll_i2sbi(inode), VFS_OPS_INODE_PERMISSION);
+
+ if (ll_i2sbi(inode)->ll_flags & LL_SBI_RMT_CLIENT)
+ return lustre_check_remote_perm(inode, mask);
+
+ ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_INODE_PERM, 1);
if ((mask & MAY_WRITE) && IS_RDONLY(inode) &&
(S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
if (capable(CAP_DAC_READ_SEARCH) && ((mask == MAY_READ) ||
(S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE))))
return 0;
-
+
return -EACCES;
}
#endif
+/* -o localflock - only provides locally consistent flock locks */
struct file_operations ll_file_operations = {
.read = ll_file_read,
.write = ll_file_write,
.release = ll_file_release,
.mmap = ll_file_mmap,
.llseek = ll_file_seek,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
.sendfile = ll_file_sendfile,
-#endif
.fsync = ll_fsync,
-#ifdef HAVE_F_OP_FLOCK
- .flock = ll_file_noflock,
-#endif
- .lock = ll_file_noflock
};
struct file_operations ll_file_operations_flock = {
.release = ll_file_release,
.mmap = ll_file_mmap,
.llseek = ll_file_seek,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
.sendfile = ll_file_sendfile,
-#endif
.fsync = ll_fsync,
#ifdef HAVE_F_OP_FLOCK
.flock = ll_file_flock,
.lock = ll_file_flock
};
+/* These are for -o noflock - to return ENOSYS on flock calls */
+struct file_operations ll_file_operations_noflock = {
+ .read = ll_file_read,
+ .write = ll_file_write,
+ .ioctl = ll_file_ioctl,
+ .open = ll_file_open,
+ .release = ll_file_release,
+ .mmap = ll_file_mmap,
+ .llseek = ll_file_seek,
+ .sendfile = ll_file_sendfile,
+ .fsync = ll_fsync,
+#ifdef HAVE_F_OP_FLOCK
+ .flock = ll_file_noflock,
+#endif
+ .lock = ll_file_noflock
+};
struct inode_operations ll_file_inode_operations = {
#ifdef LUSTRE_KERNEL_VERSION
#endif
.setattr = ll_setattr,
.truncate = ll_truncate,
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
.getattr = ll_getattr,
-#else
- .revalidate_it = ll_inode_revalidate_it,
-#endif
.permission = ll_inode_permission,
.setxattr = ll_setxattr,
.getxattr = ll_getxattr,
.removexattr = ll_removexattr,
};
+/* dynamic ioctl number support routins */
+static struct llioc_ctl_data {
+ struct rw_semaphore ioc_sem;
+ struct list_head ioc_head;
+} llioc = {
+ __RWSEM_INITIALIZER(llioc.ioc_sem),
+ CFS_LIST_HEAD_INIT(llioc.ioc_head)
+};
+
+
+struct llioc_data {
+ struct list_head iocd_list;
+ unsigned int iocd_size;
+ llioc_callback_t iocd_cb;
+ unsigned int iocd_count;
+ unsigned int iocd_cmd[0];
+};
+
+void *ll_iocontrol_register(llioc_callback_t cb, int count, unsigned int *cmd)
+{
+ unsigned int size;
+ struct llioc_data *in_data = NULL;
+ ENTRY;
+
+ if (cb == NULL || cmd == NULL ||
+ count > LLIOC_MAX_CMD || count < 0)
+ RETURN(NULL);
+
+ size = sizeof(*in_data) + count * sizeof(unsigned int);
+ OBD_ALLOC(in_data, size);
+ if (in_data == NULL)
+ RETURN(NULL);
+
+ memset(in_data, 0, sizeof(*in_data));
+ in_data->iocd_size = size;
+ in_data->iocd_cb = cb;
+ in_data->iocd_count = count;
+ memcpy(in_data->iocd_cmd, cmd, sizeof(unsigned int) * count);
+
+ down_write(&llioc.ioc_sem);
+ list_add_tail(&in_data->iocd_list, &llioc.ioc_head);
+ up_write(&llioc.ioc_sem);
+
+ RETURN(in_data);
+}
+
+void ll_iocontrol_unregister(void *magic)
+{
+ struct llioc_data *tmp;
+
+ if (magic == NULL)
+ return;
+
+ down_write(&llioc.ioc_sem);
+ list_for_each_entry(tmp, &llioc.ioc_head, iocd_list) {
+ if (tmp == magic) {
+ unsigned int size = tmp->iocd_size;
+
+ list_del(&tmp->iocd_list);
+ up_write(&llioc.ioc_sem);
+
+ OBD_FREE(tmp, size);
+ return;
+ }
+ }
+ up_write(&llioc.ioc_sem);
+
+ CWARN("didn't find iocontrol register block with magic: %p\n", magic);
+}
+
+EXPORT_SYMBOL(ll_iocontrol_register);
+EXPORT_SYMBOL(ll_iocontrol_unregister);
+
+enum llioc_iter ll_iocontrol_call(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg, int *rcp)
+{
+ enum llioc_iter ret = LLIOC_CONT;
+ struct llioc_data *data;
+ int rc = -EINVAL, i;
+
+ down_read(&llioc.ioc_sem);
+ list_for_each_entry(data, &llioc.ioc_head, iocd_list) {
+ for (i = 0; i < data->iocd_count; i++) {
+ if (cmd != data->iocd_cmd[i])
+ continue;
+
+ ret = data->iocd_cb(inode, file, cmd, arg, data, &rc);
+ break;
+ }
+
+ if (ret == LLIOC_STOP)
+ break;
+ }
+ up_read(&llioc.ioc_sem);
+
+ if (rcp)
+ *rcp = rc;
+ return ret;
+}