if (!(och->och_flags & FMODE_WRITE))
goto out;
- if (!(ll_i2mdexp(inode)->exp_connect_flags & OBD_CONNECT_SOM) ||
- !S_ISREG(inode->i_mode))
+ if (!(exp_connect_som(ll_i2mdexp(inode))) || !S_ISREG(inode->i_mode))
op_data->op_attr.ia_valid |= ATTR_SIZE | ATTR_BLOCKS;
else
ll_epoch_close(inode, op_data, &och, 0);
rc = md_close(md_exp, op_data, och->och_mod, &req);
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. */
ENTRY;
/* clear group lock, if present */
- if (unlikely(fd->fd_flags & LL_FILE_GROUP_LOCKED)) {
-#if 0 /* XXX */
- struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd;
- fd->fd_flags &= ~(LL_FILE_GROUP_LOCKED|LL_FILE_IGNORE_LOCK);
- rc = ll_extent_unlock(fd, inode, lsm, LCK_GROUP,
- &fd->fd_cwlockh);
-#endif
- }
+ if (unlikely(fd->fd_flags & LL_FILE_GROUP_LOCKED))
+ ll_put_grouplock(inode, file, fd->fd_grouplock.cg_gid);
/* Let's see if we have good enough OPEN lock on the file and if
we can skip talking to MDS */
if (itp->d.lustre.it_lock_mode)
md_set_lock_data(sbi->ll_md_exp,
&itp->d.lustre.it_lock_handle,
- file->f_dentry->d_inode);
+ file->f_dentry->d_inode, NULL);
rc = ll_prep_inode(&file->f_dentry->d_inode, req, NULL);
out:
RETURN(rc);
}
+void ll_ioepoch_open(struct ll_inode_info *lli, __u64 ioepoch)
+{
+ if (ioepoch && lli->lli_ioepoch != ioepoch) {
+ lli->lli_ioepoch = ioepoch;
+ CDEBUG(D_INODE, "Epoch "LPU64" opened on "DFID"\n",
+ ioepoch, PFID(&lli->lli_fid));
+ }
+}
+
static int ll_och_fill(struct obd_export *md_exp, struct ll_inode_info *lli,
struct lookup_intent *it, struct obd_client_handle *och)
{
och->och_magic = OBD_CLIENT_HANDLE_MAGIC;
och->och_fid = lli->lli_fid;
och->och_flags = it->it_flags;
- lli->lli_ioepoch = body->ioepoch;
+ ll_ioepoch_open(lli, body->ioepoch);
return md_set_open_replay_data(md_exp, och, req);
}
}
md_set_lock_data(ll_i2sbi(inode)->ll_md_exp,
&it->d.lustre.it_lock_handle,
- file->f_dentry->d_inode);
+ file->f_dentry->d_inode, NULL);
goto restart;
}
OBD_ALLOC(*och_p, sizeof (struct obd_client_handle));
io->u.ci_wr.wr_append = file->f_flags & O_APPEND;
io->ci_obj = ll_i2info(inode)->lli_clob;
io->ci_lockreq = CILR_MAYBE;
- if (fd->fd_flags & LL_FILE_IGNORE_LOCK || sbi->ll_flags & LL_SBI_NOLCK)
+ if (fd->fd_flags & LL_FILE_IGNORE_LOCK ||
+ sbi->ll_flags & LL_SBI_NOLCK) {
io->ci_lockreq = CILR_NEVER;
- else if (file->f_flags & O_APPEND)
+ io->ci_no_srvlock = 1;
+ } else if (file->f_flags & O_APPEND) {
io->ci_lockreq = CILR_MANDATORY;
+ }
}
static ssize_t ll_file_io_generic(const struct lu_env *env,
(void *)arg);
}
-static int ll_get_grouplock(struct inode *inode, struct file *file,
- unsigned long arg)
+int ll_get_grouplock(struct inode *inode, struct file *file, unsigned long arg)
{
- /* XXX */
- return -ENOSYS;
+ struct ll_inode_info *lli = ll_i2info(inode);
+ struct ll_file_data *fd = LUSTRE_FPRIVATE(file);
+ struct ccc_grouplock grouplock;
+ int rc;
+ ENTRY;
+
+ spin_lock(&lli->lli_lock);
+ if (fd->fd_flags & LL_FILE_GROUP_LOCKED) {
+ CERROR("group lock already existed with gid %lu\n",
+ fd->fd_grouplock.cg_gid);
+ spin_unlock(&lli->lli_lock);
+ RETURN(-EINVAL);
+ }
+ LASSERT(fd->fd_grouplock.cg_lock == NULL);
+ spin_unlock(&lli->lli_lock);
+
+ rc = cl_get_grouplock(cl_i2info(inode)->lli_clob,
+ arg, (file->f_flags & O_NONBLOCK), &grouplock);
+ if (rc)
+ RETURN(rc);
+
+ spin_lock(&lli->lli_lock);
+ if (fd->fd_flags & LL_FILE_GROUP_LOCKED) {
+ spin_unlock(&lli->lli_lock);
+ CERROR("another thread just won the race\n");
+ cl_put_grouplock(&grouplock);
+ RETURN(-EINVAL);
+ }
+
+ fd->fd_flags |= (LL_FILE_GROUP_LOCKED | LL_FILE_IGNORE_LOCK);
+ fd->fd_grouplock = grouplock;
+ spin_unlock(&lli->lli_lock);
+
+ CDEBUG(D_INFO, "group lock %lu obtained\n", arg);
+ RETURN(0);
}
-static int ll_put_grouplock(struct inode *inode, struct file *file,
- unsigned long arg)
+int ll_put_grouplock(struct inode *inode, struct file *file, unsigned long arg)
{
- /* XXX */
- return -ENOSYS;
+ struct ll_inode_info *lli = ll_i2info(inode);
+ struct ll_file_data *fd = LUSTRE_FPRIVATE(file);
+ struct ccc_grouplock grouplock;
+ ENTRY;
+
+ spin_lock(&lli->lli_lock);
+ if (!(fd->fd_flags & LL_FILE_GROUP_LOCKED)) {
+ spin_unlock(&lli->lli_lock);
+ CERROR("no group lock held\n");
+ RETURN(-EINVAL);
+ }
+ LASSERT(fd->fd_grouplock.cg_lock != NULL);
+
+ if (fd->fd_grouplock.cg_gid != arg) {
+ CERROR("group lock %lu doesn't match current id %lu\n",
+ arg, fd->fd_grouplock.cg_gid);
+ spin_unlock(&lli->lli_lock);
+ RETURN(-EINVAL);
+ }
+
+ grouplock = fd->fd_grouplock;
+ fd->fd_grouplock.cg_env = NULL;
+ fd->fd_grouplock.cg_lock = NULL;
+ fd->fd_grouplock.cg_gid = 0;
+ fd->fd_flags &= ~(LL_FILE_GROUP_LOCKED | LL_FILE_IGNORE_LOCK);
+ spin_unlock(&lli->lli_lock);
+
+ cl_put_grouplock(&grouplock);
+ CDEBUG(D_INFO, "group lock %lu released\n", arg);
+ RETURN(0);
}
#if LUSTRE_FIX >= 50
RETURN(rc);
}
+int ll_fid2path(struct obd_export *exp, void *arg)
+{
+ struct getinfo_fid2path *gfout, *gfin;
+ int outsize, rc;
+ ENTRY;
+
+ /* Need to get the buflen */
+ OBD_ALLOC_PTR(gfin);
+ if (gfin == NULL)
+ RETURN(-ENOMEM);
+ if (copy_from_user(gfin, arg, sizeof(*gfin))) {
+ OBD_FREE_PTR(gfin);
+ RETURN(-EFAULT);
+ }
+
+ outsize = sizeof(*gfout) + gfin->gf_pathlen;
+ OBD_ALLOC(gfout, outsize);
+ if (gfout == NULL) {
+ OBD_FREE_PTR(gfin);
+ RETURN(-ENOMEM);
+ }
+ memcpy(gfout, gfin, sizeof(*gfout));
+ OBD_FREE_PTR(gfin);
+
+ /* Call mdc_iocontrol */
+ rc = obd_iocontrol(OBD_IOC_FID2PATH, exp, outsize, gfout, NULL);
+ if (rc)
+ GOTO(gf_free, rc);
+ if (copy_to_user(arg, gfout, outsize))
+ rc = -EFAULT;
+
+gf_free:
+ OBD_FREE(gfout, outsize);
+ RETURN(rc);
+}
+
int ll_file_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
RETURN(0);
}
+ case OBD_IOC_FID2PATH:
+ RETURN(ll_fid2path(ll_i2mdexp(inode), (void *)arg));
+
default: {
int err;
* need to do it before permission check. */
if (inode == inode->i_sb->s_root->d_inode) {
- struct lookup_intent it = { .it_op = IT_GETATTR };
+ struct lookup_intent it = { .it_op = IT_LOOKUP };
rc = __ll_inode_revalidate_it(inode->i_sb->s_root, &it,
MDS_INODELOCK_LOOKUP);