Linux內核設計與實現---虛擬文件系統

虛擬文件系統

  • 1 通用文件系統
  • 2 文件系統抽象層
  • 3 Unix文件系統
  • 4 VFS對象及其數據結構
    • 其他VFS對象
  • 5 超級快對象
    • 超級塊操作
  • 6 索引節點對象
    • 索引節點操作
  • 7 目錄項對象
    • 目錄項狀態
    • 目錄項緩存
    • 目錄項操作
  • 8 文件對象
  • 9 和文件系統相關的數據結構
  • 10 和進程相關的數據結構
  • 11 Linux中的文件系統

虛擬文件系統,簡稱VFS,是內核的子系統,為用戶空間程序提供了文件系統相關的接口。系統中所有文件系統不但依賴VFS共存,而且也依靠VFS系統協同工作。通過虛擬文件系統,程序可以 利用標準的UNIX文件系統調用不同介質上不同文件系統進行讀寫操作。

如下圖:使用cp命令從ext3文件系統格式的硬盤拷貝數據到ext2文件系統格式的可移動磁盤上。兩種不同的文件系統,兩種不同的介質,連接到同一個VFS上。
在這里插入圖片描述

1 通用文件系統

VFS使得用戶可以直接使用open()、write()和read()這樣的系統調用而無需考慮具體文件系統實際物理介質。系統調用還可以在這些不同的文件系統和介質之間執行。正是由于包括Linux在內的現代操作系統引入了抽象層,通過虛擬接口訪問文件系統,才使得這種協作性和通用性成為可能,新的文件系統和新種類的存儲介質都能找到進入Linux之路,程序無需重寫,甚至無需重新編譯。

2 文件系統抽象層

之所以可以使用這種通用接口對所有類型的文件系統進行操作,是因為內核在它的底層文件系統接口上建立了一個抽象層,該抽象層使Linux能夠支持各種文件系統,即便是它們在功能和行為上存在很大差別。為了支持多文件系統,VFS提供了一個通用文件系統模型,該模型囊括了我們所能想到的文件系統的常用功能和行為。

VFS抽象層之所以能鏈接各種各樣的文件系統,是因為它定義了所有文件系統都支持的基本的、概念上的接口和數據結構。同時實際文件系統也將自身的諸如如何打開文件、目錄是什么等概念在形式上與VFS定義保持一致。因為實際文件系統的代碼在同一的接口和數據結構下隱藏了具體的實現細節,所以在VFS層和內核的其他部分看來,所有的文件系統都是相同的。

內核通過抽象層能夠方便、簡單地支持各種類型的文件系統,實際文件系統通過編程提供VFS所期望的抽象接口和數據結構,這樣,內核就可以毫不費力地和任何文件系統系統工作。并且這樣提供給用戶空間的接口,也可以和任何文件系統無縫連接在一起,完成實際工作。

我們在用戶空間調用write方法,會首先在VFS找到一個通用系統調用sys_write()處理,sys_wirte()會找到所在的文件系統給出的寫操作,然后通過該寫操作,往物理介質上寫數據。
在這里插入圖片描述

3 Unix文件系統

Unix使用了四種和文件系統相關的傳統抽象概念:文件、目錄項、索引節點和安裝點。

從本質上說文件系統是特殊的數據分層存儲結構,它包含文件、目錄和相關的控制信息。在Unix中,文件系統被安裝在一個特定的安裝點上,所有的已安裝文件系統都作為根文件系統數的枝葉出現在系統中。

文件其實可以看做是一個有序字節串,字節串中第一個字節是文件的頭,最后一個字節時文件的尾。文件通過目錄組織起來,文件目錄好比一個文件夾,用來容納相關文件。因為目錄也可以包含子目錄,所以目錄可以層層嵌套,形成文件路徑。路徑中的每一部分都被稱作目錄條目。/home/wolfman/butter的根目錄是/,目錄home、wolfman和文件butter都是目錄條目,它們被統稱為目錄項。在Unix中,目錄屬于普通文件,它列出包含在其中的所有文件。由于VFS把目錄當做文件對待,所以可以對目錄和文件執行相同的操作。

