Whamcloud - gitweb
- many fixes about using ENTRY, RETURN, GOTO and EXIT.
[fs/lustre-release.git] / lustre / liblustre / file.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * Lustre Light file operations
5  *
6  *  Copyright (c) 2002-2004 Cluster File Systems, Inc.
7  *
8  *   This file is part of Lustre, http://www.lustre.org.
9  *
10  *   Lustre is free software; you can redistribute it and/or
11  *   modify it under the terms of version 2 of the GNU General Public
12  *   License as published by the Free Software Foundation.
13  *
14  *   Lustre is distributed in the hope that it will be useful,
15  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *   GNU General Public License for more details.
18  *
19  *   You should have received a copy of the GNU General Public License
20  *   along with Lustre; if not, write to the Free Software
21  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  */
23
24 #define DEBUG_SUBSYSTEM S_LLITE
25
26 #include <stdlib.h>
27 #include <string.h>
28 #include <assert.h>
29 #include <time.h>
30 #include <sys/types.h>
31 #include <sys/queue.h>
32 #include <fcntl.h>
33
34 #ifdef HAVE_XTIO_H
35 #include <xtio.h>
36 #endif
37 #include <sysio.h>
38 #include <fs.h>
39 #include <mount.h>
40 #include <inode.h>
41 #ifdef HAVE_FILE_H
42 #include <file.h>
43 #endif
44
45 #undef LIST_HEAD
46
47 #include "llite_lib.h"
48
49 void llu_prepare_mdc_data(struct mdc_op_data *data, struct inode *i1,
50                           struct inode *i2, const char *name,
51                           int namelen, int mode)
52 {
53         LASSERT(i1);
54         
55         ll_inode2id(&data->id1, i1);
56         if (i2)
57                 ll_inode2id(&data->id2, i2);
58
59         data->valid = 0;
60         data->name = name;
61         data->namelen = namelen;
62         data->create_mode = mode;
63         data->mod_time = CURRENT_TIME;
64 }
65
66 static void llu_inode2mdc_data(struct mdc_op_data *op_data,
67                                struct inode *inode,
68                                obd_valid valid)
69 {
70         struct llu_inode_info *lli = llu_i2info(inode);
71         obd_valid newvalid = 0;
72         
73         LASSERT(op_data != NULL);
74         LASSERT(inode != NULL);
75
76         /* put object id there all the time. */
77         if (valid & OBD_MD_FLID) {
78                 ll_inode2id(&op_data->id1, inode);
79                 newvalid |= OBD_MD_FLID;
80         }
81         
82         if (valid & OBD_MD_FLSIZE) {
83                 op_data->size = lli->lli_st_size;
84                 newvalid |= OBD_MD_MEA;
85         }
86         if (valid & OBD_MD_FLBLOCKS) {
87                 op_data->blocks = lli->lli_st_blocks;
88                 newvalid |= OBD_MD_FLBLOCKS;
89         }
90         if (valid & OBD_MD_FLFLAGS) {
91                 op_data->flags = lli->lli_st_flags;
92                 newvalid |= OBD_MD_FLFLAGS;
93         }
94         if (valid & OBD_MD_FLATIME) {
95                 op_data->atime = LTIME_S(lli->lli_st_atime);
96                 newvalid |= OBD_MD_FLATIME;
97         }
98         if (valid & OBD_MD_FLMTIME) {
99                 op_data->mtime = LTIME_S(lli->lli_st_mtime);
100                 newvalid |= OBD_MD_FLMTIME;
101         }
102         if (valid & OBD_MD_FLCTIME) {
103                 op_data->ctime = LTIME_S(lli->lli_st_ctime);
104                 newvalid |= OBD_MD_FLCTIME;
105         }
106
107         if (valid & OBD_MD_FLTYPE) {
108                 op_data->mode = (op_data->mode & S_IALLUGO) |
109                         (lli->lli_st_mode & S_IFMT);
110                 newvalid |= OBD_MD_FLTYPE;
111         }
112
113         if (valid & OBD_MD_FLMODE) {
114                 op_data->mode = (op_data->mode & S_IFMT) |
115                         (lli->lli_st_mode & S_IALLUGO);
116                 newvalid |= OBD_MD_FLMODE;
117         }
118
119         op_data->valid |= newvalid;
120 }
121
122 void obdo_refresh_inode(struct inode *dst,
123                         struct obdo *src,
124                         obd_valid valid)
125 {
126         struct llu_inode_info *lli = llu_i2info(dst);
127         valid &= src->o_valid;
128
129         if (valid & (OBD_MD_FLCTIME | OBD_MD_FLMTIME))
130                 CDEBUG(D_INODE, "valid "LPX64", cur time %lu/%lu, new %lu/%lu\n",
131                        src->o_valid, LTIME_S(lli->lli_st_mtime), 
132                        LTIME_S(lli->lli_st_ctime),
133                        (long)src->o_mtime, (long)src->o_ctime);
134
135         if (valid & OBD_MD_FLATIME && src->o_atime > LTIME_S(lli->lli_st_atime))
136                 LTIME_S(lli->lli_st_atime) = src->o_atime;
137         if (valid & OBD_MD_FLMTIME && src->o_mtime > LTIME_S(lli->lli_st_mtime))
138                 LTIME_S(lli->lli_st_mtime) = src->o_mtime;
139         if (valid & OBD_MD_FLCTIME && src->o_ctime > LTIME_S(lli->lli_st_ctime))
140                 LTIME_S(lli->lli_st_ctime) = src->o_ctime;
141         if (valid & OBD_MD_FLSIZE && src->o_size > lli->lli_st_size)
142                 lli->lli_st_size = src->o_size;
143         /* optimum IO size */
144         if (valid & OBD_MD_FLBLKSZ)
145                 lli->lli_st_blksize = src->o_blksize;
146         /* allocation of space */
147         if (valid & OBD_MD_FLBLOCKS && src->o_blocks > lli->lli_st_blocks)
148                 lli->lli_st_blocks = src->o_blocks;
149 }
150
151 static int llu_local_open(struct llu_inode_info *lli, struct lookup_intent *it)
152 {
153         struct ptlrpc_request *req = LUSTRE_IT(it)->it_data;
154         struct ll_file_data *fd;
155         struct mds_body *body;
156         ENTRY;
157
158         body = lustre_msg_buf (req->rq_repmsg, 1, sizeof (*body));
159         LASSERT (body != NULL);                 /* reply already checked out */
160         LASSERT_REPSWABBED (req, 1);            /* and swabbed down */
161
162         /* already opened? */
163         if (lli->lli_open_count++)
164                 RETURN(0);
165
166         LASSERT(!lli->lli_file_data);
167
168         OBD_ALLOC(fd, sizeof(*fd));
169         /* We can't handle this well without reorganizing ll_file_open and
170          * ll_md_close(), so don't even try right now. */
171         LASSERT(fd != NULL);
172
173         memcpy(&fd->fd_mds_och.och_fh, &body->handle, sizeof(body->handle));
174         fd->fd_mds_och.och_magic = OBD_CLIENT_HANDLE_MAGIC;
175         lli->lli_file_data = fd;
176
177         mdc_set_open_replay_data(NULL, &fd->fd_mds_och, LUSTRE_IT(it)->it_data);
178
179         RETURN(0);
180 }
181
182 int llu_iop_open(struct pnode *pnode, int flags, mode_t mode)
183 {
184         struct inode *inode = pnode->p_base->pb_ino;
185         struct llu_inode_info *lli = llu_i2info(inode);
186         struct ll_file_data *fd;
187         struct ptlrpc_request *request;
188         struct lookup_intent *it;
189         struct lov_stripe_md *lsm;
190         int rc = 0;
191         ENTRY;
192
193         liblustre_wait_event(0);
194
195         /* don't do anything for '/' */
196         if (llu_is_root_inode(inode))
197                 RETURN(0);
198
199         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu\n", lli->lli_st_ino);
200         LL_GET_INTENT(inode, it);
201
202         if (!LUSTRE_IT(it)->it_disposition)
203                 LBUG();
204
205         rc = it_open_error(DISP_OPEN_OPEN, it);
206         if (rc)
207                 GOTO(out_release, rc);
208
209         rc = llu_local_open(lli, it);
210         if (rc)
211                 LBUG();
212
213         if (!S_ISREG(lli->lli_st_mode))
214                 GOTO(out_release, rc = 0);
215                 
216         fd = lli->lli_file_data;
217
218         lsm = lli->lli_smd;
219         if (lsm == NULL) {
220                 if (fd->fd_flags & O_LOV_DELAY_CREATE) {
221                         CDEBUG(D_INODE, "object creation was delayed\n");
222                         GOTO(out_release, rc);
223                 }
224         }
225         fd->fd_flags &= ~O_LOV_DELAY_CREATE;
226
227         lli->lli_open_flags = flags & ~(O_CREAT | O_EXCL | O_TRUNC);
228
229  out_release:
230         request = LUSTRE_IT(it)->it_data;
231         ptlrpc_req_finished(request);
232
233         it->it_op_release(it);
234         OBD_FREE(it, sizeof(*it));
235
236         /* libsysio haven't doing anything for O_TRUNC. here we
237          * simply simulate it as open(...); truncate(...);
238          */
239         if (rc == 0 && (flags & O_TRUNC) &&
240             S_ISREG(lli->lli_st_mode)) {
241                 struct iattr attr;
242
243                 memset(&attr, 0, sizeof(attr));
244                 attr.ia_size = 0;
245                 attr.ia_valid |= ATTR_SIZE | ATTR_RAW;
246                 rc  = llu_setattr_raw(inode, &attr);
247                 if (rc) {
248                         CERROR("error %d truncate in open()\n", rc);
249                 }
250         }
251
252         RETURN(rc);
253 }
254
255 int llu_objects_destroy(struct ptlrpc_request *request, struct inode *dir)
256 {
257         struct mds_body *body;
258         struct lov_mds_md *eadata;
259         struct lov_stripe_md *lsm = NULL;
260         struct obd_trans_info oti = { 0 };
261         struct obdo *oa;
262         int rc;
263         ENTRY;
264
265         /* req is swabbed so this is safe */
266         body = lustre_msg_buf(request->rq_repmsg, 0, sizeof(*body));
267
268         if (!(body->valid & OBD_MD_FLEASIZE))
269                 RETURN(0);
270
271         if (body->eadatasize == 0) {
272                 CERROR("OBD_MD_FLEASIZE set but eadatasize zero\n");
273                 GOTO(out, rc = -EPROTO);
274         }
275
276         /* The MDS sent back the EA because we unlinked the last reference
277          * to this file. Use this EA to unlink the objects on the OST.
278          * It's opaque so we don't swab here; we leave it to obd_unpackmd() to
279          * check it is complete and sensible. */
280         eadata = lustre_swab_repbuf(request, 1, body->eadatasize, NULL);
281         LASSERT(eadata != NULL);
282         if (eadata == NULL) {
283                 CERROR("Can't unpack MDS EA data\n");
284                 GOTO(out, rc = -EPROTO);
285         }
286
287         rc = obd_unpackmd(llu_i2dtexp(dir), &lsm, eadata, body->eadatasize);
288         if (rc < 0) {
289                 CERROR("obd_unpackmd: %d\n", rc);
290                 GOTO(out, rc);
291         }
292         LASSERT(rc >= sizeof(*lsm));
293
294         oa = obdo_alloc();
295         if (oa == NULL)
296                 GOTO(out_free_memmd, rc = -ENOMEM);
297
298         oa->o_id = lsm->lsm_object_id;
299         oa->o_mode = body->mode & S_IFMT;
300         oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE;
301
302         if (body->valid & OBD_MD_FLCOOKIE) {
303                 oa->o_valid |= OBD_MD_FLCOOKIE;
304                 oti.oti_logcookies =
305                         lustre_msg_buf(request->rq_repmsg, 2,
306                                        sizeof(struct llog_cookie) *
307                                        lsm->lsm_stripe_count);
308                 if (oti.oti_logcookies == NULL) {
309                         oa->o_valid &= ~OBD_MD_FLCOOKIE;
310                         body->valid &= ~OBD_MD_FLCOOKIE;
311                 }
312         }
313
314         rc = obd_destroy(llu_i2dtexp(dir), oa, lsm, &oti);
315         obdo_free(oa);
316         if (rc)
317                 CERROR("obd destroy objid 0x"LPX64" error %d\n",
318                        lsm->lsm_object_id, rc);
319  out_free_memmd:
320         obd_free_memmd(llu_i2dtexp(dir), &lsm);
321  out:
322         return rc;
323 }
324
325 int llu_mdc_close(struct obd_export *mdc_exp, struct inode *inode)
326 {
327         struct llu_inode_info *lli = llu_i2info(inode);
328         struct ll_file_data *fd = lli->lli_file_data;
329         struct ptlrpc_request *req = NULL;
330         struct obd_client_handle *och = &fd->fd_mds_och;
331         struct mdc_op_data op_data;
332         int rc, valid;
333         ENTRY;
334
335         /* clear group lock, if present */
336         if (fd->fd_flags & LL_FILE_GROUP_LOCKED) {
337                 struct lov_stripe_md *lsm = llu_i2info(inode)->lli_smd;
338                 fd->fd_flags &= ~(LL_FILE_GROUP_LOCKED|LL_FILE_IGNORE_LOCK);
339                 rc = llu_extent_unlock(fd, inode, lsm, LCK_GROUP,
340                                        &fd->fd_cwlockh);
341         }
342
343         memset(&op_data, 0, sizeof(op_data));
344         id_ino(&op_data.id1) = lli->lli_st_ino;
345         op_data.valid = OBD_MD_FLID;
346         valid = OBD_MD_FLTYPE | OBD_MD_FLMODE | OBD_MD_FLSIZE |OBD_MD_FLBLOCKS |
347                 OBD_MD_FLATIME | OBD_MD_FLMTIME | OBD_MD_FLCTIME;
348         if (test_bit(LLI_F_HAVE_OST_SIZE_LOCK, &lli->lli_flags))
349                 valid |= OBD_MD_FLSIZE | OBD_MD_FLBLOCKS;
350
351         llu_inode2mdc_data(&op_data, inode, valid);
352
353         if (0 /* ll_is_inode_dirty(inode) */) {
354                 op_data.flags = MDS_BFLAG_UNCOMMITTED_WRITES;
355                 op_data.valid |= OBD_MD_FLFLAGS;
356         }
357         rc = mdc_close(mdc_exp, &op_data, och, &req);
358         if (rc == EAGAIN) {
359                 /* We are the last writer, so the MDS has instructed us to get
360                  * the file size and any write cookies, then close again. */
361                 //ll_queue_done_writing(inode);
362                 rc = 0;
363         } else if (rc) {
364                 CERROR("inode %lu close failed: rc %d\n", lli->lli_st_ino, rc);
365         } else {
366                 rc = llu_objects_destroy(req, inode);
367                 if (rc)
368                         CERROR("inode %lu ll_objects destroy: rc = %d\n",
369                                 lli->lli_st_ino, rc);
370         }
371
372         mdc_clear_open_replay_data(NULL, och);
373         ptlrpc_req_finished(req);
374         och->och_fh.cookie = DEAD_HANDLE_MAGIC;
375         lli->lli_file_data = NULL;
376         OBD_FREE(fd, sizeof(*fd));
377
378         RETURN(rc);
379 }
380
381 int llu_file_release(struct inode *inode)
382 {
383         struct ll_file_data *fd;
384         struct llu_sb_info *sbi = llu_i2sbi(inode);
385         struct llu_inode_info *lli = llu_i2info(inode);
386         int rc = 0, rc2;
387
388         ENTRY;
389         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%lu\n", lli->lli_st_ino,
390                lli->lli_st_generation);
391
392         if (llu_is_root_inode(inode))
393                 RETURN(0);
394
395         /* still opened by others? */
396         if (--lli->lli_open_count)
397                 RETURN(0);
398
399         fd = lli->lli_file_data;
400         if (!fd) /* no process opened the file after an mcreate */
401                 RETURN(0);
402
403         rc2 = llu_mdc_close(sbi->ll_md_exp, inode);
404         if (rc2 && !rc)
405                 rc = rc2;
406
407         RETURN(rc);
408 }
409
410 /*
411  * libsysio require us return 0
412  */
413 int llu_iop_close(struct inode *inode)
414 {
415         int rc;
416
417         liblustre_wait_event(0);
418
419         rc = llu_file_release(inode);
420         if (rc) {
421                 CERROR("file close error %d\n", rc);
422         }
423         /* if open count == 0 && stale_flag is set, should we
424          * remove the inode immediately? */
425         return 0;
426 }
427
428 _SYSIO_OFF_T llu_iop_pos(struct inode *ino, _SYSIO_OFF_T off)
429 {
430         ENTRY;
431
432         liblustre_wait_event(0);
433
434         if (off < 0 || off > ll_file_maxbytes(ino))
435                 RETURN(-EINVAL);
436
437         RETURN(off);
438 }
439
440 /* this isn't where truncate starts.   roughly:
441  * sys_truncate->ll_setattr_raw->vmtruncate->ll_truncate
442  * we grab the lock back in setattr_raw to avoid races. */
443 static void llu_truncate(struct inode *inode)
444 {
445         struct llu_inode_info *lli = llu_i2info(inode);
446         struct lov_stripe_md *lsm = lli->lli_smd;
447         struct obdo oa = {0};
448         int err;
449         ENTRY;
450         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%lu\n", lli->lli_st_ino,
451                lli->lli_st_generation);
452
453         if (!lsm) {
454                 CERROR("truncate on inode %lu with no objects\n", lli->lli_st_ino);
455                 EXIT;
456                 return;
457         }
458
459         oa.o_id = lsm->lsm_object_id;
460         oa.o_valid = OBD_MD_FLID;
461         obdo_from_inode(&oa, inode, OBD_MD_FLTYPE|OBD_MD_FLMODE|OBD_MD_FLATIME|
462                                     OBD_MD_FLMTIME | OBD_MD_FLCTIME);
463
464         CDEBUG(D_INFO, "calling punch for "LPX64" (all bytes after %Lu)\n",
465                oa.o_id, lli->lli_st_size);
466
467         /* truncate == punch from new size to absolute end of file */
468         /* XXX: capa is NULL here, is it correct? */
469         err = obd_punch(llu_i2dtexp(inode), &oa, lsm, lli->lli_st_size,
470                         OBD_OBJECT_EOF, NULL, NULL);
471         if (err)
472                 CERROR("obd_truncate fails (%d) ino %lu\n", err, lli->lli_st_ino);
473         else
474                 obdo_to_inode(inode, &oa, OBD_MD_FLSIZE | OBD_MD_FLBLOCKS |
475                                           OBD_MD_FLATIME | OBD_MD_FLMTIME |
476                                           OBD_MD_FLCTIME);
477
478         EXIT;
479         return;
480 }
481
482 int llu_vmtruncate(struct inode * inode, loff_t offset)
483 {
484         struct llu_inode_info *lli = llu_i2info(inode);
485
486         lli->lli_st_size = offset;
487
488         llu_truncate(inode);
489
490         return 0;
491 }