We weren't telling the MDS what kind of unlink we were doing (unlink vs.
rmdir), so, for example, if you called rmdir() on a file, the MDS would
remove it and then the client VFS would return -ENODIR. Not so good.
We send a 'mode' flag along with the unlink request now, that must be one of
S_IFDIR or S_IFREG.
I also fixed some unaligned structures in the MDS protocol, so if you update
one node you must UPDATE THEM ALL.
Minutiae:
- in the intent policy function, if mds_reint returns EISDIR or ENOTDIR, still
go ahead and send back the file attributes
- in mds_reint_unlink, use the mode sent over the wire instead of the actual
inode mode to determine which vfs unlink function to call
struct mds_rec_setattr {
__u32 sa_opcode;
- struct ll_fid sa_fid;
__u32 sa_valid;
+ struct ll_fid sa_fid;
__u32 sa_mode;
__u32 sa_uid;
__u32 sa_gid;
+ __u32 sa_attr_flags;
__u64 sa_size;
__u64 sa_atime;
__u64 sa_mtime;
__u64 sa_ctime;
- __u32 sa_attr_flags;
};
struct mds_rec_create {
__u32 cr_opcode;
+ __u32 cr_mode;
struct ll_fid cr_fid;
__u32 cr_uid;
__u32 cr_gid;
__u64 cr_time;
- __u32 cr_mode;
__u64 cr_rdev;
};
struct mds_rec_link {
__u32 lk_opcode;
+ __u32 lk_reserved;
struct ll_fid lk_fid1;
struct ll_fid lk_fid2;
};
struct mds_rec_unlink {
__u32 ul_opcode;
+ __u32 ul_mode;
struct ll_fid ul_fid1;
struct ll_fid ul_fid2;
};
struct mds_rec_rename {
__u32 rn_opcode;
+ __u32 rn_reserved;
struct ll_fid rn_fid1;
struct ll_fid rn_fid2;
};
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
* vim:expandtab:shiftwidth=8:tabstop=8:
*
- * Copyright (C) 2001 Cluster File Systems, Inc. <braam@clusterfs.com>
+ * Copyright (C) 2001 Cluster File Systems, Inc. <info@clusterfs.com>
*
* This file is part of Lustre, http://www.lustre.org.
*
* along with Lustre; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * MDS data structures.
+ * MDS data structures.
* See also lustre_idl.h for wire formats of requests.
*
*/
#define LUSTRE_MDS_NAME "mds"
#define LUSTRE_MDC_NAME "mdc"
-struct mds_update_record {
+struct mds_update_record {
__u32 ur_opcode;
struct ll_fid *ur_fid1;
struct ll_fid *ur_fid2;
};
/* file data for open files on MDS */
-struct mds_file_data {
+struct mds_file_data {
struct list_head mfd_list;
struct file * mfd_file;
__u64 mfd_clientfd;
const char *name, int namelen, const char *tgt,
int tgtlen);
void mds_unlink_pack(struct ptlrpc_request *, int offset, struct inode *inode,
- struct inode *child, const char *name, int namelen);
+ struct inode *child, __u32 mode, const char *name,
+ int namelen);
void mds_link_pack(struct ptlrpc_request *, int offset, struct inode *ino,
struct inode *dir, const char *name, int namelen);
void mds_rename_pack(struct ptlrpc_request *, int offset, struct inode *srcdir,
void mds_pack_inode2body(struct mds_body *body, struct inode *inode);
/* mds/handler.c */
-struct dentry *mds_name2locked_dentry(struct obd_device *obd, struct dentry *dir,
+struct dentry *mds_name2locked_dentry(struct obd_device *, struct dentry *dir,
struct vfsmount **mnt, char *name,
int namelen, int lock_mode,
struct lustre_handle *lockh,
int mdc_getlovinfo(struct obd_device *obd, struct lustre_handle *mdc_connh,
uuid_t **uuids, struct ptlrpc_request **request);
int mdc_getstatus(struct lustre_handle *conn,
- struct ll_fid *rootfid, __u64 *last_committed, __u32 *last_xid, struct ptlrpc_request **);
+ struct ll_fid *rootfid, __u64 *last_committed,
+ __u32 *last_xid, struct ptlrpc_request **);
int mdc_getattr(struct lustre_handle *conn,
obd_id ino, int type, unsigned long valid, size_t ea_size,
struct ptlrpc_request **request);
struct statfs *sfs, struct ptlrpc_request **request);
int mdc_setattr(struct lustre_handle *conn,
struct inode *, struct iattr *iattr, struct ptlrpc_request **);
-int mdc_open(struct lustre_handle *conn,
- obd_id ino, int type, int flags, struct lov_stripe_md *md, __u64 cookie, __u64 *fh, struct ptlrpc_request **request);
+int mdc_open(struct lustre_handle *conn, obd_id ino, int type, int flags,
+ struct lov_stripe_md *, __u64 cookie, __u64 *fh,
+ struct ptlrpc_request **);
int mdc_close(struct lustre_handle *conn,
obd_id ino, int type, __u64 fh, struct ptlrpc_request **req);
int mdc_readpage(struct lustre_handle *conn, obd_id ino,
int mdc_create(struct lustre_handle *conn,
struct inode *dir, const char *name, int namelen,
const char *tgt, int tgtlen, int mode, __u32 uid, __u32 gid,
- __u64 time, __u64 rdev, struct lov_stripe_md *md,
+ __u64 time, __u64 rdev, struct lov_stripe_md *md,
+ struct ptlrpc_request **);
+int mdc_unlink(struct lustre_handle *, struct inode *dir, struct inode *child,
+ __u32 mode, const char *name, int namelen,
struct ptlrpc_request **);
-int mdc_unlink(struct lustre_handle *conn,
- struct inode *dir, struct inode *child, const char *name,
- int namelen, struct ptlrpc_request **);
int mdc_link(struct lustre_handle *conn,
struct dentry *src, struct inode *dir, const char *name,
int namelen, struct ptlrpc_request **);
struct iattr *iattr);
int (* fs_set_md)(struct inode *inode, void *handle,
struct lov_stripe_md *md);
- int (* fs_get_md)(struct inode *inode,
+ int (* fs_get_md)(struct inode *inode,
struct lov_stripe_md *md);
ssize_t (* fs_readpage)(struct file *file, char *buf, size_t count,
loff_t *offset);
return rc;
}
-/* Returns a referenced, lock */
+/* Returns a referenced lock */
struct ldlm_lock *ldlm_lock_create(struct ldlm_namespace *ns,
struct lustre_handle *parent_lock_handle,
__u64 * res_id, __u32 type,
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
* vim:expandtab:shiftwidth=8:tabstop=8:
*
- * Lustre Light Update Records
+ * Copryright (C) 2002 Cluster File Systems, Inc.
*
- * This code is issued under the GNU General Public License.
- * See the file COPYING in this distribution
+ * This file is part of Lustre, http://www.sf.net/projects/lustre/
*
- * Copryright (C) 2002 Cluster File Systems, Inc.
+ * This code is issued under the GNU General Public License.
+ * See the file COPYING in this distribution
*
+ * Lustre Lite Update Records
*/
#include <linux/config.h>
}
void mds_getattr_pack(struct ptlrpc_request *req, int offset,
- struct inode *inode,
+ struct inode *inode,
const char *name, int namelen)
{
struct mds_body *rec;
rec = lustre_msg_buf(req->rq_reqmsg, offset);
ll_inode2fid(&rec->fid1, inode);
- if (name) {
+ if (name) {
char *tmp;
tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1);
LOGL0(name, namelen, tmp);
}
-void mds_pack_req_body(struct ptlrpc_request *req)
+void mds_pack_req_body(struct ptlrpc_request *req)
{
struct mds_body *b = lustre_msg_buf(req->rq_reqmsg, 0);
mds_pack_body(b);
}
-void mds_pack_rep_body(struct ptlrpc_request *req)
+void mds_pack_rep_body(struct ptlrpc_request *req)
{
struct mds_body *b = lustre_msg_buf(req->rq_repmsg, 0);
mds_pack_body(b);
}
void mds_setattr_pack(struct ptlrpc_request *req, int offset,
- struct inode *inode, struct iattr *iattr,
+ struct inode *inode, struct iattr *iattr,
const char *name, int namelen)
{
struct mds_rec_setattr *rec;
rec->sa_ctime = HTON__u64(iattr->ia_ctime);
rec->sa_attr_flags = HTON__u32(iattr->ia_attr_flags);
- if (namelen) {
+ if (namelen) {
char *tmp;
tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1);
LOGL0(name, namelen, tmp);
}
void mds_unlink_pack(struct ptlrpc_request *req, int offset,
- struct inode *inode, struct inode *child,
+ struct inode *inode, struct inode *child, __u32 mode,
const char *name, int namelen)
{
struct mds_rec_unlink *rec;
rec = lustre_msg_buf(req->rq_reqmsg, offset);
rec->ul_opcode = HTON__u32(REINT_UNLINK);
+ rec->ul_mode = HTON__u32(mode);
ll_inode2fid(&rec->ul_fid1, inode);
- if (child)
+ if (child)
ll_inode2fid(&rec->ul_fid2, child);
tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1);
attr->ia_ctime = NTOH__u64(rec->sa_ctime);
attr->ia_attr_flags = NTOH__u32(rec->sa_attr_flags);
- if (req->rq_reqmsg->bufcount == offset + 2) {
+ if (req->rq_reqmsg->bufcount == offset + 2) {
r->ur_namelen = req->rq_reqmsg->buflens[offset + 1];
r->ur_name = lustre_msg_buf(req->rq_reqmsg, offset + 1);
- } else
+ } else
r->ur_namelen = 0;
RETURN(0);
req->rq_reqmsg->buflens[offset] != sizeof(*rec))
RETURN(-EFAULT);
+ r->ur_mode = NTOH__u32(rec->ul_mode);
r->ur_fid1 = &rec->ul_fid1;
r->ur_fid2 = &rec->ul_fid2;
if (file->f_mode & FMODE_WRITE) {
struct iattr attr;
- attr.ia_valid = ATTR_MTIME | ATTR_CTIME | ATTR_ATIME | ATTR_SIZE;
+ attr.ia_valid = (ATTR_MTIME | ATTR_CTIME | ATTR_ATIME |
+ ATTR_SIZE);
attr.ia_mtime = inode->i_mtime;
attr.ia_ctime = inode->i_ctime;
attr.ia_atime = inode->i_atime;
ll_inode_setattr(inode, &attr, 0);
}
-static int ll_lock_callback(struct ldlm_lock *lock,
- struct ldlm_lock_desc *new,
+static int ll_lock_callback(struct ldlm_lock *lock, struct ldlm_lock_desc *new,
void *data, __u32 data_len)
{
struct inode *inode = data;
return inode;
}
-int ll_mdc_unlink(struct inode *dir, struct inode *child,
- const char *name, int len)
+static int ll_mdc_unlink(struct inode *dir, struct inode *child, __u32 mode,
+ const char *name, int len)
{
struct ptlrpc_request *request = NULL;
- int err;
struct ll_sb_info *sbi = ll_i2sbi(dir);
+ int err;
ENTRY;
- err = mdc_unlink(&sbi->ll_mdc_conn, dir, child,
- name, len, &request);
+ err = mdc_unlink(&sbi->ll_mdc_conn, dir, child, mode, name, len,
+ &request);
ptlrpc_free_req(request);
RETURN(err);
goto out;
}
-static int ll_unlink(struct inode * dir, struct dentry *dentry)
+static int ll_common_unlink(struct inode *dir, struct dentry *dentry,
+ __u32 mode)
{
struct inode * inode = dentry->d_inode;
struct ext2_dir_entry_2 * de;
int err = -ENOENT;
if (dentry->d_it && dentry->d_it->it_disposition) {
- inode->i_nlink = 0;
- GOTO(out, err = dentry->d_it->it_status);
-
+ err = dentry->d_it->it_status;
+ if (!err)
+ inode->i_nlink = 0;
+ GOTO(out, err);
}
- de = ext2_find_entry (dir, dentry, &page);
+ de = ext2_find_entry(dir, dentry, &page);
if (!de)
goto out;
- err = ll_mdc_unlink(dir, dentry->d_inode,
+ err = ll_mdc_unlink(dir, dentry->d_inode, mode,
dentry->d_name.name, dentry->d_name.len);
if (err)
goto out;
- err = ext2_delete_entry (de, page);
+ err = ext2_delete_entry(de, page);
if (err)
goto out;
return err;
}
-static int ll_rmdir(struct inode * dir, struct dentry *dentry)
+static int ll_unlink(struct inode *dir, struct dentry *dentry)
+{
+ return ll_common_unlink(dir, dentry, S_IFREG);
+}
+
+static int ll_rmdir(struct inode *dir, struct dentry *dentry)
{
struct inode * inode = dentry->d_inode;
int err = 0;
+ ENTRY;
if (!dentry->d_it || dentry->d_it->it_disposition == 0) {
if (!ext2_empty_dir(inode))
LBUG();
- err = ll_unlink(dir, dentry);
- if (err)
- RETURN(err);
+ err = ll_common_unlink(dir, dentry, S_IFDIR);
} else
err = dentry->d_it->it_status;
+ if (err)
+ RETURN(err);
inode->i_size = 0;
ext2_dec_count(inode);
ext2_dec_count(dir);
RETURN(rc);
}
-int mdc_unlink(struct lustre_handle *conn,
- struct inode *dir, struct inode *child, const char *name,
- int namelen, struct ptlrpc_request **request)
+int mdc_unlink(struct lustre_handle *conn, struct inode *dir,
+ struct inode *child, __u32 mode, const char *name, int namelen,
+ struct ptlrpc_request **request)
{
struct ptlrpc_request *req;
int rc, size[2] = {sizeof(struct mds_rec_unlink), namelen + 1};
if (!req)
RETURN(-ENOMEM);
- mds_unlink_pack(req, 0, dir, child, name, namelen);
+ mds_unlink_pack(req, 0, dir, child, mode, name, namelen);
size[0] = sizeof(struct mds_body);
req->rq_replen = lustre_msg_size(1, size);
rc = mdc_reint(req, LUSTRE_CONN_FULL);
*request = req;
- if (rc == -ERESTARTSYS )
+ if (rc == -ERESTARTSYS)
rc = 0;
RETURN(rc);
}
int mdc_getstatus(struct lustre_handle *conn, struct ll_fid *rootfid,
- __u64 *last_committed, __u32 *last_xid,
+ __u64 *last_committed, __u32 *last_xid,
struct ptlrpc_request **request)
{
struct ptlrpc_request *req;
CDEBUG(D_NET, "root ino=%ld, last_committed=%Lu, last_xid=%d\n",
(unsigned long)rootfid->id,
- (unsigned long long)*last_committed, last_xid);
+ (unsigned long long)*last_committed, *last_xid);
}
EXIT;
out:
- ptlrpc_free_req(req);
+ ptlrpc_free_req(req);
return rc;
}
__u64 res_id[RES_NAME_SIZE] = {dir->i_ino};
int size[5] = {sizeof(struct ldlm_request), sizeof(struct ldlm_intent)};
int rc, flags;
- int repsize[3] = {sizeof(struct ldlm_reply),
+ int repsize[3] = {sizeof(struct ldlm_reply),
sizeof(struct mds_body),
obddev->u.cli.cl_max_mdsize};
struct ldlm_reply *dlm_rep;
LDLM_DEBUG_NOLOCK("mdsintent %s dir %ld", ldlm_it2str(it->it_op), dir->i_ino);
- switch (it->it_op) {
+ switch (it->it_op) {
case IT_MKDIR:
- it->it_mode = (it->it_mode | S_IFDIR) & ~current->fs->umask;
+ it->it_mode = (it->it_mode | S_IFDIR) & ~current->fs->umask;
break;
case (IT_CREAT|IT_OPEN):
case IT_CREAT:
it->it_mode &= ~current->fs->umask;
break;
case IT_SYMLINK:
- it->it_mode = (it->it_mode | S_IFLNK) & ~current->fs->umask;
+ it->it_mode = (it->it_mode | S_IFLNK) & ~current->fs->umask;
break;
}
lit->opc = NTOH__u64((__u64)it->it_op);
/* pack the intended request */
- mds_unlink_pack(req, 2, dir, NULL, de->d_name.name,
- de->d_name.len);
+ mds_unlink_pack(req, 2, dir, NULL,
+ it->it_op == IT_UNLINK ? S_IFREG : S_IFDIR,
+ de->d_name.name, de->d_name.len);
req->rq_replen = lustre_msg_size(3, repsize);
} else if (it->it_op == IT_GETATTR || it->it_op == IT_RENAME ||
RETURN(rc);
}
- dlm_rep = lustre_msg_buf(req->rq_repmsg, 0);
+ dlm_rep = lustre_msg_buf(req->rq_repmsg, 0);
it->it_disposition = (int) dlm_rep->lock_policy_res1;
it->it_status = (int) dlm_rep->lock_policy_res2;
it->it_lock_mode = lock_mode;
return rc;
}
-int mdc_close(struct lustre_handle *conn,
+int mdc_close(struct lustre_handle *conn,
obd_id ino, int type, __u64 fh, struct ptlrpc_request **request)
{
struct mds_body *body;
if (rc) {
ptlrpc_abort_bulk(desc);
GOTO(out2, rc);
- } else {
+ } else {
body = lustre_msg_buf(req->rq_repmsg, 0);
mds_unpack_body(body);
}
case IT_SYMLINK:
case IT_UNLINK:
rc = mds_reint(2, req);
- if (rc || req->rq_status != 0) {
+ if (rc || (req->rq_status != 0 &&
+ req->rq_status != -EISDIR &&
+ req->rq_status != -ENOTDIR)) {
rep->lock_policy_res2 = req->rq_status;
RETURN(ELDLM_LOCK_ABORTED);
}
OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_UNLINK_WRITE, dir->i_sb->s_dev);
-#warning FIXME: the file type needs to match the original requested operation
- switch (inode->i_mode & S_IFMT) {
+ switch (rec->ur_mode) {
case S_IFDIR:
handle = mds_fs_start(mds, dir, MDS_FSOP_RMDIR);
if (!handle)
rc = vfs_rmdir(dir, dchild);
break;
case S_IFREG:
- if (offset) {
+ if ((inode->i_mode & S_IFMT) == S_IFREG && offset) {
struct lov_stripe_md *md;
md = lustre_msg_buf(req->rq_repmsg, 2);
md->lmd_easize = mds->mds_max_mdsize;
if ((rc = mds_fs_get_md(mds, inode, md)) < 0) {
- CDEBUG(D_INFO,
- "No md for ino %ld: rc = %d\n",
+ CDEBUG(D_INFO, "No md for ino %ld: rc = %d\n",
inode->i_ino, rc);
memset(md, 0, md->lmd_easize);
}
}
- /* No break */
- default:
handle = mds_fs_start(mds, dir, MDS_FSOP_UNLINK);
if (!handle)
GOTO(out_unlink_cancel, rc = PTR_ERR(handle));
rc = vfs_unlink(dir, dchild);
break;
+ default:
+ LBUG();
}
if (!rc)
CDEBUG(D_INFO, "SEARCH %s\n", nm);
tmp = &obd_types;
- while ( (tmp = tmp->next) != &obd_types ) {
+ list_for_each(tmp, &obd_types) {
type = list_entry(tmp, struct obd_type, typ_chain);
CDEBUG(D_INFO, "TYP %s\n", type->typ_name);
if (strlen(type->typ_name) == strlen(nm) &&
}
rc = ldlm_cli_enqueue(connh, NULL,obddev->obd_namespace,
- parent_lock, &res_id, type, extent, sizeof(extent),
- mode, flags, ldlm_completion_ast, callback, data, datalen, lockh);
+ parent_lock, &res_id, type, extent,
+ sizeof(extent), mode, flags, ldlm_completion_ast,
+ callback, data, datalen, lockh);
return rc;
}
-static int osc_cancel(struct lustre_handle *oconn, struct lov_stripe_md *md, __u32 mode,
- struct lustre_handle *lockh)
+static int osc_cancel(struct lustre_handle *oconn, struct lov_stripe_md *md,
+ __u32 mode, struct lustre_handle *lockh)
{
ENTRY;
--- /dev/null
+#!/bin/sh
+
+for f in `cat $1` ; do
+ diff -u $2-pristine/$f $2/$f
+done