Unix系統將文件的相關信息和文件本身這兩個概念加以區分,文件的相關信息,有時被稱作文件的元數據,被存儲在一個單獨的數據結構中,該結構被稱為索引節點(inode)。

4 VFS對象及其數據結構

VFS其實采用的是面向對象的設計思路,使用一族數據結構來代表通用文件對象。VFS有四個主要的對象類型,它們分別是:

  • 超級塊對象,它代表一個已安裝的文件系統
  • 索引節點對象,它代表一個文件
  • 目錄項對象,它代表一個目錄項,是路徑的一個組成部分。
  • 文件對象,它代表由進程打開的文件

注意,因為VFS將目錄作為一個文件來處理,所以不存在目錄對象。目錄項代表的是路徑中的一個組成部分,它可能包括一個普通文件,目錄項不同于目錄,但目錄卻和文件相同。

其他VFS對象

VFS使用了大量結構體對象,它所包括的對象遠遠多于上面提到的這幾種主要對象。比如每個注冊的文件系統都是由file_system_type結構體來表示,它描述了文件系統及其能力,另外,每一個安裝點也都有vfsmount結構體表示,它包含安裝點的相關信息。如位置和安裝標志等。
后面還要介紹三個與進程相關的結構體,它們描述了文件系統以及和進程相關的文件,這三個結構體分別是file_struct、fs_struct和namespace。

5 超級快對象

各種文件系統都必須實現超級塊,該對象用于存儲特定文件系統的信息,通常對應于存放在磁盤特定扇區中的文件系統超級塊或文件系統控制塊。對于并非基于磁盤的文件系統(如基于內存的文件系統,比如sysfs),它們會在使用現場創建超級塊并將其保存到內存中。

超級塊對象由spuer_block結構體表示,定義在文件linux/fs.h中。創建、管理和銷毀超級塊對象的代碼位于文件fs/super.c中。超級塊對象通過alloc_super()函數創建并初始化,在文件系統安裝時,內核回調用該函數以便從磁盤讀取文件系統超級塊,并且將其信息填充到內存中的超級塊對象中。

超級塊操作

超級塊對象中最重要的一個域是s_op,它指向超級塊的操作函數表。超級塊操作函數表如下

struct super_operations {struct inode *(*alloc_inode)(struct super_block *sb);void (*destroy_inode)(struct inode *);void (*read_inode) (struct inode *);void (*dirty_inode) (struct inode *);int (*write_inode) (struct inode *, int);void (*put_inode) (struct inode *);void (*drop_inode) (struct inode *);void (*delete_inode) (struct inode *);void (*put_super) (struct super_block *);void (*write_super) (struct super_block *);int (*sync_fs)(struct super_block *sb, int wait);void (*write_super_lockfs) (struct super_block *);void (*unlockfs) (struct super_block *);int (*statfs) (struct super_block *, struct kstatfs *);int (*remount_fs) (struct super_block *, int *, char *);void (*clear_inode) (struct inode *);void (*umount_begin) (struct super_block *);int (*show_options)(struct seq_file *, struct vfsmount *);
};

該結構體中的每一項都是指向超級快操作函數的指針,超級塊操作函數執行文件系統和索引節點的低層操作。
上面所有函數都是由VFS在進程上下文中調用,必要時,它們都可以阻塞,這其中的一些函數是可選的:在超級塊操作表中,文件系統可以將不需要的函數指針設置成NULL,如果VFS發現操作函數指針是NULL,那它要么就會調用通用函數執行相應操作,要門什么也不做,如何選擇取決于函數。

6 索引節點對象

索引節點對象包含了內核在操作文件或目錄時需要的全部信息。對于Unix風格的文件系統來說,這些信息可以從磁盤索引節點直接讀入。如果一個文件系統沒有索引節點,那么,不管這些相關信息在磁盤上是怎么存放的,文件系統都必須從中提取這些消息。

索引節點對象由inode結構體表示,定義在文件linux/fs.h中。

索引節點操作

索引節點對象中的inode_operations項描述了VFS用以操作索引節點對象的所有方法,這些方法由文件系統實現。inode_operatiions結構體定義在文件linux/fs.h中

