Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / lustre / obdclass / linux / linux-obdo.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * Object Devices Class Driver
5  *
6  *  Copyright (C) 2001-2003 Cluster File Systems, Inc.
7  *
8  *   This file is part of the Lustre file system, http://www.lustre.org
9  *   Lustre is a trademark of Cluster File Systems, Inc.
10  *
11  *   You may have signed or agreed to another license before downloading
12  *   this software.  If so, you are bound by the terms and conditions
13  *   of that agreement, and the following does not apply to you.  See the
14  *   LICENSE file included with this distribution for more information.
15  *
16  *   If you did not agree to a different license, then this copy of Lustre
17  *   is open source software; you can redistribute it and/or modify it
18  *   under the terms of version 2 of the GNU General Public License as
19  *   published by the Free Software Foundation.
20  *
21  *   In either case, Lustre is distributed in the hope that it will be
22  *   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
23  *   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  *   license text for more details.
25  *
26  * These are the only exported functions, they provide some generic
27  * infrastructure for managing object devices
28  */
29
30 #define DEBUG_SUBSYSTEM S_CLASS
31 #ifndef EXPORT_SYMTAB
32 # define EXPORT_SYMTAB
33 #endif
34
35 #ifndef __KERNEL__
36 #include <liblustre.h>
37 #else
38 #include <linux/module.h>
39 #include <obd_class.h>
40 #include <lustre/lustre_idl.h>
41 #endif
42
43 #ifdef __KERNEL__
44 #include <linux/fs.h>
45 #include <linux/pagemap.h> /* for PAGE_CACHE_SIZE */
46
47 /* WARNING: the file systems must take care not to tinker with
48    attributes they don't manage (such as blocks). */
49 void obdo_from_inode(struct obdo *dst, struct inode *src, obd_flag valid)
50 {
51         obd_flag newvalid = 0;
52
53         if (valid & (OBD_MD_FLCTIME | OBD_MD_FLMTIME))
54                 CDEBUG(D_INODE, "valid %x, new time %lu/%lu\n",
55                        valid, LTIME_S(src->i_mtime), 
56                        LTIME_S(src->i_ctime));
57
58         if (valid & OBD_MD_FLATIME) {
59                 dst->o_atime = LTIME_S(src->i_atime);
60                 newvalid |= OBD_MD_FLATIME;
61         }
62         if (valid & OBD_MD_FLMTIME) {
63                 dst->o_mtime = LTIME_S(src->i_mtime);
64                 newvalid |= OBD_MD_FLMTIME;
65         }
66         if (valid & OBD_MD_FLCTIME) {
67                 dst->o_ctime = LTIME_S(src->i_ctime);
68                 newvalid |= OBD_MD_FLCTIME;
69         }
70         if (valid & OBD_MD_FLSIZE) {
71                 dst->o_size = i_size_read(src);
72                 newvalid |= OBD_MD_FLSIZE;
73         }
74         if (valid & OBD_MD_FLBLOCKS) {  /* allocation of space (x512 bytes) */
75                 dst->o_blocks = src->i_blocks;
76                 newvalid |= OBD_MD_FLBLOCKS;
77         }
78         if (valid & OBD_MD_FLBLKSZ) {   /* optimal block size */
79                 dst->o_blksize = 1 << src->i_blkbits;
80                 newvalid |= OBD_MD_FLBLKSZ;
81         }
82         if (valid & OBD_MD_FLTYPE) {
83                 dst->o_mode = (dst->o_mode & S_IALLUGO)|(src->i_mode & S_IFMT);
84                 newvalid |= OBD_MD_FLTYPE;
85         }
86         if (valid & OBD_MD_FLMODE) {
87                 dst->o_mode = (dst->o_mode & S_IFMT)|(src->i_mode & S_IALLUGO);
88                 newvalid |= OBD_MD_FLMODE;
89         }
90         if (valid & OBD_MD_FLUID) {
91                 dst->o_uid = src->i_uid;
92                 newvalid |= OBD_MD_FLUID;
93         }
94         if (valid & OBD_MD_FLGID) {
95                 dst->o_gid = src->i_gid;
96                 newvalid |= OBD_MD_FLGID;
97         }
98         if (valid & OBD_MD_FLFLAGS) {
99                 dst->o_flags = src->i_flags;
100                 newvalid |= OBD_MD_FLFLAGS;
101         }
102         if (valid & OBD_MD_FLGENER) {
103                 dst->o_generation = src->i_generation;
104                 newvalid |= OBD_MD_FLGENER;
105         }
106         if (valid & OBD_MD_FLFID) {
107                 dst->o_fid = src->i_ino;
108                 newvalid |= OBD_MD_FLFID;
109         }
110
111         dst->o_valid |= newvalid;
112 }
113 EXPORT_SYMBOL(obdo_from_inode);
114
115 /*FIXME: Just copy from obdo_from_inode*/
116 void obdo_from_la(struct obdo *dst, struct lu_attr *la, obd_flag valid)
117 {
118         obd_flag newvalid = 0;
119
120         if (valid & OBD_MD_FLATIME) {
121                 dst->o_atime = la->la_atime;
122                 newvalid |= OBD_MD_FLATIME;
123         }
124         if (valid & OBD_MD_FLMTIME) {
125                 dst->o_mtime = la->la_mtime;
126                 newvalid |= OBD_MD_FLMTIME;
127         }
128         if (valid & OBD_MD_FLCTIME) {
129                 dst->o_ctime = la->la_ctime;
130                 newvalid |= OBD_MD_FLCTIME;
131         }
132         if (valid & OBD_MD_FLSIZE) {
133                 dst->o_size = la->la_size;
134                 newvalid |= OBD_MD_FLSIZE;
135         }
136         if (valid & OBD_MD_FLBLOCKS) {  /* allocation of space (x512 bytes) */
137                 dst->o_blocks = la->la_blocks;
138                 newvalid |= OBD_MD_FLBLOCKS;
139         }
140         if (valid & OBD_MD_FLTYPE) {
141                 dst->o_mode = (dst->o_mode & S_IALLUGO)|(la->la_mode & S_IFMT);
142                 newvalid |= OBD_MD_FLTYPE;
143         }
144         if (valid & OBD_MD_FLMODE) {
145                 dst->o_mode = (dst->o_mode & S_IFMT)|(la->la_mode & S_IALLUGO);
146                 newvalid |= OBD_MD_FLMODE;
147         }
148         if (valid & OBD_MD_FLUID) {
149                 dst->o_uid = la->la_uid;
150                 newvalid |= OBD_MD_FLUID;
151         }
152         if (valid & OBD_MD_FLGID) {
153                 dst->o_gid = la->la_gid;
154                 newvalid |= OBD_MD_FLGID;
155         }
156         dst->o_valid |= newvalid;
157 }
158 EXPORT_SYMBOL(obdo_from_la);
159
160 void obdo_refresh_inode(struct inode *dst, struct obdo *src, obd_flag valid)
161 {
162         valid &= src->o_valid;
163
164         if (valid & (OBD_MD_FLCTIME | OBD_MD_FLMTIME))
165                 CDEBUG(D_INODE,
166                        "valid "LPX64", cur time %lu/%lu, new "LPU64"/"LPU64"\n",
167                        src->o_valid, LTIME_S(dst->i_mtime),
168                        LTIME_S(dst->i_ctime), src->o_mtime, src->o_ctime);
169
170         if (valid & OBD_MD_FLATIME && src->o_atime > LTIME_S(dst->i_atime))
171                 LTIME_S(dst->i_atime) = src->o_atime;
172
173         /* mtime is always updated with ctime, but can be set in past.
174            As write and utime(2) may happen within 1 second, and utime's
175            mtime has a priority over write's one, leave mtime from mds 
176            for the same ctimes. */
177         if (valid & OBD_MD_FLCTIME && src->o_ctime > LTIME_S(dst->i_ctime)) {
178                 LTIME_S(dst->i_ctime) = src->o_ctime;
179                 if (valid & OBD_MD_FLMTIME)
180                         LTIME_S(dst->i_mtime) = src->o_mtime;
181         }
182         if (valid & OBD_MD_FLSIZE)
183                 i_size_write(dst, src->o_size);
184         /* optimum IO size */
185         if (valid & OBD_MD_FLBLKSZ && src->o_blksize > (1 << dst->i_blkbits)) {
186                 dst->i_blkbits = ffs(src->o_blksize) - 1;
187 #ifdef HAVE_INODE_BLKSIZE
188                 dst->i_blkbits = src->o_blksize;
189 #endif
190         }
191
192         if (dst->i_blkbits < CFS_PAGE_SHIFT) {
193 #ifdef HAVE_INODE_BLKSIZE
194                 dst->i_blksize = CFS_PAGE_SIZE;
195 #endif
196                 dst->i_blkbits = CFS_PAGE_SHIFT;
197         }
198
199         /* allocation of space */
200         if (valid & OBD_MD_FLBLOCKS && src->o_blocks > dst->i_blocks)
201                 dst->i_blocks = src->o_blocks;
202 }
203 EXPORT_SYMBOL(obdo_refresh_inode);
204
205 void obdo_to_inode(struct inode *dst, struct obdo *src, obd_flag valid)
206 {
207         valid &= src->o_valid;
208
209         if (valid & (OBD_MD_FLCTIME | OBD_MD_FLMTIME))
210                 CDEBUG(D_INODE,
211                        "valid "LPX64", cur time %lu/%lu, new "LPU64"/"LPU64"\n",
212                        src->o_valid, LTIME_S(dst->i_mtime),
213                        LTIME_S(dst->i_ctime), src->o_mtime, src->o_ctime);
214
215         if (valid & OBD_MD_FLATIME)
216                 LTIME_S(dst->i_atime) = src->o_atime;
217         if (valid & OBD_MD_FLMTIME)
218                 LTIME_S(dst->i_mtime) = src->o_mtime;
219         if (valid & OBD_MD_FLCTIME && src->o_ctime > LTIME_S(dst->i_ctime))
220                 LTIME_S(dst->i_ctime) = src->o_ctime;
221         if (valid & OBD_MD_FLSIZE)
222                 i_size_write(dst, src->o_size);
223         if (valid & OBD_MD_FLBLOCKS) { /* allocation of space */
224                 dst->i_blocks = src->o_blocks;
225                 if (dst->i_blocks < src->o_blocks) /* overflow */
226                         dst->i_blocks = -1;
227
228         }
229         if (valid & OBD_MD_FLBLKSZ) {
230                 dst->i_blkbits = ffs(src->o_blksize)-1;
231 #ifdef HAVE_INODE_BLKSIZE
232                 dst->i_blksize = src->o_blksize;
233 #endif
234         }
235         if (valid & OBD_MD_FLTYPE)
236                 dst->i_mode = (dst->i_mode & ~S_IFMT) | (src->o_mode & S_IFMT);
237         if (valid & OBD_MD_FLMODE)
238                 dst->i_mode = (dst->i_mode & S_IFMT) | (src->o_mode & ~S_IFMT);
239         if (valid & OBD_MD_FLUID)
240                 dst->i_uid = src->o_uid;
241         if (valid & OBD_MD_FLGID)
242                 dst->i_gid = src->o_gid;
243         if (valid & OBD_MD_FLFLAGS)
244                 dst->i_flags = src->o_flags;
245         if (valid & OBD_MD_FLGENER)
246                 dst->i_generation = src->o_generation;
247 }
248 EXPORT_SYMBOL(obdo_to_inode);
249 #endif