jfs_imap.c (1a02e59a2970f9ed28ab51d3b08624b79e54d848) jfs_imap.c (88dcb91177cfa5b26143a29074389a2aa259c7cf)
1/*
2 * Copyright (C) International Business Machines Corp., 2000-2004
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *

--- 52 unchanged lines hidden (view full) ---

61 * special inodes in the fileset inode space, we hash them to a dummy head
62 */
63static HLIST_HEAD(aggregate_hash);
64
65/*
66 * imap locks
67 */
68/* iag free list lock */
1/*
2 * Copyright (C) International Business Machines Corp., 2000-2004
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *

--- 52 unchanged lines hidden (view full) ---

61 * special inodes in the fileset inode space, we hash them to a dummy head
62 */
63static HLIST_HEAD(aggregate_hash);
64
65/*
66 * imap locks
67 */
68/* iag free list lock */
69#define IAGFREE_LOCK_INIT(imap) init_MUTEX(&imap->im_freelock)
70#define IAGFREE_LOCK(imap) down(&imap->im_freelock)
71#define IAGFREE_UNLOCK(imap) up(&imap->im_freelock)
69#define IAGFREE_LOCK_INIT(imap) mutex_init(&imap->im_freelock)
70#define IAGFREE_LOCK(imap) mutex_lock(&imap->im_freelock)
71#define IAGFREE_UNLOCK(imap) mutex_unlock(&imap->im_freelock)
72
73/* per ag iag list locks */
72
73/* per ag iag list locks */
74#define AG_LOCK_INIT(imap,index) init_MUTEX(&(imap->im_aglock[index]))
75#define AG_LOCK(imap,agno) down(&imap->im_aglock[agno])
76#define AG_UNLOCK(imap,agno) up(&imap->im_aglock[agno])
74#define AG_LOCK_INIT(imap,index) mutex_init(&(imap->im_aglock[index]))
75#define AG_LOCK(imap,agno) mutex_lock(&imap->im_aglock[agno])
76#define AG_UNLOCK(imap,agno) mutex_unlock(&imap->im_aglock[agno])
77
78/*
79 * forward references
80 */
81static int diAllocAG(struct inomap *, int, boolean_t, struct inode *);
82static int diAllocAny(struct inomap *, int, boolean_t, struct inode *);
83static int diAllocBit(struct inomap *, struct iag *, int);
84static int diAllocExt(struct inomap *, int, struct inode *);

--- 1171 unchanged lines hidden (view full) ---

1256 * for the inode extent freed;
1257 *
1258 * N.B. AG_LOCK is released and iag will be released below, and
1259 * other thread may allocate inode from/reusing the ixad freed
1260 * BUT with new/different backing inode extent from the extent
1261 * to be freed by the transaction;
1262 */
1263 tid = txBegin(ipimap->i_sb, COMMIT_FORCE);
77
78/*
79 * forward references
80 */
81static int diAllocAG(struct inomap *, int, boolean_t, struct inode *);
82static int diAllocAny(struct inomap *, int, boolean_t, struct inode *);
83static int diAllocBit(struct inomap *, struct iag *, int);
84static int diAllocExt(struct inomap *, int, struct inode *);

--- 1171 unchanged lines hidden (view full) ---

1256 * for the inode extent freed;
1257 *
1258 * N.B. AG_LOCK is released and iag will be released below, and
1259 * other thread may allocate inode from/reusing the ixad freed
1260 * BUT with new/different backing inode extent from the extent
1261 * to be freed by the transaction;
1262 */
1263 tid = txBegin(ipimap->i_sb, COMMIT_FORCE);
1264 down(&JFS_IP(ipimap)->commit_sem);
1264 mutex_lock(&JFS_IP(ipimap)->commit_mutex);
1265
1266 /* acquire tlock of the iag page of the freed ixad
1267 * to force the page NOHOMEOK (even though no data is
1268 * logged from the iag page) until NOREDOPAGE|FREEXTENT log
1269 * for the free of the extent is committed;
1270 * write FREEXTENT|NOREDOPAGE log record
1271 * N.B. linelock is overlaid as freed extent descriptor;
1272 */

--- 16 unchanged lines hidden (view full) ---

1289 * It's not pretty, but it works.
1290 */
1291 iplist[1] = (struct inode *) (size_t)iagno;
1292 iplist[2] = (struct inode *) (size_t)extno;
1293
1294 rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE);
1295
1296 txEnd(tid);
1265
1266 /* acquire tlock of the iag page of the freed ixad
1267 * to force the page NOHOMEOK (even though no data is
1268 * logged from the iag page) until NOREDOPAGE|FREEXTENT log
1269 * for the free of the extent is committed;
1270 * write FREEXTENT|NOREDOPAGE log record
1271 * N.B. linelock is overlaid as freed extent descriptor;
1272 */