struct inode_operations {int (*create) (struct inode *,struct dentry *,int, struct nameidata *);struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *);int (*link) (struct dentry *,struct inode *,struct dentry *);int (*unlink) (struct inode *,struct dentry *);int (*symlink) (struct inode *,struct dentry *,const char *);int (*mkdir) (struct inode *,struct dentry *,int);int (*rmdir) (struct inode *,struct dentry *);int (*mknod) (struct inode *,struct dentry *,int,dev_t);int (*rename) (struct inode *, struct dentry *,struct inode *, struct dentry *);int (*readlink) (struct dentry *, char __user *,int);int (*follow_link) (struct dentry *, struct nameidata *);void (*put_link) (struct dentry *, struct nameidata *);void (*truncate) (struct inode *);int (*permission) (struct inode *, int, struct nameidata *);int (*setattr) (struct dentry *, struct iattr *);int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);ssize_t (*listxattr) (struct dentry *, char *, size_t);int (*removexattr) (struct dentry *, const char *);
};

7 目錄項對象

VFS把目錄當作文件看待,所以在路徑/bin/vi中,bin和vi都是文件,bin是特殊的目錄文件,而vi是一個普通文件,路徑中的每個組成部分都由一個索引節點對象表示。
為了方便查找操作,VFS引入了目錄項的概念。每個目錄項代表路徑一個特定部分,對前一個例子來說,/、bin和vi都屬于目錄項對象。前兩個是目錄,最后一個是普通文件。
目錄項也可包括安裝點。在路徑/mnt/cdrom/foo中,/、mnt、cdrom和foo都屬于目錄項對象。VFS在執行目錄操作時,如果需要的話,會現場創建目錄項對象。

目錄項對象由dentry結構體表示,定義在文件linux/dcache.h中。

struct dentry {atomic_t d_count;unsigned int d_flags;		/* protected by d_lock */spinlock_t d_lock;		/* per dentry lock */struct inode *d_inode;		/* Where the name belongs to - NULL is* negative *//** The next three fields are touched by __d_lookup.  Place them here* so they all fit in a 16-byte range, with 16-byte alignment.*/struct dentry *d_parent;	/* parent directory */struct qstr d_name;struct list_head d_lru;		/* LRU list */struct list_head d_child;	/* child of parent list */struct list_head d_subdirs;	/* our children */struct list_head d_alias;	/* inode alias list */unsigned long d_time;		/* used by d_revalidate */struct dentry_operations *d_op;struct super_block *d_sb;	/* The root of the dentry tree */void *d_fsdata;			/* fs-specific data */struct rcu_head d_rcu;struct dcookie_struct *d_cookie; /* cookie, if any */struct hlist_node d_hash;	/* lookup hash list */	int d_mounted;unsigned char d_iname[DNAME_INLINE_LEN_MIN];	/* small names */
};

不同于前面兩個對象,目錄項對象沒有對應的磁盤數據結構,VFS根據字符串性式的路徑名現場創建它,而且由于目錄項對象并非真正保存在磁盤上,所以目錄結構體沒有是否被修改的標志。

目錄項狀態

目錄項對象有三種有效狀態:被使用、未被使用和負狀態。
一個被使用的目錄項對應一個有效的索引節點(d_inode指向相應的索引節點)并且表明該對象存在一個或多個使用者(d_count為正值)。一個目錄項處于被使用狀態,意味著它正被VFS使用并且指向有效的索引節點,因此不能被丟棄。

一個未被使用的目錄項對應一個有效的索引節點,但是VFS當前并未使用它(d_count為0)。該目錄項對象指向一個有效的對象,而且被保留在緩存中以便需要時在使用它。

一個負狀態的目錄項沒有對應的有效索引節點(d_node為NULL),因為索引節點已經被刪除了,或路徑不再正確了,但是目錄項仍然保留,以便快速解析以后的路徑查詢。

目錄項緩存

