Whamcloud - gitweb
Fix the file(parent/child) x(a/m/c)time change rule according to the POSIX.
[fs/lustre-release.git] / lustre / mdd / mdd_orphans.c
1 /* -*- MODE: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  mdd/mdd_orphans.c
5  *
6  *  Orphan handling code
7  *
8  *  Copyright (C) 2006 Cluster File Systems, Inc.
9  *   Author: Mike Pershin <tappro@clusterfs.com>
10  *
11  *   This file is part of the Lustre file system, http://www.lustre.org
12  *   Lustre is a trademark of Cluster File Systems, Inc.
13  *
14  *   You may have signed or agreed to another license before downloading
15  *   this software.  If so, you are bound by the terms and conditions
16  *   of that agreement, and the following does not apply to you.  See the
17  *   LICENSE file included with this distribution for more information.
18  *
19  *   If you did not agree to a different license, then this copy of Lustre
20  *   is open source software; you can redistribute it and/or modify it
21  *   under the terms of version 2 of the GNU General Public License as
22  *   published by the Free Software Foundation.
23  *
24  *   In either case, Lustre is distributed in the hope that it will be
25  *   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
26  *   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  *   license text for more details.
28  */
29 #ifndef EXPORT_SYMTAB
30 # define EXPORT_SYMTAB
31 #endif
32 #define DEBUG_SUBSYSTEM S_MDS
33
34 #include <obd.h>
35 #include <obd_class.h>
36 #include <lustre_ver.h>
37 #include <obd_support.h>
38
39 #include "mdd_internal.h"
40
41 const char orph_index_name[] = "orphans";
42
43 static const struct dt_index_features orph_index_features = {
44         .dif_flags       = DT_IND_UPDATE,
45         .dif_keysize_min = sizeof(struct orph_key),
46         .dif_keysize_max = sizeof(struct orph_key),
47         .dif_recsize_min = sizeof(loff_t),
48         .dif_recsize_max = sizeof(loff_t)
49 };
50
51 enum {
52         ORPH_OP_UNLINK,
53         ORPH_OP_TRUNCATE
54 };
55
56 static struct orph_key *orph_key_fill(const struct lu_context *ctx,
57                                       const struct lu_fid *lf, __u32 op)
58 {
59         struct orph_key *key = &mdd_ctx_info(ctx)->mti_orph_key;
60         LASSERT(key);
61         key->ok_fid.f_seq = cpu_to_be64(fid_seq(lf));
62         key->ok_fid.f_oid = cpu_to_be32(fid_oid(lf));
63         key->ok_fid.f_ver = cpu_to_be32(fid_ver(lf));
64         key->ok_op = cpu_to_be32(op);
65         return key;
66 }
67
68 static int orph_index_insert(const struct lu_context *ctx, 
69                              struct mdd_object *obj, __u32 op,
70                              loff_t *offset, struct thandle *th)
71 {
72         struct mdd_device *mdd = mdo2mdd(&obj->mod_obj);
73         struct dt_object *dor = mdd->mdd_orphans;
74         struct orph_key *key = orph_key_fill(ctx, mdo2fid(obj), op);
75         int rc;
76         ENTRY;
77
78         rc = dor->do_index_ops->dio_insert(ctx, dor, (struct dt_rec *)offset,
79                                            (struct dt_key *)key, th);
80         RETURN(rc);
81 }
82
83 static int orph_index_delete(const struct lu_context *ctx, 
84                              struct mdd_object *obj, __u32 op,
85                              struct thandle *th)
86 {
87         struct mdd_device *mdd = mdo2mdd(&obj->mod_obj);
88         struct dt_object *dor = mdd->mdd_orphans;
89         struct orph_key *key = orph_key_fill(ctx, mdo2fid(obj), op);
90         int rc;
91         ENTRY;
92
93         rc = dor->do_index_ops->dio_delete(ctx, dor,
94                                            (struct dt_key *)key, th);
95         RETURN(rc);
96
97 }
98 #if 0
99 static int orph_index_iterate(struct lu_server_orph *orph,
100                        const struct lu_context *ctx,
101                        seqno_t seq, mdsno_t *mds)
102 {
103         struct dt_object *dt_obj = orph->orph_obj;
104         struct dt_rec    *rec = orph_rec(ctx, 0);
105         int rc;
106         ENTRY;
107
108         rc = dt_obj->do_index_ops->dio_lookup(ctx, dt_obj, rec,
109                                               orph_key(ctx, seq));
110         if (rc == 0)
111                 *mds = be64_to_cpu(*(__u64 *)rec);
112         RETURN(rc);
113 }
114 #endif
115 int orph_index_init(const struct lu_context *ctx, struct mdd_device *mdd)
116 {
117         struct lu_fid fid;
118         struct dt_object *d;
119         int rc;
120         ENTRY;
121
122         d = dt_store_open(ctx, mdd->mdd_child, orph_index_name, &fid);
123         if (!IS_ERR(d)) {
124                 mdd->mdd_orphans = d;
125                 rc = d->do_ops->do_index_try(ctx, d, &orph_index_features);
126                 if (rc == 0)
127                         LASSERT(d->do_index_ops != NULL);
128                 else
129                         CERROR("\"%s\" is not an index!\n", orph_index_name);
130         } else {
131                 CERROR("cannot find \"%s\" obj %d\n",
132                        orph_index_name, (int)PTR_ERR(d));
133                 rc = PTR_ERR(d);
134         }
135
136         RETURN(rc);
137 }
138
139 void orph_index_fini(const struct lu_context *ctx, struct mdd_device *mdd)
140 {
141         ENTRY;
142         if (mdd->mdd_orphans != NULL) {
143                 if (!IS_ERR(mdd->mdd_orphans))
144                         lu_object_put(ctx, &mdd->mdd_orphans->do_lu);
145                 mdd->mdd_orphans = NULL;
146         }
147         EXIT;
148 }
149
150 int __mdd_orphan_add(const struct lu_context *ctx,
151                             struct mdd_object *obj,
152                             struct thandle *th)
153 {
154         loff_t offset = 0;
155         return orph_index_insert(ctx, obj, ORPH_OP_UNLINK, &offset, th);
156 }
157
158 int __mdd_orphan_del(const struct lu_context *ctx,
159                             struct mdd_object *obj,
160                             struct thandle *th)
161 {
162         return orph_index_delete(ctx, obj, ORPH_OP_UNLINK, th);
163 }
164
165