1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 1998 Peter J. Braam
5 * Copyright (C) 2001 Cluster File Systems, Inc.
6 * Copyright (C) 2001 Tacit Networks, Inc. <phil@off.net>
8 * Support for journalling extended attributes
9 * Copyright (C) 2001 Shirish H. Phatak, Tacit Networks, Inc.
11 * This file is part of InterMezzo, http://www.inter-mezzo.org.
13 * InterMezzo is free software; you can redistribute it and/or
14 * modify it under the terms of version 2 of the GNU General Public
15 * License as published by the Free Software Foundation.
17 * InterMezzo is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with InterMezzo; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include <linux/types.h>
28 #include <linux/kernel.h>
29 #include <linux/sched.h>
31 #include <linux/namei.h>
32 #include <linux/slab.h>
33 #include <linux/vmalloc.h>
34 #include <linux/time.h>
35 #include <linux/errno.h>
36 #include <linux/smp_lock.h>
37 #include <asm/segment.h>
38 #include <asm/uaccess.h>
39 #include <linux/string.h>
40 #include <linux/smp_lock.h>
41 #include <linux/intermezzo_fs.h>
42 #include <linux/intermezzo_psdev.h>
44 struct presto_reservation_data
{
45 unsigned int ri_recno
;
48 struct list_head ri_list
;
54 * write lock in struct presto_log_fd:
56 * - required for: accessing any field in a presto_log_fd
57 * - may not be held across I/O
63 * reserve record space and/or atomically request state of the log
64 * rec will hold the location reserved record upon return
65 * this reservation will be placed in the queue
67 static void presto_reserve_record(struct presto_file_set
*fset
,
68 struct presto_log_fd
*fd
,
70 struct presto_reservation_data
*rd
)
72 int chunked_record
= 0;
75 write_lock(&fd
->fd_lock
);
77 int chunk
= 1 << fset
->fset_chunkbits
;
78 int chunk_mask
= ~(chunk
-1);
81 boundary
= (fd
->fd_offset
+ chunk
- 1) & chunk_mask
;
82 if ( fd
->fd_offset
+ rec
->size
>= boundary
) {
84 fd
->fd_offset
= boundary
;
90 /* this moves the fd_offset back after truncation */
91 if ( list_empty(&fd
->fd_reservations
) &&
93 fd
->fd_offset
= fd
->fd_file
->f_dentry
->d_inode
->i_size
;
96 rec
->offset
= fd
->fd_offset
;
98 rec
->offset
+= fset
->fset_kml_logical_off
;
100 rec
->recno
= fd
->fd_recno
;
102 /* add the reservation data to the end of the list */
103 rd
->ri_offset
= fd
->fd_offset
;
104 rd
->ri_size
= rec
->size
;
105 rd
->ri_recno
= rec
->recno
;
106 list_add(&rd
->ri_list
, fd
->fd_reservations
.prev
);
108 fd
->fd_offset
+= rec
->size
;
110 write_unlock(&fd
->fd_lock
);
115 static inline void presto_release_record(struct presto_log_fd
*fd
,
116 struct presto_reservation_data
*rd
)
118 write_lock(&fd
->fd_lock
);
119 list_del(&rd
->ri_list
);
120 write_unlock(&fd
->fd_lock
);
123 /* XXX should we ask for do_truncate to be exported? */
124 int izo_do_truncate(struct presto_file_set
*fset
, struct dentry
*dentry
,
125 loff_t length
, loff_t size_check
)
127 struct inode
*inode
= dentry
->d_inode
;
129 struct iattr newattrs
;
141 if (size_check
!= inode
->i_size
) {
148 newattrs
.ia_size
= length
;
149 newattrs
.ia_valid
= ATTR_SIZE
| ATTR_CTIME
;
151 if (inode
->i_op
&& inode
->i_op
->setattr
)
152 error
= inode
->i_op
->setattr(dentry
, &newattrs
);
154 inode_setattr(dentry
->d_inode
, &newattrs
);
164 static void presto_kml_truncate(struct presto_file_set
*fset
)
169 write_lock(&fset
->fset_kml
.fd_lock
);
170 if (fset
->fset_kml
.fd_truncating
== 1 ) {
171 write_unlock(&fset
->fset_kml
.fd_lock
);
176 fset
->fset_kml
.fd_truncating
= 1;
177 write_unlock(&fset
->fset_kml
.fd_lock
);
179 CERROR("islento: %d, count: %d\n",
180 ISLENTO(presto_i2m(fset
->fset_dentry
->d_inode
)),
181 fset
->fset_permit_count
);
183 rc
= izo_upc_kml_truncate(fset
->fset_cache
->cache_psdev
->uc_minor
,
184 fset
->fset_lento_off
, fset
->fset_lento_recno
,
187 /* Userspace is the only permitholder now, and will retain an exclusive
188 * hold on the permit until KML truncation completes. */
189 /* FIXME: double check this code path now that the precise semantics of
190 * fset->fset_permit_count have changed. */
193 write_lock(&fset
->fset_kml
.fd_lock
);
194 fset
->fset_kml
.fd_truncating
= 0;
195 write_unlock(&fset
->fset_kml
.fd_lock
);
201 void *presto_trans_start(struct presto_file_set
*fset
, struct inode
*inode
,
205 if ( !fset
->fset_cache
->cache_filter
->o_trops
) {
210 return fset
->fset_cache
->cache_filter
->o_trops
->tr_start
214 void presto_trans_commit(struct presto_file_set
*fset
, void *handle
)
217 if (!fset
->fset_cache
->cache_filter
->o_trops
) {
222 fset
->fset_cache
->cache_filter
->o_trops
->tr_commit(fset
, handle
);
224 /* Check to see if the KML needs truncated. */
225 if (fset
->kml_truncate_size
> 0 &&
226 !fset
->fset_kml
.fd_truncating
&&
227 fset
->fset_kml
.fd_offset
> fset
->kml_truncate_size
) {
228 CDEBUG(D_JOURNAL
, "kml size: %lu; truncating\n",
229 (unsigned long)fset
->fset_kml
.fd_offset
);
230 presto_kml_truncate(fset
);
235 inline int presto_no_journal(struct presto_file_set
*fset
)
237 int minor
= fset
->fset_cache
->cache_psdev
->uc_minor
;
238 return izo_channels
[minor
].uc_no_journal
;
241 #define size_round(x) (((x)+3) & ~0x3)
243 #define BUFF_FREE(buf) PRESTO_FREE(buf, PAGE_SIZE)
244 #define BUFF_ALLOC(newbuf, oldbuf) \
245 PRESTO_ALLOC(newbuf, PAGE_SIZE); \
253 * "buflen" should be PAGE_SIZE or more.
254 * Give relative path wrt to a fsetroot
256 char * presto_path(struct dentry
*dentry
, struct dentry
*root
,
257 char *buffer
, int buflen
)
259 char * end
= buffer
+buflen
;
264 if (dentry
->d_parent
!= dentry
&& list_empty(&dentry
->d_hash
)) {
267 memcpy(end
, " (deleted)", 10);
275 struct dentry
* parent
;
280 parent
= dentry
->d_parent
;
281 if (dentry
== parent
)
283 namelen
= dentry
->d_name
.len
;
284 buflen
-= namelen
+ 1;
288 memcpy(end
, dentry
->d_name
.name
, namelen
);
296 static inline char *logit(char *buf
, const void *value
, int size
)
298 char *ptr
= (char *)value
;
300 memcpy(buf
, ptr
, size
);
307 journal_log_prefix_with_groups_and_ids(char *buf
, int opcode
,
308 struct rec_info
*rec
,
309 __u32 ngroups
, gid_t
*groups
,
310 __u32 fsuid
, __u32 fsgid
)
312 struct kml_prefix_hdr p
;
313 u32 loggroups
[NGROUPS_MAX
];
317 p
.len
= cpu_to_le32(rec
->size
);
318 p
.version
= KML_MAJOR_VERSION
| KML_MINOR_VERSION
;
319 p
.pid
= cpu_to_le32(current
->pid
);
320 p
.auid
= cpu_to_le32(current
->uid
);
321 p
.fsuid
= cpu_to_le32(fsuid
);
322 p
.fsgid
= cpu_to_le32(fsgid
);
323 p
.ngroups
= cpu_to_le32(ngroups
);
324 p
.opcode
= cpu_to_le32(opcode
);
325 for (i
=0 ; i
< ngroups
; i
++)
326 loggroups
[i
] = cpu_to_le32((__u32
) groups
[i
]);
328 buf
= logit(buf
, &p
, sizeof(struct kml_prefix_hdr
));
329 buf
= logit(buf
, &loggroups
, sizeof(__u32
) * ngroups
);
334 journal_log_prefix(char *buf
, int opcode
, struct rec_info
*rec
)
336 __u32 groups
[NGROUPS_MAX
];
339 /* convert 16 bit gid's to 32 bit gid's */
340 for (i
=0; i
<current
->ngroups
; i
++)
341 groups
[i
] = (__u32
) current
->groups
[i
];
343 return journal_log_prefix_with_groups_and_ids(buf
, opcode
, rec
,
344 (__u32
)current
->ngroups
,
346 (__u32
)current
->fsuid
,
347 (__u32
)current
->fsgid
);
351 journal_log_prefix_with_groups(char *buf
, int opcode
, struct rec_info
*rec
,
352 __u32 ngroups
, gid_t
*groups
)
354 return journal_log_prefix_with_groups_and_ids(buf
, opcode
, rec
,
356 (__u32
)current
->fsuid
,
357 (__u32
)current
->fsgid
);
360 static inline char *log_dentry_version(char *buf
, struct dentry
*dentry
)
362 struct presto_version version
;
364 presto_getversion(&version
, dentry
->d_inode
);
366 version
.pv_mtime
= HTON__u64(version
.pv_mtime
);
367 version
.pv_ctime
= HTON__u64(version
.pv_ctime
);
368 version
.pv_size
= HTON__u64(version
.pv_size
);
370 return logit(buf
, &version
, sizeof(version
));
373 static inline char *log_version(char *buf
, struct presto_version
*pv
)
375 struct presto_version version
;
377 memcpy(&version
, pv
, sizeof(version
));
379 version
.pv_mtime
= HTON__u64(version
.pv_mtime
);
380 version
.pv_ctime
= HTON__u64(version
.pv_ctime
);
381 version
.pv_size
= HTON__u64(version
.pv_size
);
383 return logit(buf
, &version
, sizeof(version
));
386 static inline char *log_rollback(char *buf
, struct izo_rollback_data
*rb
)
388 struct izo_rollback_data rollback
;
390 memcpy(&rollback
, rb
, sizeof(rollback
));
392 rollback
.rb_mode
= HTON__u32(rollback
.rb_mode
);
393 rollback
.rb_rdev
= HTON__u32(rollback
.rb_rdev
);
394 rollback
.rb_uid
= HTON__u64(rollback
.rb_uid
);
395 rollback
.rb_gid
= HTON__u64(rollback
.rb_gid
);
397 return logit(buf
, &rollback
, sizeof(rollback
));
400 static inline char *journal_log_suffix(char *buf
, char *log
,
401 struct presto_file_set
*fset
,
402 struct dentry
*dentry
,
403 struct rec_info
*rec
)
406 struct kml_prefix_hdr
*p
= (struct kml_prefix_hdr
*)log
;
409 /* XXX needs to be done after reservation,
410 disable ths until version 1.2 */
412 s
.prevrec
= cpu_to_le32(rec
->offset
-
413 presto_d2d(dentry
)->dd_kml_offset
);
414 presto_d2d(dentry
)->dd_kml_offset
= rec
->offset
;
421 /* record number needs to be filled in after reservation
422 s.recno = cpu_to_le32(rec->recno); */
423 s
.time
= cpu_to_le32(get_seconds());
425 return logit(buf
, &s
, sizeof(s
));
428 int izo_log_close(struct presto_log_fd
*logfd
)
432 if (logfd
->fd_file
) {
433 rc
= filp_close(logfd
->fd_file
, 0);
434 logfd
->fd_file
= NULL
;
436 CERROR("InterMezzo: %s: no filp\n", __FUNCTION__
);
438 CERROR("InterMezzo: close files: filp won't close: %d\n", rc
);
443 int presto_fwrite(struct file
*file
, const char *str
, int len
, loff_t
*off
)
460 if ( ! file
->f_op
) {
465 if ( ! file
->f_op
->write
) {
472 rc
= file
->f_op
->write(file
, str
, len
, off
);
474 CERROR("presto_fwrite: wrote %d bytes instead of "
475 "%d at %ld\n", rc
, len
, (long)*off
);
483 int presto_fread(struct file
*file
, char *str
, int len
, loff_t
*off
)
490 CERROR("presto_fread: read at %Ld for %d bytes, ino %ld\n",
491 *off
, len
, file
->f_dentry
->d_inode
->i_ino
);
504 if ( ! file
->f_op
) {
509 if ( ! file
->f_op
->read
) {
516 rc
= file
->f_op
->read(file
, str
, len
, off
);
518 CDEBUG(D_FILE
, "presto_fread: read %d bytes instead of "
519 "%d at %Ld\n", rc
, len
, *off
);
527 loff_t
presto_kml_offset(struct presto_file_set
*fset
)
529 unsigned int kml_recno
;
530 struct presto_log_fd
*fd
= &fset
->fset_kml
;
534 write_lock(&fd
->fd_lock
);
536 /* Determine the largest valid offset, i.e. up until the first
537 * reservation held on the file. */
538 if ( !list_empty(&fd
->fd_reservations
) ) {
539 struct presto_reservation_data
*rd
;
540 rd
= list_entry(fd
->fd_reservations
.next
,
541 struct presto_reservation_data
,
543 offset
= rd
->ri_offset
;
544 kml_recno
= rd
->ri_recno
;
546 offset
= fd
->fd_file
->f_dentry
->d_inode
->i_size
;
547 kml_recno
= fset
->fset_kml
.fd_recno
;
549 write_unlock(&fd
->fd_lock
);
553 static int presto_kml_dispatch(struct presto_file_set
*fset
)
556 unsigned int kml_recno
;
557 struct presto_log_fd
*fd
= &fset
->fset_kml
;
561 write_lock(&fd
->fd_lock
);
563 /* Determine the largest valid offset, i.e. up until the first
564 * reservation held on the file. */
565 if ( !list_empty(&fd
->fd_reservations
) ) {
566 struct presto_reservation_data
*rd
;
567 rd
= list_entry(fd
->fd_reservations
.next
,
568 struct presto_reservation_data
,
570 offset
= rd
->ri_offset
;
571 kml_recno
= rd
->ri_recno
;
573 offset
= fd
->fd_file
->f_dentry
->d_inode
->i_size
;
574 kml_recno
= fset
->fset_kml
.fd_recno
;
577 if ( kml_recno
< fset
->fset_lento_recno
) {
578 CERROR("presto_kml_dispatch: smoke is coming\n");
579 write_unlock(&fd
->fd_lock
);
582 } else if ( kml_recno
== fset
->fset_lento_recno
) {
583 write_unlock(&fd
->fd_lock
);
586 /* XXX add a further "if" here to delay the KML upcall */
588 } else if ( kml_recno
< fset
->fset_lento_recno
+ 100) {
589 write_unlock(&fd
->fd_lock
);
594 CDEBUG(D_PIOCTL
, "fset: %s\n", fset
->fset_name
);
596 rc
= izo_upc_kml(fset
->fset_cache
->cache_psdev
->uc_minor
,
597 fset
->fset_lento_off
, fset
->fset_lento_recno
,
598 offset
+ fset
->fset_kml_logical_off
, kml_recno
,
602 write_unlock(&fd
->fd_lock
);
607 fset
->fset_lento_off
= offset
;
608 fset
->fset_lento_recno
= kml_recno
;
609 write_unlock(&fd
->fd_lock
);
614 int izo_lookup_file(struct presto_file_set
*fset
, char *path
,
615 struct nameidata
*nd
)
619 CDEBUG(D_CACHE
, "looking up: %s\n", path
);
621 error
= path_lookup(path
, LOOKUP_PARENT
, nd
);
630 /* FIXME: this function is a mess of locking and error handling. There's got to
631 * be a better way. */
632 static int do_truncate_rename(struct presto_file_set
*fset
, char *oldname
,
635 struct dentry
*old_dentry
, *new_dentry
;
636 struct nameidata oldnd
, newnd
;
637 char *oldpath
, *newpath
;
642 oldpath
= izo_make_path(fset
, oldname
);
643 if (oldpath
== NULL
) {
648 newpath
= izo_make_path(fset
, newname
);
649 if (newpath
== NULL
) {
655 if ((error
= izo_lookup_file(fset
, oldpath
, &oldnd
)) != 0) {
660 if ((error
= izo_lookup_file(fset
, newpath
, &newnd
)) != 0) {
665 lock_rename(newnd
.dentry
, oldnd
.dentry
);
666 old_dentry
= lookup_hash(&oldnd
.last
, oldnd
.dentry
);
667 error
= PTR_ERR(old_dentry
);
668 if (IS_ERR(old_dentry
)) {
673 if (!old_dentry
->d_inode
) {
677 new_dentry
= lookup_hash(&newnd
.last
, newnd
.dentry
);
678 error
= PTR_ERR(new_dentry
);
679 if (IS_ERR(new_dentry
)) {
685 extern int presto_rename(struct inode
*old_dir
,struct dentry
*old_dentry
,
686 struct inode
*new_dir
,struct dentry
*new_dentry
);
687 error
= presto_rename(old_dentry
->d_parent
->d_inode
, old_dentry
,
688 new_dentry
->d_parent
->d_inode
, new_dentry
);
696 unlock_rename(newnd
.dentry
, oldnd
.dentry
);
697 path_release(&newnd
);
699 path_release(&oldnd
);
701 PRESTO_FREE(newpath
, strlen(newpath
) + 1);
703 PRESTO_FREE(oldpath
, strlen(oldpath
) + 1);
707 /* This function is called with the fset->fset_kml.fd_lock held */
708 int presto_finish_kml_truncate(struct presto_file_set
*fset
,
709 unsigned long int offset
)
711 struct lento_vfs_context info
;
714 struct dentry
*dentry
;
717 char *kmlpath
= NULL
, *smlpath
= NULL
;
721 /* Lento couldn't do what it needed to; abort the truncation. */
722 fset
->fset_kml
.fd_truncating
= 0;
727 /* someone is about to write to the end of the KML; try again later. */
728 if ( !list_empty(&fset
->fset_kml
.fd_reservations
) ) {
733 f
= presto_copy_kml_tail(fset
, offset
);
739 /* In a single transaction:
742 * - rename 'kml_tmp' to 'kml'
744 * - rename 'sml_tmp' to 'sml'
745 * - rewrite the first record of last_rcvd with the new kml
748 handle
= presto_trans_start(fset
, fset
->fset_dentry
->d_inode
,
749 KML_OPCODE_KML_TRUNC
);
750 if (IS_ERR(handle
)) {
751 presto_release_space(fset
->fset_cache
, PRESTO_REQLOW
);
752 CERROR("ERROR: presto_finish_kml_truncate: no space for transaction\n");
757 memset(&info
, 0, sizeof(info
));
758 info
.flags
= LENTO_FL_IGNORE_TIME
;
760 kmlpath
= izo_make_path(fset
, "kml");
761 if (kmlpath
== NULL
) {
763 CERROR("make_path failed: ENOMEM\n");
768 if ((error
= izo_lookup_file(fset
, kmlpath
, &nd
)) != 0) {
769 CERROR("izo_lookup_file(kml) failed: %d.\n", error
);
773 down(&nd
.dentry
->d_inode
->i_sem
);
774 dentry
= lookup_hash(&nd
.last
, nd
.dentry
);
775 error
= PTR_ERR(dentry
);
776 if (IS_ERR(dentry
)) {
777 up(&nd
.dentry
->d_inode
->i_sem
);
779 CERROR("lookup_hash failed\n");
783 error
= presto_do_unlink(fset
, dentry
->d_parent
, dentry
, &info
);
785 up(&nd
.dentry
->d_inode
->i_sem
);
789 CERROR("presto_do_unlink(kml) failed: %d.\n", error
);
794 smlpath
= izo_make_path(fset
, "sml");
795 if (smlpath
== NULL
) {
797 CERROR("make_path() failed: ENOMEM\n");
802 if ((error
= izo_lookup_file(fset
, smlpath
, &nd
)) != 0) {
803 CERROR("izo_lookup_file(sml) failed: %d.\n", error
);
807 down(&nd
.dentry
->d_inode
->i_sem
);
808 dentry
= lookup_hash(&nd
.last
, nd
.dentry
);
809 error
= PTR_ERR(dentry
);
810 if (IS_ERR(dentry
)) {
811 up(&nd
.dentry
->d_inode
->i_sem
);
813 CERROR("lookup_hash failed\n");
817 error
= presto_do_unlink(fset
, dentry
->d_parent
, dentry
, &info
);
819 up(&nd
.dentry
->d_inode
->i_sem
);
823 CERROR("presto_do_unlink(sml) failed: %d.\n", error
);
828 error
= do_truncate_rename(fset
, "kml_tmp", "kml");
830 CERROR("do_truncate_rename(kml_tmp, kml) failed: %d\n", error
);
831 error
= do_truncate_rename(fset
, "sml_tmp", "sml");
833 CERROR("do_truncate_rename(sml_tmp, sml) failed: %d\n", error
);
835 /* Write a new 'last_rcvd' record with the new KML offset */
836 fset
->fset_kml_logical_off
+= offset
;
837 CDEBUG(D_CACHE
, "new kml_logical_offset: %Lu\n",
838 fset
->fset_kml_logical_off
);
839 if (presto_write_kml_logical_offset(fset
) != 0) {
840 CERROR("presto_write_kml_logical_offset failed\n");
843 presto_trans_commit(fset
, handle
);
845 /* Everything was successful, so swap the KML file descriptors */
846 filp_close(fset
->fset_kml
.fd_file
, NULL
);
847 fset
->fset_kml
.fd_file
= f
;
848 fset
->fset_kml
.fd_offset
-= offset
;
849 fset
->fset_kml
.fd_truncating
= 0;
855 presto_trans_commit(fset
, handle
);
856 len
= strlen("/.intermezzo/") + strlen(fset
->fset_name
) +strlen("sml");
858 PRESTO_FREE(kmlpath
, len
);
860 PRESTO_FREE(smlpath
, len
);
864 /* structure of an extended log record:
866 buf-prefix buf-body [string1 [string2 [string3]]] buf-suffix
868 note: moves offset forward
870 static inline int presto_write_record(struct file
*f
, loff_t
*off
,
871 const char *buf
, size_t size
,
872 const char *string1
, int len1
,
873 const char *string2
, int len2
,
874 const char *string3
, int len3
)
879 prefix_size
= size
- sizeof(struct kml_suffix
);
880 rc
= presto_fwrite(f
, buf
, prefix_size
, off
);
881 if ( rc
!= prefix_size
) {
882 CERROR("Write error!\n");
887 if ( string1
&& len1
) {
888 rc
= presto_fwrite(f
, string1
, len1
, off
);
890 CERROR("Write error!\n");
896 if ( string2
&& len2
) {
897 rc
= presto_fwrite(f
, string2
, len2
, off
);
899 CERROR("Write error!\n");
905 if ( string3
&& len3
) {
906 rc
= presto_fwrite(f
, string3
, len3
, off
);
908 CERROR("Write error!\n");
914 rc
= presto_fwrite(f
, buf
+ prefix_size
,
915 sizeof(struct kml_suffix
), off
);
916 if ( rc
!= sizeof(struct kml_suffix
) ) {
917 CERROR("Write error!\n");
926 * rec->size must be valid prior to calling this function.
928 * had to export this for branch_reinter in kml_reint.c
930 int presto_log(struct presto_file_set
*fset
, struct rec_info
*rec
,
931 const char *buf
, size_t size
,
932 const char *string1
, int len1
,
933 const char *string2
, int len2
,
934 const char *string3
, int len3
)
937 struct presto_reservation_data rd
;
939 struct presto_log_fd
*fd
;
940 struct kml_suffix
*s
;
945 /* buf is NULL when no_journal is in effect */
952 fd
= &fset
->fset_kml
;
954 fd
= &fset
->fset_lml
;
957 presto_reserve_record(fset
, fd
, rec
, &rd
);
960 if (rec
->offset
< fset
->fset_kml_logical_off
) {
961 CERROR("record with pre-trunc offset. tell phil.\n");
964 offset
= rec
->offset
- fset
->fset_kml_logical_off
;
966 offset
= rec
->offset
;
969 /* now we know the record number */
970 prefix_size
= size
- sizeof(struct kml_suffix
);
971 s
= (struct kml_suffix
*) (buf
+ prefix_size
);
972 s
->recno
= cpu_to_le32(rec
->recno
);
974 rc
= presto_write_record(fd
->fd_file
, &offset
, buf
, size
,
975 string1
, len1
, string2
, len2
, string3
, len3
);
977 CERROR("presto: error writing record to %s\n",
978 rec
->is_kml
? "KML" : "LML");
981 presto_release_record(fd
, &rd
);
983 rc
= presto_kml_dispatch(fset
);
989 /* read from the record at tail */
990 static int presto_last_record(struct presto_log_fd
*fd
, loff_t
*size
,
991 loff_t
*tail_offset
, __u32
*recno
, loff_t tail
)
993 struct kml_suffix suffix
;
1001 if (tail
< sizeof(struct kml_prefix_hdr
) + sizeof(suffix
)) {
1006 zeroes
= tail
- sizeof(int);
1007 while ( zeroes
>= 0 ) {
1009 rc
= presto_fread(fd
->fd_file
, (char *)&data
, sizeof(data
),
1011 if ( rc
!= sizeof(data
) ) {
1017 zeroes
-= 2 * sizeof(data
);
1020 /* zeroes at the begining of file. this is needed to prevent
1021 presto_fread errors -SHP
1023 if (zeroes
<= 0) return 0;
1025 zeroes
-= sizeof(suffix
) + sizeof(int);
1026 rc
= presto_fread(fd
->fd_file
, (char *)&suffix
, sizeof(suffix
), &zeroes
);
1027 if ( rc
!= sizeof(suffix
) ) {
1031 if ( suffix
.len
> 500 ) {
1032 CERROR("InterMezzo: Warning long record tail at %ld, rec tail_offset at %ld (size %d)\n",
1033 (long) zeroes
, (long)*tail_offset
, suffix
.len
);
1036 *recno
= suffix
.recno
;
1038 *tail_offset
= zeroes
;
1042 static int izo_kml_last_recno(struct presto_log_fd
*logfd
)
1048 loff_t tail
= logfd
->fd_file
->f_dentry
->d_inode
->i_size
;
1050 rc
= presto_last_record(logfd
, &size
, &tail_offset
, &recno
, tail
);
1056 logfd
->fd_offset
= tail_offset
;
1057 logfd
->fd_recno
= recno
;
1058 CDEBUG(D_JOURNAL
, "setting fset_kml->fd_recno to %d, offset %Ld\n",
1059 recno
, tail_offset
);
1064 struct file
*izo_log_open(struct presto_file_set
*fset
, char *name
, int flags
)
1066 struct presto_cache
*cache
= fset
->fset_cache
;
1071 f
= izo_fset_open(fset
, name
, flags
, 0644);
1079 if ( cache
!= presto_get_cache(f
->f_dentry
->d_inode
) ) {
1080 CERROR("InterMezzo: %s cache does not match fset cache!\n",name
);
1081 fset
->fset_kml
.fd_file
= NULL
;
1082 filp_close(f
, NULL
);
1088 if (cache
->cache_filter
&& cache
->cache_filter
->o_trops
&&
1089 cache
->cache_filter
->o_trops
->tr_journal_data
) {
1090 cache
->cache_filter
->o_trops
->tr_journal_data
1091 (f
->f_dentry
->d_inode
);
1093 CERROR("InterMezzo WARNING: no file data logging!\n");
1101 int izo_init_kml_file(struct presto_file_set
*fset
, struct presto_log_fd
*logfd
)
1107 if (logfd
->fd_file
) {
1108 CDEBUG(D_INODE
, "fset already has KML open\n");
1113 logfd
->fd_lock
= RW_LOCK_UNLOCKED
;
1114 INIT_LIST_HEAD(&logfd
->fd_reservations
);
1115 f
= izo_log_open(fset
, "kml", O_RDWR
| O_CREAT
);
1122 error
= izo_kml_last_recno(logfd
);
1125 logfd
->fd_file
= NULL
;
1126 filp_close(f
, NULL
);
1127 CERROR("InterMezzo: IO error in KML of fset %s\n",
1132 fset
->fset_lento_off
= logfd
->fd_offset
;
1133 fset
->fset_lento_recno
= logfd
->fd_recno
;
1139 int izo_init_last_rcvd_file(struct presto_file_set
*fset
, struct presto_log_fd
*logfd
)
1143 struct rec_info recinfo
;
1146 if (logfd
->fd_file
!= NULL
) {
1147 CDEBUG(D_INODE
, "fset already has last_rcvd open\n");
1152 logfd
->fd_lock
= RW_LOCK_UNLOCKED
;
1153 INIT_LIST_HEAD(&logfd
->fd_reservations
);
1154 f
= izo_log_open(fset
, "last_rcvd", O_RDWR
| O_CREAT
);
1161 logfd
->fd_offset
= f
->f_dentry
->d_inode
->i_size
;
1163 error
= izo_rep_cache_init(fset
);
1165 if (presto_read_kml_logical_offset(&recinfo
, fset
) == 0) {
1166 fset
->fset_kml_logical_off
= recinfo
.offset
;
1168 /* The 'last_rcvd' file doesn't contain a kml offset record,
1169 * probably because we just created 'last_rcvd'. Write one. */
1170 fset
->fset_kml_logical_off
= 0;
1171 presto_write_kml_logical_offset(fset
);
1178 int izo_init_lml_file(struct presto_file_set
*fset
, struct presto_log_fd
*logfd
)
1184 if (logfd
->fd_file
) {
1185 CDEBUG(D_INODE
, "fset already has lml open\n");
1190 logfd
->fd_lock
= RW_LOCK_UNLOCKED
;
1191 INIT_LIST_HEAD(&logfd
->fd_reservations
);
1192 f
= izo_log_open(fset
, "lml", O_RDWR
| O_CREAT
);
1199 logfd
->fd_offset
= f
->f_dentry
->d_inode
->i_size
;
1205 /* Get the KML-offset record from the last_rcvd file */
1206 int presto_read_kml_logical_offset(struct rec_info
*recinfo
,
1207 struct presto_file_set
*fset
)
1210 struct izo_rcvd_rec rec
;
1211 char uuid
[16] = {0};
1213 off
= izo_rcvd_get(&rec
, fset
, uuid
);
1217 recinfo
->offset
= rec
.lr_local_offset
;
1221 int presto_write_kml_logical_offset(struct presto_file_set
*fset
)
1224 struct izo_rcvd_rec rec
;
1225 char uuid
[16] = {0};
1227 rc
= izo_rcvd_get(&rec
, fset
, uuid
);
1229 memset(&rec
, 0, sizeof(rec
));
1231 rec
.lr_local_offset
=
1232 cpu_to_le64(fset
->fset_kml_logical_off
);
1234 return izo_rcvd_write(fset
, &rec
);
1237 struct file
* presto_copy_kml_tail(struct presto_file_set
*fset
,
1238 unsigned long int start
)
1242 loff_t read_off
, write_off
, bytes
;
1246 /* Copy the tail of 'kml' to 'kml_tmp' */
1247 f
= izo_log_open(fset
, "kml_tmp", O_RDWR
);
1255 bytes
= fset
->fset_kml
.fd_offset
- start
;
1260 if (bytes
> sizeof(buf
))
1261 toread
= sizeof(buf
);
1265 len
= presto_fread(fset
->fset_kml
.fd_file
, buf
, toread
,
1270 if (presto_fwrite(f
, buf
, len
, &write_off
) != len
) {
1271 filp_close(f
, NULL
);
1273 return ERR_PTR(-EIO
);
1284 /* LML records here */
1285 /* this writes an LML record to the LML file (rec->is_kml =0) */
1286 int presto_write_lml_close(struct rec_info
*rec
,
1287 struct presto_file_set
*fset
,
1290 __u64 remote_generation
,
1291 struct presto_version
*remote_version
,
1292 struct presto_version
*new_file_ver
)
1294 int opcode
= KML_OPCODE_CLOSE
;
1296 struct dentry
*dentry
= file
->f_dentry
;
1304 struct dentry
*root
;
1309 if ( presto_no_journal(fset
) ) {
1313 root
= fset
->fset_dentry
;
1315 BUFF_ALLOC(buffer
, NULL
);
1316 path
= presto_path(dentry
, root
, buffer
, PAGE_SIZE
);
1317 CDEBUG(D_INODE
, "Path: %s\n", path
);
1318 pathlen
= cpu_to_le32(MYPATHLEN(buffer
, path
));
1319 ino
= cpu_to_le64(dentry
->d_inode
->i_ino
);
1320 generation
= cpu_to_le32(dentry
->d_inode
->i_generation
);
1321 size
= sizeof(__u32
) * current
->ngroups
+
1322 sizeof(struct kml_prefix_hdr
) + sizeof(*new_file_ver
) +
1323 sizeof(ino
) + sizeof(generation
) + sizeof(pathlen
) +
1324 sizeof(remote_ino
) + sizeof(remote_generation
) +
1325 sizeof(remote_version
) + sizeof(rec
->offset
) +
1326 sizeof(struct kml_suffix
);
1328 if ( size
> sizeof(record
) )
1329 CERROR("InterMezzo: BUFFER OVERFLOW in %s!\n", __FUNCTION__
);
1332 rec
->size
= size
+ size_round(le32_to_cpu(pathlen
));
1334 logrecord
= journal_log_prefix(record
, opcode
, rec
);
1335 logrecord
= log_version(logrecord
, new_file_ver
);
1336 logrecord
= logit(logrecord
, &ino
, sizeof(ino
));
1337 logrecord
= logit(logrecord
, &generation
, sizeof(generation
));
1338 logrecord
= logit(logrecord
, &pathlen
, sizeof(pathlen
));
1339 logrecord
= logit(logrecord
, &remote_ino
, sizeof(remote_ino
));
1340 logrecord
= logit(logrecord
, &remote_generation
,
1341 sizeof(remote_generation
));
1342 logrecord
= log_version(logrecord
, remote_version
);
1343 logrecord
= logit(logrecord
, &rec
->offset
, sizeof(rec
->offset
));
1344 logrecord
= journal_log_suffix(logrecord
, record
, fset
, dentry
, rec
);
1346 error
= presto_log(fset
, rec
, record
, size
,
1347 path
, size_round(le32_to_cpu(pathlen
)),
1357 * Check if the given record is at the end of the file. If it is, truncate
1358 * the lml to the record's offset, removing it. Repeat on prior record,
1359 * until we reach an active record or a reserved record (as defined by the
1360 * reservations list).
1362 static int presto_truncate_lml_tail(struct presto_file_set
*fset
)
1365 loff_t lml_last_rec
;
1366 loff_t lml_last_recsize
;
1367 loff_t local_offset
;
1369 struct kml_prefix_hdr prefix
;
1370 struct inode
*inode
= fset
->fset_lml
.fd_file
->f_dentry
->d_inode
;
1375 /* If someone else is already truncating the LML, return. */
1376 write_lock(&fset
->fset_lml
.fd_lock
);
1377 if (fset
->fset_lml
.fd_truncating
== 1 ) {
1378 write_unlock(&fset
->fset_lml
.fd_lock
);
1382 /* someone is about to write to the end of the LML */
1383 if ( !list_empty(&fset
->fset_lml
.fd_reservations
) ) {
1384 write_unlock(&fset
->fset_lml
.fd_lock
);
1388 lml_tail
= fset
->fset_lml
.fd_file
->f_dentry
->d_inode
->i_size
;
1389 /* Nothing to truncate?*/
1390 if (lml_tail
== 0) {
1391 write_unlock(&fset
->fset_lml
.fd_lock
);
1395 fset
->fset_lml
.fd_truncating
= 1;
1396 write_unlock(&fset
->fset_lml
.fd_lock
);
1398 presto_last_record(&fset
->fset_lml
, &lml_last_recsize
,
1399 &lml_last_rec
, &recno
, lml_tail
);
1400 /* Do we have a record to check? If not we have zeroes at the
1401 beginning of the file. -SHP
1403 if (lml_last_recsize
!= 0) {
1404 local_offset
= lml_last_rec
- lml_last_recsize
;
1405 rc
= presto_fread(fset
->fset_lml
.fd_file
, (char *)&prefix
,
1406 sizeof(prefix
), &local_offset
);
1407 if (rc
!= sizeof(prefix
)) {
1412 if ( prefix
.opcode
!= KML_OPCODE_NOOP
) {
1415 /* We may have zeroes at the end of the file, should
1416 we clear them out? -SHP
1423 handle
= presto_trans_start(fset
, inode
, KML_OPCODE_TRUNC
);
1424 if ( IS_ERR(handle
) ) {
1430 rc
= izo_do_truncate(fset
, fset
->fset_lml
.fd_file
->f_dentry
,
1431 lml_last_rec
- lml_last_recsize
, lml_tail
);
1432 presto_trans_commit(fset
, handle
);
1439 CDEBUG(D_JOURNAL
, "rc = %d\n", rc
);
1440 write_lock(&fset
->fset_lml
.fd_lock
);
1441 fset
->fset_lml
.fd_truncating
= 0;
1442 write_unlock(&fset
->fset_lml
.fd_lock
);
1446 int presto_truncate_lml(struct presto_file_set
*fset
)
1451 while ( (rc
= presto_truncate_lml_tail(fset
)) > 0);
1452 if ( rc
< 0 && rc
!= -EALREADY
) {
1453 CERROR("truncate_lml error %d\n", rc
);
1459 int presto_clear_lml_close(struct presto_file_set
*fset
, loff_t lml_offset
)
1462 struct kml_prefix_hdr record
;
1463 loff_t offset
= lml_offset
;
1467 if ( presto_no_journal(fset
) ) {
1472 CDEBUG(D_JOURNAL
, "reading prefix: off %ld, size %d\n",
1473 (long)lml_offset
, sizeof(record
));
1474 rc
= presto_fread(fset
->fset_lml
.fd_file
, (char *)&record
,
1475 sizeof(record
), &offset
);
1477 if ( rc
!= sizeof(record
) ) {
1478 CERROR("presto: clear_lml io error %d\n", rc
);
1483 /* overwrite the prefix */
1484 CDEBUG(D_JOURNAL
, "overwriting prefix: off %ld\n", (long)lml_offset
);
1485 record
.opcode
= KML_OPCODE_NOOP
;
1486 offset
= lml_offset
;
1487 /* note: this does just a single transaction in the cache */
1488 rc
= presto_fwrite(fset
->fset_lml
.fd_file
, (char *)(&record
),
1489 sizeof(record
), &offset
);
1490 if ( rc
!= sizeof(record
) ) {
1501 /* now a journal function for every operation */
1503 int presto_journal_setattr(struct rec_info
*rec
, struct presto_file_set
*fset
,
1504 struct dentry
*dentry
, struct presto_version
*old_ver
,
1505 struct izo_rollback_data
*rb
, struct iattr
*iattr
)
1507 int opcode
= KML_OPCODE_SETATTR
;
1508 char *buffer
, *path
, *logrecord
, record
[316];
1509 struct dentry
*root
;
1510 __u32 uid
, gid
, mode
, valid
, flags
, pathlen
;
1511 __u64 fsize
, mtime
, ctime
;
1515 if ( presto_no_journal(fset
) ) {
1520 if (!dentry
->d_inode
|| (dentry
->d_inode
->i_nlink
== 0)
1521 || ((dentry
->d_parent
!= dentry
) && list_empty(&dentry
->d_hash
))) {
1526 root
= fset
->fset_dentry
;
1528 BUFF_ALLOC(buffer
, NULL
);
1529 path
= presto_path(dentry
, root
, buffer
, PAGE_SIZE
);
1530 pathlen
= cpu_to_le32(MYPATHLEN(buffer
, path
));
1531 size
= sizeof(__u32
) * current
->ngroups
+
1532 sizeof(struct kml_prefix_hdr
) + sizeof(*old_ver
) +
1533 sizeof(valid
) + sizeof(mode
) + sizeof(uid
) + sizeof(gid
) +
1534 sizeof(fsize
) + sizeof(mtime
) + sizeof(ctime
) + sizeof(flags
) +
1535 sizeof(pathlen
) + sizeof(*rb
) + sizeof(struct kml_suffix
);
1537 if ( size
> sizeof(record
) )
1538 CERROR("InterMezzo: BUFFER OVERFLOW in %s!\n", __FUNCTION__
);
1540 /* Only journal one kind of mtime, and not atime at all. Also don't
1541 * journal bogus data in iattr, to make the journal more compressible.
1543 if (iattr
->ia_valid
& ATTR_MTIME_SET
)
1544 iattr
->ia_valid
= iattr
->ia_valid
| ATTR_MTIME
;
1545 valid
= cpu_to_le32(iattr
->ia_valid
& ~(ATTR_ATIME
| ATTR_MTIME_SET
|
1547 mode
= iattr
->ia_valid
& ATTR_MODE
? cpu_to_le32(iattr
->ia_mode
): 0;
1548 uid
= iattr
->ia_valid
& ATTR_UID
? cpu_to_le32(iattr
->ia_uid
): 0;
1549 gid
= iattr
->ia_valid
& ATTR_GID
? cpu_to_le32(iattr
->ia_gid
): 0;
1550 fsize
= iattr
->ia_valid
& ATTR_SIZE
? cpu_to_le64(iattr
->ia_size
): 0;
1551 mtime
= iattr
->ia_valid
& ATTR_MTIME
? cpu_to_le64(iattr
->ia_mtime
.tv_sec
): 0;
1552 ctime
= iattr
->ia_valid
& ATTR_CTIME
? cpu_to_le64(iattr
->ia_ctime
.tv_sec
): 0;
1553 flags
= iattr
->ia_valid
& ATTR_ATTR_FLAG
?
1554 cpu_to_le32(iattr
->ia_attr_flags
): 0;
1557 rec
->size
= size
+ size_round(le32_to_cpu(pathlen
));
1559 logrecord
= journal_log_prefix(record
, opcode
, rec
);
1560 logrecord
= log_version(logrecord
, old_ver
);
1561 logrecord
= logit(logrecord
, &valid
, sizeof(valid
));
1562 logrecord
= logit(logrecord
, &mode
, sizeof(mode
));
1563 logrecord
= logit(logrecord
, &uid
, sizeof(uid
));
1564 logrecord
= logit(logrecord
, &gid
, sizeof(gid
));
1565 logrecord
= logit(logrecord
, &fsize
, sizeof(fsize
));
1566 logrecord
= logit(logrecord
, &mtime
, sizeof(mtime
));
1567 logrecord
= logit(logrecord
, &ctime
, sizeof(ctime
));
1568 logrecord
= logit(logrecord
, &flags
, sizeof(flags
));
1569 logrecord
= log_rollback(logrecord
, rb
);
1570 logrecord
= logit(logrecord
, &pathlen
, sizeof(pathlen
));
1571 logrecord
= journal_log_suffix(logrecord
, record
, fset
, dentry
, rec
);
1573 error
= presto_log(fset
, rec
, record
, size
,
1574 path
, size_round(le32_to_cpu(pathlen
)),
1582 int presto_get_fileid(int minor
, struct presto_file_set
*fset
,
1583 struct dentry
*dentry
)
1585 int opcode
= KML_OPCODE_GET_FILEID
;
1586 struct rec_info rec
;
1587 char *buffer
, *path
, *logrecord
, record
[4096]; /*include path*/
1588 struct dentry
*root
;
1589 __u32 uid
, gid
, pathlen
;
1591 struct kml_suffix
*suffix
;
1595 root
= fset
->fset_dentry
;
1597 uid
= cpu_to_le32(dentry
->d_inode
->i_uid
);
1598 gid
= cpu_to_le32(dentry
->d_inode
->i_gid
);
1599 BUFF_ALLOC(buffer
, NULL
);
1600 path
= presto_path(dentry
, root
, buffer
, PAGE_SIZE
);
1601 pathlen
= cpu_to_le32(MYPATHLEN(buffer
, path
));
1602 size
= sizeof(__u32
) * current
->ngroups
+
1603 sizeof(struct kml_prefix_hdr
) + sizeof(pathlen
) +
1604 size_round(le32_to_cpu(pathlen
)) +
1605 sizeof(struct kml_suffix
);
1607 CDEBUG(D_FILE
, "kml size: %d\n", size
);
1608 if ( size
> sizeof(record
) )
1609 CERROR("InterMezzo: BUFFER OVERFLOW in %s!\n", __FUNCTION__
);
1611 memset(&rec
, 0, sizeof(rec
));
1615 logrecord
= journal_log_prefix(record
, opcode
, &rec
);
1616 logrecord
= logit(logrecord
, &pathlen
, sizeof(pathlen
));
1617 logrecord
= logit(logrecord
, path
, size_round(le32_to_cpu(pathlen
)));
1618 suffix
= (struct kml_suffix
*)logrecord
;
1619 logrecord
= journal_log_suffix(logrecord
, record
, fset
, dentry
, &rec
);
1620 /* journal_log_suffix expects journal_log to set this */
1623 CDEBUG(D_FILE
, "actual kml size: %d\n", logrecord
- record
);
1624 CDEBUG(D_FILE
, "get fileid: uid %d, gid %d, path: %s\n", uid
, gid
,path
);
1626 error
= izo_upc_get_fileid(minor
, size
, record
,
1627 size_round(le32_to_cpu(pathlen
)), path
,
1635 int presto_journal_create(struct rec_info
*rec
, struct presto_file_set
*fset
,
1636 struct dentry
*dentry
,
1637 struct presto_version
*tgt_dir_ver
,
1638 struct presto_version
*new_file_ver
, int mode
)
1640 int opcode
= KML_OPCODE_CREATE
;
1641 char *buffer
, *path
, *logrecord
, record
[292];
1642 struct dentry
*root
;
1643 __u32 uid
, gid
, lmode
, pathlen
;
1647 if ( presto_no_journal(fset
) ) {
1652 root
= fset
->fset_dentry
;
1654 uid
= cpu_to_le32(dentry
->d_inode
->i_uid
);
1655 gid
= cpu_to_le32(dentry
->d_inode
->i_gid
);
1656 lmode
= cpu_to_le32(mode
);
1658 BUFF_ALLOC(buffer
, NULL
);
1659 path
= presto_path(dentry
, root
, buffer
, PAGE_SIZE
);
1660 pathlen
= cpu_to_le32(MYPATHLEN(buffer
, path
));
1661 size
= sizeof(__u32
) * current
->ngroups
+
1662 sizeof(struct kml_prefix_hdr
) + 3 * sizeof(*tgt_dir_ver
) +
1663 sizeof(lmode
) + sizeof(uid
) + sizeof(gid
) + sizeof(pathlen
) +
1664 sizeof(struct kml_suffix
);
1666 if ( size
> sizeof(record
) )
1667 CERROR("InterMezzo: BUFFER OVERFLOW in %s!\n", __FUNCTION__
);
1670 rec
->size
= size
+ size_round(le32_to_cpu(pathlen
));
1672 logrecord
= journal_log_prefix(record
, opcode
, rec
);
1673 logrecord
= log_version(logrecord
, tgt_dir_ver
);
1674 logrecord
= log_dentry_version(logrecord
, dentry
->d_parent
);
1675 logrecord
= log_version(logrecord
, new_file_ver
);
1676 logrecord
= logit(logrecord
, &lmode
, sizeof(lmode
));
1677 logrecord
= logit(logrecord
, &uid
, sizeof(uid
));
1678 logrecord
= logit(logrecord
, &gid
, sizeof(gid
));
1679 logrecord
= logit(logrecord
, &pathlen
, sizeof(pathlen
));
1680 logrecord
= journal_log_suffix(logrecord
, record
, fset
, dentry
, rec
);
1682 error
= presto_log(fset
, rec
, record
, size
,
1683 path
, size_round(le32_to_cpu(pathlen
)),
1691 int presto_journal_symlink(struct rec_info
*rec
, struct presto_file_set
*fset
,
1692 struct dentry
*dentry
, const char *target
,
1693 struct presto_version
*tgt_dir_ver
,
1694 struct presto_version
*new_link_ver
)
1696 int opcode
= KML_OPCODE_SYMLINK
;
1697 char *buffer
, *path
, *logrecord
, record
[292];
1698 struct dentry
*root
;
1699 __u32 uid
, gid
, pathlen
;
1700 __u32 targetlen
= cpu_to_le32(strlen(target
));
1704 if ( presto_no_journal(fset
) ) {
1709 root
= fset
->fset_dentry
;
1711 uid
= cpu_to_le32(dentry
->d_inode
->i_uid
);
1712 gid
= cpu_to_le32(dentry
->d_inode
->i_gid
);
1714 BUFF_ALLOC(buffer
, NULL
);
1715 path
= presto_path(dentry
, root
, buffer
, PAGE_SIZE
);
1716 pathlen
= cpu_to_le32(MYPATHLEN(buffer
, path
));
1717 size
= sizeof(__u32
) * current
->ngroups
+
1718 sizeof(struct kml_prefix_hdr
) + 3 * sizeof(*tgt_dir_ver
) +
1719 sizeof(uid
) + sizeof(gid
) + sizeof(pathlen
) +
1720 sizeof(targetlen
) + sizeof(struct kml_suffix
);
1722 if ( size
> sizeof(record
) )
1723 CERROR("InterMezzo: BUFFER OVERFLOW in %s!\n", __FUNCTION__
);
1726 rec
->size
= size
+ size_round(le32_to_cpu(pathlen
)) +
1727 size_round(le32_to_cpu(targetlen
));
1729 logrecord
= journal_log_prefix(record
, opcode
, rec
);
1730 logrecord
= log_version(logrecord
, tgt_dir_ver
);
1731 logrecord
= log_dentry_version(logrecord
, dentry
->d_parent
);
1732 logrecord
= log_version(logrecord
, new_link_ver
);
1733 logrecord
= logit(logrecord
, &uid
, sizeof(uid
));
1734 logrecord
= logit(logrecord
, &gid
, sizeof(gid
));
1735 logrecord
= logit(logrecord
, &pathlen
, sizeof(pathlen
));
1736 logrecord
= logit(logrecord
, &targetlen
, sizeof(targetlen
));
1737 logrecord
= journal_log_suffix(logrecord
, record
, fset
, dentry
, rec
);
1739 error
= presto_log(fset
, rec
, record
, size
,
1740 path
, size_round(le32_to_cpu(pathlen
)),
1741 target
, size_round(le32_to_cpu(targetlen
)),
1749 int presto_journal_mkdir(struct rec_info
*rec
, struct presto_file_set
*fset
,
1750 struct dentry
*dentry
,
1751 struct presto_version
*tgt_dir_ver
,
1752 struct presto_version
*new_dir_ver
, int mode
)
1754 int opcode
= KML_OPCODE_MKDIR
;
1755 char *buffer
, *path
, *logrecord
, record
[292];
1756 struct dentry
*root
;
1757 __u32 uid
, gid
, lmode
, pathlen
;
1761 if ( presto_no_journal(fset
) ) {
1766 root
= fset
->fset_dentry
;
1768 uid
= cpu_to_le32(dentry
->d_inode
->i_uid
);
1769 gid
= cpu_to_le32(dentry
->d_inode
->i_gid
);
1770 lmode
= cpu_to_le32(mode
);
1772 BUFF_ALLOC(buffer
, NULL
);
1773 path
= presto_path(dentry
, root
, buffer
, PAGE_SIZE
);
1774 pathlen
= cpu_to_le32(MYPATHLEN(buffer
, path
));
1775 size
= sizeof(__u32
) * current
->ngroups
+
1776 sizeof(struct kml_prefix_hdr
) + 3 * sizeof(*tgt_dir_ver
) +
1777 sizeof(lmode
) + sizeof(uid
) + sizeof(gid
) + sizeof(pathlen
) +
1778 sizeof(struct kml_suffix
);
1780 if ( size
> sizeof(record
) )
1781 CERROR("InterMezzo: BUFFER OVERFLOW in %s!\n", __FUNCTION__
);
1784 rec
->size
= size
+ size_round(le32_to_cpu(pathlen
));
1785 logrecord
= journal_log_prefix(record
, opcode
, rec
);
1787 logrecord
= log_version(logrecord
, tgt_dir_ver
);
1788 logrecord
= log_dentry_version(logrecord
, dentry
->d_parent
);
1789 logrecord
= log_version(logrecord
, new_dir_ver
);
1790 logrecord
= logit(logrecord
, &lmode
, sizeof(lmode
));
1791 logrecord
= logit(logrecord
, &uid
, sizeof(uid
));
1792 logrecord
= logit(logrecord
, &gid
, sizeof(gid
));
1793 logrecord
= logit(logrecord
, &pathlen
, sizeof(pathlen
));
1794 logrecord
= journal_log_suffix(logrecord
, record
, fset
, dentry
, rec
);
1796 error
= presto_log(fset
, rec
, record
, size
,
1797 path
, size_round(le32_to_cpu(pathlen
)),
1807 presto_journal_rmdir(struct rec_info
*rec
, struct presto_file_set
*fset
,
1808 struct dentry
*dir
, struct presto_version
*tgt_dir_ver
,
1809 struct presto_version
*old_dir_ver
,
1810 struct izo_rollback_data
*rb
, int len
, const char *name
)
1812 int opcode
= KML_OPCODE_RMDIR
;
1813 char *buffer
, *path
, *logrecord
, record
[316];
1814 __u32 pathlen
, llen
;
1815 struct dentry
*root
;
1819 if ( presto_no_journal(fset
) ) {
1824 root
= fset
->fset_dentry
;
1826 llen
= cpu_to_le32(len
);
1827 BUFF_ALLOC(buffer
, NULL
);
1828 path
= presto_path(dir
, root
, buffer
, PAGE_SIZE
);
1829 pathlen
= cpu_to_le32(MYPATHLEN(buffer
, path
));
1830 size
= sizeof(__u32
) * current
->ngroups
+
1831 sizeof(struct kml_prefix_hdr
) + 3 * sizeof(*tgt_dir_ver
) +
1832 sizeof(pathlen
) + sizeof(llen
) + sizeof(*rb
) +
1833 sizeof(struct kml_suffix
);
1835 if ( size
> sizeof(record
) )
1836 CERROR("InterMezzo: BUFFER OVERFLOW in %s!\n", __FUNCTION__
);
1838 CDEBUG(D_JOURNAL
, "path: %s (%d), name: %s (%d), size %d\n",
1839 path
, pathlen
, name
, len
, size
);
1842 rec
->size
= size
+ size_round(le32_to_cpu(pathlen
)) +
1845 logrecord
= journal_log_prefix(record
, opcode
, rec
);
1846 logrecord
= log_version(logrecord
, tgt_dir_ver
);
1847 logrecord
= log_dentry_version(logrecord
, dir
);
1848 logrecord
= log_version(logrecord
, old_dir_ver
);
1849 logrecord
= logit(logrecord
, rb
, sizeof(*rb
));
1850 logrecord
= logit(logrecord
, &pathlen
, sizeof(pathlen
));
1851 logrecord
= logit(logrecord
, &llen
, sizeof(llen
));
1852 logrecord
= journal_log_suffix(logrecord
, record
, fset
, dir
, rec
);
1853 error
= presto_log(fset
, rec
, record
, size
,
1854 path
, size_round(le32_to_cpu(pathlen
)),
1855 name
, size_round(len
),
1865 presto_journal_mknod(struct rec_info
*rec
, struct presto_file_set
*fset
,
1866 struct dentry
*dentry
, struct presto_version
*tgt_dir_ver
,
1867 struct presto_version
*new_node_ver
, int mode
,
1868 int dmajor
, int dminor
)
1870 int opcode
= KML_OPCODE_MKNOD
;
1871 char *buffer
, *path
, *logrecord
, record
[292];
1872 struct dentry
*root
;
1873 __u32 uid
, gid
, lmode
, lmajor
, lminor
, pathlen
;
1877 if ( presto_no_journal(fset
) ) {
1882 root
= fset
->fset_dentry
;
1884 uid
= cpu_to_le32(dentry
->d_inode
->i_uid
);
1885 gid
= cpu_to_le32(dentry
->d_inode
->i_gid
);
1886 lmode
= cpu_to_le32(mode
);
1887 lmajor
= cpu_to_le32(dmajor
);
1888 lminor
= cpu_to_le32(dminor
);
1890 BUFF_ALLOC(buffer
, NULL
);
1891 path
= presto_path(dentry
, root
, buffer
, PAGE_SIZE
);
1892 pathlen
= cpu_to_le32(MYPATHLEN(buffer
, path
));
1893 size
= sizeof(__u32
) * current
->ngroups
+
1894 sizeof(struct kml_prefix_hdr
) + 3 * sizeof(*tgt_dir_ver
) +
1895 sizeof(lmode
) + sizeof(uid
) + sizeof(gid
) + sizeof(lmajor
) +
1896 sizeof(lminor
) + sizeof(pathlen
) +
1897 sizeof(struct kml_suffix
);
1899 if ( size
> sizeof(record
) )
1900 CERROR("InterMezzo: BUFFER OVERFLOW in %s!\n", __FUNCTION__
);
1903 rec
->size
= size
+ size_round(le32_to_cpu(pathlen
));
1905 logrecord
= journal_log_prefix(record
, opcode
, rec
);
1906 logrecord
= log_version(logrecord
, tgt_dir_ver
);
1907 logrecord
= log_dentry_version(logrecord
, dentry
->d_parent
);
1908 logrecord
= log_version(logrecord
, new_node_ver
);
1909 logrecord
= logit(logrecord
, &lmode
, sizeof(lmode
));
1910 logrecord
= logit(logrecord
, &uid
, sizeof(uid
));
1911 logrecord
= logit(logrecord
, &gid
, sizeof(gid
));
1912 logrecord
= logit(logrecord
, &lmajor
, sizeof(lmajor
));
1913 logrecord
= logit(logrecord
, &lminor
, sizeof(lminor
));
1914 logrecord
= logit(logrecord
, &pathlen
, sizeof(pathlen
));
1915 logrecord
= journal_log_suffix(logrecord
, record
, fset
, dentry
, rec
);
1917 error
= presto_log(fset
, rec
, record
, size
,
1918 path
, size_round(le32_to_cpu(pathlen
)),
1927 presto_journal_link(struct rec_info
*rec
, struct presto_file_set
*fset
,
1928 struct dentry
*src
, struct dentry
*tgt
,
1929 struct presto_version
*tgt_dir_ver
,
1930 struct presto_version
*new_link_ver
)
1932 int opcode
= KML_OPCODE_LINK
;
1933 char *buffer
, *srcbuffer
, *path
, *srcpath
, *logrecord
, record
[292];
1934 __u32 pathlen
, srcpathlen
;
1935 struct dentry
*root
;
1939 if ( presto_no_journal(fset
) ) {
1944 root
= fset
->fset_dentry
;
1946 BUFF_ALLOC(srcbuffer
, NULL
);
1947 srcpath
= presto_path(src
, root
, srcbuffer
, PAGE_SIZE
);
1948 srcpathlen
= cpu_to_le32(MYPATHLEN(srcbuffer
, srcpath
));
1950 BUFF_ALLOC(buffer
, srcbuffer
);
1951 path
= presto_path(tgt
, root
, buffer
, PAGE_SIZE
);
1952 pathlen
= cpu_to_le32(MYPATHLEN(buffer
, path
));
1953 size
= sizeof(__u32
) * current
->ngroups
+
1954 sizeof(struct kml_prefix_hdr
) + 3 * sizeof(*tgt_dir_ver
) +
1955 sizeof(srcpathlen
) + sizeof(pathlen
) +
1956 sizeof(struct kml_suffix
);
1958 if ( size
> sizeof(record
) )
1959 CERROR("InterMezzo: BUFFER OVERFLOW in %s!\n", __FUNCTION__
);
1962 rec
->size
= size
+ size_round(le32_to_cpu(pathlen
)) +
1963 size_round(le32_to_cpu(srcpathlen
));
1965 logrecord
= journal_log_prefix(record
, opcode
, rec
);
1966 logrecord
= log_version(logrecord
, tgt_dir_ver
);
1967 logrecord
= log_dentry_version(logrecord
, tgt
->d_parent
);
1968 logrecord
= log_version(logrecord
, new_link_ver
);
1969 logrecord
= logit(logrecord
, &srcpathlen
, sizeof(srcpathlen
));
1970 logrecord
= logit(logrecord
, &pathlen
, sizeof(pathlen
));
1971 logrecord
= journal_log_suffix(logrecord
, record
, fset
, tgt
, rec
);
1973 error
= presto_log(fset
, rec
, record
, size
,
1974 srcpath
, size_round(le32_to_cpu(srcpathlen
)),
1975 path
, size_round(le32_to_cpu(pathlen
)),
1978 BUFF_FREE(srcbuffer
);
1985 int presto_journal_rename(struct rec_info
*rec
, struct presto_file_set
*fset
,
1986 struct dentry
*src
, struct dentry
*tgt
,
1987 struct presto_version
*src_dir_ver
,
1988 struct presto_version
*tgt_dir_ver
)
1990 int opcode
= KML_OPCODE_RENAME
;
1991 char *buffer
, *srcbuffer
, *path
, *srcpath
, *logrecord
, record
[292];
1992 __u32 pathlen
, srcpathlen
;
1993 struct dentry
*root
;
1997 if ( presto_no_journal(fset
) ) {
2002 root
= fset
->fset_dentry
;
2004 BUFF_ALLOC(srcbuffer
, NULL
);
2005 srcpath
= presto_path(src
, root
, srcbuffer
, PAGE_SIZE
);
2006 srcpathlen
= cpu_to_le32(MYPATHLEN(srcbuffer
, srcpath
));
2008 BUFF_ALLOC(buffer
, srcbuffer
);
2009 path
= presto_path(tgt
, root
, buffer
, PAGE_SIZE
);
2010 pathlen
= cpu_to_le32(MYPATHLEN(buffer
, path
));
2011 size
= sizeof(__u32
) * current
->ngroups
+
2012 sizeof(struct kml_prefix_hdr
) + 4 * sizeof(*src_dir_ver
) +
2013 sizeof(srcpathlen
) + sizeof(pathlen
) +
2014 sizeof(struct kml_suffix
);
2016 if ( size
> sizeof(record
) )
2017 CERROR("InterMezzo: BUFFER OVERFLOW in %s!\n", __FUNCTION__
);
2020 rec
->size
= size
+ size_round(le32_to_cpu(pathlen
)) +
2021 size_round(le32_to_cpu(srcpathlen
));
2023 logrecord
= journal_log_prefix(record
, opcode
, rec
);
2024 logrecord
= log_version(logrecord
, src_dir_ver
);
2025 logrecord
= log_dentry_version(logrecord
, src
->d_parent
);
2026 logrecord
= log_version(logrecord
, tgt_dir_ver
);
2027 logrecord
= log_dentry_version(logrecord
, tgt
->d_parent
);
2028 logrecord
= logit(logrecord
, &srcpathlen
, sizeof(srcpathlen
));
2029 logrecord
= logit(logrecord
, &pathlen
, sizeof(pathlen
));
2030 logrecord
= journal_log_suffix(logrecord
, record
, fset
, tgt
, rec
);
2032 error
= presto_log(fset
, rec
, record
, size
,
2033 srcpath
, size_round(le32_to_cpu(srcpathlen
)),
2034 path
, size_round(le32_to_cpu(pathlen
)),
2038 BUFF_FREE(srcbuffer
);
2043 int presto_journal_unlink(struct rec_info
*rec
, struct presto_file_set
*fset
,
2044 struct dentry
*dir
, struct presto_version
*tgt_dir_ver
,
2045 struct presto_version
*old_file_ver
,
2046 struct izo_rollback_data
*rb
, struct dentry
*dentry
,
2047 char *old_target
, int old_targetlen
)
2049 int opcode
= KML_OPCODE_UNLINK
;
2050 char *buffer
, *path
, *logrecord
, record
[316];
2052 __u32 pathlen
, llen
;
2053 struct dentry
*root
;
2054 int error
, size
, len
;
2057 if ( presto_no_journal(fset
) ) {
2062 root
= fset
->fset_dentry
;
2064 name
= dentry
->d_name
.name
;
2065 len
= dentry
->d_name
.len
;
2067 llen
= cpu_to_le32(len
);
2068 BUFF_ALLOC(buffer
, NULL
);
2069 path
= presto_path(dir
, root
, buffer
, PAGE_SIZE
);
2070 pathlen
= cpu_to_le32(MYPATHLEN(buffer
, path
));
2071 size
= sizeof(__u32
) * current
->ngroups
+
2072 sizeof(struct kml_prefix_hdr
) + 3 * sizeof(*tgt_dir_ver
) +
2073 sizeof(pathlen
) + sizeof(llen
) + sizeof(*rb
) +
2074 sizeof(old_targetlen
) + sizeof(struct kml_suffix
);
2076 if ( size
> sizeof(record
) )
2077 CERROR("InterMezzo: BUFFER OVERFLOW in %s!\n", __FUNCTION__
);
2080 rec
->size
= size
+ size_round(le32_to_cpu(pathlen
)) + size_round(len
) +
2081 size_round(old_targetlen
);
2083 logrecord
= journal_log_prefix(record
, opcode
, rec
);
2084 logrecord
= log_version(logrecord
, tgt_dir_ver
);
2085 logrecord
= log_dentry_version(logrecord
, dir
);
2086 logrecord
= log_version(logrecord
, old_file_ver
);
2087 logrecord
= log_rollback(logrecord
, rb
);
2088 logrecord
= logit(logrecord
, &pathlen
, sizeof(pathlen
));
2089 logrecord
= logit(logrecord
, &llen
, sizeof(llen
));
2090 logrecord
= logit(logrecord
, &old_targetlen
, sizeof(old_targetlen
));
2091 logrecord
= journal_log_suffix(logrecord
, record
, fset
, dir
, rec
);
2093 error
= presto_log(fset
, rec
, record
, size
,
2094 path
, size_round(le32_to_cpu(pathlen
)),
2095 name
, size_round(len
),
2096 old_target
, size_round(old_targetlen
));
2104 presto_journal_close(struct rec_info
*rec
, struct presto_file_set
*fset
,
2105 struct file
*file
, struct dentry
*dentry
,
2106 struct presto_version
*old_file_ver
,
2107 struct presto_version
*new_file_ver
)
2109 int opcode
= KML_OPCODE_CLOSE
;
2110 struct presto_file_data
*fd
;
2111 char *buffer
, *path
, *logrecord
, record
[316];
2112 struct dentry
*root
;
2114 __u32 pathlen
, generation
;
2119 __u32 open_groups
[NGROUPS_MAX
];
2126 if ( presto_no_journal(fset
) ) {
2131 if (!dentry
->d_inode
|| (dentry
->d_inode
->i_nlink
== 0)
2132 || ((dentry
->d_parent
!= dentry
) && list_empty(&dentry
->d_hash
))) {
2137 root
= fset
->fset_dentry
;
2139 fd
= (struct presto_file_data
*)file
->private_data
;
2141 open_ngroups
= fd
->fd_ngroups
;
2142 for (i
= 0; i
< fd
->fd_ngroups
; i
++)
2143 open_groups
[i
] = (__u32
) fd
->fd_groups
[i
];
2144 open_mode
= fd
->fd_mode
;
2145 open_uid
= fd
->fd_uid
;
2146 open_gid
= fd
->fd_gid
;
2147 open_fsuid
= fd
->fd_fsuid
;
2148 open_fsgid
= fd
->fd_fsgid
;
2150 open_ngroups
= current
->ngroups
;
2151 for (i
=0; i
<current
->ngroups
; i
++)
2152 open_groups
[i
] = (__u32
) current
->groups
[i
];
2153 open_mode
= dentry
->d_inode
->i_mode
;
2154 open_uid
= dentry
->d_inode
->i_uid
;
2155 open_gid
= dentry
->d_inode
->i_gid
;
2156 open_fsuid
= current
->fsuid
;
2157 open_fsgid
= current
->fsgid
;
2159 BUFF_ALLOC(buffer
, NULL
);
2160 path
= presto_path(dentry
, root
, buffer
, PAGE_SIZE
);
2161 pathlen
= cpu_to_le32(MYPATHLEN(buffer
, path
));
2162 ino
= cpu_to_le64(dentry
->d_inode
->i_ino
);
2163 generation
= cpu_to_le32(dentry
->d_inode
->i_generation
);
2164 size
= sizeof(__u32
) * open_ngroups
+
2165 sizeof(open_mode
) + sizeof(open_uid
) + sizeof(open_gid
) +
2166 sizeof(struct kml_prefix_hdr
) + sizeof(*old_file_ver
) +
2167 sizeof(*new_file_ver
) + sizeof(ino
) + sizeof(generation
) +
2168 sizeof(pathlen
) + sizeof(struct kml_suffix
);
2170 if ( size
> sizeof(record
) )
2171 CERROR("InterMezzo: BUFFER OVERFLOW in %s!\n", __FUNCTION__
);
2174 rec
->size
= size
+ size_round(le32_to_cpu(pathlen
));
2176 logrecord
= journal_log_prefix_with_groups_and_ids(
2177 record
, opcode
, rec
, open_ngroups
, open_groups
,
2178 open_fsuid
, open_fsgid
);
2179 logrecord
= logit(logrecord
, &open_mode
, sizeof(open_mode
));
2180 logrecord
= logit(logrecord
, &open_uid
, sizeof(open_uid
));
2181 logrecord
= logit(logrecord
, &open_gid
, sizeof(open_gid
));
2182 logrecord
= log_version(logrecord
, old_file_ver
);
2183 logrecord
= log_version(logrecord
, new_file_ver
);
2184 logrecord
= logit(logrecord
, &ino
, sizeof(ino
));
2185 logrecord
= logit(logrecord
, &generation
, sizeof(generation
));
2186 logrecord
= logit(logrecord
, &pathlen
, sizeof(pathlen
));
2187 logrecord
= journal_log_suffix(logrecord
, record
, fset
, dentry
, rec
);
2189 error
= presto_log(fset
, rec
, record
, size
,
2190 path
, size_round(le32_to_cpu(pathlen
)),
2198 int presto_rewrite_close(struct rec_info
*rec
, struct presto_file_set
*fset
,
2199 char *path
, __u32 pathlen
,
2200 int ngroups
, __u32
*groups
,
2201 __u64 ino
, __u32 generation
,
2202 struct presto_version
*new_file_ver
)
2204 int opcode
= KML_OPCODE_CLOSE
;
2205 char *logrecord
, record
[292];
2206 struct dentry
*root
;
2211 if ( presto_no_journal(fset
) ) {
2216 root
= fset
->fset_dentry
;
2218 size
= sizeof(__u32
) * ngroups
+
2219 sizeof(struct kml_prefix_hdr
) + sizeof(*new_file_ver
) +
2220 sizeof(ino
) + sizeof(generation
) +
2221 sizeof(le32_to_cpu(pathlen
)) +
2222 sizeof(struct kml_suffix
);
2224 if ( size
> sizeof(record
) )
2225 CERROR("InterMezzo: BUFFER OVERFLOW in %s!\n", __FUNCTION__
);
2228 rec
->size
= size
+ size_round(le32_to_cpu(pathlen
));
2230 logrecord
= journal_log_prefix_with_groups(record
, opcode
, rec
,
2232 logrecord
= log_version(logrecord
, new_file_ver
);
2233 logrecord
= logit(logrecord
, &ino
, sizeof(ino
));
2234 logrecord
= logit(logrecord
, &generation
, sizeof(generation
));
2235 logrecord
= logit(logrecord
, &pathlen
, sizeof(pathlen
));
2236 logrecord
= journal_log_suffix(logrecord
, record
, fset
, NULL
, rec
);
2238 error
= presto_log(fset
, rec
, record
, size
,
2239 path
, size_round(le32_to_cpu(pathlen
)),
2247 /* write closes for the local close records in the LML */
2248 int presto_complete_lml(struct presto_file_set
*fset
)
2250 __u32 groups
[NGROUPS_MAX
];
2255 struct rec_info rec
;
2257 struct presto_version new_file_ver
;
2262 __u32 remote_generation
;
2263 __u32 remote_version
;
2266 struct file
*file
= fset
->fset_lml
.fd_file
;
2267 struct kml_prefix_hdr prefix
;
2273 if (lml_offset
>= file
->f_dentry
->d_inode
->i_size
) {
2278 read_offset
= lml_offset
;
2279 rc
= presto_fread(file
, (char *)&prefix
,
2280 sizeof(prefix
), &read_offset
);
2281 if ( rc
!= sizeof(prefix
) ) {
2283 CERROR("presto_complete_lml: ioerror - 1, tell Peter\n");
2287 if ( prefix
.opcode
== KML_OPCODE_NOOP
) {
2288 lml_offset
+= prefix
.len
;
2292 rc
= presto_fread(file
, (char *)groups
,
2293 prefix
.ngroups
* sizeof(__u32
), &read_offset
);
2294 if ( rc
!= prefix
.ngroups
* sizeof(__u32
) ) {
2296 CERROR("presto_complete_lml: ioerror - 2, tell Peter\n");
2300 rc
= presto_fread(file
, (char *)&close_rec
,
2301 sizeof(close_rec
), &read_offset
);
2302 if ( rc
!= sizeof(close_rec
) ) {
2304 CERROR("presto_complete_lml: ioerror - 3, tell Peter\n");
2308 /* is this a backfetch or a close record? */
2309 if ( le64_to_cpu(close_rec
.remote_ino
) != 0 ) {
2310 lml_offset
+= prefix
.len
;
2314 BUFF_ALLOC(buffer
, NULL
);
2315 rc
= presto_fread(file
, (char *)buffer
,
2316 le32_to_cpu(close_rec
.pathlen
), &read_offset
);
2317 if ( rc
!= le32_to_cpu(close_rec
.pathlen
) ) {
2319 CERROR("presto_complete_lml: ioerror - 4, tell Peter\n");
2323 handle
= presto_trans_start(fset
, file
->f_dentry
->d_inode
,
2324 KML_OPCODE_RELEASE
);
2325 if ( IS_ERR(handle
) ) {
2330 rc
= presto_clear_lml_close(fset
, lml_offset
);
2332 CERROR("error during clearing: %d\n", rc
);
2333 presto_trans_commit(fset
, handle
);
2338 rc
= presto_rewrite_close(&rec
, fset
, buffer
, close_rec
.pathlen
,
2339 prefix
.ngroups
, groups
,
2340 close_rec
.ino
, close_rec
.generation
,
2341 &close_rec
.new_file_ver
);
2343 CERROR("error during rewrite close: %d\n", rc
);
2344 presto_trans_commit(fset
, handle
);
2349 presto_trans_commit(fset
, handle
);
2351 CERROR("error during truncation: %d\n", rc
);
2356 lml_offset
+= prefix
.len
;
2357 CDEBUG(D_JOURNAL
, "next LML record at: %ld\n", (long)lml_offset
);
2365 #ifdef CONFIG_FS_EXT_ATTR
2366 /* Journal an ea operation. A NULL buffer implies the attribute is
2367 * getting deleted. In this case we simply change the opcode, but nothing
2370 int presto_journal_set_ext_attr (struct rec_info
*rec
,
2371 struct presto_file_set
*fset
,
2372 struct dentry
*dentry
,
2373 struct presto_version
*ver
, const char *name
,
2374 const char *buffer
, int buffer_len
,
2377 int opcode
= (buffer
== NULL
) ?
2378 KML_OPCODE_DELEXTATTR
:
2379 KML_OPCODE_SETEXTATTR
;
2380 char *temp
, *path
, *logrecord
, record
[292];
2381 struct dentry
*root
;
2383 __u32 namelen
=cpu_to_le32(strnlen(name
,PRESTO_EXT_ATTR_NAME_MAX
));
2384 __u32 buflen
=(buffer
!= NULL
)? cpu_to_le32(buffer_len
): cpu_to_le32(0);
2385 __u32 mode
, pathlen
;
2388 if ( presto_no_journal(fset
) ) {
2393 if (!dentry
->d_inode
|| (dentry
->d_inode
->i_nlink
== 0)
2394 || ((dentry
->d_parent
!= dentry
) && list_empty(&dentry
->d_hash
))) {
2399 root
= fset
->fset_dentry
;
2401 BUFF_ALLOC(temp
, NULL
);
2402 path
= presto_path(dentry
, root
, temp
, PAGE_SIZE
);
2403 pathlen
= cpu_to_le32(MYPATHLEN(temp
, path
));
2405 flags
=cpu_to_le32(flags
);
2406 /* Ugly, but needed. posix ACLs change the mode without using
2407 * setattr, we need to record these changes. The EA code per se
2408 * is not really affected.
2410 mode
=cpu_to_le32(dentry
->d_inode
->i_mode
);
2412 size
= sizeof(__u32
) * current
->ngroups
+
2413 sizeof(struct kml_prefix_hdr
) +
2414 2 * sizeof(struct presto_version
) +
2415 sizeof(flags
) + sizeof(mode
) + sizeof(namelen
) +
2416 sizeof(buflen
) + sizeof(pathlen
) +
2417 sizeof(struct kml_suffix
);
2419 if ( size
> sizeof(record
) )
2420 CERROR("InterMezzo: BUFFER OVERFLOW in %s!\n", __FUNCTION__
);
2423 /* Make space for a path, a attr name and value*/
2424 /* We use the buflen instead of buffer_len to make sure that we
2425 * journal the right length. This may be a little paranoid, but
2426 * with 64 bits round the corner, I would rather be safe than sorry!
2427 * Also this handles deletes with non-zero buffer_lengths correctly.
2430 rec
->size
= size
+ size_round(le32_to_cpu(pathlen
)) +
2431 size_round(le32_to_cpu(namelen
)) +
2432 size_round(le32_to_cpu(buflen
));
2434 logrecord
= journal_log_prefix(record
, opcode
, rec
);
2435 logrecord
= log_version(logrecord
, ver
);
2436 logrecord
= log_dentry_version(logrecord
, dentry
);
2437 logrecord
= logit(logrecord
, &flags
, sizeof(flags
));
2438 logrecord
= logit(logrecord
, &mode
, sizeof(flags
));
2439 logrecord
= logit(logrecord
, &pathlen
, sizeof(pathlen
));
2440 logrecord
= logit(logrecord
, &namelen
, sizeof(namelen
));
2441 logrecord
= logit(logrecord
, &buflen
, sizeof(buflen
));
2442 logrecord
= journal_log_suffix(logrecord
, record
, fset
, dentry
, rec
);
2444 error
= presto_log(fset
, rec
, record
, size
,
2445 path
, size_round(le32_to_cpu(pathlen
)),
2446 name
, size_round(le32_to_cpu(namelen
)),
2447 buffer
, size_round(le32_to_cpu(buflen
)));