如果VFS層遍歷路徑名中所有的元素并將它們逐個解析成目錄項對象,這將是一件非常費力的工作,會浪費大量的時間,所以內核將目錄項對象緩存在目錄項緩存(簡稱dcache)中。
目錄項緩存包括三個主要部分:

  • "被使用的"目錄項鏈表
  • "最近被使用的"雙向鏈表。該鏈表含有未被使用的和負狀態的目錄項對象。由于該鏈表以時間順序插入,所以鏈頭的結點是最新數據,當內核必須通過刪除結點項回收內存時,會從鏈尾刪除結點項,因為尾部的節點最舊,在近期內再次被使用的可能性最小
  • 散列表和相應的散列函數用來快速地將給定路徑解析為相關目錄項對象。

舉個例子,假設你需要在自己目錄中編譯一個源文件,/home/dracula/src/foo.c,每一次對foo.c文件進行訪問,VFS必須沿著嵌套的目錄依次解析全部路徑:/、home、dracula、src和最終的foo.c。為了避免每次訪問該路徑名都進行這種耗時的操作,VFS會先在目錄項緩存中搜索路徑名,如果找到了,直接訪問。相反,如果該目錄項在目錄項緩存中并不存在,VFS就必須通過查文件系統為每個路徑分量解析路徑,解析完畢后,再將目錄項對象加入dcache中,以便以后可以快速訪問它。

目錄項操作

dentry_operation結構體指明了VFS操作目錄項的所有方法。
該結構體定義在文件<linux/dcache.h>中

struct dentry_operations {int (*d_revalidate)(struct dentry *, struct nameidata *);int (*d_hash) (struct dentry *, struct qstr *);int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);int (*d_delete)(struct dentry *);void (*d_release)(struct dentry *);void (*d_iput)(struct dentry *, struct inode *);
};

8 文件對象

文件對象表示進程已打開的文件。文件對象是已打開的文件在內存中的表示,該對象由相應的open()系統調用創建,由close()系統調用銷毀。因為多個進程可以同時打開和操作同一個文件,所以同一個文件也可能存在多個對應的文件對象(一個進程打開了一個文件就會有一個文件對象)。文件對象僅僅在進程觀點上代表已打開文件,它反過來指向目錄項對象(索引節點),其實只有目錄項對象才表示已打開的實際文件,雖然一個文件對應的文件對象不是唯一的,但對應的索引節點和目錄項對象是唯一的。

文件對象由file結構體表示,定義在文件linux/fs中

struct file {struct list_head	f_list;struct dentry		*f_dentry;struct vfsmount         *f_vfsmnt;struct file_operations	*f_op;atomic_t		f_count;unsigned int 		f_flags;mode_t			f_mode;int			f_error;loff_t			f_pos;struct fown_struct	f_owner;unsigned int		f_uid, f_gid;struct file_ra_state	f_ra;unsigned long		f_version;void			*f_security;/* needed for tty driver, and maybe others */void			*private_data;#ifdef CONFIG_EPOLL/* Used by fs/eventpoll.c to link all the hooks to this file */struct list_head	f_ep_links;spinlock_t		f_ep_lock;
#endif /* #ifdef CONFIG_EPOLL */struct address_space	*f_mapping;
};

類似于目錄項對象,文件對象實際上沒有對應的磁盤數據,所以在結構體中沒有代表其對象是否為臟,是否需要寫回磁盤的標志。文件對象通過f_dentry指針指向相關的目錄項對象。目錄項會指向相關的索引節點,索引節點會記錄文件是否是臟的。

文件對象的操作由file_operations結構體表示,定義在linux/fs.h中

struct file_operations {struct module *owner;loff_t (*llseek) (struct file *, loff_t, int);ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);ssize_t (*aio_read) (struct kiocb *, char __user *, size_t, loff_t);ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);ssize_t (*aio_write) (struct kiocb *, const char __user *, size_t, loff_t);int (*readdir) (struct file *, void *, filldir_t);unsigned int (*poll) (struct file *, struct poll_table_struct *);int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);int (*mmap) (struct file *, struct vm_area_struct *);int (*open) (struct inode *, struct file *);int (*flush) (struct file *);int (*release) (struct inode *, struct file *);int (*fsync) (struct file *, struct dentry *, int datasync);int (*aio_fsync) (struct kiocb *, int datasync);int (*fasync) (int, struct file *, int);int (*lock) (struct file *, int, struct file_lock *);ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, loff_t *);ssize_t (*writev) (struct file *, const struct iovec *, unsigned long, loff_t *);ssize_t (*sendfile) (struct file *, loff_t *, size_t, read_actor_t, void *);ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);int (*check_flags)(int);int (*dir_notify)(struct file *filp, unsigned long arg);int (*flock) (struct file *, int, struct file_lock *);
};

