aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorSunil Mushran <Sunil.Mushran@oracle.com>2006-12-05 20:56:35 -0500
committerMark Fasheh <mark.fasheh@oracle.com>2006-12-07 20:37:53 -0500
commitc271c5c22b0a7ca45fda15f1f4d258bca36a5b94 (patch)
tree9803af515ecf1c101c4a5921d7407c66184147e1 /fs
parentc99767974ebd2a719d849fdeaaa1674456f5283f (diff)
ocfs2: local mounts
This allows users to format an ocfs2 file system with a special flag, OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT. When the file system sees this flag, it will not use any cluster services, nor will it require a cluster configuration, thus acting like a 'local' file system. Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com> Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/ocfs2/dlmglue.c79
-rw-r--r--fs/ocfs2/heartbeat.c9
-rw-r--r--fs/ocfs2/inode.c3
-rw-r--r--fs/ocfs2/journal.c46
-rw-r--r--fs/ocfs2/journal.h5
-rw-r--r--fs/ocfs2/mmap.c6
-rw-r--r--fs/ocfs2/namei.c8
-rw-r--r--fs/ocfs2/ocfs2.h5
-rw-r--r--fs/ocfs2/ocfs2_fs.h5
-rw-r--r--fs/ocfs2/super.c90
-rw-r--r--fs/ocfs2/vote.c3
11 files changed, 193 insertions, 66 deletions
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index 69fba16efbd1..e6220137bf69 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -770,7 +770,7 @@ static int ocfs2_lock_create(struct ocfs2_super *osb,
770 int dlm_flags) 770 int dlm_flags)
771{ 771{
772 int ret = 0; 772 int ret = 0;
773 enum dlm_status status; 773 enum dlm_status status = DLM_NORMAL;
774 unsigned long flags; 774 unsigned long flags;
775 775
776 mlog_entry_void(); 776 mlog_entry_void();
@@ -1138,6 +1138,7 @@ int ocfs2_rw_lock(struct inode *inode, int write)
1138{ 1138{
1139 int status, level; 1139 int status, level;
1140 struct ocfs2_lock_res *lockres; 1140 struct ocfs2_lock_res *lockres;
1141 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
1141 1142
1142 BUG_ON(!inode); 1143 BUG_ON(!inode);
1143 1144
@@ -1147,6 +1148,9 @@ int ocfs2_rw_lock(struct inode *inode, int write)
1147 (unsigned long long)OCFS2_I(inode)->ip_blkno, 1148 (unsigned long long)OCFS2_I(inode)->ip_blkno,
1148 write ? "EXMODE" : "PRMODE"); 1149 write ? "EXMODE" : "PRMODE");
1149 1150
1151 if (ocfs2_mount_local(osb))
1152 return 0;
1153
1150 lockres = &OCFS2_I(inode)->ip_rw_lockres; 1154 lockres = &OCFS2_I(inode)->ip_rw_lockres;
1151 1155
1152 level = write ? LKM_EXMODE : LKM_PRMODE; 1156 level = write ? LKM_EXMODE : LKM_PRMODE;
@@ -1164,6 +1168,7 @@ void ocfs2_rw_unlock(struct inode *inode, int write)
1164{ 1168{
1165 int level = write ? LKM_EXMODE : LKM_PRMODE; 1169 int level = write ? LKM_EXMODE : LKM_PRMODE;
1166 struct ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_rw_lockres; 1170 struct ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_rw_lockres;
1171 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
1167 1172
1168 mlog_entry_void(); 1173 mlog_entry_void();
1169 1174
@@ -1171,7 +1176,8 @@ void ocfs2_rw_unlock(struct inode *inode, int write)
1171 (unsigned long long)OCFS2_I(inode)->ip_blkno, 1176 (unsigned long long)OCFS2_I(inode)->ip_blkno,
1172 write ? "EXMODE" : "PRMODE"); 1177 write ? "EXMODE" : "PRMODE");
1173 1178
1174 ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, level); 1179 if (!ocfs2_mount_local(osb))
1180 ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, level);
1175 1181
1176 mlog_exit_void(); 1182 mlog_exit_void();
1177} 1183}
@@ -1182,6 +1188,7 @@ int ocfs2_data_lock_full(struct inode *inode,
1182{ 1188{
1183 int status = 0, level; 1189 int status = 0, level;
1184 struct ocfs2_lock_res *lockres; 1190 struct ocfs2_lock_res *lockres;
1191 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
1185 1192
1186 BUG_ON(!inode); 1193 BUG_ON(!inode);
1187 1194
@@ -1201,6 +1208,9 @@ int ocfs2_data_lock_full(struct inode *inode,
1201 goto out; 1208 goto out;
1202 } 1209 }
1203 1210
1211 if (ocfs2_mount_local(osb))
1212 goto out;
1213
1204 lockres = &OCFS2_I(inode)->ip_data_lockres; 1214 lockres = &OCFS2_I(inode)->ip_data_lockres;
1205 1215
1206 level = write ? LKM_EXMODE : LKM_PRMODE; 1216 level = write ? LKM_EXMODE : LKM_PRMODE;
@@ -1269,6 +1279,7 @@ void ocfs2_data_unlock(struct inode *inode,
1269{ 1279{
1270 int level = write ? LKM_EXMODE : LKM_PRMODE; 1280 int level = write ? LKM_EXMODE : LKM_PRMODE;
1271 struct ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_data_lockres; 1281 struct ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_data_lockres;
1282 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
1272 1283
1273 mlog_entry_void(); 1284 mlog_entry_void();
1274 1285
@@ -1276,7 +1287,8 @@ void ocfs2_data_unlock(struct inode *inode,
1276 (unsigned long long)OCFS2_I(inode)->ip_blkno, 1287 (unsigned long long)OCFS2_I(inode)->ip_blkno,
1277 write ? "EXMODE" : "PRMODE"); 1288 write ? "EXMODE" : "PRMODE");
1278 1289
1279 if (!ocfs2_is_hard_readonly(OCFS2_SB(inode->i_sb))) 1290 if (!ocfs2_is_hard_readonly(OCFS2_SB(inode->i_sb)) &&
1291 !ocfs2_mount_local(osb))
1280 ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, level); 1292 ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, level);
1281 1293
1282 mlog_exit_void(); 1294 mlog_exit_void();
@@ -1467,8 +1479,9 @@ static int ocfs2_meta_lock_update(struct inode *inode,
1467{ 1479{
1468 int status = 0; 1480 int status = 0;
1469 struct ocfs2_inode_info *oi = OCFS2_I(inode); 1481 struct ocfs2_inode_info *oi = OCFS2_I(inode);
1470 struct ocfs2_lock_res *lockres; 1482 struct ocfs2_lock_res *lockres = NULL;
1471 struct ocfs2_dinode *fe; 1483 struct ocfs2_dinode *fe;
1484 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
1472 1485
1473 mlog_entry_void(); 1486 mlog_entry_void();
1474 1487
@@ -1483,10 +1496,12 @@ static int ocfs2_meta_lock_update(struct inode *inode,
1483 } 1496 }
1484 spin_unlock(&oi->ip_lock); 1497 spin_unlock(&oi->ip_lock);
1485 1498
1486 lockres = &oi->ip_meta_lockres; 1499 if (!ocfs2_mount_local(osb)) {
1500 lockres = &oi->ip_meta_lockres;
1487 1501
1488 if (!ocfs2_should_refresh_lock_res(lockres)) 1502 if (!ocfs2_should_refresh_lock_res(lockres))
1489 goto bail; 1503 goto bail;
1504 }
1490 1505
1491 /* This will discard any caching information we might have had 1506 /* This will discard any caching information we might have had
1492 * for the inode metadata. */ 1507 * for the inode metadata. */
@@ -1496,7 +1511,7 @@ static int ocfs2_meta_lock_update(struct inode *inode,
1496 * map (directories, bitmap files, etc) */ 1511 * map (directories, bitmap files, etc) */
1497 ocfs2_extent_map_trunc(inode, 0); 1512 ocfs2_extent_map_trunc(inode, 0);
1498 1513
1499 if (ocfs2_meta_lvb_is_trustable(inode, lockres)) { 1514 if (lockres && ocfs2_meta_lvb_is_trustable(inode, lockres)) {
1500 mlog(0, "Trusting LVB on inode %llu\n", 1515 mlog(0, "Trusting LVB on inode %llu\n",
1501 (unsigned long long)oi->ip_blkno); 1516 (unsigned long long)oi->ip_blkno);
1502 ocfs2_refresh_inode_from_lvb(inode); 1517 ocfs2_refresh_inode_from_lvb(inode);
@@ -1543,7 +1558,8 @@ static int ocfs2_meta_lock_update(struct inode *inode,
1543 1558
1544 status = 0; 1559 status = 0;
1545bail_refresh: 1560bail_refresh:
1546 ocfs2_complete_lock_res_refresh(lockres, status); 1561 if (lockres)
1562 ocfs2_complete_lock_res_refresh(lockres, status);
1547bail: 1563bail:
1548 mlog_exit(status); 1564 mlog_exit(status);
1549 return status; 1565 return status;
@@ -1585,7 +1601,7 @@ int ocfs2_meta_lock_full(struct inode *inode,
1585 int arg_flags) 1601 int arg_flags)
1586{ 1602{
1587 int status, level, dlm_flags, acquired; 1603 int status, level, dlm_flags, acquired;
1588 struct ocfs2_lock_res *lockres; 1604 struct ocfs2_lock_res *lockres = NULL;
1589 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 1605 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
1590 struct buffer_head *local_bh = NULL; 1606 struct buffer_head *local_bh = NULL;
1591 1607
@@ -1607,6 +1623,9 @@ int ocfs2_meta_lock_full(struct inode *inode,
1607 goto bail; 1623 goto bail;
1608 } 1624 }
1609 1625
1626 if (ocfs2_mount_local(osb))
1627 goto local;
1628
1610 if (!(arg_flags & OCFS2_META_LOCK_RECOVERY)) 1629 if (!(arg_flags & OCFS2_META_LOCK_RECOVERY))
1611 wait_event(osb->recovery_event, 1630 wait_event(osb->recovery_event,
1612 ocfs2_node_map_is_empty(osb, &osb->recovery_map)); 1631 ocfs2_node_map_is_empty(osb, &osb->recovery_map));
@@ -1636,6 +1655,7 @@ int ocfs2_meta_lock_full(struct inode *inode,
1636 wait_event(osb->recovery_event, 1655 wait_event(osb->recovery_event,
1637 ocfs2_node_map_is_empty(osb, &osb->recovery_map)); 1656 ocfs2_node_map_is_empty(osb, &osb->recovery_map));
1638 1657
1658local:
1639 /* 1659 /*
1640 * We only see this flag if we're being called from 1660 * We only see this flag if we're being called from
1641 * ocfs2_read_locked_inode(). It means we're locking an inode 1661 * ocfs2_read_locked_inode(). It means we're locking an inode
@@ -1644,7 +1664,8 @@ int ocfs2_meta_lock_full(struct inode *inode,
1644 */ 1664 */
1645 if (inode->i_state & I_NEW) { 1665 if (inode->i_state & I_NEW) {
1646 status = 0; 1666 status = 0;
1647 ocfs2_complete_lock_res_refresh(lockres, 0); 1667 if (lockres)
1668 ocfs2_complete_lock_res_refresh(lockres, 0);
1648 goto bail; 1669 goto bail;
1649 } 1670 }
1650 1671
@@ -1767,6 +1788,7 @@ void ocfs2_meta_unlock(struct inode *inode,
1767{ 1788{
1768 int level = ex ? LKM_EXMODE : LKM_PRMODE; 1789 int level = ex ? LKM_EXMODE : LKM_PRMODE;
1769 struct ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_meta_lockres; 1790 struct ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_meta_lockres;
1791 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
1770 1792
1771 mlog_entry_void(); 1793 mlog_entry_void();
1772 1794
@@ -1774,7 +1796,8 @@ void ocfs2_meta_unlock(struct inode *inode,
1774 (unsigned long long)OCFS2_I(inode)->ip_blkno, 1796 (unsigned long long)OCFS2_I(inode)->ip_blkno,
1775 ex ? "EXMODE" : "PRMODE"); 1797 ex ? "EXMODE" : "PRMODE");
1776 1798
1777 if (!ocfs2_is_hard_readonly(OCFS2_SB(inode->i_sb))) 1799 if (!ocfs2_is_hard_readonly(OCFS2_SB(inode->i_sb)) &&
1800 !ocfs2_mount_local(osb))
1778 ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, level); 1801 ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, level);
1779 1802
1780 mlog_exit_void(); 1803 mlog_exit_void();
@@ -1783,7 +1806,7 @@ void ocfs2_meta_unlock(struct inode *inode,
1783int ocfs2_super_lock(struct ocfs2_super *osb, 1806int ocfs2_super_lock(struct ocfs2_super *osb,
1784 int ex) 1807 int ex)
1785{ 1808{
1786 int status; 1809 int status = 0;
1787 int level = ex ? LKM_EXMODE : LKM_PRMODE; 1810 int level = ex ? LKM_EXMODE : LKM_PRMODE;
1788 struct ocfs2_lock_res *lockres = &osb->osb_super_lockres; 1811 struct ocfs2_lock_res *lockres = &osb->osb_super_lockres;
1789 struct buffer_head *bh; 1812 struct buffer_head *bh;
@@ -1794,6 +1817,9 @@ int ocfs2_super_lock(struct ocfs2_super *osb,
1794 if (ocfs2_is_hard_readonly(osb)) 1817 if (ocfs2_is_hard_readonly(osb))
1795 return -EROFS; 1818 return -EROFS;
1796 1819
1820 if (ocfs2_mount_local(osb))
1821 goto bail;
1822
1797 status = ocfs2_cluster_lock(osb, lockres, level, 0, 0); 1823 status = ocfs2_cluster_lock(osb, lockres, level, 0, 0);
1798 if (status < 0) { 1824 if (status < 0) {
1799 mlog_errno(status); 1825 mlog_errno(status);
@@ -1832,7 +1858,8 @@ void ocfs2_super_unlock(struct ocfs2_super *osb,
1832 int level = ex ? LKM_EXMODE : LKM_PRMODE; 1858 int level = ex ? LKM_EXMODE : LKM_PRMODE;
1833 struct ocfs2_lock_res *lockres = &osb->osb_super_lockres; 1859 struct ocfs2_lock_res *lockres = &osb->osb_super_lockres;
1834 1860
1835 ocfs2_cluster_unlock(osb, lockres, level); 1861 if (!ocfs2_mount_local(osb))
1862 ocfs2_cluster_unlock(osb, lockres, level);
1836} 1863}
1837 1864
1838int ocfs2_rename_lock(struct ocfs2_super *osb) 1865int ocfs2_rename_lock(struct ocfs2_super *osb)
@@ -1843,6 +1870,9 @@ int ocfs2_rename_lock(struct ocfs2_super *osb)
1843 if (ocfs2_is_hard_readonly(osb)) 1870 if (ocfs2_is_hard_readonly(osb))
1844 return -EROFS; 1871 return -EROFS;
1845 1872
1873 if (ocfs2_mount_local(osb))
1874 return 0;
1875
1846 status = ocfs2_cluster_lock(osb, lockres, LKM_EXMODE, 0, 0); 1876 status = ocfs2_cluster_lock(osb, lockres, LKM_EXMODE, 0, 0);
1847 if (status < 0) 1877 if (status < 0)
1848 mlog_errno(status); 1878 mlog_errno(status);
@@ -1854,7 +1884,8 @@ void ocfs2_rename_unlock(struct ocfs2_super *osb)
1854{ 1884{
1855 struct ocfs2_lock_res *lockres = &osb->osb_rename_lockres; 1885 struct ocfs2_lock_res *lockres = &osb->osb_rename_lockres;
1856 1886
1857 ocfs2_cluster_unlock(osb, lockres, LKM_EXMODE); 1887 if (!ocfs2_mount_local(osb))
1888 ocfs2_cluster_unlock(osb, lockres, LKM_EXMODE);
1858} 1889}
1859 1890
1860int ocfs2_dentry_lock(struct dentry *dentry, int ex) 1891int ocfs2_dentry_lock(struct dentry *dentry, int ex)
@@ -1869,6 +1900,9 @@ int ocfs2_dentry_lock(struct dentry *dentry, int ex)
1869 if (ocfs2_is_hard_readonly(osb)) 1900 if (ocfs2_is_hard_readonly(osb))
1870 return -EROFS; 1901 return -EROFS;
1871 1902
1903 if (ocfs2_mount_local(osb))
1904 return 0;
1905
1872 ret = ocfs2_cluster_lock(osb, &dl->dl_lockres, level, 0, 0); 1906 ret = ocfs2_cluster_lock(osb, &dl->dl_lockres, level, 0, 0);
1873 if (ret < 0) 1907 if (ret < 0)
1874 mlog_errno(ret); 1908 mlog_errno(ret);
@@ -1882,7 +1916,8 @@ void ocfs2_dentry_unlock(struct dentry *dentry, int ex)
1882 struct ocfs2_dentry_lock *dl = dentry->d_fsdata; 1916 struct ocfs2_dentry_lock *dl = dentry->d_fsdata;
1883 struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb); 1917 struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb);
1884 1918
1885 ocfs2_cluster_unlock(osb, &dl->dl_lockres, level); 1919 if (!ocfs2_mount_local(osb))
1920 ocfs2_cluster_unlock(osb, &dl->dl_lockres, level);
1886} 1921}
1887 1922
1888/* Reference counting of the dlm debug structure. We want this because 1923/* Reference counting of the dlm debug structure. We want this because
@@ -2145,12 +2180,15 @@ static void ocfs2_dlm_shutdown_debug(struct ocfs2_super *osb)
2145 2180
2146int ocfs2_dlm_init(struct ocfs2_super *osb) 2181int ocfs2_dlm_init(struct ocfs2_super *osb)
2147{ 2182{
2148 int status; 2183 int status = 0;
2149 u32 dlm_key; 2184 u32 dlm_key;
2150 struct dlm_ctxt *dlm; 2185 struct dlm_ctxt *dlm = NULL;
2151 2186
2152 mlog_entry_void(); 2187 mlog_entry_void();
2153 2188
2189 if (ocfs2_mount_local(osb))
2190 goto local;
2191
2154 status = ocfs2_dlm_init_debug(osb); 2192 status = ocfs2_dlm_init_debug(osb);
2155 if (status < 0) { 2193 if (status < 0) {
2156 mlog_errno(status); 2194 mlog_errno(status);
@@ -2178,11 +2216,12 @@ int ocfs2_dlm_init(struct ocfs2_super *osb)
2178 goto bail; 2216 goto bail;
2179 } 2217 }
2180 2218
2219 dlm_register_eviction_cb(dlm, &osb->osb_eviction_cb);
2220
2221local:
2181 ocfs2_super_lock_res_init(&osb->osb_super_lockres, osb); 2222 ocfs2_super_lock_res_init(&osb->osb_super_lockres, osb);
2182 ocfs2_rename_lock_res_init(&osb->osb_rename_lockres, osb); 2223 ocfs2_rename_lock_res_init(&osb->osb_rename_lockres, osb);
2183 2224
2184 dlm_register_eviction_cb(dlm, &osb->osb_eviction_cb);
2185
2186 osb->dlm = dlm; 2225 osb->dlm = dlm;
2187 2226
2188 status = 0; 2227 status = 0;
diff --git a/fs/ocfs2/heartbeat.c b/fs/ocfs2/heartbeat.c
index cbfd45a97a63..8fc52d6d0ce7 100644
--- a/fs/ocfs2/heartbeat.c
+++ b/fs/ocfs2/heartbeat.c
@@ -154,6 +154,9 @@ int ocfs2_register_hb_callbacks(struct ocfs2_super *osb)
154{ 154{
155 int status; 155 int status;
156 156
157 if (ocfs2_mount_local(osb))
158 return 0;
159
157 status = o2hb_register_callback(&osb->osb_hb_down); 160 status = o2hb_register_callback(&osb->osb_hb_down);
158 if (status < 0) { 161 if (status < 0) {
159 mlog_errno(status); 162 mlog_errno(status);
@@ -172,6 +175,9 @@ void ocfs2_clear_hb_callbacks(struct ocfs2_super *osb)
172{ 175{
173 int status; 176 int status;
174 177
178 if (ocfs2_mount_local(osb))
179 return;
180
175 status = o2hb_unregister_callback(&osb->osb_hb_down); 181 status = o2hb_unregister_callback(&osb->osb_hb_down);
176 if (status < 0) 182 if (status < 0)
177 mlog_errno(status); 183 mlog_errno(status);
@@ -186,6 +192,9 @@ void ocfs2_stop_heartbeat(struct ocfs2_super *osb)
186 int ret; 192 int ret;
187 char *argv[5], *envp[3]; 193 char *argv[5], *envp[3];
188 194
195 if (ocfs2_mount_local(osb))
196 return;
197
189 if (!osb->uuid_str) { 198 if (!osb->uuid_str) {
190 /* This can happen if we don't get far enough in mount... */ 199 /* This can happen if we don't get far enough in mount... */
191 mlog(0, "No UUID with which to stop heartbeat!\n\n"); 200 mlog(0, "No UUID with which to stop heartbeat!\n\n");
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
index 42e361f3054f..e4d91493d7d7 100644
--- a/fs/ocfs2/inode.c
+++ b/fs/ocfs2/inode.c
@@ -423,7 +423,8 @@ static int ocfs2_read_locked_inode(struct inode *inode,
423 * cluster lock before trusting anything anyway. 423 * cluster lock before trusting anything anyway.
424 */ 424 */
425 can_lock = !(args->fi_flags & OCFS2_FI_FLAG_SYSFILE) 425 can_lock = !(args->fi_flags & OCFS2_FI_FLAG_SYSFILE)
426 && !(args->fi_flags & OCFS2_FI_FLAG_NOLOCK); 426 && !(args->fi_flags & OCFS2_FI_FLAG_NOLOCK)
427 && !ocfs2_mount_local(osb);
427 428
428 /* 429 /*
429 * To maintain backwards compatibility with older versions of 430 * To maintain backwards compatibility with older versions of
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
index 1d7f4ab1e5ed..825cb0ae1b4c 100644
--- a/fs/ocfs2/journal.c
+++ b/fs/ocfs2/journal.c
@@ -144,8 +144,10 @@ handle_t *ocfs2_start_trans(struct ocfs2_super *osb, int max_buffs)
144 ocfs2_abort(osb->sb, "Detected aborted journal"); 144 ocfs2_abort(osb->sb, "Detected aborted journal");
145 handle = ERR_PTR(-EROFS); 145 handle = ERR_PTR(-EROFS);
146 } 146 }
147 } else 147 } else {
148 atomic_inc(&(osb->journal->j_num_trans)); 148 if (!ocfs2_mount_local(osb))
149 atomic_inc(&(osb->journal->j_num_trans));
150 }
149 151
150 return handle; 152 return handle;
151} 153}
@@ -507,9 +509,23 @@ void ocfs2_journal_shutdown(struct ocfs2_super *osb)
507 509
508 BUG_ON(atomic_read(&(osb->journal->j_num_trans)) != 0); 510 BUG_ON(atomic_read(&(osb->journal->j_num_trans)) != 0);
509 511
510 status = ocfs2_journal_toggle_dirty(osb, 0); 512 if (ocfs2_mount_local(osb)) {
511 if (status < 0) 513 journal_lock_updates(journal->j_journal);
512 mlog_errno(status); 514 status = journal_flush(journal->j_journal);
515 journal_unlock_updates(journal->j_journal);
516 if (status < 0)
517 mlog_errno(status);
518 }
519
520 if (status == 0) {
521 /*
522 * Do not toggle if flush was unsuccessful otherwise
523 * will leave dirty metadata in a "clean" journal
524 */
525 status = ocfs2_journal_toggle_dirty(osb, 0);
526 if (status < 0)
527 mlog_errno(status);
528 }
513 529
514 /* Shutdown the kernel journal system */ 530 /* Shutdown the kernel journal system */
515 journal_destroy(journal->j_journal); 531 journal_destroy(journal->j_journal);
@@ -549,7 +565,7 @@ static void ocfs2_clear_journal_error(struct super_block *sb,
549 } 565 }
550} 566}
551 567
552int ocfs2_journal_load(struct ocfs2_journal *journal) 568int ocfs2_journal_load(struct ocfs2_journal *journal, int local)
553{ 569{
554 int status = 0; 570 int status = 0;
555 struct ocfs2_super *osb; 571 struct ocfs2_super *osb;
@@ -576,14 +592,18 @@ int ocfs2_journal_load(struct ocfs2_journal *journal)
576 } 592 }
577 593
578 /* Launch the commit thread */ 594 /* Launch the commit thread */
579 osb->commit_task = kthread_run(ocfs2_commit_thread, osb, "ocfs2cmt"); 595 if (!local) {
580 if (IS_ERR(osb->commit_task)) { 596 osb->commit_task = kthread_run(ocfs2_commit_thread, osb,
581 status = PTR_ERR(osb->commit_task); 597 "ocfs2cmt");
598 if (IS_ERR(osb->commit_task)) {
599 status = PTR_ERR(osb->commit_task);
600 osb->commit_task = NULL;
601 mlog(ML_ERROR, "unable to launch ocfs2commit thread, "
602 "error=%d", status);
603 goto done;
604 }
605 } else
582 osb->commit_task = NULL; 606 osb->commit_task = NULL;
583 mlog(ML_ERROR, "unable to launch ocfs2commit thread, error=%d",
584 status);
585 goto done;
586 }
587 607
588done: 608done:
589 mlog_exit(status); 609 mlog_exit(status);
diff --git a/fs/ocfs2/journal.h b/fs/ocfs2/journal.h
index 899112ad8136..e1216364d191 100644
--- a/fs/ocfs2/journal.h
+++ b/fs/ocfs2/journal.h
@@ -157,7 +157,7 @@ int ocfs2_journal_init(struct ocfs2_journal *journal,
157void ocfs2_journal_shutdown(struct ocfs2_super *osb); 157void ocfs2_journal_shutdown(struct ocfs2_super *osb);
158int ocfs2_journal_wipe(struct ocfs2_journal *journal, 158int ocfs2_journal_wipe(struct ocfs2_journal *journal,
159 int full); 159 int full);
160int ocfs2_journal_load(struct ocfs2_journal *journal); 160int ocfs2_journal_load(struct ocfs2_journal *journal, int local);
161int ocfs2_check_journals_nolocks(struct ocfs2_super *osb); 161int ocfs2_check_journals_nolocks(struct ocfs2_super *osb);
162void ocfs2_recovery_thread(struct ocfs2_super *osb, 162void ocfs2_recovery_thread(struct ocfs2_super *osb,
163 int node_num); 163 int node_num);
@@ -174,6 +174,9 @@ static inline void ocfs2_checkpoint_inode(struct inode *inode)
174{ 174{
175 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 175 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
176 176
177 if (ocfs2_mount_local(osb))
178 return;
179
177 if (!ocfs2_inode_fully_checkpointed(inode)) { 180 if (!ocfs2_inode_fully_checkpointed(inode)) {
178 /* WARNING: This only kicks off a single 181 /* WARNING: This only kicks off a single
179 * checkpoint. If someone races you and adds more 182 * checkpoint. If someone races you and adds more
diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c
index 69f85ae392dc..51b020447683 100644
--- a/fs/ocfs2/mmap.c
+++ b/fs/ocfs2/mmap.c
@@ -83,10 +83,12 @@ static struct vm_operations_struct ocfs2_file_vm_ops = {
83int ocfs2_mmap(struct file *file, struct vm_area_struct *vma) 83int ocfs2_mmap(struct file *file, struct vm_area_struct *vma)
84{ 84{
85 int ret = 0, lock_level = 0; 85 int ret = 0, lock_level = 0;
86 struct ocfs2_super *osb = OCFS2_SB(file->f_dentry->d_inode->i_sb);
86 87
87 /* We don't want to support shared writable mappings yet. */ 88 /* We don't want to support shared writable mappings yet. */
88 if (((vma->vm_flags & VM_SHARED) || (vma->vm_flags & VM_MAYSHARE)) 89 if (!ocfs2_mount_local(osb) &&
89 && ((vma->vm_flags & VM_WRITE) || (vma->vm_flags & VM_MAYWRITE))) { 90 ((vma->vm_flags & VM_SHARED) || (vma->vm_flags & VM_MAYSHARE)) &&
91 ((vma->vm_flags & VM_WRITE) || (vma->vm_flags & VM_MAYWRITE))) {
90 mlog(0, "disallow shared writable mmaps %lx\n", vma->vm_flags); 92 mlog(0, "disallow shared writable mmaps %lx\n", vma->vm_flags);
91 /* This is -EINVAL because generic_file_readonly_mmap 93 /* This is -EINVAL because generic_file_readonly_mmap
92 * returns it in a similar situation. */ 94 * returns it in a similar situation. */
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index 21db45ddf144..9637039c2633 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -587,9 +587,11 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
587 } 587 }
588 588
589 ocfs2_inode_set_new(osb, inode); 589 ocfs2_inode_set_new(osb, inode);
590 status = ocfs2_create_new_inode_locks(inode); 590 if (!ocfs2_mount_local(osb)) {
591 if (status < 0) 591 status = ocfs2_create_new_inode_locks(inode);
592 mlog_errno(status); 592 if (status < 0)
593 mlog_errno(status);
594 }
593 595
594 status = 0; /* error in ocfs2_create_new_inode_locks is not 596 status = 0; /* error in ocfs2_create_new_inode_locks is not
595 * critical */ 597 * critical */
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
index b767fd7da6eb..db8e77cd35d3 100644
--- a/fs/ocfs2/ocfs2.h
+++ b/fs/ocfs2/ocfs2.h
@@ -349,6 +349,11 @@ static inline int ocfs2_is_soft_readonly(struct ocfs2_super *osb)
349 return ret; 349 return ret;
350} 350}
351 351
352static inline int ocfs2_mount_local(struct ocfs2_super *osb)
353{
354 return (osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT);
355}
356
352#define OCFS2_IS_VALID_DINODE(ptr) \ 357#define OCFS2_IS_VALID_DINODE(ptr) \
353 (!strcmp((ptr)->i_signature, OCFS2_INODE_SIGNATURE)) 358 (!strcmp((ptr)->i_signature, OCFS2_INODE_SIGNATURE))
354 359
diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h
index 3330a5dc6be2..2e90e89f1602 100644
--- a/fs/ocfs2/ocfs2_fs.h
+++ b/fs/ocfs2/ocfs2_fs.h
@@ -86,7 +86,7 @@
86 OCFS2_SB(sb)->s_feature_incompat &= ~(mask) 86 OCFS2_SB(sb)->s_feature_incompat &= ~(mask)
87 87
88#define OCFS2_FEATURE_COMPAT_SUPP 0 88#define OCFS2_FEATURE_COMPAT_SUPP 0
89#define OCFS2_FEATURE_INCOMPAT_SUPP 0 89#define OCFS2_FEATURE_INCOMPAT_SUPP OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT
90#define OCFS2_FEATURE_RO_COMPAT_SUPP 0 90#define OCFS2_FEATURE_RO_COMPAT_SUPP 0
91 91
92/* 92/*
@@ -97,6 +97,9 @@
97#define OCFS2_FEATURE_INCOMPAT_HEARTBEAT_DEV 0x0002 97#define OCFS2_FEATURE_INCOMPAT_HEARTBEAT_DEV 0x0002
98 98
99 99
100/* Used to denote a non-clustered volume */
101#define OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT 0x0008
102
100/* 103/*
101 * Flags on ocfs2_dinode.i_flags 104 * Flags on ocfs2_dinode.i_flags
102 */ 105 */
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 4bf39540e652..a6d2f8cc165b 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -508,6 +508,27 @@ bail:
508 return status; 508 return status;
509} 509}
510 510
511static int ocfs2_verify_heartbeat(struct ocfs2_super *osb)
512{
513 if (ocfs2_mount_local(osb)) {
514 if (osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL) {
515 mlog(ML_ERROR, "Cannot heartbeat on a locally "
516 "mounted device.\n");
517 return -EINVAL;
518 }
519 }
520
521 if (!(osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL)) {
522 if (!ocfs2_mount_local(osb) && !ocfs2_is_hard_readonly(osb)) {
523 mlog(ML_ERROR, "Heartbeat has to be started to mount "
524 "a read-write clustered device.\n");
525 return -EINVAL;
526 }
527 }
528
529 return 0;
530}
531
511static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) 532static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
512{ 533{
513 struct dentry *root; 534 struct dentry *root;
@@ -516,16 +537,24 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
516 struct inode *inode = NULL; 537 struct inode *inode = NULL;
517 struct ocfs2_super *osb = NULL; 538 struct ocfs2_super *osb = NULL;
518 struct buffer_head *bh = NULL; 539 struct buffer_head *bh = NULL;
540 char nodestr[8];
519 541
520 mlog_entry("%p, %p, %i", sb, data, silent); 542 mlog_entry("%p, %p, %i", sb, data, silent);
521 543
522 /* for now we only have one cluster/node, make sure we see it 544 if (!ocfs2_parse_options(sb, data, &parsed_opt, 0)) {
523 * in the heartbeat universe */
524 if (!o2hb_check_local_node_heartbeating()) {
525 status = -EINVAL; 545 status = -EINVAL;
526 goto read_super_error; 546 goto read_super_error;
527 } 547 }
528 548
549 /* for now we only have one cluster/node, make sure we see it
550 * in the heartbeat universe */
551 if (parsed_opt & OCFS2_MOUNT_HB_LOCAL) {
552 if (!o2hb_check_local_node_heartbeating()) {
553 status = -EINVAL;
554 goto read_super_error;
555 }
556 }
557
529 /* probe for superblock */ 558 /* probe for superblock */
530 status = ocfs2_sb_probe(sb, &bh, &sector_size); 559 status = ocfs2_sb_probe(sb, &bh, &sector_size);
531 if (status < 0) { 560 if (status < 0) {
@@ -541,11 +570,6 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
541 } 570 }
542 brelse(bh); 571 brelse(bh);
543 bh = NULL; 572 bh = NULL;
544
545 if (!ocfs2_parse_options(sb, data, &parsed_opt, 0)) {
546 status = -EINVAL;
547 goto read_super_error;
548 }
549 osb->s_mount_opt = parsed_opt; 573 osb->s_mount_opt = parsed_opt;
550 574
551 sb->s_magic = OCFS2_SUPER_MAGIC; 575 sb->s_magic = OCFS2_SUPER_MAGIC;
@@ -588,21 +612,16 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
588 } 612 }
589 613
590 if (!ocfs2_is_hard_readonly(osb)) { 614 if (!ocfs2_is_hard_readonly(osb)) {
591 /* If this isn't a hard readonly mount, then we need
592 * to make sure that heartbeat is in a valid state,
593 * and that we mark ourselves soft readonly is -oro
594 * was specified. */
595 if (!(osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL)) {
596 mlog(ML_ERROR, "No heartbeat for device (%s)\n",
597 sb->s_id);
598 status = -EINVAL;
599 goto read_super_error;
600 }
601
602 if (sb->s_flags & MS_RDONLY) 615 if (sb->s_flags & MS_RDONLY)
603 ocfs2_set_ro_flag(osb, 0); 616 ocfs2_set_ro_flag(osb, 0);
604 } 617 }
605 618
619 status = ocfs2_verify_heartbeat(osb);
620 if (status < 0) {
621 mlog_errno(status);
622 goto read_super_error;
623 }
624
606 osb->osb_debug_root = debugfs_create_dir(osb->uuid_str, 625 osb->osb_debug_root = debugfs_create_dir(osb->uuid_str,
607 ocfs2_debugfs_root); 626 ocfs2_debugfs_root);
608 if (!osb->osb_debug_root) { 627 if (!osb->osb_debug_root) {
@@ -635,9 +654,14 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
635 654
636 ocfs2_complete_mount_recovery(osb); 655 ocfs2_complete_mount_recovery(osb);
637 656
638 printk(KERN_INFO "ocfs2: Mounting device (%s) on (node %d, slot %d) " 657 if (ocfs2_mount_local(osb))
658 snprintf(nodestr, sizeof(nodestr), "local");
659 else
660 snprintf(nodestr, sizeof(nodestr), "%d", osb->node_num);
661
662 printk(KERN_INFO "ocfs2: Mounting device (%s) on (node %s, slot %d) "
639 "with %s data mode.\n", 663 "with %s data mode.\n",
640 osb->dev_str, osb->node_num, osb->slot_num, 664 osb->dev_str, nodestr, osb->slot_num,
641 osb->s_mount_opt & OCFS2_MOUNT_DATA_WRITEBACK ? "writeback" : 665 osb->s_mount_opt & OCFS2_MOUNT_DATA_WRITEBACK ? "writeback" :
642 "ordered"); 666 "ordered");
643 667
@@ -999,7 +1023,11 @@ static int ocfs2_fill_local_node_info(struct ocfs2_super *osb)
999 1023
1000 /* XXX hold a ref on the node while mounte? easy enough, if 1024 /* XXX hold a ref on the node while mounte? easy enough, if
1001 * desirable. */ 1025 * desirable. */
1002 osb->node_num = o2nm_this_node(); 1026 if (ocfs2_mount_local(osb))
1027 osb->node_num = 0;
1028 else
1029 osb->node_num = o2nm_this_node();
1030
1003 if (osb->node_num == O2NM_MAX_NODES) { 1031 if (osb->node_num == O2NM_MAX_NODES) {
1004 mlog(ML_ERROR, "could not find this host's node number\n"); 1032 mlog(ML_ERROR, "could not find this host's node number\n");
1005 status = -ENOENT; 1033 status = -ENOENT;
@@ -1084,6 +1112,9 @@ static int ocfs2_mount_volume(struct super_block *sb)
1084 goto leave; 1112 goto leave;
1085 } 1113 }
1086 1114
1115 if (ocfs2_mount_local(osb))
1116 goto leave;
1117
1087 /* This should be sent *after* we recovered our journal as it 1118 /* This should be sent *after* we recovered our journal as it
1088 * will cause other nodes to unmark us as needing 1119 * will cause other nodes to unmark us as needing
1089 * recovery. However, we need to send it *before* dropping the 1120 * recovery. However, we need to send it *before* dropping the
@@ -1114,6 +1145,7 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err)
1114{ 1145{
1115 int tmp; 1146 int tmp;
1116 struct ocfs2_super *osb = NULL; 1147 struct ocfs2_super *osb = NULL;
1148 char nodestr[8];
1117 1149
1118 mlog_entry("(0x%p)\n", sb); 1150 mlog_entry("(0x%p)\n", sb);
1119 1151
@@ -1177,8 +1209,13 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err)
1177 1209
1178 atomic_set(&osb->vol_state, VOLUME_DISMOUNTED); 1210 atomic_set(&osb->vol_state, VOLUME_DISMOUNTED);
1179 1211
1180 printk(KERN_INFO "ocfs2: Unmounting device (%s) on (node %d)\n", 1212 if (ocfs2_mount_local(osb))
1181 osb->dev_str, osb->node_num); 1213 snprintf(nodestr, sizeof(nodestr), "local");
1214 else
1215 snprintf(nodestr, sizeof(nodestr), "%d", osb->node_num);
1216
1217 printk(KERN_INFO "ocfs2: Unmounting device (%s) on (node %s)\n",
1218 osb->dev_str, nodestr);
1182 1219
1183 ocfs2_delete_osb(osb); 1220 ocfs2_delete_osb(osb);
1184 kfree(osb); 1221 kfree(osb);
@@ -1536,6 +1573,7 @@ static int ocfs2_check_volume(struct ocfs2_super *osb)
1536{ 1573{
1537 int status = 0; 1574 int status = 0;
1538 int dirty; 1575 int dirty;
1576 int local;
1539 struct ocfs2_dinode *local_alloc = NULL; /* only used if we 1577 struct ocfs2_dinode *local_alloc = NULL; /* only used if we
1540 * recover 1578 * recover
1541 * ourselves. */ 1579 * ourselves. */
@@ -1563,8 +1601,10 @@ static int ocfs2_check_volume(struct ocfs2_super *osb)
1563 "recovering volume.\n"); 1601 "recovering volume.\n");
1564 } 1602 }
1565 1603
1604 local = ocfs2_mount_local(osb);
1605
1566 /* will play back anything left in the journal. */ 1606 /* will play back anything left in the journal. */
1567 ocfs2_journal_load(osb->journal); 1607 ocfs2_journal_load(osb->journal, local);
1568 1608
1569 if (dirty) { 1609 if (dirty) {
1570 /* recover my local alloc if we didn't unmount cleanly. */ 1610 /* recover my local alloc if we didn't unmount cleanly. */
diff --git a/fs/ocfs2/vote.c b/fs/ocfs2/vote.c
index 5b4dca79990b..0315a8b61ed6 100644
--- a/fs/ocfs2/vote.c
+++ b/fs/ocfs2/vote.c
@@ -1000,6 +1000,9 @@ int ocfs2_register_net_handlers(struct ocfs2_super *osb)
1000{ 1000{
1001 int status = 0; 1001 int status = 0;
1002 1002
1003 if (ocfs2_mount_local(osb))
1004 return 0;
1005
1003 status = o2net_register_handler(OCFS2_MESSAGE_TYPE_RESPONSE, 1006 status = o2net_register_handler(OCFS2_MESSAGE_TYPE_RESPONSE,
1004 osb->net_key, 1007 osb->net_key,
1005 sizeof(struct ocfs2_response_msg), 1008 sizeof(struct ocfs2_response_msg),