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
b=19053
[fs/lustre-release.git]
/
lustre
/
llite
/
file.c
diff --git
a/lustre/llite/file.c
b/lustre/llite/file.c
index
35c1d87
..
c5d6702
100644
(file)
--- a/
lustre/llite/file.c
+++ b/
lustre/llite/file.c
@@
-55,7
+55,7
@@
struct ll_file_data *ll_file_data_get(void)
{
struct ll_file_data *fd;
- OBD_SLAB_ALLOC_PTR
(fd, ll_file_data_slab
);
+ OBD_SLAB_ALLOC_PTR
_GFP(fd, ll_file_data_slab, CFS_ALLOC_IO
);
return fd;
}
@@
-92,8
+92,7
@@
static void ll_prepare_close(struct inode *inode, struct md_op_data *op_data,
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);
@@
-112,7
+111,7
@@
static int ll_close_inode_openhandle(struct obd_export *md_exp,
struct ptlrpc_request *req = NULL;
struct obd_device *obd = class_exp2obd(exp);
int epoch_close = 1;
- int
seq_end = 0,
rc;
+ int rc;
ENTRY;
if (obd == NULL) {
@@
-140,17
+139,13
@@
static int ll_close_inode_openhandle(struct obd_export *md_exp,
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);
+ rc = ll_sizeonmds_update(inode,
&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);
@@
-176,8
+171,6
@@
out:
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;
@@
-237,14
+230,8
@@
int ll_md_close(struct obd_export *md_exp, struct inode *inode,
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 */
@@
-331,7
+318,7
@@
int ll_file_release(struct inode *inode, struct file *file)
* Different processes can open the same dir, "ll_opendir_key" means:
* it is me that should stop the statahead thread. */
if (lli->lli_opendir_key == fd && lli->lli_opendir_pid != 0)
- ll_stop_statahead(inode,
fd
);
+ ll_stop_statahead(inode,
lli->lli_opendir_key
);
if (inode->i_sb->s_root == file->f_dentry) {
LUSTRE_FPRIVATE(file) = NULL;
@@
-403,7
+390,7
@@
static int ll_intent_file_open(struct file *file, void *lmm,
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:
@@
-414,6
+401,15
@@
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)
{
@@
-429,7
+425,7
@@
static int ll_och_fill(struct obd_export *md_exp, struct ll_inode_info *lli,
och->och_magic = OBD_CLIENT_HANDLE_MAGIC;
och->och_fid = lli->lli_fid;
och->och_flags = it->it_flags;
- ll
i->lli_ioepoch = body->ioepoch
;
+ ll
_ioepoch_open(lli, body->ioepoch)
;
return md_set_open_replay_data(md_exp, och, req);
}
@@
-511,29
+507,12
@@
int ll_file_open(struct inode *inode, struct file *file)
fd->fd_file = file;
if (S_ISDIR(inode->i_mode)) {
-again:
spin_lock(&lli->lli_lock);
if (lli->lli_opendir_key == NULL && lli->lli_opendir_pid == 0) {
LASSERT(lli->lli_sai == NULL);
lli->lli_opendir_key = fd;
lli->lli_opendir_pid = cfs_curproc_pid();
opendir_set = 1;
- } else if (unlikely(lli->lli_opendir_pid == cfs_curproc_pid() &&
- lli->lli_opendir_key != NULL)) {
- /* Two cases for this:
- * (1) The same process open such directory many times.
- * (2) The old process opened the directory, and exited
- * before its children processes. Then new process
- * with the same pid opens such directory before the
- * old process's children processes exit.
- * reset stat ahead for such cases. */
- spin_unlock(&lli->lli_lock);
- CDEBUG(D_INFO, "Conflict statahead for %.*s "DFID
- " reset it.\n", file->f_dentry->d_name.len,
- file->f_dentry->d_name.name,
- PFID(&lli->lli_fid));
- ll_stop_statahead(inode, lli->lli_opendir_key);
- goto again;
}
spin_unlock(&lli->lli_lock);
}
@@
-612,9
+591,9
@@
restart:
would attempt to grab och_sem as well, that would
result in a deadlock */
up(&lli->lli_och_sem);
- it->it_
flags |= O
_CHECK_STALE;
+ it->it_
create_mode |= M
_CHECK_STALE;
rc = ll_intent_file_open(file, NULL, 0, it);
- it->it_
flags &= ~O
_CHECK_STALE;
+ it->it_
create_mode &= ~M
_CHECK_STALE;
if (rc) {
ll_file_data_put(fd);
GOTO(out_openerr, rc);
@@
-627,7
+606,7
@@
restart:
}
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));
@@
-690,21
+669,20
@@
out_och_free:
up(&lli->lli_och_sem);
out_openerr:
if (opendir_set != 0)
- ll_stop_statahead(inode,
fd
);
+ ll_stop_statahead(inode,
lli->lli_opendir_key
);
}
return rc;
}
-/* Fills the obdo with the attributes for the inode defined by lsm */
-int ll_inode_getattr(struct inode *inode, struct obdo *obdo)
+/* 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)
{
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
;
- struct obd_info oinfo = { { { 0 } } };
- int rc;
ENTRY;
LASSERT(lsm != NULL);
@@
-719,32
+697,44
@@
int ll_inode_getattr(struct inode *inode, struct obdo *obdo)
OBD_MD_FLBLKSZ | OBD_MD_FLATIME |
OBD_MD_FLMTIME | OBD_MD_FLCTIME |
OBD_MD_FLGROUP;
- oinfo.oi_capa =
ll_mdscapa_get(inode)
;
+ oinfo.oi_capa =
capa
;
set = ptlrpc_prep_set();
if (set == NULL) {
CERROR("can't allocate ptlrpc set\n");
rc = -ENOMEM;
} else {
- rc = obd_getattr_async(
ll_i2dtexp(inode)
, &oinfo, set);
+ rc = obd_getattr_async(
exp
, &oinfo, set);
if (rc == 0)
rc = ptlrpc_set_wait(set);
ptlrpc_set_destroy(set);
}
- capa_put(oinfo.oi_capa);
- if (rc)
- RETURN(rc);
+ if (rc == 0)
+ oinfo.oi_oa->o_valid &= (OBD_MD_FLBLOCKS | OBD_MD_FLBLKSZ |
+ OBD_MD_FLATIME | OBD_MD_FLMTIME |
+ OBD_MD_FLCTIME | OBD_MD_FLSIZE);
+ RETURN(rc);
+}
- oinfo.oi_oa->o_valid &= (OBD_MD_FLBLOCKS | OBD_MD_FLBLKSZ |
- OBD_MD_FLATIME | OBD_MD_FLMTIME |
- OBD_MD_FLCTIME | OBD_MD_FLSIZE);
+/* Fills the obdo with the attributes for the inode defined by lsm */
+int ll_inode_getattr(struct inode *inode, struct obdo *obdo)
+{
+ struct ll_inode_info *lli = ll_i2info(inode);
+ struct obd_capa *capa = ll_mdscapa_get(inode);
+ int rc;
+ ENTRY;
- obdo_refresh_inode(inode, oinfo.oi_oa, oinfo.oi_oa->o_valid);
- CDEBUG(D_INODE, "objid "LPX64" size %Lu, blocks %llu, blksize %lu\n",
- lli->lli_smd->lsm_object_id, i_size_read(inode),
- (unsigned long long)inode->i_blocks,
- (unsigned long)ll_inode_blksize(inode));
- RETURN(0);
+ rc = ll_lsm_getattr(lli->lli_smd, ll_i2dtexp(inode), capa, obdo);
+ capa_put(capa);
+ if (rc == 0) {
+ obdo_refresh_inode(inode, obdo, obdo->o_valid);
+ CDEBUG(D_INODE,
+ "objid "LPX64" size %Lu, blocks %llu, blksize %lu\n",
+ lli->lli_smd->lsm_object_id, i_size_read(inode),
+ (unsigned long long)inode->i_blocks,
+ (unsigned long)ll_inode_blksize(inode));
+ }
+ RETURN(rc);
}
int ll_merge_lvb(struct inode *inode)
@@
-773,8
+763,18
@@
int ll_merge_lvb(struct inode *inode)
int ll_glimpse_ioctl(struct ll_sb_info *sbi, struct lov_stripe_md *lsm,
lstat_t *st)
{
- /* XXX */
- return -ENOSYS;
+ struct obdo obdo = { 0 };
+ int rc;
+
+ rc = ll_lsm_getattr(lsm, sbi->ll_dt_exp, NULL, &obdo);
+ if (rc == 0) {
+ st->st_size = obdo.o_size;
+ st->st_blocks = obdo.o_blocks;
+ st->st_mtime = obdo.o_mtime;
+ st->st_atime = obdo.o_atime;
+ st->st_ctime = obdo.o_ctime;
+ }
+ return rc;
}
void ll_io_init(struct cl_io *io, const struct file *file, int write)
@@
-790,10
+790,13
@@
void ll_io_init(struct cl_io *io, const struct file *file, int write)
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,
@@
-1405,18
+1408,77
@@
static int ll_lov_getstripe(struct inode *inode, unsigned long arg)
(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
@@
-1448,7
+1510,8
@@
static int join_file(struct inode *head_inode, struct file *head_filp,
{
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};
+ .it_flags = head_filp->f_flags,
+ .it_create_mode = M_JOIN_FILE};
struct ldlm_enqueue_info einfo = { LDLM_IBITS, LCK_CW,
ll_md_blocking_ast, ldlm_completion_ast, NULL, NULL, NULL };
@@
-1506,7
+1569,7
@@
static int ll_file_join(struct inode *head, struct file *filp,
struct file *tail_filp, *first_filp, *second_filp;
struct ll_lock_tree first_tree, second_tree;
struct ll_lock_tree_node *first_node, *second_node;
- struct ll_inode_info *hlli = ll_i2info(head)
, *tlli
;
+ struct ll_inode_info *hlli = ll_i2info(head);
int rc = 0, cleanup_phase = 0;
ENTRY;
@@
-1521,7
+1584,6
@@
static int ll_file_join(struct inode *head, struct file *filp,
}
tail = igrab(tail_filp->f_dentry->d_inode);
- tlli = ll_i2info(tail);
tail_dentry = tail_filp->f_dentry;
LASSERT(tail_dentry);
cleanup_phase = 1;
@@
-1680,6
+1742,42
@@
int ll_fiemap(struct inode *inode, struct ll_user_fiemap *fiemap,
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)
{
@@
-1729,7
+1827,7
@@
int ll_file_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
RETURN(ll_lov_getstripe(inode, arg));
case LL_IOC_RECREATE_OBJ:
RETURN(ll_lov_recreate_obj(inode, file, arg));
- case
EXT3
_IOC_FIEMAP: {
+ case
FSFILT
_IOC_FIEMAP: {
struct ll_user_fiemap *fiemap_s;
size_t num_bytes, ret_bytes;
unsigned int extent_count;
@@
-1795,11
+1893,11
@@
error:
OBD_VFREE(fiemap_s, num_bytes);
RETURN(rc);
}
- case
EXT3
_IOC_GETFLAGS:
- case
EXT3
_IOC_SETFLAGS:
+ case
FSFILT
_IOC_GETFLAGS:
+ case
FSFILT
_IOC_SETFLAGS:
RETURN(ll_iocontrol(inode, file, cmd, arg));
- case
EXT3
_IOC_GETVERSION_OLD:
- case
EXT3
_IOC_GETVERSION:
+ case
FSFILT
_IOC_GETVERSION_OLD:
+ case
FSFILT
_IOC_GETVERSION:
RETURN(put_user(inode->i_generation, (int *)arg));
case LL_IOC_JOIN: {
#if LUSTRE_FIX >= 50
@@
-1828,18
+1926,21
@@
error:
/* We need to special case any other ioctls we want to handle,
* to send them to the MDS/OST as appropriate and to properly
* network encode the arg field.
- case
EXT3
_IOC_SETVERSION_OLD:
- case
EXT3
_IOC_SETVERSION:
+ case
FSFILT
_IOC_SETVERSION_OLD:
+ case
FSFILT
_IOC_SETVERSION:
*/
case LL_IOC_FLUSHCTX:
RETURN(ll_flush_ctx(inode));
case LL_IOC_PATH2FID: {
- if (copy_to_user((void *)arg,
&ll_i2info(inode)->lli_fid
,
+ if (copy_to_user((void *)arg,
ll_inode2fid(inode)
,
sizeof(struct lu_fid)))
RETURN(-EFAULT);
RETURN(0);
}
+ case OBD_IOC_FID2PATH:
+ RETURN(ll_fid2path(ll_i2mdexp(inode), (void *)arg));
+
default: {
int err;
@@
-2131,13
+2232,14
@@
static int ll_inode_revalidate_fini(struct inode *inode, int rc) {
return 0;
}
-int ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it)
+int __ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it,
+ __u64 ibits)
{
struct inode *inode = dentry->d_inode;
struct ptlrpc_request *req = NULL;
struct ll_sb_info *sbi;
struct obd_export *exp;
- int rc;
+ int rc
= 0
;
ENTRY;
if (!inode) {
@@
-2162,14
+2264,14
@@
int ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it)
if (IS_ERR(op_data))
RETURN(PTR_ERR(op_data));
- oit.it_
flags |= O
_CHECK_STALE;
+ oit.it_
create_mode |= M
_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;
+ oit.it_
create_mode &= ~M
_CHECK_STALE;
if (rc < 0) {
rc = ll_inode_revalidate_fini(inode, rc);
GOTO (out, rc);
@@
-2194,8
+2296,8
@@
int ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it)
}
ll_lookup_finish_locks(&oit, dentry);
- } else if (!ll_have_md_lock(dentry->d_inode,
MDS_INODELOCK_UPDATE |
- MDS_INODELOCK_LOOKUP)) {
+ } else if (!ll_have_md_lock(dentry->d_inode,
ibits)) {
+
struct ll_sb_info *sbi = ll_i2sbi(dentry->d_inode);
obd_valid valid = OBD_MD_FLGETATTR;
struct obd_capa *oc;
@@
-2220,21
+2322,31
@@
int ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it)
}
rc = ll_prep_inode(&inode, req, NULL);
- if (rc)
- GOTO(out, rc);
}
+out:
+ ptlrpc_req_finished(req);
+ return rc;
+}
+
+int ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it)
+{
+ int rc;
+ ENTRY;
+
+ rc = __ll_inode_revalidate_it(dentry, it, MDS_INODELOCK_UPDATE |
+ MDS_INODELOCK_LOOKUP);
/* if object not yet allocated, don't validate size */
- if (
ll_i2info(
inode)->lli_smd == NULL)
-
GOTO(out, rc =
0);
+ if (
rc == 0 && ll_i2info(dentry->d_
inode)->lli_smd == NULL)
+
RETURN(
0);
/* cl_glimpse_size will prefer locally cached writes if they extend
* the file */
- rc = cl_glimpse_size(inode);
- EXIT;
-out:
- ptlrpc_req_finished(req);
-
return rc
;
+
+ if (rc == 0)
+ rc = cl_glimpse_size(dentry->d_inode);
+
+
RETURN(rc)
;
}
int ll_getattr_it(struct vfsmount *mnt, struct dentry *de,
@@
-2307,13
+2419,31
@@
int lustre_check_acl(struct inode *inode, int mask)
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10))
int ll_inode_permission(struct inode *inode, int mask, struct nameidata *nd)
{
- CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), mask %o\n",
- inode->i_ino, inode->i_generation, inode, mask);
+ int rc = 0;
+ ENTRY;
+
+ /* as root inode are NOT getting validated in lookup operation,
+ * need to do it before permission check. */
+
+ if (inode == inode->i_sb->s_root->d_inode) {
+ struct lookup_intent it = { .it_op = IT_LOOKUP };
+
+ rc = __ll_inode_revalidate_it(inode->i_sb->s_root, &it,
+ MDS_INODELOCK_LOOKUP);
+ if (rc)
+ RETURN(rc);
+ }
+
+ CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), inode mode %x mask %o\n",
+ inode->i_ino, inode->i_generation, inode, inode->i_mode, mask);
+
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);
+ rc = generic_permission(inode, mask, lustre_check_acl);
+
+ RETURN(rc);
}
#else
int ll_inode_permission(struct inode *inode, int mask, struct nameidata *nd)