9 和文件系統相關的數據結構

除了以上幾種VFS基礎對象外,內核還使用了另外一些標準數據結構來管理文件系統的其他相關數據。第一個結構體是file_system_type,用來描述各種特定文件系統類型,比如ext3。第二個結構體是vfsmount,用來描述一個安裝文件系統的實例。

因為Linux支持眾多不同的文件系統,所以內核必須由一個特殊的結構體來描述每種文件系統的功能和行為。file_system_type定義在linux/fs.h中

struct file_system_type {const char *name;int fs_flags;struct super_block *(*get_sb) (struct file_system_type *, int,const char *, void *);void (*kill_sb) (struct super_block *);struct module *owner;struct file_system_type * next;struct list_head fs_supers;
};

每種文件系統,不管有多少個實例安裝到系統中,還是根本就沒有安裝到奧系統中,都只有一個file_system_type結構。

當文件系統被實際安裝時,將有一個vfsmount結構體在安裝時被創建。該結構體用來代表文件系統的實例。
vfsmount結構被定義在linux/mount.h中

struct vfsmount
{struct list_head mnt_hash;struct vfsmount *mnt_parent;	/* fs we are mounted on */struct dentry *mnt_mountpoint;	/* dentry of mountpoint */struct dentry *mnt_root;	/* root of the mounted tree */struct super_block *mnt_sb;	/* pointer to superblock */struct list_head mnt_mounts;	/* list of children, anchored here */struct list_head mnt_child;	/* and going through their mnt_child */atomic_t mnt_count;int mnt_flags;int mnt_expiry_mark;		/* true if marked for expiry */char *mnt_devname;		/* Name of device e.g. /dev/dsk/hda1 */struct list_head mnt_list;struct list_head mnt_fslink;	/* link in fs-specific expiry list */struct namespace *mnt_namespace; /* containing namespace */
};

10 和進程相關的數據結構

系統中的每一個進程都有自己的一組打開的文件,像根文件系統、當前工作目錄、安裝點等。有三個數據結構將VFS層和系統的進程緊緊聯系在一起,它們分別是:files_struct、fs_struct和namespace結構體。

files_struct結構體定義在文件linux/file.h中。該結構體由進程描述符中的files域指向。所有與每個進程相關的信息如打開的文件及文件描述符都包含在其中,其結構體描述如下:

struct files_struct {atomic_t count;spinlock_t file_lock;     /* Protects all the below members.  Nests inside tsk->alloc_lock */int max_fds;int max_fdset;int next_fd;struct file ** fd;      /* current fd array */fd_set *close_on_exec;fd_set *open_fds;fd_set close_on_exec_init;fd_set open_fds_init;struct file * fd_array[NR_OPEN_DEFAULT];
};

fd數組指針指向已打開的文件對象鏈表,默認情況下,指向fd_array數組,因為NR_OPEN_DEFALUT等于32,所以該數組可以容納32個文件對象,如果一個進程鎖打開的文件對象超過32個,內核將分配一個新數組,并且將fd指針指向它。

fs_struct由進程描述符的fs域指向,它包含文件系統和進程相關的信息,定義在linux/fs_struct.h中。

struct fs_struct {atomic_t count;rwlock_t lock;int umask;struct dentry * root, * pwd, * altroot;struct vfsmount * rootmnt, * pwdmnt, * altrootmnt;
};

該結構包含了當前進程的當前工作目錄(pwd)和根目錄(root)。

namespace定義在文件linux/namespace.h中,由進程描述符中的namespace域指向。2.4內核以后,單進程命名空間被加入到內核中,它使得每一個進程都在系統中都看到唯一的安裝系統文件

