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",
- file, file->f_dentry, file->f_dentry->d_name.name);
- }
+ } else {
+ CERROR("released file has negative dentry: file = %p, "
+ "dentry = %p, name = %s\n",
+ file, file->f_dentry, file->f_dentry->d_name.name);
+ }
out:
LUSTRE_FPRIVATE(file) = NULL;
op_data->op_data = lmm;
op_data->op_data_size = lmmsize;
- if (parent == de) {
- /*
- * Fixup for NFS export open.
- *
- * We're called in the context of NFS export, and parent
- * unknown, use parent fid saved in lli_pfid which will
- * be used by MDS to create data.
- */
- struct ll_inode_info *lli = ll_i2info(de->d_inode);
-
- spin_lock(&lli->lli_lock);
- op_data->op_fid1 = lli->lli_pfid;
- spin_unlock(&lli->lli_lock);
-
- LASSERT(fid_is_sane(&op_data->op_fid1));
- /** We ignore parent's capability temporary. */
- if (op_data->op_capa1 != NULL) {
- capa_put(op_data->op_capa1);
- op_data->op_capa1 = NULL;
- }
- }
-
rc = md_intent_lock(sbi->ll_md_exp, op_data, itp, &req,
&ll_md_blocking_ast, 0);
ll_finish_md_op_data(op_data);
/*
* Normally called under two situations:
* 1. NFS export.
- * 2. revalidate with IT_OPEN (revalidate doesn't
- * execute this intent any more).
+ * 2. A race/condition on MDS resulting in no open
+ * handle to be returned from LOOKUP|OPEN request,
+ * for example if the target entry was a symlink.
*
* Always fetch MDS_OPEN_LOCK if this is not setstripe.
*
oinfo.oi_oa->o_flags |= OBD_FL_FLUSH;
}
- set = ptlrpc_prep_set();
- if (set == NULL) {
- CERROR("can't allocate ptlrpc set\n");
- rc = -ENOMEM;
- } else {
+ set = ptlrpc_prep_set();
+ if (set == NULL) {
+ CERROR("cannot allocate ptlrpc set: rc = %d\n", -ENOMEM);
+ rc = -ENOMEM;
+ } else {
rc = obd_getattr_async(exp, &oinfo, set);
if (rc == 0)
rc = ptlrpc_set_wait(set);
cio->cui_fd = LUSTRE_FPRIVATE(file);
vio->cui_io_subtype = args->via_io_subtype;
- ll_cl_add(file, env, io);
-
switch (vio->cui_io_subtype) {
case IO_NORMAL:
cio->cui_iov = args->u.normal.via_iov;
CERROR("Unknow IO type - %u\n", vio->cui_io_subtype);
LBUG();
}
+
+ ll_cl_add(file, env, io);
result = cl_io_loop(env, io);
+ ll_cl_remove(file, env);
+
if (args->via_io_subtype == IO_NORMAL)
up_read(&lli->lli_trunc_sem);
if (write_mutex_locked)
mutex_unlock(&lli->lli_write_mutex);
- ll_cl_remove(file, env);
} else {
/* cl_io_rw_init() handled IO */
result = io->ci_result;
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);
- LASSERTF(io->ci_nob == 0, "%zd", io->ci_nob);
+ LASSERTF(io->ci_nob == 0, "%zd\n", io->ci_nob);
goto restart;
}
RETURN(rc);
}
-int ll_fid2path(struct inode *inode, void *arg)
+int ll_fid2path(struct inode *inode, void __user *arg)
{
struct obd_export *exp = ll_i2mdexp(inode);
- struct getinfo_fid2path *gfout, *gfin;
- int outsize, rc;
+ const struct getinfo_fid2path __user *gfin = arg;
+ __u32 pathlen;
+ struct getinfo_fid2path *gfout;
+ size_t outsize;
+ int rc;
+
ENTRY;
if (!cfs_capable(CFS_CAP_DAC_READ_SEARCH) &&
!(ll_i2sbi(inode)->ll_flags & LL_SBI_USER_FID2PATH))
RETURN(-EPERM);
- /* 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);
+ /* Only need to get the buflen */
+ if (get_user(pathlen, &gfin->gf_pathlen))
RETURN(-EFAULT);
- }
- outsize = sizeof(*gfout) + gfin->gf_pathlen;
+ if (pathlen > PATH_MAX)
+ RETURN(-EINVAL);
+
+ outsize = sizeof(*gfout) + pathlen;
OBD_ALLOC(gfout, outsize);
- if (gfout == NULL) {
- OBD_FREE_PTR(gfin);
+ if (gfout == NULL)
RETURN(-ENOMEM);
- }
- memcpy(gfout, gfin, sizeof(*gfout));
- OBD_FREE_PTR(gfin);
+
+ if (copy_from_user(gfout, arg, sizeof(*gfout)))
+ GOTO(gf_free, rc = -EFAULT);
/* Call mdc_iocontrol */
rc = obd_iocontrol(OBD_IOC_FID2PATH, exp, outsize, gfout, NULL);
- if (rc)
+ if (rc != 0)
GOTO(gf_free, rc);
if (copy_to_user(arg, gfout, outsize))
ATTR_MTIME | ATTR_MTIME_SET |
ATTR_ATIME | ATTR_ATIME_SET;
+ mutex_lock(&inode->i_mutex);
+
rc = ll_setattr_raw(file->f_dentry, attr, true);
if (rc == -ENODATA)
rc = 0;
+ mutex_unlock(&inode->i_mutex);
+
out:
if (hss != NULL)
OBD_FREE_PTR(hss);
RETURN(rc);
}
+static inline long ll_lease_type_from_fmode(fmode_t fmode)
+{
+ return ((fmode & FMODE_READ) ? LL_LEASE_RDLCK : 0) |
+ ((fmode & FMODE_WRITE) ? LL_LEASE_WRLCK : 0);
+}
+
static long
ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct ll_inode_info *lli = ll_i2info(inode);
struct obd_client_handle *och = NULL;
bool lease_broken;
- fmode_t mode = 0;
+ fmode_t fmode;
switch (arg) {
- case F_WRLCK:
+ case LL_LEASE_WRLCK:
if (!(file->f_mode & FMODE_WRITE))
RETURN(-EPERM);
- mode = FMODE_WRITE;
+ fmode = FMODE_WRITE;
break;
- case F_RDLCK:
+ case LL_LEASE_RDLCK:
if (!(file->f_mode & FMODE_READ))
RETURN(-EPERM);
- mode = FMODE_READ;
+ fmode = FMODE_READ;
break;
- case F_UNLCK:
+ case LL_LEASE_UNLCK:
mutex_lock(&lli->lli_och_mutex);
if (fd->fd_lease_och != NULL) {
och = fd->fd_lease_och;
}
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;
- }
+ if (och == NULL)
+ RETURN(-ENOLCK);
+
+ fmode = och->och_flags;
+ rc = ll_lease_close(och, inode, &lease_broken);
+ if (rc < 0)
+ RETURN(rc);
+
+ if (lease_broken)
+ fmode = 0;
- /* return the type of lease or error */
- RETURN(rc < 0 ? rc : (int)mode);
+ RETURN(ll_lease_type_from_fmode(fmode));
default:
RETURN(-EINVAL);
}
- CDEBUG(D_INODE, "Set lease with mode %d\n", mode);
+ CDEBUG(D_INODE, "Set lease with mode %u\n", fmode);
/* apply for lease */
- och = ll_lease_open(inode, file, mode, 0);
+ och = ll_lease_open(inode, file, fmode, 0);
if (IS_ERR(och))
RETURN(PTR_ERR(och));
case LL_IOC_GET_LEASE: {
struct ll_inode_info *lli = ll_i2info(inode);
struct ldlm_lock *lock = NULL;
+ fmode_t fmode = 0;
- rc = 0;
mutex_lock(&lli->lli_och_mutex);
if (fd->fd_lease_och != NULL) {
struct obd_client_handle *och = fd->fd_lease_och;
if (lock != NULL) {
lock_res_and_lock(lock);
if (!ldlm_is_cancel(lock))
- rc = och->och_flags &
- (FMODE_READ | FMODE_WRITE);
+ fmode = och->och_flags;
+
unlock_res_and_lock(lock);
LDLM_LOCK_PUT(lock);
}
}
mutex_unlock(&lli->lli_och_mutex);
- RETURN(rc);
+
+ RETURN(ll_lease_type_from_fmode(fmode));
}
case LL_IOC_HSM_IMPORT: {
struct hsm_user_import *hui;
LASSERT(lock != NULL);
LASSERT(ldlm_has_layout(lock));
- LDLM_DEBUG(lock, "file "DFID"(%p) being reconfigured: %d\n",
+ LDLM_DEBUG(lock, "file "DFID"(%p) being reconfigured: %d",
PFID(&lli->lli_fid), inode, reconf);
/* in case this is a caching lock and reinstate with new inode */
it.it_op = IT_LAYOUT;
lockh.cookie = 0ULL;
- LDLM_DEBUG_NOLOCK("%s: requeue layout lock for file "DFID"(%p)\n",
+ LDLM_DEBUG_NOLOCK("%s: requeue layout lock for file "DFID"(%p)",
ll_get_fsname(inode->i_sb, NULL, 0),
PFID(&lli->lli_fid), inode);