aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/Kconfig4
-rw-r--r--fs/cifs/CHANGES7
-rw-r--r--fs/cifs/cifs_fs_sb.h2
-rw-r--r--fs/cifs/cifsfs.c2
-rw-r--r--fs/cifs/cifsfs.h2
-rw-r--r--fs/cifs/cifspdu.h2
-rw-r--r--fs/cifs/connect.c47
-rw-r--r--fs/cifs/dir.c23
-rw-r--r--fs/cifs/file.c3
-rw-r--r--fs/cifs/xattr.c2
-rw-r--r--fs/configfs/dir.c32
-rw-r--r--fs/ext2/balloc.c1
-rw-r--r--fs/ext2/ialloc.c1
-rw-r--r--fs/ext2/super.c2
-rw-r--r--fs/jffs2/jffs2_fs_i.h4
-rw-r--r--fs/jffs2/nodelist.c6
-rw-r--r--fs/jffs2/nodelist.h1
-rw-r--r--fs/jffs2/xattr.c1
-rw-r--r--fs/nfs/nfs4proc.c6
-rw-r--r--fs/nfs/read.c6
-rw-r--r--fs/nfs/write.c4
-rw-r--r--fs/nfsd/nfs4recover.c21
-rw-r--r--fs/ocfs2/Makefile1
-rw-r--r--fs/ocfs2/alloc.c28
-rw-r--r--fs/ocfs2/aops.c83
-rw-r--r--fs/ocfs2/buffer_head_io.c95
-rw-r--r--fs/ocfs2/buffer_head_io.h2
-rw-r--r--fs/ocfs2/cluster/heartbeat.c8
-rw-r--r--fs/ocfs2/dir.c28
-rw-r--r--fs/ocfs2/dlm/dlmast.c10
-rw-r--r--fs/ocfs2/dlmglue.c9
-rw-r--r--fs/ocfs2/dlmglue.h5
-rw-r--r--fs/ocfs2/file.c3
-rw-r--r--fs/ocfs2/inode.c32
-rw-r--r--fs/ocfs2/inode.h3
-rw-r--r--fs/ocfs2/ioctl.c136
-rw-r--r--fs/ocfs2/ioctl.h16
-rw-r--r--fs/ocfs2/namei.c32
-rw-r--r--fs/ocfs2/ocfs2_fs.h24
-rw-r--r--fs/ocfs2/uptodate.c21
-rw-r--r--fs/ocfs2/uptodate.h2
41 files changed, 541 insertions, 176 deletions
diff --git a/fs/Kconfig b/fs/Kconfig
index 3f00a9faabcb..530581628311 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -325,8 +325,8 @@ config FS_POSIX_ACL
325source "fs/xfs/Kconfig" 325source "fs/xfs/Kconfig"
326 326
327config OCFS2_FS 327config OCFS2_FS
328 tristate "OCFS2 file system support (EXPERIMENTAL)" 328 tristate "OCFS2 file system support"
329 depends on NET && SYSFS && EXPERIMENTAL 329 depends on NET && SYSFS
330 select CONFIGFS_FS 330 select CONFIGFS_FS
331 select JBD 331 select JBD
332 select CRC32 332 select CRC32
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 0feb3bd49cb8..1eb9a2ec0a3b 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,3 +1,7 @@
1Version 1.46
2------------
3Support deep tree mounts. Better support OS/2, Win9x (DOS) time stamps.
4
1Version 1.45 5Version 1.45
2------------ 6------------
3Do not time out lockw calls when using posix extensions. Do not 7Do not time out lockw calls when using posix extensions. Do not
@@ -6,7 +10,8 @@ on requests on other threads. Improve POSIX locking emulation,
6(lock cancel now works, and unlock of merged range works even 10(lock cancel now works, and unlock of merged range works even
7to Windows servers now). Fix oops on mount to lanman servers 11to Windows servers now). Fix oops on mount to lanman servers
8(win9x, os/2 etc.) when null password. Do not send listxattr 12(win9x, os/2 etc.) when null password. Do not send listxattr
9(SMB to query all EAs) if nouser_xattr specified. 13(SMB to query all EAs) if nouser_xattr specified. Fix SE Linux
14problem (instantiate inodes/dentries in right order for readdir).
10 15
11Version 1.44 16Version 1.44
12------------ 17------------
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index ad58eb0c4d6d..fd1e52ebcee6 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -40,5 +40,7 @@ struct cifs_sb_info {
40 mode_t mnt_file_mode; 40 mode_t mnt_file_mode;
41 mode_t mnt_dir_mode; 41 mode_t mnt_dir_mode;
42 int mnt_cifs_flags; 42 int mnt_cifs_flags;
43 int prepathlen;
44 char * prepath;
43}; 45};
44#endif /* _CIFS_FS_SB_H */ 46#endif /* _CIFS_FS_SB_H */
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 3cd750029be2..c3ef1c0d0e68 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -189,7 +189,6 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
189 buf->f_files = 0; /* undefined */ 189 buf->f_files = 0; /* undefined */
190 buf->f_ffree = 0; /* unlimited */ 190 buf->f_ffree = 0; /* unlimited */
191 191
192#ifdef CONFIG_CIFS_EXPERIMENTAL
193/* BB we could add a second check for a QFS Unix capability bit */ 192/* BB we could add a second check for a QFS Unix capability bit */
194/* BB FIXME check CIFS_POSIX_EXTENSIONS Unix cap first FIXME BB */ 193/* BB FIXME check CIFS_POSIX_EXTENSIONS Unix cap first FIXME BB */
195 if ((pTcon->ses->capabilities & CAP_UNIX) && (CIFS_POSIX_EXTENSIONS & 194 if ((pTcon->ses->capabilities & CAP_UNIX) && (CIFS_POSIX_EXTENSIONS &
@@ -199,7 +198,6 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
199 /* Only need to call the old QFSInfo if failed 198 /* Only need to call the old QFSInfo if failed
200 on newer one */ 199 on newer one */
201 if(rc) 200 if(rc)
202#endif /* CIFS_EXPERIMENTAL */
203 rc = CIFSSMBQFSInfo(xid, pTcon, buf); 201 rc = CIFSSMBQFSInfo(xid, pTcon, buf);
204 202
205 /* Old Windows servers do not support level 103, retry with level 203 /* Old Windows servers do not support level 103, retry with level
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 39ee8ef3bdeb..bea875d9a46a 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -100,5 +100,5 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
100extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); 100extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
101extern int cifs_ioctl (struct inode * inode, struct file * filep, 101extern int cifs_ioctl (struct inode * inode, struct file * filep,
102 unsigned int command, unsigned long arg); 102 unsigned int command, unsigned long arg);
103#define CIFS_VERSION "1.45" 103#define CIFS_VERSION "1.46"
104#endif /* _CIFSFS_H */ 104#endif /* _CIFSFS_H */
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index 86239023545b..81df2bf8e75a 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -1344,6 +1344,7 @@ struct smb_t2_rsp {
1344#define SMB_QUERY_ATTR_FLAGS 0x206 /* append,immutable etc. */ 1344#define SMB_QUERY_ATTR_FLAGS 0x206 /* append,immutable etc. */
1345#define SMB_QUERY_POSIX_PERMISSION 0x207 1345#define SMB_QUERY_POSIX_PERMISSION 0x207
1346#define SMB_QUERY_POSIX_LOCK 0x208 1346#define SMB_QUERY_POSIX_LOCK 0x208
1347/* #define SMB_POSIX_OPEN 0x209 */
1347#define SMB_QUERY_FILE_INTERNAL_INFO 0x3ee 1348#define SMB_QUERY_FILE_INTERNAL_INFO 0x3ee
1348#define SMB_QUERY_FILE_ACCESS_INFO 0x3f0 1349#define SMB_QUERY_FILE_ACCESS_INFO 0x3f0
1349#define SMB_QUERY_FILE_NAME_INFO2 0x3f1 /* 0x30 bytes */ 1350#define SMB_QUERY_FILE_NAME_INFO2 0x3f1 /* 0x30 bytes */
@@ -1363,6 +1364,7 @@ struct smb_t2_rsp {
1363#define SMB_SET_XATTR 0x205 1364#define SMB_SET_XATTR 0x205
1364#define SMB_SET_ATTR_FLAGS 0x206 /* append, immutable etc. */ 1365#define SMB_SET_ATTR_FLAGS 0x206 /* append, immutable etc. */
1365#define SMB_SET_POSIX_LOCK 0x208 1366#define SMB_SET_POSIX_LOCK 0x208
1367#define SMB_POSIX_OPEN 0x209
1366#define SMB_SET_FILE_BASIC_INFO2 0x3ec 1368#define SMB_SET_FILE_BASIC_INFO2 0x3ec
1367#define SMB_SET_FILE_RENAME_INFORMATION 0x3f2 /* BB check if qpathinfo level too */ 1369#define SMB_SET_FILE_RENAME_INFORMATION 0x3f2 /* BB check if qpathinfo level too */
1368#define SMB_FILE_ALL_INFO2 0x3fa 1370#define SMB_FILE_ALL_INFO2 0x3fa
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 5d394c726860..0e9ba0b9d71e 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -89,6 +89,7 @@ struct smb_vol {
89 unsigned int wsize; 89 unsigned int wsize;
90 unsigned int sockopt; 90 unsigned int sockopt;
91 unsigned short int port; 91 unsigned short int port;
92 char * prepath;
92}; 93};
93 94
94static int ipv4_connect(struct sockaddr_in *psin_server, 95static int ipv4_connect(struct sockaddr_in *psin_server,
@@ -993,6 +994,28 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
993 printk(KERN_WARNING "CIFS: domain name too long\n"); 994 printk(KERN_WARNING "CIFS: domain name too long\n");
994 return 1; 995 return 1;
995 } 996 }
997 } else if (strnicmp(data, "prefixpath", 10) == 0) {
998 if (!value || !*value) {
999 printk(KERN_WARNING
1000 "CIFS: invalid path prefix\n");
1001 return 1; /* needs_arg; */
1002 }
1003 if ((temp_len = strnlen(value, 1024)) < 1024) {
1004 if(value[0] != '/')
1005 temp_len++; /* missing leading slash */
1006 vol->prepath = kmalloc(temp_len+1,GFP_KERNEL);
1007 if(vol->prepath == NULL)
1008 return 1;
1009 if(value[0] != '/') {
1010 vol->prepath[0] = '/';
1011 strcpy(vol->prepath+1,value);
1012 } else
1013 strcpy(vol->prepath,value);
1014 cFYI(1,("prefix path %s",vol->prepath));
1015 } else {
1016 printk(KERN_WARNING "CIFS: prefix too long\n");
1017 return 1;
1018 }
996 } else if (strnicmp(data, "iocharset", 9) == 0) { 1019 } else if (strnicmp(data, "iocharset", 9) == 0) {
997 if (!value || !*value) { 1020 if (!value || !*value) {
998 printk(KERN_WARNING "CIFS: invalid iocharset specified\n"); 1021 printk(KERN_WARNING "CIFS: invalid iocharset specified\n");
@@ -1605,6 +1628,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1605 if (cifs_parse_mount_options(mount_data, devname, &volume_info)) { 1628 if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
1606 kfree(volume_info.UNC); 1629 kfree(volume_info.UNC);
1607 kfree(volume_info.password); 1630 kfree(volume_info.password);
1631 kfree(volume_info.prepath);
1608 FreeXid(xid); 1632 FreeXid(xid);
1609 return -EINVAL; 1633 return -EINVAL;
1610 } 1634 }
@@ -1619,6 +1643,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1619 locations such as env variables and files on disk */ 1643 locations such as env variables and files on disk */
1620 kfree(volume_info.UNC); 1644 kfree(volume_info.UNC);
1621 kfree(volume_info.password); 1645 kfree(volume_info.password);
1646 kfree(volume_info.prepath);
1622 FreeXid(xid); 1647 FreeXid(xid);
1623 return -EINVAL; 1648 return -EINVAL;
1624 } 1649 }
@@ -1639,6 +1664,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1639 /* we failed translating address */ 1664 /* we failed translating address */
1640 kfree(volume_info.UNC); 1665 kfree(volume_info.UNC);
1641 kfree(volume_info.password); 1666 kfree(volume_info.password);
1667 kfree(volume_info.prepath);
1642 FreeXid(xid); 1668 FreeXid(xid);
1643 return -EINVAL; 1669 return -EINVAL;
1644 } 1670 }
@@ -1651,6 +1677,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1651 cERROR(1,("Connecting to DFS root not implemented yet")); 1677 cERROR(1,("Connecting to DFS root not implemented yet"));
1652 kfree(volume_info.UNC); 1678 kfree(volume_info.UNC);
1653 kfree(volume_info.password); 1679 kfree(volume_info.password);
1680 kfree(volume_info.prepath);
1654 FreeXid(xid); 1681 FreeXid(xid);
1655 return -EINVAL; 1682 return -EINVAL;
1656 } else /* which servers DFS root would we conect to */ { 1683 } else /* which servers DFS root would we conect to */ {
@@ -1658,6 +1685,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1658 ("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified")); 1685 ("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified"));
1659 kfree(volume_info.UNC); 1686 kfree(volume_info.UNC);
1660 kfree(volume_info.password); 1687 kfree(volume_info.password);
1688 kfree(volume_info.prepath);
1661 FreeXid(xid); 1689 FreeXid(xid);
1662 return -EINVAL; 1690 return -EINVAL;
1663 } 1691 }
@@ -1672,6 +1700,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1672 cERROR(1,("CIFS mount error: iocharset %s not found",volume_info.iocharset)); 1700 cERROR(1,("CIFS mount error: iocharset %s not found",volume_info.iocharset));
1673 kfree(volume_info.UNC); 1701 kfree(volume_info.UNC);
1674 kfree(volume_info.password); 1702 kfree(volume_info.password);
1703 kfree(volume_info.prepath);
1675 FreeXid(xid); 1704 FreeXid(xid);
1676 return -ELIBACC; 1705 return -ELIBACC;
1677 } 1706 }
@@ -1688,6 +1717,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1688 else { 1717 else {
1689 kfree(volume_info.UNC); 1718 kfree(volume_info.UNC);
1690 kfree(volume_info.password); 1719 kfree(volume_info.password);
1720 kfree(volume_info.prepath);
1691 FreeXid(xid); 1721 FreeXid(xid);
1692 return -EINVAL; 1722 return -EINVAL;
1693 } 1723 }
@@ -1710,6 +1740,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1710 sock_release(csocket); 1740 sock_release(csocket);
1711 kfree(volume_info.UNC); 1741 kfree(volume_info.UNC);
1712 kfree(volume_info.password); 1742 kfree(volume_info.password);
1743 kfree(volume_info.prepath);
1713 FreeXid(xid); 1744 FreeXid(xid);
1714 return rc; 1745 return rc;
1715 } 1746 }
@@ -1720,6 +1751,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1720 sock_release(csocket); 1751 sock_release(csocket);
1721 kfree(volume_info.UNC); 1752 kfree(volume_info.UNC);
1722 kfree(volume_info.password); 1753 kfree(volume_info.password);
1754 kfree(volume_info.prepath);
1723 FreeXid(xid); 1755 FreeXid(xid);
1724 return rc; 1756 return rc;
1725 } else { 1757 } else {
@@ -1744,6 +1776,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1744 sock_release(csocket); 1776 sock_release(csocket);
1745 kfree(volume_info.UNC); 1777 kfree(volume_info.UNC);
1746 kfree(volume_info.password); 1778 kfree(volume_info.password);
1779 kfree(volume_info.prepath);
1747 FreeXid(xid); 1780 FreeXid(xid);
1748 return rc; 1781 return rc;
1749 } 1782 }
@@ -1831,6 +1864,14 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1831 /* Windows ME may prefer this */ 1864 /* Windows ME may prefer this */
1832 cFYI(1,("readsize set to minimum 2048")); 1865 cFYI(1,("readsize set to minimum 2048"));
1833 } 1866 }
1867 /* calculate prepath */
1868 cifs_sb->prepath = volume_info.prepath;
1869 if(cifs_sb->prepath) {
1870 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
1871 cifs_sb->prepath[0] = CIFS_DIR_SEP(cifs_sb);
1872 volume_info.prepath = NULL;
1873 } else
1874 cifs_sb->prepathlen = 0;
1834 cifs_sb->mnt_uid = volume_info.linux_uid; 1875 cifs_sb->mnt_uid = volume_info.linux_uid;
1835 cifs_sb->mnt_gid = volume_info.linux_gid; 1876 cifs_sb->mnt_gid = volume_info.linux_gid;
1836 cifs_sb->mnt_file_mode = volume_info.file_mode; 1877 cifs_sb->mnt_file_mode = volume_info.file_mode;
@@ -2008,6 +2049,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2008 the password ptr is put in the new session structure (in which case the 2049 the password ptr is put in the new session structure (in which case the
2009 password will be freed at unmount time) */ 2050 password will be freed at unmount time) */
2010 kfree(volume_info.UNC); 2051 kfree(volume_info.UNC);
2052 kfree(volume_info.prepath);
2011 FreeXid(xid); 2053 FreeXid(xid);
2012 return rc; 2054 return rc;
2013} 2055}
@@ -3195,6 +3237,7 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3195 int xid; 3237 int xid;
3196 struct cifsSesInfo *ses = NULL; 3238 struct cifsSesInfo *ses = NULL;
3197 struct task_struct *cifsd_task; 3239 struct task_struct *cifsd_task;
3240 char * tmp;
3198 3241
3199 xid = GetXid(); 3242 xid = GetXid();
3200 3243
@@ -3228,6 +3271,10 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3228 } 3271 }
3229 3272
3230 cifs_sb->tcon = NULL; 3273 cifs_sb->tcon = NULL;
3274 tmp = cifs_sb->prepath;
3275 cifs_sb->prepathlen = 0;
3276 cifs_sb->prepath = NULL;
3277 kfree(tmp);
3231 if (ses) 3278 if (ses)
3232 schedule_timeout_interruptible(msecs_to_jiffies(500)); 3279 schedule_timeout_interruptible(msecs_to_jiffies(500));
3233 if (ses) 3280 if (ses)
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 914239d53634..66b825ade3e1 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -46,7 +46,8 @@ char *
46build_path_from_dentry(struct dentry *direntry) 46build_path_from_dentry(struct dentry *direntry)
47{ 47{
48 struct dentry *temp; 48 struct dentry *temp;
49 int namelen = 0; 49 int namelen;
50 int pplen;
50 char *full_path; 51 char *full_path;
51 char dirsep; 52 char dirsep;
52 53
@@ -56,7 +57,9 @@ build_path_from_dentry(struct dentry *direntry)
56 when the server crashed */ 57 when the server crashed */
57 58
58 dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb)); 59 dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb));
60 pplen = CIFS_SB(direntry->d_sb)->prepathlen;
59cifs_bp_rename_retry: 61cifs_bp_rename_retry:
62 namelen = pplen;
60 for (temp = direntry; !IS_ROOT(temp);) { 63 for (temp = direntry; !IS_ROOT(temp);) {
61 namelen += (1 + temp->d_name.len); 64 namelen += (1 + temp->d_name.len);
62 temp = temp->d_parent; 65 temp = temp->d_parent;
@@ -70,7 +73,6 @@ cifs_bp_rename_retry:
70 if(full_path == NULL) 73 if(full_path == NULL)
71 return full_path; 74 return full_path;
72 full_path[namelen] = 0; /* trailing null */ 75 full_path[namelen] = 0; /* trailing null */
73
74 for (temp = direntry; !IS_ROOT(temp);) { 76 for (temp = direntry; !IS_ROOT(temp);) {
75 namelen -= 1 + temp->d_name.len; 77 namelen -= 1 + temp->d_name.len;
76 if (namelen < 0) { 78 if (namelen < 0) {
@@ -79,7 +81,7 @@ cifs_bp_rename_retry:
79 full_path[namelen] = dirsep; 81 full_path[namelen] = dirsep;
80 strncpy(full_path + namelen + 1, temp->d_name.name, 82 strncpy(full_path + namelen + 1, temp->d_name.name,
81 temp->d_name.len); 83 temp->d_name.len);
82 cFYI(0, (" name: %s ", full_path + namelen)); 84 cFYI(0, ("name: %s", full_path + namelen));
83 } 85 }
84 temp = temp->d_parent; 86 temp = temp->d_parent;
85 if(temp == NULL) { 87 if(temp == NULL) {
@@ -88,18 +90,23 @@ cifs_bp_rename_retry:
88 return NULL; 90 return NULL;
89 } 91 }
90 } 92 }
91 if (namelen != 0) { 93 if (namelen != pplen) {
92 cERROR(1, 94 cERROR(1,
93 ("We did not end path lookup where we expected namelen is %d", 95 ("did not end path lookup where expected namelen is %d",
94 namelen)); 96 namelen));
95 /* presumably this is only possible if we were racing with a rename 97 /* presumably this is only possible if racing with a rename
96 of one of the parent directories (we can not lock the dentries 98 of one of the parent directories (we can not lock the dentries
97 above us to prevent this, but retrying should be harmless) */ 99 above us to prevent this, but retrying should be harmless) */
98 kfree(full_path); 100 kfree(full_path);
99 namelen = 0;
100 goto cifs_bp_rename_retry; 101 goto cifs_bp_rename_retry;
101 } 102 }
102 103 /* DIR_SEP already set for byte 0 / vs \ but not for
104 subsequent slashes in prepath which currently must
105 be entered the right way - not sure if there is an alternative
106 since the '\' is a valid posix character so we can not switch
107 those safely to '/' if any are found in the middle of the prepath */
108 /* BB test paths to Windows with '/' in the midst of prepath */
109 strncpy(full_path,CIFS_SB(direntry->d_sb)->prepath,pplen);
103 return full_path; 110 return full_path;
104} 111}
105 112
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index e9c5ba9084fc..ddb012a68023 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -752,6 +752,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
752 int stored_rc = 0; 752 int stored_rc = 0;
753 struct cifsLockInfo *li, *tmp; 753 struct cifsLockInfo *li, *tmp;
754 754
755 rc = 0;
755 down(&fid->lock_sem); 756 down(&fid->lock_sem);
756 list_for_each_entry_safe(li, tmp, &fid->llist, llist) { 757 list_for_each_entry_safe(li, tmp, &fid->llist, llist) {
757 if (pfLock->fl_start <= li->offset && 758 if (pfLock->fl_start <= li->offset &&
@@ -766,7 +767,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
766 kfree(li); 767 kfree(li);
767 } 768 }
768 } 769 }
769 up(&fid->lock_sem); 770 up(&fid->lock_sem);
770 } 771 }
771 } 772 }
772 773
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c
index 067648b7179b..18fcec190f8b 100644
--- a/fs/cifs/xattr.c
+++ b/fs/cifs/xattr.c
@@ -269,7 +269,7 @@ ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name,
269 rc = CIFSSMBGetCIFSACL(xid, pTcon, fid, 269 rc = CIFSSMBGetCIFSACL(xid, pTcon, fid,
270 ea_value, buf_size, 270 ea_value, buf_size,
271 ACL_TYPE_ACCESS); 271 ACL_TYPE_ACCESS);
272 CIFSSMBClose(xid, pTcon, fid) 272 CIFSSMBClose(xid, pTcon, fid);
273 } 273 }
274 } */ /* BB enable after fixing up return data */ 274 } */ /* BB enable after fixing up return data */
275 275
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
index df025453dd97..816e8ef64560 100644
--- a/fs/configfs/dir.c
+++ b/fs/configfs/dir.c
@@ -86,6 +86,32 @@ static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent * pare
86 return sd; 86 return sd;
87} 87}
88 88
89/*
90 *
91 * Return -EEXIST if there is already a configfs element with the same
92 * name for the same parent.
93 *
94 * called with parent inode's i_mutex held
95 */
96int configfs_dirent_exists(struct configfs_dirent *parent_sd,
97 const unsigned char *new)
98{
99 struct configfs_dirent * sd;
100
101 list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
102 if (sd->s_element) {
103 const unsigned char *existing = configfs_get_name(sd);
104 if (strcmp(existing, new))
105 continue;
106 else
107 return -EEXIST;
108 }
109 }
110
111 return 0;
112}
113
114
89int configfs_make_dirent(struct configfs_dirent * parent_sd, 115int configfs_make_dirent(struct configfs_dirent * parent_sd,
90 struct dentry * dentry, void * element, 116 struct dentry * dentry, void * element,
91 umode_t mode, int type) 117 umode_t mode, int type)
@@ -136,8 +162,10 @@ static int create_dir(struct config_item * k, struct dentry * p,
136 int error; 162 int error;
137 umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; 163 umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO;
138 164
139 error = configfs_make_dirent(p->d_fsdata, d, k, mode, 165 error = configfs_dirent_exists(p->d_fsdata, d->d_name.name);
140 CONFIGFS_DIR); 166 if (!error)
167 error = configfs_make_dirent(p->d_fsdata, d, k, mode,
168 CONFIGFS_DIR);
141 if (!error) { 169 if (!error) {
142 error = configfs_create(d, mode, init_dir); 170 error = configfs_create(d, mode, init_dir);
143 if (!error) { 171 if (!error) {
diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c
index d4870432ecfc..b1981d0e95ad 100644
--- a/fs/ext2/balloc.c
+++ b/fs/ext2/balloc.c
@@ -539,7 +539,6 @@ unsigned long ext2_count_free (struct buffer_head * map, unsigned int numchars)
539 539
540#endif /* EXT2FS_DEBUG */ 540#endif /* EXT2FS_DEBUG */
541 541
542/* Superblock must be locked */
543unsigned long ext2_count_free_blocks (struct super_block * sb) 542unsigned long ext2_count_free_blocks (struct super_block * sb)
544{ 543{
545 struct ext2_group_desc * desc; 544 struct ext2_group_desc * desc;
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c
index de85c61c58c5..695f69ccf908 100644
--- a/fs/ext2/ialloc.c
+++ b/fs/ext2/ialloc.c
@@ -637,7 +637,6 @@ fail:
637 return ERR_PTR(err); 637 return ERR_PTR(err);
638} 638}
639 639
640/* Superblock must be locked */
641unsigned long ext2_count_free_inodes (struct super_block * sb) 640unsigned long ext2_count_free_inodes (struct super_block * sb)
642{ 641{
643 struct ext2_group_desc *desc; 642 struct ext2_group_desc *desc;
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index ca5bfb6914d2..4286ff6330b6 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -1083,7 +1083,6 @@ static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf)
1083 unsigned long overhead; 1083 unsigned long overhead;
1084 int i; 1084 int i;
1085 1085
1086 lock_super(sb);
1087 if (test_opt (sb, MINIX_DF)) 1086 if (test_opt (sb, MINIX_DF))
1088 overhead = 0; 1087 overhead = 0;
1089 else { 1088 else {
@@ -1124,7 +1123,6 @@ static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf)
1124 buf->f_files = le32_to_cpu(sbi->s_es->s_inodes_count); 1123 buf->f_files = le32_to_cpu(sbi->s_es->s_inodes_count);
1125 buf->f_ffree = ext2_count_free_inodes (sb); 1124 buf->f_ffree = ext2_count_free_inodes (sb);
1126 buf->f_namelen = EXT2_NAME_LEN; 1125 buf->f_namelen = EXT2_NAME_LEN;
1127 unlock_super(sb);
1128 return 0; 1126 return 0;
1129} 1127}
1130 1128
diff --git a/fs/jffs2/jffs2_fs_i.h b/fs/jffs2/jffs2_fs_i.h
index 2e0cc8e00b85..3a566077ac95 100644
--- a/fs/jffs2/jffs2_fs_i.h
+++ b/fs/jffs2/jffs2_fs_i.h
@@ -41,11 +41,7 @@ struct jffs2_inode_info {
41 41
42 uint16_t flags; 42 uint16_t flags;
43 uint8_t usercompr; 43 uint8_t usercompr;
44#if !defined (__ECOS)
45#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2)
46 struct inode vfs_inode; 44 struct inode vfs_inode;
47#endif
48#endif
49#ifdef CONFIG_JFFS2_FS_POSIX_ACL 45#ifdef CONFIG_JFFS2_FS_POSIX_ACL
50 struct posix_acl *i_acl_access; 46 struct posix_acl *i_acl_access;
51 struct posix_acl *i_acl_default; 47 struct posix_acl *i_acl_default;
diff --git a/fs/jffs2/nodelist.c b/fs/jffs2/nodelist.c
index 7675b33396c7..5a6b4d64206c 100644
--- a/fs/jffs2/nodelist.c
+++ b/fs/jffs2/nodelist.c
@@ -21,6 +21,9 @@
21#include <linux/pagemap.h> 21#include <linux/pagemap.h>
22#include "nodelist.h" 22#include "nodelist.h"
23 23
24static void jffs2_obsolete_node_frag(struct jffs2_sb_info *c,
25 struct jffs2_node_frag *this);
26
24void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list) 27void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list)
25{ 28{
26 struct jffs2_full_dirent **prev = list; 29 struct jffs2_full_dirent **prev = list;
@@ -87,7 +90,8 @@ void jffs2_truncate_fragtree(struct jffs2_sb_info *c, struct rb_root *list, uint
87 } 90 }
88} 91}
89 92
90void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, struct jffs2_node_frag *this) 93static void jffs2_obsolete_node_frag(struct jffs2_sb_info *c,
94 struct jffs2_node_frag *this)
91{ 95{
92 if (this->node) { 96 if (this->node) {
93 this->node->frags--; 97 this->node->frags--;
diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h
index cae92c14116d..0ddfd70307fb 100644
--- a/fs/jffs2/nodelist.h
+++ b/fs/jffs2/nodelist.h
@@ -334,7 +334,6 @@ void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c_delete);
334struct rb_node *rb_next(struct rb_node *); 334struct rb_node *rb_next(struct rb_node *);
335struct rb_node *rb_prev(struct rb_node *); 335struct rb_node *rb_prev(struct rb_node *);
336void rb_replace_node(struct rb_node *victim, struct rb_node *new, struct rb_root *root); 336void rb_replace_node(struct rb_node *victim, struct rb_node *new, struct rb_root *root);
337void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, struct jffs2_node_frag *this);
338int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn); 337int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn);
339void jffs2_truncate_fragtree (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size); 338void jffs2_truncate_fragtree (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size);
340int jffs2_add_older_frag_to_fragtree(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_tmp_dnode_info *tn); 339int jffs2_add_older_frag_to_fragtree(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_tmp_dnode_info *tn);
diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c
index 25bc1ae08648..4da09ce1d1f5 100644
--- a/fs/jffs2/xattr.c
+++ b/fs/jffs2/xattr.c
@@ -1215,7 +1215,6 @@ int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xatt
1215 rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XATTR_SIZE); 1215 rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XATTR_SIZE);
1216 if (rc) { 1216 if (rc) {
1217 JFFS2_WARNING("jffs2_reserve_space_gc()=%d, request=%u\n", rc, totlen); 1217 JFFS2_WARNING("jffs2_reserve_space_gc()=%d, request=%u\n", rc, totlen);
1218 rc = rc ? rc : -EBADFD;
1219 goto out; 1218 goto out;
1220 } 1219 }
1221 rc = save_xattr_datum(c, xd); 1220 rc = save_xattr_datum(c, xd);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 153898e1331f..b14145b7b87f 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -970,7 +970,7 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
970 status = -ENOMEM; 970 status = -ENOMEM;
971 opendata = nfs4_opendata_alloc(dentry, sp, flags, sattr); 971 opendata = nfs4_opendata_alloc(dentry, sp, flags, sattr);
972 if (opendata == NULL) 972 if (opendata == NULL)
973 goto err_put_state_owner; 973 goto err_release_rwsem;
974 974
975 status = _nfs4_proc_open(opendata); 975 status = _nfs4_proc_open(opendata);
976 if (status != 0) 976 if (status != 0)
@@ -989,11 +989,11 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
989 return 0; 989 return 0;
990err_opendata_free: 990err_opendata_free:
991 nfs4_opendata_free(opendata); 991 nfs4_opendata_free(opendata);
992err_release_rwsem:
993 up_read(&clp->cl_sem);
992err_put_state_owner: 994err_put_state_owner:
993 nfs4_put_state_owner(sp); 995 nfs4_put_state_owner(sp);
994out_err: 996out_err:
995 /* Note: clp->cl_sem must be released before nfs4_put_open_state()! */
996 up_read(&clp->cl_sem);
997 *res = NULL; 997 *res = NULL;
998 return status; 998 return status;
999} 999}
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 7a9ee00e0c61..f0aff824a291 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -204,9 +204,11 @@ static int nfs_readpage_sync(struct nfs_open_context *ctx, struct inode *inode,
204 NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME; 204 NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME;
205 spin_unlock(&inode->i_lock); 205 spin_unlock(&inode->i_lock);
206 206
207 nfs_readpage_truncate_uninitialised_page(rdata); 207 if (rdata->res.eof || rdata->res.count == rdata->args.count) {
208 if (rdata->res.eof || rdata->res.count == rdata->args.count)
209 SetPageUptodate(page); 208 SetPageUptodate(page);
209 if (rdata->res.eof && count != 0)
210 memclear_highpage_flush(page, rdata->args.pgbase, count);
211 }
210 result = 0; 212 result = 0;
211 213
212io_error: 214io_error:
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 8ab3cf10d792..7084ac9a6455 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -590,8 +590,8 @@ static void nfs_cancel_commit_list(struct list_head *head)
590 req = nfs_list_entry(head->next); 590 req = nfs_list_entry(head->next);
591 nfs_list_remove_request(req); 591 nfs_list_remove_request(req);
592 nfs_inode_remove_request(req); 592 nfs_inode_remove_request(req);
593 nfs_clear_page_writeback(req);
594 dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); 593 dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
594 nfs_clear_page_writeback(req);
595 } 595 }
596} 596}
597 597
@@ -1386,8 +1386,8 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how)
1386 req = nfs_list_entry(head->next); 1386 req = nfs_list_entry(head->next);
1387 nfs_list_remove_request(req); 1387 nfs_list_remove_request(req);
1388 nfs_mark_request_commit(req); 1388 nfs_mark_request_commit(req);
1389 nfs_clear_page_writeback(req);
1390 dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); 1389 dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
1390 nfs_clear_page_writeback(req);
1391 } 1391 }
1392 return -ENOMEM; 1392 return -ENOMEM;
1393} 1393}
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 06da7506363c..e35d7e52fdeb 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -33,7 +33,7 @@
33* 33*
34*/ 34*/
35 35
36 36#include <linux/err.h>
37#include <linux/sunrpc/svc.h> 37#include <linux/sunrpc/svc.h>
38#include <linux/nfsd/nfsd.h> 38#include <linux/nfsd/nfsd.h>
39#include <linux/nfs4.h> 39#include <linux/nfs4.h>
@@ -87,34 +87,35 @@ int
87nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname) 87nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname)
88{ 88{
89 struct xdr_netobj cksum; 89 struct xdr_netobj cksum;
90 struct crypto_tfm *tfm; 90 struct hash_desc desc;
91 struct scatterlist sg[1]; 91 struct scatterlist sg[1];
92 int status = nfserr_resource; 92 int status = nfserr_resource;
93 93
94 dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n", 94 dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n",
95 clname->len, clname->data); 95 clname->len, clname->data);
96 tfm = crypto_alloc_tfm("md5", CRYPTO_TFM_REQ_MAY_SLEEP); 96 desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
97 if (tfm == NULL) 97 desc.tfm = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC);
98 goto out; 98 if (IS_ERR(desc.tfm))
99 cksum.len = crypto_tfm_alg_digestsize(tfm); 99 goto out_no_tfm;
100 cksum.len = crypto_hash_digestsize(desc.tfm);
100 cksum.data = kmalloc(cksum.len, GFP_KERNEL); 101 cksum.data = kmalloc(cksum.len, GFP_KERNEL);
101 if (cksum.data == NULL) 102 if (cksum.data == NULL)
102 goto out; 103 goto out;
103 crypto_digest_init(tfm);
104 104
105 sg[0].page = virt_to_page(clname->data); 105 sg[0].page = virt_to_page(clname->data);
106 sg[0].offset = offset_in_page(clname->data); 106 sg[0].offset = offset_in_page(clname->data);
107 sg[0].length = clname->len; 107 sg[0].length = clname->len;
108 108
109 crypto_digest_update(tfm, sg, 1); 109 if (crypto_hash_digest(&desc, sg, sg->length, cksum.data))
110 crypto_digest_final(tfm, cksum.data); 110 goto out;
111 111
112 md5_to_hex(dname, cksum.data); 112 md5_to_hex(dname, cksum.data);
113 113
114 kfree(cksum.data); 114 kfree(cksum.data);
115 status = nfs_ok; 115 status = nfs_ok;
116out: 116out:
117 crypto_free_tfm(tfm); 117 crypto_free_hash(desc.tfm);
118out_no_tfm:
118 return status; 119 return status;
119} 120}
120 121
diff --git a/fs/ocfs2/Makefile b/fs/ocfs2/Makefile
index 7d3be845a614..9fb8132f19b0 100644
--- a/fs/ocfs2/Makefile
+++ b/fs/ocfs2/Makefile
@@ -16,6 +16,7 @@ ocfs2-objs := \
16 file.o \ 16 file.o \
17 heartbeat.o \ 17 heartbeat.o \
18 inode.o \ 18 inode.o \
19 ioctl.o \
19 journal.o \ 20 journal.o \
20 localalloc.o \ 21 localalloc.o \
21 mmap.o \ 22 mmap.o \
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index edaab05a93e0..f43bc5f18a35 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -1717,17 +1717,29 @@ static int ocfs2_do_truncate(struct ocfs2_super *osb,
1717 1717
1718 ocfs2_remove_from_cache(inode, eb_bh); 1718 ocfs2_remove_from_cache(inode, eb_bh);
1719 1719
1720 BUG_ON(eb->h_suballoc_slot);
1721 BUG_ON(el->l_recs[0].e_clusters); 1720 BUG_ON(el->l_recs[0].e_clusters);
1722 BUG_ON(el->l_recs[0].e_cpos); 1721 BUG_ON(el->l_recs[0].e_cpos);
1723 BUG_ON(el->l_recs[0].e_blkno); 1722 BUG_ON(el->l_recs[0].e_blkno);
1724 status = ocfs2_free_extent_block(handle, 1723 if (eb->h_suballoc_slot == 0) {
1725 tc->tc_ext_alloc_inode, 1724 /*
1726 tc->tc_ext_alloc_bh, 1725 * This code only understands how to
1727 eb); 1726 * lock the suballocator in slot 0,
1728 if (status < 0) { 1727 * which is fine because allocation is
1729 mlog_errno(status); 1728 * only ever done out of that
1730 goto bail; 1729 * suballocator too. A future version
1730 * might change that however, so avoid
1731 * a free if we don't know how to
1732 * handle it. This way an fs incompat
1733 * bit will not be necessary.
1734 */
1735 status = ocfs2_free_extent_block(handle,
1736 tc->tc_ext_alloc_inode,
1737 tc->tc_ext_alloc_bh,
1738 eb);
1739 if (status < 0) {
1740 mlog_errno(status);
1741 goto bail;
1742 }
1731 } 1743 }
1732 } 1744 }
1733 brelse(eb_bh); 1745 brelse(eb_bh);
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index f1d1c342ce01..3d7c082a8f58 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -391,31 +391,28 @@ out:
391static int ocfs2_commit_write(struct file *file, struct page *page, 391static int ocfs2_commit_write(struct file *file, struct page *page,
392 unsigned from, unsigned to) 392 unsigned from, unsigned to)
393{ 393{
394 int ret, extending = 0, locklevel = 0; 394 int ret;
395 loff_t new_i_size;
396 struct buffer_head *di_bh = NULL; 395 struct buffer_head *di_bh = NULL;
397 struct inode *inode = page->mapping->host; 396 struct inode *inode = page->mapping->host;
398 struct ocfs2_journal_handle *handle = NULL; 397 struct ocfs2_journal_handle *handle = NULL;
398 struct ocfs2_dinode *di;
399 399
400 mlog_entry("(0x%p, 0x%p, %u, %u)\n", file, page, from, to); 400 mlog_entry("(0x%p, 0x%p, %u, %u)\n", file, page, from, to);
401 401
402 /* NOTE: ocfs2_file_aio_write has ensured that it's safe for 402 /* NOTE: ocfs2_file_aio_write has ensured that it's safe for
403 * us to sample inode->i_size here without the metadata lock: 403 * us to continue here without rechecking the I/O against
404 * changed inode values.
404 * 405 *
405 * 1) We're currently holding the inode alloc lock, so no 406 * 1) We're currently holding the inode alloc lock, so no
406 * nodes can change it underneath us. 407 * nodes can change it underneath us.
407 * 408 *
408 * 2) We've had to take the metadata lock at least once 409 * 2) We've had to take the metadata lock at least once
409 * already to check for extending writes, hence insuring 410 * already to check for extending writes, suid removal, etc.
410 * that our current copy is also up to date. 411 * The meta data update code then ensures that we don't get a
412 * stale inode allocation image (i_size, i_clusters, etc).
411 */ 413 */
412 new_i_size = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
413 if (new_i_size > i_size_read(inode)) {
414 extending = 1;
415 locklevel = 1;
416 }
417 414
418 ret = ocfs2_meta_lock_with_page(inode, NULL, &di_bh, locklevel, page); 415 ret = ocfs2_meta_lock_with_page(inode, NULL, &di_bh, 1, page);
419 if (ret != 0) { 416 if (ret != 0) {
420 mlog_errno(ret); 417 mlog_errno(ret);
421 goto out; 418 goto out;
@@ -427,23 +424,20 @@ static int ocfs2_commit_write(struct file *file, struct page *page,
427 goto out_unlock_meta; 424 goto out_unlock_meta;
428 } 425 }
429 426
430 if (extending) { 427 handle = ocfs2_start_walk_page_trans(inode, page, from, to);
431 handle = ocfs2_start_walk_page_trans(inode, page, from, to); 428 if (IS_ERR(handle)) {
432 if (IS_ERR(handle)) { 429 ret = PTR_ERR(handle);
433 ret = PTR_ERR(handle); 430 goto out_unlock_data;
434 handle = NULL; 431 }
435 goto out_unlock_data;
436 }
437 432
438 /* Mark our buffer early. We'd rather catch this error up here 433 /* Mark our buffer early. We'd rather catch this error up here
439 * as opposed to after a successful commit_write which would 434 * as opposed to after a successful commit_write which would
440 * require us to set back inode->i_size. */ 435 * require us to set back inode->i_size. */
441 ret = ocfs2_journal_access(handle, inode, di_bh, 436 ret = ocfs2_journal_access(handle, inode, di_bh,
442 OCFS2_JOURNAL_ACCESS_WRITE); 437 OCFS2_JOURNAL_ACCESS_WRITE);
443 if (ret < 0) { 438 if (ret < 0) {
444 mlog_errno(ret); 439 mlog_errno(ret);
445 goto out_commit; 440 goto out_commit;
446 }
447 } 441 }
448 442
449 /* might update i_size */ 443 /* might update i_size */
@@ -453,37 +447,28 @@ static int ocfs2_commit_write(struct file *file, struct page *page,
453 goto out_commit; 447 goto out_commit;
454 } 448 }
455 449
456 if (extending) { 450 di = (struct ocfs2_dinode *)di_bh->b_data;
457 loff_t size = (u64) i_size_read(inode);
458 struct ocfs2_dinode *di =
459 (struct ocfs2_dinode *)di_bh->b_data;
460 451
461 /* ocfs2_mark_inode_dirty is too heavy to use here. */ 452 /* ocfs2_mark_inode_dirty() is too heavy to use here. */
462 inode->i_blocks = ocfs2_align_bytes_to_sectors(size); 453 inode->i_mtime = inode->i_ctime = CURRENT_TIME;
463 inode->i_ctime = inode->i_mtime = CURRENT_TIME; 454 di->i_mtime = di->i_ctime = cpu_to_le64(inode->i_mtime.tv_sec);
455 di->i_mtime_nsec = di->i_ctime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec);
464 456
465 di->i_size = cpu_to_le64(size); 457 inode->i_blocks = ocfs2_align_bytes_to_sectors((u64)(i_size_read(inode)));
466 di->i_ctime = di->i_mtime = 458 di->i_size = cpu_to_le64((u64)i_size_read(inode));
467 cpu_to_le64(inode->i_mtime.tv_sec);
468 di->i_ctime_nsec = di->i_mtime_nsec =
469 cpu_to_le32(inode->i_mtime.tv_nsec);
470 459
471 ret = ocfs2_journal_dirty(handle, di_bh); 460 ret = ocfs2_journal_dirty(handle, di_bh);
472 if (ret < 0) { 461 if (ret < 0) {
473 mlog_errno(ret); 462 mlog_errno(ret);
474 goto out_commit; 463 goto out_commit;
475 }
476 } 464 }
477 465
478 BUG_ON(extending && (i_size_read(inode) != new_i_size));
479
480out_commit: 466out_commit:
481 if (handle) 467 ocfs2_commit_trans(handle);
482 ocfs2_commit_trans(handle);
483out_unlock_data: 468out_unlock_data:
484 ocfs2_data_unlock(inode, 1); 469 ocfs2_data_unlock(inode, 1);
485out_unlock_meta: 470out_unlock_meta:
486 ocfs2_meta_unlock(inode, locklevel); 471 ocfs2_meta_unlock(inode, 1);
487out: 472out:
488 if (di_bh) 473 if (di_bh)
489 brelse(di_bh); 474 brelse(di_bh);
diff --git a/fs/ocfs2/buffer_head_io.c b/fs/ocfs2/buffer_head_io.c
index 9a24adf9be6e..c9037414f4f6 100644
--- a/fs/ocfs2/buffer_head_io.c
+++ b/fs/ocfs2/buffer_head_io.c
@@ -100,6 +100,9 @@ int ocfs2_read_blocks(struct ocfs2_super *osb, u64 block, int nr,
100 mlog_entry("(block=(%llu), nr=(%d), flags=%d, inode=%p)\n", 100 mlog_entry("(block=(%llu), nr=(%d), flags=%d, inode=%p)\n",
101 (unsigned long long)block, nr, flags, inode); 101 (unsigned long long)block, nr, flags, inode);
102 102
103 BUG_ON((flags & OCFS2_BH_READAHEAD) &&
104 (!inode || !(flags & OCFS2_BH_CACHED)));
105
103 if (osb == NULL || osb->sb == NULL || bhs == NULL) { 106 if (osb == NULL || osb->sb == NULL || bhs == NULL) {
104 status = -EINVAL; 107 status = -EINVAL;
105 mlog_errno(status); 108 mlog_errno(status);
@@ -140,6 +143,30 @@ int ocfs2_read_blocks(struct ocfs2_super *osb, u64 block, int nr,
140 bh = bhs[i]; 143 bh = bhs[i];
141 ignore_cache = 0; 144 ignore_cache = 0;
142 145
146 /* There are three read-ahead cases here which we need to
147 * be concerned with. All three assume a buffer has
148 * previously been submitted with OCFS2_BH_READAHEAD
149 * and it hasn't yet completed I/O.
150 *
151 * 1) The current request is sync to disk. This rarely
152 * happens these days, and never when performance
153 * matters - the code can just wait on the buffer
154 * lock and re-submit.
155 *
156 * 2) The current request is cached, but not
157 * readahead. ocfs2_buffer_uptodate() will return
158 * false anyway, so we'll wind up waiting on the
159 * buffer lock to do I/O. We re-check the request
160 * with after getting the lock to avoid a re-submit.
161 *
162 * 3) The current request is readahead (and so must
163 * also be a caching one). We short circuit if the
164 * buffer is locked (under I/O) and if it's in the
165 * uptodate cache. The re-check from #2 catches the
166 * case that the previous read-ahead completes just
167 * before our is-it-in-flight check.
168 */
169
143 if (flags & OCFS2_BH_CACHED && 170 if (flags & OCFS2_BH_CACHED &&
144 !ocfs2_buffer_uptodate(inode, bh)) { 171 !ocfs2_buffer_uptodate(inode, bh)) {
145 mlog(ML_UPTODATE, 172 mlog(ML_UPTODATE,
@@ -169,6 +196,14 @@ int ocfs2_read_blocks(struct ocfs2_super *osb, u64 block, int nr,
169 continue; 196 continue;
170 } 197 }
171 198
199 /* A read-ahead request was made - if the
200 * buffer is already under read-ahead from a
201 * previously submitted request than we are
202 * done here. */
203 if ((flags & OCFS2_BH_READAHEAD)
204 && ocfs2_buffer_read_ahead(inode, bh))
205 continue;
206
172 lock_buffer(bh); 207 lock_buffer(bh);
173 if (buffer_jbd(bh)) { 208 if (buffer_jbd(bh)) {
174#ifdef CATCH_BH_JBD_RACES 209#ifdef CATCH_BH_JBD_RACES
@@ -181,13 +216,22 @@ int ocfs2_read_blocks(struct ocfs2_super *osb, u64 block, int nr,
181 continue; 216 continue;
182#endif 217#endif
183 } 218 }
219
220 /* Re-check ocfs2_buffer_uptodate() as a
221 * previously read-ahead buffer may have
222 * completed I/O while we were waiting for the
223 * buffer lock. */
224 if ((flags & OCFS2_BH_CACHED)
225 && !(flags & OCFS2_BH_READAHEAD)
226 && ocfs2_buffer_uptodate(inode, bh)) {
227 unlock_buffer(bh);
228 continue;
229 }
230
184 clear_buffer_uptodate(bh); 231 clear_buffer_uptodate(bh);
185 get_bh(bh); /* for end_buffer_read_sync() */ 232 get_bh(bh); /* for end_buffer_read_sync() */
186 bh->b_end_io = end_buffer_read_sync; 233 bh->b_end_io = end_buffer_read_sync;
187 if (flags & OCFS2_BH_READAHEAD) 234 submit_bh(READ, bh);
188 submit_bh(READA, bh);
189 else
190 submit_bh(READ, bh);
191 continue; 235 continue;
192 } 236 }
193 } 237 }
@@ -197,34 +241,39 @@ int ocfs2_read_blocks(struct ocfs2_super *osb, u64 block, int nr,
197 for (i = (nr - 1); i >= 0; i--) { 241 for (i = (nr - 1); i >= 0; i--) {
198 bh = bhs[i]; 242 bh = bhs[i];
199 243
200 /* We know this can't have changed as we hold the 244 if (!(flags & OCFS2_BH_READAHEAD)) {
201 * inode sem. Avoid doing any work on the bh if the 245 /* We know this can't have changed as we hold the
202 * journal has it. */ 246 * inode sem. Avoid doing any work on the bh if the
203 if (!buffer_jbd(bh)) 247 * journal has it. */
204 wait_on_buffer(bh); 248 if (!buffer_jbd(bh))
205 249 wait_on_buffer(bh);
206 if (!buffer_uptodate(bh)) { 250
207 /* Status won't be cleared from here on out, 251 if (!buffer_uptodate(bh)) {
208 * so we can safely record this and loop back 252 /* Status won't be cleared from here on out,
209 * to cleanup the other buffers. Don't need to 253 * so we can safely record this and loop back
210 * remove the clustered uptodate information 254 * to cleanup the other buffers. Don't need to
211 * for this bh as it's not marked locally 255 * remove the clustered uptodate information
212 * uptodate. */ 256 * for this bh as it's not marked locally
213 status = -EIO; 257 * uptodate. */
214 brelse(bh); 258 status = -EIO;
215 bhs[i] = NULL; 259 brelse(bh);
216 continue; 260 bhs[i] = NULL;
261 continue;
262 }
217 } 263 }
218 264
265 /* Always set the buffer in the cache, even if it was
266 * a forced read, or read-ahead which hasn't yet
267 * completed. */
219 if (inode) 268 if (inode)
220 ocfs2_set_buffer_uptodate(inode, bh); 269 ocfs2_set_buffer_uptodate(inode, bh);
221 } 270 }
222 if (inode) 271 if (inode)
223 mutex_unlock(&OCFS2_I(inode)->ip_io_mutex); 272 mutex_unlock(&OCFS2_I(inode)->ip_io_mutex);
224 273
225 mlog(ML_BH_IO, "block=(%llu), nr=(%d), cached=%s\n", 274 mlog(ML_BH_IO, "block=(%llu), nr=(%d), cached=%s, flags=0x%x\n",
226 (unsigned long long)block, nr, 275 (unsigned long long)block, nr,
227 (!(flags & OCFS2_BH_CACHED) || ignore_cache) ? "no" : "yes"); 276 (!(flags & OCFS2_BH_CACHED) || ignore_cache) ? "no" : "yes", flags);
228 277
229bail: 278bail:
230 279
diff --git a/fs/ocfs2/buffer_head_io.h b/fs/ocfs2/buffer_head_io.h
index 6ecb90937b68..6cc20930fac3 100644
--- a/fs/ocfs2/buffer_head_io.h
+++ b/fs/ocfs2/buffer_head_io.h
@@ -49,7 +49,7 @@ int ocfs2_read_blocks(struct ocfs2_super *osb,
49 49
50 50
51#define OCFS2_BH_CACHED 1 51#define OCFS2_BH_CACHED 1
52#define OCFS2_BH_READAHEAD 8 /* use this to pass READA down to submit_bh */ 52#define OCFS2_BH_READAHEAD 8
53 53
54static inline int ocfs2_read_block(struct ocfs2_super * osb, u64 off, 54static inline int ocfs2_read_block(struct ocfs2_super * osb, u64 off,
55 struct buffer_head **bh, int flags, 55 struct buffer_head **bh, int flags,
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index 504595d6cf65..305cba3681fe 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -320,8 +320,12 @@ static int compute_max_sectors(struct block_device *bdev)
320 max_pages = q->max_hw_segments; 320 max_pages = q->max_hw_segments;
321 max_pages--; /* Handle I/Os that straddle a page */ 321 max_pages--; /* Handle I/Os that straddle a page */
322 322
323 max_sectors = max_pages << (PAGE_SHIFT - 9); 323 if (max_pages) {
324 324 max_sectors = max_pages << (PAGE_SHIFT - 9);
325 } else {
326 /* If BIO contains 1 or less than 1 page. */
327 max_sectors = q->max_sectors;
328 }
325 /* Why is fls() 1-based???? */ 329 /* Why is fls() 1-based???? */
326 pow_two_sectors = 1 << (fls(max_sectors) - 1); 330 pow_two_sectors = 1 << (fls(max_sectors) - 1);
327 331
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index 3d494d1a5f36..04e01915b86e 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -74,14 +74,14 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,
74int ocfs2_readdir(struct file * filp, void * dirent, filldir_t filldir) 74int ocfs2_readdir(struct file * filp, void * dirent, filldir_t filldir)
75{ 75{
76 int error = 0; 76 int error = 0;
77 unsigned long offset, blk; 77 unsigned long offset, blk, last_ra_blk = 0;
78 int i, num, stored; 78 int i, stored;
79 struct buffer_head * bh, * tmp; 79 struct buffer_head * bh, * tmp;
80 struct ocfs2_dir_entry * de; 80 struct ocfs2_dir_entry * de;
81 int err; 81 int err;
82 struct inode *inode = filp->f_dentry->d_inode; 82 struct inode *inode = filp->f_dentry->d_inode;
83 struct super_block * sb = inode->i_sb; 83 struct super_block * sb = inode->i_sb;
84 int have_disk_lock = 0; 84 unsigned int ra_sectors = 16;
85 85
86 mlog_entry("dirino=%llu\n", 86 mlog_entry("dirino=%llu\n",
87 (unsigned long long)OCFS2_I(inode)->ip_blkno); 87 (unsigned long long)OCFS2_I(inode)->ip_blkno);
@@ -95,9 +95,8 @@ int ocfs2_readdir(struct file * filp, void * dirent, filldir_t filldir)
95 mlog_errno(error); 95 mlog_errno(error);
96 /* we haven't got any yet, so propagate the error. */ 96 /* we haven't got any yet, so propagate the error. */
97 stored = error; 97 stored = error;
98 goto bail; 98 goto bail_nolock;
99 } 99 }
100 have_disk_lock = 1;
101 100
102 offset = filp->f_pos & (sb->s_blocksize - 1); 101 offset = filp->f_pos & (sb->s_blocksize - 1);
103 102
@@ -113,16 +112,21 @@ int ocfs2_readdir(struct file * filp, void * dirent, filldir_t filldir)
113 continue; 112 continue;
114 } 113 }
115 114
116 /* 115 /* The idea here is to begin with 8k read-ahead and to stay
117 * Do the readahead (8k) 116 * 4k ahead of our current position.
118 */ 117 *
119 if (!offset) { 118 * TODO: Use the pagecache for this. We just need to
120 for (i = 16 >> (sb->s_blocksize_bits - 9), num = 0; 119 * make sure it's cluster-safe... */
120 if (!last_ra_blk
121 || (((last_ra_blk - blk) << 9) <= (ra_sectors / 2))) {
122 for (i = ra_sectors >> (sb->s_blocksize_bits - 9);
121 i > 0; i--) { 123 i > 0; i--) {
122 tmp = ocfs2_bread(inode, ++blk, &err, 1); 124 tmp = ocfs2_bread(inode, ++blk, &err, 1);
123 if (tmp) 125 if (tmp)
124 brelse(tmp); 126 brelse(tmp);
125 } 127 }
128 last_ra_blk = blk;
129 ra_sectors = 8;
126 } 130 }
127 131
128revalidate: 132revalidate:
@@ -194,9 +198,9 @@ revalidate:
194 198
195 stored = 0; 199 stored = 0;
196bail: 200bail:
197 if (have_disk_lock) 201 ocfs2_meta_unlock(inode, 0);
198 ocfs2_meta_unlock(inode, 0);
199 202
203bail_nolock:
200 mlog_exit(stored); 204 mlog_exit(stored);
201 205
202 return stored; 206 return stored;
diff --git a/fs/ocfs2/dlm/dlmast.c b/fs/ocfs2/dlm/dlmast.c
index 42775e2bbe2c..f13a4bac41f0 100644
--- a/fs/ocfs2/dlm/dlmast.c
+++ b/fs/ocfs2/dlm/dlmast.c
@@ -367,12 +367,10 @@ int dlm_proxy_ast_handler(struct o2net_msg *msg, u32 len, void *data)
367 goto do_ast; 367 goto do_ast;
368 } 368 }
369 369
370 mlog(ML_ERROR, "got %sast for unknown lock! cookie=%u:%llu, " 370 mlog(0, "got %sast for unknown lock! cookie=%u:%llu, "
371 "name=%.*s, namelen=%u\n", 371 "name=%.*s, namelen=%u\n", past->type == DLM_AST ? "" : "b",
372 past->type == DLM_AST ? "" : "b", 372 dlm_get_lock_cookie_node(cookie), dlm_get_lock_cookie_seq(cookie),
373 dlm_get_lock_cookie_node(cookie), 373 locklen, name, locklen);
374 dlm_get_lock_cookie_seq(cookie),
375 locklen, name, locklen);
376 374
377 ret = DLM_NORMAL; 375 ret = DLM_NORMAL;
378unlock_out: 376unlock_out:
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index 762eb1fbb34d..151b41781eab 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -1330,6 +1330,7 @@ static void __ocfs2_stuff_meta_lvb(struct inode *inode)
1330 cpu_to_be64(ocfs2_pack_timespec(&inode->i_ctime)); 1330 cpu_to_be64(ocfs2_pack_timespec(&inode->i_ctime));
1331 lvb->lvb_imtime_packed = 1331 lvb->lvb_imtime_packed =
1332 cpu_to_be64(ocfs2_pack_timespec(&inode->i_mtime)); 1332 cpu_to_be64(ocfs2_pack_timespec(&inode->i_mtime));
1333 lvb->lvb_iattr = cpu_to_be32(oi->ip_attr);
1333 1334
1334 mlog_meta_lvb(0, lockres); 1335 mlog_meta_lvb(0, lockres);
1335 1336
@@ -1360,6 +1361,9 @@ static void ocfs2_refresh_inode_from_lvb(struct inode *inode)
1360 oi->ip_clusters = be32_to_cpu(lvb->lvb_iclusters); 1361 oi->ip_clusters = be32_to_cpu(lvb->lvb_iclusters);
1361 i_size_write(inode, be64_to_cpu(lvb->lvb_isize)); 1362 i_size_write(inode, be64_to_cpu(lvb->lvb_isize));
1362 1363
1364 oi->ip_attr = be32_to_cpu(lvb->lvb_iattr);
1365 ocfs2_set_inode_flags(inode);
1366
1363 /* fast-symlinks are a special case */ 1367 /* fast-symlinks are a special case */
1364 if (S_ISLNK(inode->i_mode) && !oi->ip_clusters) 1368 if (S_ISLNK(inode->i_mode) && !oi->ip_clusters)
1365 inode->i_blocks = 0; 1369 inode->i_blocks = 0;
@@ -2899,8 +2903,9 @@ void ocfs2_dump_meta_lvb_info(u64 level,
2899 be32_to_cpu(lvb->lvb_iuid), be32_to_cpu(lvb->lvb_igid), 2903 be32_to_cpu(lvb->lvb_iuid), be32_to_cpu(lvb->lvb_igid),
2900 be16_to_cpu(lvb->lvb_imode)); 2904 be16_to_cpu(lvb->lvb_imode));
2901 mlog(level, "nlink %u, atime_packed 0x%llx, ctime_packed 0x%llx, " 2905 mlog(level, "nlink %u, atime_packed 0x%llx, ctime_packed 0x%llx, "
2902 "mtime_packed 0x%llx\n", be16_to_cpu(lvb->lvb_inlink), 2906 "mtime_packed 0x%llx iattr 0x%x\n", be16_to_cpu(lvb->lvb_inlink),
2903 (long long)be64_to_cpu(lvb->lvb_iatime_packed), 2907 (long long)be64_to_cpu(lvb->lvb_iatime_packed),
2904 (long long)be64_to_cpu(lvb->lvb_ictime_packed), 2908 (long long)be64_to_cpu(lvb->lvb_ictime_packed),
2905 (long long)be64_to_cpu(lvb->lvb_imtime_packed)); 2909 (long long)be64_to_cpu(lvb->lvb_imtime_packed),
2910 be32_to_cpu(lvb->lvb_iattr));
2906} 2911}
diff --git a/fs/ocfs2/dlmglue.h b/fs/ocfs2/dlmglue.h
index 8f2d1db2d9ea..243ae862ece5 100644
--- a/fs/ocfs2/dlmglue.h
+++ b/fs/ocfs2/dlmglue.h
@@ -27,7 +27,7 @@
27#ifndef DLMGLUE_H 27#ifndef DLMGLUE_H
28#define DLMGLUE_H 28#define DLMGLUE_H
29 29
30#define OCFS2_LVB_VERSION 2 30#define OCFS2_LVB_VERSION 3
31 31
32struct ocfs2_meta_lvb { 32struct ocfs2_meta_lvb {
33 __be32 lvb_version; 33 __be32 lvb_version;
@@ -40,7 +40,8 @@ struct ocfs2_meta_lvb {
40 __be64 lvb_isize; 40 __be64 lvb_isize;
41 __be16 lvb_imode; 41 __be16 lvb_imode;
42 __be16 lvb_inlink; 42 __be16 lvb_inlink;
43 __be32 lvb_reserved[3]; 43 __be32 lvb_iattr;
44 __be32 lvb_reserved[2];
44}; 45};
45 46
46/* ocfs2_meta_lock_full() and ocfs2_data_lock_full() 'arg_flags' flags */ 47/* ocfs2_meta_lock_full() and ocfs2_data_lock_full() 'arg_flags' flags */
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index a9559c874530..2bbfa17090cf 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -44,6 +44,7 @@
44#include "file.h" 44#include "file.h"
45#include "sysfile.h" 45#include "sysfile.h"
46#include "inode.h" 46#include "inode.h"
47#include "ioctl.h"
47#include "journal.h" 48#include "journal.h"
48#include "mmap.h" 49#include "mmap.h"
49#include "suballoc.h" 50#include "suballoc.h"
@@ -1227,10 +1228,12 @@ const struct file_operations ocfs2_fops = {
1227 .open = ocfs2_file_open, 1228 .open = ocfs2_file_open,
1228 .aio_read = ocfs2_file_aio_read, 1229 .aio_read = ocfs2_file_aio_read,
1229 .aio_write = ocfs2_file_aio_write, 1230 .aio_write = ocfs2_file_aio_write,
1231 .ioctl = ocfs2_ioctl,
1230}; 1232};
1231 1233
1232const struct file_operations ocfs2_dops = { 1234const struct file_operations ocfs2_dops = {
1233 .read = generic_read_dir, 1235 .read = generic_read_dir,
1234 .readdir = ocfs2_readdir, 1236 .readdir = ocfs2_readdir,
1235 .fsync = ocfs2_sync_file, 1237 .fsync = ocfs2_sync_file,
1238 .ioctl = ocfs2_ioctl,
1236}; 1239};
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
index 327a5b7b86ed..7bcf69154592 100644
--- a/fs/ocfs2/inode.c
+++ b/fs/ocfs2/inode.c
@@ -71,6 +71,26 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb,
71 struct inode *inode, 71 struct inode *inode,
72 struct buffer_head *fe_bh); 72 struct buffer_head *fe_bh);
73 73
74void ocfs2_set_inode_flags(struct inode *inode)
75{
76 unsigned int flags = OCFS2_I(inode)->ip_attr;
77
78 inode->i_flags &= ~(S_IMMUTABLE |
79 S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
80
81 if (flags & OCFS2_IMMUTABLE_FL)
82 inode->i_flags |= S_IMMUTABLE;
83
84 if (flags & OCFS2_SYNC_FL)
85 inode->i_flags |= S_SYNC;
86 if (flags & OCFS2_APPEND_FL)
87 inode->i_flags |= S_APPEND;
88 if (flags & OCFS2_NOATIME_FL)
89 inode->i_flags |= S_NOATIME;
90 if (flags & OCFS2_DIRSYNC_FL)
91 inode->i_flags |= S_DIRSYNC;
92}
93
74struct inode *ocfs2_ilookup_for_vote(struct ocfs2_super *osb, 94struct inode *ocfs2_ilookup_for_vote(struct ocfs2_super *osb,
75 u64 blkno, 95 u64 blkno,
76 int delete_vote) 96 int delete_vote)
@@ -260,7 +280,6 @@ int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
260 inode->i_blocks = 280 inode->i_blocks =
261 ocfs2_align_bytes_to_sectors(le64_to_cpu(fe->i_size)); 281 ocfs2_align_bytes_to_sectors(le64_to_cpu(fe->i_size));
262 inode->i_mapping->a_ops = &ocfs2_aops; 282 inode->i_mapping->a_ops = &ocfs2_aops;
263 inode->i_flags |= S_NOATIME;
264 inode->i_atime.tv_sec = le64_to_cpu(fe->i_atime); 283 inode->i_atime.tv_sec = le64_to_cpu(fe->i_atime);
265 inode->i_atime.tv_nsec = le32_to_cpu(fe->i_atime_nsec); 284 inode->i_atime.tv_nsec = le32_to_cpu(fe->i_atime_nsec);
266 inode->i_mtime.tv_sec = le64_to_cpu(fe->i_mtime); 285 inode->i_mtime.tv_sec = le64_to_cpu(fe->i_mtime);
@@ -276,6 +295,7 @@ int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
276 295
277 OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters); 296 OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
278 OCFS2_I(inode)->ip_orphaned_slot = OCFS2_INVALID_SLOT; 297 OCFS2_I(inode)->ip_orphaned_slot = OCFS2_INVALID_SLOT;
298 OCFS2_I(inode)->ip_attr = le32_to_cpu(fe->i_attr);
279 299
280 if (create_ino) 300 if (create_ino)
281 inode->i_ino = ino_from_blkno(inode->i_sb, 301 inode->i_ino = ino_from_blkno(inode->i_sb,
@@ -330,6 +350,9 @@ int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
330 ocfs2_inode_lock_res_init(&OCFS2_I(inode)->ip_data_lockres, 350 ocfs2_inode_lock_res_init(&OCFS2_I(inode)->ip_data_lockres,
331 OCFS2_LOCK_TYPE_DATA, inode); 351 OCFS2_LOCK_TYPE_DATA, inode);
332 352
353 ocfs2_set_inode_flags(inode);
354 inode->i_flags |= S_NOATIME;
355
333 status = 0; 356 status = 0;
334bail: 357bail:
335 mlog_exit(status); 358 mlog_exit(status);
@@ -1027,12 +1050,8 @@ struct buffer_head *ocfs2_bread(struct inode *inode,
1027 u64 p_blkno; 1050 u64 p_blkno;
1028 int readflags = OCFS2_BH_CACHED; 1051 int readflags = OCFS2_BH_CACHED;
1029 1052
1030#if 0
1031 /* only turn this on if we know we can deal with read_block
1032 * returning nothing */
1033 if (reada) 1053 if (reada)
1034 readflags |= OCFS2_BH_READAHEAD; 1054 readflags |= OCFS2_BH_READAHEAD;
1035#endif
1036 1055
1037 if (((u64)block << inode->i_sb->s_blocksize_bits) >= 1056 if (((u64)block << inode->i_sb->s_blocksize_bits) >=
1038 i_size_read(inode)) { 1057 i_size_read(inode)) {
@@ -1131,6 +1150,7 @@ int ocfs2_mark_inode_dirty(struct ocfs2_journal_handle *handle,
1131 1150
1132 spin_lock(&OCFS2_I(inode)->ip_lock); 1151 spin_lock(&OCFS2_I(inode)->ip_lock);
1133 fe->i_clusters = cpu_to_le32(OCFS2_I(inode)->ip_clusters); 1152 fe->i_clusters = cpu_to_le32(OCFS2_I(inode)->ip_clusters);
1153 fe->i_attr = cpu_to_le32(OCFS2_I(inode)->ip_attr);
1134 spin_unlock(&OCFS2_I(inode)->ip_lock); 1154 spin_unlock(&OCFS2_I(inode)->ip_lock);
1135 1155
1136 fe->i_size = cpu_to_le64(i_size_read(inode)); 1156 fe->i_size = cpu_to_le64(i_size_read(inode));
@@ -1169,6 +1189,8 @@ void ocfs2_refresh_inode(struct inode *inode,
1169 spin_lock(&OCFS2_I(inode)->ip_lock); 1189 spin_lock(&OCFS2_I(inode)->ip_lock);
1170 1190
1171 OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters); 1191 OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
1192 OCFS2_I(inode)->ip_attr = le32_to_cpu(fe->i_attr);
1193 ocfs2_set_inode_flags(inode);
1172 i_size_write(inode, le64_to_cpu(fe->i_size)); 1194 i_size_write(inode, le64_to_cpu(fe->i_size));
1173 inode->i_nlink = le16_to_cpu(fe->i_links_count); 1195 inode->i_nlink = le16_to_cpu(fe->i_links_count);
1174 inode->i_uid = le32_to_cpu(fe->i_uid); 1196 inode->i_uid = le32_to_cpu(fe->i_uid);
diff --git a/fs/ocfs2/inode.h b/fs/ocfs2/inode.h
index 35140f6cf840..4d1e53992566 100644
--- a/fs/ocfs2/inode.h
+++ b/fs/ocfs2/inode.h
@@ -56,6 +56,7 @@ struct ocfs2_inode_info
56 struct ocfs2_journal_handle *ip_handle; 56 struct ocfs2_journal_handle *ip_handle;
57 57
58 u32 ip_flags; /* see below */ 58 u32 ip_flags; /* see below */
59 u32 ip_attr; /* inode attributes */
59 60
60 /* protected by recovery_lock. */ 61 /* protected by recovery_lock. */
61 struct inode *ip_next_orphan; 62 struct inode *ip_next_orphan;
@@ -142,4 +143,6 @@ int ocfs2_mark_inode_dirty(struct ocfs2_journal_handle *handle,
142int ocfs2_aio_read(struct file *file, struct kiocb *req, struct iocb *iocb); 143int ocfs2_aio_read(struct file *file, struct kiocb *req, struct iocb *iocb);
143int ocfs2_aio_write(struct file *file, struct kiocb *req, struct iocb *iocb); 144int ocfs2_aio_write(struct file *file, struct kiocb *req, struct iocb *iocb);
144 145
146void ocfs2_set_inode_flags(struct inode *inode);
147
145#endif /* OCFS2_INODE_H */ 148#endif /* OCFS2_INODE_H */
diff --git a/fs/ocfs2/ioctl.c b/fs/ocfs2/ioctl.c
new file mode 100644
index 000000000000..3663cef80689
--- /dev/null
+++ b/fs/ocfs2/ioctl.c
@@ -0,0 +1,136 @@
1/*
2 * linux/fs/ocfs2/ioctl.c
3 *
4 * Copyright (C) 2006 Herbert Poetzl
5 * adapted from Remy Card's ext2/ioctl.c
6 */
7
8#include <linux/fs.h>
9#include <linux/mount.h>
10
11#define MLOG_MASK_PREFIX ML_INODE
12#include <cluster/masklog.h>
13
14#include "ocfs2.h"
15#include "alloc.h"
16#include "dlmglue.h"
17#include "inode.h"
18#include "journal.h"
19
20#include "ocfs2_fs.h"
21#include "ioctl.h"
22
23#include <linux/ext2_fs.h>
24
25static int ocfs2_get_inode_attr(struct inode *inode, unsigned *flags)
26{
27 int status;
28
29 status = ocfs2_meta_lock(inode, NULL, NULL, 0);
30 if (status < 0) {
31 mlog_errno(status);
32 return status;
33 }
34 *flags = OCFS2_I(inode)->ip_attr;
35 ocfs2_meta_unlock(inode, 0);
36
37 mlog_exit(status);
38 return status;
39}
40
41static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
42 unsigned mask)
43{
44 struct ocfs2_inode_info *ocfs2_inode = OCFS2_I(inode);
45 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
46 struct ocfs2_journal_handle *handle = NULL;
47 struct buffer_head *bh = NULL;
48 unsigned oldflags;
49 int status;
50
51 mutex_lock(&inode->i_mutex);
52
53 status = ocfs2_meta_lock(inode, NULL, &bh, 1);
54 if (status < 0) {
55 mlog_errno(status);
56 goto bail;
57 }
58
59 status = -EROFS;
60 if (IS_RDONLY(inode))
61 goto bail_unlock;
62
63 status = -EACCES;
64 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
65 goto bail_unlock;
66
67 if (!S_ISDIR(inode->i_mode))
68 flags &= ~OCFS2_DIRSYNC_FL;
69
70 handle = ocfs2_start_trans(osb, NULL, OCFS2_INODE_UPDATE_CREDITS);
71 if (IS_ERR(handle)) {
72 status = PTR_ERR(handle);
73 mlog_errno(status);
74 goto bail_unlock;
75 }
76
77 oldflags = ocfs2_inode->ip_attr;
78 flags = flags & mask;
79 flags |= oldflags & ~mask;
80
81 /*
82 * The IMMUTABLE and APPEND_ONLY flags can only be changed by
83 * the relevant capability.
84 */
85 status = -EPERM;
86 if ((oldflags & OCFS2_IMMUTABLE_FL) || ((flags ^ oldflags) &
87 (OCFS2_APPEND_FL | OCFS2_IMMUTABLE_FL))) {
88 if (!capable(CAP_LINUX_IMMUTABLE))
89 goto bail_unlock;
90 }
91
92 ocfs2_inode->ip_attr = flags;
93 ocfs2_set_inode_flags(inode);
94
95 status = ocfs2_mark_inode_dirty(handle, inode, bh);
96 if (status < 0)
97 mlog_errno(status);
98
99 ocfs2_commit_trans(handle);
100bail_unlock:
101 ocfs2_meta_unlock(inode, 1);
102bail:
103 mutex_unlock(&inode->i_mutex);
104
105 if (bh)
106 brelse(bh);
107
108 mlog_exit(status);
109 return status;
110}
111
112int ocfs2_ioctl(struct inode * inode, struct file * filp,
113 unsigned int cmd, unsigned long arg)
114{
115 unsigned int flags;
116 int status;
117
118 switch (cmd) {
119 case OCFS2_IOC_GETFLAGS:
120 status = ocfs2_get_inode_attr(inode, &flags);
121 if (status < 0)
122 return status;
123
124 flags &= OCFS2_FL_VISIBLE;
125 return put_user(flags, (int __user *) arg);
126 case OCFS2_IOC_SETFLAGS:
127 if (get_user(flags, (int __user *) arg))
128 return -EFAULT;
129
130 return ocfs2_set_inode_attr(inode, flags,
131 OCFS2_FL_MODIFIABLE);
132 default:
133 return -ENOTTY;
134 }
135}
136
diff --git a/fs/ocfs2/ioctl.h b/fs/ocfs2/ioctl.h
new file mode 100644
index 000000000000..4a7c82931dba
--- /dev/null
+++ b/fs/ocfs2/ioctl.h
@@ -0,0 +1,16 @@
1/*
2 * ioctl.h
3 *
4 * Function prototypes
5 *
6 * Copyright (C) 2006 Herbert Poetzl
7 *
8 */
9
10#ifndef OCFS2_IOCTL_H
11#define OCFS2_IOCTL_H
12
13int ocfs2_ioctl(struct inode * inode, struct file * filp,
14 unsigned int cmd, unsigned long arg);
15
16#endif /* OCFS2_IOCTL_H */
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index 0673862c8bdd..0d3e939b1f56 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -56,6 +56,7 @@
56#include "journal.h" 56#include "journal.h"
57#include "namei.h" 57#include "namei.h"
58#include "suballoc.h" 58#include "suballoc.h"
59#include "super.h"
59#include "symlink.h" 60#include "symlink.h"
60#include "sysfile.h" 61#include "sysfile.h"
61#include "uptodate.h" 62#include "uptodate.h"
@@ -310,13 +311,6 @@ static int ocfs2_mknod(struct inode *dir,
310 /* get our super block */ 311 /* get our super block */
311 osb = OCFS2_SB(dir->i_sb); 312 osb = OCFS2_SB(dir->i_sb);
312 313
313 if (S_ISDIR(mode) && (dir->i_nlink >= OCFS2_LINK_MAX)) {
314 mlog(ML_ERROR, "inode %llu has i_nlink of %u\n",
315 (unsigned long long)OCFS2_I(dir)->ip_blkno, dir->i_nlink);
316 status = -EMLINK;
317 goto leave;
318 }
319
320 handle = ocfs2_alloc_handle(osb); 314 handle = ocfs2_alloc_handle(osb);
321 if (handle == NULL) { 315 if (handle == NULL) {
322 status = -ENOMEM; 316 status = -ENOMEM;
@@ -331,6 +325,11 @@ static int ocfs2_mknod(struct inode *dir,
331 goto leave; 325 goto leave;
332 } 326 }
333 327
328 if (S_ISDIR(mode) && (dir->i_nlink >= OCFS2_LINK_MAX)) {
329 status = -EMLINK;
330 goto leave;
331 }
332
334 dirfe = (struct ocfs2_dinode *) parent_fe_bh->b_data; 333 dirfe = (struct ocfs2_dinode *) parent_fe_bh->b_data;
335 if (!dirfe->i_links_count) { 334 if (!dirfe->i_links_count) {
336 /* can't make a file in a deleted directory. */ 335 /* can't make a file in a deleted directory. */
@@ -643,11 +642,6 @@ static int ocfs2_link(struct dentry *old_dentry,
643 goto bail; 642 goto bail;
644 } 643 }
645 644
646 if (inode->i_nlink >= OCFS2_LINK_MAX) {
647 err = -EMLINK;
648 goto bail;
649 }
650
651 handle = ocfs2_alloc_handle(osb); 645 handle = ocfs2_alloc_handle(osb);
652 if (handle == NULL) { 646 if (handle == NULL) {
653 err = -ENOMEM; 647 err = -ENOMEM;
@@ -661,6 +655,11 @@ static int ocfs2_link(struct dentry *old_dentry,
661 goto bail; 655 goto bail;
662 } 656 }
663 657
658 if (!dir->i_nlink) {
659 err = -ENOENT;
660 goto bail;
661 }
662
664 err = ocfs2_check_dir_for_entry(dir, dentry->d_name.name, 663 err = ocfs2_check_dir_for_entry(dir, dentry->d_name.name,
665 dentry->d_name.len); 664 dentry->d_name.len);
666 if (err) 665 if (err)
@@ -1964,13 +1963,8 @@ restart:
1964 } 1963 }
1965 num++; 1964 num++;
1966 1965
1967 /* XXX: questionable readahead stuff here */
1968 bh = ocfs2_bread(dir, b++, &err, 1); 1966 bh = ocfs2_bread(dir, b++, &err, 1);
1969 bh_use[ra_max] = bh; 1967 bh_use[ra_max] = bh;
1970#if 0 // ???
1971 if (bh)
1972 ll_rw_block(READ, 1, &bh);
1973#endif
1974 } 1968 }
1975 } 1969 }
1976 if ((bh = bh_use[ra_ptr++]) == NULL) 1970 if ((bh = bh_use[ra_ptr++]) == NULL)
@@ -1978,6 +1972,10 @@ restart:
1978 wait_on_buffer(bh); 1972 wait_on_buffer(bh);
1979 if (!buffer_uptodate(bh)) { 1973 if (!buffer_uptodate(bh)) {
1980 /* read error, skip block & hope for the best */ 1974 /* read error, skip block & hope for the best */
1975 ocfs2_error(dir->i_sb, "reading directory %llu, "
1976 "offset %lu\n",
1977 (unsigned long long)OCFS2_I(dir)->ip_blkno,
1978 block);
1981 brelse(bh); 1979 brelse(bh);
1982 goto next; 1980 goto next;
1983 } 1981 }
diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h
index c5b1ac547c15..3330a5dc6be2 100644
--- a/fs/ocfs2/ocfs2_fs.h
+++ b/fs/ocfs2/ocfs2_fs.h
@@ -114,6 +114,26 @@
114#define OCFS2_CHAIN_FL (0x00000400) /* Chain allocator */ 114#define OCFS2_CHAIN_FL (0x00000400) /* Chain allocator */
115#define OCFS2_DEALLOC_FL (0x00000800) /* Truncate log */ 115#define OCFS2_DEALLOC_FL (0x00000800) /* Truncate log */
116 116
117/* Inode attributes, keep in sync with EXT2 */
118#define OCFS2_SECRM_FL (0x00000001) /* Secure deletion */
119#define OCFS2_UNRM_FL (0x00000002) /* Undelete */
120#define OCFS2_COMPR_FL (0x00000004) /* Compress file */
121#define OCFS2_SYNC_FL (0x00000008) /* Synchronous updates */
122#define OCFS2_IMMUTABLE_FL (0x00000010) /* Immutable file */
123#define OCFS2_APPEND_FL (0x00000020) /* writes to file may only append */
124#define OCFS2_NODUMP_FL (0x00000040) /* do not dump file */
125#define OCFS2_NOATIME_FL (0x00000080) /* do not update atime */
126#define OCFS2_DIRSYNC_FL (0x00010000) /* dirsync behaviour (directories only) */
127
128#define OCFS2_FL_VISIBLE (0x000100FF) /* User visible flags */
129#define OCFS2_FL_MODIFIABLE (0x000100FF) /* User modifiable flags */
130
131/*
132 * ioctl commands
133 */
134#define OCFS2_IOC_GETFLAGS _IOR('f', 1, long)
135#define OCFS2_IOC_SETFLAGS _IOW('f', 2, long)
136
117/* 137/*
118 * Journal Flags (ocfs2_dinode.id1.journal1.i_flags) 138 * Journal Flags (ocfs2_dinode.id1.journal1.i_flags)
119 */ 139 */
@@ -399,7 +419,9 @@ struct ocfs2_dinode {
399 __le32 i_atime_nsec; 419 __le32 i_atime_nsec;
400 __le32 i_ctime_nsec; 420 __le32 i_ctime_nsec;
401 __le32 i_mtime_nsec; 421 __le32 i_mtime_nsec;
402/*70*/ __le64 i_reserved1[9]; 422 __le32 i_attr;
423 __le32 i_reserved1;
424/*70*/ __le64 i_reserved2[8];
403/*B8*/ union { 425/*B8*/ union {
404 __le64 i_pad1; /* Generic way to refer to this 426 __le64 i_pad1; /* Generic way to refer to this
405 64bit union */ 427 64bit union */
diff --git a/fs/ocfs2/uptodate.c b/fs/ocfs2/uptodate.c
index b8a00a793326..9707ed7a3206 100644
--- a/fs/ocfs2/uptodate.c
+++ b/fs/ocfs2/uptodate.c
@@ -206,7 +206,10 @@ static int ocfs2_buffer_cached(struct ocfs2_inode_info *oi,
206} 206}
207 207
208/* Warning: even if it returns true, this does *not* guarantee that 208/* Warning: even if it returns true, this does *not* guarantee that
209 * the block is stored in our inode metadata cache. */ 209 * the block is stored in our inode metadata cache.
210 *
211 * This can be called under lock_buffer()
212 */
210int ocfs2_buffer_uptodate(struct inode *inode, 213int ocfs2_buffer_uptodate(struct inode *inode,
211 struct buffer_head *bh) 214 struct buffer_head *bh)
212{ 215{
@@ -226,6 +229,16 @@ int ocfs2_buffer_uptodate(struct inode *inode,
226 return ocfs2_buffer_cached(OCFS2_I(inode), bh); 229 return ocfs2_buffer_cached(OCFS2_I(inode), bh);
227} 230}
228 231
232/*
233 * Determine whether a buffer is currently out on a read-ahead request.
234 * ip_io_sem should be held to serialize submitters with the logic here.
235 */
236int ocfs2_buffer_read_ahead(struct inode *inode,
237 struct buffer_head *bh)
238{
239 return buffer_locked(bh) && ocfs2_buffer_cached(OCFS2_I(inode), bh);
240}
241
229/* Requires ip_lock */ 242/* Requires ip_lock */
230static void ocfs2_append_cache_array(struct ocfs2_caching_info *ci, 243static void ocfs2_append_cache_array(struct ocfs2_caching_info *ci,
231 sector_t block) 244 sector_t block)
@@ -403,7 +416,11 @@ out_free:
403 * 416 *
404 * Note that this function may actually fail to insert the block if 417 * Note that this function may actually fail to insert the block if
405 * memory cannot be allocated. This is not fatal however (but may 418 * memory cannot be allocated. This is not fatal however (but may
406 * result in a performance penalty) */ 419 * result in a performance penalty)
420 *
421 * Readahead buffers can be passed in here before the I/O request is
422 * completed.
423 */
407void ocfs2_set_buffer_uptodate(struct inode *inode, 424void ocfs2_set_buffer_uptodate(struct inode *inode,
408 struct buffer_head *bh) 425 struct buffer_head *bh)
409{ 426{
diff --git a/fs/ocfs2/uptodate.h b/fs/ocfs2/uptodate.h
index 01cd32d26b06..2e73206059a8 100644
--- a/fs/ocfs2/uptodate.h
+++ b/fs/ocfs2/uptodate.h
@@ -40,5 +40,7 @@ void ocfs2_set_new_buffer_uptodate(struct inode *inode,
40 struct buffer_head *bh); 40 struct buffer_head *bh);
41void ocfs2_remove_from_cache(struct inode *inode, 41void ocfs2_remove_from_cache(struct inode *inode,
42 struct buffer_head *bh); 42 struct buffer_head *bh);
43int ocfs2_buffer_read_ahead(struct inode *inode,
44 struct buffer_head *bh);
43 45
44#endif /* OCFS2_UPTODATE_H */ 46#endif /* OCFS2_UPTODATE_H */