struct namespace {atomic_t		count;struct vfsmount *	root;struct list_head	list;struct rw_semaphore	sem;
};

list域是連接已安裝文件系統的雙向鏈表,它包含的元素組成了全體命名空間。默認情況下,所有的進程共享同樣的命名空間,只有在進行clone()操作時使用CLONE_NEWNS標志,才會給進程一個另外的命名空間結構體的拷貝。

11 Linux中的文件系統

Linux支持相當多種類的文件系統,從本地文件系統。如ext2和ext3,到網絡文件系統,如NFS和Coda、VFS層提供了給這些文件系統一個統一的實現框架,而且還提供了能和標準系統調用交換工作的同一接口。由于VFS層的存在,使得Linux實現新文件系統的工作變得簡單起來,它可以輕松地使這些文件系統通過Unix系統調用而協同工作。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/379627.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/379627.shtml
英文地址,請注明出處:http://en.pswp.cn/news/379627.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Oracle 查詢歷史數據(轉帖)

回復誤刪除數據信息。 1、執行 alter table table_name enable row movement; 2、執行 FlashBack table table_name to timestamp to_timestamp(2012-05-24 14:59:36,yyyy-mm-dd hh24:mi:ss); 查詢歷史操作數據信息。 比較合理的方法是先從閃回區查找出被誤刪的數據&#xff0c…

Java里面的幾種路徑的區別

1&#xff0c;相對路徑 相對路徑就是指由這個文件所在的路徑引起的跟其它文件&#xff08;或文件夾&#xff09;的路徑關系。 也就是說&#xff1a; 對于如圖所示&#xff1a;一news.html為例 在WEB15工程下的WebContent下的WEB-INF下的news.html 當我訪問的news.html的時候…

Linux內核設計與實現---塊I/O層

塊I/O層1 解刨一個塊設備2 緩沖區和緩沖區頭3 bio結構體新老方法對比4 請求隊列5 I/O調度程序I/O調度程序的工作Linus電梯最終期限I/O調度程序預測I/O調度程序完全公正的排隊I/O調度程序空操作的I/O調度程序I/O調度程序的選擇系統中能夠 隨機訪問 固定大小數據片的設備被稱為塊…

Java字符類isUpperCase()方法與示例

角色類isUpperCase()方法 (Character class isUpperCase() method) isUpperCase() method is available in java.lang package. isUpperCase()方法在java.lang包中可用。 isUpperCase() method is used to check whether the given char value is uppercase or not. isUpperCas…

javascript:history.go()和History.back()的區別

javascript:history.go()和History.back()的區別收藏 <input typebutton value刷新 οnclick"window.location.reload()"> <input typebutton value前進 οnclick"window.history.go(1)"> <input typebutton value后…

sql查詢行轉列

