patch-2.3.32 linux/fs/buffer.c
Next file: linux/fs/coda/symlink.c
Previous file: linux/fs/autofs/symlink.c
Back to the patch index
Back to the overall index
- Lines: 110
- Date:
Thu Dec 9 13:10:18 1999
- Orig file:
v2.3.31/linux/fs/buffer.c
- Orig date:
Tue Dec 7 09:32:47 1999
diff -u --recursive --new-file v2.3.31/linux/fs/buffer.c linux/fs/buffer.c
@@ -1378,11 +1378,10 @@
return err;
}
-int block_write_range(struct dentry *dentry, struct page *page,
+int block_write_zero_range(struct inode *inode, struct page *page,
unsigned zerofrom, unsigned from, unsigned to,
const char * buf)
{
- struct inode *inode = dentry->d_inode;
unsigned zeroto = 0, block_start, block_end;
unsigned long block;
int err = 0, partial = 0, need_balance_dirty = 0;
@@ -1504,7 +1503,7 @@
int block_write_partial_page(struct file *file, struct page *page, unsigned long offset, unsigned long bytes, const char * buf)
{
- struct dentry *dentry = file->f_dentry;
+ struct inode *inode = file->f_dentry->d_inode;
int err;
if (!PageLocked(page))
@@ -1514,7 +1513,7 @@
if (bytes+offset < 0 || bytes+offset > PAGE_SIZE)
BUG();
- err = block_write_range(dentry, page, offset,offset,offset+bytes, buf);
+ err = block_write_range(inode, page, offset, bytes, buf);
return err ? err : bytes;
}
@@ -1525,8 +1524,7 @@
int block_write_cont_page(struct file *file, struct page *page, unsigned long offset, unsigned long bytes, const char * buf)
{
- struct dentry *dentry = file->f_dentry;
- struct inode *inode = dentry->d_inode;
+ struct inode *inode = file->f_dentry->d_inode;
int err;
unsigned zerofrom = offset;
@@ -1535,7 +1533,8 @@
else if (page->index == (inode->i_size >> PAGE_CACHE_SHIFT) &&
offset > (inode->i_size & ~PAGE_CACHE_MASK))
zerofrom = inode->i_size & ~PAGE_CACHE_MASK;
- err = block_write_range(dentry, page, zerofrom,offset,offset+bytes,buf);
+ err = block_write_zero_range(inode, page, zerofrom,offset,offset+bytes,
+ buf);
return err ? err : bytes;
}
@@ -1829,9 +1828,8 @@
* mark_buffer_uptodate() functions propagate buffer state into the
* page struct once IO has completed.
*/
-int block_read_full_page(struct dentry * dentry, struct page * page)
+static inline int __block_read_full_page(struct inode *inode, struct page *page)
{
- struct inode *inode = dentry->d_inode;
unsigned long iblock;
struct buffer_head *bh, *head, *arr[MAX_BUF_PER_PAGE];
unsigned int blocksize, blocks;
@@ -1888,6 +1886,47 @@
if (kaddr)
kunmap(page);
return 0;
+}
+
+int block_read_full_page(struct dentry *dentry, struct page *page)
+{
+ return __block_read_full_page(dentry->d_inode, page);
+}
+
+int block_symlink(struct inode *inode, const char *symname, int len)
+{
+ struct page *page = grab_cache_page(&inode->i_data, 0);
+ mm_segment_t fs;
+ int err = -ENOMEM;
+
+ if (!page)
+ goto fail;
+ fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = block_write_range(inode, page, 0, len-1, symname);
+ set_fs(fs);
+ inode->i_size = len-1;
+ if (err)
+ goto fail_write;
+ /*
+ * Notice that we are _not_ going to block here - end of page is
+ * unmapped, so this will only try to map the rest of page, see
+ * that it is unmapped (typically even will not look into inode -
+ * ->i_size will be enough for everything) and zero it out.
+ * OTOH it's obviously correct and should make the page up-to-date.
+ */
+ err = __block_read_full_page(inode, page);
+ wait_on_page(page);
+ page_cache_release(page);
+ if (err < 0)
+ goto fail;
+ mark_inode_dirty(inode);
+ return 0;
+fail_write:
+ UnlockPage(page);
+ page_cache_release(page);
+fail:
+ return err;
}
/*
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)