/*
* GPL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 only,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License version 2 for more details (a copy is included
* in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; If not, see
* http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
* GPL HEADER END
*/
/*
* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
* Copyright (c) 2011, 2012, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
* Lustre is a trademark of Sun Microsystems, Inc.
*/
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/quotaops.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
#include <linux/security.h>
#define DEBUG_SUBSYSTEM S_LLITE
#include "../include/obd_support.h"
#include "../include/lustre_fid.h"
#include "../include/lustre_lite.h"
#include "../include/lustre_dlm.h"
#include "../include/lustre_ver.h"
#include "llite_internal.h"
static int ll_create_it(struct inode *, struct dentry *,
int, struct lookup_intent *);
/* called from iget5_locked->find_inode() under inode_hash_lock spinlock */
static int ll_test_inode(struct inode *inode, void *opaque)
{
struct ll_inode_info *lli = ll_i2info(inode);
struct lustre_md *md = opaque;
if (unlikely(!(md->body->valid & OBD_MD_FLID))) {
CERROR("MDS body missing FID\n");
return 0;
}
if (!lu_fid_eq(&lli->lli_fid, &md->body->fid1))
return 0;
return 1;
}
static int ll_set_inode(struct inode *inode, void *opaque)
{
struct ll_inode_info *lli = ll_i2info(inode);
struct mdt_body *body = ((struct lustre_md *)opaque)->body;
if (unlikely(!(body->valid & OBD_MD_FLID))) {
CERROR("MDS body missing FID\n");
return -EINVAL;
}
lli->lli_fid = body->fid1;
if (unlikely(!(body->valid & OBD_MD_FLTYPE))) {
CERROR("Can not initialize inode " DFID " without object type: valid = %#llx\n",
PFID(&lli->lli_fid), body->valid);
return -EINVAL;
}
inode->i_mode = (inode->i_mode & ~S_IFMT) | (body->mode & S_IFMT);
if (unlikely(inode->i_mode == 0)) {
CERROR("Invalid inode "DFID" type\n", PFID(&lli->lli_fid));
return -EINVAL;
}
ll_lli_init(lli);
return 0;
}
/*
* Get an inode by inode number (already instantiated by the intent lookup).
* Returns inode or NULL
*/
struct inode *ll_iget(struct super_block *sb, ino_t hash,
struct lustre_md *md)
{
struct inode *inode;
LASSERT(hash != 0);
inode = iget5_locked(sb, hash, ll_test_inode, ll_set_inode, md);
if (inode) {
if (inode->i_state & I_NEW)