--- 16 unchanged lines hidden (view full) ---

1289 * It's not pretty, but it works.
1290 */
1291 iplist[1] = (struct inode *) (size_t)iagno;
1292 iplist[2] = (struct inode *) (size_t)extno;
1293
1294 rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE);
1295
1296 txEnd(tid);
1297 up(&JFS_IP(ipimap)->commit_sem);
1297 mutex_unlock(&JFS_IP(ipimap)->commit_mutex);
1298
1299 /* unlock the AG inode map information */
1300 AG_UNLOCK(imap, agno);
1301
1302 return (0);
1303
1304 error_out:
1305 IREAD_UNLOCK(ipimap);

--- 1243 unchanged lines hidden (view full) ---

2549 goto out;
2550 }
2551
2552 /*
2553 * start transaction of update of the inode map
2554 * addressing structure pointing to the new iag page;
2555 */
2556 tid = txBegin(sb, COMMIT_FORCE);
1298
1299 /* unlock the AG inode map information */
1300 AG_UNLOCK(imap, agno);
1301
1302 return (0);
1303
1304 error_out:
1305 IREAD_UNLOCK(ipimap);

--- 1243 unchanged lines hidden (view full) ---

2549 goto out;
2550 }
2551
2552 /*
2553 * start transaction of update of the inode map
2554 * addressing structure pointing to the new iag page;
2555 */
2556 tid = txBegin(sb, COMMIT_FORCE);
2557 down(&JFS_IP(ipimap)->commit_sem);
2557 mutex_lock(&JFS_IP(ipimap)->commit_mutex);
2558
2559 /* update the inode map addressing structure to point to it */
2560 if ((rc =
2561 xtInsert(tid, ipimap, 0, blkno, xlen, &xaddr, 0))) {
2562 txEnd(tid);
2558
2559 /* update the inode map addressing structure to point to it */
2560 if ((rc =
2561 xtInsert(tid, ipimap, 0, blkno, xlen, &xaddr, 0))) {
2562 txEnd(tid);
2563 up(&JFS_IP(ipimap)->commit_sem);
2563 mutex_unlock(&JFS_IP(ipimap)->commit_mutex);
2564 /* Free the blocks allocated for the iag since it was
2565 * not successfully added to the inode map
2566 */
2567 dbFree(ipimap, xaddr, (s64) xlen);
2568
2569 /* release the inode map lock */
2570 IWRITE_UNLOCK(ipimap);
2571

--- 49 unchanged lines hidden (view full) ---

2621 * txCommit(COMMIT_FORCE) will synchronously write address
2622 * index pages and inode after commit in careful update order
2623 * of address index pages (right to left, bottom up);
2624 */
2625 iplist[0] = ipimap;
2626 rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE);
2627
2628 txEnd(tid);
2564 /* Free the blocks allocated for the iag since it was
2565 * not successfully added to the inode map
2566 */
2567 dbFree(ipimap, xaddr, (s64) xlen);
2568
2569 /* release the inode map lock */
2570 IWRITE_UNLOCK(ipimap);
2571

--- 49 unchanged lines hidden (view full) ---

2621 * txCommit(COMMIT_FORCE) will synchronously write address
2622 * index pages and inode after commit in careful update order
2623 * of address index pages (right to left, bottom up);
2624 */
2625 iplist[0] = ipimap;
2626 rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE);
2627
2628 txEnd(tid);
2629 up(&JFS_IP(ipimap)->commit_sem);
2629 mutex_unlock(&JFS_IP(ipimap)->commit_mutex);
2630
2631 duplicateIXtree(sb, blkno, xlen, &xaddr);
2632
2633 /* update the next avaliable iag number */
2634 imap->im_nextiag += 1;
2635
2636 /* Add the iag to the iag free list so we don't lose the iag
2637 * if a failure happens now.

--- 431 unchanged lines hidden (view full) ---

3069 *
3070 * RETURN VALUES:
3071 * 0 - success
3072 * -ENOMEM - insufficient memory
3073 */
3074static int copy_from_dinode(struct dinode * dip, struct inode *ip)
3075{
3076 struct jfs_inode_info *jfs_ip = JFS_IP(ip);
2630
2631 duplicateIXtree(sb, blkno, xlen, &xaddr);
2632
2633 /* update the next avaliable iag number */
2634 imap->im_nextiag += 1;
2635
2636 /* Add the iag to the iag free list so we don't lose the iag
2637 * if a failure happens now.

--- 431 unchanged lines hidden (view full) ---

3069 *
3070 * RETURN VALUES:
3071 * 0 - success
3072 * -ENOMEM - insufficient memory
3073 */
3074static int copy_from_dinode(struct dinode * dip, struct inode *ip)
3075{
3076 struct jfs_inode_info *jfs_ip = JFS_IP(ip);
3077 struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
3077
3078 jfs_ip->fileset = le32_to_cpu(dip->di_fileset);
3079 jfs_ip->mode2 = le32_to_cpu(dip->di_mode);
3080
3081 ip->i_mode = le32_to_cpu(dip->di_mode) & 0xffff;
3078
3079 jfs_ip->fileset = le32_to_cpu(dip->di_fileset);
3080 jfs_ip->mode2 = le32_to_cpu(dip->di_mode);
3081
3082 ip->i_mode = le32_to_cpu(dip->di_mode) & 0xffff;
3083 if (sbi->umask != -1) {
3084 ip->i_mode = (ip->i_mode & ~0777) | (0777 & ~sbi->umask);
3085 /* For directories, add x permission if r is allowed by umask */
3086 if (S_ISDIR(ip->i_mode)) {
3087 if (ip->i_mode & 0400)
3088 ip->i_mode |= 0100;
3089 if (ip->i_mode & 0040)
3090 ip->i_mode |= 0010;
3091 if (ip->i_mode & 0004)
3092 ip->i_mode |= 0001;
3093 }
3094 }
3082 ip->i_nlink = le32_to_cpu(dip->di_nlink);
3095 ip->i_nlink = le32_to_cpu(dip->di_nlink);
3083 ip->i_uid = le32_to_cpu(dip->di_uid);
3084 ip->i_gid = le32_to_cpu(dip->di_gid);
3096
3097 jfs_ip->saved_uid = le32_to_cpu(dip->di_uid);
3098 if (sbi->uid == -1)
3099 ip->i_uid = jfs_ip->saved_uid;
3100 else {
3101 ip->i_uid = sbi->uid;
3102 }
3103
3104 jfs_ip->saved_gid = le32_to_cpu(dip->di_gid);
3105 if (sbi->gid == -1)
3106 ip->i_gid = jfs_ip->saved_gid;
3107 else {
3108 ip->i_gid = sbi->gid;
3109 }
3110
3085 ip->i_size = le64_to_cpu(dip->di_size);
3086 ip->i_atime.tv_sec = le32_to_cpu(dip->di_atime.tv_sec);
3087 ip->i_atime.tv_nsec = le32_to_cpu(dip->di_atime.tv_nsec);
3088 ip->i_mtime.tv_sec = le32_to_cpu(dip->di_mtime.tv_sec);
3089 ip->i_mtime.tv_nsec = le32_to_cpu(dip->di_mtime.tv_nsec);
3090 ip->i_ctime.tv_sec = le32_to_cpu(dip->di_ctime.tv_sec);
3091 ip->i_ctime.tv_nsec = le32_to_cpu(dip->di_ctime.tv_nsec);
3092 ip->i_blksize = ip->i_sb->s_blocksize;

--- 34 unchanged lines hidden (view full) ---

3127/*
3128 * NAME: copy_to_dinode()
3129 *
3130 * FUNCTION: Copies inode info from in-memory inode to disk inode
3131 */
3132static void copy_to_dinode(struct dinode * dip, struct inode *ip)
3133{
3134 struct jfs_inode_info *jfs_ip = JFS_IP(ip);
3111 ip->i_size = le64_to_cpu(dip->di_size);
3112 ip->i_atime.tv_sec = le32_to_cpu(dip->di_atime.tv_sec);
3113 ip->i_atime.tv_nsec = le32_to_cpu(dip->di_atime.tv_nsec);
3114 ip->i_mtime.tv_sec = le32_to_cpu(dip->di_mtime.tv_sec);
3115 ip->i_mtime.tv_nsec = le32_to_cpu(dip->di_mtime.tv_nsec);
3116 ip->i_ctime.tv_sec = le32_to_cpu(dip->di_ctime.tv_sec);
3117 ip->i_ctime.tv_nsec = le32_to_cpu(dip->di_ctime.tv_nsec);
3118 ip->i_blksize = ip->i_sb->s_blocksize;

--- 34 unchanged lines hidden (view full) ---

3153/*
3154 * NAME: copy_to_dinode()
3155 *
3156 * FUNCTION: Copies inode info from in-memory inode to disk inode
3157 */
3158static void copy_to_dinode(struct dinode * dip, struct inode *ip)
3159{
3160 struct jfs_inode_info *jfs_ip = JFS_IP(ip);
3161 struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
3135
3136 dip->di_fileset = cpu_to_le32(jfs_ip->fileset);
3162
3163 dip->di_fileset = cpu_to_le32(jfs_ip->fileset);
3137 dip->di_inostamp = cpu_to_le32(JFS_SBI(ip->i_sb)->inostamp);
3164 dip->di_inostamp = cpu_to_le32(sbi->inostamp);
3138 dip->di_number = cpu_to_le32(ip->i_ino);
3139 dip->di_gen = cpu_to_le32(ip->i_generation);
3140 dip->di_size = cpu_to_le64(ip->i_size);
3141 dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks));
3142 dip->di_nlink = cpu_to_le32(ip->i_nlink);
3165 dip->di_number = cpu_to_le32(ip->i_ino);
3166 dip->di_gen = cpu_to_le32(ip->i_generation);
3167 dip->di_size = cpu_to_le64(ip->i_size);
3168 dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks));
3169 dip->di_nlink = cpu_to_le32(ip->i_nlink);
3143 dip->di_uid = cpu_to_le32(ip->i_uid);
3144 dip->di_gid = cpu_to_le32(ip->i_gid);
3170 if (sbi->uid == -1)
3171 dip->di_uid = cpu_to_le32(ip->i_uid);
3172 else
3173 dip->di_uid = cpu_to_le32(jfs_ip->saved_uid);
3174 if (sbi->gid == -1)
3175 dip->di_gid = cpu_to_le32(ip->i_gid);
3176 else
3177 dip->di_gid = cpu_to_le32(jfs_ip->saved_gid);
3145 /*
3146 * mode2 is only needed for storing the higher order bits.
3147 * Trust i_mode for the lower order ones
3148 */
3178 /*
3179 * mode2 is only needed for storing the higher order bits.
3180 * Trust i_mode for the lower order ones
3181 */
3149 dip->di_mode = cpu_to_le32((jfs_ip->mode2 & 0xffff0000) | ip->i_mode);
3182 if (sbi->umask == -1)
3183 dip->di_mode = cpu_to_le32((jfs_ip->mode2 & 0xffff0000) |
3184 ip->i_mode);
3185 else /* Leave the original permissions alone */
3186 dip->di_mode = cpu_to_le32(jfs_ip->mode2);
3187
3150 dip->di_atime.tv_sec = cpu_to_le32(ip->i_atime.tv_sec);
3151 dip->di_atime.tv_nsec = cpu_to_le32(ip->i_atime.tv_nsec);
3152 dip->di_ctime.tv_sec = cpu_to_le32(ip->i_ctime.tv_sec);
3153 dip->di_ctime.tv_nsec = cpu_to_le32(ip->i_ctime.tv_nsec);
3154 dip->di_mtime.tv_sec = cpu_to_le32(ip->i_mtime.tv_sec);
3155 dip->di_mtime.tv_nsec = cpu_to_le32(ip->i_mtime.tv_nsec);
3156 dip->di_ixpxd = jfs_ip->ixpxd; /* in-memory pxd's are little-endian */
3157 dip->di_acl = jfs_ip->acl; /* as are dxd's */
3158 dip->di_ea = jfs_ip->ea;
3159 dip->di_next_index = cpu_to_le32(jfs_ip->next_index);
3160 dip->di_otime.tv_sec = cpu_to_le32(jfs_ip->otime);
3161 dip->di_otime.tv_nsec = 0;
3162 dip->di_acltype = cpu_to_le32(jfs_ip->acltype);
3163 if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode))
3164 dip->di_rdev = cpu_to_le32(jfs_ip->dev);
3165}
3188 dip->di_atime.tv_sec = cpu_to_le32(ip->i_atime.tv_sec);
3189 dip->di_atime.tv_nsec = cpu_to_le32(ip->i_atime.tv_nsec);
3190 dip->di_ctime.tv_sec = cpu_to_le32(ip->i_ctime.tv_sec);
3191 dip->di_ctime.tv_nsec = cpu_to_le32(ip->i_ctime.tv_nsec);
3192 dip->di_mtime.tv_sec = cpu_to_le32(ip->i_mtime.tv_sec);
3193 dip->di_mtime.tv_nsec = cpu_to_le32(ip->i_mtime.tv_nsec);
3194 dip->di_ixpxd = jfs_ip->ixpxd; /* in-memory pxd's are little-endian */
3195 dip->di_acl = jfs_ip->acl; /* as are dxd's */
3196 dip->di_ea = jfs_ip->ea;
3197 dip->di_next_index = cpu_to_le32(jfs_ip->next_index);
3198 dip->di_otime.tv_sec = cpu_to_le32(jfs_ip->otime);
3199 dip->di_otime.tv_nsec = 0;
3200 dip->di_acltype = cpu_to_le32(jfs_ip->acltype);
3201 if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode))
3202 dip->di_rdev = cpu_to_le32(jfs_ip->dev);
3203}