--SQL 面試題 /* 問題&#xff1a;假設有張學生成績表(tb)如下: 姓名 課程 分數 張三 語文 74 張三 數學 83 張三 物理 93 李四 語文 74 李四 數學 84 李四 物理 94 想變成(得到如下結果)&#xff1a; 姓名 語文 數學 物理 ---- ---- ---- ---- 李四 74 84 94 張三 74 83 93 --…

算法---數

數1 最大公約數2 最小公約數3 進制轉換4 階乘統計階乘尾部0的個數5 字符串加法減法二進制加法6 多數投票問題數組中出現次數多于n/2的元素7 相遇問題改變數組元素使所有元素都相同1 最大公約數 歐幾里得算法&#xff1a;兩個整數的最大公約數等于其中較小的那個數和兩數相除余…

Java ByteArrayOutputStream reset()方法及示例

ByteArrayOutputStream類reset()方法 (ByteArrayOutputStream Class reset() method) reset() method is available in java.io package. reset()方法在java.io包中可用。 reset() method is used to reset this stream (i.e. it removes all currently consumed output in thi…

使用存儲過程修改sql server 2005 用戶密碼

exec sp_password null,新密碼,用戶名轉載于:https://www.cnblogs.com/SXLBlog/archive/2009/07/10/1520590.html

winform TopMost

當設置winform窗體的TopMost屬性為true時&#xff0c;有時會出現不好使的狀況&#xff0c;這可能是因為窗體設置了MdiParent屬性。轉載于:https://www.cnblogs.com/magic-cube/archive/2012/06/10/2544216.html

Linux內核設計與實現---進程地址空間

進程地址空間1 內存描述符分配內存描述符銷毀內存描述符mm_struct與內核線程2 內存區域VMA標志VMA操作內存區域的樹形結構和內存區域的鏈表結構3 操作內存區域find_vma()find_vma_prev()find_vma_intersection()4 mmap()和do_mmap()&#xff1a;創建地址空間mmap&#xff08;&a…

JavaScript中帶有示例的Math.log10()方法

JavaScript | Math.log10()方法 (JavaScript | Math.log10() Method) Math operations in JavaScript are handled using functions of math library in JavaScript. In this tutorial on Math.log10() method, we will learn about the log10() method and its working with e…

JSP技術

一、jsp腳本和注釋 jsp腳本&#xff1a; 1&#xff09;<%java代碼%> ----- 內部的java代碼翻譯到service方法的內部 2&#xff09;<%java變量或表達式> ----- 會被翻譯成service方法內部out.print() 3&#xff09;<%!java代碼%> ---- 會被翻譯成servlet的成…

jQuery.ajax不能實現return值調用問題

我們使用jQuery.ajax函數是不能實現success方法return值的&#xff0c;而有時候我們需要對成功返回的數據進行處理&#xff0c;一般來說&#xff0c;與服務器交互后會返回很多的數據&#xff0c;而有些數據需要進行特別處理&#xff0c;這時需要實現success方法return&#xff…

Linux內核設計與實現---頁高速緩存和頁回寫

頁高速緩存和頁回寫1 頁高速緩存2 基樹3 緩沖區高速緩存4 pdflush后臺例程膝上型電腦模式bdflush和kupdated避免擁塞的方法&#xff1a;使用多線程頁高速緩存&#xff08;cache&#xff09;是Linux內核實現的一種主要磁盤緩存&#xff0c;通過把磁盤中的數據緩存到物理內存中&a…

EL技術

1&#xff0e;EL 表達式概述 EL&#xff08;Express Lanuage&#xff09;表達式可以嵌入在jsp頁面內部&#xff0c;減少jsp腳本的編寫&#xff0c;EL 出現的目的是要替代jsp頁面中腳本的編寫。 2&#xff0e;EL從域中取出數據(EL最重要的作用) jsp腳本&#xff1a;<%requ…

math.trunc_JavaScript中帶有示例的Math.trunc()方法

math.truncJavaScript | Math.trunc()方法 (JavaScript | Math.trunc() Method) Math.trunc() is a function in math library of JavaScript that is used to extract the integer part of the given floating-point number. It removes the decimal and all the digits after…

.NET程序員的書單

zz from sjtu bbs: http://bbs.sjtu.edu.cn/bbscon?boardDotNET&fileM.1126188158.A 發信人: luckySeven(lucky為這位mm默哀), 信區: DotNET 標 題: .NET程序員的書單 發信站: 飲水思源 (2005年09月08日22:02:45 星期四), 轉信 發信人: AtomAndBit (原子與比特), 信區: D…

SVN+AnkhSVN端配置

對于ankhSVN我想很多人不陌生&#xff0c;因為經常使用&#xff0c;但是我還是發現很多人并不怎么會配置&#xff0c;或者完全不知道其需要配置&#xff0c;如果不配置的話&#xff0c;當兩個人同時需要修改某個文件的時候就容易中彈了。SVN默認是不支持“鎖定-編輯-解鎖”的&a…

Linux內核設計與實現---模塊

模塊1 構建模塊放在內核源代碼樹中放在內核代碼外2 安裝模塊3 產生模塊依賴性4 載入模塊5 管理配置選項6 模塊參數7 導出符號表Linux內核是模塊化組成的&#xff0c;它允許內核在運行時動態地向其中插入或從中刪除代碼。 與開發的內核核心子系統不同&#xff0c;模塊開發更接近…